]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - drivers/pci/pcie/pme/pcie_pme.c
PM: Make it possible to avoid races between wakeup and system sleep
[net-next-2.6.git] / drivers / pci / pcie / pme / pcie_pme.c
index aac285a16b62bec0f84690c5241c4ee82185e383..bbdea18693d94048fc2444dcb388c0a18817fc6e 100644 (file)
@@ -34,7 +34,7 @@
  * being registered.  Consequently, the interrupt-based PCIe PME signaling will
  * not be used by any PCIe root ports in that case.
  */
-static bool pcie_pme_disabled;
+static bool pcie_pme_disabled = true;
 
 /*
  * The PCI Express Base Specification 2.0, Section 6.1.8, states the following:
@@ -64,12 +64,19 @@ bool pcie_pme_msi_disabled;
 
 static int __init pcie_pme_setup(char *str)
 {
-       if (!strcmp(str, "off"))
-               pcie_pme_disabled = true;
-       else if (!strcmp(str, "force"))
+       if (!strncmp(str, "auto", 4))
+               pcie_pme_disabled = false;
+       else if (!strncmp(str, "force", 5))
                pcie_pme_force_enable = true;
-       else if (!strcmp(str, "nomsi"))
-               pcie_pme_msi_disabled = true;
+
+       str = strchr(str, ',');
+       if (str) {
+               str++;
+               str += strspn(str, " \t");
+               if (*str && !strcmp(str, "nomsi"))
+                       pcie_pme_msi_disabled = true;
+       }
+
        return 1;
 }
 __setup("pcie_pme=", pcie_pme_setup);
@@ -147,6 +154,7 @@ static bool pcie_pme_walk_bus(struct pci_bus *bus)
                /* Skip PCIe devices in case we started from a root port. */
                if (!pci_is_pcie(dev) && pci_check_pme_status(dev)) {
                        pm_request_resume(&dev->dev);
+                       pci_wakeup_event(dev);
                        ret = true;
                }
 
@@ -247,8 +255,10 @@ static void pcie_pme_handle_request(struct pci_dev *port, u16 req_id)
        if (found) {
                /* The device is there, but we have to check its PME status. */
                found = pci_check_pme_status(dev);
-               if (found)
+               if (found) {
                        pm_request_resume(&dev->dev);
+                       pci_wakeup_event(dev);
+               }
                pci_dev_put(dev);
        } else if (devfn) {
                /*