From: Ranjani Sridharan <ranjani.sridha...@linux.intel.com>

[ Upstream commit ef9bec27485fefb6b93168fea73fda0dc9638046 ]

snd_hdac_ext_bus_device_exit() has been recently modified
to no longer free the hdac device. SOF allocates memory for
hdac_device and hda_hda_priv with kzalloc. Make them
device-managed instead so that they will be freed when the
SOF driver is unloaded.

Because of the above change, hda_codec is device-managed and
it will be freed when the ASoC device is removed. Freeing
the codec in snd_hda_codec_dev_release() leads to kernel
panic while unloading and reloading the ASoC driver. So,
avoid freeing the hda_codec for ASoC driver. This is done in
the same patch to avoid bisect failure.

Signed-off-by: Libin Yang <libin.y...@intel.com>
Signed-off-by: Ranjani Sridharan <ranjani.sridha...@linux.intel.com>
Reviewed-by: Takashi Iwai <ti...@suse.de>
Link: 
https://lore.kernel.org/r/20190626070450.7229-1-ranjani.sridha...@linux.intel.com
Signed-off-by: Mark Brown <broo...@kernel.org>
Signed-off-by: Sasha Levin <sas...@kernel.org>
---
 sound/pci/hda/hda_codec.c       | 8 +++++++-
 sound/soc/sof/intel/hda-codec.c | 6 ++----
 2 files changed, 9 insertions(+), 5 deletions(-)

diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 106328584998f..c2a6554c98776 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -846,7 +846,13 @@ static void snd_hda_codec_dev_release(struct device *dev)
        snd_hda_sysfs_clear(codec);
        kfree(codec->modelname);
        kfree(codec->wcaps);
-       kfree(codec);
+
+       /*
+        * In the case of ASoC HD-audio, hda_codec is device managed.
+        * It will be freed when the ASoC device is removed.
+        */
+       if (codec->core.type == HDA_DEV_LEGACY)
+               kfree(codec);
 }
 
 #define DEV_NAME_LEN 31
diff --git a/sound/soc/sof/intel/hda-codec.c b/sound/soc/sof/intel/hda-codec.c
index b8b37f0823094..0d8437b080bfa 100644
--- a/sound/soc/sof/intel/hda-codec.c
+++ b/sound/soc/sof/intel/hda-codec.c
@@ -62,8 +62,7 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int 
address)
                address, resp);
 
 #if IS_ENABLED(CONFIG_SND_SOC_SOF_HDA_AUDIO_CODEC)
-       /* snd_hdac_ext_bus_device_exit will use kfree to free hdev */
-       hda_priv = kzalloc(sizeof(*hda_priv), GFP_KERNEL);
+       hda_priv = devm_kzalloc(sdev->dev, sizeof(*hda_priv), GFP_KERNEL);
        if (!hda_priv)
                return -ENOMEM;
 
@@ -82,8 +81,7 @@ static int hda_codec_probe(struct snd_sof_dev *sdev, int 
address)
 
        return 0;
 #else
-       /* snd_hdac_ext_bus_device_exit will use kfree to free hdev */
-       hdev = kzalloc(sizeof(*hdev), GFP_KERNEL);
+       hdev = devm_kzalloc(sdev->dev, sizeof(*hdev), GFP_KERNEL);
        if (!hdev)
                return -ENOMEM;
 
-- 
2.20.1



Reply via email to