watchdog: s3c2410_wdt: add wdt_stop_intclear function
authorHyunki Koo <hyunki00.koo@samsung.com>
Thu, 26 Dec 2013 07:31:40 +0000 (16:31 +0900)
committerJaehyoung Choi <jkkkkk.choi@samsung.com>
Wed, 9 May 2018 11:27:46 +0000 (20:27 +0900)
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 <hyunki00.koo@samsung.com>
Signed-off-by: Hosung Kim <hosung0.kim@samsung.com>
Signed-off-by: Changki Kim <changki.kim@samsung.com>
Signed-off-by: Choi Jaehyoung <jkkkkk.choi@samsung.com>
drivers/watchdog/s3c2410_wdt.c

index adaa43543f0a7c2591ea0bf472926aa367567fa0..7841da48ace1c300dcc38cfa0cad1634fd70267d 100644 (file)
@@ -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;