Re: Linux-next: File system over NFS broken on DRA7/AM5 platforms

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



* Tony Lindgren <tony@xxxxxxxxxxx> [190903 14:06]:
> * Grygorii Strashko <grygorii.strashko@xxxxxx> [190903 12:46]:
> > > The clock definition itself looks fine, however the question is why does someone try to disable it while it
> >  is apparently still used (by NFS that is)? If it fails to disable, clock core is trying to disable it, but the IDLEST bit does not switch for some reason.
> > 
> > I've tried to disable "ti,no-idle" in DT for dra7 cpsw and got below failure
> > 
> > [    0.634530] gmac-clkctrl:0000:0: failed to enable 08070002
> > [    0.634557] ti-sysc: probe of 48485200.target-module failed with error -16
> > 
> > so samthing is not right with GMAC clocks as it should probe without "ti,no-idle".
> > 
> > 
> > original place of the issue is:
> > 
> > cpsw_probe()
> >  -> pm_runtime_get_sync()
> >     -> sysc_runtime_resume()
> >        -> sysc_enable_main_clocks()
> > 
> > Note. the sysc_init_module() for "ti,no-idle" case looks a little bit strange as there is
> > no guarantee that target-module or clock were enabled before.
> 
> Good point on the "ti,no-idle" handling. That is easy to fix by always enabling
> the clocks. The "ti,no-idle-on-init" handling needs probably a flag set for
> PM runtime.

The following should fix the clock handling for "ti,no-idle" and
"ti,no-idle-on-init". Sounds like we still might have other issues
left though based on removing "ti,no-idle"?

Regards,

Tony

8< -------------------------
diff --git a/drivers/bus/ti-sysc.c b/drivers/bus/ti-sysc.c
--- a/drivers/bus/ti-sysc.c
+++ b/drivers/bus/ti-sysc.c
@@ -66,6 +66,7 @@ static const char * const clock_names[SYSC_MAX_CLOCKS] = {
  * @name: name if available
  * @revision: interconnect target module revision
  * @enabled: sysc runtime enabled status
+ * @clocks_enabled_from_init: clocks left on from init with ti,no-idle-on-init
  * @needs_resume: runtime resume needed on resume from suspend
  * @child_needs_resume: runtime resume needed for child on resume from suspend
  * @disable_on_idle: status flag used for disabling modules with resets
@@ -93,6 +94,7 @@ struct sysc {
 	const char *name;
 	u32 revision;
 	unsigned int enabled:1;
+	unsigned int clocks_enabled_from_init:1;
 	unsigned int needs_resume:1;
 	unsigned int child_needs_resume:1;
 	struct delayed_work idle_work;
@@ -1128,6 +1130,18 @@ static int __maybe_unused sysc_runtime_resume(struct device *dev)
 
 	sysc_clkdm_allow_idle(ddata);
 
+	/*
+	 * One time decrement of clock usage counts if left on from init.
+	 * Note that we disable opt clocks unconditionally in this case
+	 * as they are enabled unconditionally during init without
+	 * considering sysc_opt_clks_needed() at that point.
+	 */
+	if (unlikely(ddata->clocks_enabled_from_init)) {
+		sysc_disable_main_clocks(ddata);
+		sysc_disable_opt_clocks(ddata);
+		ddata->clocks_enabled_from_init = false;
+	}
+
 	return 0;
 
 err_main_clocks:
@@ -1628,21 +1642,26 @@ static int sysc_init_module(struct sysc *ddata)
 	    (SYSC_QUIRK_NO_IDLE | SYSC_QUIRK_NO_IDLE_ON_INIT))
 		manage_clocks = false;
 
+	if (ddata->cfg.quirks & SYSC_QUIRK_NO_IDLE_ON_INIT)
+		ddata->clocks_enabled_from_init = true;
+
 	error = sysc_clockdomain_init(ddata);
 	if (error)
 		return error;
 
-	if (manage_clocks) {
-		sysc_clkdm_deny_idle(ddata);
+	sysc_clkdm_deny_idle(ddata);
 
-		error = sysc_enable_opt_clocks(ddata);
-		if (error)
-			return error;
+	/*
+	 * Always enable clocks. The bootloader may or may not have enabled
+	 * the related clocks.
+	 */
+	error = sysc_enable_opt_clocks(ddata);
+	if (error)
+		return error;
 
-		error = sysc_enable_main_clocks(ddata);
-		if (error)
-			goto err_opt_clocks;
-	}
+	error = sysc_enable_main_clocks(ddata);
+	if (error)
+		goto err_opt_clocks;
 
 	if (!(ddata->cfg.quirks & SYSC_QUIRK_NO_RESET_ON_INIT)) {
 		error = sysc_rstctrl_reset_deassert(ddata, true);
@@ -1677,10 +1696,10 @@ static int sysc_init_module(struct sysc *ddata)
 	if (manage_clocks)
 		sysc_disable_main_clocks(ddata);
 err_opt_clocks:
-	if (manage_clocks) {
+	if (manage_clocks)
 		sysc_disable_opt_clocks(ddata);
-		sysc_clkdm_allow_idle(ddata);
-	}
+
+	sysc_clkdm_allow_idle(ddata);
 
 	return error;
 }
-- 
2.23.0



[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux