From c676be488ba35fcfb89a297e036228784b51b70c Mon Sep 17 00:00:00 2001 From: Changki Kim Date: Fri, 3 Mar 2017 14:37:33 +0900 Subject: [PATCH] [COMMON] watchdog: s3c2410_wdt: Change device to syscore PM function Change-Id: Id3a35873afe3222f817ef56123b9cd8d6862df1d Signed-off-by: Changki Kim --- drivers/watchdog/s3c2410_wdt.c | 118 ++++++++++++++++++--------------- 1 file changed, 66 insertions(+), 52 deletions(-) diff --git a/drivers/watchdog/s3c2410_wdt.c b/drivers/watchdog/s3c2410_wdt.c index bb95a30352dd..dcd29dc8c27f 100644 --- a/drivers/watchdog/s3c2410_wdt.c +++ b/drivers/watchdog/s3c2410_wdt.c @@ -36,6 +36,7 @@ #include #include #include +#include #define S3C2410_WTCON 0x00 #define S3C2410_WTDAT 0x04 @@ -642,6 +643,70 @@ static struct notifier_block nb_panic_block = { }; #endif +#ifdef CONFIG_PM +static int s3c2410wdt_suspend(void) +{ + int ret = 0; + struct s3c2410_wdt *wdt = s3c_wdt; + + if (!wdt) + return ret; + + /* 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); + + /* Note that WTCNT doesn't need to be saved. */ + s3c2410wdt_stop(&wdt->wdt_device); + + ret = s3c2410wdt_mask_wdt_reset(wdt, true); + + return ret; +} + +static void s3c2410wdt_resume(void) +{ + int ret; + unsigned int val; + struct s3c2410_wdt *wdt = s3c_wdt; + + if (!wdt) + return; + + ret = s3c2410wdt_automatic_disable_wdt(wdt, false); + if (ret < 0) { + dev_info(wdt->dev, "automatic_dsiable fail"); + return; + } + + s3c2410wdt_stop_intclear(wdt); + /* Restore watchdog state. */ + writel(wdt->wtdat_save, wdt->reg_base + S3C2410_WTDAT); + writel(wdt->wtdat_save, wdt->reg_base + S3C2410_WTCNT);/* Reset count */ + writel(wdt->wtcon_save, wdt->reg_base + S3C2410_WTCON); + + ret = s3c2410wdt_mask_wdt_reset(wdt, false); + if (ret < 0) { + dev_info(wdt->dev, "wdt reset mask fail"); + return; + } + + val = readl(wdt->reg_base + S3C2410_WTCON); + dev_info(wdt->dev, "watchdog %sabled, con: 0x%08x, dat: 0x%08x, cnt: 0x%08x\n", + (val & S3C2410_WTCON_ENABLE) ? "en" : "dis", val, + readl(wdt->reg_base + S3C2410_WTDAT), + readl(wdt->reg_base + S3C2410_WTCNT)); +} +#else +#define s3c2410_wdt_suspend NULL +#define s3c2410_wdt_resume NULL +#endif + +static struct syscore_ops s3c2410wdt_syscore_ops = { + .suspend = s3c2410wdt_suspend, + .resume = s3c2410wdt_resume, +}; + static int s3c2410wdt_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; @@ -784,6 +849,7 @@ static int s3c2410wdt_probe(struct platform_device *pdev) wtcon = readl(wdt->reg_base + S3C2410_WTCON); + register_syscore_ops(&s3c2410wdt_syscore_ops); #ifdef CONFIG_EXYNOS_SNAPSHOT_WATCHDOG_RESET /* register panic handler for watchdog reset */ atomic_notifier_chain_register(&panic_notifier_list, &nb_panic_block); @@ -838,57 +904,6 @@ static void s3c2410wdt_shutdown(struct platform_device *dev) s3c2410wdt_stop(&wdt->wdt_device); } -#ifdef CONFIG_PM_SLEEP -static int s3c2410wdt_suspend(struct device *dev) -{ - 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); - - /* Note that WTCNT doesn't need to be saved. */ - s3c2410wdt_stop(&wdt->wdt_device); - - ret = s3c2410wdt_mask_wdt_reset(wdt, true); - - return ret; -} - -static int s3c2410wdt_resume(struct device *dev) -{ - int ret; - unsigned int val; - struct s3c2410_wdt *wdt = dev_get_drvdata(dev); - - ret = s3c2410wdt_automatic_disable_wdt(wdt, false); - if (ret < 0) - return ret; - - s3c2410wdt_stop_intclear(wdt); - /* Restore watchdog state. */ - writel(wdt->wtdat_save, wdt->reg_base + S3C2410_WTDAT); - writel(wdt->wtdat_save, wdt->reg_base + S3C2410_WTCNT);/* Reset count */ - writel(wdt->wtcon_save, wdt->reg_base + S3C2410_WTCON); - - ret = s3c2410wdt_mask_wdt_reset(wdt, false); - if (ret < 0) - return ret; - - val = readl(wdt->reg_base + S3C2410_WTCON); - dev_info(dev, "watchdog %sabled, con: 0x%08x, dat: 0x%08x, cnt: 0x%08x\n", - (val & S3C2410_WTCON_ENABLE) ? "en" : "dis", val, - readl(wdt->reg_base + S3C2410_WTDAT), - readl(wdt->reg_base + S3C2410_WTCNT)); - - return 0; -} -#endif - -static SIMPLE_DEV_PM_OPS(s3c2410wdt_pm_ops, s3c2410wdt_suspend, - s3c2410wdt_resume); - static struct platform_driver s3c2410wdt_driver = { .probe = s3c2410wdt_probe, .remove = s3c2410wdt_remove, @@ -896,7 +911,6 @@ static struct platform_driver s3c2410wdt_driver = { .id_table = s3c2410_wdt_ids, .driver = { .name = "s3c2410-wdt", - .pm = &s3c2410wdt_pm_ops, .of_match_table = of_match_ptr(s3c2410_wdt_match), }, }; -- 2.20.1