2 * drivers/watchdog/orion_wdt.c
4 * Watchdog driver for Orion/Kirkwood processors
6 * Author: Sylver Bruneau <sylver.bruneau@googlemail.com>
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.
13 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
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>
23 #include <linux/clk.h>
24 #include <linux/err.h>
26 #include <linux/of_device.h>
28 /* RSTOUT mask register physical address for Orion5x, Kirkwood and Dove */
29 #define ORION_RSTOUT_MASK_OFFSET 0x20108
31 /* Internal registers can be configured at any 1 MiB aligned address */
32 #define INTERNAL_REGS_MASK ~(SZ_1M - 1)
35 * Watchdog timer block registers.
37 #define TIMER_CTRL 0x0000
38 #define TIMER_A370_STATUS 0x04
40 #define WDT_MAX_CYCLE_COUNT 0xffffffff
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)
46 #define WDT_AXP_FIXED_ENABLE_BIT BIT(10)
47 #define WDT_A370_EXPIRED BIT(31)
49 static bool nowayout
= WATCHDOG_NOWAYOUT
;
50 static int heartbeat
= -1; /* module parameter (seconds) */
52 struct orion_watchdog
;
54 struct orion_watchdog_data
{
55 int wdt_counter_offset
;
57 int rstout_enable_bit
;
58 int (*clock_init
)(struct platform_device
*,
59 struct orion_watchdog
*);
60 int (*start
)(struct watchdog_device
*);
63 struct orion_watchdog
{
64 struct watchdog_device wdt
;
67 unsigned long clk_rate
;
69 const struct orion_watchdog_data
*data
;
72 static int orion_wdt_clock_init(struct platform_device
*pdev
,
73 struct orion_watchdog
*dev
)
77 dev
->clk
= clk_get(&pdev
->dev
, NULL
);
79 return PTR_ERR(dev
->clk
);
80 ret
= clk_prepare_enable(dev
->clk
);
86 dev
->clk_rate
= clk_get_rate(dev
->clk
);
90 static int armada370_wdt_clock_init(struct platform_device
*pdev
,
91 struct orion_watchdog
*dev
)
95 dev
->clk
= clk_get(&pdev
->dev
, NULL
);
97 return PTR_ERR(dev
->clk
);
98 ret
= clk_prepare_enable(dev
->clk
);
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
));
109 dev
->clk_rate
= clk_get_rate(dev
->clk
) / WDT_A370_RATIO
;
113 static int armadaxp_wdt_clock_init(struct platform_device
*pdev
,
114 struct orion_watchdog
*dev
)
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
);
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
);
132 dev
->clk_rate
= clk_get_rate(dev
->clk
);
136 static int orion_wdt_ping(struct watchdog_device
*wdt_dev
)
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
);
145 static int armada370_start(struct watchdog_device
*wdt_dev
)
147 struct orion_watchdog
*dev
= watchdog_get_drvdata(wdt_dev
);
149 /* Set watchdog duration */
150 writel(dev
->clk_rate
* wdt_dev
->timeout
,
151 dev
->reg
+ dev
->data
->wdt_counter_offset
);
153 /* Clear the watchdog expiration bit */
154 atomic_io_modify(dev
->reg
+ TIMER_A370_STATUS
, WDT_A370_EXPIRED
, 0);
156 /* Enable watchdog timer */
157 atomic_io_modify(dev
->reg
+ TIMER_CTRL
, dev
->data
->wdt_enable_bit
,
158 dev
->data
->wdt_enable_bit
);
160 atomic_io_modify(dev
->rstout
, dev
->data
->rstout_enable_bit
,
161 dev
->data
->rstout_enable_bit
);
165 static int orion_start(struct watchdog_device
*wdt_dev
)
167 struct orion_watchdog
*dev
= watchdog_get_drvdata(wdt_dev
);
169 /* Set watchdog duration */
170 writel(dev
->clk_rate
* wdt_dev
->timeout
,
171 dev
->reg
+ dev
->data
->wdt_counter_offset
);
173 /* Enable watchdog timer */
174 atomic_io_modify(dev
->reg
+ TIMER_CTRL
, dev
->data
->wdt_enable_bit
,
175 dev
->data
->wdt_enable_bit
);
177 /* Enable reset on watchdog */
178 atomic_io_modify(dev
->rstout
, dev
->data
->rstout_enable_bit
,
179 dev
->data
->rstout_enable_bit
);
184 static int orion_wdt_start(struct watchdog_device
*wdt_dev
)
186 struct orion_watchdog
*dev
= watchdog_get_drvdata(wdt_dev
);
188 /* There are some per-SoC quirks to handle */
189 return dev
->data
->start(wdt_dev
);
192 static int orion_wdt_stop(struct watchdog_device
*wdt_dev
)
194 struct orion_watchdog
*dev
= watchdog_get_drvdata(wdt_dev
);
196 /* Disable reset on watchdog */
197 atomic_io_modify(dev
->rstout
, dev
->data
->rstout_enable_bit
, 0);
199 /* Disable watchdog timer */
200 atomic_io_modify(dev
->reg
+ TIMER_CTRL
, dev
->data
->wdt_enable_bit
, 0);
205 static int orion_wdt_enabled(struct orion_watchdog
*dev
)
207 bool enabled
, running
;
209 enabled
= readl(dev
->rstout
) & dev
->data
->rstout_enable_bit
;
210 running
= readl(dev
->reg
+ TIMER_CTRL
) & dev
->data
->wdt_enable_bit
;
212 return enabled
&& running
;
215 static unsigned int orion_wdt_get_timeleft(struct watchdog_device
*wdt_dev
)
217 struct orion_watchdog
*dev
= watchdog_get_drvdata(wdt_dev
);
218 return readl(dev
->reg
+ dev
->data
->wdt_counter_offset
) / dev
->clk_rate
;
221 static int orion_wdt_set_timeout(struct watchdog_device
*wdt_dev
,
222 unsigned int timeout
)
224 wdt_dev
->timeout
= timeout
;
228 static const struct watchdog_info orion_wdt_info
= {
229 .options
= WDIOF_SETTIMEOUT
| WDIOF_KEEPALIVEPING
| WDIOF_MAGICCLOSE
,
230 .identity
= "Orion Watchdog",
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
,
242 static irqreturn_t
orion_wdt_irq(int irq
, void *devid
)
244 panic("Watchdog Timeout");
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.
254 static void __iomem
*orion_wdt_ioremap_rstout(struct platform_device
*pdev
,
255 phys_addr_t internal_regs
)
257 struct resource
*res
;
260 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 1);
262 return devm_ioremap(&pdev
->dev
, res
->start
,
265 /* This workaround works only for "orion-wdt", DT-enabled */
266 if (!of_device_is_compatible(pdev
->dev
.of_node
, "marvell,orion-wdt"))
269 rstout
= internal_regs
+ ORION_RSTOUT_MASK_OFFSET
;
271 WARN(1, FW_BUG
"falling back to harcoded RSTOUT reg %pa\n", &rstout
);
272 return devm_ioremap(&pdev
->dev
, rstout
, 0x4);
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
,
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
,
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
,
299 static const struct of_device_id orion_wdt_of_match_table
[] = {
301 .compatible
= "marvell,orion-wdt",
305 .compatible
= "marvell,armada-370-wdt",
306 .data
= &armada370_data
,
309 .compatible
= "marvell,armada-xp-wdt",
310 .data
= &armadaxp_data
,
314 MODULE_DEVICE_TABLE(of
, orion_wdt_of_match_table
);
316 static int orion_wdt_probe(struct platform_device
*pdev
)
318 struct orion_watchdog
*dev
;
319 const struct of_device_id
*match
;
320 unsigned int wdt_max_duration
; /* (seconds) */
321 struct resource
*res
;
324 dev
= devm_kzalloc(&pdev
->dev
, sizeof(struct orion_watchdog
),
329 match
= of_match_device(orion_wdt_of_match_table
, &pdev
->dev
);
331 /* Default legacy match */
332 match
= &orion_wdt_of_match_table
[0];
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
;
339 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
343 dev
->reg
= devm_ioremap(&pdev
->dev
, res
->start
,
348 dev
->rstout
= orion_wdt_ioremap_rstout(pdev
, res
->start
&
353 ret
= dev
->data
->clock_init(pdev
, dev
);
355 dev_err(&pdev
->dev
, "cannot initialize clock\n");
359 wdt_max_duration
= WDT_MAX_CYCLE_COUNT
/ dev
->clk_rate
;
361 dev
->wdt
.timeout
= wdt_max_duration
;
362 dev
->wdt
.max_timeout
= wdt_max_duration
;
363 watchdog_init_timeout(&dev
->wdt
, heartbeat
, &pdev
->dev
);
365 platform_set_drvdata(pdev
, &dev
->wdt
);
366 watchdog_set_drvdata(&dev
->wdt
, dev
);
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.
374 if (!orion_wdt_enabled(dev
))
375 orion_wdt_stop(&dev
->wdt
);
377 /* Request the IRQ only after the watchdog is disabled */
378 irq
= platform_get_irq(pdev
, 0);
381 * Not all supported platforms specify an interrupt for the
382 * watchdog, so let's make it optional.
384 ret
= devm_request_irq(&pdev
->dev
, irq
, orion_wdt_irq
, 0,
387 dev_err(&pdev
->dev
, "failed to request IRQ\n");
392 watchdog_set_nowayout(&dev
->wdt
, nowayout
);
393 ret
= watchdog_register_device(&dev
->wdt
);
397 pr_info("Initial timeout %d sec%s\n",
398 dev
->wdt
.timeout
, nowayout
? ", nowayout" : "");
402 clk_disable_unprepare(dev
->clk
);
407 static int orion_wdt_remove(struct platform_device
*pdev
)
409 struct watchdog_device
*wdt_dev
= platform_get_drvdata(pdev
);
410 struct orion_watchdog
*dev
= watchdog_get_drvdata(wdt_dev
);
412 watchdog_unregister_device(wdt_dev
);
413 clk_disable_unprepare(dev
->clk
);
418 static void orion_wdt_shutdown(struct platform_device
*pdev
)
420 struct watchdog_device
*wdt_dev
= platform_get_drvdata(pdev
);
421 orion_wdt_stop(wdt_dev
);
424 static struct platform_driver orion_wdt_driver
= {
425 .probe
= orion_wdt_probe
,
426 .remove
= orion_wdt_remove
,
427 .shutdown
= orion_wdt_shutdown
,
429 .owner
= THIS_MODULE
,
431 .of_match_table
= orion_wdt_of_match_table
,
435 module_platform_driver(orion_wdt_driver
);
437 MODULE_AUTHOR("Sylver Bruneau <sylver.bruneau@googlemail.com>");
438 MODULE_DESCRIPTION("Orion Processor Watchdog");
440 module_param(heartbeat
, int, 0);
441 MODULE_PARM_DESC(heartbeat
, "Initial watchdog heartbeat in seconds");
443 module_param(nowayout
, bool, 0);
444 MODULE_PARM_DESC(nowayout
, "Watchdog cannot be stopped once started (default="
445 __MODULE_STRING(WATCHDOG_NOWAYOUT
) ")");
447 MODULE_LICENSE("GPL");
448 MODULE_ALIAS("platform:orion_wdt");