diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-16 17:45:55 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-03-16 17:45:55 -0400 |
commit | 63e30271b04c712c684c07567401b61b10d094d4 (patch) | |
tree | 88a206568a0e35deaf0663a200eeda5c105e2486 /drivers/pci/pcie | |
parent | 277edbabf6fece057b14fb6db5e3a34e00f42f42 (diff) | |
parent | 6e6f498b039aa5558c7377fbbe65f7421d34cea4 (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/Kconfig | 7 | ||||
-rw-r--r-- | drivers/pci/pcie/aer/aer_inject.c | 90 | ||||
-rw-r--r-- | drivers/pci/pcie/pme.c | 11 |
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 | |||
47 | config PCIEASPM_DEBUG | 48 | config 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 | ||
60 | config PCIEASPM_DEFAULT | 61 | config 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 | ||
66 | config PCIEASPM_POWERSAVE | 67 | config 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 | ||
73 | config PCIEASPM_PERFORMANCE | 74 | config 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) | |||
124 | static struct pci_bus_ops *pci_bus_ops_pop(void) | 125 | static 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 | ||
184 | static int pci_read_aer(struct pci_bus *bus, unsigned int devfn, int where, | 182 | static 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 | } |
209 | out: | 209 | out: |
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 | ||
215 | static int pci_write_aer(struct pci_bus *bus, unsigned int devfn, int where, | 226 | static 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 | } |
244 | out: | 257 | out: |
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 | ||
250 | static struct pci_ops pci_ops_aer = { | 274 | static 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 | ||
255 | static void pci_bus_ops_init(struct pci_bus_ops *bus_ops, | 279 | static 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 | } | ||
467 | out_put: | 503 | out_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; |