aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/watchdog
diff options
context:
space:
mode:
authorGeert Uytterhoeven <geert+renesas@glider.be>2015-01-29 09:26:05 -0500
committerWim Van Sebroeck <wim@iguana.be>2015-02-17 15:33:06 -0500
commit396f163ceba3ac2829e3076764efcfb10797293c (patch)
tree07987c80e4041c2265620db685081a44a78f4d12 /drivers/watchdog
parent9a4c88016458424e53084ed3c26bfbae8cd8af22 (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.c32
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 };
38struct da9063_watchdog { 39struct 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
43static unsigned int da9063_wdt_timeout_to_sel(unsigned int secs) 45static 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
124static 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
122static const struct watchdog_info da9063_watchdog_info = { 141static 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
170static int da9063_wdt_remove(struct platform_device *pdev) 198static 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;