2 * Watchdog driver for Technologic Systems TS-72xx based SBCs
3 * (TS-7200, TS-7250 and TS-7260). These boards have external
4 * glue logic CPLD chip, which includes programmable watchdog
7 * Copyright (c) 2009 Mika Westerberg <mika.westerberg@iki.fi>
9 * This driver is based on ep93xx_wdt and wm831x_wdt drivers.
11 * This file is licensed under the terms of the GNU General Public
12 * License version 2. This program is licensed "as is" without any
13 * warranty of any kind, whether express or implied.
16 #include <linux/platform_device.h>
17 #include <linux/module.h>
18 #include <linux/watchdog.h>
21 #define TS72XX_WDT_DEFAULT_TIMEOUT 30
24 module_param(timeout
, int, 0);
25 MODULE_PARM_DESC(timeout
, "Watchdog timeout in seconds.");
27 static bool nowayout
= WATCHDOG_NOWAYOUT
;
28 module_param(nowayout
, bool, 0);
29 MODULE_PARM_DESC(nowayout
, "Disable watchdog shutdown on close");
31 /* priv->control_reg */
32 #define TS72XX_WDT_CTRL_DISABLE 0x00
33 #define TS72XX_WDT_CTRL_250MS 0x01
34 #define TS72XX_WDT_CTRL_500MS 0x02
35 #define TS72XX_WDT_CTRL_1SEC 0x03
36 #define TS72XX_WDT_CTRL_RESERVED 0x04
37 #define TS72XX_WDT_CTRL_2SEC 0x05
38 #define TS72XX_WDT_CTRL_4SEC 0x06
39 #define TS72XX_WDT_CTRL_8SEC 0x07
42 #define TS72XX_WDT_FEED_VAL 0x05
44 struct ts72xx_wdt_priv
{
45 void __iomem
*control_reg
;
46 void __iomem
*feed_reg
;
47 struct watchdog_device wdd
;
51 static int ts72xx_wdt_start(struct watchdog_device
*wdd
)
53 struct ts72xx_wdt_priv
*priv
= watchdog_get_drvdata(wdd
);
55 writeb(TS72XX_WDT_FEED_VAL
, priv
->feed_reg
);
56 writeb(priv
->regval
, priv
->control_reg
);
61 static int ts72xx_wdt_stop(struct watchdog_device
*wdd
)
63 struct ts72xx_wdt_priv
*priv
= watchdog_get_drvdata(wdd
);
65 writeb(TS72XX_WDT_FEED_VAL
, priv
->feed_reg
);
66 writeb(TS72XX_WDT_CTRL_DISABLE
, priv
->control_reg
);
71 static int ts72xx_wdt_ping(struct watchdog_device
*wdd
)
73 struct ts72xx_wdt_priv
*priv
= watchdog_get_drvdata(wdd
);
75 writeb(TS72XX_WDT_FEED_VAL
, priv
->feed_reg
);
80 static int ts72xx_wdt_settimeout(struct watchdog_device
*wdd
, unsigned int to
)
82 struct ts72xx_wdt_priv
*priv
= watchdog_get_drvdata(wdd
);
85 priv
->regval
= TS72XX_WDT_CTRL_1SEC
;
87 priv
->regval
= TS72XX_WDT_CTRL_2SEC
;
89 priv
->regval
= TS72XX_WDT_CTRL_4SEC
;
92 priv
->regval
= TS72XX_WDT_CTRL_8SEC
;
99 if (watchdog_active(wdd
)) {
100 ts72xx_wdt_stop(wdd
);
101 ts72xx_wdt_start(wdd
);
107 static const struct watchdog_info ts72xx_wdt_ident
= {
108 .options
= WDIOF_KEEPALIVEPING
|
111 .firmware_version
= 1,
112 .identity
= "TS-72XX WDT",
115 static const struct watchdog_ops ts72xx_wdt_ops
= {
116 .owner
= THIS_MODULE
,
117 .start
= ts72xx_wdt_start
,
118 .stop
= ts72xx_wdt_stop
,
119 .ping
= ts72xx_wdt_ping
,
120 .set_timeout
= ts72xx_wdt_settimeout
,
123 static int ts72xx_wdt_probe(struct platform_device
*pdev
)
125 struct ts72xx_wdt_priv
*priv
;
126 struct watchdog_device
*wdd
;
127 struct resource
*res
;
130 priv
= devm_kzalloc(&pdev
->dev
, sizeof(*priv
), GFP_KERNEL
);
134 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
135 priv
->control_reg
= devm_ioremap_resource(&pdev
->dev
, res
);
136 if (IS_ERR(priv
->control_reg
))
137 return PTR_ERR(priv
->control_reg
);
139 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 1);
140 priv
->feed_reg
= devm_ioremap_resource(&pdev
->dev
, res
);
141 if (IS_ERR(priv
->feed_reg
))
142 return PTR_ERR(priv
->feed_reg
);
145 wdd
->info
= &ts72xx_wdt_ident
;
146 wdd
->ops
= &ts72xx_wdt_ops
;
147 wdd
->min_timeout
= 1;
148 wdd
->max_hw_heartbeat_ms
= 8000;
149 wdd
->parent
= &pdev
->dev
;
151 watchdog_set_nowayout(wdd
, nowayout
);
153 wdd
->timeout
= TS72XX_WDT_DEFAULT_TIMEOUT
;
154 watchdog_init_timeout(wdd
, timeout
, &pdev
->dev
);
156 watchdog_set_drvdata(wdd
, priv
);
158 ret
= devm_watchdog_register_device(&pdev
->dev
, wdd
);
162 dev_info(&pdev
->dev
, "TS-72xx Watchdog driver\n");
167 static struct platform_driver ts72xx_wdt_driver
= {
168 .probe
= ts72xx_wdt_probe
,
170 .name
= "ts72xx-wdt",
174 module_platform_driver(ts72xx_wdt_driver
);
176 MODULE_AUTHOR("Mika Westerberg <mika.westerberg@iki.fi>");
177 MODULE_DESCRIPTION("TS-72xx SBC Watchdog");
178 MODULE_LICENSE("GPL");
179 MODULE_ALIAS("platform:ts72xx-wdt");