root/drivers/clocksource/timer-efm32.c

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

DEFINITIONS

This source file includes following definitions.
  1. efm32_clock_event_shutdown
  2. efm32_clock_event_set_oneshot
  3. efm32_clock_event_set_periodic
  4. efm32_clock_event_set_next_event
  5. efm32_clock_event_handler
  6. efm32_clocksource_init
  7. efm32_clockevent_init
  8. efm32_timer_init

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  * Copyright (C) 2013 Pengutronix
   4  * Uwe Kleine-Koenig <u.kleine-koenig@pengutronix.de>
   5  */
   6 
   7 #define pr_fmt(fmt)     KBUILD_MODNAME ": " fmt
   8 
   9 #include <linux/kernel.h>
  10 #include <linux/clocksource.h>
  11 #include <linux/clockchips.h>
  12 #include <linux/irq.h>
  13 #include <linux/interrupt.h>
  14 #include <linux/of.h>
  15 #include <linux/of_address.h>
  16 #include <linux/of_irq.h>
  17 #include <linux/clk.h>
  18 
  19 #define TIMERn_CTRL                     0x00
  20 #define TIMERn_CTRL_PRESC(val)                  (((val) & 0xf) << 24)
  21 #define TIMERn_CTRL_PRESC_1024                  TIMERn_CTRL_PRESC(10)
  22 #define TIMERn_CTRL_CLKSEL(val)                 (((val) & 0x3) << 16)
  23 #define TIMERn_CTRL_CLKSEL_PRESCHFPERCLK        TIMERn_CTRL_CLKSEL(0)
  24 #define TIMERn_CTRL_OSMEN                       0x00000010
  25 #define TIMERn_CTRL_MODE(val)                   (((val) & 0x3) <<  0)
  26 #define TIMERn_CTRL_MODE_UP                     TIMERn_CTRL_MODE(0)
  27 #define TIMERn_CTRL_MODE_DOWN                   TIMERn_CTRL_MODE(1)
  28 
  29 #define TIMERn_CMD                      0x04
  30 #define TIMERn_CMD_START                        0x00000001
  31 #define TIMERn_CMD_STOP                         0x00000002
  32 
  33 #define TIMERn_IEN                      0x0c
  34 #define TIMERn_IF                       0x10
  35 #define TIMERn_IFS                      0x14
  36 #define TIMERn_IFC                      0x18
  37 #define TIMERn_IRQ_UF                           0x00000002
  38 
  39 #define TIMERn_TOP                      0x1c
  40 #define TIMERn_CNT                      0x24
  41 
  42 struct efm32_clock_event_ddata {
  43         struct clock_event_device evtdev;
  44         void __iomem *base;
  45         unsigned periodic_top;
  46 };
  47 
  48 static int efm32_clock_event_shutdown(struct clock_event_device *evtdev)
  49 {
  50         struct efm32_clock_event_ddata *ddata =
  51                 container_of(evtdev, struct efm32_clock_event_ddata, evtdev);
  52 
  53         writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD);
  54         return 0;
  55 }
  56 
  57 static int efm32_clock_event_set_oneshot(struct clock_event_device *evtdev)
  58 {
  59         struct efm32_clock_event_ddata *ddata =
  60                 container_of(evtdev, struct efm32_clock_event_ddata, evtdev);
  61 
  62         writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD);
  63         writel_relaxed(TIMERn_CTRL_PRESC_1024 |
  64                        TIMERn_CTRL_CLKSEL_PRESCHFPERCLK |
  65                        TIMERn_CTRL_OSMEN |
  66                        TIMERn_CTRL_MODE_DOWN,
  67                        ddata->base + TIMERn_CTRL);
  68         return 0;
  69 }
  70 
  71 static int efm32_clock_event_set_periodic(struct clock_event_device *evtdev)
  72 {
  73         struct efm32_clock_event_ddata *ddata =
  74                 container_of(evtdev, struct efm32_clock_event_ddata, evtdev);
  75 
  76         writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD);
  77         writel_relaxed(ddata->periodic_top, ddata->base + TIMERn_TOP);
  78         writel_relaxed(TIMERn_CTRL_PRESC_1024 |
  79                        TIMERn_CTRL_CLKSEL_PRESCHFPERCLK |
  80                        TIMERn_CTRL_MODE_DOWN,
  81                        ddata->base + TIMERn_CTRL);
  82         writel_relaxed(TIMERn_CMD_START, ddata->base + TIMERn_CMD);
  83         return 0;
  84 }
  85 
  86 static int efm32_clock_event_set_next_event(unsigned long evt,
  87                                             struct clock_event_device *evtdev)
  88 {
  89         struct efm32_clock_event_ddata *ddata =
  90                 container_of(evtdev, struct efm32_clock_event_ddata, evtdev);
  91 
  92         writel_relaxed(TIMERn_CMD_STOP, ddata->base + TIMERn_CMD);
  93         writel_relaxed(evt, ddata->base + TIMERn_CNT);
  94         writel_relaxed(TIMERn_CMD_START, ddata->base + TIMERn_CMD);
  95 
  96         return 0;
  97 }
  98 
  99 static irqreturn_t efm32_clock_event_handler(int irq, void *dev_id)
 100 {
 101         struct efm32_clock_event_ddata *ddata = dev_id;
 102 
 103         writel_relaxed(TIMERn_IRQ_UF, ddata->base + TIMERn_IFC);
 104 
 105         ddata->evtdev.event_handler(&ddata->evtdev);
 106 
 107         return IRQ_HANDLED;
 108 }
 109 
 110 static struct efm32_clock_event_ddata clock_event_ddata = {
 111         .evtdev = {
 112                 .name = "efm32 clockevent",
 113                 .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC,
 114                 .set_state_shutdown = efm32_clock_event_shutdown,
 115                 .set_state_periodic = efm32_clock_event_set_periodic,
 116                 .set_state_oneshot = efm32_clock_event_set_oneshot,
 117                 .set_next_event = efm32_clock_event_set_next_event,
 118                 .rating = 200,
 119         },
 120 };
 121 
 122 static struct irqaction efm32_clock_event_irq = {
 123         .name = "efm32 clockevent",
 124         .flags = IRQF_TIMER,
 125         .handler = efm32_clock_event_handler,
 126         .dev_id = &clock_event_ddata,
 127 };
 128 
 129 static int __init efm32_clocksource_init(struct device_node *np)
 130 {
 131         struct clk *clk;
 132         void __iomem *base;
 133         unsigned long rate;
 134         int ret;
 135 
 136         clk = of_clk_get(np, 0);
 137         if (IS_ERR(clk)) {
 138                 ret = PTR_ERR(clk);
 139                 pr_err("failed to get clock for clocksource (%d)\n", ret);
 140                 goto err_clk_get;
 141         }
 142 
 143         ret = clk_prepare_enable(clk);
 144         if (ret) {
 145                 pr_err("failed to enable timer clock for clocksource (%d)\n",
 146                        ret);
 147                 goto err_clk_enable;
 148         }
 149         rate = clk_get_rate(clk);
 150 
 151         base = of_iomap(np, 0);
 152         if (!base) {
 153                 ret = -EADDRNOTAVAIL;
 154                 pr_err("failed to map registers for clocksource\n");
 155                 goto err_iomap;
 156         }
 157 
 158         writel_relaxed(TIMERn_CTRL_PRESC_1024 |
 159                        TIMERn_CTRL_CLKSEL_PRESCHFPERCLK |
 160                        TIMERn_CTRL_MODE_UP, base + TIMERn_CTRL);
 161         writel_relaxed(TIMERn_CMD_START, base + TIMERn_CMD);
 162 
 163         ret = clocksource_mmio_init(base + TIMERn_CNT, "efm32 timer",
 164                                     DIV_ROUND_CLOSEST(rate, 1024), 200, 16,
 165                                     clocksource_mmio_readl_up);
 166         if (ret) {
 167                 pr_err("failed to init clocksource (%d)\n", ret);
 168                 goto err_clocksource_init;
 169         }
 170 
 171         return 0;
 172 
 173 err_clocksource_init:
 174 
 175         iounmap(base);
 176 err_iomap:
 177 
 178         clk_disable_unprepare(clk);
 179 err_clk_enable:
 180 
 181         clk_put(clk);
 182 err_clk_get:
 183 
 184         return ret;
 185 }
 186 
 187 static int __init efm32_clockevent_init(struct device_node *np)
 188 {
 189         struct clk *clk;
 190         void __iomem *base;
 191         unsigned long rate;
 192         int irq;
 193         int ret;
 194 
 195         clk = of_clk_get(np, 0);
 196         if (IS_ERR(clk)) {
 197                 ret = PTR_ERR(clk);
 198                 pr_err("failed to get clock for clockevent (%d)\n", ret);
 199                 goto err_clk_get;
 200         }
 201 
 202         ret = clk_prepare_enable(clk);
 203         if (ret) {
 204                 pr_err("failed to enable timer clock for clockevent (%d)\n",
 205                        ret);
 206                 goto err_clk_enable;
 207         }
 208         rate = clk_get_rate(clk);
 209 
 210         base = of_iomap(np, 0);
 211         if (!base) {
 212                 ret = -EADDRNOTAVAIL;
 213                 pr_err("failed to map registers for clockevent\n");
 214                 goto err_iomap;
 215         }
 216 
 217         irq = irq_of_parse_and_map(np, 0);
 218         if (!irq) {
 219                 ret = -ENOENT;
 220                 pr_err("failed to get irq for clockevent\n");
 221                 goto err_get_irq;
 222         }
 223 
 224         writel_relaxed(TIMERn_IRQ_UF, base + TIMERn_IEN);
 225 
 226         clock_event_ddata.base = base;
 227         clock_event_ddata.periodic_top = DIV_ROUND_CLOSEST(rate, 1024 * HZ);
 228 
 229         clockevents_config_and_register(&clock_event_ddata.evtdev,
 230                                         DIV_ROUND_CLOSEST(rate, 1024),
 231                                         0xf, 0xffff);
 232 
 233         ret = setup_irq(irq, &efm32_clock_event_irq);
 234         if (ret) {
 235                 pr_err("Failed setup irq\n");
 236                 goto err_setup_irq;
 237         }
 238 
 239         return 0;
 240 
 241 err_setup_irq:
 242 err_get_irq:
 243 
 244         iounmap(base);
 245 err_iomap:
 246 
 247         clk_disable_unprepare(clk);
 248 err_clk_enable:
 249 
 250         clk_put(clk);
 251 err_clk_get:
 252 
 253         return ret;
 254 }
 255 
 256 /*
 257  * This function asserts that we have exactly one clocksource and one
 258  * clock_event_device in the end.
 259  */
 260 static int __init efm32_timer_init(struct device_node *np)
 261 {
 262         static int has_clocksource, has_clockevent;
 263         int ret = 0;
 264 
 265         if (!has_clocksource) {
 266                 ret = efm32_clocksource_init(np);
 267                 if (!ret) {
 268                         has_clocksource = 1;
 269                         return 0;
 270                 }
 271         }
 272 
 273         if (!has_clockevent) {
 274                 ret = efm32_clockevent_init(np);
 275                 if (!ret) {
 276                         has_clockevent = 1;
 277                         return 0;
 278                 }
 279         }
 280 
 281         return ret;
 282 }
 283 TIMER_OF_DECLARE(efm32compat, "efm32,timer", efm32_timer_init);
 284 TIMER_OF_DECLARE(efm32, "energymicro,efm32-timer", efm32_timer_init);

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