All of lore.kernel.org
 help / color / mirror / Atom feed
From: yass27106 <yass27106@gmail.com>
To: andersson@kernel.org, broonie@kernel.org, srini@kernel.org,
	konradybcio@kernel.org
Cc: robh@kernel.org, krzk+dt@kernel.org, conor+dt@kernel.org,
	vkoul@kernel.org, tiwai@suse.com, perex@perex.cz,
	lgirdwood@gmail.com, pierre-louis.bossart@linux.dev,
	yung-chuan.liao@linux.intel.com, abelvesa@kernel.org,
	linux-arm-msm@vger.kernel.org, linux-sound@vger.kernel.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	yass27106@gmail.com
Subject: [PATCH 2/2] ASoC: qcom: lpass macro / soundwire: retry deferred clock acquisition
Date: Fri, 13 Nov 2026 13:24:34 -0000	[thread overview]
Message-ID: <90d9d32bd8d44c4f97ca3af4e1bc5481@gmail.com> (raw)
In-Reply-To: <5cfd0705da5845b88ffe6d9e8bfeb966@gmail.com>

drivers/soundwire/qcom.c           | 37 +++++++++++++++++++++++-
 sound/soc/codecs/lpass-rx-macro.c  | 45 ++++++++++++++++++++++++++----
 sound/soc/codecs/lpass-tx-macro.c  | 45 ++++++++++++++++++++++++++----
 sound/soc/codecs/lpass-va-macro.c  | 43 +++++++++++++++++++++++++---
 sound/soc/codecs/lpass-wsa-macro.c | 45 ++++++++++++++++++++++++++----
 5 files changed, 195 insertions(+), 20 deletions(-)

diff --git a/drivers/soundwire/qcom.c b/drivers/soundwire/qcom.c
index 6e0c5fb10ef..cb50cf239cd 100644
--- a/drivers/soundwire/qcom.c
+++ b/drivers/soundwire/qcom.c
@@ -21,6 +21,41 @@
 #include <sound/pcm_params.h>
 #include <sound/soc.h>
 #include "bus.h"
+#include <linux/delay.h>
+
+/*
+ * Bounded retry for deferred clock providers. Clock-provider registration
+ * does not trigger deferred-probe retries, so a consumer that loses the
+ * probe-order race stays deferred forever. Wait up to 30 s for providers
+ * that are registered milliseconds later.
+ */
+static struct clk *clk_get_retry(struct device *dev, const char *id)
+{
+	struct clk *c;
+	int i;
+
+	for (i = 0; i < 60; i++) {
+		c = devm_clk_get(dev, id);
+		if (!IS_ERR(c) || PTR_ERR(c) != -EPROBE_DEFER)
+			return c;
+		msleep(500);
+	}
+	return c;
+}
+
+static struct clk *clk_get_retry_optional(struct device *dev, const char *id)
+{
+	struct clk *c;
+	int i;
+
+	for (i = 0; i < 60; i++) {
+		c = devm_clk_get_optional(dev, id);
+		if (!IS_ERR(c) || PTR_ERR(c) != -EPROBE_DEFER)
+			return c;
+		msleep(500);
+	}
+	return c;
+}
 
 #define SWRM_COMP_SW_RESET					0x008
 #define SWRM_COMP_STATUS					0x014
@@ -1669,7 +1704,7 @@ static int qcom_swrm_probe(struct platform_device *pdev)
 		goto err_init;
 	}
 
-	ctrl->hclk = devm_clk_get(dev, "iface");
+	ctrl->hclk = clk_get_retry(dev, "iface");
 	if (IS_ERR(ctrl->hclk)) {
 		ret = dev_err_probe(dev, PTR_ERR(ctrl->hclk), "unable to get iface clock\n");
 		goto err_init;
diff --git a/sound/soc/codecs/lpass-rx-macro.c b/sound/soc/codecs/lpass-rx-macro.c
index c41eb8de616..5d893960dd8 100644
--- a/sound/soc/codecs/lpass-rx-macro.c
+++ b/sound/soc/codecs/lpass-rx-macro.c
@@ -18,6 +18,41 @@
 #include <linux/clk-provider.h>
 
 #include "lpass-macro-common.h"
+#include <linux/delay.h>
+
+/*
+ * Bounded retry for deferred clock providers. Clock-provider registration
+ * does not trigger deferred-probe retries, so a consumer that loses the
+ * probe-order race stays deferred forever. Wait up to 30 s for providers
+ * that are registered milliseconds later.
+ */
+static struct clk *clk_get_retry(struct device *dev, const char *id)
+{
+	struct clk *c;
+	int i;
+
+	for (i = 0; i < 60; i++) {
+		c = devm_clk_get(dev, id);
+		if (!IS_ERR(c) || PTR_ERR(c) != -EPROBE_DEFER)
+			return c;
+		msleep(500);
+	}
+	return c;
+}
+
+static struct clk *clk_get_retry_optional(struct device *dev, const char *id)
+{
+	struct clk *c;
+	int i;
+
+	for (i = 0; i < 60; i++) {
+		c = devm_clk_get_optional(dev, id);
+		if (!IS_ERR(c) || PTR_ERR(c) != -EPROBE_DEFER)
+			return c;
+		msleep(500);
+	}
+	return c;
+}
 
 #define CDC_RX_TOP_TOP_CFG0		(0x0000)
 #define CDC_RX_TOP_SWR_CTRL		(0x0008)
@@ -3780,25 +3815,25 @@ static int rx_macro_probe(struct platform_device *pdev)
 	if (!rx)
 		return -ENOMEM;
 
-	rx->macro = devm_clk_get_optional(dev, "macro");
+	rx->macro = clk_get_retry_optional(dev, "macro");
 	if (IS_ERR(rx->macro))
 		return dev_err_probe(dev, PTR_ERR(rx->macro), "unable to get macro clock\n");
 
-	rx->dcodec = devm_clk_get_optional(dev, "dcodec");
+	rx->dcodec = clk_get_retry_optional(dev, "dcodec");
 	if (IS_ERR(rx->dcodec))
 		return dev_err_probe(dev, PTR_ERR(rx->dcodec), "unable to get dcodec clock\n");
 
-	rx->mclk = devm_clk_get(dev, "mclk");
+	rx->mclk = clk_get_retry(dev, "mclk");
 	if (IS_ERR(rx->mclk))
 		return dev_err_probe(dev, PTR_ERR(rx->mclk), "unable to get mclk clock\n");
 
 	if (flags & LPASS_MACRO_FLAG_HAS_NPL_CLOCK) {
-		rx->npl = devm_clk_get(dev, "npl");
+		rx->npl = clk_get_retry(dev, "npl");
 		if (IS_ERR(rx->npl))
 			return dev_err_probe(dev, PTR_ERR(rx->npl), "unable to get npl clock\n");
 	}
 
-	rx->fsgen = devm_clk_get(dev, "fsgen");
+	rx->fsgen = clk_get_retry(dev, "fsgen");
 	if (IS_ERR(rx->fsgen))
 		return dev_err_probe(dev, PTR_ERR(rx->fsgen), "unable to get fsgen clock\n");
 
diff --git a/sound/soc/codecs/lpass-tx-macro.c b/sound/soc/codecs/lpass-tx-macro.c
index 6deaaabe43a..4b8635cc2b2 100644
--- a/sound/soc/codecs/lpass-tx-macro.c
+++ b/sound/soc/codecs/lpass-tx-macro.c
@@ -16,6 +16,41 @@
 #include <linux/clk-provider.h>
 
 #include "lpass-macro-common.h"
+#include <linux/delay.h>
+
+/*
+ * Bounded retry for deferred clock providers. Clock-provider registration
+ * does not trigger deferred-probe retries, so a consumer that loses the
+ * probe-order race stays deferred forever. Wait up to 30 s for providers
+ * that are registered milliseconds later.
+ */
+static struct clk *clk_get_retry(struct device *dev, const char *id)
+{
+	struct clk *c;
+	int i;
+
+	for (i = 0; i < 60; i++) {
+		c = devm_clk_get(dev, id);
+		if (!IS_ERR(c) || PTR_ERR(c) != -EPROBE_DEFER)
+			return c;
+		msleep(500);
+	}
+	return c;
+}
+
+static struct clk *clk_get_retry_optional(struct device *dev, const char *id)
+{
+	struct clk *c;
+	int i;
+
+	for (i = 0; i < 60; i++) {
+		c = devm_clk_get_optional(dev, id);
+		if (!IS_ERR(c) || PTR_ERR(c) != -EPROBE_DEFER)
+			return c;
+		msleep(500);
+	}
+	return c;
+}
 
 #define CDC_TX_CLK_RST_CTRL_MCLK_CONTROL (0x0000)
 #define CDC_TX_MCLK_EN_MASK		BIT(0)
@@ -2258,25 +2293,25 @@ static int tx_macro_probe(struct platform_device *pdev)
 
 	tx->data = device_get_match_data(dev);
 
-	tx->macro = devm_clk_get_optional(dev, "macro");
+	tx->macro = clk_get_retry_optional(dev, "macro");
 	if (IS_ERR(tx->macro))
 		return dev_err_probe(dev, PTR_ERR(tx->macro), "unable to get macro clock\n");
 
-	tx->dcodec = devm_clk_get_optional(dev, "dcodec");
+	tx->dcodec = clk_get_retry_optional(dev, "dcodec");
 	if (IS_ERR(tx->dcodec))
 		return dev_err_probe(dev, PTR_ERR(tx->dcodec), "unable to get dcodec clock\n");
 
-	tx->mclk = devm_clk_get(dev, "mclk");
+	tx->mclk = clk_get_retry(dev, "mclk");
 	if (IS_ERR(tx->mclk))
 		return dev_err_probe(dev, PTR_ERR(tx->mclk), "unable to get mclk clock\n");
 
 	if (tx->data->flags & LPASS_MACRO_FLAG_HAS_NPL_CLOCK) {
-		tx->npl = devm_clk_get(dev, "npl");
+		tx->npl = clk_get_retry(dev, "npl");
 		if (IS_ERR(tx->npl))
 			return dev_err_probe(dev, PTR_ERR(tx->npl), "unable to get npl clock\n");
 	}
 
-	tx->fsgen = devm_clk_get(dev, "fsgen");
+	tx->fsgen = clk_get_retry(dev, "fsgen");
 	if (IS_ERR(tx->fsgen))
 		return dev_err_probe(dev, PTR_ERR(tx->fsgen), "unable to get fsgen clock\n");
 
diff --git a/sound/soc/codecs/lpass-va-macro.c b/sound/soc/codecs/lpass-va-macro.c
index 03d6434a4a1..fda1bbada11 100644
--- a/sound/soc/codecs/lpass-va-macro.c
+++ b/sound/soc/codecs/lpass-va-macro.c
@@ -19,6 +19,41 @@
 #include <sound/tlv.h>
 
 #include "lpass-macro-common.h"
+#include <linux/delay.h>
+
+/*
+ * Bounded retry for deferred clock providers. Clock-provider registration
+ * does not trigger deferred-probe retries, so a consumer that loses the
+ * probe-order race stays deferred forever. Wait up to 30 s for providers
+ * that are registered milliseconds later.
+ */
+static struct clk *clk_get_retry(struct device *dev, const char *id)
+{
+	struct clk *c;
+	int i;
+
+	for (i = 0; i < 60; i++) {
+		c = devm_clk_get(dev, id);
+		if (!IS_ERR(c) || PTR_ERR(c) != -EPROBE_DEFER)
+			return c;
+		msleep(500);
+	}
+	return c;
+}
+
+static struct clk *clk_get_retry_optional(struct device *dev, const char *id)
+{
+	struct clk *c;
+	int i;
+
+	for (i = 0; i < 60; i++) {
+		c = devm_clk_get_optional(dev, id);
+		if (!IS_ERR(c) || PTR_ERR(c) != -EPROBE_DEFER)
+			return c;
+		msleep(500);
+	}
+	return c;
+}
 
 /* VA macro registers */
 #define CDC_VA_CLK_RST_CTRL_MCLK_CONTROL	(0x0000)
@@ -1557,15 +1592,15 @@ static int va_macro_probe(struct platform_device *pdev)
 
 	va->dev = dev;
 
-	va->macro = devm_clk_get_optional(dev, "macro");
+	va->macro = clk_get_retry_optional(dev, "macro");
 	if (IS_ERR(va->macro))
 		return dev_err_probe(dev, PTR_ERR(va->macro), "unable to get macro clock\n");
 
-	va->dcodec = devm_clk_get_optional(dev, "dcodec");
+	va->dcodec = clk_get_retry_optional(dev, "dcodec");
 	if (IS_ERR(va->dcodec))
 		return dev_err_probe(dev, PTR_ERR(va->dcodec), "unable to get dcodec clock\n");
 
-	va->mclk = devm_clk_get(dev, "mclk");
+	va->mclk = clk_get_retry(dev, "mclk");
 	if (IS_ERR(va->mclk))
 		return dev_err_probe(dev, PTR_ERR(va->mclk), "unable to get mclk clock\n");
 
@@ -1610,7 +1645,7 @@ static int va_macro_probe(struct platform_device *pdev)
 		goto err;
 
 	if (va->has_npl_clk) {
-		va->npl = devm_clk_get(dev, "npl");
+		va->npl = clk_get_retry(dev, "npl");
 		if (IS_ERR(va->npl)) {
 			ret = PTR_ERR(va->npl);
 			goto err;
diff --git a/sound/soc/codecs/lpass-wsa-macro.c b/sound/soc/codecs/lpass-wsa-macro.c
index 899c8bee464..437a0876a8b 100644
--- a/sound/soc/codecs/lpass-wsa-macro.c
+++ b/sound/soc/codecs/lpass-wsa-macro.c
@@ -19,6 +19,41 @@
 
 #include "lpass-macro-common.h"
 #include "lpass-wsa-macro.h"
+#include <linux/delay.h>
+
+/*
+ * Bounded retry for deferred clock providers. Clock-provider registration
+ * does not trigger deferred-probe retries, so a consumer that loses the
+ * probe-order race stays deferred forever. Wait up to 30 s for providers
+ * that are registered milliseconds later.
+ */
+static struct clk *clk_get_retry(struct device *dev, const char *id)
+{
+	struct clk *c;
+	int i;
+
+	for (i = 0; i < 60; i++) {
+		c = devm_clk_get(dev, id);
+		if (!IS_ERR(c) || PTR_ERR(c) != -EPROBE_DEFER)
+			return c;
+		msleep(500);
+	}
+	return c;
+}
+
+static struct clk *clk_get_retry_optional(struct device *dev, const char *id)
+{
+	struct clk *c;
+	int i;
+
+	for (i = 0; i < 60; i++) {
+		c = devm_clk_get_optional(dev, id);
+		if (!IS_ERR(c) || PTR_ERR(c) != -EPROBE_DEFER)
+			return c;
+		msleep(500);
+	}
+	return c;
+}
 
 #define CDC_WSA_CLK_RST_CTRL_MCLK_CONTROL	(0x0000)
 #define CDC_WSA_MCLK_EN_MASK			BIT(0)
@@ -2701,25 +2736,25 @@ static int wsa_macro_probe(struct platform_device *pdev)
 	if (!wsa)
 		return -ENOMEM;
 
-	wsa->macro = devm_clk_get_optional(dev, "macro");
+	wsa->macro = clk_get_retry_optional(dev, "macro");
 	if (IS_ERR(wsa->macro))
 		return dev_err_probe(dev, PTR_ERR(wsa->macro), "unable to get macro clock\n");
 
-	wsa->dcodec = devm_clk_get_optional(dev, "dcodec");
+	wsa->dcodec = clk_get_retry_optional(dev, "dcodec");
 	if (IS_ERR(wsa->dcodec))
 		return dev_err_probe(dev, PTR_ERR(wsa->dcodec), "unable to get dcodec clock\n");
 
-	wsa->mclk = devm_clk_get(dev, "mclk");
+	wsa->mclk = clk_get_retry(dev, "mclk");
 	if (IS_ERR(wsa->mclk))
 		return dev_err_probe(dev, PTR_ERR(wsa->mclk), "unable to get mclk clock\n");
 
 	if (flags & LPASS_MACRO_FLAG_HAS_NPL_CLOCK) {
-		wsa->npl = devm_clk_get(dev, "npl");
+		wsa->npl = clk_get_retry(dev, "npl");
 		if (IS_ERR(wsa->npl))
 			return dev_err_probe(dev, PTR_ERR(wsa->npl), "unable to get npl clock\n");
 	}
 
-	wsa->fsgen = devm_clk_get(dev, "fsgen");
+	wsa->fsgen = clk_get_retry(dev, "fsgen");
 	if (IS_ERR(wsa->fsgen))
 		return dev_err_probe(dev, PTR_ERR(wsa->fsgen), "unable to get fsgen clock\n");
 
-- 
2.55.0

  reply	other threads:[~2026-11-13 13:24 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-13 13:24 [PATCH 0/2] qcom: add Asus Vivobook 16 X1607QA DT + LPASS audio clock retry yass27106
2026-11-13 13:24 ` [PATCH 1/2] arm64: dts: qcom: add device tree for Asus Vivobook 16 X1607QA yass27106
2026-11-13 13:24   ` yass27106 [this message]
2026-11-13 13:43     ` [PATCH 2/2] ASoC: qcom: lpass macro / soundwire: retry deferred clock acquisition sashiko-bot
2026-11-13 15:04     ` Mark Brown
2026-11-13 13:39   ` [PATCH 1/2] arm64: dts: qcom: add device tree for Asus Vivobook 16 X1607QA sashiko-bot
2026-11-13 15:44   ` Krzysztof Kozlowski

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=90d9d32bd8d44c4f97ca3af4e1bc5481@gmail.com \
    --to=yass27106@gmail.com \
    --cc=abelvesa@kernel.org \
    --cc=andersson@kernel.org \
    --cc=broonie@kernel.org \
    --cc=conor+dt@kernel.org \
    --cc=devicetree@vger.kernel.org \
    --cc=konradybcio@kernel.org \
    --cc=krzk+dt@kernel.org \
    --cc=lgirdwood@gmail.com \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-sound@vger.kernel.org \
    --cc=perex@perex.cz \
    --cc=pierre-louis.bossart@linux.dev \
    --cc=robh@kernel.org \
    --cc=srini@kernel.org \
    --cc=tiwai@suse.com \
    --cc=vkoul@kernel.org \
    --cc=yung-chuan.liao@linux.intel.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.