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/portdrv_pci.c | |
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/portdrv_pci.c')
-rw-r--r-- | drivers/pci/pcie/portdrv_pci.c | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c index 13c8972886e..127e8f169d9 100644 --- a/drivers/pci/pcie/portdrv_pci.c +++ b/drivers/pci/pcie/portdrv_pci.c | |||
@@ -15,6 +15,7 @@ | |||
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/pcieport_if.h> | 16 | #include <linux/pcieport_if.h> |
17 | #include <linux/aer.h> | 17 | #include <linux/aer.h> |
18 | #include <linux/dmi.h> | ||
18 | 19 | ||
19 | #include "portdrv.h" | 20 | #include "portdrv.h" |
20 | #include "aer/aerdrv.h" | 21 | #include "aer/aerdrv.h" |
@@ -273,10 +274,36 @@ static struct pci_driver pcie_portdriver = { | |||
273 | .driver.pm = PCIE_PORTDRV_PM_OPS, | 274 | .driver.pm = PCIE_PORTDRV_PM_OPS, |
274 | }; | 275 | }; |
275 | 276 | ||
277 | static int __init dmi_pcie_pme_disable_msi(const struct dmi_system_id *d) | ||
278 | { | ||
279 | pr_notice("%s detected: will not use MSI for PCIe PME signaling\n", | ||
280 | d->ident); | ||
281 | pcie_pme_disable_msi(); | ||
282 | return 0; | ||
283 | } | ||
284 | |||
285 | static struct dmi_system_id __initdata pcie_portdrv_dmi_table[] = { | ||
286 | /* | ||
287 | * Boxes that should not use MSI for PCIe PME signaling. | ||
288 | */ | ||
289 | { | ||
290 | .callback = dmi_pcie_pme_disable_msi, | ||
291 | .ident = "MSI Wind U-100", | ||
292 | .matches = { | ||
293 | DMI_MATCH(DMI_SYS_VENDOR, | ||
294 | "MICRO-STAR INTERNATIONAL CO., LTD"), | ||
295 | DMI_MATCH(DMI_PRODUCT_NAME, "U-100"), | ||
296 | }, | ||
297 | }, | ||
298 | {} | ||
299 | }; | ||
300 | |||
276 | static int __init pcie_portdrv_init(void) | 301 | static int __init pcie_portdrv_init(void) |
277 | { | 302 | { |
278 | int retval; | 303 | int retval; |
279 | 304 | ||
305 | dmi_check_system(pcie_portdrv_dmi_table); | ||
306 | |||
280 | retval = pcie_port_bus_register(); | 307 | retval = pcie_port_bus_register(); |
281 | if (retval) { | 308 | if (retval) { |
282 | printk(KERN_WARNING "PCIE: bus_register error: %d\n", retval); | 309 | printk(KERN_WARNING "PCIE: bus_register error: %d\n", retval); |