diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2010-02-17 17:40:07 -0500 |
---|---|---|
committer | Jesse Barnes <jbarnes@virtuousgeek.org> | 2010-02-22 19:20:39 -0500 |
commit | c39fae1416d59fd565606793f090cebe3720d50d (patch) | |
tree | f53b3dc3202706c328c2306f168058ec2e9ae859 /drivers/pci/pcie/pme | |
parent | c7f486567c1d0acd2e4166c47069835b9f75e77b (diff) |
PCI PM: Make it possible to force using INTx for PCIe PME signaling
Apparently, some machines may have problems with PCI run-time power
management if MSIs are used for the native PCIe PME signaling. In
particular, on the MSI Wind U-100 PCIe PME interrupts are not
generated by a PCIe root port after a resume from suspend to RAM, if
the system wake-up was triggered by a PME from the device attached to
this port. [It doesn't help to free the interrupt on suspend and
request it back on resume, even if that is done along with disabling
the MSI and re-enabling it, respectively.] However, if INTx
interrupts are used for this purpose on the same machine, everything
works just fine.
For this reason, add a kernel command line switch allowing one to
request that MSIs be not used for the native PCIe PME signaling,
introduce a DMI table allowing us to blacklist machines that need
this switch to be set by default and put the MSI Wind U-100 into this
table.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>
Diffstat (limited to 'drivers/pci/pcie/pme')
-rw-r--r-- | drivers/pci/pcie/pme/pcie_pme.c | 14 |
1 files changed, 13 insertions, 1 deletions
diff --git a/drivers/pci/pcie/pme/pcie_pme.c b/drivers/pci/pcie/pme/pcie_pme.c index b5f96fb3cd83..51a69061b120 100644 --- a/drivers/pci/pcie/pme/pcie_pme.c +++ b/drivers/pci/pcie/pme/pcie_pme.c | |||
@@ -53,12 +53,22 @@ static bool pcie_pme_disabled; | |||
53 | */ | 53 | */ |
54 | static bool pcie_pme_force_enable; | 54 | static bool pcie_pme_force_enable; |
55 | 55 | ||
56 | /* | ||
57 | * If this switch is set, MSI will not be used for PCIe PME signaling. This | ||
58 | * causes the PCIe port driver to use INTx interrupts only, but it turns out | ||
59 | * that using MSI for PCIe PME signaling doesn't play well with PCIe PME-based | ||
60 | * wake-up from system sleep states. | ||
61 | */ | ||
62 | bool pcie_pme_msi_disabled; | ||
63 | |||
56 | static int __init pcie_pme_setup(char *str) | 64 | static int __init pcie_pme_setup(char *str) |
57 | { | 65 | { |
58 | if (!strcmp(str, "off")) | 66 | if (!strcmp(str, "off")) |
59 | pcie_pme_disabled = true; | 67 | pcie_pme_disabled = true; |
60 | else if (!strcmp(str, "force")) | 68 | else if (!strcmp(str, "force")) |
61 | pcie_pme_force_enable = true; | 69 | pcie_pme_force_enable = true; |
70 | else if (!strcmp(str, "nomsi")) | ||
71 | pcie_pme_msi_disabled = true; | ||
62 | return 1; | 72 | return 1; |
63 | } | 73 | } |
64 | __setup("pcie_pme=", pcie_pme_setup); | 74 | __setup("pcie_pme=", pcie_pme_setup); |
@@ -73,7 +83,9 @@ __setup("pcie_pme=", pcie_pme_setup); | |||
73 | */ | 83 | */ |
74 | static bool pcie_pme_platform_setup(struct pcie_device *srv) | 84 | static bool pcie_pme_platform_setup(struct pcie_device *srv) |
75 | { | 85 | { |
76 | return !pcie_pme_platform_notify(srv) || pcie_pme_force_enable; | 86 | if (!pcie_pme_platform_notify(srv)) |
87 | return true; | ||
88 | return pcie_pme_force_enable; | ||
77 | } | 89 | } |
78 | 90 | ||
79 | struct pcie_pme_service_data { | 91 | struct pcie_pme_service_data { |