diff --git a/sound/soc/sof/sof-pci-dev.c b/sound/soc/sof/sof-pci-dev.c index 83c71ac3418eb8..eaa04ad567933a 100644 --- a/sound/soc/sof/sof-pci-dev.c +++ b/sound/soc/sof/sof-pci-dev.c @@ -198,9 +198,17 @@ static int sof_pci_probe(struct pci_dev *pci, dev_dbg(&pci->dev, "PCI DSP detected"); + /* get ops for platform */ + ops = sof_pci_get_ops(desc); + if (!ops) { + dev_err(dev, "error: no matching PCI descriptor ops\n"); + return -ENODEV; + } + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); if (!priv) return -ENOMEM; + pci_set_drvdata(pci, priv); sof_pdata = devm_kzalloc(dev, sizeof(*sof_pdata), GFP_KERNEL); @@ -213,14 +221,7 @@ static int sof_pci_probe(struct pci_dev *pci, ret = pci_request_regions(pci, "Audio DSP"); if (ret < 0) - return ret; - - /* get ops for platform */ - ops = sof_pci_get_ops(desc); - if (!ops) { - dev_err(dev, "error: no matching PCI descriptor ops\n"); - return -ENODEV; - } + goto disable_dev; #if IS_ENABLED(CONFIG_SND_SOC_SOF_FORCE_NOCODEC_MODE) /* force nocodec mode */ @@ -228,7 +229,7 @@ static int sof_pci_probe(struct pci_dev *pci, mach = devm_kzalloc(dev, sizeof(*mach), GFP_KERNEL); ret = sof_nocodec_setup(dev, sof_pdata, mach, desc, ops); if (ret < 0) - return ret; + goto release_regions; #else /* find machine */ mach = snd_soc_acpi_find_machine(desc->machines); @@ -239,10 +240,11 @@ static int sof_pci_probe(struct pci_dev *pci, mach = devm_kzalloc(dev, sizeof(*mach), GFP_KERNEL); ret = sof_nocodec_setup(dev, sof_pdata, mach, desc, ops); if (ret < 0) - return ret; + goto release_regions; #else dev_err(dev, "No matching ASoC machine driver found - aborting probe\n"); - return -ENODEV; + ret = -ENODEV; + goto release_regions; #endif } #endif @@ -261,8 +263,11 @@ static int sof_pci_probe(struct pci_dev *pci, sof_pdata->pdev_mach = platform_device_register_data(dev, mach->drv_name, -1, sof_pdata, sizeof(*sof_pdata)); - if (IS_ERR(sof_pdata->pdev_mach)) - return PTR_ERR(sof_pdata->pdev_mach); + if (IS_ERR(sof_pdata->pdev_mach)) { + ret = PTR_ERR(sof_pdata->pdev_mach); + goto release_regions; + } + dev_dbg(dev, "created machine %s\n", dev_name(&sof_pdata->pdev_mach->dev)); @@ -274,8 +279,16 @@ static int sof_pci_probe(struct pci_dev *pci, platform_device_unregister(sof_pdata->pdev_mach); dev_err(dev, "error: failed to load firmware %s\n", mach->sof_fw_filename); + goto release_regions; } + return ret; + +release_regions: + pci_release_regions(pci); +disable_dev: + pci_disable_device(pci); + return ret; } @@ -289,11 +302,19 @@ static void sof_pci_remove(struct pci_dev *pci) struct sof_pci_priv *priv = pci_get_drvdata(pci); struct snd_sof_pdata *sof_pdata = priv->sof_pdata; + /* unregister machine driver */ platform_device_unregister(sof_pdata->pdev_mach); + + /* unregister sof-audio platform driver */ if (!IS_ERR_OR_NULL(priv->pdev_pcm)) platform_device_unregister(priv->pdev_pcm); + + /* release firmware */ release_firmware(sof_pdata->fw); + + /* release pci regions and disable device */ pci_release_regions(pci); + pci_disable_device(pci); } /* PCI IDs */ diff --git a/sound/soc/sof/utils.c b/sound/soc/sof/utils.c index 8f2116a453526e..215ea84dfe7e68 100644 --- a/sound/soc/sof/utils.c +++ b/sound/soc/sof/utils.c @@ -26,9 +26,9 @@ int sof_bes_setup(struct device *dev, struct snd_sof_dsp_ops *ops, /* set up BE dai_links */ for (i = 0; i < link_num; i++) { snprintf(name, 32, "NoCodec-%d", i); - links[i].name = kmemdup(name, sizeof(name), GFP_KERNEL); + links[i].name = devm_kstrdup(dev, name, GFP_KERNEL); if (!links[i].name) - goto no_mem; + return -ENOMEM; links[i].id = i; links[i].no_pcm = 1; @@ -44,12 +44,6 @@ int sof_bes_setup(struct device *dev, struct snd_sof_dsp_ops *ops, card->num_links = link_num; return 0; -no_mem: - /* free allocated memories and return error */ - for (; i > 0; i--) - kfree(links[i - 1].name); - - return -ENOMEM; } EXPORT_SYMBOL(sof_bes_setup);