1 // SPDX-License-Identifier: GPL-2.0
3 * Watchdog driver for IMX2 and later processors
5 * Copyright (C) 2010 Wolfram Sang, Pengutronix e.K. <kernel@pengutronix.de>
6 * Copyright (C) 2014 Freescale Semiconductor, Inc.
8 * some parts adapted by similar drivers from Darius Augulis and Vladimir
9 * Zapolskiy, additional improvements by Wim Van Sebroeck.
11 * NOTE: MX1 has a slightly different Watchdog than MX2 and later:
15 * Registers: 32-bit 16-bit
16 * Stopable timer: Yes No
17 * Need to enable clk: No Yes
18 * Halt on suspend: Manual Can be automatic
21 #include <linux/clk.h>
22 #include <linux/delay.h>
23 #include <linux/init.h>
24 #include <linux/interrupt.h>
26 #include <linux/kernel.h>
27 #include <linux/module.h>
28 #include <linux/moduleparam.h>
30 #include <linux/platform_device.h>
31 #include <linux/regmap.h>
32 #include <linux/watchdog.h>
34 #define DRIVER_NAME "imx2-wdt"
36 #define IMX2_WDT_WCR 0x00 /* Control Register */
37 #define IMX2_WDT_WCR_WT (0xFF << 8) /* -> Watchdog Timeout Field */
38 #define IMX2_WDT_WCR_WDW BIT(7) /* -> Watchdog disable for WAIT */
39 #define IMX2_WDT_WCR_WDA BIT(5) /* -> External Reset WDOG_B */
40 #define IMX2_WDT_WCR_SRS BIT(4) /* -> Software Reset Signal */
41 #define IMX2_WDT_WCR_WRE BIT(3) /* -> WDOG Reset Enable */
42 #define IMX2_WDT_WCR_WDE BIT(2) /* -> Watchdog Enable */
43 #define IMX2_WDT_WCR_WDZST BIT(0) /* -> Watchdog timer Suspend */
45 #define IMX2_WDT_WSR 0x02 /* Service Register */
46 #define IMX2_WDT_SEQ1 0x5555 /* -> service sequence 1 */
47 #define IMX2_WDT_SEQ2 0xAAAA /* -> service sequence 2 */
49 #define IMX2_WDT_WRSR 0x04 /* Reset Status Register */
50 #define IMX2_WDT_WRSR_TOUT BIT(1) /* -> Reset due to Timeout */
52 #define IMX2_WDT_WICR 0x06 /* Interrupt Control Register */
53 #define IMX2_WDT_WICR_WIE BIT(15) /* -> Interrupt Enable */
54 #define IMX2_WDT_WICR_WTIS BIT(14) /* -> Interrupt Status */
55 #define IMX2_WDT_WICR_WICT 0xFF /* -> Interrupt Count Timeout */
57 #define IMX2_WDT_WMCR 0x08 /* Misc Register */
59 #define IMX2_WDT_MAX_TIME 128U
60 #define IMX2_WDT_DEFAULT_TIME 60 /* in seconds */
62 #define WDOG_SEC_TO_COUNT(s) ((s * 2 - 1) << 8)
64 struct imx2_wdt_data
{
68 struct imx2_wdt_device
{
70 struct regmap
*regmap
;
71 struct watchdog_device wdog
;
72 const struct imx2_wdt_data
*data
;
79 static bool nowayout
= WATCHDOG_NOWAYOUT
;
80 module_param(nowayout
, bool, 0);
81 MODULE_PARM_DESC(nowayout
, "Watchdog cannot be stopped once started (default="
82 __MODULE_STRING(WATCHDOG_NOWAYOUT
) ")");
84 static unsigned timeout
;
85 module_param(timeout
, uint
, 0);
86 MODULE_PARM_DESC(timeout
, "Watchdog timeout in seconds (default="
87 __MODULE_STRING(IMX2_WDT_DEFAULT_TIME
) ")");
89 static const struct watchdog_info imx2_wdt_info
= {
90 .identity
= "imx2+ watchdog",
91 .options
= WDIOF_KEEPALIVEPING
| WDIOF_SETTIMEOUT
| WDIOF_MAGICCLOSE
,
94 static const struct watchdog_info imx2_wdt_pretimeout_info
= {
95 .identity
= "imx2+ watchdog",
96 .options
= WDIOF_KEEPALIVEPING
| WDIOF_SETTIMEOUT
| WDIOF_MAGICCLOSE
|
100 static int imx2_wdt_restart(struct watchdog_device
*wdog
, unsigned long action
,
103 struct imx2_wdt_device
*wdev
= watchdog_get_drvdata(wdog
);
104 unsigned int wcr_enable
= IMX2_WDT_WCR_WDE
;
106 /* Use internal reset or external - not both */
108 wcr_enable
|= IMX2_WDT_WCR_SRS
; /* do not assert int reset */
110 wcr_enable
|= IMX2_WDT_WCR_WDA
; /* do not assert ext-reset */
112 /* Assert SRS signal */
113 regmap_write(wdev
->regmap
, IMX2_WDT_WCR
, wcr_enable
);
115 * Due to imx6q errata ERR004346 (WDOG: WDOG SRS bit requires to be
116 * written twice), we add another two writes to ensure there must be at
117 * least two writes happen in the same one 32kHz clock period. We save
118 * the target check here, since the writes shouldn't be a huge burden
119 * for other platforms.
121 regmap_write(wdev
->regmap
, IMX2_WDT_WCR
, wcr_enable
);
122 regmap_write(wdev
->regmap
, IMX2_WDT_WCR
, wcr_enable
);
124 /* wait for reset to assert... */
130 static inline void imx2_wdt_setup(struct watchdog_device
*wdog
)
132 struct imx2_wdt_device
*wdev
= watchdog_get_drvdata(wdog
);
135 regmap_read(wdev
->regmap
, IMX2_WDT_WCR
, &val
);
137 /* Suspend timer in low power mode, write once-only */
138 val
|= IMX2_WDT_WCR_WDZST
;
139 /* Suspend timer in low power WAIT mode, write once-only */
140 if (wdev
->sleep_wait
)
141 val
|= IMX2_WDT_WCR_WDW
;
142 /* Strip the old watchdog Time-Out value */
143 val
&= ~IMX2_WDT_WCR_WT
;
144 /* Generate internal chip-level reset if WDOG times out */
145 if (!wdev
->ext_reset
)
146 val
&= ~IMX2_WDT_WCR_WRE
;
147 /* Or if external-reset assert WDOG_B reset only on time-out */
149 val
|= IMX2_WDT_WCR_WRE
;
150 /* Keep Watchdog Disabled */
151 val
&= ~IMX2_WDT_WCR_WDE
;
152 /* Set the watchdog's Time-Out value */
153 val
|= WDOG_SEC_TO_COUNT(wdog
->timeout
);
155 regmap_write(wdev
->regmap
, IMX2_WDT_WCR
, val
);
157 /* enable the watchdog */
158 val
|= IMX2_WDT_WCR_WDE
;
159 regmap_write(wdev
->regmap
, IMX2_WDT_WCR
, val
);
162 static inline bool imx2_wdt_is_running(struct imx2_wdt_device
*wdev
)
166 regmap_read(wdev
->regmap
, IMX2_WDT_WCR
, &val
);
168 return val
& IMX2_WDT_WCR_WDE
;
171 static int imx2_wdt_ping(struct watchdog_device
*wdog
)
173 struct imx2_wdt_device
*wdev
= watchdog_get_drvdata(wdog
);
175 if (!wdev
->clk_is_on
)
178 regmap_write(wdev
->regmap
, IMX2_WDT_WSR
, IMX2_WDT_SEQ1
);
179 regmap_write(wdev
->regmap
, IMX2_WDT_WSR
, IMX2_WDT_SEQ2
);
183 static void __imx2_wdt_set_timeout(struct watchdog_device
*wdog
,
184 unsigned int new_timeout
)
186 struct imx2_wdt_device
*wdev
= watchdog_get_drvdata(wdog
);
188 regmap_update_bits(wdev
->regmap
, IMX2_WDT_WCR
, IMX2_WDT_WCR_WT
,
189 WDOG_SEC_TO_COUNT(new_timeout
));
192 static int imx2_wdt_set_timeout(struct watchdog_device
*wdog
,
193 unsigned int new_timeout
)
197 actual
= min(new_timeout
, IMX2_WDT_MAX_TIME
);
198 __imx2_wdt_set_timeout(wdog
, actual
);
199 wdog
->timeout
= new_timeout
;
203 static int imx2_wdt_set_pretimeout(struct watchdog_device
*wdog
,
204 unsigned int new_pretimeout
)
206 struct imx2_wdt_device
*wdev
= watchdog_get_drvdata(wdog
);
208 if (new_pretimeout
>= IMX2_WDT_MAX_TIME
)
211 wdog
->pretimeout
= new_pretimeout
;
213 regmap_update_bits(wdev
->regmap
, IMX2_WDT_WICR
,
214 IMX2_WDT_WICR_WIE
| IMX2_WDT_WICR_WICT
,
215 IMX2_WDT_WICR_WIE
| (new_pretimeout
<< 1));
219 static irqreturn_t
imx2_wdt_isr(int irq
, void *wdog_arg
)
221 struct watchdog_device
*wdog
= wdog_arg
;
222 struct imx2_wdt_device
*wdev
= watchdog_get_drvdata(wdog
);
224 regmap_write_bits(wdev
->regmap
, IMX2_WDT_WICR
,
225 IMX2_WDT_WICR_WTIS
, IMX2_WDT_WICR_WTIS
);
227 watchdog_notify_pretimeout(wdog
);
232 static int imx2_wdt_start(struct watchdog_device
*wdog
)
234 struct imx2_wdt_device
*wdev
= watchdog_get_drvdata(wdog
);
236 if (imx2_wdt_is_running(wdev
))
237 imx2_wdt_set_timeout(wdog
, wdog
->timeout
);
239 imx2_wdt_setup(wdog
);
241 set_bit(WDOG_HW_RUNNING
, &wdog
->status
);
243 return imx2_wdt_ping(wdog
);
246 static const struct watchdog_ops imx2_wdt_ops
= {
247 .owner
= THIS_MODULE
,
248 .start
= imx2_wdt_start
,
249 .ping
= imx2_wdt_ping
,
250 .set_timeout
= imx2_wdt_set_timeout
,
251 .set_pretimeout
= imx2_wdt_set_pretimeout
,
252 .restart
= imx2_wdt_restart
,
255 static const struct regmap_config imx2_wdt_regmap_config
= {
262 static void imx2_wdt_action(void *data
)
264 clk_disable_unprepare(data
);
267 static int __init
imx2_wdt_probe(struct platform_device
*pdev
)
269 struct device
*dev
= &pdev
->dev
;
270 struct imx2_wdt_device
*wdev
;
271 struct watchdog_device
*wdog
;
276 wdev
= devm_kzalloc(dev
, sizeof(*wdev
), GFP_KERNEL
);
280 base
= devm_platform_ioremap_resource(pdev
, 0);
282 return PTR_ERR(base
);
284 wdev
->regmap
= devm_regmap_init_mmio_clk(dev
, NULL
, base
,
285 &imx2_wdt_regmap_config
);
286 if (IS_ERR(wdev
->regmap
)) {
287 dev_err(dev
, "regmap init failed\n");
288 return PTR_ERR(wdev
->regmap
);
291 wdev
->clk
= devm_clk_get(dev
, NULL
);
292 if (IS_ERR(wdev
->clk
)) {
293 dev_err(dev
, "can't get Watchdog clock\n");
294 return PTR_ERR(wdev
->clk
);
298 wdog
->info
= &imx2_wdt_info
;
299 wdog
->ops
= &imx2_wdt_ops
;
300 wdog
->min_timeout
= 1;
301 wdog
->timeout
= IMX2_WDT_DEFAULT_TIME
;
302 wdog
->max_hw_heartbeat_ms
= IMX2_WDT_MAX_TIME
* 1000;
305 wdev
->data
= of_device_get_match_data(dev
);
307 ret
= platform_get_irq(pdev
, 0);
309 if (!devm_request_irq(dev
, ret
, imx2_wdt_isr
, 0,
310 dev_name(dev
), wdog
))
311 wdog
->info
= &imx2_wdt_pretimeout_info
;
313 ret
= clk_prepare_enable(wdev
->clk
);
317 ret
= devm_add_action_or_reset(dev
, imx2_wdt_action
, wdev
->clk
);
321 wdev
->clk_is_on
= true;
323 regmap_read(wdev
->regmap
, IMX2_WDT_WRSR
, &val
);
324 wdog
->bootstatus
= val
& IMX2_WDT_WRSR_TOUT
? WDIOF_CARDRESET
: 0;
326 wdev
->ext_reset
= of_property_read_bool(dev
->of_node
,
327 "fsl,ext-reset-output");
329 if (of_property_read_bool(dev
->of_node
, "fsl,suspend-in-wait")) {
330 if (!wdev
->data
->wdw_supported
) {
331 dev_err(dev
, "suspend-in-wait not supported\n");
334 wdev
->sleep_wait
= true;
338 * The i.MX7D doesn't support low power mode, so we need to ping the watchdog
339 * during suspend. Interaction with "fsl,suspend-in-wait" is unknown!
341 wdev
->no_ping
= !of_device_is_compatible(dev
->of_node
, "fsl,imx7d-wdt");
342 platform_set_drvdata(pdev
, wdog
);
343 watchdog_set_drvdata(wdog
, wdev
);
344 watchdog_set_nowayout(wdog
, nowayout
);
345 watchdog_set_restart_priority(wdog
, 128);
346 watchdog_init_timeout(wdog
, timeout
, dev
);
348 watchdog_stop_ping_on_suspend(wdog
);
350 if (imx2_wdt_is_running(wdev
)) {
351 imx2_wdt_set_timeout(wdog
, wdog
->timeout
);
352 set_bit(WDOG_HW_RUNNING
, &wdog
->status
);
356 * Disable the watchdog power down counter at boot. Otherwise the power
357 * down counter will pull down the #WDOG interrupt line for one clock
360 regmap_write(wdev
->regmap
, IMX2_WDT_WMCR
, 0);
362 return devm_watchdog_register_device(dev
, wdog
);
365 static void imx2_wdt_shutdown(struct platform_device
*pdev
)
367 struct watchdog_device
*wdog
= platform_get_drvdata(pdev
);
368 struct imx2_wdt_device
*wdev
= watchdog_get_drvdata(wdog
);
370 if (imx2_wdt_is_running(wdev
)) {
372 * We are running, configure max timeout before reboot
375 imx2_wdt_set_timeout(wdog
, IMX2_WDT_MAX_TIME
);
377 dev_crit(&pdev
->dev
, "Device shutdown.\n");
381 /* Disable watchdog if it is active or non-active but still running */
382 static int imx2_wdt_suspend(struct device
*dev
)
384 struct watchdog_device
*wdog
= dev_get_drvdata(dev
);
385 struct imx2_wdt_device
*wdev
= watchdog_get_drvdata(wdog
);
387 /* The watchdog IP block is running */
388 if (imx2_wdt_is_running(wdev
)) {
390 * Don't update wdog->timeout, we'll restore the current value
393 __imx2_wdt_set_timeout(wdog
, IMX2_WDT_MAX_TIME
);
398 clk_disable_unprepare(wdev
->clk
);
400 wdev
->clk_is_on
= false;
406 /* Enable watchdog and configure it if necessary */
407 static int imx2_wdt_resume(struct device
*dev
)
409 struct watchdog_device
*wdog
= dev_get_drvdata(dev
);
410 struct imx2_wdt_device
*wdev
= watchdog_get_drvdata(wdog
);
414 ret
= clk_prepare_enable(wdev
->clk
);
419 wdev
->clk_is_on
= true;
422 if (watchdog_active(wdog
) && !imx2_wdt_is_running(wdev
)) {
424 * If the watchdog is still active and resumes
425 * from deep sleep state, need to restart the
428 imx2_wdt_setup(wdog
);
430 if (imx2_wdt_is_running(wdev
)) {
431 imx2_wdt_set_timeout(wdog
, wdog
->timeout
);
438 static DEFINE_SIMPLE_DEV_PM_OPS(imx2_wdt_pm_ops
, imx2_wdt_suspend
,
441 static struct imx2_wdt_data imx_wdt
= {
442 .wdw_supported
= true,
445 static struct imx2_wdt_data imx_wdt_legacy
= {
446 .wdw_supported
= false,
449 static const struct of_device_id imx2_wdt_dt_ids
[] = {
450 { .compatible
= "fsl,imx21-wdt", .data
= &imx_wdt_legacy
},
451 { .compatible
= "fsl,imx25-wdt", .data
= &imx_wdt
},
452 { .compatible
= "fsl,imx27-wdt", .data
= &imx_wdt_legacy
},
453 { .compatible
= "fsl,imx31-wdt", .data
= &imx_wdt_legacy
},
454 { .compatible
= "fsl,imx35-wdt", .data
= &imx_wdt
},
455 { .compatible
= "fsl,imx50-wdt", .data
= &imx_wdt
},
456 { .compatible
= "fsl,imx51-wdt", .data
= &imx_wdt
},
457 { .compatible
= "fsl,imx53-wdt", .data
= &imx_wdt
},
458 { .compatible
= "fsl,imx6q-wdt", .data
= &imx_wdt
},
459 { .compatible
= "fsl,imx6sl-wdt", .data
= &imx_wdt
},
460 { .compatible
= "fsl,imx6sll-wdt", .data
= &imx_wdt
},
461 { .compatible
= "fsl,imx6sx-wdt", .data
= &imx_wdt
},
462 { .compatible
= "fsl,imx6ul-wdt", .data
= &imx_wdt
},
463 { .compatible
= "fsl,imx7d-wdt", .data
= &imx_wdt
},
464 { .compatible
= "fsl,imx8mm-wdt", .data
= &imx_wdt
},
465 { .compatible
= "fsl,imx8mn-wdt", .data
= &imx_wdt
},
466 { .compatible
= "fsl,imx8mp-wdt", .data
= &imx_wdt
},
467 { .compatible
= "fsl,imx8mq-wdt", .data
= &imx_wdt
},
468 { .compatible
= "fsl,ls1012a-wdt", .data
= &imx_wdt_legacy
},
469 { .compatible
= "fsl,ls1043a-wdt", .data
= &imx_wdt_legacy
},
470 { .compatible
= "fsl,vf610-wdt", .data
= &imx_wdt
},
473 MODULE_DEVICE_TABLE(of
, imx2_wdt_dt_ids
);
475 static struct platform_driver imx2_wdt_driver
= {
476 .shutdown
= imx2_wdt_shutdown
,
479 .pm
= pm_sleep_ptr(&imx2_wdt_pm_ops
),
480 .of_match_table
= imx2_wdt_dt_ids
,
484 module_platform_driver_probe(imx2_wdt_driver
, imx2_wdt_probe
);
486 MODULE_AUTHOR("Wolfram Sang");
487 MODULE_DESCRIPTION("Watchdog driver for IMX2 and later");
488 MODULE_LICENSE("GPL v2");
489 MODULE_ALIAS("platform:" DRIVER_NAME
);