Skip to contentSkip to conversation

FAILED: patch "[PATCH] ALSA: hda: Fix unhandled register update during auto-suspend" failed to apply to 5.4-stable tree

PATCH [email protected] 1 participant 1 message May 26, 2023

Subsystems (2)
lore
Share & tools
lore

[email protected]

author maintainer
#0 lore raw

The patch below does not apply to the 5.4-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.

To reproduce the conflict and resubmit, you may use the following commands:

git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-5.4.y
git checkout FETCH_HEAD
git cherry-pick -x 81302b1c7c997e8a56c1c2fc63a296ebeb0cd2d0
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2023052649-kilt-concert-cd8a@gregkh' --subject-prefix 'PATCH 5.4.y' HEAD^..

Possible dependencies:

81302b1c7c99 ("ALSA: hda: Fix unhandled register update during auto-suspend period")

thanks,

greg k-h

------------------ original commit in Linus's tree ------------------

From 81302b1c7c997e8a56c1c2fc63a296ebeb0cd2d0 Mon Sep 17 00:00:00 2001
From: Takashi Iwai <[email protected]>
Date: Thu, 18 May 2023 13:35:20 +0200
Subject: [PATCH] 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

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().

sound/hda/hdac_device.c +1 -1
index accc9d279ce5..6c043fbd606f 100644
@@ -611,7 +611,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)