summaryrefslogtreecommitdiffstats
path: root/drivers/pci/pci-acpi.c
diff options
context:
space:
mode:
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>2017-06-12 22:48:41 +0200
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2017-06-15 00:55:42 +0200
commit64fd1c7040880292710e6592ddc88d0d73cfb6fb (patch)
tree8b0527537fdc5cadd399266cdd3741188a6212d4 /drivers/pci/pci-acpi.c
parentLinux 4.12-rc5 (diff)
downloadlinux-64fd1c7040880292710e6592ddc88d0d73cfb6fb.tar.xz
linux-64fd1c7040880292710e6592ddc88d0d73cfb6fb.zip
ACPI / PM: Run wakeup notify handlers synchronously
The work functions provided by the users of acpi_add_pm_notifier() should be run synchronously before re-enabling the wakeup GPE in case they are used to clear the status and/or disable the wakeup signaling at the source. Otherwise, which is the case currently in the PCI bus type code, the same wakeup event may be signaled for multiple times while the execution of the work function in response to it has already been queued up. Fortunately, acpi_add_pm_notifier() is only used by PCI and by ACPI device PM code internally, so the change is relatively straightforward to make. Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Acked-by: Bjorn Helgaas <bhelgaas@google.com>
Diffstat (limited to 'drivers/pci/pci-acpi.c')
-rw-r--r--drivers/pci/pci-acpi.c17
1 files changed, 7 insertions, 10 deletions
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c
index 001860361434..9284ae6f669a 100644
--- a/drivers/pci/pci-acpi.c
+++ b/drivers/pci/pci-acpi.c
@@ -395,29 +395,26 @@ bool pciehp_is_native(struct pci_dev *pdev)
/**
* pci_acpi_wake_bus - Root bus wakeup notification fork function.
- * @work: Work item to handle.
+ * @context: Device wakeup context.
*/
-static void pci_acpi_wake_bus(struct work_struct *work)
+static void pci_acpi_wake_bus(struct acpi_device_wakeup_context *context)
{
struct acpi_device *adev;
struct acpi_pci_root *root;
- adev = container_of(work, struct acpi_device, wakeup.context.work);
+ adev = container_of(context, struct acpi_device, wakeup.context);
root = acpi_driver_data(adev);
pci_pme_wakeup_bus(root->bus);
}
/**
* pci_acpi_wake_dev - PCI device wakeup notification work function.
- * @handle: ACPI handle of a device the notification is for.
- * @work: Work item to handle.
+ * @context: Device wakeup context.
*/
-static void pci_acpi_wake_dev(struct work_struct *work)
+static void pci_acpi_wake_dev(struct acpi_device_wakeup_context *context)
{
- struct acpi_device_wakeup_context *context;
struct pci_dev *pci_dev;
- context = container_of(work, struct acpi_device_wakeup_context, work);
pci_dev = to_pci_dev(context->dev);
if (pci_dev->pme_poll)
@@ -425,7 +422,7 @@ static void pci_acpi_wake_dev(struct work_struct *work)
if (pci_dev->current_state == PCI_D3cold) {
pci_wakeup_event(pci_dev);
- pm_runtime_resume(&pci_dev->dev);
+ pm_request_resume(&pci_dev->dev);
return;
}
@@ -434,7 +431,7 @@ static void pci_acpi_wake_dev(struct work_struct *work)
pci_check_pme_status(pci_dev);
pci_wakeup_event(pci_dev);
- pm_runtime_resume(&pci_dev->dev);
+ pm_request_resume(&pci_dev->dev);
pci_pme_wakeup_bus(pci_dev->subordinate);
}