diff options
| -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 @@  #include <linux/delay.h>  #include <linux/mfd/da9063/registers.h>  #include <linux/mfd/da9063/core.h> +#include <linux/reboot.h>  #include <linux/regmap.h>  /* @@ -38,6 +39,7 @@ static const unsigned int wdt_timeout[] = { 0, 2, 4, 8, 16, 32, 65, 131 };  struct da9063_watchdog {  	struct da9063 *da9063;  	struct watchdog_device wdtdev; +	struct notifier_block restart_handler;  };  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,  	return ret;  } +static int da9063_wdt_restart_handler(struct notifier_block *this, +				      unsigned long mode, void *cmd) +{ +	struct da9063_watchdog *wdt = container_of(this, +						   struct da9063_watchdog, +						   restart_handler); +	int ret; + +	ret = regmap_write(wdt->da9063->regmap, DA9063_REG_CONTROL_F, +			   DA9063_SHUTDOWN); +	if (ret) +		dev_alert(wdt->da9063->dev, "Failed to shutdown (err = %d)\n", +			  ret); + +	return NOTIFY_DONE; +} +  static const struct watchdog_info da9063_watchdog_info = {  	.options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING,  	.identity = "DA9063 Watchdog", @@ -163,14 +182,25 @@ static int da9063_wdt_probe(struct platform_device *pdev)  	dev_set_drvdata(&pdev->dev, wdt);  	ret = watchdog_register_device(&wdt->wdtdev); +	if (ret) +		return ret; -	return ret; +	wdt->restart_handler.notifier_call = da9063_wdt_restart_handler; +	wdt->restart_handler.priority = 128; +	ret = register_restart_handler(&wdt->restart_handler); +	if (ret) +		dev_err(wdt->da9063->dev, +			"Failed to register restart handler (err = %d)\n", ret); + +	return 0;  }  static int da9063_wdt_remove(struct platform_device *pdev)  {  	struct da9063_watchdog *wdt = dev_get_drvdata(&pdev->dev); +	unregister_restart_handler(&wdt->restart_handler); +  	watchdog_unregister_device(&wdt->wdtdev);  	return 0; | 
