mvebu: Refresh kernel configuration
[oweals/openwrt.git] / target / linux / gemini / patches-4.14 / 0018-watchdog-gemini-ftwdt010-rename-driver-and-symbols.patch
1 From c197a5a04d658da490de08636066a6bdbebf16c5 Mon Sep 17 00:00:00 2001
2 From: Linus Walleij <linus.walleij@linaro.org>
3 Date: Mon, 16 Oct 2017 22:54:24 +0200
4 Subject: [PATCH 18/31] watchdog: gemini/ftwdt010: rename driver and symbols
5
6 This renames all the driver files and symbols for the Gemini
7 watchdog to FTWDT010 as it has been revealed that this IP block
8 is a generic watchdog timer from Faraday Technology used in
9 several SoC designs.
10
11 Select this driver by default for the Gemini, it is a sensible
12 driver to always have enabled.
13
14 Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
15 Reviewed-by: Guenter Roeck <linux@roeck-us.net>
16 Signed-off-by: Guenter Roeck <linux@roeck-us.net>
17 Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
18 ---
19  drivers/watchdog/Kconfig                          |  14 +--
20  drivers/watchdog/Makefile                         |   2 +-
21  drivers/watchdog/{gemini_wdt.c => ftwdt010_wdt.c} | 117 +++++++++++-----------
22  3 files changed, 68 insertions(+), 65 deletions(-)
23  rename drivers/watchdog/{gemini_wdt.c => ftwdt010_wdt.c} (50%)
24
25 --- a/drivers/watchdog/Kconfig
26 +++ b/drivers/watchdog/Kconfig
27 @@ -321,16 +321,18 @@ config 977_WATCHDOG
28  
29           Not sure? It's safe to say N.
30  
31 -config GEMINI_WATCHDOG
32 -       tristate "Gemini watchdog"
33 -       depends on ARCH_GEMINI
34 +config FTWDT010_WATCHDOG
35 +       tristate "Faraday Technology FTWDT010 watchdog"
36 +       depends on ARM || COMPILE_TEST
37         select WATCHDOG_CORE
38 +       default ARCH_GEMINI
39         help
40 -         Say Y here if to include support for the watchdog timer
41 -         embedded in the Cortina Systems Gemini family of devices.
42 +         Say Y here if to include support for the Faraday Technology
43 +         FTWDT010 watchdog timer embedded in the Cortina Systems Gemini
44 +         family of devices.
45  
46           To compile this driver as a module, choose M here: the
47 -         module will be called gemini_wdt.
48 +         module will be called ftwdt010_wdt.
49  
50  config IXP4XX_WATCHDOG
51         tristate "IXP4xx Watchdog"
52 --- a/drivers/watchdog/Makefile
53 +++ b/drivers/watchdog/Makefile
54 @@ -46,7 +46,7 @@ obj-$(CONFIG_OMAP_WATCHDOG) += omap_wdt.
55  obj-$(CONFIG_TWL4030_WATCHDOG) += twl4030_wdt.o
56  obj-$(CONFIG_21285_WATCHDOG) += wdt285.o
57  obj-$(CONFIG_977_WATCHDOG) += wdt977.o
58 -obj-$(CONFIG_GEMINI_WATCHDOG) += gemini_wdt.o
59 +obj-$(CONFIG_FTWDT010_WATCHDOG) += ftwdt010_wdt.o
60  obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o
61  obj-$(CONFIG_KS8695_WATCHDOG) += ks8695_wdt.o
62  obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o
63 --- a/drivers/watchdog/gemini_wdt.c
64 +++ /dev/null
65 @@ -1,229 +0,0 @@
66 -/*
67 - * Watchdog driver for Cortina Systems Gemini SoC
68 - *
69 - * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org>
70 - *
71 - * Inspired by the out-of-tree drivers from OpenWRT:
72 - * Copyright (C) 2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
73 - *
74 - * This program is free software; you can redistribute it and/or modify
75 - * it under the terms of the GNU General Public License version 2 as
76 - * published by the Free Software Foundation.
77 - */
78 -
79 -#include <linux/bitops.h>
80 -#include <linux/init.h>
81 -#include <linux/interrupt.h>
82 -#include <linux/io.h>
83 -#include <linux/kernel.h>
84 -#include <linux/module.h>
85 -#include <linux/of_device.h>
86 -#include <linux/platform_device.h>
87 -#include <linux/slab.h>
88 -#include <linux/watchdog.h>
89 -
90 -#define GEMINI_WDCOUNTER       0x0
91 -#define GEMINI_WDLOAD          0x4
92 -#define GEMINI_WDRESTART       0x8
93 -#define GEMINI_WDCR            0xC
94 -
95 -#define WDRESTART_MAGIC                0x5AB9
96 -
97 -#define WDCR_CLOCK_5MHZ                BIT(4)
98 -#define WDCR_SYS_RST           BIT(1)
99 -#define WDCR_ENABLE            BIT(0)
100 -
101 -#define WDT_CLOCK              5000000         /* 5 MHz */
102 -
103 -struct gemini_wdt {
104 -       struct watchdog_device  wdd;
105 -       struct device           *dev;
106 -       void __iomem            *base;
107 -};
108 -
109 -static inline
110 -struct gemini_wdt *to_gemini_wdt(struct watchdog_device *wdd)
111 -{
112 -       return container_of(wdd, struct gemini_wdt, wdd);
113 -}
114 -
115 -static int gemini_wdt_start(struct watchdog_device *wdd)
116 -{
117 -       struct gemini_wdt *gwdt = to_gemini_wdt(wdd);
118 -
119 -       writel(wdd->timeout * WDT_CLOCK, gwdt->base + GEMINI_WDLOAD);
120 -       writel(WDRESTART_MAGIC, gwdt->base + GEMINI_WDRESTART);
121 -       /* set clock before enabling */
122 -       writel(WDCR_CLOCK_5MHZ | WDCR_SYS_RST,
123 -                       gwdt->base + GEMINI_WDCR);
124 -       writel(WDCR_CLOCK_5MHZ | WDCR_SYS_RST | WDCR_ENABLE,
125 -                       gwdt->base + GEMINI_WDCR);
126 -
127 -       return 0;
128 -}
129 -
130 -static int gemini_wdt_stop(struct watchdog_device *wdd)
131 -{
132 -       struct gemini_wdt *gwdt = to_gemini_wdt(wdd);
133 -
134 -       writel(0, gwdt->base + GEMINI_WDCR);
135 -
136 -       return 0;
137 -}
138 -
139 -static int gemini_wdt_ping(struct watchdog_device *wdd)
140 -{
141 -       struct gemini_wdt *gwdt = to_gemini_wdt(wdd);
142 -
143 -       writel(WDRESTART_MAGIC, gwdt->base + GEMINI_WDRESTART);
144 -
145 -       return 0;
146 -}
147 -
148 -static int gemini_wdt_set_timeout(struct watchdog_device *wdd,
149 -                                 unsigned int timeout)
150 -{
151 -       wdd->timeout = timeout;
152 -       if (watchdog_active(wdd))
153 -               gemini_wdt_start(wdd);
154 -
155 -       return 0;
156 -}
157 -
158 -static irqreturn_t gemini_wdt_interrupt(int irq, void *data)
159 -{
160 -       struct gemini_wdt *gwdt = data;
161 -
162 -       watchdog_notify_pretimeout(&gwdt->wdd);
163 -
164 -       return IRQ_HANDLED;
165 -}
166 -
167 -static const struct watchdog_ops gemini_wdt_ops = {
168 -       .start          = gemini_wdt_start,
169 -       .stop           = gemini_wdt_stop,
170 -       .ping           = gemini_wdt_ping,
171 -       .set_timeout    = gemini_wdt_set_timeout,
172 -       .owner          = THIS_MODULE,
173 -};
174 -
175 -static const struct watchdog_info gemini_wdt_info = {
176 -       .options        = WDIOF_KEEPALIVEPING
177 -                       | WDIOF_MAGICCLOSE
178 -                       | WDIOF_SETTIMEOUT,
179 -       .identity       = KBUILD_MODNAME,
180 -};
181 -
182 -
183 -static int gemini_wdt_probe(struct platform_device *pdev)
184 -{
185 -       struct device *dev = &pdev->dev;
186 -       struct resource *res;
187 -       struct gemini_wdt *gwdt;
188 -       unsigned int reg;
189 -       int irq;
190 -       int ret;
191 -
192 -       gwdt = devm_kzalloc(dev, sizeof(*gwdt), GFP_KERNEL);
193 -       if (!gwdt)
194 -               return -ENOMEM;
195 -
196 -       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
197 -       gwdt->base = devm_ioremap_resource(dev, res);
198 -       if (IS_ERR(gwdt->base))
199 -               return PTR_ERR(gwdt->base);
200 -
201 -       irq = platform_get_irq(pdev, 0);
202 -       if (!irq)
203 -               return -EINVAL;
204 -
205 -       gwdt->dev = dev;
206 -       gwdt->wdd.info = &gemini_wdt_info;
207 -       gwdt->wdd.ops = &gemini_wdt_ops;
208 -       gwdt->wdd.min_timeout = 1;
209 -       gwdt->wdd.max_timeout = 0xFFFFFFFF / WDT_CLOCK;
210 -       gwdt->wdd.parent = dev;
211 -
212 -       /*
213 -        * If 'timeout-sec' unspecified in devicetree, assume a 13 second
214 -        * default.
215 -        */
216 -       gwdt->wdd.timeout = 13U;
217 -       watchdog_init_timeout(&gwdt->wdd, 0, dev);
218 -
219 -       reg = readw(gwdt->base + GEMINI_WDCR);
220 -       if (reg & WDCR_ENABLE) {
221 -               /* Watchdog was enabled by the bootloader, disable it. */
222 -               reg &= ~WDCR_ENABLE;
223 -               writel(reg, gwdt->base + GEMINI_WDCR);
224 -       }
225 -
226 -       ret = devm_request_irq(dev, irq, gemini_wdt_interrupt, 0,
227 -                              "watchdog bark", gwdt);
228 -       if (ret)
229 -               return ret;
230 -
231 -       ret = devm_watchdog_register_device(dev, &gwdt->wdd);
232 -       if (ret) {
233 -               dev_err(&pdev->dev, "failed to register watchdog\n");
234 -               return ret;
235 -       }
236 -
237 -       /* Set up platform driver data */
238 -       platform_set_drvdata(pdev, gwdt);
239 -       dev_info(dev, "Gemini watchdog driver enabled\n");
240 -
241 -       return 0;
242 -}
243 -
244 -static int __maybe_unused gemini_wdt_suspend(struct device *dev)
245 -{
246 -       struct gemini_wdt *gwdt = dev_get_drvdata(dev);
247 -       unsigned int reg;
248 -
249 -       reg = readw(gwdt->base + GEMINI_WDCR);
250 -       reg &= ~WDCR_ENABLE;
251 -       writel(reg, gwdt->base + GEMINI_WDCR);
252 -
253 -       return 0;
254 -}
255 -
256 -static int __maybe_unused gemini_wdt_resume(struct device *dev)
257 -{
258 -       struct gemini_wdt *gwdt = dev_get_drvdata(dev);
259 -       unsigned int reg;
260 -
261 -       if (watchdog_active(&gwdt->wdd)) {
262 -               reg = readw(gwdt->base + GEMINI_WDCR);
263 -               reg |= WDCR_ENABLE;
264 -               writel(reg, gwdt->base + GEMINI_WDCR);
265 -       }
266 -
267 -       return 0;
268 -}
269 -
270 -static const struct dev_pm_ops gemini_wdt_dev_pm_ops = {
271 -       SET_SYSTEM_SLEEP_PM_OPS(gemini_wdt_suspend,
272 -                               gemini_wdt_resume)
273 -};
274 -
275 -#ifdef CONFIG_OF
276 -static const struct of_device_id gemini_wdt_match[] = {
277 -       { .compatible = "cortina,gemini-watchdog" },
278 -       {},
279 -};
280 -MODULE_DEVICE_TABLE(of, gemini_wdt_match);
281 -#endif
282 -
283 -static struct platform_driver gemini_wdt_driver = {
284 -       .probe          = gemini_wdt_probe,
285 -       .driver         = {
286 -               .name   = "gemini-wdt",
287 -               .of_match_table = of_match_ptr(gemini_wdt_match),
288 -               .pm = &gemini_wdt_dev_pm_ops,
289 -       },
290 -};
291 -module_platform_driver(gemini_wdt_driver);
292 -MODULE_AUTHOR("Linus Walleij");
293 -MODULE_DESCRIPTION("Watchdog driver for Gemini");
294 -MODULE_LICENSE("GPL");
295 --- /dev/null
296 +++ b/drivers/watchdog/ftwdt010_wdt.c
297 @@ -0,0 +1,230 @@
298 +/*
299 + * Watchdog driver for Faraday Technology FTWDT010
300 + *
301 + * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org>
302 + *
303 + * Inspired by the out-of-tree drivers from OpenWRT:
304 + * Copyright (C) 2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
305 + *
306 + * This program is free software; you can redistribute it and/or modify
307 + * it under the terms of the GNU General Public License version 2 as
308 + * published by the Free Software Foundation.
309 + */
310 +
311 +#include <linux/bitops.h>
312 +#include <linux/init.h>
313 +#include <linux/interrupt.h>
314 +#include <linux/io.h>
315 +#include <linux/kernel.h>
316 +#include <linux/module.h>
317 +#include <linux/of_device.h>
318 +#include <linux/platform_device.h>
319 +#include <linux/slab.h>
320 +#include <linux/watchdog.h>
321 +
322 +#define FTWDT010_WDCOUNTER     0x0
323 +#define FTWDT010_WDLOAD                0x4
324 +#define FTWDT010_WDRESTART     0x8
325 +#define FTWDT010_WDCR          0xC
326 +
327 +#define WDRESTART_MAGIC                0x5AB9
328 +
329 +#define WDCR_CLOCK_5MHZ                BIT(4)
330 +#define WDCR_SYS_RST           BIT(1)
331 +#define WDCR_ENABLE            BIT(0)
332 +
333 +#define WDT_CLOCK              5000000         /* 5 MHz */
334 +
335 +struct ftwdt010_wdt {
336 +       struct watchdog_device  wdd;
337 +       struct device           *dev;
338 +       void __iomem            *base;
339 +};
340 +
341 +static inline
342 +struct ftwdt010_wdt *to_ftwdt010_wdt(struct watchdog_device *wdd)
343 +{
344 +       return container_of(wdd, struct ftwdt010_wdt, wdd);
345 +}
346 +
347 +static int ftwdt010_wdt_start(struct watchdog_device *wdd)
348 +{
349 +       struct ftwdt010_wdt *gwdt = to_ftwdt010_wdt(wdd);
350 +
351 +       writel(wdd->timeout * WDT_CLOCK, gwdt->base + FTWDT010_WDLOAD);
352 +       writel(WDRESTART_MAGIC, gwdt->base + FTWDT010_WDRESTART);
353 +       /* set clock before enabling */
354 +       writel(WDCR_CLOCK_5MHZ | WDCR_SYS_RST,
355 +                       gwdt->base + FTWDT010_WDCR);
356 +       writel(WDCR_CLOCK_5MHZ | WDCR_SYS_RST | WDCR_ENABLE,
357 +                       gwdt->base + FTWDT010_WDCR);
358 +
359 +       return 0;
360 +}
361 +
362 +static int ftwdt010_wdt_stop(struct watchdog_device *wdd)
363 +{
364 +       struct ftwdt010_wdt *gwdt = to_ftwdt010_wdt(wdd);
365 +
366 +       writel(0, gwdt->base + FTWDT010_WDCR);
367 +
368 +       return 0;
369 +}
370 +
371 +static int ftwdt010_wdt_ping(struct watchdog_device *wdd)
372 +{
373 +       struct ftwdt010_wdt *gwdt = to_ftwdt010_wdt(wdd);
374 +
375 +       writel(WDRESTART_MAGIC, gwdt->base + FTWDT010_WDRESTART);
376 +
377 +       return 0;
378 +}
379 +
380 +static int ftwdt010_wdt_set_timeout(struct watchdog_device *wdd,
381 +                                 unsigned int timeout)
382 +{
383 +       wdd->timeout = timeout;
384 +       if (watchdog_active(wdd))
385 +               ftwdt010_wdt_start(wdd);
386 +
387 +       return 0;
388 +}
389 +
390 +static irqreturn_t ftwdt010_wdt_interrupt(int irq, void *data)
391 +{
392 +       struct ftwdt010_wdt *gwdt = data;
393 +
394 +       watchdog_notify_pretimeout(&gwdt->wdd);
395 +
396 +       return IRQ_HANDLED;
397 +}
398 +
399 +static const struct watchdog_ops ftwdt010_wdt_ops = {
400 +       .start          = ftwdt010_wdt_start,
401 +       .stop           = ftwdt010_wdt_stop,
402 +       .ping           = ftwdt010_wdt_ping,
403 +       .set_timeout    = ftwdt010_wdt_set_timeout,
404 +       .owner          = THIS_MODULE,
405 +};
406 +
407 +static const struct watchdog_info ftwdt010_wdt_info = {
408 +       .options        = WDIOF_KEEPALIVEPING
409 +                       | WDIOF_MAGICCLOSE
410 +                       | WDIOF_SETTIMEOUT,
411 +       .identity       = KBUILD_MODNAME,
412 +};
413 +
414 +
415 +static int ftwdt010_wdt_probe(struct platform_device *pdev)
416 +{
417 +       struct device *dev = &pdev->dev;
418 +       struct resource *res;
419 +       struct ftwdt010_wdt *gwdt;
420 +       unsigned int reg;
421 +       int irq;
422 +       int ret;
423 +
424 +       gwdt = devm_kzalloc(dev, sizeof(*gwdt), GFP_KERNEL);
425 +       if (!gwdt)
426 +               return -ENOMEM;
427 +
428 +       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
429 +       gwdt->base = devm_ioremap_resource(dev, res);
430 +       if (IS_ERR(gwdt->base))
431 +               return PTR_ERR(gwdt->base);
432 +
433 +       irq = platform_get_irq(pdev, 0);
434 +       if (!irq)
435 +               return -EINVAL;
436 +
437 +       gwdt->dev = dev;
438 +       gwdt->wdd.info = &ftwdt010_wdt_info;
439 +       gwdt->wdd.ops = &ftwdt010_wdt_ops;
440 +       gwdt->wdd.min_timeout = 1;
441 +       gwdt->wdd.max_timeout = 0xFFFFFFFF / WDT_CLOCK;
442 +       gwdt->wdd.parent = dev;
443 +
444 +       /*
445 +        * If 'timeout-sec' unspecified in devicetree, assume a 13 second
446 +        * default.
447 +        */
448 +       gwdt->wdd.timeout = 13U;
449 +       watchdog_init_timeout(&gwdt->wdd, 0, dev);
450 +
451 +       reg = readw(gwdt->base + FTWDT010_WDCR);
452 +       if (reg & WDCR_ENABLE) {
453 +               /* Watchdog was enabled by the bootloader, disable it. */
454 +               reg &= ~WDCR_ENABLE;
455 +               writel(reg, gwdt->base + FTWDT010_WDCR);
456 +       }
457 +
458 +       ret = devm_request_irq(dev, irq, ftwdt010_wdt_interrupt, 0,
459 +                              "watchdog bark", gwdt);
460 +       if (ret)
461 +               return ret;
462 +
463 +       ret = devm_watchdog_register_device(dev, &gwdt->wdd);
464 +       if (ret) {
465 +               dev_err(&pdev->dev, "failed to register watchdog\n");
466 +               return ret;
467 +       }
468 +
469 +       /* Set up platform driver data */
470 +       platform_set_drvdata(pdev, gwdt);
471 +       dev_info(dev, "FTWDT010 watchdog driver enabled\n");
472 +
473 +       return 0;
474 +}
475 +
476 +static int __maybe_unused ftwdt010_wdt_suspend(struct device *dev)
477 +{
478 +       struct ftwdt010_wdt *gwdt = dev_get_drvdata(dev);
479 +       unsigned int reg;
480 +
481 +       reg = readw(gwdt->base + FTWDT010_WDCR);
482 +       reg &= ~WDCR_ENABLE;
483 +       writel(reg, gwdt->base + FTWDT010_WDCR);
484 +
485 +       return 0;
486 +}
487 +
488 +static int __maybe_unused ftwdt010_wdt_resume(struct device *dev)
489 +{
490 +       struct ftwdt010_wdt *gwdt = dev_get_drvdata(dev);
491 +       unsigned int reg;
492 +
493 +       if (watchdog_active(&gwdt->wdd)) {
494 +               reg = readw(gwdt->base + FTWDT010_WDCR);
495 +               reg |= WDCR_ENABLE;
496 +               writel(reg, gwdt->base + FTWDT010_WDCR);
497 +       }
498 +
499 +       return 0;
500 +}
501 +
502 +static const struct dev_pm_ops ftwdt010_wdt_dev_pm_ops = {
503 +       SET_SYSTEM_SLEEP_PM_OPS(ftwdt010_wdt_suspend,
504 +                               ftwdt010_wdt_resume)
505 +};
506 +
507 +#ifdef CONFIG_OF
508 +static const struct of_device_id ftwdt010_wdt_match[] = {
509 +       { .compatible = "faraday,ftwdt010" },
510 +       { .compatible = "cortina,gemini-watchdog" },
511 +       {},
512 +};
513 +MODULE_DEVICE_TABLE(of, ftwdt010_wdt_match);
514 +#endif
515 +
516 +static struct platform_driver ftwdt010_wdt_driver = {
517 +       .probe          = ftwdt010_wdt_probe,
518 +       .driver         = {
519 +               .name   = "ftwdt010-wdt",
520 +               .of_match_table = of_match_ptr(ftwdt010_wdt_match),
521 +               .pm = &ftwdt010_wdt_dev_pm_ops,
522 +       },
523 +};
524 +module_platform_driver(ftwdt010_wdt_driver);
525 +MODULE_AUTHOR("Linus Walleij");
526 +MODULE_DESCRIPTION("Watchdog driver for Faraday Technology FTWDT010");
527 +MODULE_LICENSE("GPL");