summaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2018-08-30 15:13:16 +0200
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-09-19 22:47:10 +0200
commit50cad8ddc49db7467dac9f243ad80ac026f938e5 (patch)
treedd5c93ab281e03f6b22dca57175a7eed7453e69f /sound
parent2fdd661abee33f83cb57c4bccf40c951a5d29cd3 (diff)
downloadlinux-stable-50cad8ddc49db7467dac9f243ad80ac026f938e5.tar.gz
linux-stable-50cad8ddc49db7467dac9f243ad80ac026f938e5.tar.bz2
linux-stable-50cad8ddc49db7467dac9f243ad80ac026f938e5.zip
ALSA: hda - Fix cancel_work_sync() stall from jackpoll work
commit 16037643969e095509cd8446a3f8e406a6dc3a2c upstream. On AMD/ATI controllers, the HD-audio controller driver allows a bus reset upon the error recovery, and its procedure includes the cancellation of pending jack polling work as found in snd_hda_bus_codec_reset(). This works usually fine, but it becomes a problem when the reset happens from the jack poll work itself; then calling cancel_work_sync() from the work being processed tries to wait the finish endlessly. As a workaround, this patch adds the check of current_work() and applies the cancel_work_sync() only when it's not from the jackpoll_work. This doesn't fix the root cause of the reported error below, but at least, it eases the unexpected stall of the whole system. Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=200937 Cc: <stable@vger.kernel.org> Cc: Lukas Wunner <lukas@wunner.de> Signed-off-by: Takashi Iwai <tiwai@suse.de> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'sound')
-rw-r--r--sound/pci/hda/hda_codec.c3
1 files changed, 2 insertions, 1 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index e46c561a8c90..c6b046ddefdd 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -4025,7 +4025,8 @@ void snd_hda_bus_reset_codecs(struct hda_bus *bus)
list_for_each_codec(codec, bus) {
/* FIXME: maybe a better way needed for forced reset */
- cancel_delayed_work_sync(&codec->jackpoll_work);
+ if (current_work() != &codec->jackpoll_work.work)
+ cancel_delayed_work_sync(&codec->jackpoll_work);
#ifdef CONFIG_PM
if (hda_codec_is_power_on(codec)) {
hda_call_codec_suspend(codec);