• Rafael J. Wysocki's avatar
    ACPI: PM: Fix sharing of wakeup power resources · a2d7b2e0
    Rafael J. Wysocki authored
    If an ACPI wakeup power resource is shared between multiple devices,
    it may not be managed correctly.
    
    Suppose, for example, that two devices, A and B, share a wakeup power
    resource P whose wakeup_enabled flag is 0 initially.  Next, suppose
    that wakeup power is enabled for A and B, in this order, and disabled
    for B.  When wakeup power is enabled for A, P will be turned on and
    its wakeup_enabled flag will be set.  Next, when wakeup power is
    enabled for B, P will not be touched, because its wakeup_enabled flag
    is set.  Now, when wakeup power is disabled for B, P will be turned
    off which is incorrect, because A will still need P in order to signal
    wakeup.
    
    Moreover, if wakeup power is enabled for A and then disabled for B,
    the latter will cause P to be turned off incorrectly (it will be still
    needed by A), because acpi_disable_wakeup_device_power() is allowed
    to manipulate power resources when the wakeup.prepare_count counter
    of the given device is 0.
    
    While the first issue could be addressed by changing the
    wakeup_enabled power resource flag into a counter, addressing the
    second one requires modifying acpi_disable_wakeup_device_power() to
    do nothing when the target device's wakeup.prepare_count reference
    counter is zero and that would cause the new counter to be redundant.
    Namely, if acpi_disable_wakeup_device_power() is modified as per the
    above, every change of the new counter following a wakeup.prepare_count
    change would be reflected by the analogous change of the main reference
    counter of the given power resource.
    
    Accordingly, modify acpi_disable_wakeup_device_power() to do nothing
    when the target device's wakeup.prepare_count reference counter is
    zero and drop the power resource wakeup_enabled flag altogether.
    
    While at it, ensure that all of the power resources that can be
    turned off will be turned off when disabling device wakeup due to
    a power resource manipulation error, to prevent energy from being
    wasted.
    
    Fixes: b5d667eb ("ACPI / PM: Take unusual configurations of power resources into account")
    Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
    a2d7b2e0
power.c 25.7 KB