ASoC: Fix SoundWire randconfig issues

Charles Keepax <ckeepax@opensource.cirrus.com> says:

Moving all the waiting for soundwire devices to enumerate into the core
code [1] has caused some randconfig issues. This is the second attempt
to fix this after there were some short coming in [2].

Sorry for sending during the merge window, but people are keen to see
a solution posted.

[1] https://lore.kernel.org/linux-sound/20260608102714.2503120-1-ckeepax@opensource.cirrus.com/
[2] https://lore.kernel.org/lkml/20260615150523.4006982-1-ckeepax@opensource.cirrus.com/

Link: https://patch.msgid.link/20260623101814.24044-1-ckeepax@opensource.cirrus.com
This commit is contained in:
Mark Brown
2026-06-23 12:52:35 +01:00
18 changed files with 78 additions and 52 deletions

View File

@@ -1372,34 +1372,6 @@ int sdw_slave_get_current_bank(struct sdw_slave *slave)
}
EXPORT_SYMBOL_GPL(sdw_slave_get_current_bank);
/**
* sdw_slave_wait_for_init - Wait for device initialisation
* @slave: Pointer to the SoundWire peripheral.
* @timeout_ms: Timeout in milliseconds.
*
* Wait for a peripheral device to enumerate and be initialised by the
* SoundWire core.
*
* Return: Zero on success, and a negative error code on failure.
*/
int sdw_slave_wait_for_init(struct sdw_slave *slave, int timeout_ms)
{
unsigned long time;
time = wait_for_completion_timeout(&slave->initialization_complete,
msecs_to_jiffies(timeout_ms));
if (!time) {
dev_err(&slave->dev, "Initialization not complete\n");
sdw_show_ping_status(slave->bus, true);
return -ETIMEDOUT;
}
slave->unattach_request = 0;
return 0;
}
EXPORT_SYMBOL_GPL(sdw_slave_wait_for_init);
static int sdw_slave_set_frequency(struct sdw_slave *slave)
{
int scale_index;

View File

@@ -11,6 +11,7 @@
#include <linux/idr.h>
#include <linux/irq.h>
#include <linux/irqdomain.h>
#include <linux/jiffies.h>
#include <linux/lockdep_types.h>
#include <linux/mod_devicetable.h>
#include <linux/mutex.h>
@@ -1093,8 +1094,6 @@ int sdw_slave_get_current_bank(struct sdw_slave *sdev);
int sdw_slave_get_scale_index(struct sdw_slave *slave, u8 *base);
int sdw_slave_wait_for_init(struct sdw_slave *slave, int timeout_ms);
/* messaging and data APIs */
int sdw_read(struct sdw_slave *slave, u32 addr);
int sdw_write(struct sdw_slave *slave, u32 addr, u8 value);
@@ -1138,12 +1137,6 @@ static inline int sdw_slave_get_current_bank(struct sdw_slave *sdev)
return -EINVAL;
}
static inline int sdw_slave_wait_for_init(struct sdw_slave *slave, int timeout_ms)
{
WARN_ONCE(1, "SoundWire API is disabled");
return -EINVAL;
}
/* messaging and data APIs */
static inline int sdw_read(struct sdw_slave *slave, u32 addr)
{
@@ -1207,4 +1200,33 @@ static inline int sdw_update_no_pm(struct sdw_slave *slave, u32 addr, u8 mask, u
#endif /* CONFIG_SOUNDWIRE */
/**
* sdw_slave_wait_for_init - Wait for device initialisation
* @slave: Pointer to the SoundWire peripheral.
* @timeout_ms: Timeout in milliseconds.
*
* Wait for a peripheral device to enumerate and be initialised by the
* SoundWire core.
*
* Return: Zero on success, and a negative error code on failure.
*/
static inline int sdw_slave_wait_for_init(struct sdw_slave *slave, int timeout_ms)
{
unsigned long time;
if (!slave)
return 0;
time = wait_for_completion_timeout(&slave->initialization_complete,
msecs_to_jiffies(timeout_ms));
if (!time) {
dev_err(&slave->dev, "Initialization not complete\n");
return -ETIMEDOUT;
}
slave->unattach_request = 0;
return 0;
}
#endif /* __SOUNDWIRE_H */

View File

@@ -1111,8 +1111,10 @@ static int es9356_sdca_dev_resume(struct device *dev)
es9356->disable_irq = false;
ret = sdw_slave_wait_for_init(slave, es9356_PROBE_TIMEOUT);
if (ret)
if (ret) {
sdw_show_ping_status(slave->bus, true);
return ret;
}
regcache_cache_only(es9356->regmap, false);
regcache_sync(es9356->regmap);

View File

@@ -272,8 +272,10 @@ static int max98373_resume(struct device *dev)
return 0;
ret = sdw_slave_wait_for_init(slave, MAX98373_PROBE_TIMEOUT);
if (ret)
if (ret) {
sdw_show_ping_status(slave->bus, true);
return ret;
}
regcache_cache_only(max98373->regmap, false);
regcache_sync(max98373->regmap);

View File

@@ -779,8 +779,10 @@ static int rt1017_sdca_dev_resume(struct device *dev)
return 0;
ret = sdw_slave_wait_for_init(slave, RT1017_PROBE_TIMEOUT);
if (ret)
if (ret) {
sdw_show_ping_status(slave->bus, true);
return ret;
}
regcache_cache_only(rt1017->regmap, false);
regcache_sync(rt1017->regmap);

View File

@@ -774,8 +774,10 @@ static int rt1308_dev_resume(struct device *dev)
return 0;
ret = sdw_slave_wait_for_init(slave, RT1308_PROBE_TIMEOUT);
if (ret)
if (ret) {
sdw_show_ping_status(slave->bus, true);
return ret;
}
regcache_cache_only(rt1308->regmap, false);
regcache_sync_region(rt1308->regmap, 0xc000, 0xcfff);

View File

@@ -751,8 +751,10 @@ static int rt1316_dev_resume(struct device *dev)
return 0;
ret = sdw_slave_wait_for_init(slave, RT1316_PROBE_TIMEOUT);
if (ret)
if (ret) {
sdw_show_ping_status(slave->bus, true);
return ret;
}
regcache_cache_only(rt1316->regmap, false);
regcache_sync(rt1316->regmap);

View File

@@ -769,8 +769,10 @@ static int rt5682_dev_resume(struct device *dev)
}
ret = sdw_slave_wait_for_init(slave, RT5682_PROBE_TIMEOUT);
if (ret)
if (ret) {
sdw_show_ping_status(slave->bus, true);
return ret;
}
regcache_cache_only(rt5682->sdw_regmap, false);
regcache_cache_only(rt5682->regmap, false);

View File

@@ -528,8 +528,10 @@ static int rt700_dev_resume(struct device *dev)
return 0;
ret = sdw_slave_wait_for_init(slave, RT700_PROBE_TIMEOUT);
if (ret)
if (ret) {
sdw_show_ping_status(slave->bus, true);
return ret;
}
regcache_cache_only(rt700->regmap, false);
regcache_sync_region(rt700->regmap, 0x3000, 0x8fff);

View File

@@ -454,8 +454,10 @@ static int rt711_sdca_dev_resume(struct device *dev)
}
ret = sdw_slave_wait_for_init(slave, RT711_PROBE_TIMEOUT);
if (ret)
if (ret) {
sdw_show_ping_status(slave->bus, true);
return ret;
}
regcache_cache_only(rt711->regmap, false);
regcache_sync(rt711->regmap);

View File

@@ -911,8 +911,10 @@ static int rt712_sdca_dmic_dev_resume(struct device *dev)
return 0;
ret = sdw_slave_wait_for_init(slave, RT712_PROBE_TIMEOUT);
if (ret)
if (ret) {
sdw_show_ping_status(slave->bus, true);
return ret;
}
regcache_cache_only(rt712->regmap, false);
regcache_sync(rt712->regmap);

View File

@@ -467,8 +467,10 @@ static int rt712_sdca_dev_resume(struct device *dev)
}
ret = sdw_slave_wait_for_init(slave, RT712_PROBE_TIMEOUT);
if (ret)
if (ret) {
sdw_show_ping_status(slave->bus, true);
return ret;
}
regcache_cache_only(rt712->regmap, false);
regcache_sync(rt712->regmap);

View File

@@ -230,8 +230,10 @@ static int rt715_dev_resume(struct device *dev)
return 0;
ret = sdw_slave_wait_for_init(slave, RT715_PROBE_TIMEOUT);
if (ret)
if (ret) {
sdw_show_ping_status(slave->bus, true);
return ret;
}
regcache_cache_only(rt715->regmap, false);
regcache_sync_region(rt715->regmap,

View File

@@ -507,8 +507,10 @@ static int rt715_dev_resume(struct device *dev)
return 0;
ret = sdw_slave_wait_for_init(slave, RT715_PROBE_TIMEOUT);
if (ret)
if (ret) {
sdw_show_ping_status(slave->bus, true);
return ret;
}
regcache_cache_only(rt715->regmap, false);
regcache_sync_region(rt715->regmap, 0x3000, 0x8fff);

View File

@@ -505,8 +505,10 @@ static int rt721_sdca_dev_resume(struct device *dev)
}
ret = sdw_slave_wait_for_init(slave, RT721_PROBE_TIMEOUT);
if (ret)
if (ret) {
sdw_show_ping_status(slave->bus, true);
return ret;
}
regcache_cache_only(rt721->regmap, false);
regcache_sync(rt721->regmap);

View File

@@ -552,8 +552,10 @@ static int rt722_sdca_dev_resume(struct device *dev)
}
ret = sdw_slave_wait_for_init(slave, RT722_PROBE_TIMEOUT);
if (ret)
if (ret) {
sdw_show_ping_status(slave->bus, true);
return ret;
}
regcache_cache_only(rt722->regmap, false);
regcache_sync(rt722->regmap);

View File

@@ -1445,8 +1445,10 @@ static s32 tac5xx2_sdca_dev_resume(struct device *dev)
}
ret = sdw_slave_wait_for_init(slave, TAC5XX2_PROBE_TIMEOUT_MS);
if (ret)
if (ret) {
sdw_show_ping_status(slave->bus, true);
return ret;
}
regcache_cache_only(tac_dev->regmap, false);
regcache_mark_dirty(tac_dev->regmap);

View File

@@ -1083,8 +1083,10 @@ static s32 tas2783_sdca_dev_resume(struct device *dev)
int ret;
ret = sdw_slave_wait_for_init(slave, TAS2783_PROBE_TIMEOUT);
if (ret)
if (ret) {
sdw_show_ping_status(slave->bus, true);
return ret;
}
regcache_cache_only(tas_dev->regmap, false);
regcache_sync(tas_dev->regmap);