diff options
author | Andrew Bresticker <abrestic@chromium.org> | 2015-04-03 13:05:22 -0400 |
---|---|---|
committer | Wim Van Sebroeck <wim@iguana.be> | 2015-06-22 09:54:14 -0400 |
commit | c631f20068369a8b901574df9c7bfc57ce13de75 (patch) | |
tree | dfd20ca844fdb97eb3a00b61d011e0898aa21187 | |
parent | 8aa453a533faf383fe711aa8dedcf421563ddf66 (diff) |
watchdog: imgpdc: Add reboot support
Register a restart handler that will restart the system by writing
to the watchdog's SOFT_RESET register.
Signed-off-by: Andrew Bresticker <abrestic@chromium.org>
Reviewed-by: Ezequiel Garcia <ezequiel.garcia@imgtec.com>
Tested-by: Ezequiel Garcia <ezequiel.garcia@imgtec.com>
Cc: James Hogan <james.hogan@imgtec.com>
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Wim Van Sebroeck <wim@iguana.be>
-rw-r--r-- | drivers/watchdog/imgpdc_wdt.c | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/drivers/watchdog/imgpdc_wdt.c b/drivers/watchdog/imgpdc_wdt.c index ffeb1bf85252..28c10e292aa3 100644 --- a/drivers/watchdog/imgpdc_wdt.c +++ b/drivers/watchdog/imgpdc_wdt.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/log2.h> | 16 | #include <linux/log2.h> |
17 | #include <linux/module.h> | 17 | #include <linux/module.h> |
18 | #include <linux/platform_device.h> | 18 | #include <linux/platform_device.h> |
19 | #include <linux/reboot.h> | ||
19 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
20 | #include <linux/watchdog.h> | 21 | #include <linux/watchdog.h> |
21 | 22 | ||
@@ -57,6 +58,7 @@ struct pdc_wdt_dev { | |||
57 | struct clk *wdt_clk; | 58 | struct clk *wdt_clk; |
58 | struct clk *sys_clk; | 59 | struct clk *sys_clk; |
59 | void __iomem *base; | 60 | void __iomem *base; |
61 | struct notifier_block restart_handler; | ||
60 | }; | 62 | }; |
61 | 63 | ||
62 | static int pdc_wdt_keepalive(struct watchdog_device *wdt_dev) | 64 | static int pdc_wdt_keepalive(struct watchdog_device *wdt_dev) |
@@ -136,6 +138,18 @@ static const struct watchdog_ops pdc_wdt_ops = { | |||
136 | .set_timeout = pdc_wdt_set_timeout, | 138 | .set_timeout = pdc_wdt_set_timeout, |
137 | }; | 139 | }; |
138 | 140 | ||
141 | static int pdc_wdt_restart(struct notifier_block *this, unsigned long mode, | ||
142 | void *cmd) | ||
143 | { | ||
144 | struct pdc_wdt_dev *wdt = container_of(this, struct pdc_wdt_dev, | ||
145 | restart_handler); | ||
146 | |||
147 | /* Assert SOFT_RESET */ | ||
148 | writel(0x1, wdt->base + PDC_WDT_SOFT_RESET); | ||
149 | |||
150 | return NOTIFY_OK; | ||
151 | } | ||
152 | |||
139 | static int pdc_wdt_probe(struct platform_device *pdev) | 153 | static int pdc_wdt_probe(struct platform_device *pdev) |
140 | { | 154 | { |
141 | int ret, val; | 155 | int ret, val; |
@@ -242,6 +256,13 @@ static int pdc_wdt_probe(struct platform_device *pdev) | |||
242 | if (ret) | 256 | if (ret) |
243 | goto disable_wdt_clk; | 257 | goto disable_wdt_clk; |
244 | 258 | ||
259 | pdc_wdt->restart_handler.notifier_call = pdc_wdt_restart; | ||
260 | pdc_wdt->restart_handler.priority = 128; | ||
261 | ret = register_restart_handler(&pdc_wdt->restart_handler); | ||
262 | if (ret) | ||
263 | dev_warn(&pdev->dev, "failed to register restart handler: %d\n", | ||
264 | ret); | ||
265 | |||
245 | return 0; | 266 | return 0; |
246 | 267 | ||
247 | disable_wdt_clk: | 268 | disable_wdt_clk: |