diff options
Diffstat (limited to 'drivers/acpi/pci_root.c')
-rw-r--r-- | drivers/acpi/pci_root.c | 49 |
1 files changed, 47 insertions, 2 deletions
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 3ba8d1f44a73..d06078d660ad 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -27,16 +27,17 @@ | |||
27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
29 | #include <linux/types.h> | 29 | #include <linux/types.h> |
30 | #include <linux/proc_fs.h> | ||
31 | #include <linux/spinlock.h> | 30 | #include <linux/spinlock.h> |
32 | #include <linux/pm.h> | 31 | #include <linux/pm.h> |
33 | #include <linux/pm_runtime.h> | 32 | #include <linux/pm_runtime.h> |
34 | #include <linux/pci.h> | 33 | #include <linux/pci.h> |
35 | #include <linux/pci-acpi.h> | 34 | #include <linux/pci-acpi.h> |
35 | #include <linux/pci-aspm.h> | ||
36 | #include <linux/acpi.h> | 36 | #include <linux/acpi.h> |
37 | #include <linux/slab.h> | 37 | #include <linux/slab.h> |
38 | #include <acpi/acpi_bus.h> | 38 | #include <acpi/acpi_bus.h> |
39 | #include <acpi/acpi_drivers.h> | 39 | #include <acpi/acpi_drivers.h> |
40 | #include <acpi/apei.h> | ||
40 | 41 | ||
41 | #define PREFIX "ACPI: " | 42 | #define PREFIX "ACPI: " |
42 | 43 | ||
@@ -48,6 +49,11 @@ static int acpi_pci_root_add(struct acpi_device *device); | |||
48 | static int acpi_pci_root_remove(struct acpi_device *device, int type); | 49 | static int acpi_pci_root_remove(struct acpi_device *device, int type); |
49 | static int acpi_pci_root_start(struct acpi_device *device); | 50 | static int acpi_pci_root_start(struct acpi_device *device); |
50 | 51 | ||
52 | #define ACPI_PCIE_REQ_SUPPORT (OSC_EXT_PCI_CONFIG_SUPPORT \ | ||
53 | | OSC_ACTIVE_STATE_PWR_SUPPORT \ | ||
54 | | OSC_CLOCK_PWR_CAPABILITY_SUPPORT \ | ||
55 | | OSC_MSI_SUPPORT) | ||
56 | |||
51 | static const struct acpi_device_id root_device_ids[] = { | 57 | static const struct acpi_device_id root_device_ids[] = { |
52 | {"PNP0A03", 0}, | 58 | {"PNP0A03", 0}, |
53 | {"", 0}, | 59 | {"", 0}, |
@@ -559,7 +565,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
559 | /* Indicate support for various _OSC capabilities. */ | 565 | /* Indicate support for various _OSC capabilities. */ |
560 | if (pci_ext_cfg_avail(root->bus->self)) | 566 | if (pci_ext_cfg_avail(root->bus->self)) |
561 | flags |= OSC_EXT_PCI_CONFIG_SUPPORT; | 567 | flags |= OSC_EXT_PCI_CONFIG_SUPPORT; |
562 | if (pcie_aspm_enabled()) | 568 | if (pcie_aspm_support_enabled()) |
563 | flags |= OSC_ACTIVE_STATE_PWR_SUPPORT | | 569 | flags |= OSC_ACTIVE_STATE_PWR_SUPPORT | |
564 | OSC_CLOCK_PWR_CAPABILITY_SUPPORT; | 570 | OSC_CLOCK_PWR_CAPABILITY_SUPPORT; |
565 | if (pci_msi_enabled()) | 571 | if (pci_msi_enabled()) |
@@ -567,6 +573,43 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device) | |||
567 | if (flags != base_flags) | 573 | if (flags != base_flags) |
568 | acpi_pci_osc_support(root, flags); | 574 | acpi_pci_osc_support(root, flags); |
569 | 575 | ||
576 | if (!pcie_ports_disabled | ||
577 | && (flags & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) { | ||
578 | flags = OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL | ||
579 | | OSC_PCI_EXPRESS_NATIVE_HP_CONTROL | ||
580 | | OSC_PCI_EXPRESS_PME_CONTROL; | ||
581 | |||
582 | if (pci_aer_available()) { | ||
583 | if (aer_acpi_firmware_first()) | ||
584 | dev_dbg(root->bus->bridge, | ||
585 | "PCIe errors handled by BIOS.\n"); | ||
586 | else | ||
587 | flags |= OSC_PCI_EXPRESS_AER_CONTROL; | ||
588 | } | ||
589 | |||
590 | dev_info(root->bus->bridge, | ||
591 | "Requesting ACPI _OSC control (0x%02x)\n", flags); | ||
592 | |||
593 | status = acpi_pci_osc_control_set(device->handle, &flags, | ||
594 | OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL); | ||
595 | if (ACPI_SUCCESS(status)) { | ||
596 | dev_info(root->bus->bridge, | ||
597 | "ACPI _OSC control (0x%02x) granted\n", flags); | ||
598 | } else { | ||
599 | dev_info(root->bus->bridge, | ||
600 | "ACPI _OSC request failed (%s), " | ||
601 | "returned control mask: 0x%02x\n", | ||
602 | acpi_format_exception(status), flags); | ||
603 | pr_info("ACPI _OSC control for PCIe not granted, " | ||
604 | "disabling ASPM\n"); | ||
605 | pcie_no_aspm(); | ||
606 | } | ||
607 | } else { | ||
608 | dev_info(root->bus->bridge, | ||
609 | "Unable to request _OSC control " | ||
610 | "(_OSC support mask: 0x%02x)\n", flags); | ||
611 | } | ||
612 | |||
570 | pci_acpi_add_bus_pm_notifier(device, root->bus); | 613 | pci_acpi_add_bus_pm_notifier(device, root->bus); |
571 | if (device->wakeup.flags.run_wake) | 614 | if (device->wakeup.flags.run_wake) |
572 | device_set_run_wake(root->bus->bridge, true); | 615 | device_set_run_wake(root->bus->bridge, true); |
@@ -601,6 +644,8 @@ static int acpi_pci_root_remove(struct acpi_device *device, int type) | |||
601 | 644 | ||
602 | static int __init acpi_pci_root_init(void) | 645 | static int __init acpi_pci_root_init(void) |
603 | { | 646 | { |
647 | acpi_hest_init(); | ||
648 | |||
604 | if (acpi_pci_disabled) | 649 | if (acpi_pci_disabled) |
605 | return 0; | 650 | return 0; |
606 | 651 | ||