diff mbox series

[SRU,R,1/3] ASoC: codecs: tas2783-sdw: Propagate regcache_sync() errors

Message ID 20260825024732.3420898-2-chris.chiu@canonical.com
State New
Headers show
Series Fix TAS2783 SoundWire amp resume timeout >5s | expand

Commit Message

Chris Chiu Aug. 25, 2026, 2:47 a.m. UTC
From: Pengpeng Hou <pengpeng@iscas.ac.cn>

BugLink: https://bugs.launchpad.net/bugs/2164967

regcache_sync() can fail while replaying cached register state after
SoundWire resume or attach handling. tas2783 currently ignores that
failure.

Propagate the error and restore cache-only/dirty state on failure.

Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Link: https://patch.msgid.link/20260704035746.82560-1-pengpeng@iscas.ac.cn
Signed-off-by: Mark Brown <broonie@kernel.org>
(cherry picked from commit 0d6b2d6f93a6715827a9b3c027cd8448d76e0e47)
Signed-off-by: Chris Chiu <chris.chiu@canonical.com>
---
 sound/soc/codecs/tas2783-sdw.c | 16 ++++++++++++++--
 1 file changed, 14 insertions(+), 2 deletions(-)
diff mbox series

Patch

diff --git a/sound/soc/codecs/tas2783-sdw.c b/sound/soc/codecs/tas2783-sdw.c
index 90008d2d06e2..506fc7f99517 100644
--- a/sound/soc/codecs/tas2783-sdw.c
+++ b/sound/soc/codecs/tas2783-sdw.c
@@ -1099,7 +1099,13 @@  static s32 tas2783_sdca_dev_resume(struct device *dev)
 
 regmap_sync:
 	regcache_cache_only(tas_dev->regmap, false);
-	regcache_sync(tas_dev->regmap);
+	ret = regcache_sync(tas_dev->regmap);
+	if (ret) {
+		regcache_cache_only(tas_dev->regmap, true);
+		regcache_mark_dirty(tas_dev->regmap);
+		return ret;
+	}
+
 	return 0;
 }
 
@@ -1193,6 +1199,7 @@  static s32 tas_update_status(struct sdw_slave *slave,
 {
 	struct tas2783_prv *tas_dev = dev_get_drvdata(&slave->dev);
 	struct device *dev = &slave->dev;
+	int ret;
 
 	dev_dbg(dev, "Peripheral status = %s",
 		status == SDW_SLAVE_UNATTACHED ? "unattached" :
@@ -1210,7 +1217,12 @@  static s32 tas_update_status(struct sdw_slave *slave,
 
 	/* updated the cache data to device */
 	regcache_cache_only(tas_dev->regmap, false);
-	regcache_sync(tas_dev->regmap);
+	ret = regcache_sync(tas_dev->regmap);
+	if (ret) {
+		regcache_cache_only(tas_dev->regmap, true);
+		regcache_mark_dirty(tas_dev->regmap);
+		return ret;
+	}
 
 	/* perform I/O transfers required for Slave initialization */
 	return tas_io_init(&slave->dev, slave);