aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pci/pcie
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2016-03-16 17:45:55 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2016-03-16 17:45:55 -0400
commit63e30271b04c712c684c07567401b61b10d094d4 (patch)
tree88a206568a0e35deaf0663a200eeda5c105e2486 /drivers/pci/pcie
parent277edbabf6fece057b14fb6db5e3a34e00f42f42 (diff)
parent6e6f498b039aa5558c7377fbbe65f7421d34cea4 (diff)
Merge tag 'pci-v4.6-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci
Pull PCI updates from Bjorn Helgaas: "PCI changes for v4.6: Enumeration: - Disable IO/MEM decoding for devices with non-compliant BARs (Bjorn Helgaas) - Mark Broadwell-EP Home Agent & PCU as having non-compliant BARs (Bjorn Helgaas Resource management: - Mark shadow copy of VGA ROM as IORESOURCE_PCI_FIXED (Bjorn Helgaas) - Don't assign or reassign immutable resources (Bjorn Helgaas) - Don't enable/disable ROM BAR if we're using a RAM shadow copy (Bjorn Helgaas) - Set ROM shadow location in arch code, not in PCI core (Bjorn Helgaas) - Remove arch-specific IORESOURCE_ROM_SHADOW size from sysfs (Bjorn Helgaas) - ia64: Use ioremap() instead of open-coded equivalent (Bjorn Helgaas) - ia64: Keep CPU physical (not virtual) addresses in shadow ROM resource (Bjorn Helgaas) - MIPS: Keep CPU physical (not virtual) addresses in shadow ROM resource (Bjorn Helgaas) - Remove unused IORESOURCE_ROM_COPY and IORESOURCE_ROM_BIOS_COPY (Bjorn Helgaas) - Don't leak memory if sysfs_create_bin_file() fails (Bjorn Helgaas) - rcar: Remove PCI_PROBE_ONLY handling (Lorenzo Pieralisi) - designware: Remove PCI_PROBE_ONLY handling (Lorenzo Pieralisi) Virtualization: - Wait for up to 1000ms after FLR reset (Alex Williamson) - Support SR-IOV on any function type (Kelly Zytaruk) - Add ACS quirk for all Cavium devices (Manish Jaggi) AER: - Rename pci_ops_aer to aer_inj_pci_ops (Bjorn Helgaas) - Restore pci_ops pointer while calling original pci_ops (David Daney) - Fix aer_inject error codes (Jean Delvare) - Use dev_warn() in aer_inject (Jean Delvare) - Log actual error causes in aer_inject (Jean Delvare) - Log aer_inject error injections (Jean Delvare) VPD: - Prevent VPD access for buggy devices (Babu Moger) - Move pci_read_vpd() and pci_write_vpd() close to other VPD code (Bjorn Helgaas) - Move pci_vpd_release() from header file to pci/access.c (Bjorn Helgaas) - Remove struct pci_vpd_ops.release function pointer (Bjorn Helgaas) - Rename VPD symbols to remove unnecessary "pci22" (Bjorn Helgaas) - Fold struct pci_vpd_pci22 into struct pci_vpd (Bjorn Helgaas) - Sleep rather than busy-wait for VPD access completion (Bjorn Helgaas) - Update VPD definitions (Hannes Reinecke) - Allow access to VPD attributes with size 0 (Hannes Reinecke) - Determine actual VPD size on first access (Hannes Reinecke) Generic host bridge driver: - Move structure definitions to separate header file (David Daney) - Add pci_host_common_probe(), based on gen_pci_probe() (David Daney) - Expose pci_host_common_probe() for use by other drivers (David Daney) Altera host bridge driver: - Fix altera_pcie_link_is_up() (Ley Foon Tan) Cavium ThunderX host bridge driver: - Add PCIe host driver for ThunderX processors (David Daney) - Add driver for ThunderX-pass{1,2} on-chip devices (David Daney) Freescale i.MX6 host bridge driver: - Add DT bindings to configure PHY Tx driver settings (Justin Waters) - Move imx6_pcie_reset_phy() near other PHY handling functions (Lucas Stach) - Move PHY reset into imx6_pcie_establish_link() (Lucas Stach) - Remove broken Gen2 workaround (Lucas Stach) - Move link up check into imx6_pcie_wait_for_link() (Lucas Stach) Freescale Layerscape host bridge driver: - Add "fsl,ls2085a-pcie" compatible ID (Yang Shi) Intel VMD host bridge driver: - Attach VMD resources to parent domain's resource tree (Jon Derrick) - Set bus resource start to 0 (Keith Busch) Microsoft Hyper-V host bridge driver: - Add fwnode_handle to x86 pci_sysdata (Jake Oshins) - Look up IRQ domain by fwnode_handle (Jake Oshins) - Add paravirtual PCI front-end for Microsoft Hyper-V VMs (Jake Oshins) NVIDIA Tegra host bridge driver: - Add pci_ops.{add,remove}_bus() callbacks (Thierry Reding) - Implement ->{add,remove}_bus() callbacks (Thierry Reding) - Remove unused struct tegra_pcie.num_ports field (Thierry Reding) - Track bus -> CPU mapping (Thierry Reding) - Remove misleading PHYS_OFFSET (Thierry Reding) Renesas R-Car host bridge driver: - Depend on ARCH_RENESAS, not ARCH_SHMOBILE (Simon Horman) Synopsys DesignWare host bridge driver: - ARC: Add PCI support (Joao Pinto) - Add generic dw_pcie_wait_for_link() (Joao Pinto) - Add default link up check if sub-driver doesn't override (Joao Pinto) - Add driver for prototyping kits based on ARC SDP (Joao Pinto) TI Keystone host bridge driver: - Defer probing if devm_phy_get() returns -EPROBE_DEFER (Shawn Lin) Xilinx AXI host bridge driver: - Use of_pci_get_host_bridge_resources() to parse DT (Bharat Kumar Gogada) - Remove dependency on ARM-specific struct hw_pci (Bharat Kumar Gogada) - Don't call pci_fixup_irqs() on Microblaze (Bharat Kumar Gogada) - Update Zynq binding with Microblaze node (Bharat Kumar Gogada) - microblaze: Support generic Xilinx AXI PCIe Host Bridge IP driver (Bharat Kumar Gogada) Xilinx NWL host bridge driver: - Add support for Xilinx NWL PCIe Host Controller (Bharat Kumar Gogada) Miscellaneous: - Check device_attach() return value always (Bjorn Helgaas) - Move pci_set_flags() from asm-generic/pci-bridge.h to linux/pci.h (Bjorn Helgaas) - Remove includes of empty asm-generic/pci-bridge.h (Bjorn Helgaas) - ARM64: Remove generated include of asm-generic/pci-bridge.h (Bjorn Helgaas) - Remove empty asm-generic/pci-bridge.h (Bjorn Helgaas) - Remove includes of asm/pci-bridge.h (Bjorn Helgaas) - Consolidate PCI DMA constants and interfaces in linux/pci-dma-compat.h (Bjorn Helgaas) - unicore32: Remove unused HAVE_ARCH_PCI_SET_DMA_MASK definition (Bjorn Helgaas) - Cleanup pci/pcie/Kconfig whitespace (Andreas Ziegler) - Include pci/hotplug Kconfig directly from pci/Kconfig (Bjorn Helgaas) - Include pci/pcie/Kconfig directly from pci/Kconfig (Bogicevic Sasa) - frv: Remove stray pci_{alloc,free}_consistent() declaration (Christoph Hellwig) - Move pci_dma_* helpers to common code (Christoph Hellwig) - Add PCI_CLASS_SERIAL_USB_DEVICE definition (Heikki Krogerus) - Add QEMU top-level IDs for (sub)vendor & device (Robin H. Johnson) - Fix broken URL for Dell biosdevname (Naga Venkata Sai Indubhaskar Jupudi)" * tag 'pci-v4.6-changes' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci: (94 commits) PCI: Add PCI_CLASS_SERIAL_USB_DEVICE definition PCI: designware: Add driver for prototyping kits based on ARC SDP PCI: designware: Add default link up check if sub-driver doesn't override PCI: designware: Add generic dw_pcie_wait_for_link() PCI: Cleanup pci/pcie/Kconfig whitespace PCI: Simplify pci_create_attr() control flow PCI: Don't leak memory if sysfs_create_bin_file() fails PCI: Simplify sysfs ROM cleanup PCI: Remove unused IORESOURCE_ROM_COPY and IORESOURCE_ROM_BIOS_COPY MIPS: Loongson 3: Keep CPU physical (not virtual) addresses in shadow ROM resource MIPS: Loongson 3: Use temporary struct resource * to avoid repetition ia64/PCI: Keep CPU physical (not virtual) addresses in shadow ROM resource ia64/PCI: Use ioremap() instead of open-coded equivalent ia64/PCI: Use temporary struct resource * to avoid repetition PCI: Clean up pci_map_rom() whitespace PCI: Remove arch-specific IORESOURCE_ROM_SHADOW size from sysfs PCI: thunder: Add driver for ThunderX-pass{1,2} on-chip devices PCI: thunder: Add PCIe host driver for ThunderX processors PCI: generic: Expose pci_host_common_probe() for use by other drivers PCI: generic: Add pci_host_common_probe(), based on gen_pci_probe() ...
Diffstat (limited to 'drivers/pci/pcie')
-rw-r--r--drivers/pci/pcie/Kconfig7
-rw-r--r--drivers/pci/pcie/aer/aer_inject.c90
-rw-r--r--drivers/pci/pcie/pme.c11
3 files changed, 73 insertions, 35 deletions
diff --git a/drivers/pci/pcie/Kconfig b/drivers/pci/pcie/Kconfig
index e294713c8143..72db7f4209ca 100644
--- a/drivers/pci/pcie/Kconfig
+++ b/drivers/pci/pcie/Kconfig
@@ -44,6 +44,7 @@ config PCIEASPM
44 /sys/module/pcie_aspm/parameters/policy 44 /sys/module/pcie_aspm/parameters/policy
45 45
46 When in doubt, say Y. 46 When in doubt, say Y.
47
47config PCIEASPM_DEBUG 48config PCIEASPM_DEBUG
48 bool "Debug PCI Express ASPM" 49 bool "Debug PCI Express ASPM"
49 depends on PCIEASPM 50 depends on PCIEASPM
@@ -58,20 +59,20 @@ choice
58 depends on PCIEASPM 59 depends on PCIEASPM
59 60
60config PCIEASPM_DEFAULT 61config PCIEASPM_DEFAULT
61 bool "BIOS default" 62 bool "BIOS default"
62 depends on PCIEASPM 63 depends on PCIEASPM
63 help 64 help
64 Use the BIOS defaults for PCI Express ASPM. 65 Use the BIOS defaults for PCI Express ASPM.
65 66
66config PCIEASPM_POWERSAVE 67config PCIEASPM_POWERSAVE
67 bool "Powersave" 68 bool "Powersave"
68 depends on PCIEASPM 69 depends on PCIEASPM
69 help 70 help
70 Enable PCI Express ASPM L0s and L1 where possible, even if the 71 Enable PCI Express ASPM L0s and L1 where possible, even if the
71 BIOS did not. 72 BIOS did not.
72 73
73config PCIEASPM_PERFORMANCE 74config PCIEASPM_PERFORMANCE
74 bool "Performance" 75 bool "Performance"
75 depends on PCIEASPM 76 depends on PCIEASPM
76 help 77 help
77 Disable PCI Express ASPM L0s and L1, even if the BIOS enabled them. 78 Disable PCI Express ASPM L0s and L1, even if the BIOS enabled them.
diff --git a/drivers/pci/pcie/aer/aer_inject.c b/drivers/pci/pcie/aer/aer_inject.c
index 20db790465dd..db553dc22c8e 100644
--- a/drivers/pci/pcie/aer/aer_inject.c
+++ b/drivers/pci/pcie/aer/aer_inject.c
@@ -25,6 +25,7 @@
25#include <linux/fs.h> 25#include <linux/fs.h>
26#include <linux/uaccess.h> 26#include <linux/uaccess.h>
27#include <linux/stddef.h> 27#include <linux/stddef.h>
28#include <linux/device.h>
28#include "aerdrv.h" 29#include "aerdrv.h"
29 30
30/* Override the existing corrected and uncorrected error masks */ 31/* Override the existing corrected and uncorrected error masks */
@@ -124,16 +125,13 @@ static struct pci_ops *__find_pci_bus_ops(struct pci_bus *bus)
124static struct pci_bus_ops *pci_bus_ops_pop(void) 125static struct pci_bus_ops *pci_bus_ops_pop(void)
125{ 126{
126 unsigned long flags; 127 unsigned long flags;
127 struct pci_bus_ops *bus_ops = NULL; 128 struct pci_bus_ops *bus_ops;
128 129
129 spin_lock_irqsave(&inject_lock, flags); 130 spin_lock_irqsave(&inject_lock, flags);
130 if (list_empty(&pci_bus_ops_list)) 131 bus_ops = list_first_entry_or_null(&pci_bus_ops_list,
131 bus_ops = NULL; 132 struct pci_bus_ops, list);
132 else { 133 if (bus_ops)
133 struct list_head *lh = pci_bus_ops_list.next; 134 list_del(&bus_ops->list);
134 list_del(lh);
135 bus_ops = list_entry(lh, struct pci_bus_ops, list);
136 }
137 spin_unlock_irqrestore(&inject_lock, flags); 135 spin_unlock_irqrestore(&inject_lock, flags);
138 return bus_ops; 136 return bus_ops;
139} 137}
@@ -181,14 +179,16 @@ static u32 *find_pci_config_dword(struct aer_error *err, int where,
181 return target; 179 return target;
182} 180}
183 181
184static int pci_read_aer(struct pci_bus *bus, unsigned int devfn, int where, 182static int aer_inj_read_config(struct pci_bus *bus, unsigned int devfn,
185 int size, u32 *val) 183 int where, int size, u32 *val)
186{ 184{
187 u32 *sim; 185 u32 *sim;
188 struct aer_error *err; 186 struct aer_error *err;
189 unsigned long flags; 187 unsigned long flags;
190 struct pci_ops *ops; 188 struct pci_ops *ops;
189 struct pci_ops *my_ops;
191 int domain; 190 int domain;
191 int rv;
192 192
193 spin_lock_irqsave(&inject_lock, flags); 193 spin_lock_irqsave(&inject_lock, flags);
194 if (size != sizeof(u32)) 194 if (size != sizeof(u32))
@@ -208,19 +208,32 @@ static int pci_read_aer(struct pci_bus *bus, unsigned int devfn, int where,
208 } 208 }
209out: 209out:
210 ops = __find_pci_bus_ops(bus); 210 ops = __find_pci_bus_ops(bus);
211 /*
212 * pci_lock must already be held, so we can directly
213 * manipulate bus->ops. Many config access functions,
214 * including pci_generic_config_read() require the original
215 * bus->ops be installed to function, so temporarily put them
216 * back.
217 */
218 my_ops = bus->ops;
219 bus->ops = ops;
220 rv = ops->read(bus, devfn, where, size, val);
221 bus->ops = my_ops;
211 spin_unlock_irqrestore(&inject_lock, flags); 222 spin_unlock_irqrestore(&inject_lock, flags);
212 return ops->read(bus, devfn, where, size, val); 223 return rv;
213} 224}
214 225
215static int pci_write_aer(struct pci_bus *bus, unsigned int devfn, int where, 226static int aer_inj_write_config(struct pci_bus *bus, unsigned int devfn,
216 int size, u32 val) 227 int where, int size, u32 val)
217{ 228{
218 u32 *sim; 229 u32 *sim;
219 struct aer_error *err; 230 struct aer_error *err;
220 unsigned long flags; 231 unsigned long flags;
221 int rw1cs; 232 int rw1cs;
222 struct pci_ops *ops; 233 struct pci_ops *ops;
234 struct pci_ops *my_ops;
223 int domain; 235 int domain;
236 int rv;
224 237
225 spin_lock_irqsave(&inject_lock, flags); 238 spin_lock_irqsave(&inject_lock, flags);
226 if (size != sizeof(u32)) 239 if (size != sizeof(u32))
@@ -243,13 +256,24 @@ static int pci_write_aer(struct pci_bus *bus, unsigned int devfn, int where,
243 } 256 }
244out: 257out:
245 ops = __find_pci_bus_ops(bus); 258 ops = __find_pci_bus_ops(bus);
259 /*
260 * pci_lock must already be held, so we can directly
261 * manipulate bus->ops. Many config access functions,
262 * including pci_generic_config_write() require the original
263 * bus->ops be installed to function, so temporarily put them
264 * back.
265 */
266 my_ops = bus->ops;
267 bus->ops = ops;
268 rv = ops->write(bus, devfn, where, size, val);
269 bus->ops = my_ops;
246 spin_unlock_irqrestore(&inject_lock, flags); 270 spin_unlock_irqrestore(&inject_lock, flags);
247 return ops->write(bus, devfn, where, size, val); 271 return rv;
248} 272}
249 273
250static struct pci_ops pci_ops_aer = { 274static struct pci_ops aer_inj_pci_ops = {
251 .read = pci_read_aer, 275 .read = aer_inj_read_config,
252 .write = pci_write_aer, 276 .write = aer_inj_write_config,
253}; 277};
254 278
255static void pci_bus_ops_init(struct pci_bus_ops *bus_ops, 279static void pci_bus_ops_init(struct pci_bus_ops *bus_ops,
@@ -270,9 +294,9 @@ static int pci_bus_set_aer_ops(struct pci_bus *bus)
270 bus_ops = kmalloc(sizeof(*bus_ops), GFP_KERNEL); 294 bus_ops = kmalloc(sizeof(*bus_ops), GFP_KERNEL);
271 if (!bus_ops) 295 if (!bus_ops)
272 return -ENOMEM; 296 return -ENOMEM;
273 ops = pci_bus_set_ops(bus, &pci_ops_aer); 297 ops = pci_bus_set_ops(bus, &aer_inj_pci_ops);
274 spin_lock_irqsave(&inject_lock, flags); 298 spin_lock_irqsave(&inject_lock, flags);
275 if (ops == &pci_ops_aer) 299 if (ops == &aer_inj_pci_ops)
276 goto out; 300 goto out;
277 pci_bus_ops_init(bus_ops, bus, ops); 301 pci_bus_ops_init(bus_ops, bus, ops);
278 list_add(&bus_ops->list, &pci_bus_ops_list); 302 list_add(&bus_ops->list, &pci_bus_ops_list);
@@ -334,13 +358,15 @@ static int aer_inject(struct aer_error_inj *einj)
334 return -ENODEV; 358 return -ENODEV;
335 rpdev = pcie_find_root_port(dev); 359 rpdev = pcie_find_root_port(dev);
336 if (!rpdev) { 360 if (!rpdev) {
361 dev_err(&dev->dev, "aer_inject: Root port not found\n");
337 ret = -ENODEV; 362 ret = -ENODEV;
338 goto out_put; 363 goto out_put;
339 } 364 }
340 365
341 pos_cap_err = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR); 366 pos_cap_err = pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR);
342 if (!pos_cap_err) { 367 if (!pos_cap_err) {
343 ret = -EPERM; 368 dev_err(&dev->dev, "aer_inject: Device doesn't support AER\n");
369 ret = -EPROTONOSUPPORT;
344 goto out_put; 370 goto out_put;
345 } 371 }
346 pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_SEVER, &sever); 372 pci_read_config_dword(dev, pos_cap_err + PCI_ERR_UNCOR_SEVER, &sever);
@@ -350,7 +376,9 @@ static int aer_inject(struct aer_error_inj *einj)
350 376
351 rp_pos_cap_err = pci_find_ext_capability(rpdev, PCI_EXT_CAP_ID_ERR); 377 rp_pos_cap_err = pci_find_ext_capability(rpdev, PCI_EXT_CAP_ID_ERR);
352 if (!rp_pos_cap_err) { 378 if (!rp_pos_cap_err) {
353 ret = -EPERM; 379 dev_err(&rpdev->dev,
380 "aer_inject: Root port doesn't support AER\n");
381 ret = -EPROTONOSUPPORT;
354 goto out_put; 382 goto out_put;
355 } 383 }
356 384
@@ -397,14 +425,16 @@ static int aer_inject(struct aer_error_inj *einj)
397 if (!aer_mask_override && einj->cor_status && 425 if (!aer_mask_override && einj->cor_status &&
398 !(einj->cor_status & ~cor_mask)) { 426 !(einj->cor_status & ~cor_mask)) {
399 ret = -EINVAL; 427 ret = -EINVAL;
400 printk(KERN_WARNING "The correctable error(s) is masked by device\n"); 428 dev_warn(&dev->dev,
429 "aer_inject: The correctable error(s) is masked by device\n");
401 spin_unlock_irqrestore(&inject_lock, flags); 430 spin_unlock_irqrestore(&inject_lock, flags);
402 goto out_put; 431 goto out_put;
403 } 432 }
404 if (!aer_mask_override && einj->uncor_status && 433 if (!aer_mask_override && einj->uncor_status &&
405 !(einj->uncor_status & ~uncor_mask)) { 434 !(einj->uncor_status & ~uncor_mask)) {
406 ret = -EINVAL; 435 ret = -EINVAL;
407 printk(KERN_WARNING "The uncorrectable error(s) is masked by device\n"); 436 dev_warn(&dev->dev,
437 "aer_inject: The uncorrectable error(s) is masked by device\n");
408 spin_unlock_irqrestore(&inject_lock, flags); 438 spin_unlock_irqrestore(&inject_lock, flags);
409 goto out_put; 439 goto out_put;
410 } 440 }
@@ -457,13 +487,19 @@ static int aer_inject(struct aer_error_inj *einj)
457 487
458 if (find_aer_device(rpdev, &edev)) { 488 if (find_aer_device(rpdev, &edev)) {
459 if (!get_service_data(edev)) { 489 if (!get_service_data(edev)) {
460 printk(KERN_WARNING "AER service is not initialized\n"); 490 dev_warn(&edev->device,
461 ret = -EINVAL; 491 "aer_inject: AER service is not initialized\n");
492 ret = -EPROTONOSUPPORT;
462 goto out_put; 493 goto out_put;
463 } 494 }
495 dev_info(&edev->device,
496 "aer_inject: Injecting errors %08x/%08x into device %s\n",
497 einj->cor_status, einj->uncor_status, pci_name(dev));
464 aer_irq(-1, edev); 498 aer_irq(-1, edev);
465 } else 499 } else {
466 ret = -EINVAL; 500 dev_err(&rpdev->dev, "aer_inject: AER device not found\n");
501 ret = -ENODEV;
502 }
467out_put: 503out_put:
468 kfree(err_alloc); 504 kfree(err_alloc);
469 kfree(rperr_alloc); 505 kfree(rperr_alloc);
diff --git a/drivers/pci/pcie/pme.c b/drivers/pci/pcie/pme.c
index 63fc63911295..1ae4c73e7a3c 100644
--- a/drivers/pci/pcie/pme.c
+++ b/drivers/pci/pcie/pme.c
@@ -396,7 +396,7 @@ static int pcie_pme_suspend(struct pcie_device *srv)
396{ 396{
397 struct pcie_pme_service_data *data = get_service_data(srv); 397 struct pcie_pme_service_data *data = get_service_data(srv);
398 struct pci_dev *port = srv->port; 398 struct pci_dev *port = srv->port;
399 bool wakeup; 399 bool wakeup, wake_irq_enabled = false;
400 int ret; 400 int ret;
401 401
402 if (device_may_wakeup(&port->dev)) { 402 if (device_may_wakeup(&port->dev)) {
@@ -409,11 +409,12 @@ static int pcie_pme_suspend(struct pcie_device *srv)
409 spin_lock_irq(&data->lock); 409 spin_lock_irq(&data->lock);
410 if (wakeup) { 410 if (wakeup) {
411 ret = enable_irq_wake(srv->irq); 411 ret = enable_irq_wake(srv->irq);
412 data->suspend_level = PME_SUSPEND_WAKEUP; 412 if (ret == 0) {
413 data->suspend_level = PME_SUSPEND_WAKEUP;
414 wake_irq_enabled = true;
415 }
413 } 416 }
414 if (!wakeup || ret) { 417 if (!wake_irq_enabled) {
415 struct pci_dev *port = srv->port;
416
417 pcie_pme_interrupt_enable(port, false); 418 pcie_pme_interrupt_enable(port, false);
418 pcie_clear_root_pme_status(port); 419 pcie_clear_root_pme_status(port);
419 data->suspend_level = PME_SUSPEND_NOIRQ; 420 data->suspend_level = PME_SUSPEND_NOIRQ;