This is a note to let you know that I've just added the patch titled ALSA: hda: Fix unhandled register update during auto-suspend period to the 4.14-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: alsa-hda-fix-unhandled-register-update-during-auto-suspend-period.patch and it can be found in the queue-4.14 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@xxxxxxxxxxxxxxx> know about it. >From 81302b1c7c997e8a56c1c2fc63a296ebeb0cd2d0 Mon Sep 17 00:00:00 2001 From: Takashi Iwai <tiwai@xxxxxxx> Date: Thu, 18 May 2023 13:35:20 +0200 Subject: ALSA: hda: Fix unhandled register update during auto-suspend period MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From: Takashi Iwai <tiwai@xxxxxxx> commit 81302b1c7c997e8a56c1c2fc63a296ebeb0cd2d0 upstream. It's reported that the recording started right after the driver probe doesn't work properly, and it turned out that this is related with the codec auto-suspend. Namely, after the probe phase, the usage count goes zero, and the auto-suspend is programmed, but the codec is kept still active until the auto-suspend expiration. When an application (e.g. alsactl) updates the mixer values at this moment, the values are cached but not actually written. Then, starting arecord thereafter also results in the silence because of the missing unmute. The root cause is the handling of "lazy update" mode; when a mixer value is updated *after* the suspend, it should update only the cache and exits. At the resume, the cached value is written to the device, in turn. The problem is that the current code misinterprets the state of auto-suspend as if it were already suspended. Although we can add the check of the actual device state after pm_runtime_get_if_in_use() for catching the missing state, this won't suffice; the second call of regmap_update_bits_check() will skip writing the register because the cache has been already updated by the first call. So we'd need fixes in two different places. OTOH, a simpler fix is to replace pm_runtime_get_if_in_use() with pm_runtime_get_if_active() (with ign_usage_count=true). This change implies that the driver takes the pm refcount if the device is still in ACTIVE state and continues the processing. A small caveat is that this will leave the auto-suspend timer. But, since the timer callback itself checks the device state and aborts gracefully when it's active, this won't be any substantial problem. Long story short: we address the missing register-write problem just by replacing the pm_runtime_*() call in snd_hda_keep_power_up(). Fixes: fc4f000bf8c0 ("ALSA: hda - Fix unexpected resume through regmap code path") Reported-by: Amadeusz Sławiński <amadeuszx.slawinski@xxxxxxxxxxxxxxx> Closes: https://lore.kernel.org/r/a7478636-af11-92ab-731c-9b13c582a70d@xxxxxxxxxxxxxxx Suggested-by: Cezary Rojewski <cezary.rojewski@xxxxxxxxx> Cc: <stable@xxxxxxxxxxxxxxx> Link: https://lore.kernel.org/r/20230518113520.15213-1-tiwai@xxxxxxx Signed-off-by: Takashi Iwai <tiwai@xxxxxxx> Signed-off-by: Greg Kroah-Hartman <gregkh@xxxxxxxxxxxxxxxxxxx> --- sound/hda/hdac_device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) --- a/sound/hda/hdac_device.c +++ b/sound/hda/hdac_device.c @@ -619,7 +619,7 @@ EXPORT_SYMBOL_GPL(snd_hdac_power_up_pm); int snd_hdac_keep_power_up(struct hdac_device *codec) { if (!atomic_inc_not_zero(&codec->in_pm)) { - int ret = pm_runtime_get_if_in_use(&codec->dev); + int ret = pm_runtime_get_if_active(&codec->dev, true); if (!ret) return -1; if (ret < 0) Patches currently in stable-queue which might be from tiwai@xxxxxxx are queue-4.14/alsa-hda-fix-unhandled-register-update-during-auto-suspend-period.patch queue-4.14/alsa-hda-fix-oops-by-9.1-surround-channel-names.patch queue-4.14/alsa-hda-add-nvidia-codec-ids-a3-through-a7-to-patch-table.patch