PCI/ACPI: provide MMCONFIG address for PCI host bridges
authorJiang Liu <jiang.liu@huawei.com>
Fri, 22 Jun 2012 06:55:16 +0000 (14:55 +0800)
committerBjorn Helgaas <bhelgaas@google.com>
Fri, 22 Jun 2012 21:16:51 +0000 (15:16 -0600)
This patch provide MMCONFIG address for PCI host bridges, which will
be used to support host bridge hotplug.  It gets MMCONFIG address
by evaluating _CBA method if available.

Reviewed-by: Yinghai Lu <yinghai@kernel.org>
Signed-off-by: Jiang Liu <liuj97@gmail.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
drivers/acpi/pci_root.c
drivers/pci/pci-acpi.c
include/acpi/acnames.h
include/acpi/acpi_bus.h
include/linux/pci-acpi.h

index 7aff631..ec54014 100644 (file)
@@ -505,6 +505,8 @@ static int __devinit acpi_pci_root_add(struct acpi_device *device)
        strcpy(acpi_device_class(device), ACPI_PCI_ROOT_CLASS);
        device->driver_data = root;
 
+       root->mcfg_addr = acpi_pci_root_get_mcfg_addr(device->handle);
+
        /*
         * All supported architectures that use ACPI have support for
         * PCI domains, so we indicate this in _OSC support capabilities.
index 61e2fef..87f4c50 100644 (file)
@@ -162,6 +162,20 @@ acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev)
        return remove_pm_notifier(dev, pci_acpi_wake_dev);
 }
 
+phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle)
+{
+       acpi_status status = AE_NOT_EXIST;
+       unsigned long long mcfg_addr;
+
+       if (handle)
+               status = acpi_evaluate_integer(handle, METHOD_NAME__CBA,
+                                              NULL, &mcfg_addr);
+       if (ACPI_FAILURE(status))
+               return 0;
+
+       return (phys_addr_t)mcfg_addr;
+}
+
 /*
  * _SxD returns the D-state with the highest power
  * (lowest D-state number) supported in the S-state "x".
index 38f5088..b177f97 100644 (file)
@@ -62,6 +62,7 @@
 #define METHOD_NAME__AEI        "_AEI"
 #define METHOD_NAME__PRW        "_PRW"
 #define METHOD_NAME__SRS        "_SRS"
+#define METHOD_NAME__CBA        "_CBA"
 
 /* Method names - these methods must appear at the namespace root */
 
index 9e6e1c6..4579740 100644 (file)
@@ -401,6 +401,7 @@ struct acpi_pci_root {
 
        u32 osc_support_set;    /* _OSC state of support bits */
        u32 osc_control_set;    /* _OSC state of control bits */
+       phys_addr_t mcfg_addr;
 };
 
 /* helper */
index 4462350..248fba2 100644 (file)
@@ -17,6 +17,7 @@ extern acpi_status pci_acpi_remove_bus_pm_notifier(struct acpi_device *dev);
 extern acpi_status pci_acpi_add_pm_notifier(struct acpi_device *dev,
                                             struct pci_dev *pci_dev);
 extern acpi_status pci_acpi_remove_pm_notifier(struct acpi_device *dev);
+extern phys_addr_t acpi_pci_root_get_mcfg_addr(acpi_handle handle);
 
 static inline acpi_handle acpi_find_root_bridge_handle(struct pci_dev *pdev)
 {