Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

authored by

Geert Uytterhoeven and committed by
Wim Van Sebroeck
396f163c 9a4c8801

+31 -1
+31 -1
drivers/watchdog/da9063_wdt.c
··· 20 20 #include <linux/delay.h> 21 21 #include <linux/mfd/da9063/registers.h> 22 22 #include <linux/mfd/da9063/core.h> 23 + #include <linux/reboot.h> 23 24 #include <linux/regmap.h> 24 25 25 26 /* ··· 39 38 struct da9063_watchdog { 40 39 struct da9063 *da9063; 41 40 struct watchdog_device wdtdev; 41 + struct notifier_block restart_handler; 42 42 }; 43 43 44 44 static unsigned int da9063_wdt_timeout_to_sel(unsigned int secs) ··· 121 119 return ret; 122 120 } 123 121 122 + static int da9063_wdt_restart_handler(struct notifier_block *this, 123 + unsigned long mode, void *cmd) 124 + { 125 + struct da9063_watchdog *wdt = container_of(this, 126 + struct da9063_watchdog, 127 + restart_handler); 128 + int ret; 129 + 130 + ret = regmap_write(wdt->da9063->regmap, DA9063_REG_CONTROL_F, 131 + DA9063_SHUTDOWN); 132 + if (ret) 133 + dev_alert(wdt->da9063->dev, "Failed to shutdown (err = %d)\n", 134 + ret); 135 + 136 + return NOTIFY_DONE; 137 + } 138 + 124 139 static const struct watchdog_info da9063_watchdog_info = { 125 140 .options = WDIOF_SETTIMEOUT | WDIOF_KEEPALIVEPING, 126 141 .identity = "DA9063 Watchdog", ··· 182 163 dev_set_drvdata(&pdev->dev, wdt); 183 164 184 165 ret = watchdog_register_device(&wdt->wdtdev); 166 + if (ret) 167 + return ret; 185 168 186 - return ret; 169 + wdt->restart_handler.notifier_call = da9063_wdt_restart_handler; 170 + wdt->restart_handler.priority = 128; 171 + ret = register_restart_handler(&wdt->restart_handler); 172 + if (ret) 173 + dev_err(wdt->da9063->dev, 174 + "Failed to register restart handler (err = %d)\n", ret); 175 + 176 + return 0; 187 177 } 188 178 189 179 static int da9063_wdt_remove(struct platform_device *pdev) 190 180 { 191 181 struct da9063_watchdog *wdt = dev_get_drvdata(&pdev->dev); 182 + 183 + unregister_restart_handler(&wdt->restart_handler); 192 184 193 185 watchdog_unregister_device(&wdt->wdtdev); 194 186