• Takashi Iwai's avatar
    ALSA: hda - Work around races of power up/down with runtime PM · 664c7155
    Takashi Iwai authored
    Currently, snd_hdac_power_up()/down() helpers checks whether the codec
    is being in pm (suspend/resume), and skips the call of runtime get/put
    during it.  This is needed as there are lots of power up/down
    sequences called in the paths that are also used in the PM itself.  An
    example is found in hda_codec.c::codec_exec_verb(), where this can
    power up the codec while it may be called again in its power up
    sequence, too.
    
    The above works in most cases, but sometimes we really want to wait
    for the real power up.  For example, the control element get/put may
    want explicit power up so that the value change is assured to reach to
    the hardware.   Using the current snd_hdac_power_up(), however,
    results in a race, e.g. when it's called during the runtime suspend is
    being performed.  In the worst case, as found in patch_ca0132.c, it
    can even lead to the deadlock because the code assumes the power up
    while it was skipped due to the check above.
    
    For dealing with such cases, this patch makes snd_hdac_power_up() and
    _down() to two variants: with and without in_pm flag check.  The
    version with pm flag check is named as snd_hdac_power_up_pm() while
    the version without pm flag check is still kept as
    snd_hdac_power_up().  (Just because the usage of the former is fewer.)
    
    Then finally, the patch replaces each call potentially done in PM with
    the new _pm() variant.
    
    In theory, we can implement a unified version -- if we can distinguish
    the current context whether it's in the pm path.  But such an
    implementation is cumbersome, so leave the code like this a bit messy
    way for now...
    
    Bugzilla: https://bugzilla.kernel.org/show_bug.cgi?id=96271Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
    664c7155
hdac_device.c 13.9 KB