Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
[cascardo/linux.git] / drivers / pci / pci-acpi.c
index c5792d6..1af4008 100644 (file)
 
 #include <linux/pci-acpi.h>
 #include <linux/pm_runtime.h>
+#include <linux/pm_qos.h>
 #include "pci.h"
 
-static DEFINE_MUTEX(pci_acpi_pm_notify_mtx);
-
 /**
  * pci_acpi_wake_bus - Wake-up notification handler for root buses.
  * @handle: ACPI handle of a device the notification is for.
@@ -67,67 +66,6 @@ static void pci_acpi_wake_dev(acpi_handle handle, u32 event, void *context)
                pci_pme_wakeup_bus(pci_dev->subordinate);
 }
 
-/**
- * add_pm_notifier - Register PM notifier for given ACPI device.
- * @dev: ACPI device to add the notifier for.
- * @context: PCI device or bus to check for PME status if an event is signaled.
- *
- * NOTE: @dev need not be a run-wake or wake-up device to be a valid source of
- * PM wake-up events.  For example, wake-up events may be generated for bridges
- * if one of the devices below the bridge is signaling PME, even if the bridge
- * itself doesn't have a wake-up GPE associated with it.
- */
-static acpi_status add_pm_notifier(struct acpi_device *dev,
-                                  acpi_notify_handler handler,
-                                  void *context)
-{
-       acpi_status status = AE_ALREADY_EXISTS;
-
-       mutex_lock(&pci_acpi_pm_notify_mtx);
-
-       if (dev->wakeup.flags.notifier_present)
-               goto out;
-
-       status = acpi_install_notify_handler(dev->handle,
-                                            ACPI_SYSTEM_NOTIFY,
-                                            handler, context);
-       if (ACPI_FAILURE(status))
-               goto out;
-
-       dev->wakeup.flags.notifier_present = true;
-
- out:
-       mutex_unlock(&pci_acpi_pm_notify_mtx);
-       return status;
-}
-
-/**
- * remove_pm_notifier - Unregister PM notifier from given ACPI device.
- * @dev: ACPI device to remove the notifier from.
- */
-static acpi_status remove_pm_notifier(struct acpi_device *dev,
-                                     acpi_notify_handler handler)
-{
-       acpi_status status = AE_BAD_PARAMETER;
-
-       mutex_lock(&pci_acpi_pm_notify_mtx);
-
-       if (!dev->wakeup.flags.notifier_present)
-               goto out;
-
-       status = acpi_remove_notify_handler(dev->handle,
-                                           ACPI_SYSTEM_NOTIFY,
-                                           handler);
-       if (ACPI_FAILURE(status))
-               goto out;
-
-       dev->wakeup.flags.notifier_present = false;
-
- out:
-       mutex_unlock(&pci_acpi_pm_notify_mtx);
-       return status;
-}
-
 /**
  * pci_acpi_add_bus_pm_notifier - Register PM notifier for given PCI bus.
  * @dev: ACPI device to add the notifier for.
@@ -136,7 +74,7 @@ static acpi_status remove_pm_notifier(struct acpi_device *dev,
 acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev,
                                         struct pci_bus *pci_bus)
 {
-       return add_pm_notifier(dev, pci_acpi_wake_bus, pci_bus);
+       return acpi_add_pm_notifier(dev, pci_acpi_wake_bus, pci_bus);
 }
 
 /**
@@ -145,7 +83,7 @@ acpi_status pci_acpi_add_bus_pm_notifier(struct acpi_device *dev,
  */
 acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev)
 {
-       return remove_pm_notifier(dev, pci_acpi_wake_bus);
+       return acpi_remove_pm_notifier(dev, pci_acpi_wake_bus);
 }
 
 /**
@@ -156,7 +94,7 @@ acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev)
 acpi_status pci_acpi_add_pm_notifier(struct acpi_device *dev,
                                     struct pci_dev *pci_dev)
 {
-       return add_pm_notifier(dev, pci_acpi_wake_dev, pci_dev);
+       return acpi_add_pm_notifier(dev, pci_acpi_wake_dev, pci_dev);
 }
 
 /**
@@ -165,7 +103,7 @@ acpi_status pci_acpi_add_pm_notifier(struct acpi_device *dev,
  */
 acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev)
 {
-       return remove_pm_notifier(dev, pci_acpi_wake_dev);
+       return acpi_remove_pm_notifier(dev, pci_acpi_wake_dev);
 }
 
 phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle)
@@ -257,11 +195,16 @@ static int acpi_pci_set_power_state(struct pci_dev *dev, pci_power_t state)
                return -ENODEV;
 
        switch (state) {
+       case PCI_D3cold:
+               if (dev_pm_qos_flags(&dev->dev, PM_QOS_FLAG_NO_POWER_OFF) ==
+                               PM_QOS_FLAGS_ALL) {
+                       error = -EBUSY;
+                       break;
+               }
        case PCI_D0:
        case PCI_D1:
        case PCI_D2:
        case PCI_D3hot:
-       case PCI_D3cold:
                error = acpi_bus_set_power(handle, state_conv[state]);
        }