[PATCHv2] watchdog: imx2_wdt: add restart handler support

Jingchang Lu jingchang.lu at freescale.com
Wed Sep 17 00:40:01 PDT 2014


Hi, Guenter,

  Could you please help review this v2 patch, Thanks.

Best Regards,
Jingchang

>-----Original Message-----
>From: Jingchang Lu [mailto:jingchang.lu at freescale.com]
>Sent: Friday, September 12, 2014 3:25 PM
>To: wim at iguana.be
>Cc: Guo Shawn-R65073; arnd at arndb.de; linux at roeck-us.net; linux-
>watchdog at vger.kernel.org; linux-arm-kernel at lists.infradead.org; Lu
>Jingchang-B35083
>Subject: [PATCHv2] watchdog: imx2_wdt: add restart handler support
>
>  Register the watchdog as the system restart function
>to the new introducing kernel restart call chain in the
>driver instead of providing the restart in machine desc.
>  This restart handler function is from the mxc_restart()
>in arch/arm/mach-imx/system.c
>
>Signed-off-by: Jingchang Lu <jingchang.lu at freescale.com>
>---
> drivers/watchdog/imx2_wdt.c | 37 +++++++++++++++++++++++++++++++++++++
> 1 file changed, 37 insertions(+)
>
>diff --git a/drivers/watchdog/imx2_wdt.c b/drivers/watchdog/imx2_wdt.c
>index 68c3d37..d32470e 100644
>--- a/drivers/watchdog/imx2_wdt.c
>+++ b/drivers/watchdog/imx2_wdt.c
>@@ -22,14 +22,17 @@
>  */
>
> #include <linux/clk.h>
>+#include <linux/delay.h>
> #include <linux/init.h>
> #include <linux/io.h>
> #include <linux/jiffies.h>
> #include <linux/kernel.h>
> #include <linux/module.h>
> #include <linux/moduleparam.h>
>+#include <linux/notifier.h>
> #include <linux/of_address.h>
> #include <linux/platform_device.h>
>+#include <linux/reboot.h>
> #include <linux/regmap.h>
> #include <linux/timer.h>
> #include <linux/watchdog.h>
>@@ -59,6 +62,7 @@ struct imx2_wdt_device {
> 	struct regmap *regmap;
> 	struct timer_list timer;	/* Pings the watchdog when closed */
> 	struct watchdog_device wdog;
>+	struct notifier_block restart_handler;
> };
>
> static bool nowayout = WATCHDOG_NOWAYOUT;
>@@ -77,6 +81,31 @@ static const struct watchdog_info imx2_wdt_info = {
> 	.options = WDIOF_KEEPALIVEPING | WDIOF_SETTIMEOUT | WDIOF_MAGICCLOSE,
> };
>
>+static int imx2_restart_handler(struct notifier_block *this, unsigned
>long mode,
>+				void *cmd)
>+{
>+	unsigned int wcr_enable = IMX2_WDT_WCR_WDE;
>+	struct imx2_wdt_device *wdev = container_of(this,
>+						    struct imx2_wdt_device,
>+						    restart_handler);
>+	/* Assert SRS signal */
>+	regmap_write(wdev->regmap, 0, wcr_enable);
>+	/*
>+	 * Due to imx6q errata ERR004346 (WDOG: WDOG SRS bit requires to be
>+	 * written twice), we add another two writes to ensure there must be
>at
>+	 * least two writes happen in the same one 32kHz clock period.  We
>save
>+	 * the target check here, since the writes shouldn't be a huge
>burden
>+	 * for other platforms.
>+	 */
>+	regmap_write(wdev->regmap, 0, wcr_enable);
>+	regmap_write(wdev->regmap, 0, wcr_enable);
>+
>+	/* wait for reset to assert... */
>+	mdelay(500);
>+
>+	return NOTIFY_DONE;
>+}
>+
> static inline void imx2_wdt_setup(struct watchdog_device *wdog)
> {
> 	struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
>@@ -257,6 +286,12 @@ static int __init imx2_wdt_probe(struct
>platform_device *pdev)
> 		return ret;
> 	}
>
>+	wdev->restart_handler.notifier_call = imx2_restart_handler;
>+	wdev->restart_handler.priority = 128;
>+	ret = register_restart_handler(&wdev->restart_handler);
>+	if (ret)
>+		dev_err(&pdev->dev, "cannot register restart handler\n");
>+
> 	dev_info(&pdev->dev, "timeout %d sec (nowayout=%d)\n",
> 		 wdog->timeout, nowayout);
>
>@@ -268,6 +303,8 @@ static int __exit imx2_wdt_remove(struct
>platform_device *pdev)
> 	struct watchdog_device *wdog = platform_get_drvdata(pdev);
> 	struct imx2_wdt_device *wdev = watchdog_get_drvdata(wdog);
>
>+	unregister_restart_handler(&wdev->restart_handler);
>+
> 	watchdog_unregister_device(wdog);
>
> 	if (imx2_wdt_is_running(wdev)) {
>--
>1.8.0



More information about the linux-arm-kernel mailing list