Unverified Commit 87a36978 authored by Mark Brown's avatar Mark Brown
Browse files

ASoC: SOF/soundwire: use resume_and_get on component probe

Merge series from Pierre-Louis Bossart <pierre-louis.bossart@linux.intel.com>:

While testing driver bind/unbind sequences, I stumbled on a corner
case where the SoundWire bus can be suspended before the ASoC card
registration happens. During the registration, register accesses would
then lead to timeouts. This does not happen in regular usages where
the card registration happens within the 3-second time window before
suspend.

Adding a simple pm_runtime_resume_and_get() on component probe solves
the issue, but experiments showed it was too invasive to add at the
ASoC core level, with multiple regressions reported by our CI.

This patchset limits the additional resume to the SOF and SoundWire
codec drivers. An additional patch for the soundwire/intel component
will be sent separately.
parents 6c9e9046 011e397f
Loading
Loading
Loading
Loading
+13 −1
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/slab.h>
#include <linux/cdev.h>
@@ -440,8 +441,19 @@ const struct snd_soc_component_driver soc_codec_dev_max98373 = {
};
EXPORT_SYMBOL_GPL(soc_codec_dev_max98373);

static int max98373_sdw_probe(struct snd_soc_component *component)
{
	int ret;

	ret = pm_runtime_resume(component->dev);
	if (ret < 0 && ret != -EACCES)
		return ret;

	return 0;
}

const struct snd_soc_component_driver soc_codec_dev_max98373_sdw = {
	.probe			= NULL,
	.probe			= max98373_sdw_probe,
	.controls		= max98373_snd_controls,
	.num_controls		= ARRAY_SIZE(max98373_snd_controls),
	.dapm_widgets		= max98373_dapm_widgets,
+12 −0
Original line number Diff line number Diff line
@@ -608,7 +608,19 @@ static const struct sdw_slave_ops rt1308_slave_ops = {
	.bus_config = rt1308_bus_config,
};

static int rt1308_sdw_component_probe(struct snd_soc_component *component)
{
	int ret;

	ret = pm_runtime_resume(component->dev);
	if (ret < 0 && ret != -EACCES)
		return ret;

	return 0;
}

static const struct snd_soc_component_driver soc_component_sdw_rt1308 = {
	.probe = rt1308_sdw_component_probe,
	.controls = rt1308_snd_controls,
	.num_controls = ARRAY_SIZE(rt1308_snd_controls),
	.dapm_widgets = rt1308_dapm_widgets,
+12 −0
Original line number Diff line number Diff line
@@ -590,7 +590,19 @@ static struct sdw_slave_ops rt1316_slave_ops = {
	.update_status = rt1316_update_status,
};

static int rt1316_sdw_component_probe(struct snd_soc_component *component)
{
	int ret;

	ret = pm_runtime_resume(component->dev);
	if (ret < 0 && ret != -EACCES)
		return ret;

	return 0;
}

static const struct snd_soc_component_driver soc_component_sdw_rt1316 = {
	.probe = rt1316_sdw_component_probe,
	.controls = rt1316_snd_controls,
	.num_controls = ARRAY_SIZE(rt1316_snd_controls),
	.dapm_widgets = rt1316_dapm_widgets,
+5 −0
Original line number Diff line number Diff line
@@ -818,9 +818,14 @@ static const struct snd_soc_dapm_route rt700_audio_map[] = {
static int rt700_probe(struct snd_soc_component *component)
{
	struct rt700_priv *rt700 = snd_soc_component_get_drvdata(component);
	int ret;

	rt700->component = component;

	ret = pm_runtime_resume(component->dev);
	if (ret < 0 && ret != -EACCES)
		return ret;

	return 0;
}

+5 −0
Original line number Diff line number Diff line
@@ -1194,10 +1194,15 @@ static int rt711_sdca_parse_dt(struct rt711_sdca_priv *rt711, struct device *dev
static int rt711_sdca_probe(struct snd_soc_component *component)
{
	struct rt711_sdca_priv *rt711 = snd_soc_component_get_drvdata(component);
	int ret;

	rt711_sdca_parse_dt(rt711, &rt711->slave->dev);
	rt711->component = component;

	ret = pm_runtime_resume(component->dev);
	if (ret < 0 && ret != -EACCES)
		return ret;

	return 0;
}

Loading