Commit 766a2aad645e6c4c4dec0c02be34318d5538e75e

Authored by Linus Walleij
Committed by Wim Van Sebroeck
1 parent ef3c9cc1a5

watchdog: gemini/ftwdt010: rename driver and symbols

This renames all the driver files and symbols for the Gemini
watchdog to FTWDT010 as it has been revealed that this IP block
is a generic watchdog timer from Faraday Technology used in
several SoC designs.

Select this driver by default for the Gemini, it is a sensible
driver to always have enabled.

Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Wim Van Sebroeck <wim@iguana.be>

Showing 4 changed files with 239 additions and 236 deletions Side-by-side Diff

drivers/watchdog/Kconfig
... ... @@ -321,16 +321,18 @@
321 321  
322 322 Not sure? It's safe to say N.
323 323  
324   -config GEMINI_WATCHDOG
325   - tristate "Gemini watchdog"
326   - depends on ARCH_GEMINI
  324 +config FTWDT010_WATCHDOG
  325 + tristate "Faraday Technology FTWDT010 watchdog"
  326 + depends on ARM || COMPILE_TEST
327 327 select WATCHDOG_CORE
  328 + default ARCH_GEMINI
328 329 help
329   - Say Y here if to include support for the watchdog timer
330   - embedded in the Cortina Systems Gemini family of devices.
  330 + Say Y here if to include support for the Faraday Technology
  331 + FTWDT010 watchdog timer embedded in the Cortina Systems Gemini
  332 + family of devices.
331 333  
332 334 To compile this driver as a module, choose M here: the
333   - module will be called gemini_wdt.
  335 + module will be called ftwdt010_wdt.
334 336  
335 337 config IXP4XX_WATCHDOG
336 338 tristate "IXP4xx Watchdog"
drivers/watchdog/Makefile
... ... @@ -46,7 +46,7 @@
46 46 obj-$(CONFIG_TWL4030_WATCHDOG) += twl4030_wdt.o
47 47 obj-$(CONFIG_21285_WATCHDOG) += wdt285.o
48 48 obj-$(CONFIG_977_WATCHDOG) += wdt977.o
49   -obj-$(CONFIG_GEMINI_WATCHDOG) += gemini_wdt.o
  49 +obj-$(CONFIG_FTWDT010_WATCHDOG) += ftwdt010_wdt.o
50 50 obj-$(CONFIG_IXP4XX_WATCHDOG) += ixp4xx_wdt.o
51 51 obj-$(CONFIG_KS8695_WATCHDOG) += ks8695_wdt.o
52 52 obj-$(CONFIG_S3C2410_WATCHDOG) += s3c2410_wdt.o
drivers/watchdog/ftwdt010_wdt.c
  1 +/*
  2 + * Watchdog driver for Faraday Technology FTWDT010
  3 + *
  4 + * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org>
  5 + *
  6 + * Inspired by the out-of-tree drivers from OpenWRT:
  7 + * Copyright (C) 2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
  8 + *
  9 + * This program is free software; you can redistribute it and/or modify
  10 + * it under the terms of the GNU General Public License version 2 as
  11 + * published by the Free Software Foundation.
  12 + */
  13 +
  14 +#include <linux/bitops.h>
  15 +#include <linux/init.h>
  16 +#include <linux/interrupt.h>
  17 +#include <linux/io.h>
  18 +#include <linux/kernel.h>
  19 +#include <linux/module.h>
  20 +#include <linux/of_device.h>
  21 +#include <linux/platform_device.h>
  22 +#include <linux/slab.h>
  23 +#include <linux/watchdog.h>
  24 +
  25 +#define FTWDT010_WDCOUNTER 0x0
  26 +#define FTWDT010_WDLOAD 0x4
  27 +#define FTWDT010_WDRESTART 0x8
  28 +#define FTWDT010_WDCR 0xC
  29 +
  30 +#define WDRESTART_MAGIC 0x5AB9
  31 +
  32 +#define WDCR_CLOCK_5MHZ BIT(4)
  33 +#define WDCR_SYS_RST BIT(1)
  34 +#define WDCR_ENABLE BIT(0)
  35 +
  36 +#define WDT_CLOCK 5000000 /* 5 MHz */
  37 +
  38 +struct ftwdt010_wdt {
  39 + struct watchdog_device wdd;
  40 + struct device *dev;
  41 + void __iomem *base;
  42 +};
  43 +
  44 +static inline
  45 +struct ftwdt010_wdt *to_ftwdt010_wdt(struct watchdog_device *wdd)
  46 +{
  47 + return container_of(wdd, struct ftwdt010_wdt, wdd);
  48 +}
  49 +
  50 +static int ftwdt010_wdt_start(struct watchdog_device *wdd)
  51 +{
  52 + struct ftwdt010_wdt *gwdt = to_ftwdt010_wdt(wdd);
  53 +
  54 + writel(wdd->timeout * WDT_CLOCK, gwdt->base + FTWDT010_WDLOAD);
  55 + writel(WDRESTART_MAGIC, gwdt->base + FTWDT010_WDRESTART);
  56 + /* set clock before enabling */
  57 + writel(WDCR_CLOCK_5MHZ | WDCR_SYS_RST,
  58 + gwdt->base + FTWDT010_WDCR);
  59 + writel(WDCR_CLOCK_5MHZ | WDCR_SYS_RST | WDCR_ENABLE,
  60 + gwdt->base + FTWDT010_WDCR);
  61 +
  62 + return 0;
  63 +}
  64 +
  65 +static int ftwdt010_wdt_stop(struct watchdog_device *wdd)
  66 +{
  67 + struct ftwdt010_wdt *gwdt = to_ftwdt010_wdt(wdd);
  68 +
  69 + writel(0, gwdt->base + FTWDT010_WDCR);
  70 +
  71 + return 0;
  72 +}
  73 +
  74 +static int ftwdt010_wdt_ping(struct watchdog_device *wdd)
  75 +{
  76 + struct ftwdt010_wdt *gwdt = to_ftwdt010_wdt(wdd);
  77 +
  78 + writel(WDRESTART_MAGIC, gwdt->base + FTWDT010_WDRESTART);
  79 +
  80 + return 0;
  81 +}
  82 +
  83 +static int ftwdt010_wdt_set_timeout(struct watchdog_device *wdd,
  84 + unsigned int timeout)
  85 +{
  86 + wdd->timeout = timeout;
  87 + if (watchdog_active(wdd))
  88 + ftwdt010_wdt_start(wdd);
  89 +
  90 + return 0;
  91 +}
  92 +
  93 +static irqreturn_t ftwdt010_wdt_interrupt(int irq, void *data)
  94 +{
  95 + struct ftwdt010_wdt *gwdt = data;
  96 +
  97 + watchdog_notify_pretimeout(&gwdt->wdd);
  98 +
  99 + return IRQ_HANDLED;
  100 +}
  101 +
  102 +static const struct watchdog_ops ftwdt010_wdt_ops = {
  103 + .start = ftwdt010_wdt_start,
  104 + .stop = ftwdt010_wdt_stop,
  105 + .ping = ftwdt010_wdt_ping,
  106 + .set_timeout = ftwdt010_wdt_set_timeout,
  107 + .owner = THIS_MODULE,
  108 +};
  109 +
  110 +static const struct watchdog_info ftwdt010_wdt_info = {
  111 + .options = WDIOF_KEEPALIVEPING
  112 + | WDIOF_MAGICCLOSE
  113 + | WDIOF_SETTIMEOUT,
  114 + .identity = KBUILD_MODNAME,
  115 +};
  116 +
  117 +
  118 +static int ftwdt010_wdt_probe(struct platform_device *pdev)
  119 +{
  120 + struct device *dev = &pdev->dev;
  121 + struct resource *res;
  122 + struct ftwdt010_wdt *gwdt;
  123 + unsigned int reg;
  124 + int irq;
  125 + int ret;
  126 +
  127 + gwdt = devm_kzalloc(dev, sizeof(*gwdt), GFP_KERNEL);
  128 + if (!gwdt)
  129 + return -ENOMEM;
  130 +
  131 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  132 + gwdt->base = devm_ioremap_resource(dev, res);
  133 + if (IS_ERR(gwdt->base))
  134 + return PTR_ERR(gwdt->base);
  135 +
  136 + irq = platform_get_irq(pdev, 0);
  137 + if (!irq)
  138 + return -EINVAL;
  139 +
  140 + gwdt->dev = dev;
  141 + gwdt->wdd.info = &ftwdt010_wdt_info;
  142 + gwdt->wdd.ops = &ftwdt010_wdt_ops;
  143 + gwdt->wdd.min_timeout = 1;
  144 + gwdt->wdd.max_timeout = 0xFFFFFFFF / WDT_CLOCK;
  145 + gwdt->wdd.parent = dev;
  146 +
  147 + /*
  148 + * If 'timeout-sec' unspecified in devicetree, assume a 13 second
  149 + * default.
  150 + */
  151 + gwdt->wdd.timeout = 13U;
  152 + watchdog_init_timeout(&gwdt->wdd, 0, dev);
  153 +
  154 + reg = readw(gwdt->base + FTWDT010_WDCR);
  155 + if (reg & WDCR_ENABLE) {
  156 + /* Watchdog was enabled by the bootloader, disable it. */
  157 + reg &= ~WDCR_ENABLE;
  158 + writel(reg, gwdt->base + FTWDT010_WDCR);
  159 + }
  160 +
  161 + ret = devm_request_irq(dev, irq, ftwdt010_wdt_interrupt, 0,
  162 + "watchdog bark", gwdt);
  163 + if (ret)
  164 + return ret;
  165 +
  166 + ret = devm_watchdog_register_device(dev, &gwdt->wdd);
  167 + if (ret) {
  168 + dev_err(&pdev->dev, "failed to register watchdog\n");
  169 + return ret;
  170 + }
  171 +
  172 + /* Set up platform driver data */
  173 + platform_set_drvdata(pdev, gwdt);
  174 + dev_info(dev, "FTWDT010 watchdog driver enabled\n");
  175 +
  176 + return 0;
  177 +}
  178 +
  179 +static int __maybe_unused ftwdt010_wdt_suspend(struct device *dev)
  180 +{
  181 + struct ftwdt010_wdt *gwdt = dev_get_drvdata(dev);
  182 + unsigned int reg;
  183 +
  184 + reg = readw(gwdt->base + FTWDT010_WDCR);
  185 + reg &= ~WDCR_ENABLE;
  186 + writel(reg, gwdt->base + FTWDT010_WDCR);
  187 +
  188 + return 0;
  189 +}
  190 +
  191 +static int __maybe_unused ftwdt010_wdt_resume(struct device *dev)
  192 +{
  193 + struct ftwdt010_wdt *gwdt = dev_get_drvdata(dev);
  194 + unsigned int reg;
  195 +
  196 + if (watchdog_active(&gwdt->wdd)) {
  197 + reg = readw(gwdt->base + FTWDT010_WDCR);
  198 + reg |= WDCR_ENABLE;
  199 + writel(reg, gwdt->base + FTWDT010_WDCR);
  200 + }
  201 +
  202 + return 0;
  203 +}
  204 +
  205 +static const struct dev_pm_ops ftwdt010_wdt_dev_pm_ops = {
  206 + SET_SYSTEM_SLEEP_PM_OPS(ftwdt010_wdt_suspend,
  207 + ftwdt010_wdt_resume)
  208 +};
  209 +
  210 +#ifdef CONFIG_OF
  211 +static const struct of_device_id ftwdt010_wdt_match[] = {
  212 + { .compatible = "faraday,ftwdt010" },
  213 + { .compatible = "cortina,gemini-watchdog" },
  214 + {},
  215 +};
  216 +MODULE_DEVICE_TABLE(of, ftwdt010_wdt_match);
  217 +#endif
  218 +
  219 +static struct platform_driver ftwdt010_wdt_driver = {
  220 + .probe = ftwdt010_wdt_probe,
  221 + .driver = {
  222 + .name = "ftwdt010-wdt",
  223 + .of_match_table = of_match_ptr(ftwdt010_wdt_match),
  224 + .pm = &ftwdt010_wdt_dev_pm_ops,
  225 + },
  226 +};
  227 +module_platform_driver(ftwdt010_wdt_driver);
  228 +MODULE_AUTHOR("Linus Walleij");
  229 +MODULE_DESCRIPTION("Watchdog driver for Faraday Technology FTWDT010");
  230 +MODULE_LICENSE("GPL");
drivers/watchdog/gemini_wdt.c
1   -/*
2   - * Watchdog driver for Cortina Systems Gemini SoC
3   - *
4   - * Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org>
5   - *
6   - * Inspired by the out-of-tree drivers from OpenWRT:
7   - * Copyright (C) 2009 Paulius Zaleckas <paulius.zaleckas@teltonika.lt>
8   - *
9   - * This program is free software; you can redistribute it and/or modify
10   - * it under the terms of the GNU General Public License version 2 as
11   - * published by the Free Software Foundation.
12   - */
13   -
14   -#include <linux/bitops.h>
15   -#include <linux/init.h>
16   -#include <linux/interrupt.h>
17   -#include <linux/io.h>
18   -#include <linux/kernel.h>
19   -#include <linux/module.h>
20   -#include <linux/of_device.h>
21   -#include <linux/platform_device.h>
22   -#include <linux/slab.h>
23   -#include <linux/watchdog.h>
24   -
25   -#define GEMINI_WDCOUNTER 0x0
26   -#define GEMINI_WDLOAD 0x4
27   -#define GEMINI_WDRESTART 0x8
28   -#define GEMINI_WDCR 0xC
29   -
30   -#define WDRESTART_MAGIC 0x5AB9
31   -
32   -#define WDCR_CLOCK_5MHZ BIT(4)
33   -#define WDCR_SYS_RST BIT(1)
34   -#define WDCR_ENABLE BIT(0)
35   -
36   -#define WDT_CLOCK 5000000 /* 5 MHz */
37   -
38   -struct gemini_wdt {
39   - struct watchdog_device wdd;
40   - struct device *dev;
41   - void __iomem *base;
42   -};
43   -
44   -static inline
45   -struct gemini_wdt *to_gemini_wdt(struct watchdog_device *wdd)
46   -{
47   - return container_of(wdd, struct gemini_wdt, wdd);
48   -}
49   -
50   -static int gemini_wdt_start(struct watchdog_device *wdd)
51   -{
52   - struct gemini_wdt *gwdt = to_gemini_wdt(wdd);
53   -
54   - writel(wdd->timeout * WDT_CLOCK, gwdt->base + GEMINI_WDLOAD);
55   - writel(WDRESTART_MAGIC, gwdt->base + GEMINI_WDRESTART);
56   - /* set clock before enabling */
57   - writel(WDCR_CLOCK_5MHZ | WDCR_SYS_RST,
58   - gwdt->base + GEMINI_WDCR);
59   - writel(WDCR_CLOCK_5MHZ | WDCR_SYS_RST | WDCR_ENABLE,
60   - gwdt->base + GEMINI_WDCR);
61   -
62   - return 0;
63   -}
64   -
65   -static int gemini_wdt_stop(struct watchdog_device *wdd)
66   -{
67   - struct gemini_wdt *gwdt = to_gemini_wdt(wdd);
68   -
69   - writel(0, gwdt->base + GEMINI_WDCR);
70   -
71   - return 0;
72   -}
73   -
74   -static int gemini_wdt_ping(struct watchdog_device *wdd)
75   -{
76   - struct gemini_wdt *gwdt = to_gemini_wdt(wdd);
77   -
78   - writel(WDRESTART_MAGIC, gwdt->base + GEMINI_WDRESTART);
79   -
80   - return 0;
81   -}
82   -
83   -static int gemini_wdt_set_timeout(struct watchdog_device *wdd,
84   - unsigned int timeout)
85   -{
86   - wdd->timeout = timeout;
87   - if (watchdog_active(wdd))
88   - gemini_wdt_start(wdd);
89   -
90   - return 0;
91   -}
92   -
93   -static irqreturn_t gemini_wdt_interrupt(int irq, void *data)
94   -{
95   - struct gemini_wdt *gwdt = data;
96   -
97   - watchdog_notify_pretimeout(&gwdt->wdd);
98   -
99   - return IRQ_HANDLED;
100   -}
101   -
102   -static const struct watchdog_ops gemini_wdt_ops = {
103   - .start = gemini_wdt_start,
104   - .stop = gemini_wdt_stop,
105   - .ping = gemini_wdt_ping,
106   - .set_timeout = gemini_wdt_set_timeout,
107   - .owner = THIS_MODULE,
108   -};
109   -
110   -static const struct watchdog_info gemini_wdt_info = {
111   - .options = WDIOF_KEEPALIVEPING
112   - | WDIOF_MAGICCLOSE
113   - | WDIOF_SETTIMEOUT,
114   - .identity = KBUILD_MODNAME,
115   -};
116   -
117   -
118   -static int gemini_wdt_probe(struct platform_device *pdev)
119   -{
120   - struct device *dev = &pdev->dev;
121   - struct resource *res;
122   - struct gemini_wdt *gwdt;
123   - unsigned int reg;
124   - int irq;
125   - int ret;
126   -
127   - gwdt = devm_kzalloc(dev, sizeof(*gwdt), GFP_KERNEL);
128   - if (!gwdt)
129   - return -ENOMEM;
130   -
131   - res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
132   - gwdt->base = devm_ioremap_resource(dev, res);
133   - if (IS_ERR(gwdt->base))
134   - return PTR_ERR(gwdt->base);
135   -
136   - irq = platform_get_irq(pdev, 0);
137   - if (!irq)
138   - return -EINVAL;
139   -
140   - gwdt->dev = dev;
141   - gwdt->wdd.info = &gemini_wdt_info;
142   - gwdt->wdd.ops = &gemini_wdt_ops;
143   - gwdt->wdd.min_timeout = 1;
144   - gwdt->wdd.max_timeout = 0xFFFFFFFF / WDT_CLOCK;
145   - gwdt->wdd.parent = dev;
146   -
147   - /*
148   - * If 'timeout-sec' unspecified in devicetree, assume a 13 second
149   - * default.
150   - */
151   - gwdt->wdd.timeout = 13U;
152   - watchdog_init_timeout(&gwdt->wdd, 0, dev);
153   -
154   - reg = readw(gwdt->base + GEMINI_WDCR);
155   - if (reg & WDCR_ENABLE) {
156   - /* Watchdog was enabled by the bootloader, disable it. */
157   - reg &= ~WDCR_ENABLE;
158   - writel(reg, gwdt->base + GEMINI_WDCR);
159   - }
160   -
161   - ret = devm_request_irq(dev, irq, gemini_wdt_interrupt, 0,
162   - "watchdog bark", gwdt);
163   - if (ret)
164   - return ret;
165   -
166   - ret = devm_watchdog_register_device(dev, &gwdt->wdd);
167   - if (ret) {
168   - dev_err(&pdev->dev, "failed to register watchdog\n");
169   - return ret;
170   - }
171   -
172   - /* Set up platform driver data */
173   - platform_set_drvdata(pdev, gwdt);
174   - dev_info(dev, "Gemini watchdog driver enabled\n");
175   -
176   - return 0;
177   -}
178   -
179   -static int __maybe_unused gemini_wdt_suspend(struct device *dev)
180   -{
181   - struct gemini_wdt *gwdt = dev_get_drvdata(dev);
182   - unsigned int reg;
183   -
184   - reg = readw(gwdt->base + GEMINI_WDCR);
185   - reg &= ~WDCR_ENABLE;
186   - writel(reg, gwdt->base + GEMINI_WDCR);
187   -
188   - return 0;
189   -}
190   -
191   -static int __maybe_unused gemini_wdt_resume(struct device *dev)
192   -{
193   - struct gemini_wdt *gwdt = dev_get_drvdata(dev);
194   - unsigned int reg;
195   -
196   - if (watchdog_active(&gwdt->wdd)) {
197   - reg = readw(gwdt->base + GEMINI_WDCR);
198   - reg |= WDCR_ENABLE;
199   - writel(reg, gwdt->base + GEMINI_WDCR);
200   - }
201   -
202   - return 0;
203   -}
204   -
205   -static const struct dev_pm_ops gemini_wdt_dev_pm_ops = {
206   - SET_SYSTEM_SLEEP_PM_OPS(gemini_wdt_suspend,
207   - gemini_wdt_resume)
208   -};
209   -
210   -#ifdef CONFIG_OF
211   -static const struct of_device_id gemini_wdt_match[] = {
212   - { .compatible = "cortina,gemini-watchdog" },
213   - {},
214   -};
215   -MODULE_DEVICE_TABLE(of, gemini_wdt_match);
216   -#endif
217   -
218   -static struct platform_driver gemini_wdt_driver = {
219   - .probe = gemini_wdt_probe,
220   - .driver = {
221   - .name = "gemini-wdt",
222   - .of_match_table = of_match_ptr(gemini_wdt_match),
223   - .pm = &gemini_wdt_dev_pm_ops,
224   - },
225   -};
226   -module_platform_driver(gemini_wdt_driver);
227   -MODULE_AUTHOR("Linus Walleij");
228   -MODULE_DESCRIPTION("Watchdog driver for Gemini");
229   -MODULE_LICENSE("GPL");