From 87d8c65087fa017a6e9f684b2c786e194ef37214 Mon Sep 17 00:00:00 2001 From: Hyunki Koo Date: Thu, 26 Dec 2013 16:31:40 +0900 Subject: [PATCH] watchdog: s3c2410_wdt: add wdt_stop_intclear function In 4.9 kernel porting, I excluded the 8289222f1db85a6b0af0387e21ceb2f6e5d5a5d4 patch. There is already a related patch, 882dec1ff125e9020157d27672ec11c2fdfb82c2. In this Patch, I removed all functions and variables associated with the 8289222f1.. patch. Sometimes watchdog interrupt is pended in booting time before initialize watchdog timer. In this case system can be reboot from thi interrupt. This patch clear watchdog interrupt before watchdog reset enable to ignore interrupt in booting time. And code is move after wdt clock initialize. Change-Id: I2900ae733f9b24c8c4a84ef030be29cb06f19727 Signed-off-by: Hyunki Koo Signed-off-by: Hosung Kim Signed-off-by: Changki Kim Signed-off-by: Choi Jaehyoung --- drivers/watchdog/s3c2410_wdt.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c index adaa43543f0a..7841da48ace1 100644 --- a/drivers/watchdog/s3c2410_wdt.c +++ b/drivers/watchdog/s3c2410_wdt.c @@ -43,6 +43,7 @@ #define S3C2410_WTCLRINT 0x0c #define S3C2410_WTCNT_MAXCNT 0xffff +#define S3C2410_WTCLRINT 0x0C #define S3C2410_WTCON_RSTEN (1 << 0) #define S3C2410_WTCON_INTEN (1 << 2) @@ -269,6 +270,16 @@ static int s3c2410wdt_stop(struct watchdog_device *wdd) return 0; } +static int s3c2410wdt_stop_intclear(struct s3c2410_wdt *wdt) +{ + spin_lock(&wdt->lock); + __s3c2410wdt_stop(wdt); + writel(1, wdt->reg_base + S3C2410_WTCLRINT); + spin_unlock(&wdt->lock); + + return 0; +} + static int s3c2410wdt_start(struct watchdog_device *wdd) { unsigned long wtcon; @@ -621,7 +632,9 @@ static int s3c2410wdt_probe(struct platform_device *pdev) dev_err(dev, "cannot register watchdog (%d)\n", ret); goto err_cpufreq; } - + /* Prevent watchdog reset while setting */ + s3c2410wdt_stop_intclear(wdt); + /* Enable pmu watchdog reset control */ ret = s3c2410wdt_mask_and_disable_reset(wdt, false); if (ret < 0) goto err_unregister; @@ -691,24 +704,21 @@ static void s3c2410wdt_shutdown(struct platform_device *dev) } #ifdef CONFIG_PM_SLEEP - static int s3c2410wdt_suspend(struct device *dev) { - int ret; + int ret = 0; struct s3c2410_wdt *wdt = dev_get_drvdata(dev); /* Save watchdog state, and turn it off. */ wdt->wtcon_save = readl(wdt->reg_base + S3C2410_WTCON); wdt->wtdat_save = readl(wdt->reg_base + S3C2410_WTDAT); - ret = s3c2410wdt_mask_and_disable_reset(wdt, true); - if (ret < 0) - return ret; - /* Note that WTCNT doesn't need to be saved. */ s3c2410wdt_stop(&wdt->wdt_device); - return 0; + ret = s3c2410wdt_mask_and_disable_reset(wdt, true); + + return ret; } static int s3c2410wdt_resume(struct device *dev) @@ -721,6 +731,8 @@ static int s3c2410wdt_resume(struct device *dev) writel(wdt->wtdat_save, wdt->reg_base + S3C2410_WTCNT);/* Reset count */ writel(wdt->wtcon_save, wdt->reg_base + S3C2410_WTCON); + s3c2410wdt_stop_intclear(wdt); + /* Enable pmu watchdog reset control */ ret = s3c2410wdt_mask_and_disable_reset(wdt, false); if (ret < 0) return ret; -- 2.20.1