From c82790c13373e4283f0ec932c76717f960b7f322 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Wed, 17 Sep 2025 14:13:16 +0800 Subject: [PATCH 1/4] Revert "ASoC: SOF: Intel: use sof_sdw as default SDW machine driver" This reverts commit 5f38e117c959b6786757c1705962a40254687930. To split the commit into 2 commits. One to skip checking dummy topology and the other to use sof_sdw as default SDW machine driver. --- sound/soc/sof/fw-file-profile.c | 4 - sound/soc/sof/intel/hda.c | 195 +------------------------------- sound/soc/sof/topology.c | 5 - 3 files changed, 2 insertions(+), 202 deletions(-) diff --git a/sound/soc/sof/fw-file-profile.c b/sound/soc/sof/fw-file-profile.c index 0b6d071f1269dc..71abd6295ca9f7 100644 --- a/sound/soc/sof/fw-file-profile.c +++ b/sound/soc/sof/fw-file-profile.c @@ -73,10 +73,6 @@ static int sof_test_topology_file(struct device *dev, if (!profile->tplg_path || !profile->tplg_name) return 0; - /* Dummy topology does not exist and should not be used */ - if (strstr(profile->tplg_name, "dummy")) - return 0; - tplg_filename = kasprintf(GFP_KERNEL, "%s/%s", profile->tplg_path, profile->tplg_name); if (!tplg_filename) diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index ee70ec3cc53cc5..52e86fa6007788 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include #include @@ -34,7 +33,6 @@ #include "../sof-pci-dev.h" #include "../ops.h" #include "../ipc4-topology.h" -#include "../../intel/common/sof-function-topology-lib.h" #include "hda.h" #include @@ -1133,159 +1131,14 @@ static void hda_generic_machine_select(struct snd_sof_dev *sdev, #if IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE) -static bool is_endpoint_present(struct sdw_slave *sdw_device, - struct asoc_sdw_codec_info *dai_info, int dai_type) -{ - int i; - - for (i = 0; i < sdw_device->sdca_data.num_functions; i++) { - if (dai_type == dai_info->dais[i].dai_type) - return true; - } - dev_dbg(&sdw_device->dev, "Endpoint DAI type %d not found\n", dai_type); - return false; -} - -static struct snd_soc_acpi_adr_device *find_acpi_adr_device(struct device *dev, - struct sdw_slave *sdw_device, - struct snd_soc_acpi_link_adr *link, - int *amp_index) -{ - struct snd_soc_acpi_adr_device *adr_dev; - const char *name_prefix = ""; - int index = link->num_adr; - bool is_amp = true; /* Set it to false if the codec wiah any NON-AMP DAI type */ - int ep_index = 0; - int i, j; - - link->mask = BIT(sdw_device->bus->link_id); - /* index is 0 based, we need allocate index + 1 for the array size */ - if (!index) - adr_dev = devm_kzalloc(dev, sizeof(*adr_dev), GFP_KERNEL); - else - adr_dev = devm_krealloc(dev, (struct snd_soc_acpi_adr_device *)link->adr_d, - (index + 1) * sizeof(*adr_dev), GFP_KERNEL); - - if (!adr_dev) - return NULL; - - for (i = 0; i < asoc_sdw_get_codec_info_list_count(); i++) { - struct snd_soc_acpi_endpoint *endpoints; - int amp_group_id = 1; - - if (sdw_device->id.part_id != codec_info_list[i].part_id) - continue; - - endpoints = devm_kcalloc(dev, codec_info_list[i].dai_num, - sizeof(struct snd_soc_acpi_endpoint), GFP_KERNEL); - if (!endpoints) { - dev_err(dev, "failed to allocate memory for endpoints\n"); - return NULL; - } - - name_prefix = codec_info_list[i].name_prefix; - for (j = 0; j < codec_info_list[i].dai_num; j++) { - /* Check if the endpoint is present by the SDCA DisCo table */ - if (!is_endpoint_present(sdw_device, &codec_info_list[i], - codec_info_list[i].dais[j].dai_type)) - continue; - - endpoints[ep_index].num = ep_index; - if (codec_info_list[i].dais[j].dai_type == SOC_SDW_DAI_TYPE_AMP) { - /* Assume all amp are aggregated */ - endpoints[ep_index].aggregated = 1; - endpoints[ep_index].group_id = amp_group_id; - endpoints[ep_index].group_position = *amp_index; - /* Set group id = 2 for feedback capture endpoint */ - amp_group_id++; - } else { - endpoints[ep_index].aggregated = 0; - endpoints[ep_index].group_id = 0; - endpoints[ep_index].group_position = 0; - is_amp = false; - } - ep_index++; - } - adr_dev[index].endpoints = endpoints; - adr_dev[index].num_endpoints = ep_index; - break; - } - - if (i == asoc_sdw_get_codec_info_list_count()) { - dev_err(dev, "part id %#x is not supported\n", sdw_device->id.part_id); - return NULL; - } - - adr_dev[index].adr = ((u64)sdw_device->id.class_id & 0xFF) | - ((u64)sdw_device->id.part_id & 0xFFFF) << 8 | - ((u64)sdw_device->id.mfg_id & 0xFFFF) << 24 | - ((u64)(sdw_device->id.unique_id & 0xF) << 40) | - ((u64)(sdw_device->id.sdw_version & 0xF) << 44) | - ((u64)(sdw_device->bus->link_id & 0xF) << 48); - - if (!is_amp) { - /* For non-amp codecs, get name_prefix from codec_info_list[] */ - adr_dev[index].name_prefix = devm_kasprintf(dev, GFP_KERNEL, "%s", name_prefix); - goto done_name_prefix; - } - - /* - * The name_prefix comes from codec_info_list which has a name_prefix per codec. - * And we need to give a unique name_prefix for each amp and should be backwards - * compatible to the existing acpi match tables to not break existing UCMs. - * For the common name_prefix, we append the amp index to it. However, for the - * "Left" name_prefix, we convert the second amp name_prefix to "Right" and - * for the third and further amps, we set the name_prefix to "AMP". - */ - if (!strcmp(name_prefix, "Left")) { - switch (*amp_index) { - case 1: - adr_dev[index].name_prefix = devm_kasprintf(dev, GFP_KERNEL, - "%s", "Left"); - break; - case 2: - adr_dev[index].name_prefix = devm_kasprintf(dev, GFP_KERNEL, - "%s", "Right"); - break; - default: - /* Set the name_fix to AMP if there are more than 2 amps */ - adr_dev[index].name_prefix = devm_kasprintf(dev, GFP_KERNEL, "%s%d", - "AMP", *amp_index); - break; - } - } else { - adr_dev[index].name_prefix = devm_kasprintf(dev, GFP_KERNEL, "%s%d", - name_prefix, - *amp_index); - } - (*amp_index)++; - -done_name_prefix: - if (!adr_dev[index].name_prefix) { - dev_err(dev, "failed to allocate memory for name_prefix\n"); - return NULL; - } - - dev_dbg(dev, "adr[%d] 0x%llx link id %d name_prefix \"%s\" is found\n", - index, adr_dev[index].adr, sdw_device->bus->link_id, adr_dev[index].name_prefix); - - link->num_adr++; - - return adr_dev; -} - static struct snd_soc_acpi_mach *hda_sdw_machine_select(struct snd_sof_dev *sdev) { struct snd_sof_pdata *pdata = sdev->pdata; const struct snd_soc_acpi_link_adr *link; - const struct sof_intel_dsp_desc *chip; - struct snd_soc_acpi_link_adr *links; struct sdw_peripherals *peripherals; struct snd_soc_acpi_mach *mach; struct sof_intel_hda_dev *hdev; - int link_index, link_num; - int amp_index = 1; - u32 link_mask = 0; + u32 link_mask; int i; hdev = pdata->hw_pdata; @@ -1362,50 +1215,7 @@ static struct snd_soc_acpi_mach *hda_sdw_machine_select(struct snd_sof_dev *sdev peripherals->array[i]->id.part_id, peripherals->array[i]->id.sdw_version); - chip = get_chip_info(sdev->pdata); - - /* SDCA was not well supported in the BIOS before ACE2.0 */ - if (chip->hw_ip_version < SOF_INTEL_ACE_2_0) - return NULL; - - if (!peripherals->num_peripherals) - return NULL; - - /* Create default SDW mach */ - mach = devm_kzalloc(sdev->dev, sizeof(*mach), GFP_KERNEL); - if (!mach) - return NULL; - - /* Get link mask and link number */ - for (i = 0; i < peripherals->num_peripherals; i++) - link_mask |= BIT(peripherals->array[i]->bus->link_id); - - link_num = hweight32(link_mask); - links = devm_kcalloc(sdev->dev, link_num, sizeof(*links), GFP_KERNEL); - if (!links) - return NULL; - - /* Generate snd_soc_acpi_link_adr struct for each peripheral reported by the ACPI table */ - for (i = 0; i < peripherals->num_peripherals; i++) { - /* 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], - &links[link_index], &_index); - } - - mach->drv_name = "sof_sdw"; - mach->mach_params.links = links; - mach->mach_params.link_mask = link_mask; - mach->mach_params.platform = dev_name(sdev->dev); - mach->get_function_tplg_files = sof_sdw_get_tplg_files; - /* - * Set mach->sof_tplg_filename as a dummy topology to avoid tplg file checking - * and being used. - */ - mach->sof_tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL, "sof-%s-dummy.tplg", chip->platform); - - dev_info(sdev->dev, "Use SoundWire default machine driver with function topologies\n"); - return mach; + return NULL; } #else static struct snd_soc_acpi_mach *hda_sdw_machine_select(struct snd_sof_dev *sdev) @@ -1733,7 +1543,6 @@ MODULE_IMPORT_NS("SND_SOC_SOF_XTENSA"); MODULE_IMPORT_NS("SND_INTEL_SOUNDWIRE_ACPI"); MODULE_IMPORT_NS("SOUNDWIRE_INTEL_INIT"); MODULE_IMPORT_NS("SOUNDWIRE_INTEL"); -MODULE_IMPORT_NS("SND_SOC_SDW_UTILS"); MODULE_IMPORT_NS("SND_SOC_SOF_HDA_MLINK"); MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_HDA_COMMON"); MODULE_IMPORT_NS("SND_SOC_ACPI_INTEL_MATCH"); diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index 72cc8983720d05..3404f1306494c2 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -2523,11 +2523,6 @@ int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file) * callback or the callback returns 0. */ if (!tplg_cnt) { - if (strstr(file, "dummy")) { - dev_err(scomp->dev, - "Function topology is required, please upgrade sof-bin\n"); - return -EINVAL; - } tplg_files[0] = file; tplg_cnt = 1; dev_info(scomp->dev, "loading topology: %s\n", file); From f86a7c5e8ad32d1a1b4ea997162bc2579f32e1e8 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Wed, 17 Sep 2025 14:18:18 +0800 Subject: [PATCH 2/4] ASoC: SOF: don't check the existence of dummy topology Monolithic topology is not needed if function topology is used. Instead of creating a dummy topology in the file system, we can skip the existence check in the kernel. Signed-off-by: Bard Liao --- sound/soc/sof/fw-file-profile.c | 4 ++++ sound/soc/sof/topology.c | 5 +++++ 2 files changed, 9 insertions(+) diff --git a/sound/soc/sof/fw-file-profile.c b/sound/soc/sof/fw-file-profile.c index 71abd6295ca9f7..0b6d071f1269dc 100644 --- a/sound/soc/sof/fw-file-profile.c +++ b/sound/soc/sof/fw-file-profile.c @@ -73,6 +73,10 @@ static int sof_test_topology_file(struct device *dev, if (!profile->tplg_path || !profile->tplg_name) return 0; + /* Dummy topology does not exist and should not be used */ + if (strstr(profile->tplg_name, "dummy")) + return 0; + tplg_filename = kasprintf(GFP_KERNEL, "%s/%s", profile->tplg_path, profile->tplg_name); if (!tplg_filename) diff --git a/sound/soc/sof/topology.c b/sound/soc/sof/topology.c index 3404f1306494c2..c1083ea4624ad7 100644 --- a/sound/soc/sof/topology.c +++ b/sound/soc/sof/topology.c @@ -2523,6 +2523,11 @@ int snd_sof_load_topology(struct snd_soc_component *scomp, const char *file) * callback or the callback returns 0. */ if (!tplg_cnt) { + if (strstr(file, "dummy")) { + dev_err(scomp->dev, + "Function topology is required, please upgrade sof-firmware\n"); + return -EINVAL; + } tplg_files[0] = file; tplg_cnt = 1; dev_info(scomp->dev, "loading topology: %s\n", file); From fce518beac5a42fb4bbe034f0a0ad58de3631713 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Mon, 12 May 2025 19:34:56 +0800 Subject: [PATCH 3/4] ASoC: SOF: Intel: use sof_sdw as default SDW machine driver If there is no SoundWire machine matches the existing acpi match table, get the required machine data from the acpi table and construct the link adrs and endpoints. Pass the data to the default Intel SoundWire machine driver. And we don't need to add new item to the acpi match table in common cases. We will construct a dummy topology name. The dummy topology is just used to extract the platform name for function topology and should not be used. Signed-off-by: Bard Liao --- sound/soc/sof/intel/hda.c | 195 +++++++++++++++++++++++++++++++++++++- 1 file changed, 193 insertions(+), 2 deletions(-) diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index 52e86fa6007788..ee70ec3cc53cc5 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -33,6 +34,7 @@ #include "../sof-pci-dev.h" #include "../ops.h" #include "../ipc4-topology.h" +#include "../../intel/common/sof-function-topology-lib.h" #include "hda.h" #include @@ -1131,14 +1133,159 @@ static void hda_generic_machine_select(struct snd_sof_dev *sdev, #if IS_ENABLED(CONFIG_SND_SOC_SOF_INTEL_SOUNDWIRE) +static bool is_endpoint_present(struct sdw_slave *sdw_device, + struct asoc_sdw_codec_info *dai_info, int dai_type) +{ + int i; + + for (i = 0; i < sdw_device->sdca_data.num_functions; i++) { + if (dai_type == dai_info->dais[i].dai_type) + return true; + } + dev_dbg(&sdw_device->dev, "Endpoint DAI type %d not found\n", dai_type); + return false; +} + +static struct snd_soc_acpi_adr_device *find_acpi_adr_device(struct device *dev, + struct sdw_slave *sdw_device, + struct snd_soc_acpi_link_adr *link, + int *amp_index) +{ + struct snd_soc_acpi_adr_device *adr_dev; + const char *name_prefix = ""; + int index = link->num_adr; + bool is_amp = true; /* Set it to false if the codec wiah any NON-AMP DAI type */ + int ep_index = 0; + int i, j; + + link->mask = BIT(sdw_device->bus->link_id); + /* index is 0 based, we need allocate index + 1 for the array size */ + if (!index) + adr_dev = devm_kzalloc(dev, sizeof(*adr_dev), GFP_KERNEL); + else + adr_dev = devm_krealloc(dev, (struct snd_soc_acpi_adr_device *)link->adr_d, + (index + 1) * sizeof(*adr_dev), GFP_KERNEL); + + if (!adr_dev) + return NULL; + + for (i = 0; i < asoc_sdw_get_codec_info_list_count(); i++) { + struct snd_soc_acpi_endpoint *endpoints; + int amp_group_id = 1; + + if (sdw_device->id.part_id != codec_info_list[i].part_id) + continue; + + endpoints = devm_kcalloc(dev, codec_info_list[i].dai_num, + sizeof(struct snd_soc_acpi_endpoint), GFP_KERNEL); + if (!endpoints) { + dev_err(dev, "failed to allocate memory for endpoints\n"); + return NULL; + } + + name_prefix = codec_info_list[i].name_prefix; + for (j = 0; j < codec_info_list[i].dai_num; j++) { + /* Check if the endpoint is present by the SDCA DisCo table */ + if (!is_endpoint_present(sdw_device, &codec_info_list[i], + codec_info_list[i].dais[j].dai_type)) + continue; + + endpoints[ep_index].num = ep_index; + if (codec_info_list[i].dais[j].dai_type == SOC_SDW_DAI_TYPE_AMP) { + /* Assume all amp are aggregated */ + endpoints[ep_index].aggregated = 1; + endpoints[ep_index].group_id = amp_group_id; + endpoints[ep_index].group_position = *amp_index; + /* Set group id = 2 for feedback capture endpoint */ + amp_group_id++; + } else { + endpoints[ep_index].aggregated = 0; + endpoints[ep_index].group_id = 0; + endpoints[ep_index].group_position = 0; + is_amp = false; + } + ep_index++; + } + adr_dev[index].endpoints = endpoints; + adr_dev[index].num_endpoints = ep_index; + break; + } + + if (i == asoc_sdw_get_codec_info_list_count()) { + dev_err(dev, "part id %#x is not supported\n", sdw_device->id.part_id); + return NULL; + } + + adr_dev[index].adr = ((u64)sdw_device->id.class_id & 0xFF) | + ((u64)sdw_device->id.part_id & 0xFFFF) << 8 | + ((u64)sdw_device->id.mfg_id & 0xFFFF) << 24 | + ((u64)(sdw_device->id.unique_id & 0xF) << 40) | + ((u64)(sdw_device->id.sdw_version & 0xF) << 44) | + ((u64)(sdw_device->bus->link_id & 0xF) << 48); + + if (!is_amp) { + /* For non-amp codecs, get name_prefix from codec_info_list[] */ + adr_dev[index].name_prefix = devm_kasprintf(dev, GFP_KERNEL, "%s", name_prefix); + goto done_name_prefix; + } + + /* + * The name_prefix comes from codec_info_list which has a name_prefix per codec. + * And we need to give a unique name_prefix for each amp and should be backwards + * compatible to the existing acpi match tables to not break existing UCMs. + * For the common name_prefix, we append the amp index to it. However, for the + * "Left" name_prefix, we convert the second amp name_prefix to "Right" and + * for the third and further amps, we set the name_prefix to "AMP". + */ + if (!strcmp(name_prefix, "Left")) { + switch (*amp_index) { + case 1: + adr_dev[index].name_prefix = devm_kasprintf(dev, GFP_KERNEL, + "%s", "Left"); + break; + case 2: + adr_dev[index].name_prefix = devm_kasprintf(dev, GFP_KERNEL, + "%s", "Right"); + break; + default: + /* Set the name_fix to AMP if there are more than 2 amps */ + adr_dev[index].name_prefix = devm_kasprintf(dev, GFP_KERNEL, "%s%d", + "AMP", *amp_index); + break; + } + } else { + adr_dev[index].name_prefix = devm_kasprintf(dev, GFP_KERNEL, "%s%d", + name_prefix, + *amp_index); + } + (*amp_index)++; + +done_name_prefix: + if (!adr_dev[index].name_prefix) { + dev_err(dev, "failed to allocate memory for name_prefix\n"); + return NULL; + } + + dev_dbg(dev, "adr[%d] 0x%llx link id %d name_prefix \"%s\" is found\n", + index, adr_dev[index].adr, sdw_device->bus->link_id, adr_dev[index].name_prefix); + + link->num_adr++; + + return adr_dev; +} + static struct snd_soc_acpi_mach *hda_sdw_machine_select(struct snd_sof_dev *sdev) { struct snd_sof_pdata *pdata = sdev->pdata; const struct snd_soc_acpi_link_adr *link; + const struct sof_intel_dsp_desc *chip; + struct snd_soc_acpi_link_adr *links; struct sdw_peripherals *peripherals; struct snd_soc_acpi_mach *mach; struct sof_intel_hda_dev *hdev; - u32 link_mask; + int link_index, link_num; + int amp_index = 1; + u32 link_mask = 0; int i; hdev = pdata->hw_pdata; @@ -1215,7 +1362,50 @@ static struct snd_soc_acpi_mach *hda_sdw_machine_select(struct snd_sof_dev *sdev peripherals->array[i]->id.part_id, peripherals->array[i]->id.sdw_version); - return NULL; + chip = get_chip_info(sdev->pdata); + + /* SDCA was not well supported in the BIOS before ACE2.0 */ + if (chip->hw_ip_version < SOF_INTEL_ACE_2_0) + return NULL; + + if (!peripherals->num_peripherals) + return NULL; + + /* Create default SDW mach */ + mach = devm_kzalloc(sdev->dev, sizeof(*mach), GFP_KERNEL); + if (!mach) + return NULL; + + /* Get link mask and link number */ + for (i = 0; i < peripherals->num_peripherals; i++) + link_mask |= BIT(peripherals->array[i]->bus->link_id); + + link_num = hweight32(link_mask); + links = devm_kcalloc(sdev->dev, link_num, sizeof(*links), GFP_KERNEL); + if (!links) + return NULL; + + /* Generate snd_soc_acpi_link_adr struct for each peripheral reported by the ACPI table */ + for (i = 0; i < peripherals->num_peripherals; i++) { + /* 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], + &links[link_index], &_index); + } + + mach->drv_name = "sof_sdw"; + mach->mach_params.links = links; + mach->mach_params.link_mask = link_mask; + mach->mach_params.platform = dev_name(sdev->dev); + mach->get_function_tplg_files = sof_sdw_get_tplg_files; + /* + * Set mach->sof_tplg_filename as a dummy topology to avoid tplg file checking + * and being used. + */ + mach->sof_tplg_filename = devm_kasprintf(sdev->dev, GFP_KERNEL, "sof-%s-dummy.tplg", chip->platform); + + dev_info(sdev->dev, "Use SoundWire default machine driver with function topologies\n"); + return mach; } #else static struct snd_soc_acpi_mach *hda_sdw_machine_select(struct snd_sof_dev *sdev) @@ -1543,6 +1733,7 @@ MODULE_IMPORT_NS("SND_SOC_SOF_XTENSA"); MODULE_IMPORT_NS("SND_INTEL_SOUNDWIRE_ACPI"); MODULE_IMPORT_NS("SOUNDWIRE_INTEL_INIT"); MODULE_IMPORT_NS("SOUNDWIRE_INTEL"); +MODULE_IMPORT_NS("SND_SOC_SDW_UTILS"); MODULE_IMPORT_NS("SND_SOC_SOF_HDA_MLINK"); MODULE_IMPORT_NS("SND_SOC_SOF_INTEL_HDA_COMMON"); MODULE_IMPORT_NS("SND_SOC_ACPI_INTEL_MATCH"); From 88292009a3613ff6d956ea34157589696d779ff8 Mon Sep 17 00:00:00 2001 From: Bard Liao Date: Wed, 1 Oct 2025 09:27:03 +0800 Subject: [PATCH 4/4] fixup! ASoC: SOF: Intel: use sof_sdw as default SDW machine driver We can't use default SDW machine driver if links[link_index].adr_d is null. Also, add a paranoid check to avoid kernel NULL pointer dereference. Signed-off-by: Bard Liao --- sound/soc/sof/intel/hda.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/sound/soc/sof/intel/hda.c b/sound/soc/sof/intel/hda.c index ee70ec3cc53cc5..4c926c23443bcc 100644 --- a/sound/soc/sof/intel/hda.c +++ b/sound/soc/sof/intel/hda.c @@ -1184,6 +1184,15 @@ static struct snd_soc_acpi_adr_device *find_acpi_adr_device(struct device *dev, } name_prefix = codec_info_list[i].name_prefix; + /* + * This should not happen, but add a paranoid check to avoid NULL pointer + * dereference + */ + if (!name_prefix) { + dev_err(dev, "codec_info_list name_prefix of part id %#x is missing\n", + codec_info_list[i].part_id); + return NULL; + } for (j = 0; j < codec_info_list[i].dai_num; j++) { /* Check if the endpoint is present by the SDCA DisCo table */ if (!is_endpoint_present(sdw_device, &codec_info_list[i], @@ -1391,6 +1400,8 @@ static struct snd_soc_acpi_mach *hda_sdw_machine_select(struct snd_sof_dev *sdev 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], &links[link_index], &_index); + if (!links[link_index].adr_d) + return NULL; } mach->drv_name = "sof_sdw";