root/arch/mips/kernel/cevt-gt641xx.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. gt641xx_set_base_clock
  2. gt641xx_timer0_state
  3. gt641xx_timer0_set_next_event
  4. gt641xx_timer0_shutdown
  5. gt641xx_timer0_set_oneshot
  6. gt641xx_timer0_set_periodic
  7. gt641xx_timer0_event_handler
  8. gt641xx_timer0_interrupt
  9. gt641xx_timer0_clockevent_init

   1 // SPDX-License-Identifier: GPL-2.0-or-later
   2 /*
   3  *  GT641xx clockevent routines.
   4  *
   5  *  Copyright (C) 2007  Yoichi Yuasa <yuasa@linux-mips.org>
   6  */
   7 #include <linux/clockchips.h>
   8 #include <linux/init.h>
   9 #include <linux/interrupt.h>
  10 #include <linux/spinlock.h>
  11 #include <linux/irq.h>
  12 
  13 #include <asm/gt64120.h>
  14 #include <asm/time.h>
  15 
  16 static DEFINE_RAW_SPINLOCK(gt641xx_timer_lock);
  17 static unsigned int gt641xx_base_clock;
  18 
  19 void gt641xx_set_base_clock(unsigned int clock)
  20 {
  21         gt641xx_base_clock = clock;
  22 }
  23 
  24 int gt641xx_timer0_state(void)
  25 {
  26         if (GT_READ(GT_TC0_OFS))
  27                 return 0;
  28 
  29         GT_WRITE(GT_TC0_OFS, gt641xx_base_clock / HZ);
  30         GT_WRITE(GT_TC_CONTROL_OFS, GT_TC_CONTROL_ENTC0_MSK);
  31 
  32         return 1;
  33 }
  34 
  35 static int gt641xx_timer0_set_next_event(unsigned long delta,
  36                                          struct clock_event_device *evt)
  37 {
  38         u32 ctrl;
  39 
  40         raw_spin_lock(&gt641xx_timer_lock);
  41 
  42         ctrl = GT_READ(GT_TC_CONTROL_OFS);
  43         ctrl &= ~(GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK);
  44         ctrl |= GT_TC_CONTROL_ENTC0_MSK;
  45 
  46         GT_WRITE(GT_TC0_OFS, delta);
  47         GT_WRITE(GT_TC_CONTROL_OFS, ctrl);
  48 
  49         raw_spin_unlock(&gt641xx_timer_lock);
  50 
  51         return 0;
  52 }
  53 
  54 static int gt641xx_timer0_shutdown(struct clock_event_device *evt)
  55 {
  56         u32 ctrl;
  57 
  58         raw_spin_lock(&gt641xx_timer_lock);
  59 
  60         ctrl = GT_READ(GT_TC_CONTROL_OFS);
  61         ctrl &= ~(GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK);
  62         GT_WRITE(GT_TC_CONTROL_OFS, ctrl);
  63 
  64         raw_spin_unlock(&gt641xx_timer_lock);
  65         return 0;
  66 }
  67 
  68 static int gt641xx_timer0_set_oneshot(struct clock_event_device *evt)
  69 {
  70         u32 ctrl;
  71 
  72         raw_spin_lock(&gt641xx_timer_lock);
  73 
  74         ctrl = GT_READ(GT_TC_CONTROL_OFS);
  75         ctrl &= ~GT_TC_CONTROL_SELTC0_MSK;
  76         ctrl |= GT_TC_CONTROL_ENTC0_MSK;
  77         GT_WRITE(GT_TC_CONTROL_OFS, ctrl);
  78 
  79         raw_spin_unlock(&gt641xx_timer_lock);
  80         return 0;
  81 }
  82 
  83 static int gt641xx_timer0_set_periodic(struct clock_event_device *evt)
  84 {
  85         u32 ctrl;
  86 
  87         raw_spin_lock(&gt641xx_timer_lock);
  88 
  89         ctrl = GT_READ(GT_TC_CONTROL_OFS);
  90         ctrl |= GT_TC_CONTROL_ENTC0_MSK | GT_TC_CONTROL_SELTC0_MSK;
  91         GT_WRITE(GT_TC_CONTROL_OFS, ctrl);
  92 
  93         raw_spin_unlock(&gt641xx_timer_lock);
  94         return 0;
  95 }
  96 
  97 static void gt641xx_timer0_event_handler(struct clock_event_device *dev)
  98 {
  99 }
 100 
 101 static struct clock_event_device gt641xx_timer0_clockevent = {
 102         .name                   = "gt641xx-timer0",
 103         .features               = CLOCK_EVT_FEAT_PERIODIC |
 104                                   CLOCK_EVT_FEAT_ONESHOT,
 105         .irq                    = GT641XX_TIMER0_IRQ,
 106         .set_next_event         = gt641xx_timer0_set_next_event,
 107         .set_state_shutdown     = gt641xx_timer0_shutdown,
 108         .set_state_periodic     = gt641xx_timer0_set_periodic,
 109         .set_state_oneshot      = gt641xx_timer0_set_oneshot,
 110         .tick_resume            = gt641xx_timer0_shutdown,
 111         .event_handler          = gt641xx_timer0_event_handler,
 112 };
 113 
 114 static irqreturn_t gt641xx_timer0_interrupt(int irq, void *dev_id)
 115 {
 116         struct clock_event_device *cd = &gt641xx_timer0_clockevent;
 117 
 118         cd->event_handler(cd);
 119 
 120         return IRQ_HANDLED;
 121 }
 122 
 123 static struct irqaction gt641xx_timer0_irqaction = {
 124         .handler        = gt641xx_timer0_interrupt,
 125         .flags          = IRQF_PERCPU | IRQF_TIMER,
 126         .name           = "gt641xx_timer0",
 127 };
 128 
 129 static int __init gt641xx_timer0_clockevent_init(void)
 130 {
 131         struct clock_event_device *cd;
 132 
 133         if (!gt641xx_base_clock)
 134                 return 0;
 135 
 136         GT_WRITE(GT_TC0_OFS, gt641xx_base_clock / HZ);
 137 
 138         cd = &gt641xx_timer0_clockevent;
 139         cd->rating = 200 + gt641xx_base_clock / 10000000;
 140         clockevent_set_clock(cd, gt641xx_base_clock);
 141         cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
 142         cd->max_delta_ticks = 0x7fffffff;
 143         cd->min_delta_ns = clockevent_delta2ns(0x300, cd);
 144         cd->min_delta_ticks = 0x300;
 145         cd->cpumask = cpumask_of(0);
 146 
 147         clockevents_register_device(&gt641xx_timer0_clockevent);
 148 
 149         return setup_irq(GT641XX_TIMER0_IRQ, &gt641xx_timer0_irqaction);
 150 }
 151 arch_initcall(gt641xx_timer0_clockevent_init);

/* [<][>][^][v][top][bottom][index][help] */