This patchset fixes a race condition when a SoundWire codec signals an 'Alert' status during a system suspend, which can happen when e.g. a jack detection event is detected and handled in a workqueue scheduled after the link is suspended.
When this happens in pm_runtime suspend, we already use pm_runtime_get_resume() to force the link to remain active, or resume immediately, but during a system suspend we don't have this option: we can't prevent the entire system from suspending just because of a jack detection or codec-specific event.
This patch suggests instead disabling the implementation-defined or class-defined IRQs at the start of the suspend, along with an additional flag to protect against an interrupt thread/workqueue being scheduled after the interrupts are disabled.
One could argue that the SoundWire core could have handled this case, which is a fair objection. I chose to keep the interrupt handling codec-specific since not all codecs can actually generate interrupts, and what they do during these interrupts is also quite custom - see e.g. the difference between the RT711 and RT711-SDCA versions. In the latter case the class-defined interrupts are cleared by the codec driver, not by the core.
This patchset implies changes to both ASoC and SoundWire, with a minimal dependency on a sdw_update() helper and its _no_pm version, both of which should have been added a long time ago for read-modify-write operations.
This race condition was present in all previous kernel versions but was only identified in late May in automated tests. We added Fixes tag to help linux-stable backports, but there's no real point in back-porting to earlier than 5.10 due to other missing dependencies in the upstream code.
Pierre-Louis Bossart (5): soundwire: export sdw_update() and sdw_update_no_pm() ASoC: rt700-sdw: fix race condition on system suspend ASoC: rt711-sdw: fix race condition on system suspend ASoC: rt5682-sdw: fix race condition on system suspend ASoC: rt711-sdca-sdw: fix race condition on system suspend
drivers/soundwire/bus.c | 17 +++++++++++- drivers/soundwire/bus.h | 13 --------- include/linux/soundwire/sdw.h | 3 ++ sound/soc/codecs/rt5682-sdw.c | 38 +++++++++++++++++++++++-- sound/soc/codecs/rt5682.h | 2 ++ sound/soc/codecs/rt700-sdw.c | 34 +++++++++++++++++++++-- sound/soc/codecs/rt700.c | 4 +++ sound/soc/codecs/rt700.h | 2 ++ sound/soc/codecs/rt711-sdca-sdw.c | 46 +++++++++++++++++++++++++++++-- sound/soc/codecs/rt711-sdca.c | 4 +++ sound/soc/codecs/rt711-sdca.h | 2 ++ sound/soc/codecs/rt711-sdw.c | 34 +++++++++++++++++++++-- sound/soc/codecs/rt711.c | 4 +++ sound/soc/codecs/rt711.h | 2 ++ 14 files changed, 183 insertions(+), 22 deletions(-)
base-commit: bf28c803f2f4b14716df168e98f6ede4ba955866