Merge tag 'drivers-3.15' of git://git.kernel.org/pub/scm/linux/kernel/git/arm/arm-soc
[pandora-kernel.git] / drivers / watchdog / orion_wdt.c
1 /*
2  * drivers/watchdog/orion_wdt.c
3  *
4  * Watchdog driver for Orion/Kirkwood processors
5  *
6  * Author: Sylver Bruneau <sylver.bruneau@googlemail.com>
7  *
8  * This file is licensed under  the terms of the GNU General Public
9  * License version 2. This program is licensed "as is" without any
10  * warranty of any kind, whether express or implied.
11  */
12
13 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
14
15 #include <linux/module.h>
16 #include <linux/moduleparam.h>
17 #include <linux/types.h>
18 #include <linux/kernel.h>
19 #include <linux/platform_device.h>
20 #include <linux/watchdog.h>
21 #include <linux/interrupt.h>
22 #include <linux/io.h>
23 #include <linux/clk.h>
24 #include <linux/err.h>
25 #include <linux/of.h>
26 #include <linux/of_device.h>
27
28 /* RSTOUT mask register physical address for Orion5x, Kirkwood and Dove */
29 #define ORION_RSTOUT_MASK_OFFSET        0x20108
30
31 /* Internal registers can be configured at any 1 MiB aligned address */
32 #define INTERNAL_REGS_MASK              ~(SZ_1M - 1)
33
34 /*
35  * Watchdog timer block registers.
36  */
37 #define TIMER_CTRL              0x0000
38 #define TIMER_A370_STATUS       0x04
39
40 #define WDT_MAX_CYCLE_COUNT     0xffffffff
41
42 #define WDT_A370_RATIO_MASK(v)  ((v) << 16)
43 #define WDT_A370_RATIO_SHIFT    5
44 #define WDT_A370_RATIO          (1 << WDT_A370_RATIO_SHIFT)
45
46 #define WDT_AXP_FIXED_ENABLE_BIT BIT(10)
47 #define WDT_A370_EXPIRED        BIT(31)
48
49 static bool nowayout = WATCHDOG_NOWAYOUT;
50 static int heartbeat = -1;              /* module parameter (seconds) */
51
52 struct orion_watchdog;
53
54 struct orion_watchdog_data {
55         int wdt_counter_offset;
56         int wdt_enable_bit;
57         int rstout_enable_bit;
58         int (*clock_init)(struct platform_device *,
59                           struct orion_watchdog *);
60         int (*start)(struct watchdog_device *);
61 };
62
63 struct orion_watchdog {
64         struct watchdog_device wdt;
65         void __iomem *reg;
66         void __iomem *rstout;
67         unsigned long clk_rate;
68         struct clk *clk;
69         const struct orion_watchdog_data *data;
70 };
71
72 static int orion_wdt_clock_init(struct platform_device *pdev,
73                                 struct orion_watchdog *dev)
74 {
75         int ret;
76
77         dev->clk = clk_get(&pdev->dev, NULL);
78         if (IS_ERR(dev->clk))
79                 return PTR_ERR(dev->clk);
80         ret = clk_prepare_enable(dev->clk);
81         if (ret) {
82                 clk_put(dev->clk);
83                 return ret;
84         }
85
86         dev->clk_rate = clk_get_rate(dev->clk);
87         return 0;
88 }
89
90 static int armada370_wdt_clock_init(struct platform_device *pdev,
91                                     struct orion_watchdog *dev)
92 {
93         int ret;
94
95         dev->clk = clk_get(&pdev->dev, NULL);
96         if (IS_ERR(dev->clk))
97                 return PTR_ERR(dev->clk);
98         ret = clk_prepare_enable(dev->clk);
99         if (ret) {
100                 clk_put(dev->clk);
101                 return ret;
102         }
103
104         /* Setup watchdog input clock */
105         atomic_io_modify(dev->reg + TIMER_CTRL,
106                         WDT_A370_RATIO_MASK(WDT_A370_RATIO_SHIFT),
107                         WDT_A370_RATIO_MASK(WDT_A370_RATIO_SHIFT));
108
109         dev->clk_rate = clk_get_rate(dev->clk) / WDT_A370_RATIO;
110         return 0;
111 }
112
113 static int armadaxp_wdt_clock_init(struct platform_device *pdev,
114                                    struct orion_watchdog *dev)
115 {
116         int ret;
117
118         dev->clk = of_clk_get_by_name(pdev->dev.of_node, "fixed");
119         if (IS_ERR(dev->clk))
120                 return PTR_ERR(dev->clk);
121         ret = clk_prepare_enable(dev->clk);
122         if (ret) {
123                 clk_put(dev->clk);
124                 return ret;
125         }
126
127         /* Enable the fixed watchdog clock input */
128         atomic_io_modify(dev->reg + TIMER_CTRL,
129                          WDT_AXP_FIXED_ENABLE_BIT,
130                          WDT_AXP_FIXED_ENABLE_BIT);
131
132         dev->clk_rate = clk_get_rate(dev->clk);
133         return 0;
134 }
135
136 static int orion_wdt_ping(struct watchdog_device *wdt_dev)
137 {
138         struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev);
139         /* Reload watchdog duration */
140         writel(dev->clk_rate * wdt_dev->timeout,
141                dev->reg + dev->data->wdt_counter_offset);
142         return 0;
143 }
144
145 static int armada370_start(struct watchdog_device *wdt_dev)
146 {
147         struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev);
148
149         /* Set watchdog duration */
150         writel(dev->clk_rate * wdt_dev->timeout,
151                dev->reg + dev->data->wdt_counter_offset);
152
153         /* Clear the watchdog expiration bit */
154         atomic_io_modify(dev->reg + TIMER_A370_STATUS, WDT_A370_EXPIRED, 0);
155
156         /* Enable watchdog timer */
157         atomic_io_modify(dev->reg + TIMER_CTRL, dev->data->wdt_enable_bit,
158                                                 dev->data->wdt_enable_bit);
159
160         atomic_io_modify(dev->rstout, dev->data->rstout_enable_bit,
161                                       dev->data->rstout_enable_bit);
162         return 0;
163 }
164
165 static int orion_start(struct watchdog_device *wdt_dev)
166 {
167         struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev);
168
169         /* Set watchdog duration */
170         writel(dev->clk_rate * wdt_dev->timeout,
171                dev->reg + dev->data->wdt_counter_offset);
172
173         /* Enable watchdog timer */
174         atomic_io_modify(dev->reg + TIMER_CTRL, dev->data->wdt_enable_bit,
175                                                 dev->data->wdt_enable_bit);
176
177         /* Enable reset on watchdog */
178         atomic_io_modify(dev->rstout, dev->data->rstout_enable_bit,
179                                       dev->data->rstout_enable_bit);
180
181         return 0;
182 }
183
184 static int orion_wdt_start(struct watchdog_device *wdt_dev)
185 {
186         struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev);
187
188         /* There are some per-SoC quirks to handle */
189         return dev->data->start(wdt_dev);
190 }
191
192 static int orion_wdt_stop(struct watchdog_device *wdt_dev)
193 {
194         struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev);
195
196         /* Disable reset on watchdog */
197         atomic_io_modify(dev->rstout, dev->data->rstout_enable_bit, 0);
198
199         /* Disable watchdog timer */
200         atomic_io_modify(dev->reg + TIMER_CTRL, dev->data->wdt_enable_bit, 0);
201
202         return 0;
203 }
204
205 static int orion_wdt_enabled(struct orion_watchdog *dev)
206 {
207         bool enabled, running;
208
209         enabled = readl(dev->rstout) & dev->data->rstout_enable_bit;
210         running = readl(dev->reg + TIMER_CTRL) & dev->data->wdt_enable_bit;
211
212         return enabled && running;
213 }
214
215 static unsigned int orion_wdt_get_timeleft(struct watchdog_device *wdt_dev)
216 {
217         struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev);
218         return readl(dev->reg + dev->data->wdt_counter_offset) / dev->clk_rate;
219 }
220
221 static int orion_wdt_set_timeout(struct watchdog_device *wdt_dev,
222                                  unsigned int timeout)
223 {
224         wdt_dev->timeout = timeout;
225         return 0;
226 }
227
228 static const struct watchdog_info orion_wdt_info = {
229         .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING | WDIOF_MAGICCLOSE,
230         .identity = "Orion Watchdog",
231 };
232
233 static const struct watchdog_ops orion_wdt_ops = {
234         .owner = THIS_MODULE,
235         .start = orion_wdt_start,
236         .stop = orion_wdt_stop,
237         .ping = orion_wdt_ping,
238         .set_timeout = orion_wdt_set_timeout,
239         .get_timeleft = orion_wdt_get_timeleft,
240 };
241
242 static irqreturn_t orion_wdt_irq(int irq, void *devid)
243 {
244         panic("Watchdog Timeout");
245         return IRQ_HANDLED;
246 }
247
248 /*
249  * The original devicetree binding for this driver specified only
250  * one memory resource, so in order to keep DT backwards compatibility
251  * we try to fallback to a hardcoded register address, if the resource
252  * is missing from the devicetree.
253  */
254 static void __iomem *orion_wdt_ioremap_rstout(struct platform_device *pdev,
255                                               phys_addr_t internal_regs)
256 {
257         struct resource *res;
258         phys_addr_t rstout;
259
260         res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
261         if (res)
262                 return devm_ioremap(&pdev->dev, res->start,
263                                     resource_size(res));
264
265         /* This workaround works only for "orion-wdt", DT-enabled */
266         if (!of_device_is_compatible(pdev->dev.of_node, "marvell,orion-wdt"))
267                 return NULL;
268
269         rstout = internal_regs + ORION_RSTOUT_MASK_OFFSET;
270
271         WARN(1, FW_BUG "falling back to harcoded RSTOUT reg %pa\n", &rstout);
272         return devm_ioremap(&pdev->dev, rstout, 0x4);
273 }
274
275 static const struct orion_watchdog_data orion_data = {
276         .rstout_enable_bit = BIT(1),
277         .wdt_enable_bit = BIT(4),
278         .wdt_counter_offset = 0x24,
279         .clock_init = orion_wdt_clock_init,
280         .start = orion_start,
281 };
282
283 static const struct orion_watchdog_data armada370_data = {
284         .rstout_enable_bit = BIT(8),
285         .wdt_enable_bit = BIT(8),
286         .wdt_counter_offset = 0x34,
287         .clock_init = armada370_wdt_clock_init,
288         .start = armada370_start,
289 };
290
291 static const struct orion_watchdog_data armadaxp_data = {
292         .rstout_enable_bit = BIT(8),
293         .wdt_enable_bit = BIT(8),
294         .wdt_counter_offset = 0x34,
295         .clock_init = armadaxp_wdt_clock_init,
296         .start = armada370_start,
297 };
298
299 static const struct of_device_id orion_wdt_of_match_table[] = {
300         {
301                 .compatible = "marvell,orion-wdt",
302                 .data = &orion_data,
303         },
304         {
305                 .compatible = "marvell,armada-370-wdt",
306                 .data = &armada370_data,
307         },
308         {
309                 .compatible = "marvell,armada-xp-wdt",
310                 .data = &armadaxp_data,
311         },
312         {},
313 };
314 MODULE_DEVICE_TABLE(of, orion_wdt_of_match_table);
315
316 static int orion_wdt_probe(struct platform_device *pdev)
317 {
318         struct orion_watchdog *dev;
319         const struct of_device_id *match;
320         unsigned int wdt_max_duration;  /* (seconds) */
321         struct resource *res;
322         int ret, irq;
323
324         dev = devm_kzalloc(&pdev->dev, sizeof(struct orion_watchdog),
325                            GFP_KERNEL);
326         if (!dev)
327                 return -ENOMEM;
328
329         match = of_match_device(orion_wdt_of_match_table, &pdev->dev);
330         if (!match)
331                 /* Default legacy match */
332                 match = &orion_wdt_of_match_table[0];
333
334         dev->wdt.info = &orion_wdt_info;
335         dev->wdt.ops = &orion_wdt_ops;
336         dev->wdt.min_timeout = 1;
337         dev->data = match->data;
338
339         res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
340         if (!res)
341                 return -ENODEV;
342
343         dev->reg = devm_ioremap(&pdev->dev, res->start,
344                                resource_size(res));
345         if (!dev->reg)
346                 return -ENOMEM;
347
348         dev->rstout = orion_wdt_ioremap_rstout(pdev, res->start &
349                                                      INTERNAL_REGS_MASK);
350         if (!dev->rstout)
351                 return -ENODEV;
352
353         ret = dev->data->clock_init(pdev, dev);
354         if (ret) {
355                 dev_err(&pdev->dev, "cannot initialize clock\n");
356                 return ret;
357         }
358
359         wdt_max_duration = WDT_MAX_CYCLE_COUNT / dev->clk_rate;
360
361         dev->wdt.timeout = wdt_max_duration;
362         dev->wdt.max_timeout = wdt_max_duration;
363         watchdog_init_timeout(&dev->wdt, heartbeat, &pdev->dev);
364
365         platform_set_drvdata(pdev, &dev->wdt);
366         watchdog_set_drvdata(&dev->wdt, dev);
367
368         /*
369          * Let's make sure the watchdog is fully stopped, unless it's
370          * explicitly enabled. This may be the case if the module was
371          * removed and re-insterted, or if the bootloader explicitly
372          * set a running watchdog before booting the kernel.
373          */
374         if (!orion_wdt_enabled(dev))
375                 orion_wdt_stop(&dev->wdt);
376
377         /* Request the IRQ only after the watchdog is disabled */
378         irq = platform_get_irq(pdev, 0);
379         if (irq > 0) {
380                 /*
381                  * Not all supported platforms specify an interrupt for the
382                  * watchdog, so let's make it optional.
383                  */
384                 ret = devm_request_irq(&pdev->dev, irq, orion_wdt_irq, 0,
385                                        pdev->name, dev);
386                 if (ret < 0) {
387                         dev_err(&pdev->dev, "failed to request IRQ\n");
388                         goto disable_clk;
389                 }
390         }
391
392         watchdog_set_nowayout(&dev->wdt, nowayout);
393         ret = watchdog_register_device(&dev->wdt);
394         if (ret)
395                 goto disable_clk;
396
397         pr_info("Initial timeout %d sec%s\n",
398                 dev->wdt.timeout, nowayout ? ", nowayout" : "");
399         return 0;
400
401 disable_clk:
402         clk_disable_unprepare(dev->clk);
403         clk_put(dev->clk);
404         return ret;
405 }
406
407 static int orion_wdt_remove(struct platform_device *pdev)
408 {
409         struct watchdog_device *wdt_dev = platform_get_drvdata(pdev);
410         struct orion_watchdog *dev = watchdog_get_drvdata(wdt_dev);
411
412         watchdog_unregister_device(wdt_dev);
413         clk_disable_unprepare(dev->clk);
414         clk_put(dev->clk);
415         return 0;
416 }
417
418 static void orion_wdt_shutdown(struct platform_device *pdev)
419 {
420         struct watchdog_device *wdt_dev = platform_get_drvdata(pdev);
421         orion_wdt_stop(wdt_dev);
422 }
423
424 static struct platform_driver orion_wdt_driver = {
425         .probe          = orion_wdt_probe,
426         .remove         = orion_wdt_remove,
427         .shutdown       = orion_wdt_shutdown,
428         .driver         = {
429                 .owner  = THIS_MODULE,
430                 .name   = "orion_wdt",
431                 .of_match_table = orion_wdt_of_match_table,
432         },
433 };
434
435 module_platform_driver(orion_wdt_driver);
436
437 MODULE_AUTHOR("Sylver Bruneau <sylver.bruneau@googlemail.com>");
438 MODULE_DESCRIPTION("Orion Processor Watchdog");
439
440 module_param(heartbeat, int, 0);
441 MODULE_PARM_DESC(heartbeat, "Initial watchdog heartbeat in seconds");
442
443 module_param(nowayout, bool, 0);
444 MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
445                                 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
446
447 MODULE_LICENSE("GPL");
448 MODULE_ALIAS("platform:orion_wdt");