mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH] ASoC: ak4458: Check reset status after deassert
@ 2026-10-10  8:40 shengjiu.wang
  2026-10-10 19:03 ` Alvin Šipraga
  0 siblings, 1 reply; 4+ messages in thread
From: shengjiu.wang @ 2026-10-10  8:40 UTC (permalink / raw)
  To: lgirdwood, broonie, perex, tiwai, p.zabel, kuninori.morimoto.gx,
	linux-sound, linux-kernel

From: Shengjiu Wang <shengjiu.wang@nxp.com>

The reset line of the ak4458 can be shared, for example when two ak4458
devices use the same reset GPIO. In that case the two codecs may call
reset_control_deassert() concurrently from their runtime resume paths.

Only the first caller performs the actual hardware deassert, which may
sleep (for example a GPIO-expander based reset controller). A second
caller merely increments the shared deassert count and returns
immediately, so it can continue while the first caller's .deassert() has
not finished releasing the line yet, leaving the device still in reset.

Poll reset_control_status() after deassert so a caller does not continue
until the reset is really released. reset_control_status() returns a
positive value while the line is still asserted, zero once it is
deasserted, and a negative errno when the reset controller does not
implement status reporting. Stop polling on status <= 0 so controllers
without a .status callback do not spin for the full timeout, and check
the reset_control_deassert() return value as well.

Fixes: 8a0de73cf9dc ("ASoC: ak4458: add optional reset control to instead of gpio")
Signed-off-by: Shengjiu Wang <shengjiu.wang@nxp.com>
---
 sound/soc/codecs/ak4458.c | 32 +++++++++++++++++++++++++++++---
 1 file changed, 29 insertions(+), 3 deletions(-)

diff --git a/sound/soc/codecs/ak4458.c b/sound/soc/codecs/ak4458.c
index a74be99e877d..64984974ff88 100644
--- a/sound/soc/codecs/ak4458.c
+++ b/sound/soc/codecs/ak4458.c
@@ -8,6 +8,7 @@
 #include <linux/delay.h>
 #include <linux/gpio/consumer.h>
 #include <linux/i2c.h>
+#include <linux/iopoll.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/pm_runtime.h>
@@ -635,11 +636,36 @@ static struct snd_soc_dai_driver ak4497_dai = {
 
 static void ak4458_reset(struct ak4458_priv *ak4458, bool active)
 {
+	int ret, status;
+
 	if (!IS_ERR_OR_NULL(ak4458->reset)) {
-		if (active)
+		if (active) {
 			reset_control_assert(ak4458->reset);
-		else
-			reset_control_deassert(ak4458->reset);
+		} else {
+			ret = reset_control_deassert(ak4458->reset);
+			if (ret) {
+				dev_warn(ak4458->dev,
+					 "failed to deassert reset: %d\n", ret);
+			} else {
+				/*
+				 * On a shared reset line another consumer may
+				 * still be in its hardware .deassert(), which can
+				 * sleep, so the line may not be released yet.
+				 * Poll the status until it reads deasserted (0).
+				 * A negative return means the controller does not
+				 * report status, so stop polling in that case.
+				 */
+				ret = read_poll_timeout(reset_control_status, status,
+							status <= 0, 100, 20000,
+							false, ak4458->reset);
+				if (ret)
+					dev_warn(ak4458->dev,
+						 "reset still asserted after deassert\n");
+				else if (status < 0)
+					dev_dbg(ak4458->dev,
+						"reset status not supported: %d\n", status);
+			}
+		}
 		usleep_range(1000, 2000);
 	}
 }
-- 
2.34.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-10-12 11:45 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-10  8:40 [PATCH] ASoC: ak4458: Check reset status after deassert shengjiu.wang
2026-10-10 19:03 ` Alvin Šipraga
2026-10-12  6:49   ` Shengjiu Wang
2026-10-12 11:44     ` Alvin Šipraga

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®