root/arch/mips/ralink/cevt-rt3352.c

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

DEFINITIONS

This source file includes following definitions.
  1. systick_next_event
  2. systick_event_handler
  3. systick_interrupt
  4. systick_shutdown
  5. systick_set_oneshot
  6. ralink_systick_init

   1 /*
   2  * This file is subject to the terms and conditions of the GNU General Public
   3  * License.  See the file "COPYING" in the main directory of this archive
   4  * for more details.
   5  *
   6  * Copyright (C) 2013 by John Crispin <john@phrozen.org>
   7  */
   8 
   9 #include <linux/clockchips.h>
  10 #include <linux/clocksource.h>
  11 #include <linux/interrupt.h>
  12 #include <linux/reset.h>
  13 #include <linux/init.h>
  14 #include <linux/time.h>
  15 #include <linux/of.h>
  16 #include <linux/of_irq.h>
  17 #include <linux/of_address.h>
  18 
  19 #include <asm/mach-ralink/ralink_regs.h>
  20 
  21 #define SYSTICK_FREQ            (50 * 1000)
  22 
  23 #define SYSTICK_CONFIG          0x00
  24 #define SYSTICK_COMPARE         0x04
  25 #define SYSTICK_COUNT           0x08
  26 
  27 /* route systick irq to mips irq 7 instead of the r4k-timer */
  28 #define CFG_EXT_STK_EN          0x2
  29 /* enable the counter */
  30 #define CFG_CNT_EN              0x1
  31 
  32 struct systick_device {
  33         void __iomem *membase;
  34         struct clock_event_device dev;
  35         int irq_requested;
  36         int freq_scale;
  37 };
  38 
  39 static int systick_set_oneshot(struct clock_event_device *evt);
  40 static int systick_shutdown(struct clock_event_device *evt);
  41 
  42 static int systick_next_event(unsigned long delta,
  43                                 struct clock_event_device *evt)
  44 {
  45         struct systick_device *sdev;
  46         u32 count;
  47 
  48         sdev = container_of(evt, struct systick_device, dev);
  49         count = ioread32(sdev->membase + SYSTICK_COUNT);
  50         count = (count + delta) % SYSTICK_FREQ;
  51         iowrite32(count, sdev->membase + SYSTICK_COMPARE);
  52 
  53         return 0;
  54 }
  55 
  56 static void systick_event_handler(struct clock_event_device *dev)
  57 {
  58         /* noting to do here */
  59 }
  60 
  61 static irqreturn_t systick_interrupt(int irq, void *dev_id)
  62 {
  63         struct clock_event_device *dev = (struct clock_event_device *) dev_id;
  64 
  65         dev->event_handler(dev);
  66 
  67         return IRQ_HANDLED;
  68 }
  69 
  70 static struct systick_device systick = {
  71         .dev = {
  72                 /*
  73                  * cevt-r4k uses 300, make sure systick
  74                  * gets used if available
  75                  */
  76                 .rating                 = 310,
  77                 .features               = CLOCK_EVT_FEAT_ONESHOT,
  78                 .set_next_event         = systick_next_event,
  79                 .set_state_shutdown     = systick_shutdown,
  80                 .set_state_oneshot      = systick_set_oneshot,
  81                 .event_handler          = systick_event_handler,
  82         },
  83 };
  84 
  85 static struct irqaction systick_irqaction = {
  86         .handler = systick_interrupt,
  87         .flags = IRQF_PERCPU | IRQF_TIMER,
  88         .dev_id = &systick.dev,
  89 };
  90 
  91 static int systick_shutdown(struct clock_event_device *evt)
  92 {
  93         struct systick_device *sdev;
  94 
  95         sdev = container_of(evt, struct systick_device, dev);
  96 
  97         if (sdev->irq_requested)
  98                 free_irq(systick.dev.irq, &systick_irqaction);
  99         sdev->irq_requested = 0;
 100         iowrite32(0, systick.membase + SYSTICK_CONFIG);
 101 
 102         return 0;
 103 }
 104 
 105 static int systick_set_oneshot(struct clock_event_device *evt)
 106 {
 107         struct systick_device *sdev;
 108 
 109         sdev = container_of(evt, struct systick_device, dev);
 110 
 111         if (!sdev->irq_requested)
 112                 setup_irq(systick.dev.irq, &systick_irqaction);
 113         sdev->irq_requested = 1;
 114         iowrite32(CFG_EXT_STK_EN | CFG_CNT_EN,
 115                   systick.membase + SYSTICK_CONFIG);
 116 
 117         return 0;
 118 }
 119 
 120 static int __init ralink_systick_init(struct device_node *np)
 121 {
 122         int ret;
 123 
 124         systick.membase = of_iomap(np, 0);
 125         if (!systick.membase)
 126                 return -ENXIO;
 127 
 128         systick_irqaction.name = np->name;
 129         systick.dev.name = np->name;
 130         clockevents_calc_mult_shift(&systick.dev, SYSTICK_FREQ, 60);
 131         systick.dev.max_delta_ns = clockevent_delta2ns(0x7fff, &systick.dev);
 132         systick.dev.max_delta_ticks = 0x7fff;
 133         systick.dev.min_delta_ns = clockevent_delta2ns(0x3, &systick.dev);
 134         systick.dev.min_delta_ticks = 0x3;
 135         systick.dev.irq = irq_of_parse_and_map(np, 0);
 136         if (!systick.dev.irq) {
 137                 pr_err("%pOFn: request_irq failed", np);
 138                 return -EINVAL;
 139         }
 140 
 141         ret = clocksource_mmio_init(systick.membase + SYSTICK_COUNT, np->name,
 142                                     SYSTICK_FREQ, 301, 16,
 143                                     clocksource_mmio_readl_up);
 144         if (ret)
 145                 return ret;
 146 
 147         clockevents_register_device(&systick.dev);
 148 
 149         pr_info("%pOFn: running - mult: %d, shift: %d\n",
 150                         np, systick.dev.mult, systick.dev.shift);
 151 
 152         return 0;
 153 }
 154 
 155 TIMER_OF_DECLARE(systick, "ralink,cevt-systick", ralink_systick_init);

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