1 // SPDX-License-Identifier: GPL-2.0-only
3 * Watchdog driver for Technologic Systems TS-72xx based SBCs
4 * (TS-7200, TS-7250 and TS-7260). These boards have external
5 * glue logic CPLD chip, which includes programmable watchdog
8 * Copyright (c) 2009 Mika Westerberg <mika.westerberg@iki.fi>
10 * This driver is based on ep93xx_wdt and wm831x_wdt drivers.
14 #include <linux/platform_device.h>
15 #include <linux/mod_devicetable.h>
16 #include <linux/module.h>
17 #include <linux/watchdog.h>
20 #define TS72XX_WDT_DEFAULT_TIMEOUT 30
23 module_param(timeout
, int, 0);
24 MODULE_PARM_DESC(timeout
, "Watchdog timeout in seconds.");
26 static bool nowayout
= WATCHDOG_NOWAYOUT
;
27 module_param(nowayout
, bool, 0);
28 MODULE_PARM_DESC(nowayout
, "Disable watchdog shutdown on close");
30 /* priv->control_reg */
31 #define TS72XX_WDT_CTRL_DISABLE 0x00
32 #define TS72XX_WDT_CTRL_250MS 0x01
33 #define TS72XX_WDT_CTRL_500MS 0x02
34 #define TS72XX_WDT_CTRL_1SEC 0x03
35 #define TS72XX_WDT_CTRL_RESERVED 0x04
36 #define TS72XX_WDT_CTRL_2SEC 0x05
37 #define TS72XX_WDT_CTRL_4SEC 0x06
38 #define TS72XX_WDT_CTRL_8SEC 0x07
41 #define TS72XX_WDT_FEED_VAL 0x05
43 struct ts72xx_wdt_priv
{
44 void __iomem
*control_reg
;
45 void __iomem
*feed_reg
;
46 struct watchdog_device wdd
;
50 static int ts72xx_wdt_start(struct watchdog_device
*wdd
)
52 struct ts72xx_wdt_priv
*priv
= watchdog_get_drvdata(wdd
);
54 writeb(TS72XX_WDT_FEED_VAL
, priv
->feed_reg
);
55 writeb(priv
->regval
, priv
->control_reg
);
60 static int ts72xx_wdt_stop(struct watchdog_device
*wdd
)
62 struct ts72xx_wdt_priv
*priv
= watchdog_get_drvdata(wdd
);
64 writeb(TS72XX_WDT_FEED_VAL
, priv
->feed_reg
);
65 writeb(TS72XX_WDT_CTRL_DISABLE
, priv
->control_reg
);
70 static int ts72xx_wdt_ping(struct watchdog_device
*wdd
)
72 struct ts72xx_wdt_priv
*priv
= watchdog_get_drvdata(wdd
);
74 writeb(TS72XX_WDT_FEED_VAL
, priv
->feed_reg
);
79 static int ts72xx_wdt_settimeout(struct watchdog_device
*wdd
, unsigned int to
)
81 struct ts72xx_wdt_priv
*priv
= watchdog_get_drvdata(wdd
);
84 priv
->regval
= TS72XX_WDT_CTRL_1SEC
;
86 priv
->regval
= TS72XX_WDT_CTRL_2SEC
;
88 priv
->regval
= TS72XX_WDT_CTRL_4SEC
;
91 priv
->regval
= TS72XX_WDT_CTRL_8SEC
;
98 if (watchdog_active(wdd
)) {
100 ts72xx_wdt_start(wdd
);
106 static const struct watchdog_info ts72xx_wdt_ident
= {
107 .options
= WDIOF_KEEPALIVEPING
|
110 .firmware_version
= 1,
111 .identity
= "TS-72XX WDT",
114 static const struct watchdog_ops ts72xx_wdt_ops
= {
115 .owner
= THIS_MODULE
,
116 .start
= ts72xx_wdt_start
,
117 .stop
= ts72xx_wdt_stop
,
118 .ping
= ts72xx_wdt_ping
,
119 .set_timeout
= ts72xx_wdt_settimeout
,
122 static int ts72xx_wdt_probe(struct platform_device
*pdev
)
124 struct device
*dev
= &pdev
->dev
;
125 struct ts72xx_wdt_priv
*priv
;
126 struct watchdog_device
*wdd
;
129 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
133 priv
->control_reg
= devm_platform_ioremap_resource(pdev
, 0);
134 if (IS_ERR(priv
->control_reg
))
135 return PTR_ERR(priv
->control_reg
);
137 priv
->feed_reg
= devm_platform_ioremap_resource(pdev
, 1);
138 if (IS_ERR(priv
->feed_reg
))
139 return PTR_ERR(priv
->feed_reg
);
142 wdd
->info
= &ts72xx_wdt_ident
;
143 wdd
->ops
= &ts72xx_wdt_ops
;
144 wdd
->min_timeout
= 1;
145 wdd
->max_hw_heartbeat_ms
= 8000;
148 watchdog_set_nowayout(wdd
, nowayout
);
150 wdd
->timeout
= TS72XX_WDT_DEFAULT_TIMEOUT
;
151 watchdog_init_timeout(wdd
, timeout
, dev
);
153 watchdog_set_drvdata(wdd
, priv
);
155 ret
= devm_watchdog_register_device(dev
, wdd
);
159 dev_info(dev
, "TS-72xx Watchdog driver\n");
164 static const struct of_device_id ts72xx_wdt_of_ids
[] = {
165 { .compatible
= "technologic,ts7200-wdt" },
168 MODULE_DEVICE_TABLE(of
, ts72xx_wdt_of_ids
);
170 static struct platform_driver ts72xx_wdt_driver
= {
171 .probe
= ts72xx_wdt_probe
,
173 .name
= "ts72xx-wdt",
174 .of_match_table
= ts72xx_wdt_of_ids
,
178 module_platform_driver(ts72xx_wdt_driver
);
180 MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>");
181 MODULE_DESCRIPTION("TS-72xx SBC Watchdog");
182 MODULE_LICENSE("GPL");
183 MODULE_ALIAS("platform:ts72xx-wdt");