diff options
Diffstat (limited to 'drivers/watchdog/starfive-wdt.c')
| -rw-r--r-- | drivers/watchdog/starfive-wdt.c | 41 |
1 files changed, 25 insertions, 16 deletions
diff --git a/drivers/watchdog/starfive-wdt.c b/drivers/watchdog/starfive-wdt.c index 8058fca4d05d..ed71d3960a0f 100644 --- a/drivers/watchdog/starfive-wdt.c +++ b/drivers/watchdog/starfive-wdt.c @@ -8,7 +8,8 @@ #include <linux/clk.h> #include <linux/iopoll.h> #include <linux/module.h> -#include <linux/of_device.h> +#include <linux/of.h> +#include <linux/platform_device.h> #include <linux/pm_runtime.h> #include <linux/reset.h> #include <linux/watchdog.h> @@ -79,7 +80,7 @@ MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); struct starfive_wdt_variant { - unsigned int control; /* Watchdog Control Resgister for reset enable */ + unsigned int control; /* Watchdog Control Register for reset enable */ unsigned int load; /* Watchdog Load register */ unsigned int reload; /* Watchdog Reload Control register */ unsigned int enable; /* Watchdog Enable Register */ @@ -151,8 +152,10 @@ static int starfive_wdt_enable_clock(struct starfive_wdt *wdt) return dev_err_probe(wdt->wdd.parent, ret, "failed to enable apb clock\n"); ret = clk_prepare_enable(wdt->core_clk); - if (ret) + if (ret) { + clk_disable_unprepare(wdt->apb_clk); return dev_err_probe(wdt->wdd.parent, ret, "failed to enable core clock\n"); + } return 0; } @@ -201,12 +204,14 @@ static u32 starfive_wdt_ticks_to_sec(struct starfive_wdt *wdt, u32 ticks) /* Write unlock-key to unlock. Write other value to lock. */ static void starfive_wdt_unlock(struct starfive_wdt *wdt) + __acquires(&wdt->lock) { spin_lock(&wdt->lock); writel(wdt->variant->unlock_key, wdt->base + wdt->variant->unlock); } static void starfive_wdt_lock(struct starfive_wdt *wdt) + __releases(&wdt->lock) { writel(~wdt->variant->unlock_key, wdt->base + wdt->variant->unlock); spin_unlock(&wdt->lock); @@ -491,11 +496,18 @@ static int starfive_wdt_probe(struct platform_device *pdev) if (ret) goto err_exit; - if (!early_enable) - pm_runtime_put_sync(&pdev->dev); + if (!early_enable) { + if (pm_runtime_enabled(&pdev->dev)) { + ret = pm_runtime_put_sync(&pdev->dev); + if (ret) + goto err_unregister_wdt; + } + } return 0; +err_unregister_wdt: + watchdog_unregister_device(&wdt->wdd); err_exit: starfive_wdt_disable_clock(wdt); pm_runtime_disable(&pdev->dev); @@ -503,7 +515,7 @@ err_exit: return ret; } -static int starfive_wdt_remove(struct platform_device *pdev) +static void starfive_wdt_remove(struct platform_device *pdev) { struct starfive_wdt *wdt = platform_get_drvdata(pdev); @@ -515,8 +527,6 @@ static int starfive_wdt_remove(struct platform_device *pdev) else /* disable clock without PM */ starfive_wdt_disable_clock(wdt); - - return 0; } static void starfive_wdt_shutdown(struct platform_device *pdev) @@ -526,7 +536,6 @@ static void starfive_wdt_shutdown(struct platform_device *pdev) starfive_wdt_pm_stop(&wdt->wdd); } -#ifdef CONFIG_PM_SLEEP static int starfive_wdt_suspend(struct device *dev) { struct starfive_wdt *wdt = dev_get_drvdata(dev); @@ -554,11 +563,12 @@ static int starfive_wdt_resume(struct device *dev) starfive_wdt_set_reload_count(wdt, wdt->reload); starfive_wdt_lock(wdt); - return starfive_wdt_start(wdt); + if (watchdog_active(&wdt->wdd)) + return starfive_wdt_start(wdt); + + return 0; } -#endif /* CONFIG_PM_SLEEP */ -#ifdef CONFIG_PM static int starfive_wdt_runtime_suspend(struct device *dev) { struct starfive_wdt *wdt = dev_get_drvdata(dev); @@ -574,11 +584,10 @@ static int starfive_wdt_runtime_resume(struct device *dev) return starfive_wdt_enable_clock(wdt); } -#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) - SET_SYSTEM_SLEEP_PM_OPS(starfive_wdt_suspend, starfive_wdt_resume) + RUNTIME_PM_OPS(starfive_wdt_runtime_suspend, starfive_wdt_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(starfive_wdt_suspend, starfive_wdt_resume) }; static const struct of_device_id starfive_wdt_match[] = { @@ -594,7 +603,7 @@ static struct platform_driver starfive_wdt_driver = { .shutdown = starfive_wdt_shutdown, .driver = { .name = "starfive-wdt", - .pm = &starfive_wdt_pm_ops, + .pm = pm_ptr(&starfive_wdt_pm_ops), .of_match_table = starfive_wdt_match, }, }; |
