watchdog: rti_wdt: Drop runtime pm reference count when watchdog is unused
[ Upstream commit c1a6edf3b541e44e78f10bc6024df779715723f1 ]
Call runtime_pm_put*() if watchdog is not already started during probe and re
enable it in watchdog start as required.
On K3 SoCs, watchdogs and their corresponding CPUs are under same
power-domain, so if the reference count of unused watchdogs aren't
dropped, it will lead to CPU hotplug failures as Device Management
firmware won't allow to turn off the power-domain due to dangling
reference count.
Fixes: 2d63908bdb
("watchdog: Add K3 RTI watchdog support")
Signed-off-by: Vignesh Raghavendra <vigneshr@ti.com>
Tested-by: Manorit Chawdhry <m-chawdhry@ti.com>
Reviewed-by: Guenter Roeck <linux@roeck-us.net>
Link: https://lore.kernel.org/r/20231213140110.938129-1-vigneshr@ti.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Wim Van Sebroeck <wim@linux-watchdog.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
6317445623
commit
24961a5dc7
@ -70,6 +70,11 @@ static int rti_wdt_start(struct watchdog_device *wdd)
|
||||
{
|
||||
u32 timer_margin;
|
||||
struct rti_wdt_device *wdt = watchdog_get_drvdata(wdd);
|
||||
int ret;
|
||||
|
||||
ret = pm_runtime_resume_and_get(wdd->parent);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* set timeout period */
|
||||
timer_margin = (u64)wdd->timeout * wdt->freq;
|
||||
@ -295,6 +300,9 @@ static int rti_wdt_probe(struct platform_device *pdev)
|
||||
if (last_ping)
|
||||
watchdog_set_last_hw_keepalive(wdd, last_ping);
|
||||
|
||||
if (!watchdog_hw_running(wdd))
|
||||
pm_runtime_put_sync(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
|
||||
err_iomap:
|
||||
@ -309,7 +317,10 @@ static int rti_wdt_remove(struct platform_device *pdev)
|
||||
struct rti_wdt_device *wdt = platform_get_drvdata(pdev);
|
||||
|
||||
watchdog_unregister_device(&wdt->wdd);
|
||||
pm_runtime_put(&pdev->dev);
|
||||
|
||||
if (!pm_runtime_suspended(&pdev->dev))
|
||||
pm_runtime_put(&pdev->dev);
|
||||
|
||||
pm_runtime_disable(&pdev->dev);
|
||||
|
||||
return 0;
|
||||
|
Loading…
Reference in New Issue
Block a user