/**
  * pci_pme_wakeup - Wake up a PCI device if its PME Status bit is set.
  * @dev: Device to handle.
- * @ign: Ignored.
+ * @pme_poll_reset: Whether or not to reset the device's pme_poll flag.
  *
  * Check if @dev has generated PME and queue a resume request for it in that
  * case.
  */
-static int pci_pme_wakeup(struct pci_dev *dev, void *ign)
+static int pci_pme_wakeup(struct pci_dev *dev, void *pme_poll_reset)
 {
+       if (pme_poll_reset && dev->pme_poll)
+               dev->pme_poll = false;
+
        if (pci_check_pme_status(dev)) {
                pci_wakeup_event(dev);
                pm_request_resume(&dev->dev);
 void pci_pme_wakeup_bus(struct pci_bus *bus)
 {
        if (bus)
-               pci_walk_bus(bus, pci_pme_wakeup, NULL);
+               pci_walk_bus(bus, pci_pme_wakeup, (void *)true);
 }
 
 /**
 
 static void pci_pme_list_scan(struct work_struct *work)
 {
-       struct pci_pme_device *pme_dev;
+       struct pci_pme_device *pme_dev, *n;
 
        mutex_lock(&pci_pme_list_mutex);
        if (!list_empty(&pci_pme_list)) {
-               list_for_each_entry(pme_dev, &pci_pme_list, list)
-                       pci_pme_wakeup(pme_dev->dev, NULL);
-               schedule_delayed_work(&pci_pme_work, msecs_to_jiffies(PME_TIMEOUT));
+               list_for_each_entry_safe(pme_dev, n, &pci_pme_list, list) {
+                       if (pme_dev->dev->pme_poll) {
+                               pci_pme_wakeup(pme_dev->dev, NULL);
+                       } else {
+                               list_del(&pme_dev->list);
+                               kfree(pme_dev);
+                       }
+               }
+               if (!list_empty(&pci_pme_list))
+                       schedule_delayed_work(&pci_pme_work,
+                                             msecs_to_jiffies(PME_TIMEOUT));
        }
        mutex_unlock(&pci_pme_list_mutex);
 }
 
-/**
- * pci_external_pme - is a device an external PCI PME source?
- * @dev: PCI device to check
- *
- */
-
-static bool pci_external_pme(struct pci_dev *dev)
-{
-       if (pci_is_pcie(dev) || dev->bus->number == 0)
-               return false;
-       return true;
-}
-
 /**
  * pci_pme_active - enable or disable PCI device's PME# function
  * @dev: PCI device to handle.
           hit, and the power savings from the devices will still be a
           win. */
 
-       if (pci_external_pme(dev)) {
+       if (dev->pme_poll) {
                struct pci_pme_device *pme_dev;
                if (enable) {
                        pme_dev = kmalloc(sizeof(struct pci_pme_device),
                         (pmc & PCI_PM_CAP_PME_D3) ? " D3hot" : "",
                         (pmc & PCI_PM_CAP_PME_D3cold) ? " D3cold" : "");
                dev->pme_support = pmc >> PCI_PM_CAP_PME_SHIFT;
+               dev->pme_poll = true;
                /*
                 * Make device's PM flags reflect the wake-up capability, but
                 * let the user space enable it to wake up the system as needed.
 
        list_for_each_entry(dev, &bus->devices, bus_list) {
                /* Skip PCIe devices in case we started from a root port. */
                if (!pci_is_pcie(dev) && pci_check_pme_status(dev)) {
+                       if (dev->pme_poll)
+                               dev->pme_poll = false;
+
                        pci_wakeup_event(dev);
                        pm_request_resume(&dev->dev);
                        ret = true;
 
        /* First, check if the PME is from the root port itself. */
        if (port->devfn == devfn && port->bus->number == busnr) {
+               if (port->pme_poll)
+                       port->pme_poll = false;
+
                if (pci_check_pme_status(port)) {
                        pm_request_resume(&port->dev);
                        found = true;
                /* The device is there, but we have to check its PME status. */
                found = pci_check_pme_status(dev);
                if (found) {
+                       if (dev->pme_poll)
+                               dev->pme_poll = false;
+
                        pci_wakeup_event(dev);
                        pm_request_resume(&dev->dev);
                }