aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-09-07 19:00:17 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-09-07 19:00:17 -0400
commitd56557af19867edb8c0e96f8e26399698a08857f (patch)
tree2d98f87962a5a08839371ed90b9eaa7f256bea36
parentfa2925cf90e612cb9c10c45d0cb8a7c7332e56a7 (diff)
parent17134d96735115644cc2f0e2b1bab51ca6e3ab95 (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jbarnes/pci-2.6: PCI: bus speed strings should be const PCI hotplug: Fix build with CONFIG_ACPI unset PCI: PCIe: Remove the port driver module exit routine PCI: PCIe: Move PCIe PME code to the pcie directory PCI: PCIe: Disable PCIe port services during port initialization PCI: PCIe: Ask BIOS for control of all native services at once ACPI/PCI: Negotiate _OSC control bits before requesting them ACPI/PCI: Do not preserve _OSC control bits returned by a query ACPI/PCI: Make acpi_pci_query_osc() return control bits ACPI/PCI: Reorder checks in acpi_pci_osc_control_set() PCI: PCIe: Introduce commad line switch for disabling port services PCI: PCIe AER: Introduce pci_aer_available() x86/PCI: only define pci_domain_nr if PCI and PCI_DOMAINS are set PCI: provide stub pci_domain_nr function for !CONFIG_PCI configs
-rw-r--r--Documentation/kernel-parameters.txt17
-rw-r--r--arch/x86/include/asm/pci.h6
-rw-r--r--drivers/acpi/pci_root.c97
-rw-r--r--drivers/pci/hotplug/acpi_pcihp.c6
-rw-r--r--drivers/pci/hotplug/pciehp.h16
-rw-r--r--drivers/pci/hotplug/pciehp_acpi.c4
-rw-r--r--drivers/pci/hotplug/pciehp_core.c4
-rw-r--r--drivers/pci/pci.h2
-rw-r--r--drivers/pci/pcie/Makefile3
-rw-r--r--drivers/pci/pcie/aer/aerdrv.c9
-rw-r--r--drivers/pci/pcie/aer/aerdrv_acpi.c36
-rw-r--r--drivers/pci/pcie/aer/aerdrv_core.c14
-rw-r--r--drivers/pci/pcie/pme.c (renamed from drivers/pci/pcie/pme/pcie_pme.c)66
-rw-r--r--drivers/pci/pcie/pme/Makefile8
-rw-r--r--drivers/pci/pcie/pme/pcie_pme.h28
-rw-r--r--drivers/pci/pcie/pme/pcie_pme_acpi.c54
-rw-r--r--drivers/pci/pcie/portdrv.h22
-rw-r--r--drivers/pci/pcie/portdrv_acpi.c77
-rw-r--r--drivers/pci/pcie/portdrv_core.c53
-rw-r--r--drivers/pci/pcie/portdrv_pci.c38
-rw-r--r--drivers/pci/slot.c2
-rw-r--r--include/acpi/acpi_bus.h3
-rw-r--r--include/linux/acpi.h4
-rw-r--r--include/linux/pci.h3
24 files changed, 281 insertions, 291 deletions
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index f084af0cb8e0..8dd7248508a9 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1974,15 +1974,18 @@ and is between 256 and 4096 characters. It is defined in the file
1974 force Enable ASPM even on devices that claim not to support it. 1974 force Enable ASPM even on devices that claim not to support it.
1975 WARNING: Forcing ASPM on may cause system lockups. 1975 WARNING: Forcing ASPM on may cause system lockups.
1976 1976
1977 pcie_ports= [PCIE] PCIe ports handling:
1978 auto Ask the BIOS whether or not to use native PCIe services
1979 associated with PCIe ports (PME, hot-plug, AER). Use
1980 them only if that is allowed by the BIOS.
1981 native Use native PCIe services associated with PCIe ports
1982 unconditionally.
1983 compat Treat PCIe ports as PCI-to-PCI bridges, disable the PCIe
1984 ports driver.
1985
1977 pcie_pme= [PCIE,PM] Native PCIe PME signaling options: 1986 pcie_pme= [PCIE,PM] Native PCIe PME signaling options:
1978 Format: {auto|force}[,nomsi]
1979 auto Use native PCIe PME signaling if the BIOS allows the
1980 kernel to control PCIe config registers of root ports.
1981 force Use native PCIe PME signaling even if the BIOS refuses
1982 to allow the kernel to control the relevant PCIe config
1983 registers.
1984 nomsi Do not use MSI for native PCIe PME signaling (this makes 1987 nomsi Do not use MSI for native PCIe PME signaling (this makes
1985 all PCIe root ports use INTx for everything). 1988 all PCIe root ports use INTx for all services).
1986 1989
1987 pcmv= [HW,PCMCIA] BadgePAD 4 1990 pcmv= [HW,PCMCIA] BadgePAD 4
1988 1991
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index 404a880ea325..d395540ff894 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -27,6 +27,9 @@ extern struct pci_bus *pci_scan_bus_on_node(int busno, struct pci_ops *ops,
27 int node); 27 int node);
28extern struct pci_bus *pci_scan_bus_with_sysdata(int busno); 28extern struct pci_bus *pci_scan_bus_with_sysdata(int busno);
29 29
30#ifdef CONFIG_PCI
31
32#ifdef CONFIG_PCI_DOMAINS
30static inline int pci_domain_nr(struct pci_bus *bus) 33static inline int pci_domain_nr(struct pci_bus *bus)
31{ 34{
32 struct pci_sysdata *sd = bus->sysdata; 35 struct pci_sysdata *sd = bus->sysdata;
@@ -37,13 +40,12 @@ static inline int pci_proc_domain(struct pci_bus *bus)
37{ 40{
38 return pci_domain_nr(bus); 41 return pci_domain_nr(bus);
39} 42}
40 43#endif
41 44
42/* Can be used to override the logic in pci_scan_bus for skipping 45/* Can be used to override the logic in pci_scan_bus for skipping
43 already-configured bus numbers - to be used for buggy BIOSes 46 already-configured bus numbers - to be used for buggy BIOSes
44 or architectures with incomplete PCI setup by the loader */ 47 or architectures with incomplete PCI setup by the loader */
45 48
46#ifdef CONFIG_PCI
47extern unsigned int pcibios_assign_all_busses(void); 49extern unsigned int pcibios_assign_all_busses(void);
48extern int pci_legacy_init(void); 50extern int pci_legacy_init(void);
49# ifdef CONFIG_ACPI 51# ifdef CONFIG_ACPI
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 1f67057af2a5..3ba8d1f44a73 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -33,7 +33,6 @@
33#include <linux/pm_runtime.h> 33#include <linux/pm_runtime.h>
34#include <linux/pci.h> 34#include <linux/pci.h>
35#include <linux/pci-acpi.h> 35#include <linux/pci-acpi.h>
36#include <linux/pci-aspm.h>
37#include <linux/acpi.h> 36#include <linux/acpi.h>
38#include <linux/slab.h> 37#include <linux/slab.h>
39#include <acpi/acpi_bus.h> 38#include <acpi/acpi_bus.h>
@@ -226,22 +225,31 @@ static acpi_status acpi_pci_run_osc(acpi_handle handle,
226 return status; 225 return status;
227} 226}
228 227
229static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root, u32 flags) 228static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root,
229 u32 support,
230 u32 *control)
230{ 231{
231 acpi_status status; 232 acpi_status status;
232 u32 support_set, result, capbuf[3]; 233 u32 result, capbuf[3];
234
235 support &= OSC_PCI_SUPPORT_MASKS;
236 support |= root->osc_support_set;
233 237
234 /* do _OSC query for all possible controls */
235 support_set = root->osc_support_set | (flags & OSC_PCI_SUPPORT_MASKS);
236 capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE; 238 capbuf[OSC_QUERY_TYPE] = OSC_QUERY_ENABLE;
237 capbuf[OSC_SUPPORT_TYPE] = support_set; 239 capbuf[OSC_SUPPORT_TYPE] = support;
238 capbuf[OSC_CONTROL_TYPE] = OSC_PCI_CONTROL_MASKS; 240 if (control) {
241 *control &= OSC_PCI_CONTROL_MASKS;
242 capbuf[OSC_CONTROL_TYPE] = *control | root->osc_control_set;
243 } else {
244 /* Run _OSC query for all possible controls. */
245 capbuf[OSC_CONTROL_TYPE] = OSC_PCI_CONTROL_MASKS;
246 }
239 247
240 status = acpi_pci_run_osc(root->device->handle, capbuf, &result); 248 status = acpi_pci_run_osc(root->device->handle, capbuf, &result);
241 if (ACPI_SUCCESS(status)) { 249 if (ACPI_SUCCESS(status)) {
242 root->osc_support_set = support_set; 250 root->osc_support_set = support;
243 root->osc_control_qry = result; 251 if (control)
244 root->osc_queried = 1; 252 *control = result;
245 } 253 }
246 return status; 254 return status;
247} 255}
@@ -255,7 +263,7 @@ static acpi_status acpi_pci_osc_support(struct acpi_pci_root *root, u32 flags)
255 if (ACPI_FAILURE(status)) 263 if (ACPI_FAILURE(status))
256 return status; 264 return status;
257 mutex_lock(&osc_lock); 265 mutex_lock(&osc_lock);
258 status = acpi_pci_query_osc(root, flags); 266 status = acpi_pci_query_osc(root, flags, NULL);
259 mutex_unlock(&osc_lock); 267 mutex_unlock(&osc_lock);
260 return status; 268 return status;
261} 269}
@@ -365,55 +373,70 @@ out:
365EXPORT_SYMBOL_GPL(acpi_get_pci_dev); 373EXPORT_SYMBOL_GPL(acpi_get_pci_dev);
366 374
367/** 375/**
368 * acpi_pci_osc_control_set - commit requested control to Firmware 376 * acpi_pci_osc_control_set - Request control of PCI root _OSC features.
369 * @handle: acpi_handle for the target ACPI object 377 * @handle: ACPI handle of a PCI root bridge (or PCIe Root Complex).
370 * @flags: driver's requested control bits 378 * @mask: Mask of _OSC bits to request control of, place to store control mask.
379 * @req: Mask of _OSC bits the control of is essential to the caller.
380 *
381 * Run _OSC query for @mask and if that is successful, compare the returned
382 * mask of control bits with @req. If all of the @req bits are set in the
383 * returned mask, run _OSC request for it.
371 * 384 *
372 * Attempt to take control from Firmware on requested control bits. 385 * The variable at the @mask address may be modified regardless of whether or
386 * not the function returns success. On success it will contain the mask of
387 * _OSC bits the BIOS has granted control of, but its contents are meaningless
388 * on failure.
373 **/ 389 **/
374acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 flags) 390acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 *mask, u32 req)
375{ 391{
392 struct acpi_pci_root *root;
376 acpi_status status; 393 acpi_status status;
377 u32 control_req, result, capbuf[3]; 394 u32 ctrl, capbuf[3];
378 acpi_handle tmp; 395 acpi_handle tmp;
379 struct acpi_pci_root *root;
380 396
381 status = acpi_get_handle(handle, "_OSC", &tmp); 397 if (!mask)
382 if (ACPI_FAILURE(status)) 398 return AE_BAD_PARAMETER;
383 return status;
384 399
385 control_req = (flags & OSC_PCI_CONTROL_MASKS); 400 ctrl = *mask & OSC_PCI_CONTROL_MASKS;
386 if (!control_req) 401 if ((ctrl & req) != req)
387 return AE_TYPE; 402 return AE_TYPE;
388 403
389 root = acpi_pci_find_root(handle); 404 root = acpi_pci_find_root(handle);
390 if (!root) 405 if (!root)
391 return AE_NOT_EXIST; 406 return AE_NOT_EXIST;
392 407
408 status = acpi_get_handle(handle, "_OSC", &tmp);
409 if (ACPI_FAILURE(status))
410 return status;
411
393 mutex_lock(&osc_lock); 412 mutex_lock(&osc_lock);
413
414 *mask = ctrl | root->osc_control_set;
394 /* No need to evaluate _OSC if the control was already granted. */ 415 /* No need to evaluate _OSC if the control was already granted. */
395 if ((root->osc_control_set & control_req) == control_req) 416 if ((root->osc_control_set & ctrl) == ctrl)
396 goto out; 417 goto out;
397 418
398 /* Need to query controls first before requesting them */ 419 /* Need to check the available controls bits before requesting them. */
399 if (!root->osc_queried) { 420 while (*mask) {
400 status = acpi_pci_query_osc(root, root->osc_support_set); 421 status = acpi_pci_query_osc(root, root->osc_support_set, mask);
401 if (ACPI_FAILURE(status)) 422 if (ACPI_FAILURE(status))
402 goto out; 423 goto out;
424 if (ctrl == *mask)
425 break;
426 ctrl = *mask;
403 } 427 }
404 if ((root->osc_control_qry & control_req) != control_req) { 428
405 printk(KERN_DEBUG 429 if ((ctrl & req) != req) {
406 "Firmware did not grant requested _OSC control\n");
407 status = AE_SUPPORT; 430 status = AE_SUPPORT;
408 goto out; 431 goto out;
409 } 432 }
410 433
411 capbuf[OSC_QUERY_TYPE] = 0; 434 capbuf[OSC_QUERY_TYPE] = 0;
412 capbuf[OSC_SUPPORT_TYPE] = root->osc_support_set; 435 capbuf[OSC_SUPPORT_TYPE] = root->osc_support_set;
413 capbuf[OSC_CONTROL_TYPE] = root->osc_control_set | control_req; 436 capbuf[OSC_CONTROL_TYPE] = ctrl;
414 status = acpi_pci_run_osc(handle, capbuf, &result); 437 status = acpi_pci_run_osc(handle, capbuf, mask);
415 if (ACPI_SUCCESS(status)) 438 if (ACPI_SUCCESS(status))
416 root->osc_control_set = result; 439 root->osc_control_set = *mask;
417out: 440out:
418 mutex_unlock(&osc_lock); 441 mutex_unlock(&osc_lock);
419 return status; 442 return status;
@@ -544,14 +567,6 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
544 if (flags != base_flags) 567 if (flags != base_flags)
545 acpi_pci_osc_support(root, flags); 568 acpi_pci_osc_support(root, flags);
546 569
547 status = acpi_pci_osc_control_set(root->device->handle,
548 OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
549
550 if (ACPI_FAILURE(status)) {
551 printk(KERN_INFO "Unable to assume PCIe control: Disabling ASPM\n");
552 pcie_no_aspm();
553 }
554
555 pci_acpi_add_bus_pm_notifier(device, root->bus); 570 pci_acpi_add_bus_pm_notifier(device, root->bus);
556 if (device->wakeup.flags.run_wake) 571 if (device->wakeup.flags.run_wake)
557 device_set_run_wake(root->bus->bridge, true); 572 device_set_run_wake(root->bus->bridge, true);
diff --git a/drivers/pci/hotplug/acpi_pcihp.c b/drivers/pci/hotplug/acpi_pcihp.c
index 45fcc1e96df9..3bc72d18b121 100644
--- a/drivers/pci/hotplug/acpi_pcihp.c
+++ b/drivers/pci/hotplug/acpi_pcihp.c
@@ -338,9 +338,7 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags)
338 acpi_handle chandle, handle; 338 acpi_handle chandle, handle;
339 struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL }; 339 struct acpi_buffer string = { ACPI_ALLOCATE_BUFFER, NULL };
340 340
341 flags &= (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | 341 flags &= OSC_SHPC_NATIVE_HP_CONTROL;
342 OSC_SHPC_NATIVE_HP_CONTROL |
343 OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
344 if (!flags) { 342 if (!flags) {
345 err("Invalid flags %u specified!\n", flags); 343 err("Invalid flags %u specified!\n", flags);
346 return -EINVAL; 344 return -EINVAL;
@@ -360,7 +358,7 @@ int acpi_get_hp_hw_control_from_firmware(struct pci_dev *pdev, u32 flags)
360 acpi_get_name(handle, ACPI_FULL_PATHNAME, &string); 358 acpi_get_name(handle, ACPI_FULL_PATHNAME, &string);
361 dbg("Trying to get hotplug control for %s\n", 359 dbg("Trying to get hotplug control for %s\n",
362 (char *)string.pointer); 360 (char *)string.pointer);
363 status = acpi_pci_osc_control_set(handle, flags); 361 status = acpi_pci_osc_control_set(handle, &flags, flags);
364 if (ACPI_SUCCESS(status)) 362 if (ACPI_SUCCESS(status))
365 goto got_one; 363 goto got_one;
366 if (status == AE_SUPPORT) 364 if (status == AE_SUPPORT)
diff --git a/drivers/pci/hotplug/pciehp.h b/drivers/pci/hotplug/pciehp.h
index 4ed76b47b6dc..73d513989263 100644
--- a/drivers/pci/hotplug/pciehp.h
+++ b/drivers/pci/hotplug/pciehp.h
@@ -176,19 +176,11 @@ static inline void pciehp_firmware_init(void)
176{ 176{
177 pciehp_acpi_slot_detection_init(); 177 pciehp_acpi_slot_detection_init();
178} 178}
179
180static inline int pciehp_get_hp_hw_control_from_firmware(struct pci_dev *dev)
181{
182 int retval;
183 u32 flags = (OSC_PCI_EXPRESS_NATIVE_HP_CONTROL |
184 OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
185 retval = acpi_get_hp_hw_control_from_firmware(dev, flags);
186 if (retval)
187 return retval;
188 return pciehp_acpi_slot_detection_check(dev);
189}
190#else 179#else
191#define pciehp_firmware_init() do {} while (0) 180#define pciehp_firmware_init() do {} while (0)
192#define pciehp_get_hp_hw_control_from_firmware(dev) 0 181static inline int pciehp_acpi_slot_detection_check(struct pci_dev *dev)
182{
183 return 0;
184}
193#endif /* CONFIG_ACPI */ 185#endif /* CONFIG_ACPI */
194#endif /* _PCIEHP_H */ 186#endif /* _PCIEHP_H */
diff --git a/drivers/pci/hotplug/pciehp_acpi.c b/drivers/pci/hotplug/pciehp_acpi.c
index 1f4000a5a108..2574700db461 100644
--- a/drivers/pci/hotplug/pciehp_acpi.c
+++ b/drivers/pci/hotplug/pciehp_acpi.c
@@ -85,9 +85,7 @@ static int __init dummy_probe(struct pcie_device *dev)
85 acpi_handle handle; 85 acpi_handle handle;
86 struct dummy_slot *slot, *tmp; 86 struct dummy_slot *slot, *tmp;
87 struct pci_dev *pdev = dev->port; 87 struct pci_dev *pdev = dev->port;
88 /* Note: pciehp_detect_mode != PCIEHP_DETECT_ACPI here */ 88
89 if (pciehp_get_hp_hw_control_from_firmware(pdev))
90 return -ENODEV;
91 pos = pci_pcie_cap(pdev); 89 pos = pci_pcie_cap(pdev);
92 if (!pos) 90 if (!pos)
93 return -ENODEV; 91 return -ENODEV;
diff --git a/drivers/pci/hotplug/pciehp_core.c b/drivers/pci/hotplug/pciehp_core.c
index 3588ea61b0dd..aa5f3ff629ff 100644
--- a/drivers/pci/hotplug/pciehp_core.c
+++ b/drivers/pci/hotplug/pciehp_core.c
@@ -59,7 +59,7 @@ module_param(pciehp_force, bool, 0644);
59MODULE_PARM_DESC(pciehp_debug, "Debugging mode enabled or not"); 59MODULE_PARM_DESC(pciehp_debug, "Debugging mode enabled or not");
60MODULE_PARM_DESC(pciehp_poll_mode, "Using polling mechanism for hot-plug events or not"); 60MODULE_PARM_DESC(pciehp_poll_mode, "Using polling mechanism for hot-plug events or not");
61MODULE_PARM_DESC(pciehp_poll_time, "Polling mechanism frequency, in seconds"); 61MODULE_PARM_DESC(pciehp_poll_time, "Polling mechanism frequency, in seconds");
62MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if _OSC and OSHP are missing"); 62MODULE_PARM_DESC(pciehp_force, "Force pciehp, even if OSHP is missing");
63 63
64#define PCIE_MODULE_NAME "pciehp" 64#define PCIE_MODULE_NAME "pciehp"
65 65
@@ -235,7 +235,7 @@ static int pciehp_probe(struct pcie_device *dev)
235 dev_info(&dev->device, 235 dev_info(&dev->device,
236 "Bypassing BIOS check for pciehp use on %s\n", 236 "Bypassing BIOS check for pciehp use on %s\n",
237 pci_name(dev->port)); 237 pci_name(dev->port));
238 else if (pciehp_get_hp_hw_control_from_firmware(dev->port)) 238 else if (pciehp_acpi_slot_detection_check(dev->port))
239 goto err_out_none; 239 goto err_out_none;
240 240
241 ctrl = pcie_init(dev); 241 ctrl = pcie_init(dev);
diff --git a/drivers/pci/pci.h b/drivers/pci/pci.h
index 679c39de6a89..7754a678ab15 100644
--- a/drivers/pci/pci.h
+++ b/drivers/pci/pci.h
@@ -140,8 +140,10 @@ static inline void pci_msi_init_pci_dev(struct pci_dev *dev) { }
140 140
141#ifdef CONFIG_PCIEAER 141#ifdef CONFIG_PCIEAER
142void pci_no_aer(void); 142void pci_no_aer(void);
143bool pci_aer_available(void);
143#else 144#else
144static inline void pci_no_aer(void) { } 145static inline void pci_no_aer(void) { }
146static inline bool pci_aer_available(void) { return false; }
145#endif 147#endif
146 148
147static inline int pci_no_d1d2(struct pci_dev *dev) 149static inline int pci_no_d1d2(struct pci_dev *dev)
diff --git a/drivers/pci/pcie/Makefile b/drivers/pci/pcie/Makefile
index ea654545e7c4..00c62df5a9fc 100644
--- a/drivers/pci/pcie/Makefile
+++ b/drivers/pci/pcie/Makefile
@@ -6,10 +6,11 @@
6obj-$(CONFIG_PCIEASPM) += aspm.o 6obj-$(CONFIG_PCIEASPM) += aspm.o
7 7
8pcieportdrv-y := portdrv_core.o portdrv_pci.o portdrv_bus.o 8pcieportdrv-y := portdrv_core.o portdrv_pci.o portdrv_bus.o
9pcieportdrv-$(CONFIG_ACPI) += portdrv_acpi.o
9 10
10obj-$(CONFIG_PCIEPORTBUS) += pcieportdrv.o 11obj-$(CONFIG_PCIEPORTBUS) += pcieportdrv.o
11 12
12# Build PCI Express AER if needed 13# Build PCI Express AER if needed
13obj-$(CONFIG_PCIEAER) += aer/ 14obj-$(CONFIG_PCIEAER) += aer/
14 15
15obj-$(CONFIG_PCIE_PME) += pme/ 16obj-$(CONFIG_PCIE_PME) += pme.o
diff --git a/drivers/pci/pcie/aer/aerdrv.c b/drivers/pci/pcie/aer/aerdrv.c
index 484cc55194b8..f409948e1a9b 100644
--- a/drivers/pci/pcie/aer/aerdrv.c
+++ b/drivers/pci/pcie/aer/aerdrv.c
@@ -72,6 +72,11 @@ void pci_no_aer(void)
72 pcie_aer_disable = 1; /* has priority over 'forceload' */ 72 pcie_aer_disable = 1; /* has priority over 'forceload' */
73} 73}
74 74
75bool pci_aer_available(void)
76{
77 return !pcie_aer_disable && pci_msi_enabled();
78}
79
75static int set_device_error_reporting(struct pci_dev *dev, void *data) 80static int set_device_error_reporting(struct pci_dev *dev, void *data)
76{ 81{
77 bool enable = *((bool *)data); 82 bool enable = *((bool *)data);
@@ -411,9 +416,7 @@ static void aer_error_resume(struct pci_dev *dev)
411 */ 416 */
412static int __init aer_service_init(void) 417static int __init aer_service_init(void)
413{ 418{
414 if (pcie_aer_disable) 419 if (!pci_aer_available())
415 return -ENXIO;
416 if (!pci_msi_enabled())
417 return -ENXIO; 420 return -ENXIO;
418 return pcie_port_service_register(&aerdriver); 421 return pcie_port_service_register(&aerdriver);
419} 422}
diff --git a/drivers/pci/pcie/aer/aerdrv_acpi.c b/drivers/pci/pcie/aer/aerdrv_acpi.c
index f278d7b0d95d..2bb9b8972211 100644
--- a/drivers/pci/pcie/aer/aerdrv_acpi.c
+++ b/drivers/pci/pcie/aer/aerdrv_acpi.c
@@ -19,42 +19,6 @@
19#include <acpi/apei.h> 19#include <acpi/apei.h>
20#include "aerdrv.h" 20#include "aerdrv.h"
21 21
22/**
23 * aer_osc_setup - run ACPI _OSC method
24 * @pciedev: pcie_device which AER is being enabled on
25 *
26 * @return: Zero on success. Nonzero otherwise.
27 *
28 * Invoked when PCIe bus loads AER service driver. To avoid conflict with
29 * BIOS AER support requires BIOS to yield AER control to OS native driver.
30 **/
31int aer_osc_setup(struct pcie_device *pciedev)
32{
33 acpi_status status = AE_NOT_FOUND;
34 struct pci_dev *pdev = pciedev->port;
35 acpi_handle handle = NULL;
36
37 if (acpi_pci_disabled)
38 return -1;
39
40 handle = acpi_find_root_bridge_handle(pdev);
41 if (handle) {
42 status = acpi_pci_osc_control_set(handle,
43 OSC_PCI_EXPRESS_AER_CONTROL |
44 OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
45 }
46
47 if (ACPI_FAILURE(status)) {
48 dev_printk(KERN_DEBUG, &pciedev->device, "AER service couldn't "
49 "init device: %s\n",
50 (status == AE_SUPPORT || status == AE_NOT_FOUND) ?
51 "no _OSC support" : "_OSC failed");
52 return -1;
53 }
54
55 return 0;
56}
57
58#ifdef CONFIG_ACPI_APEI 22#ifdef CONFIG_ACPI_APEI
59static inline int hest_match_pci(struct acpi_hest_aer_common *p, 23static inline int hest_match_pci(struct acpi_hest_aer_common *p,
60 struct pci_dev *pci) 24 struct pci_dev *pci)
diff --git a/drivers/pci/pcie/aer/aerdrv_core.c b/drivers/pci/pcie/aer/aerdrv_core.c
index fc0b5a93e1de..29e268fadf14 100644
--- a/drivers/pci/pcie/aer/aerdrv_core.c
+++ b/drivers/pci/pcie/aer/aerdrv_core.c
@@ -772,22 +772,10 @@ void aer_isr(struct work_struct *work)
772 */ 772 */
773int aer_init(struct pcie_device *dev) 773int aer_init(struct pcie_device *dev)
774{ 774{
775 if (pcie_aer_get_firmware_first(dev->port)) {
776 dev_printk(KERN_DEBUG, &dev->device,
777 "PCIe errors handled by platform firmware.\n");
778 goto out;
779 }
780
781 if (aer_osc_setup(dev))
782 goto out;
783
784 return 0;
785out:
786 if (forceload) { 775 if (forceload) {
787 dev_printk(KERN_DEBUG, &dev->device, 776 dev_printk(KERN_DEBUG, &dev->device,
788 "aerdrv forceload requested.\n"); 777 "aerdrv forceload requested.\n");
789 pcie_aer_force_firmware_first(dev->port, 0); 778 pcie_aer_force_firmware_first(dev->port, 0);
790 return 0;
791 } 779 }
792 return -ENXIO; 780 return 0;
793} 781}
diff --git a/drivers/pci/pcie/pme/pcie_pme.c b/drivers/pci/pcie/pme.c
index bbdea18693d9..2f3c90407227 100644
--- a/drivers/pci/pcie/pme/pcie_pme.c
+++ b/drivers/pci/pcie/pme.c
@@ -23,38 +23,13 @@
23#include <linux/pci-acpi.h> 23#include <linux/pci-acpi.h>
24#include <linux/pm_runtime.h> 24#include <linux/pm_runtime.h>
25 25
26#include "../../pci.h" 26#include "../pci.h"
27#include "pcie_pme.h" 27#include "portdrv.h"
28 28
29#define PCI_EXP_RTSTA_PME 0x10000 /* PME status */ 29#define PCI_EXP_RTSTA_PME 0x10000 /* PME status */
30#define PCI_EXP_RTSTA_PENDING 0x20000 /* PME pending */ 30#define PCI_EXP_RTSTA_PENDING 0x20000 /* PME pending */
31 31
32/* 32/*
33 * If set, this switch will prevent the PCIe root port PME service driver from
34 * being registered. Consequently, the interrupt-based PCIe PME signaling will
35 * not be used by any PCIe root ports in that case.
36 */
37static bool pcie_pme_disabled = true;
38
39/*
40 * The PCI Express Base Specification 2.0, Section 6.1.8, states the following:
41 * "In order to maintain compatibility with non-PCI Express-aware system
42 * software, system power management logic must be configured by firmware to use
43 * the legacy mechanism of signaling PME by default. PCI Express-aware system
44 * software must notify the firmware prior to enabling native, interrupt-based
45 * PME signaling." However, if the platform doesn't provide us with a suitable
46 * notification mechanism or the notification fails, it is not clear whether or
47 * not we are supposed to use the interrupt-based PCIe PME signaling. The
48 * switch below can be used to indicate the desired behaviour. When set, it
49 * will make the kernel use the interrupt-based PCIe PME signaling regardless of
50 * the platform notification status, although the kernel will attempt to notify
51 * the platform anyway. When unset, it will prevent the kernel from using the
52 * the interrupt-based PCIe PME signaling if the platform notification fails,
53 * which is the default.
54 */
55static bool pcie_pme_force_enable;
56
57/*
58 * If this switch is set, MSI will not be used for PCIe PME signaling. This 33 * If this switch is set, MSI will not be used for PCIe PME signaling. This
59 * causes the PCIe port driver to use INTx interrupts only, but it turns out 34 * causes the PCIe port driver to use INTx interrupts only, but it turns out
60 * that using MSI for PCIe PME signaling doesn't play well with PCIe PME-based 35 * that using MSI for PCIe PME signaling doesn't play well with PCIe PME-based
@@ -64,38 +39,13 @@ bool pcie_pme_msi_disabled;
64 39
65static int __init pcie_pme_setup(char *str) 40static int __init pcie_pme_setup(char *str)
66{ 41{
67 if (!strncmp(str, "auto", 4)) 42 if (!strncmp(str, "nomsi", 5))
68 pcie_pme_disabled = false; 43 pcie_pme_msi_disabled = true;
69 else if (!strncmp(str, "force", 5))
70 pcie_pme_force_enable = true;
71
72 str = strchr(str, ',');
73 if (str) {
74 str++;
75 str += strspn(str, " \t");
76 if (*str && !strcmp(str, "nomsi"))
77 pcie_pme_msi_disabled = true;
78 }
79 44
80 return 1; 45 return 1;
81} 46}
82__setup("pcie_pme=", pcie_pme_setup); 47__setup("pcie_pme=", pcie_pme_setup);
83 48
84/**
85 * pcie_pme_platform_setup - Ensure that the kernel controls the PCIe PME.
86 * @srv: PCIe PME root port service to use for carrying out the check.
87 *
88 * Notify the platform that the native PCIe PME is going to be used and return
89 * 'true' if the control of the PCIe PME registers has been acquired from the
90 * platform.
91 */
92static bool pcie_pme_platform_setup(struct pcie_device *srv)
93{
94 if (!pcie_pme_platform_notify(srv))
95 return true;
96 return pcie_pme_force_enable;
97}
98
99struct pcie_pme_service_data { 49struct pcie_pme_service_data {
100 spinlock_t lock; 50 spinlock_t lock;
101 struct pcie_device *srv; 51 struct pcie_device *srv;
@@ -108,7 +58,7 @@ struct pcie_pme_service_data {
108 * @dev: PCIe root port or event collector. 58 * @dev: PCIe root port or event collector.
109 * @enable: Enable or disable the interrupt. 59 * @enable: Enable or disable the interrupt.
110 */ 60 */
111static void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable) 61void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable)
112{ 62{
113 int rtctl_pos; 63 int rtctl_pos;
114 u16 rtctl; 64 u16 rtctl;
@@ -417,9 +367,6 @@ static int pcie_pme_probe(struct pcie_device *srv)
417 struct pcie_pme_service_data *data; 367 struct pcie_pme_service_data *data;
418 int ret; 368 int ret;
419 369
420 if (!pcie_pme_platform_setup(srv))
421 return -EACCES;
422
423 data = kzalloc(sizeof(*data), GFP_KERNEL); 370 data = kzalloc(sizeof(*data), GFP_KERNEL);
424 if (!data) 371 if (!data)
425 return -ENOMEM; 372 return -ENOMEM;
@@ -509,8 +456,7 @@ static struct pcie_port_service_driver pcie_pme_driver = {
509 */ 456 */
510static int __init pcie_pme_service_init(void) 457static int __init pcie_pme_service_init(void)
511{ 458{
512 return pcie_pme_disabled ? 459 return pcie_port_service_register(&pcie_pme_driver);
513 -ENODEV : pcie_port_service_register(&pcie_pme_driver);
514} 460}
515 461
516module_init(pcie_pme_service_init); 462module_init(pcie_pme_service_init);
diff --git a/drivers/pci/pcie/pme/Makefile b/drivers/pci/pcie/pme/Makefile
deleted file mode 100644
index 8b9238053080..000000000000
--- a/drivers/pci/pcie/pme/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
1#
2# Makefile for PCI-Express Root Port PME signaling driver
3#
4
5obj-$(CONFIG_PCIE_PME) += pmedriver.o
6
7pmedriver-objs := pcie_pme.o
8pmedriver-$(CONFIG_ACPI) += pcie_pme_acpi.o
diff --git a/drivers/pci/pcie/pme/pcie_pme.h b/drivers/pci/pcie/pme/pcie_pme.h
deleted file mode 100644
index b30d2b7c9775..000000000000
--- a/drivers/pci/pcie/pme/pcie_pme.h
+++ /dev/null
@@ -1,28 +0,0 @@
1/*
2 * drivers/pci/pcie/pme/pcie_pme.h
3 *
4 * PCI Express Root Port PME signaling support
5 *
6 * Copyright (C) 2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
7 */
8
9#ifndef _PCIE_PME_H_
10#define _PCIE_PME_H_
11
12struct pcie_device;
13
14#ifdef CONFIG_ACPI
15extern int pcie_pme_acpi_setup(struct pcie_device *srv);
16
17static inline int pcie_pme_platform_notify(struct pcie_device *srv)
18{
19 return pcie_pme_acpi_setup(srv);
20}
21#else /* !CONFIG_ACPI */
22static inline int pcie_pme_platform_notify(struct pcie_device *srv)
23{
24 return 0;
25}
26#endif /* !CONFIG_ACPI */
27
28#endif
diff --git a/drivers/pci/pcie/pme/pcie_pme_acpi.c b/drivers/pci/pcie/pme/pcie_pme_acpi.c
deleted file mode 100644
index 83ab2287ae3f..000000000000
--- a/drivers/pci/pcie/pme/pcie_pme_acpi.c
+++ /dev/null
@@ -1,54 +0,0 @@
1/*
2 * PCIe Native PME support, ACPI-related part
3 *
4 * Copyright (C) 2009 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License V2. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10
11#include <linux/pci.h>
12#include <linux/kernel.h>
13#include <linux/errno.h>
14#include <linux/acpi.h>
15#include <linux/pci-acpi.h>
16#include <linux/pcieport_if.h>
17
18/**
19 * pcie_pme_acpi_setup - Request the ACPI BIOS to release control over PCIe PME.
20 * @srv - PCIe PME service for a root port or event collector.
21 *
22 * Invoked when the PCIe bus type loads PCIe PME service driver. To avoid
23 * conflict with the BIOS PCIe support requires the BIOS to yield PCIe PME
24 * control to the kernel.
25 */
26int pcie_pme_acpi_setup(struct pcie_device *srv)
27{
28 acpi_status status = AE_NOT_FOUND;
29 struct pci_dev *port = srv->port;
30 acpi_handle handle;
31 int error = 0;
32
33 if (acpi_pci_disabled)
34 return -ENOSYS;
35
36 dev_info(&port->dev, "Requesting control of PCIe PME from ACPI BIOS\n");
37
38 handle = acpi_find_root_bridge_handle(port);
39 if (!handle)
40 return -EINVAL;
41
42 status = acpi_pci_osc_control_set(handle,
43 OSC_PCI_EXPRESS_PME_CONTROL |
44 OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
45 if (ACPI_FAILURE(status)) {
46 dev_info(&port->dev,
47 "Failed to receive control of PCIe PME service: %s\n",
48 (status == AE_SUPPORT || status == AE_NOT_FOUND) ?
49 "no _OSC support" : "ACPI _OSC failed");
50 error = -ENODEV;
51 }
52
53 return error;
54}
diff --git a/drivers/pci/pcie/portdrv.h b/drivers/pci/pcie/portdrv.h
index 813a5c3427b6..7b5aba0a3291 100644
--- a/drivers/pci/pcie/portdrv.h
+++ b/drivers/pci/pcie/portdrv.h
@@ -20,6 +20,9 @@
20 20
21#define get_descriptor_id(type, service) (((type - 4) << 4) | service) 21#define get_descriptor_id(type, service) (((type - 4) << 4) | service)
22 22
23extern bool pcie_ports_disabled;
24extern bool pcie_ports_auto;
25
23extern struct bus_type pcie_port_bus_type; 26extern struct bus_type pcie_port_bus_type;
24extern int pcie_port_device_register(struct pci_dev *dev); 27extern int pcie_port_device_register(struct pci_dev *dev);
25#ifdef CONFIG_PM 28#ifdef CONFIG_PM
@@ -30,6 +33,8 @@ extern void pcie_port_device_remove(struct pci_dev *dev);
30extern int __must_check pcie_port_bus_register(void); 33extern int __must_check pcie_port_bus_register(void);
31extern void pcie_port_bus_unregister(void); 34extern void pcie_port_bus_unregister(void);
32 35
36struct pci_dev;
37
33#ifdef CONFIG_PCIE_PME 38#ifdef CONFIG_PCIE_PME
34extern bool pcie_pme_msi_disabled; 39extern bool pcie_pme_msi_disabled;
35 40
@@ -42,9 +47,26 @@ static inline bool pcie_pme_no_msi(void)
42{ 47{
43 return pcie_pme_msi_disabled; 48 return pcie_pme_msi_disabled;
44} 49}
50
51extern void pcie_pme_interrupt_enable(struct pci_dev *dev, bool enable);
45#else /* !CONFIG_PCIE_PME */ 52#else /* !CONFIG_PCIE_PME */
46static inline void pcie_pme_disable_msi(void) {} 53static inline void pcie_pme_disable_msi(void) {}
47static inline bool pcie_pme_no_msi(void) { return false; } 54static inline bool pcie_pme_no_msi(void) { return false; }
55static inline void pcie_pme_interrupt_enable(struct pci_dev *dev, bool en) {}
48#endif /* !CONFIG_PCIE_PME */ 56#endif /* !CONFIG_PCIE_PME */
49 57
58#ifdef CONFIG_ACPI
59extern int pcie_port_acpi_setup(struct pci_dev *port, int *mask);
60
61static inline int pcie_port_platform_notify(struct pci_dev *port, int *mask)
62{
63 return pcie_port_acpi_setup(port, mask);
64}
65#else /* !CONFIG_ACPI */
66static inline int pcie_port_platform_notify(struct pci_dev *port, int *mask)
67{
68 return 0;
69}
70#endif /* !CONFIG_ACPI */
71
50#endif /* _PORTDRV_H_ */ 72#endif /* _PORTDRV_H_ */
diff --git a/drivers/pci/pcie/portdrv_acpi.c b/drivers/pci/pcie/portdrv_acpi.c
new file mode 100644
index 000000000000..b7c4cb1ccb23
--- /dev/null
+++ b/drivers/pci/pcie/portdrv_acpi.c
@@ -0,0 +1,77 @@
1/*
2 * PCIe Port Native Services Support, ACPI-Related Part
3 *
4 * Copyright (C) 2010 Rafael J. Wysocki <rjw@sisk.pl>, Novell Inc.
5 *
6 * This file is subject to the terms and conditions of the GNU General Public
7 * License V2. See the file "COPYING" in the main directory of this archive
8 * for more details.
9 */
10
11#include <linux/pci.h>
12#include <linux/kernel.h>
13#include <linux/errno.h>
14#include <linux/acpi.h>
15#include <linux/pci-acpi.h>
16#include <linux/pcieport_if.h>
17
18#include "aer/aerdrv.h"
19#include "../pci.h"
20
21/**
22 * pcie_port_acpi_setup - Request the BIOS to release control of PCIe services.
23 * @port: PCIe Port service for a root port or event collector.
24 * @srv_mask: Bit mask of services that can be enabled for @port.
25 *
26 * Invoked when @port is identified as a PCIe port device. To avoid conflicts
27 * with the BIOS PCIe port native services support requires the BIOS to yield
28 * control of these services to the kernel. The mask of services that the BIOS
29 * allows to be enabled for @port is written to @srv_mask.
30 *
31 * NOTE: It turns out that we cannot do that for individual port services
32 * separately, because that would make some systems work incorrectly.
33 */
34int pcie_port_acpi_setup(struct pci_dev *port, int *srv_mask)
35{
36 acpi_status status;
37 acpi_handle handle;
38 u32 flags;
39
40 if (acpi_pci_disabled)
41 return 0;
42
43 handle = acpi_find_root_bridge_handle(port);
44 if (!handle)
45 return -EINVAL;
46
47 flags = OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL
48 | OSC_PCI_EXPRESS_NATIVE_HP_CONTROL
49 | OSC_PCI_EXPRESS_PME_CONTROL;
50
51 if (pci_aer_available()) {
52 if (pcie_aer_get_firmware_first(port))
53 dev_dbg(&port->dev, "PCIe errors handled by BIOS.\n");
54 else
55 flags |= OSC_PCI_EXPRESS_AER_CONTROL;
56 }
57
58 status = acpi_pci_osc_control_set(handle, &flags,
59 OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
60 if (ACPI_FAILURE(status)) {
61 dev_dbg(&port->dev, "ACPI _OSC request failed (code %d)\n",
62 status);
63 return -ENODEV;
64 }
65
66 dev_info(&port->dev, "ACPI _OSC control granted for 0x%02x\n", flags);
67
68 *srv_mask = PCIE_PORT_SERVICE_VC;
69 if (flags & OSC_PCI_EXPRESS_NATIVE_HP_CONTROL)
70 *srv_mask |= PCIE_PORT_SERVICE_HP;
71 if (flags & OSC_PCI_EXPRESS_PME_CONTROL)
72 *srv_mask |= PCIE_PORT_SERVICE_PME;
73 if (flags & OSC_PCI_EXPRESS_AER_CONTROL)
74 *srv_mask |= PCIE_PORT_SERVICE_AER;
75
76 return 0;
77}
diff --git a/drivers/pci/pcie/portdrv_core.c b/drivers/pci/pcie/portdrv_core.c
index e73effbe402c..a9c222d79ebc 100644
--- a/drivers/pci/pcie/portdrv_core.c
+++ b/drivers/pci/pcie/portdrv_core.c
@@ -14,6 +14,8 @@
14#include <linux/string.h> 14#include <linux/string.h>
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>
18#include <linux/pci-aspm.h>
17 19
18#include "../pci.h" 20#include "../pci.h"
19#include "portdrv.h" 21#include "portdrv.h"
@@ -236,24 +238,64 @@ static int get_port_device_capability(struct pci_dev *dev)
236 int services = 0, pos; 238 int services = 0, pos;
237 u16 reg16; 239 u16 reg16;
238 u32 reg32; 240 u32 reg32;
241 int cap_mask;
242 int err;
243
244 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 {
251 cap_mask = PCIE_PORT_SERVICE_PME | PCIE_PORT_SERVICE_HP
252 | PCIE_PORT_SERVICE_VC;
253 if (pci_aer_available())
254 cap_mask |= PCIE_PORT_SERVICE_AER;
255 }
239 256
240 pos = pci_pcie_cap(dev); 257 pos = pci_pcie_cap(dev);
241 pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &reg16); 258 pci_read_config_word(dev, pos + PCI_EXP_FLAGS, &reg16);
242 /* Hot-Plug Capable */ 259 /* Hot-Plug Capable */
243 if (reg16 & PCI_EXP_FLAGS_SLOT) { 260 if ((cap_mask & PCIE_PORT_SERVICE_HP) && (reg16 & PCI_EXP_FLAGS_SLOT)) {
244 pci_read_config_dword(dev, pos + PCI_EXP_SLTCAP, &reg32); 261 pci_read_config_dword(dev, pos + PCI_EXP_SLTCAP, &reg32);
245 if (reg32 & PCI_EXP_SLTCAP_HPC) 262 if (reg32 & PCI_EXP_SLTCAP_HPC) {
246 services |= PCIE_PORT_SERVICE_HP; 263 services |= PCIE_PORT_SERVICE_HP;
264 /*
265 * Disable hot-plug interrupts in case they have been
266 * enabled by the BIOS and the hot-plug service driver
267 * is not loaded.
268 */
269 pos += PCI_EXP_SLTCTL;
270 pci_read_config_word(dev, pos, &reg16);
271 reg16 &= ~(PCI_EXP_SLTCTL_CCIE | PCI_EXP_SLTCTL_HPIE);
272 pci_write_config_word(dev, pos, reg16);
273 }
247 } 274 }
248 /* AER capable */ 275 /* AER capable */
249 if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR)) 276 if ((cap_mask & PCIE_PORT_SERVICE_AER)
277 && pci_find_ext_capability(dev, PCI_EXT_CAP_ID_ERR)) {
250 services |= PCIE_PORT_SERVICE_AER; 278 services |= PCIE_PORT_SERVICE_AER;
279 /*
280 * Disable AER on this port in case it's been enabled by the
281 * BIOS (the AER service driver will enable it when necessary).
282 */
283 pci_disable_pcie_error_reporting(dev);
284 }
251 /* VC support */ 285 /* VC support */
252 if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VC)) 286 if (pci_find_ext_capability(dev, PCI_EXT_CAP_ID_VC))
253 services |= PCIE_PORT_SERVICE_VC; 287 services |= PCIE_PORT_SERVICE_VC;
254 /* Root ports are capable of generating PME too */ 288 /* Root ports are capable of generating PME too */
255 if (dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) 289 if ((cap_mask & PCIE_PORT_SERVICE_PME)
290 && dev->pcie_type == PCI_EXP_TYPE_ROOT_PORT) {
256 services |= PCIE_PORT_SERVICE_PME; 291 services |= PCIE_PORT_SERVICE_PME;
292 /*
293 * Disable PME interrupt on this port in case it's been enabled
294 * by the BIOS (the PME service driver will enable it when
295 * necessary).
296 */
297 pcie_pme_interrupt_enable(dev, false);
298 }
257 299
258 return services; 300 return services;
259} 301}
@@ -494,6 +536,9 @@ static void pcie_port_shutdown_service(struct device *dev) {}
494 */ 536 */
495int pcie_port_service_register(struct pcie_port_service_driver *new) 537int pcie_port_service_register(struct pcie_port_service_driver *new)
496{ 538{
539 if (pcie_ports_disabled)
540 return -ENODEV;
541
497 new->driver.name = (char *)new->name; 542 new->driver.name = (char *)new->name;
498 new->driver.bus = &pcie_port_bus_type; 543 new->driver.bus = &pcie_port_bus_type;
499 new->driver.probe = pcie_port_probe_service; 544 new->driver.probe = pcie_port_probe_service;
diff --git a/drivers/pci/pcie/portdrv_pci.c b/drivers/pci/pcie/portdrv_pci.c
index 3debed25e46b..f9033e190fb6 100644
--- a/drivers/pci/pcie/portdrv_pci.c
+++ b/drivers/pci/pcie/portdrv_pci.c
@@ -15,6 +15,7 @@
15#include <linux/pcieport_if.h> 15#include <linux/pcieport_if.h>
16#include <linux/aer.h> 16#include <linux/aer.h>
17#include <linux/dmi.h> 17#include <linux/dmi.h>
18#include <linux/pci-aspm.h>
18 19
19#include "portdrv.h" 20#include "portdrv.h"
20#include "aer/aerdrv.h" 21#include "aer/aerdrv.h"
@@ -29,6 +30,31 @@ MODULE_AUTHOR(DRIVER_AUTHOR);
29MODULE_DESCRIPTION(DRIVER_DESC); 30MODULE_DESCRIPTION(DRIVER_DESC);
30MODULE_LICENSE("GPL"); 31MODULE_LICENSE("GPL");
31 32
33/* If this switch is set, PCIe port native services should not be enabled. */
34bool pcie_ports_disabled;
35
36/*
37 * If this switch is set, ACPI _OSC will be used to determine whether or not to
38 * enable PCIe port native services.
39 */
40bool pcie_ports_auto = true;
41
42static int __init pcie_port_setup(char *str)
43{
44 if (!strncmp(str, "compat", 6)) {
45 pcie_ports_disabled = true;
46 } else if (!strncmp(str, "native", 6)) {
47 pcie_ports_disabled = false;
48 pcie_ports_auto = false;
49 } else if (!strncmp(str, "auto", 4)) {
50 pcie_ports_disabled = false;
51 pcie_ports_auto = true;
52 }
53
54 return 1;
55}
56__setup("pcie_ports=", pcie_port_setup);
57
32/* global data */ 58/* global data */
33 59
34static int pcie_portdrv_restore_config(struct pci_dev *dev) 60static int pcie_portdrv_restore_config(struct pci_dev *dev)
@@ -301,6 +327,11 @@ static int __init pcie_portdrv_init(void)
301{ 327{
302 int retval; 328 int retval;
303 329
330 if (pcie_ports_disabled) {
331 pcie_no_aspm();
332 return -EACCES;
333 }
334
304 dmi_check_system(pcie_portdrv_dmi_table); 335 dmi_check_system(pcie_portdrv_dmi_table);
305 336
306 retval = pcie_port_bus_register(); 337 retval = pcie_port_bus_register();
@@ -315,11 +346,4 @@ static int __init pcie_portdrv_init(void)
315 return retval; 346 return retval;
316} 347}
317 348
318static void __exit pcie_portdrv_exit(void)
319{
320 pci_unregister_driver(&pcie_portdriver);
321 pcie_port_bus_unregister();
322}
323
324module_init(pcie_portdrv_init); 349module_init(pcie_portdrv_init);
325module_exit(pcie_portdrv_exit);
diff --git a/drivers/pci/slot.c b/drivers/pci/slot.c
index 659eaa0fc48f..968cfea04f74 100644
--- a/drivers/pci/slot.c
+++ b/drivers/pci/slot.c
@@ -49,7 +49,7 @@ static ssize_t address_read_file(struct pci_slot *slot, char *buf)
49} 49}
50 50
51/* these strings match up with the values in pci_bus_speed */ 51/* these strings match up with the values in pci_bus_speed */
52static char *pci_bus_speed_strings[] = { 52static const char *pci_bus_speed_strings[] = {
53 "33 MHz PCI", /* 0x00 */ 53 "33 MHz PCI", /* 0x00 */
54 "66 MHz PCI", /* 0x01 */ 54 "66 MHz PCI", /* 0x01 */
55 "66 MHz PCI-X", /* 0x02 */ 55 "66 MHz PCI-X", /* 0x02 */
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index baacd98e7cc6..4de84ce3a927 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -377,9 +377,6 @@ struct acpi_pci_root {
377 377
378 u32 osc_support_set; /* _OSC state of support bits */ 378 u32 osc_support_set; /* _OSC state of support bits */
379 u32 osc_control_set; /* _OSC state of control bits */ 379 u32 osc_control_set; /* _OSC state of control bits */
380 u32 osc_control_qry; /* the latest _OSC query result */
381
382 u32 osc_queried:1; /* has _OSC control been queried? */
383}; 380};
384 381
385/* helper */ 382/* helper */
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index ccf94dc5acdf..c227757feb06 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -304,8 +304,8 @@ acpi_status acpi_run_osc(acpi_handle handle, struct acpi_osc_context *context);
304 OSC_PCI_EXPRESS_PME_CONTROL | \ 304 OSC_PCI_EXPRESS_PME_CONTROL | \
305 OSC_PCI_EXPRESS_AER_CONTROL | \ 305 OSC_PCI_EXPRESS_AER_CONTROL | \
306 OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL) 306 OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL)
307 307extern acpi_status acpi_pci_osc_control_set(acpi_handle handle,
308extern acpi_status acpi_pci_osc_control_set(acpi_handle handle, u32 flags); 308 u32 *mask, u32 req);
309extern void acpi_early_init(void); 309extern void acpi_early_init(void);
310 310
311#else /* !CONFIG_ACPI */ 311#else /* !CONFIG_ACPI */
diff --git a/include/linux/pci.h b/include/linux/pci.h
index b1d17956a153..c8d95e369ff4 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1214,6 +1214,9 @@ static inline struct pci_dev *pci_get_bus_and_slot(unsigned int bus,
1214 unsigned int devfn) 1214 unsigned int devfn)
1215{ return NULL; } 1215{ return NULL; }
1216 1216
1217static inline int pci_domain_nr(struct pci_bus *bus)
1218{ return 0; }
1219
1217#define dev_is_pci(d) (false) 1220#define dev_is_pci(d) (false)
1218#define dev_is_pf(d) (false) 1221#define dev_is_pf(d) (false)
1219#define dev_num_vf(d) (0) 1222#define dev_num_vf(d) (0)