Commit fe31e69740eddc7316071ed5165fed6703c8cd12

Authored by Rafael J. Wysocki
Committed by Jesse Barnes
1 parent 99a0fadf56

PCI/PCIe: Clear Root PME Status bits early during system resume

I noticed that PCI Express PMEs don't work on my Toshiba Portege R500
after the system has been woken up from a sleep state by a PME
(through Wake-on-LAN).  After some investigation it turned out that
the BIOS didn't clear the Root PME Status bit in the root port that
received the wakeup PME and since the Requester ID was also set in
the port's Root Status register, any subsequent PMEs didn't trigger
interrupts.

This problem can be avoided by clearing the Root PME Status bits in
all PCI Express root ports during early resume.  For this purpose,
add an early resume routine to the PCIe port driver and make this
driver be always registered, even if pci_ports_disable is set (in
which case the driver's only function is to provide the early
resume callback).

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Jesse Barnes <jbarnes@virtuousgeek.org>

Showing 5 changed files with 55 additions and 38 deletions Side-by-side Diff

drivers/pci/pcie/pme.c
... ... @@ -26,9 +26,6 @@
26 26 #include "../pci.h"
27 27 #include "portdrv.h"
28 28  
29   -#define PCI_EXP_RTSTA_PME 0x10000 /* PME status */
30   -#define PCI_EXP_RTSTA_PENDING 0x20000 /* PME pending */
31   -
32 29 /*
33 30 * If this switch is set, MSI will not be used for PCIe PME signaling. This
34 31 * causes the PCIe port driver to use INTx interrupts only, but it turns out
... ... @@ -74,22 +71,6 @@
74 71 }
75 72  
76 73 /**
77   - * pcie_pme_clear_status - Clear root port PME interrupt status.
78   - * @dev: PCIe root port or event collector.
79   - */
80   -static void pcie_pme_clear_status(struct pci_dev *dev)
81   -{
82   - int rtsta_pos;
83   - u32 rtsta;
84   -
85   - rtsta_pos = pci_pcie_cap(dev) + PCI_EXP_RTSTA;
86   -
87   - pci_read_config_dword(dev, rtsta_pos, &rtsta);
88   - rtsta |= PCI_EXP_RTSTA_PME;
89   - pci_write_config_dword(dev, rtsta_pos, rtsta);
90   -}
91   -
92   -/**
93 74 * pcie_pme_walk_bus - Scan a PCI bus for devices asserting PME#.
94 75 * @bus: PCI bus to scan.
95 76 *
... ... @@ -253,7 +234,7 @@
253 234 * Clear PME status of the port. If there are other
254 235 * pending PMEs, the status will be set again.
255 236 */
256   - pcie_pme_clear_status(port);
  237 + pcie_clear_root_pme_status(port);
257 238  
258 239 spin_unlock_irq(&data->lock);
259 240 pcie_pme_handle_request(port, rtsta & 0xffff);
... ... @@ -378,7 +359,7 @@
378 359  
379 360 port = srv->port;
380 361 pcie_pme_interrupt_enable(port, false);
381   - pcie_pme_clear_status(port);
  362 + pcie_clear_root_pme_status(port);
382 363  
383 364 ret = request_irq(srv->irq, pcie_pme_irq, IRQF_SHARED, "PCIe PME", srv);
384 365 if (ret) {
... ... @@ -402,7 +383,7 @@
402 383  
403 384 spin_lock_irq(&data->lock);
404 385 pcie_pme_interrupt_enable(port, false);
405   - pcie_pme_clear_status(port);
  386 + pcie_clear_root_pme_status(port);
406 387 data->noirq = true;
407 388 spin_unlock_irq(&data->lock);
408 389  
... ... @@ -422,7 +403,7 @@
422 403  
423 404 spin_lock_irq(&data->lock);
424 405 data->noirq = false;
425   - pcie_pme_clear_status(port);
  406 + pcie_clear_root_pme_status(port);
426 407 pcie_pme_interrupt_enable(port, true);
427 408 spin_unlock_irq(&data->lock);
428 409  
drivers/pci/pcie/portdrv.h
... ... @@ -35,6 +35,8 @@
35 35  
36 36 struct pci_dev;
37 37  
  38 +extern void pcie_clear_root_pme_status(struct pci_dev *dev);
  39 +
38 40 #ifdef CONFIG_PCIE_PME
39 41 extern bool pcie_pme_msi_disabled;
40 42  
drivers/pci/pcie/portdrv_core.c
... ... @@ -241,17 +241,17 @@
241 241 int cap_mask;
242 242 int err;
243 243  
  244 + if (pcie_ports_disabled)
  245 + return 0;
  246 +
244 247 err = pcie_port_platform_notify(dev, &cap_mask);
245   - if (pcie_ports_auto) {
246   - if (err) {
247   - pcie_no_aspm();
248   - return 0;
249   - }
250   - } else {
  248 + if (!pcie_ports_auto) {
251 249 cap_mask = PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP
252 250 | PCIE_PORT_SERVICE_VC;
253 251 if (pci_aer_available())
254 252 cap_mask |= PCIE_PORT_SERVICE_AER;
  253 + } else if (err) {
  254 + return 0;
255 255 }
256 256  
257 257 pos = pci_pcie_cap(dev);
258 258  
... ... @@ -349,15 +349,18 @@
349 349 int status, capabilities, i, nr_service;
350 350 int irqs[PCIE_PORT_DEVICE_MAXSERVICES];
351 351  
352   - /* Get and check PCI Express port services */
353   - capabilities = get_port_device_capability(dev);
354   - if (!capabilities)
355   - return -ENODEV;
356   -
357 352 /* Enable PCI Express port device */
358 353 status = pci_enable_device(dev);
359 354 if (status)
360 355 return status;
  356 +
  357 + /* Get and check PCI Express port services */
  358 + capabilities = get_port_device_capability(dev);
  359 + if (!capabilities) {
  360 + pcie_no_aspm();
  361 + return 0;
  362 + }
  363 +
361 364 pci_set_master(dev);
362 365 /*
363 366 * Initialize service irqs. Don't use service devices that
drivers/pci/pcie/portdrv_pci.c
... ... @@ -57,6 +57,22 @@
57 57  
58 58 /* global data */
59 59  
  60 +/**
  61 + * pcie_clear_root_pme_status - Clear root port PME interrupt status.
  62 + * @dev: PCIe root port or event collector.
  63 + */
  64 +void pcie_clear_root_pme_status(struct pci_dev *dev)
  65 +{
  66 + int rtsta_pos;
  67 + u32 rtsta;
  68 +
  69 + rtsta_pos = pci_pcie_cap(dev) + PCI_EXP_RTSTA;
  70 +
  71 + pci_read_config_dword(dev, rtsta_pos, &rtsta);
  72 + rtsta |= PCI_EXP_RTSTA_PME;
  73 + pci_write_config_dword(dev, rtsta_pos, rtsta);
  74 +}
  75 +
60 76 static int pcie_portdrv_restore_config(struct pci_dev *dev)
61 77 {
62 78 int retval;
... ... @@ -69,6 +85,20 @@
69 85 }
70 86  
71 87 #ifdef CONFIG_PM
  88 +static int pcie_port_resume_noirq(struct device *dev)
  89 +{
  90 + struct pci_dev *pdev = to_pci_dev(dev);
  91 +
  92 + /*
  93 + * Some BIOSes forget to clear Root PME Status bits after system wakeup
  94 + * which breaks ACPI-based runtime wakeup on PCI Express, so clear those
  95 + * bits now just in case (shouldn't hurt).
  96 + */
  97 + if(pdev->pcie_type == PCI_EXP_TYPE_ROOT_PORT)
  98 + pcie_clear_root_pme_status(pdev);
  99 + return 0;
  100 +}
  101 +
72 102 static const struct dev_pm_ops pcie_portdrv_pm_ops = {
73 103 .suspend = pcie_port_device_suspend,
74 104 .resume = pcie_port_device_resume,
... ... @@ -76,6 +106,7 @@
76 106 .thaw = pcie_port_device_resume,
77 107 .poweroff = pcie_port_device_suspend,
78 108 .restore = pcie_port_device_resume,
  109 + .resume_noirq = pcie_port_resume_noirq,
79 110 };
80 111  
81 112 #define PCIE_PORTDRV_PM_OPS (&pcie_portdrv_pm_ops)
... ... @@ -327,10 +358,8 @@
327 358 {
328 359 int retval;
329 360  
330   - if (pcie_ports_disabled) {
331   - pcie_no_aspm();
332   - return -EACCES;
333   - }
  361 + if (pcie_ports_disabled)
  362 + return pci_register_driver(&pcie_portdriver);
334 363  
335 364 dmi_check_system(pcie_portdrv_dmi_table);
336 365  
include/linux/pci_regs.h
... ... @@ -504,6 +504,8 @@
504 504 #define PCI_EXP_RTCTL_CRSSVE 0x10 /* CRS Software Visibility Enable */
505 505 #define PCI_EXP_RTCAP 30 /* Root Capabilities */
506 506 #define PCI_EXP_RTSTA 32 /* Root Status */
  507 +#define PCI_EXP_RTSTA_PME 0x10000 /* PME status */
  508 +#define PCI_EXP_RTSTA_PENDING 0x20000 /* PME pending */
507 509 #define PCI_EXP_DEVCAP2 36 /* Device Capabilities 2 */
508 510 #define PCI_EXP_DEVCAP2_ARI 0x20 /* Alternative Routing-ID */
509 511 #define PCI_EXP_DEVCTL2 40 /* Device Control 2 */