Revert "ARM: tegra: tegratab: dummy change"
[linux-2.6.git] / drivers / acpi / pci_root.c
index 3ba8d1f..5b0f075 100644 (file)
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/types.h>
-#include <linux/proc_fs.h>
 #include <linux/spinlock.h>
 #include <linux/pm.h>
 #include <linux/pm_runtime.h>
 #include <linux/pci.h>
 #include <linux/pci-acpi.h>
+#include <linux/pci-aspm.h>
 #include <linux/acpi.h>
 #include <linux/slab.h>
 #include <acpi/acpi_bus.h>
 #include <acpi/acpi_drivers.h>
+#include <acpi/apei.h>
 
 #define PREFIX "ACPI: "
 
@@ -48,6 +49,11 @@ static int acpi_pci_root_add(struct acpi_device *device);
 static int acpi_pci_root_remove(struct acpi_device *device, int type);
 static int acpi_pci_root_start(struct acpi_device *device);
 
+#define ACPI_PCIE_REQ_SUPPORT (OSC_EXT_PCI_CONFIG_SUPPORT \
+                               | OSC_ACTIVE_STATE_PWR_SUPPORT \
+                               | OSC_CLOCK_PWR_CAPABILITY_SUPPORT \
+                               | OSC_MSI_SUPPORT)
+
 static const struct acpi_device_id root_device_ids[] = {
        {"PNP0A03", 0},
        {"", 0},
@@ -241,8 +247,8 @@ static acpi_status acpi_pci_query_osc(struct acpi_pci_root *root,
                *control &= OSC_PCI_CONTROL_MASKS;
                capbuf[OSC_CONTROL_TYPE] = *control | root->osc_control_set;
        } else {
-               /* Run _OSC query for all possible controls. */
-               capbuf[OSC_CONTROL_TYPE] = OSC_PCI_CONTROL_MASKS;
+               /* Run _OSC query only with existing controls. */
+               capbuf[OSC_CONTROL_TYPE] = root->osc_control_set;
        }
 
        status = acpi_pci_run_osc(root->device->handle, capbuf, &result);
@@ -479,7 +485,8 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
                root->secondary.end = 0xFF;
                printk(KERN_WARNING FW_BUG PREFIX
                       "no secondary bus range in _CRS\n");
-               status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN,                                               NULL, &bus);
+               status = acpi_evaluate_integer(device->handle, METHOD_NAME__BBN,
+                                              NULL, &bus);
                if (ACPI_SUCCESS(status))
                        root->secondary.start = bus;
                else if (status == AE_NOT_FOUND)
@@ -559,7 +566,7 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
        /* Indicate support for various _OSC capabilities. */
        if (pci_ext_cfg_avail(root->bus->self))
                flags |= OSC_EXT_PCI_CONFIG_SUPPORT;
-       if (pcie_aspm_enabled())
+       if (pcie_aspm_support_enabled())
                flags |= OSC_ACTIVE_STATE_PWR_SUPPORT |
                        OSC_CLOCK_PWR_CAPABILITY_SUPPORT;
        if (pci_msi_enabled())
@@ -567,6 +574,50 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
        if (flags != base_flags)
                acpi_pci_osc_support(root, flags);
 
+       if (!pcie_ports_disabled
+           && (flags & ACPI_PCIE_REQ_SUPPORT) == ACPI_PCIE_REQ_SUPPORT) {
+               flags = OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL
+                       | OSC_PCI_EXPRESS_NATIVE_HP_CONTROL
+                       | OSC_PCI_EXPRESS_PME_CONTROL;
+
+               if (pci_aer_available()) {
+                       if (aer_acpi_firmware_first())
+                               dev_dbg(root->bus->bridge,
+                                       "PCIe errors handled by BIOS.\n");
+                       else
+                               flags |= OSC_PCI_EXPRESS_AER_CONTROL;
+               }
+
+               dev_info(root->bus->bridge,
+                       "Requesting ACPI _OSC control (0x%02x)\n", flags);
+
+               status = acpi_pci_osc_control_set(device->handle, &flags,
+                                       OSC_PCI_EXPRESS_CAP_STRUCTURE_CONTROL);
+               if (ACPI_SUCCESS(status)) {
+                       dev_info(root->bus->bridge,
+                               "ACPI _OSC control (0x%02x) granted\n", flags);
+                       if (acpi_gbl_FADT.boot_flags & ACPI_FADT_NO_ASPM) {
+                               /*
+                                * We have ASPM control, but the FADT indicates
+                                * that it's unsupported. Clear it.
+                                */
+                               pcie_clear_aspm(root->bus);
+                       }
+               } else {
+                       dev_info(root->bus->bridge,
+                               "ACPI _OSC request failed (%s), "
+                               "returned control mask: 0x%02x\n",
+                               acpi_format_exception(status), flags);
+                       pr_info("ACPI _OSC control for PCIe not granted, "
+                               "disabling ASPM\n");
+                       pcie_no_aspm();
+               }
+       } else {
+               dev_info(root->bus->bridge,
+                        "Unable to request _OSC control "
+                        "(_OSC support mask: 0x%02x)\n", flags);
+       }
+
        pci_acpi_add_bus_pm_notifier(device, root->bus);
        if (device->wakeup.flags.run_wake)
                device_set_run_wake(root->bus->bridge, true);
@@ -601,6 +652,8 @@ static int acpi_pci_root_remove(struct acpi_device *device, int type)
 
 static int __init acpi_pci_root_init(void)
 {
+       acpi_hest_init();
+
        if (acpi_pci_disabled)
                return 0;