Skip to content
  • Rafael J. Wysocki's avatar
    7482c5cb
    PM: ACPI: PCI: Drop acpi_pm_set_bridge_wakeup() · 7482c5cb
    Rafael J. Wysocki authored
    
    
    The idea behind acpi_pm_set_bridge_wakeup() was to allow bridges to
    be reference counted for wakeup enabling, because they may be enabled
    to signal wakeup on behalf of their subordinate devices and that
    may happen for multiple times in a row, whereas for the other devices
    it only makes sense to enable wakeup signaling once.
    
    However, this becomes problematic if the bridge itself is suspended,
    because it is treated as a "regular" device in that case and the
    reference counting doesn't work.
    
    For instance, suppose that there are two devices below a bridge and
    they both can signal wakeup.  Every time one of them is suspended,
    wakeup signaling is enabled for the bridge, so when they both have
    been suspended, the bridge's wakeup reference counter value is 2.
    
    Say that the bridge is suspended subsequently and acpi_pci_wakeup()
    is called for it.  Because the bridge can signal wakeup, that
    function will invoke acpi_pm_set_device_wakeup() to configure it
    and __acpi_pm_set_device_wakeup() will be called with the last
    argument equal to 1.  This causes __acpi_device_wakeup_enable()
    invoked by it to omit the reference counting, because the reference
    counter of the target device (the bridge) is 2 at that time.
    
    Now say that the bridge resumes and one of the device below it
    resumes too, so the bridge's reference counter becomes 0 and
    wakeup signaling is disabled for it, but there is still the other
    suspended device which may need the bridge to signal wakeup on its
    behalf and that is not going to work.
    
    To address this scenario, use wakeup enable reference counting for
    all devices, not just for bridges, so drop the last argument from
    __acpi_device_wakeup_enable() and __acpi_pm_set_device_wakeup(),
    which causes acpi_pm_set_device_wakeup() and
    acpi_pm_set_bridge_wakeup() to become identical, so drop the latter
    and use the former instead of it everywhere.
    
    Fixes: 1ba51a7c ("ACPI / PCI / PM: Rework acpi_pci_propagate_wakeup()")
    Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
    Reviewed-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
    Acked-by: default avatarBjorn Helgaas <bhelgaas@google.com>
    Cc: 4.14+ <stable@vger.kernel.org> # 4.14+
    7482c5cb
    PM: ACPI: PCI: Drop acpi_pm_set_bridge_wakeup()
    Rafael J. Wysocki authored
    
    
    The idea behind acpi_pm_set_bridge_wakeup() was to allow bridges to
    be reference counted for wakeup enabling, because they may be enabled
    to signal wakeup on behalf of their subordinate devices and that
    may happen for multiple times in a row, whereas for the other devices
    it only makes sense to enable wakeup signaling once.
    
    However, this becomes problematic if the bridge itself is suspended,
    because it is treated as a "regular" device in that case and the
    reference counting doesn't work.
    
    For instance, suppose that there are two devices below a bridge and
    they both can signal wakeup.  Every time one of them is suspended,
    wakeup signaling is enabled for the bridge, so when they both have
    been suspended, the bridge's wakeup reference counter value is 2.
    
    Say that the bridge is suspended subsequently and acpi_pci_wakeup()
    is called for it.  Because the bridge can signal wakeup, that
    function will invoke acpi_pm_set_device_wakeup() to configure it
    and __acpi_pm_set_device_wakeup() will be called with the last
    argument equal to 1.  This causes __acpi_device_wakeup_enable()
    invoked by it to omit the reference counting, because the reference
    counter of the target device (the bridge) is 2 at that time.
    
    Now say that the bridge resumes and one of the device below it
    resumes too, so the bridge's reference counter becomes 0 and
    wakeup signaling is disabled for it, but there is still the other
    suspended device which may need the bridge to signal wakeup on its
    behalf and that is not going to work.
    
    To address this scenario, use wakeup enable reference counting for
    all devices, not just for bridges, so drop the last argument from
    __acpi_device_wakeup_enable() and __acpi_pm_set_device_wakeup(),
    which causes acpi_pm_set_device_wakeup() and
    acpi_pm_set_bridge_wakeup() to become identical, so drop the latter
    and use the former instead of it everywhere.
    
    Fixes: 1ba51a7c ("ACPI / PCI / PM: Rework acpi_pci_propagate_wakeup()")
    Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
    Reviewed-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
    Acked-by: default avatarBjorn Helgaas <bhelgaas@google.com>
    Cc: 4.14+ <stable@vger.kernel.org> # 4.14+
Loading