From a93739b4910af73bbfe38daacee79fe7acf0c9ef Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Mon, 20 Apr 2026 20:27:41 +0800 Subject: [PATCH] ASoC: SOF: add SOF_DBG_CHECK_SDW_PERIPHERAL debug flag If the flag is set, the driver waits for and verifies the presence of SoundWire peripherals listed in the ACPI table. This prevents the system from probing non-existent (ghost) SoundWire devices. Signed-off-by: Bard Liao --- sound/soc/sof/intel/hda.c | 20 ++++++++++++++++++-- sound/soc/sof/sof-priv.h | 3 +++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index b3d61d973ce40b..1f9b4de308b827 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -1306,6 +1306,8 @@ static struct snd_soc_acpi_adr_device *find_acpi_adr_device(struct device *dev, return adr_dev; } +#define ENUMERATION_TIMEOUT 3000 + static struct snd_soc_acpi_mach *hda_sdw_machine_select(struct snd_sof_dev *sdev) { struct snd_sof_pdata *pdata = sdev->pdata; @@ -1315,7 +1317,9 @@ static struct snd_soc_acpi_mach *hda_sdw_machine_select(struct snd_sof_dev *sdev struct sdw_peripherals *peripherals; struct snd_soc_acpi_mach *mach; struct sof_intel_hda_dev *hdev; + struct sdw_slave *slave; int link_index, link_num; + unsigned long time; int amp_index = 1; u32 link_mask = 0; int i; @@ -1418,9 +1422,21 @@ static struct snd_soc_acpi_mach *hda_sdw_machine_select(struct snd_sof_dev *sdev /* Generate snd_soc_acpi_link_adr struct for each peripheral reported by the ACPI table */ for (i = 0; i < peripherals->num_peripherals; i++) { + slave = peripherals->array[i]; + + /* Check if the SoundWire peripheral is present */ + if (sof_debug_check_flag(SOF_DBG_CHECK_SDW_PERIPHERAL) && !slave->dev_num_sticky) { + /* Wait for the peripheral to enumerate */ + time = wait_for_completion_timeout(&slave->enumeration_complete, + msecs_to_jiffies(ENUMERATION_TIMEOUT)); + if (!time) { + dev_warn(&slave->dev, "SoundWire peripheral is not present\n"); + continue; + } + } /* link_index = the number of used links below the current link */ - link_index = hweight32(link_mask & (BIT(peripherals->array[i]->bus->link_id) - 1)); - links[link_index].adr_d = find_acpi_adr_device(sdev->dev, peripherals->array[i], + link_index = hweight32(link_mask & (BIT(slave->bus->link_id) - 1)); + links[link_index].adr_d = find_acpi_adr_device(sdev->dev, slave, &links[link_index], &_index); if (!links[link_index].adr_d) return NULL; diff --git a/sound/soc/sof/sof-priv.h b/sound/soc/sof/sof-priv.h index d90d4524b6002e..17564aeade78cc 100644 --- a/sound/soc/sof/sof-priv.h +++ b/sound/soc/sof/sof-priv.h @@ -56,6 +56,9 @@ struct snd_sof_pcm_stream; * DSPLESS_MODE is not set. * No audio functionality when enabled. */ +#define SOF_DBG_CHECK_SDW_PERIPHERAL BIT(17) /* Check if SoundWire peripherals are + * present while selecting machine driver + */ /* Flag definitions used for controlling the DSP dump behavior */ #define SOF_DBG_DUMP_REGS BIT(0)