diff options
author | Geert Uytterhoeven <geert+renesas@glider.be> | 2015-01-29 09:26:05 -0500 |
---|---|---|
committer | Wim Van Sebroeck <wim@iguana.be> | 2015-02-17 15:33:06 -0500 |
commit | 396f163ceba3ac2829e3076764efcfb10797293c (patch) | |
tree | 07987c80e4041c2265620db685081a44a78f4d12 /drivers/watchdog | |
parent | 9a4c88016458424e53084ed3c26bfbae8cd8af22 (diff) |
watchdog: da9063: Add restart handler support
Register a restart handler for the da9063 watchdog. System restart is
triggered by sending the shutdown command to the PMIC.
As more-suitable restart handlers may exist, the priority of the
watchdog restart handler is set to 128.
The actual restart method was inspired by a platform-specific patch from
the BSP by Hisashi Nakamura <hisashi.nakamura.ak@renesas.com>.
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Acked-by: Steve Twiss <stwiss.opensource@diasemi.com>
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
Diffstat (limited to 'drivers/watchdog')
-rw-r--r-- | drivers/watchdog/da9063_wdt.c | 32 |
1 files changed, 31 insertions, 1 deletions
diff --git a/drivers/watchdog/da9063_wdt.c b/drivers/watchdog/da9063_wdt.c index 2cd6b2c2dd2a..e2fe2ebdebd4 100644 --- a/drivers/watchdog/da9063_wdt.c +++ b/drivers/watchdog/da9063_wdt.c | |||
@@ -20,6 +20,7 @@ | |||
20 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
21 | #include <linux/mfd/da9063/registers.h> | 21 | #include <linux/mfd/da9063/registers.h> |
22 | #include <linux/mfd/da9063/core.h> | 22 | #include <linux/mfd/da9063/core.h> |
23 | #include <linux/reboot.h> | ||
23 | #include <linux/regmap.h> | 24 | #include <linux/regmap.h> |
24 | 25 | ||
25 | /* | 26 | /* |
@@ -38,6 +39,7 @@ static const unsigned int wdt_timeout[] = { 0, 2, 4, 8, 16, 32, 65, 131 }; | |||
38 | struct da9063_watchdog { | 39 | struct da9063_watchdog { |
39 | struct da9063 *da9063; | 40 | struct da9063 *da9063; |
40 | struct watchdog_device wdtdev; | 41 | struct watchdog_device wdtdev; |
42 | struct notifier_block restart_handler; | ||
41 | }; | 43 | }; |
42 | 44 | ||
43 | static unsigned int da9063_wdt_timeout_to_sel(unsigned int secs) | 45 | static unsigned int da9063_wdt_timeout_to_sel(unsigned int secs) |
@@ -119,6 +121,23 @@ static int da9063_wdt_set_timeout(struct watchdog_device *wdd, | |||
119 | return ret; | 121 | return ret; |
120 | } | 122 | } |
121 | 123 | ||
124 | static int da9063_wdt_restart_handler(struct notifier_block *this, | ||
125 | unsigned long mode, void *cmd) | ||
126 | { | ||
127 | struct da9063_watchdog *wdt = container_of(this, | ||
128 | struct da9063_watchdog, | ||
129 | restart_handler); | ||
130 | int ret; | ||
131 | |||
132 | ret = regmap_write(wdt->da9063->regmap, DA9063_REG_CONTROL_F, | ||
133 | DA9063_SHUTDOWN); | ||
134 | if (ret) | ||
135 | dev_alert(wdt->da9063->dev, "Failed to shutdown (err = %d)\n", | ||
136 | ret); | ||
137 | |||
138 | return NOTIFY_DONE; | ||
139 | } | ||
140 | |||
122 | static const struct watchdog_info da9063_watchdog_info = { | 141 | static const struct watchdog_info da9063_watchdog_info = { |
123 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, | 142 | .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, |
124 | .identity = "DA9063 Watchdog", | 143 | .identity = "DA9063 Watchdog", |
@@ -163,14 +182,25 @@ static int da9063_wdt_probe(struct platform_device *pdev) | |||
163 | dev_set_drvdata(&pdev->dev, wdt); | 182 | dev_set_drvdata(&pdev->dev, wdt); |
164 | 183 | ||
165 | ret = watchdog_register_device(&wdt->wdtdev); | 184 | ret = watchdog_register_device(&wdt->wdtdev); |
185 | if (ret) | ||
186 | return ret; | ||
166 | 187 | ||
167 | return ret; | 188 | wdt->restart_handler.notifier_call = da9063_wdt_restart_handler; |
189 | wdt->restart_handler.priority = 128; | ||
190 | ret = register_restart_handler(&wdt->restart_handler); | ||
191 | if (ret) | ||
192 | dev_err(wdt->da9063->dev, | ||
193 | "Failed to register restart handler (err = %d)\n", ret); | ||
194 | |||
195 | return 0; | ||
168 | } | 196 | } |
169 | 197 | ||
170 | static int da9063_wdt_remove(struct platform_device *pdev) | 198 | static int da9063_wdt_remove(struct platform_device *pdev) |
171 | { | 199 | { |
172 | struct da9063_watchdog *wdt = dev_get_drvdata(&pdev->dev); | 200 | struct da9063_watchdog *wdt = dev_get_drvdata(&pdev->dev); |
173 | 201 | ||
202 | unregister_restart_handler(&wdt->restart_handler); | ||
203 | |||
174 | watchdog_unregister_device(&wdt->wdtdev); | 204 | watchdog_unregister_device(&wdt->wdtdev); |
175 | 205 | ||
176 | return 0; | 206 | return 0; |