Skip to content

Commit d098913

Browse files
committed
bus: ti-sysc: Fix clock handling for no-idle quirks
NFSroot can fail on dra7 when cpsw is probed using ti-sysc interconnect target module driver as reported by Keerthy. Device clocks and the interconnect target module may or may not be enabled by the bootloader on init, but we currently assume the clocks and module are on from the bootloader for "ti,no-idle" and "ti,no-idle-on-init" quirks as reported by Grygorii Strashko. Let's fix the issue by always enabling clocks init, and never disable them for "ti,no-idle" quirk. For "ti,no-idle-on-init" quirk, we must decrement the usage count later on to allow PM runtime to idle the module if requested. Fixes: 1a5cd7c ("bus: ti-sysc: Enable all clocks directly during init to read revision") Cc: Keerthy <[email protected]> Cc: Vignesh Raghavendra <[email protected]> Reported-by: Keerthy <[email protected]> Reported-by: Grygorii Strashko <[email protected]> Reviewed-by: Grygorii Strashko <[email protected]> Signed-off-by: Tony Lindgren <[email protected]>
1 parent 4a65bbb commit d098913

File tree

1 file changed

+37
-11
lines changed

1 file changed

+37
-11
lines changed

drivers/bus/ti-sysc.c

Lines changed: 37 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1630,17 +1630,19 @@ static int sysc_init_module(struct sysc *ddata)
16301630
if (error)
16311631
return error;
16321632

1633-
if (manage_clocks) {
1634-
sysc_clkdm_deny_idle(ddata);
1633+
sysc_clkdm_deny_idle(ddata);
16351634

1636-
error = sysc_enable_opt_clocks(ddata);
1637-
if (error)
1638-
return error;
1635+
/*
1636+
* Always enable clocks. The bootloader may or may not have enabled
1637+
* the related clocks.
1638+
*/
1639+
error = sysc_enable_opt_clocks(ddata);
1640+
if (error)
1641+
return error;
16391642

1640-
error = sysc_enable_main_clocks(ddata);
1641-
if (error)
1642-
goto err_opt_clocks;
1643-
}
1643+
error = sysc_enable_main_clocks(ddata);
1644+
if (error)
1645+
goto err_opt_clocks;
16441646

16451647
if (!(ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT)) {
16461648
error = sysc_rstctrl_reset_deassert(ddata, true);
@@ -1658,7 +1660,7 @@ static int sysc_init_module(struct sysc *ddata)
16581660
goto err_main_clocks;
16591661
}
16601662

1661-
if (!ddata->legacy_mode && manage_clocks) {
1663+
if (!ddata->legacy_mode) {
16621664
error = sysc_enable_module(ddata->dev);
16631665
if (error)
16641666
goto err_main_clocks;
@@ -1675,6 +1677,7 @@ static int sysc_init_module(struct sysc *ddata)
16751677
if (manage_clocks)
16761678
sysc_disable_main_clocks(ddata);
16771679
err_opt_clocks:
1680+
/* No re-enable of clockdomain autoidle to prevent module autoidle */
16781681
if (manage_clocks) {
16791682
sysc_disable_opt_clocks(ddata);
16801683
sysc_clkdm_allow_idle(ddata);
@@ -2355,6 +2358,28 @@ static void ti_sysc_idle(struct work_struct *work)
23552358

23562359
ddata = container_of(work, struct sysc, idle_work.work);
23572360

2361+
/*
2362+
* One time decrement of clock usage counts if left on from init.
2363+
* Note that we disable opt clocks unconditionally in this case
2364+
* as they are enabled unconditionally during init without
2365+
* considering sysc_opt_clks_needed() at that point.
2366+
*/
2367+
if (ddata->cfg.quirks & (SYSC_QUIRK_NO_IDLE |
2368+
SYSC_QUIRK_NO_IDLE_ON_INIT)) {
2369+
sysc_clkdm_deny_idle(ddata);
2370+
sysc_disable_main_clocks(ddata);
2371+
sysc_disable_opt_clocks(ddata);
2372+
sysc_clkdm_allow_idle(ddata);
2373+
}
2374+
2375+
/* Keep permanent PM runtime usage count for SYSC_QUIRK_NO_IDLE */
2376+
if (ddata->cfg.quirks & SYSC_QUIRK_NO_IDLE)
2377+
return;
2378+
2379+
/*
2380+
* Decrement PM runtime usage count for SYSC_QUIRK_NO_IDLE_ON_INIT
2381+
* and SYSC_QUIRK_NO_RESET_ON_INIT
2382+
*/
23582383
if (pm_runtime_active(ddata->dev))
23592384
pm_runtime_put_sync(ddata->dev);
23602385
}
@@ -2439,7 +2464,8 @@ static int sysc_probe(struct platform_device *pdev)
24392464
INIT_DELAYED_WORK(&ddata->idle_work, ti_sysc_idle);
24402465

24412466
/* At least earlycon won't survive without deferred idle */
2442-
if (ddata->cfg.quirks & (SYSC_QUIRK_NO_IDLE_ON_INIT |
2467+
if (ddata->cfg.quirks & (SYSC_QUIRK_NO_IDLE |
2468+
SYSC_QUIRK_NO_IDLE_ON_INIT |
24432469
SYSC_QUIRK_NO_RESET_ON_INIT)) {
24442470
schedule_delayed_work(&ddata->idle_work, 3000);
24452471
} else {

0 commit comments

Comments
 (0)