mail archive of the barebox mailing list
 help / color / mirror / Atom feed
From: Ahmad Fatoum <a.fatoum@pengutronix.de>
To: barebox@lists.infradead.org
Cc: Sam Ravnborg <sam@ravnborg.org>, Ahmad Fatoum <a.fatoum@pengutronix.de>
Subject: [PATCH v3 15/15] usb: ohci-at91: fix possible hang chainloading barebox
Date: Thu, 15 Feb 2024 17:30:09 +0100	[thread overview]
Message-ID: <20240215163009.2172795-16-a.fatoum@pengutronix.de> (raw)
In-Reply-To: <20240215163009.2172795-1-a.fatoum@pengutronix.de>

barebox, like Linux, will consider disabling parents when disabling a
child clock. In the AT91 OHCI driver ported to barebox from Linux, this
leads to the USB clock shutdown during device shutdown to propagate up
to PLLB, which is also disabled.

On probe of the kernel driver, the USB clock rate is set to 48MHz, which
propagates up to the PLL, which is powered on again. In barebox, this clock
rate propagation does not happen and the PLL is only initially
configured in the first stage bootloader.

This has the effect that chainloading barebox from within barebox will
hang as the first barebox disables PLLB on shutdown and the second
barebox never power it on.

The proper solution would be to support propagation of clock rate change
requests, but till we have that, patch the driver, so only the immediate
clock is disabled and not its parents.

Signed-off-by: Ahmad Fatoum <a.fatoum@pengutronix.de>
---
v3:
  - new patch
---
 drivers/clk/clk.c            | 12 +++++++++---
 drivers/usb/host/ohci-at91.c | 13 +++++++++++--
 include/linux/clk.h          | 20 ++++++++++++++++++--
 3 files changed, 38 insertions(+), 7 deletions(-)

diff --git a/drivers/clk/clk.c b/drivers/clk/clk.c
index d3f5d5e83880..03533b61df0a 100644
--- a/drivers/clk/clk.c
+++ b/drivers/clk/clk.c
@@ -66,7 +66,7 @@ int clk_enable(struct clk *clk)
 	return 0;
 }
 
-void clk_disable(struct clk *clk)
+void clk_disable_one(struct clk *clk)
 {
 	struct clk_hw *hw;
 
@@ -91,11 +91,17 @@ void clk_disable(struct clk *clk)
 	if (!clk->enable_count) {
 		if (clk->ops->disable)
 			clk->ops->disable(hw);
-
-		clk_parent_disable(clk);
 	}
 }
 
+void clk_disable(struct clk *clk)
+{
+	clk_disable_one(clk);
+
+	if (!IS_ERR_OR_NULL(clk) && !clk->enable_count)
+		clk_parent_disable(clk);
+}
+
 unsigned long clk_get_rate(struct clk *clk)
 {
 	struct clk_hw *hw;
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index 867c0977be78..447d928ad4ce 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -50,8 +50,17 @@ static int at91_start_clock(struct ohci_at91_priv *ohci_at91)
 
 static void at91_stop_clock(struct ohci_at91_priv *ohci_at91)
 {
-	clk_disable(ohci_at91->fclk);
-	clk_disable(ohci_at91->iclk);
+	/*
+	 * We don't want to use clk_disable() here as that would
+	 * propagate up until PLLB is disabled breaking chainloadig
+	 * barebox from barebox. The proper solution would be to
+	 * set rate to 48MHz in at91_start_clock() and teach the CCF
+	 * to propagate up rate requests like Linux does, but till we
+	 * have that, we take the easy way out and ensure PLLB remains
+	 * enabled with the parameters that the first stage configured.
+	 */
+	clk_disable_one(ohci_at91->fclk);
+	clk_disable_one(ohci_at91->iclk);
 }
 
 static int at91_ohci_probe_dt(struct device *dev)
diff --git a/include/linux/clk.h b/include/linux/clk.h
index fe0b1ce3e36c..6be6e91e9eee 100644
--- a/include/linux/clk.h
+++ b/include/linux/clk.h
@@ -83,11 +83,27 @@ int clk_enable(struct clk *clk);
  *
  * Implementation detail: if the clock source is shared between
  * multiple drivers, clk_enable() calls must be balanced by the
- * same number of clk_disable() calls for the clock source to be
- * disabled.
+ * same number of clk_disable() or clk_disable_one() calls for
+ * the clock source to be disabled.
  */
 void clk_disable(struct clk *clk);
 
+/**
+ * clk_disable_one - inform the system when a specific clock is no longer required.
+ * @clk: clock source
+ *
+ * Inform the system that a clock source is no longer required by
+ * a driver and may be shut down. Unlike clk_disable(), this only
+ * affects the specified @clk and can't result in disabling any
+ * parents.
+ *
+ * Implementation detail: if the clock source is shared between
+ * multiple drivers, clk_enable() calls must be balanced by the
+ * same number of clk_disable() or clk_disable_one() calls for
+ * the clock source to be disabled.
+ */
+void clk_disable_one(struct clk *clk);
+
 /**
  * clk_get_rate - obtain the current clock rate (in Hz) for a clock source.
  *		  This is only valid once the clock source has been enabled.
-- 
2.39.2




  parent reply	other threads:[~2024-02-15 16:45 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-02-15 16:29 [PATCH v3 00/15] ARM: at91: skov-arm9cpu (SAM9263) first stage support Ahmad Fatoum
2024-02-15 16:29 ` [PATCH v3 01/15] mci: atmel_mci: disable power save mode Ahmad Fatoum
2024-02-15 16:29 ` [PATCH v3 02/15] mci: atmel_mci: fix zeroing of block length on AT91SAM9263 Ahmad Fatoum
2024-02-15 16:29 ` [PATCH v3 03/15] ARM: replace ENTRY_FUNCTION_HEAD with ENTRY_FUNCTION_WITHSTACK_HEAD Ahmad Fatoum
2024-02-15 16:29 ` [PATCH v3 04/15] ARM: at91: use AT91 header instead of generic barebox ARM's Ahmad Fatoum
2024-02-15 16:29 ` [PATCH v3 05/15] ARM: at91: implement SAM9_ENTRY_FUNCTION Ahmad Fatoum
2024-02-15 16:30 ` [PATCH v3 06/15] ARM: at91: sam9263_ll: drop PLL charge pump initialization Ahmad Fatoum
2024-02-15 16:30 ` [PATCH v3 07/15] ARM: at91: sam9263_ll: pass AT91_PMC_LL_AT91SAM9263 to PMC functions Ahmad Fatoum
2024-02-15 16:30 ` [PATCH v3 08/15] ARM: at91: sam9263_ll: refactor MCK switch to PLLA for clarity Ahmad Fatoum
2024-02-15 16:30 ` [PATCH v3 09/15] ARM: at91: sam9263_ll: support configuration of PLLB Ahmad Fatoum
2024-02-15 16:30 ` [PATCH v3 10/15] ARM: dts: AT91: skov-arm9cpu: remove barebox environment on NOR Ahmad Fatoum
2024-02-15 16:30 ` [PATCH v3 11/15] ARM: at91: skov-arm9cpu: Add SD-Card xload support Ahmad Fatoum
2024-02-15 22:29   ` Sam Ravnborg
2024-02-20  9:25     ` Ahmad Fatoum
2024-02-21 16:28       ` Sam Ravnborg
2024-02-15 16:30 ` [PATCH v3 12/15] ARM: at91: skov-arm9cpu: configure SMC for NOR flash use Ahmad Fatoum
2024-02-15 16:30 ` [PATCH v3 13/15] ARM: at91: skov-arm9cpu: configure more appropriate hostname Ahmad Fatoum
2024-02-15 16:30 ` [PATCH v3 14/15] ARM: AT91: skov-arm9cpu: support environment on SD-Card Ahmad Fatoum
2024-02-15 16:30 ` Ahmad Fatoum [this message]
2024-02-16 13:15   ` [PATCH v3 15/15] usb: ohci-at91: fix possible hang chainloading barebox Sascha Hauer
2024-02-20  9:26     ` Ahmad Fatoum
2024-02-15 22:33 ` [PATCH v3 00/15] ARM: at91: skov-arm9cpu (SAM9263) first stage support Sam Ravnborg
2024-02-20  9:27   ` Ahmad Fatoum

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240215163009.2172795-16-a.fatoum@pengutronix.de \
    --to=a.fatoum@pengutronix.de \
    --cc=barebox@lists.infradead.org \
    --cc=sam@ravnborg.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox