diff options
author | Ziv.Xu <Ziv.Xu@starfivetech.com> | 2022-10-08 10:02:15 +0300 |
---|---|---|
committer | mason.huo <mason.huo@starfivetech.com> | 2022-10-27 08:56:12 +0300 |
commit | 52149fbd1ebe094c556befff2f57f6f87690dc5a (patch) | |
tree | 070478581211d7d6f14eefd0694003d8eddb2bff | |
parent | 7f10362dfcf51fe7018d9b0b26db8d9b0baf7e39 (diff) | |
download | linux-52149fbd1ebe094c556befff2f57f6f87690dc5a.tar.xz |
add runtime pm for watchdog
add runtime pm for watchdog
Signed-off-by: Ziv.Xu <Ziv.Xu@starfivetech.com>
-rwxr-xr-x | drivers/watchdog/starfive-wdt.c | 47 |
1 files changed, 44 insertions, 3 deletions
diff --git a/drivers/watchdog/starfive-wdt.c b/drivers/watchdog/starfive-wdt.c index 70588a5cbb87..22d5dfc6a7e5 100755 --- a/drivers/watchdog/starfive-wdt.c +++ b/drivers/watchdog/starfive-wdt.c @@ -31,6 +31,7 @@ #include <linux/watchdog.h> #include <linux/reset.h> #include <linux/reset-controller.h> +#include <linux/pm_runtime.h> #define WDT_INT_DIS BIT(0) #define DELAY_US 0 @@ -500,6 +501,8 @@ static int starfive_wdt_stop(struct watchdog_device *wdd) spin_unlock(&wdt->lock); + pm_runtime_put(wdt->dev); + return 0; } @@ -507,6 +510,8 @@ static int starfive_wdt_start(struct watchdog_device *wdd) { struct starfive_wdt *wdt = watchdog_get_drvdata(wdd); + pm_runtime_get_sync(wdt->dev); + spin_lock(&wdt->lock); starfive_wdt_unlock(wdt); @@ -642,6 +647,8 @@ static int starfive_wdt_probe(struct platform_device *pdev) int started = 0; int ret; + pm_runtime_enable(dev); + wdt = devm_kzalloc(dev, sizeof(*wdt), GFP_KERNEL); if (!wdt) return -ENOMEM; @@ -728,9 +735,13 @@ static int starfive_wdt_probe(struct platform_device *pdev) * disabled if it has been left running from the bootloader * or other source. */ + pm_runtime_get_noresume(dev); starfive_wdt_stop(&wdt->wdt_device); } + clk_disable_unprepare(wdt->core_clk); + clk_disable_unprepare(wdt->apb_clk); + platform_set_drvdata(pdev, wdt); return 0; @@ -754,6 +765,7 @@ static int starfive_wdt_remove(struct platform_device *dev) watchdog_unregister_device(&wdt->wdt_device); clk_disable_unprepare(wdt->core_clk); + pm_runtime_disable(wdt->dev); return 0; } @@ -765,7 +777,6 @@ static void starfive_wdt_shutdown(struct platform_device *dev) starfive_wdt_mask_and_disable_reset(wdt, true); starfive_wdt_stop(&wdt->wdt_device); - } #ifdef CONFIG_PM_SLEEP @@ -815,8 +826,33 @@ static int starfive_wdt_resume(struct device *dev) } #endif /* CONFIG_PM_SLEEP */ -static SIMPLE_DEV_PM_OPS(starfive_wdt_pm_ops, starfive_wdt_suspend, - starfive_wdt_resume); +#ifdef CONFIG_PM + +static int starfive_wdt_runtime_suspend(struct device *dev) +{ + struct starfive_wdt *wdt = dev_get_drvdata(dev); + + clk_disable_unprepare(wdt->apb_clk); + clk_disable_unprepare(wdt->core_clk); + + return 0; +} + +static int starfive_wdt_runtime_resume(struct device *dev) +{ + struct starfive_wdt *wdt = dev_get_drvdata(dev); + + clk_prepare_enable(wdt->apb_clk); + clk_prepare_enable(wdt->core_clk); + + return 0; +} + +#endif /*CONFIG_PM*/ + +static const struct dev_pm_ops starfive_wdt_pm_ops = { + SET_RUNTIME_PM_OPS(starfive_wdt_runtime_suspend, starfive_wdt_runtime_resume, NULL) +}; static struct platform_driver starfive_starfive_wdt_driver = { .probe = starfive_wdt_probe, @@ -825,6 +861,11 @@ static struct platform_driver starfive_starfive_wdt_driver = { .id_table = starfive_wdt_ids, .driver = { .name = "starfive-wdt", +#if 1 + /* Currently wdt suspend & resume will cause system reboot. + * Comment the pm operation for now, will add it back once + * the feature is ready. + */ .pm = &starfive_wdt_pm_ops, .of_match_table = of_match_ptr(starfive_wdt_match), }, |