Skip to content

Commit

Permalink
ASoC: Intel: sof_sdw_rt711*: keep codec device reference until remove
Browse files Browse the repository at this point in the history
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.

Signed-off-by: Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>
  • Loading branch information
plbossart committed Aug 12, 2021
1 parent 432939a commit f8b6c2b
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 49 deletions.
44 changes: 19 additions & 25 deletions sound/soc/intel/boards/sof_sdw_rt711.c
Original file line number Diff line number Diff line change
Expand Up @@ -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[] = {
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;

/*
Expand All @@ -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;

Expand Down
43 changes: 19 additions & 24 deletions sound/soc/intel/boards/sof_sdw_rt711_sdca.c
Original file line number Diff line number Diff line change
Expand Up @@ -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[] = {
Expand Down Expand Up @@ -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;
}
Expand All @@ -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;

/*
Expand All @@ -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;

Expand Down

0 comments on commit f8b6c2b

Please sign in to comment.