Unverified Commit 27e05fcb authored by Mark Brown's avatar Mark Brown
Browse files

ASoC: harden SoundWire codec/machine drivers used on Intel platforms

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

While testing fixes for SoundWire race conditions initially reported
in [1], I found additional issues in codec drivers. When the order in
which drivers are probed is changed, multiple errors are reported,
from unbalanced pm_runtime_enable() calls to invalid mutex lock magic
numbers, workqueues not initialized and missing resume sequences.

In 'nominal' usages, there is no change of functionality, this is just
a first step to test random device/driver bind/unbind sequences.

Important note: these changes only touch Intel-based platforms, I
don't have any background and ability to test on Qualcomm-based
devices.

[1] https://lore.kernel.org/alsa-devel/d0559e97-c4a0-b817-428c-d3e305390270@linux.intel.com/

Pierre-Louis Bossart (7):
  ASoC: Realtek/Maxim SoundWire codecs: disable pm_runtime on remove
  ASoC: rt711-sdca-sdw: fix calibrate mutex initialization
  ASoC: Intel: sof_sdw: handle errors on card registration
  ASoC: rt711: fix calibrate mutex initialization
  ASoC: rt7*-sdw: harden jack_detect_handler
  ASoC: codecs: rt700/rt711/rt711-sdca: initialize workqueues in probe
  ASoC: codecs: rt700/rt711/rt711-sdca: resume bus/codec in
    .set_jack_detect

 sound/soc/codecs/max98373-sdw.c   | 12 +++++++-
 sound/soc/codecs/rt1308-sdw.c     | 11 +++++++
 sound/soc/codecs/rt1316-sdw.c     | 11 +++++++
 sound/soc/codecs/rt5682-sdw.c     |  5 ++-
 sound/soc/codecs/rt700-sdw.c      |  6 +++-
 sound/soc/codecs/rt700.c          | 30 +++++++++++-------
 sound/soc/codecs/rt711-sdca-sdw.c |  9 +++++-
 sound/soc/codecs/rt711-sdca.c     | 40 ++++++++++++------------
 sound/soc/codecs/rt711-sdw.c      |  9 +++++-
 sound/soc/codecs/rt711.c          | 40 ++++++++++++------------
 sound/soc/codecs/rt715-sdca-sdw.c | 12 ++++++++
 sound/soc/codecs/rt715-sdw.c      | 12 ++++++++
 sound/soc/intel/boards/sof_sdw.c  | 51 ++++++++++++++++++-------------
 13 files changed, 169 insertions(+), 79 deletions(-)

--
2.34.1
parents 5871321f e02b99e9
Loading
Loading
Loading
Loading
+11 −1
Original line number Diff line number Diff line
@@ -862,6 +862,16 @@ static int max98373_sdw_probe(struct sdw_slave *slave,
	return max98373_init(slave, regmap);
}

static int max98373_sdw_remove(struct sdw_slave *slave)
{
	struct max98373_priv *max98373 = dev_get_drvdata(&slave->dev);

	if (max98373->first_hw_init)
		pm_runtime_disable(&slave->dev);

	return 0;
}

#if defined(CONFIG_OF)
static const struct of_device_id max98373_of_match[] = {
	{ .compatible = "maxim,max98373", },
@@ -893,7 +903,7 @@ static struct sdw_driver max98373_sdw_driver = {
		.pm = &max98373_pm,
	},
	.probe = max98373_sdw_probe,
	.remove = NULL,
	.remove = max98373_sdw_remove,
	.ops = &max98373_slave_ops,
	.id_table = max98373_id,
};
+11 −0
Original line number Diff line number Diff line
@@ -691,6 +691,16 @@ static int rt1308_sdw_probe(struct sdw_slave *slave,
	return 0;
}

static int rt1308_sdw_remove(struct sdw_slave *slave)
{
	struct rt1308_sdw_priv *rt1308 = dev_get_drvdata(&slave->dev);

	if (rt1308->first_hw_init)
		pm_runtime_disable(&slave->dev);

	return 0;
}

static const struct sdw_device_id rt1308_id[] = {
	SDW_SLAVE_ENTRY_EXT(0x025d, 0x1308, 0x2, 0, 0),
	{},
@@ -750,6 +760,7 @@ static struct sdw_driver rt1308_sdw_driver = {
		.pm = &rt1308_pm,
	},
	.probe = rt1308_sdw_probe,
	.remove = rt1308_sdw_remove,
	.ops = &rt1308_slave_ops,
	.id_table = rt1308_id,
};
+11 −0
Original line number Diff line number Diff line
@@ -676,6 +676,16 @@ static int rt1316_sdw_probe(struct sdw_slave *slave,
	return rt1316_sdw_init(&slave->dev, regmap, slave);
}

static int rt1316_sdw_remove(struct sdw_slave *slave)
{
	struct rt1316_sdw_priv *rt1316 = dev_get_drvdata(&slave->dev);

	if (rt1316->first_hw_init)
		pm_runtime_disable(&slave->dev);

	return 0;
}

static const struct sdw_device_id rt1316_id[] = {
	SDW_SLAVE_ENTRY_EXT(0x025d, 0x1316, 0x3, 0x1, 0),
	{},
@@ -735,6 +745,7 @@ static struct sdw_driver rt1316_sdw_driver = {
		.pm = &rt1316_pm,
	},
	.probe = rt1316_sdw_probe,
	.remove = rt1316_sdw_remove,
	.ops = &rt1316_slave_ops,
	.id_table = rt1316_id,
};
+4 −1
Original line number Diff line number Diff line
@@ -719,9 +719,12 @@ static int rt5682_sdw_remove(struct sdw_slave *slave)
{
	struct rt5682_priv *rt5682 = dev_get_drvdata(&slave->dev);

	if (rt5682 && rt5682->hw_init)
	if (rt5682->hw_init)
		cancel_delayed_work_sync(&rt5682->jack_detect_work);

	if (rt5682->first_hw_init)
		pm_runtime_disable(&slave->dev);

	return 0;
}

+5 −1
Original line number Diff line number Diff line
@@ -13,6 +13,7 @@
#include <linux/soundwire/sdw_type.h>
#include <linux/soundwire/sdw_registers.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <sound/soc.h>
#include "rt700.h"
@@ -463,11 +464,14 @@ static int rt700_sdw_remove(struct sdw_slave *slave)
{
	struct rt700_priv *rt700 = dev_get_drvdata(&slave->dev);

	if (rt700 && rt700->hw_init) {
	if (rt700->hw_init) {
		cancel_delayed_work_sync(&rt700->jack_detect_work);
		cancel_delayed_work_sync(&rt700->jack_btn_check_work);
	}

	if (rt700->first_hw_init)
		pm_runtime_disable(&slave->dev);

	return 0;
}

Loading