[PATCH 04/20] ASoC: cs42l42: Propagate system resume restore errors

Pengpeng Hou <[email protected]>
Newsgroups gmane.linux.sound,gmane.linux.kernel
Message-ID <[email protected]>
Commit a118fea777a2 ("ASoC: codecs: cs42l42-sdw: Propagate
regcache_sync() errors") makes the SoundWire runtime-resume path return
failures from the LATCH_TO_VP and full cache replay.  The separate
shared system-resume restore helper still ignores the same two
operations and clears suspended.  Both the I2C and SoundWire
system-resume callbacks call this helper.

Make cs42l42_resume_restore() return the first replay error.  Keep
suspended set and restore reset, cache-only state and supplies before
returning the error through both bus callbacks.

The issue was identified via static analysis and manually reviewed.

Fixes: f8593e885400 ("ASoC: cs42l42: Handle system suspend")

Assisted-by: LLM
Signed-off-by: Pengpeng Hou <[email protected]>
---
 sound/soc/codecs/cs42l42-sdw.c |  4 +---
 sound/soc/codecs/cs42l42.c     | 27 ++++++++++++++++++++-------
 sound/soc/codecs/cs42l42.h     |  2 +-
 3 files changed, 22 insertions(+), 11 deletions(-)

diff --git a/sound/soc/codecs/cs42l42-sdw.c b/sound/soc/codecs/cs42l42-sdw.c
index b61ca74dcf0b..055c37c08e87 100644
--- a/sound/soc/codecs/cs42l42-sdw.c
+++ b/sound/soc/codecs/cs42l42-sdw.c
@@ -514,9 +514,7 @@ static int cs42l42_sdw_resume(struct device *dev)
 	if (ret < 0)
 		return ret;
 
-	cs42l42_resume_restore(dev);
-
-	return 0;
+	return cs42l42_resume_restore(dev);
 }
 
 static int cs42l42_sdw_probe(struct sdw_slave *peripheral, const struct sdw_device_id *id)
diff --git a/sound/soc/codecs/cs42l42.c b/sound/soc/codecs/cs42l42.c
index fadf68860601..b6e9b7f53977 100644
--- a/sound/soc/codecs/cs42l42.c
+++ b/sound/soc/codecs/cs42l42.c
@@ -2237,22 +2237,37 @@ int cs42l42_resume(struct device *dev)
 }
 EXPORT_SYMBOL_NS_GPL(cs42l42_resume, "SND_SOC_CS42L42_CORE");
 
-void cs42l42_resume_restore(struct device *dev)
+int cs42l42_resume_restore(struct device *dev)
 {
 	struct cs42l42_private *cs42l42 = dev_get_drvdata(dev);
+	int ret;
 
 	regcache_cache_only(cs42l42->regmap, false);
 	regcache_mark_dirty(cs42l42->regmap);
 
 	scoped_guard(mutex, &cs42l42->irq_lock) {
 		/* Sync LATCH_TO_VP first so the VP domain registers sync correctly */
-		regcache_sync_region(cs42l42->regmap, CS42L42_MIC_DET_CTL1, CS42L42_MIC_DET_CTL1);
-		regcache_sync(cs42l42->regmap);
+		ret = regcache_sync_region(cs42l42->regmap,
+					   CS42L42_MIC_DET_CTL1,
+					   CS42L42_MIC_DET_CTL1);
+		if (!ret)
+			ret = regcache_sync(cs42l42->regmap);
+
+		if (!ret)
+			cs42l42->suspended = false;
+	}
 
-		cs42l42->suspended = false;
+	if (ret) {
+		regcache_cache_only(cs42l42->regmap, true);
+		gpiod_set_value_cansleep(cs42l42->reset_gpio, 0);
+		regulator_bulk_disable(ARRAY_SIZE(cs42l42->supplies),
+				       cs42l42->supplies);
+		return ret;
 	}
 
 	dev_dbg(dev, "System resumed\n");
+
+	return 0;
 }
 EXPORT_SYMBOL_NS_GPL(cs42l42_resume_restore, "SND_SOC_CS42L42_CORE");
 
@@ -2264,9 +2279,7 @@ static int __maybe_unused cs42l42_i2c_resume(struct device *dev)
 	if (ret)
 		return ret;
 
-	cs42l42_resume_restore(dev);
-
-	return 0;
+	return cs42l42_resume_restore(dev);
 }
 
 int cs42l42_common_probe(struct cs42l42_private *cs42l42,
diff --git a/sound/soc/codecs/cs42l42.h b/sound/soc/codecs/cs42l42.h
index 3d85ebc59489..7f17b9f73be6 100644
--- a/sound/soc/codecs/cs42l42.h
+++ b/sound/soc/codecs/cs42l42.h
@@ -72,7 +72,7 @@ int cs42l42_mute_stream(struct snd_soc_dai *dai, int mute, int stream);
 irqreturn_t cs42l42_irq_thread(int irq, void *data);
 int cs42l42_suspend(struct device *dev);
 int cs42l42_resume(struct device *dev);
-void cs42l42_resume_restore(struct device *dev);
+int cs42l42_resume_restore(struct device *dev);
 int cs42l42_common_probe(struct cs42l42_private *cs42l42,
 			 const struct snd_soc_component_driver *component_drv,
 			 struct snd_soc_dai_driver *dai);
-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.