[PATCH 2/2] ASoC: sdw_utils: skip unattached SoundWire peripherals

From: Amaan Lalani

Date: Fri Aug 28 2026 - 15:04:28 EST


Firmware may describe SoundWire peripherals which do not physically
enumerate on the bus. The corresponding SoundWire device can still be
present with SDW_SLAVE_UNATTACHED status.

Counting and parsing endpoints for such peripherals can create entries
for devices which are not actually present and therefore interfere with
sound card registration.

Check the SoundWire slave status before counting or parsing a
peripheral. Skip peripherals reported as SDW_SLAVE_UNATTACHED while
preserving the existing behavior when the SoundWire device cannot be
looked up.

Fixes: 27fd36aefa00 ("ASoC: Intel: sof-sdw: Add new code for parsing the snd_soc_acpi structs")

Assisted-by: LLM
Signed-off-by: Amaan Lalani <zlzzm2014@xxxxxxxxxxx>
---
sound/soc/sdw_utils/soc_sdw_utils.c | 35 +++++++++++++++++++++++++++++
1 file changed, 35 insertions(+)

diff --git a/sound/soc/sdw_utils/soc_sdw_utils.c b/sound/soc/sdw_utils/soc_sdw_utils.c
index 8a07ba2a29e5..381eb884efb9 100644
--- a/sound/soc/sdw_utils/soc_sdw_utils.c
+++ b/sound/soc/sdw_utils/soc_sdw_utils.c
@@ -1854,6 +1854,33 @@ static int is_sdca_aux_dev_present(struct device *dev,
return 0;
}

+static bool is_peripheral_attached(struct device *dev,
+ const struct snd_soc_acpi_link_adr *adr_link,
+ int adr_index)
+{
+ const char *sdw_codec_name;
+ struct sdw_slave *slave;
+
+ sdw_codec_name = _asoc_sdw_get_codec_name(dev, adr_link, adr_index);
+ if (!sdw_codec_name)
+ return true;
+
+ struct device *sdw_dev __free(put_device) =
+ bus_find_device_by_name(&sdw_bus_type, NULL, sdw_codec_name);
+ if (!sdw_dev)
+ return true;
+
+ slave = dev_to_sdw_dev(sdw_dev);
+
+ if (slave->status == SDW_SLAVE_UNATTACHED) {
+ dev_dbg(dev, "%s not present on the bus, skipping\n",
+ sdw_codec_name);
+ return false;
+ }
+
+ return true;
+}
+
int asoc_sdw_count_sdw_endpoints(struct snd_soc_card *card,
int *num_devs, int *num_ends, int *num_aux)
{
@@ -1870,6 +1897,11 @@ int asoc_sdw_count_sdw_endpoints(struct snd_soc_card *card,
const struct snd_soc_acpi_adr_device *adr_dev = &adr_link->adr_d[i];
struct asoc_sdw_codec_info *codec_info;

+ if (!is_peripheral_attached(dev, adr_link, i)) {
+ (*num_devs)--;
+ continue;
+ }
+
*num_ends += adr_dev->num_endpoints;

codec_info = asoc_sdw_find_codec_info_part(adr_dev->adr);
@@ -2029,6 +2061,9 @@ int asoc_sdw_parse_sdw_endpoints(struct device *dev,
return -EINVAL;
}

+ if (!is_peripheral_attached(dev, adr_link, i))
+ continue;
+
codec_info = asoc_sdw_find_codec_info_part(adr_dev->adr);
if (!codec_info)
return -EINVAL;
--
2.55.0