• Takashi Iwai's avatar
    ALSA: hda: Fix unhandled register update during auto-suspend period · 81302b1c
    Takashi Iwai authored
    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: fc4f000b ("ALSA: hda - Fix unexpected resume through regmap code path")
    Reported-by: default avatarAmadeusz Sławiński <amadeuszx.slawinski@linux.intel.com>
    Closes: https://lore.kernel.org/r/a7478636-af11-92ab-731c-9b13c582a70d@linux.intel.comSuggested-by: default avatarCezary Rojewski <cezary.rojewski@intel.com>
    Cc: <stable@vger.kernel.org>
    Link: https://lore.kernel.org/r/20230518113520.15213-1-tiwai@suse.deSigned-off-by: default avatarTakashi Iwai <tiwai@suse.de>
    81302b1c
hdac_device.c 27.5 KB