Blob Blame History Raw
From 82027585fce0c5e78e666cfbd0066fe3c80070dd Mon Sep 17 00:00:00 2001
From: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Date: Fri, 13 Aug 2021 10:11:13 -0500
Subject: [PATCH] ASoC: Intel: sof_sdw_rt711*: keep codec device reference until remove
Git-commit: 82027585fce0c5e78e666cfbd0066fe3c80070dd
Patch-mainline: v5.15-rc1
References: bsc#1192354

Follow the example of Intel Atom drivers and keep a reference to the
headset codec until the properties are removed.

There is no guarantee that the module for the codec driver is loaded
before the machine driver probe, the use of the deferred probe
mechanism is required.

Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Hans de Goede <hdegoede@redhat.com>
Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
Link: https://lore.kernel.org/r/20210813151116.23931-6-pierre-louis.bossart@linux.intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Acked-by: Takashi Iwai <tiwai@suse.de>

---
 sound/soc/intel/boards/sof_sdw_rt711.c      | 44 +++++++++------------
 sound/soc/intel/boards/sof_sdw_rt711_sdca.c | 43 +++++++++-----------
 2 files changed, 38 insertions(+), 49 deletions(-)

diff --git a/sound/soc/intel/boards/sof_sdw_rt711.c b/sound/soc/intel/boards/sof_sdw_rt711.c
index 8a6a17fe676e..510301e09b09 100644
--- a/sound/soc/intel/boards/sof_sdw_rt711.c
+++ b/sound/soc/intel/boards/sof_sdw_rt711.c
@@ -21,25 +21,15 @@
  * Note this MUST be called before snd_soc_register_card(), so that the props
  * are in place before the codec component driver's probe function parses them.
  */
-static int rt711_add_codec_device_props(const char *sdw_dev_name)
+static int rt711_add_codec_device_props(struct device *sdw_dev)
 {
 	struct property_entry props[MAX_NO_PROPS] = {};
-	struct device *sdw_dev;
-	int ret;
-
-	sdw_dev = bus_find_device_by_name(&sdw_bus_type, NULL, sdw_dev_name);
-	if (!sdw_dev)
-		return -EPROBE_DEFER;
 
-	if (SOF_RT711_JDSRC(sof_sdw_quirk)) {
-		props[0] = PROPERTY_ENTRY_U32("realtek,jd-src",
-					      SOF_RT711_JDSRC(sof_sdw_quirk));
-	}
-
-	ret = device_add_properties(sdw_dev, props);
-	put_device(sdw_dev);
+	if (!SOF_RT711_JDSRC(sof_sdw_quirk))
+		return 0;
+	props[0] = PROPERTY_ENTRY_U32("realtek,jd-src", SOF_RT711_JDSRC(sof_sdw_quirk));
 
-	return ret;
+	return device_add_properties(sdw_dev, props);
 }
 
 static const struct snd_soc_dapm_widget rt711_widgets[] = {
@@ -137,15 +127,10 @@ static int rt711_rtd_init(struct snd_soc_pcm_runtime *rtd)
 
 int sof_sdw_rt711_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link)
 {
-	struct device *sdw_dev;
-
-	sdw_dev = bus_find_device_by_name(&sdw_bus_type, NULL,
-					  dai_link->codecs[0].name);
-	if (!sdw_dev)
-		return -EINVAL;
+	struct mc_private *ctx = snd_soc_card_get_drvdata(card);
 
-	device_remove_properties(sdw_dev);
-	put_device(sdw_dev);
+	device_remove_properties(ctx->headset_codec_dev);
+	put_device(ctx->headset_codec_dev);
 
 	return 0;
 }
@@ -156,6 +141,8 @@ int sof_sdw_rt711_init(struct snd_soc_card *card,
 		       struct sof_sdw_codec_info *info,
 		       bool playback)
 {
+	struct mc_private *ctx = snd_soc_card_get_drvdata(card);
+	struct device *sdw_dev;
 	int ret;
 
 	/*
@@ -165,9 +152,16 @@ int sof_sdw_rt711_init(struct snd_soc_card *card,
 	if (!playback)
 		return 0;
 
-	ret = rt711_add_codec_device_props(dai_links->codecs[0].name);
-	if (ret < 0)
+	sdw_dev = bus_find_device_by_name(&sdw_bus_type, NULL, dai_links->codecs[0].name);
+	if (!sdw_dev)
+		return -EPROBE_DEFER;
+
+	ret = rt711_add_codec_device_props(sdw_dev);
+	if (ret < 0) {
+		put_device(sdw_dev);
 		return ret;
+	}
+	ctx->headset_codec_dev = sdw_dev;
 
 	dai_links->init = rt711_rtd_init;
 
diff --git a/sound/soc/intel/boards/sof_sdw_rt711_sdca.c b/sound/soc/intel/boards/sof_sdw_rt711_sdca.c
index 1ae66f266c6c..94af40e2beb0 100644
--- a/sound/soc/intel/boards/sof_sdw_rt711_sdca.c
+++ b/sound/soc/intel/boards/sof_sdw_rt711_sdca.c
@@ -21,25 +21,16 @@
  * Note this MUST be called before snd_soc_register_card(), so that the props
  * are in place before the codec component driver's probe function parses them.
  */
-static int rt711_sdca_add_codec_device_props(const char *sdw_dev_name)
+static int rt711_sdca_add_codec_device_props(struct device *sdw_dev)
 {
 	struct property_entry props[MAX_NO_PROPS] = {};
-	struct device *sdw_dev;
-	int ret;
-
-	sdw_dev = bus_find_device_by_name(&sdw_bus_type, NULL, sdw_dev_name);
-	if (!sdw_dev)
-		return -EPROBE_DEFER;
 
-	if (SOF_RT711_JDSRC(sof_sdw_quirk)) {
-		props[0] = PROPERTY_ENTRY_U32("realtek,jd-src",
-					      SOF_RT711_JDSRC(sof_sdw_quirk));
-	}
+	if (!SOF_RT711_JDSRC(sof_sdw_quirk))
+		return 0;
 
-	ret = device_add_properties(sdw_dev, props);
-	put_device(sdw_dev);
+	props[0] = PROPERTY_ENTRY_U32("realtek,jd-src", SOF_RT711_JDSRC(sof_sdw_quirk));
 
-	return ret;
+	return device_add_properties(sdw_dev, props);
 }
 
 static const struct snd_soc_dapm_widget rt711_sdca_widgets[] = {
@@ -137,15 +128,10 @@ static int rt711_sdca_rtd_init(struct snd_soc_pcm_runtime *rtd)
 
 int sof_sdw_rt711_sdca_exit(struct snd_soc_card *card, struct snd_soc_dai_link *dai_link)
 {
-	struct device *sdw_dev;
-
-	sdw_dev = bus_find_device_by_name(&sdw_bus_type, NULL,
-					  dai_link->codecs[0].name);
-	if (!sdw_dev)
-		return -EINVAL;
+	struct mc_private *ctx = snd_soc_card_get_drvdata(card);
 
-	device_remove_properties(sdw_dev);
-	put_device(sdw_dev);
+	device_remove_properties(ctx->headset_codec_dev);
+	put_device(ctx->headset_codec_dev);
 
 	return 0;
 }
@@ -156,6 +142,8 @@ int sof_sdw_rt711_sdca_init(struct snd_soc_card *card,
 			    struct sof_sdw_codec_info *info,
 			    bool playback)
 {
+	struct mc_private *ctx = snd_soc_card_get_drvdata(card);
+	struct device *sdw_dev;
 	int ret;
 
 	/*
@@ -165,9 +153,16 @@ int sof_sdw_rt711_sdca_init(struct snd_soc_card *card,
 	if (!playback)
 		return 0;
 
-	ret = rt711_sdca_add_codec_device_props(dai_links->codecs[0].name);
-	if (ret < 0)
+	sdw_dev = bus_find_device_by_name(&sdw_bus_type, NULL, dai_links->codecs[0].name);
+	if (!sdw_dev)
+		return -EPROBE_DEFER;
+
+	ret = rt711_sdca_add_codec_device_props(sdw_dev);
+	if (ret < 0) {
+		put_device(sdw_dev);
 		return ret;
+	}
+	ctx->headset_codec_dev = sdw_dev;
 
 	dai_links->init = rt711_sdca_rtd_init;
 
-- 
2.26.2