aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/watchdog/alim7101_wdt.c42
1 files changed, 32 insertions, 10 deletions
diff --git a/drivers/watchdog/alim7101_wdt.c b/drivers/watchdog/alim7101_wdt.c
index 996b2f7d330e..665e0e7dfe1e 100644
--- a/drivers/watchdog/alim7101_wdt.c
+++ b/drivers/watchdog/alim7101_wdt.c
@@ -301,6 +301,28 @@ static struct miscdevice wdt_miscdev = {
301 .fops = &wdt_fops, 301 .fops = &wdt_fops,
302}; 302};
303 303
304static int wdt_restart_handle(struct notifier_block *this, unsigned long mode,
305 void *cmd)
306{
307 /*
308 * Cobalt devices have no way of rebooting themselves other
309 * than getting the watchdog to pull reset, so we restart the
310 * watchdog on reboot with no heartbeat.
311 */
312 wdt_change(WDT_ENABLE);
313
314 /* loop until the watchdog fires */
315 while (true)
316 ;
317
318 return NOTIFY_DONE;
319}
320
321static struct notifier_block wdt_restart_handler = {
322 .notifier_call = wdt_restart_handle,
323 .priority = 128,
324};
325
304/* 326/*
305 * Notifier for system down 327 * Notifier for system down
306 */ 328 */
@@ -311,15 +333,6 @@ static int wdt_notify_sys(struct notifier_block *this,
311 if (code == SYS_DOWN || code == SYS_HALT) 333 if (code == SYS_DOWN || code == SYS_HALT)
312 wdt_turnoff(); 334 wdt_turnoff();
313 335
314 if (code == SYS_RESTART) {
315 /*
316 * Cobalt devices have no way of rebooting themselves other
317 * than getting the watchdog to pull reset, so we restart the
318 * watchdog on reboot with no heartbeat
319 */
320 wdt_change(WDT_ENABLE);
321 pr_info("Watchdog timer is now enabled with no heartbeat - should reboot in ~1 second\n");
322 }
323 return NOTIFY_DONE; 336 return NOTIFY_DONE;
324} 337}
325 338
@@ -338,6 +351,7 @@ static void __exit alim7101_wdt_unload(void)
338 /* Deregister */ 351 /* Deregister */
339 misc_deregister(&wdt_miscdev); 352 misc_deregister(&wdt_miscdev);
340 unregister_reboot_notifier(&wdt_notifier); 353 unregister_reboot_notifier(&wdt_notifier);
354 unregister_restart_handler(&wdt_restart_handler);
341 pci_dev_put(alim7101_pmu); 355 pci_dev_put(alim7101_pmu);
342} 356}
343 357
@@ -390,11 +404,17 @@ static int __init alim7101_wdt_init(void)
390 goto err_out; 404 goto err_out;
391 } 405 }
392 406
407 rc = register_restart_handler(&wdt_restart_handler);
408 if (rc) {
409 pr_err("cannot register restart handler (err=%d)\n", rc);
410 goto err_out_reboot;
411 }
412
393 rc = misc_register(&wdt_miscdev); 413 rc = misc_register(&wdt_miscdev);
394 if (rc) { 414 if (rc) {
395 pr_err("cannot register miscdev on minor=%d (err=%d)\n", 415 pr_err("cannot register miscdev on minor=%d (err=%d)\n",
396 wdt_miscdev.minor, rc); 416 wdt_miscdev.minor, rc);
397 goto err_out_reboot; 417 goto err_out_restart;
398 } 418 }
399 419
400 if (nowayout) 420 if (nowayout)
@@ -404,6 +424,8 @@ static int __init alim7101_wdt_init(void)
404 timeout, nowayout); 424 timeout, nowayout);
405 return 0; 425 return 0;
406 426
427err_out_restart:
428 unregister_restart_handler(&wdt_restart_handler);
407err_out_reboot: 429err_out_reboot:
408 unregister_reboot_notifier(&wdt_notifier); 430 unregister_reboot_notifier(&wdt_notifier);
409err_out: 431err_out: