]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/acpi/pci_root.c
Merge branch 'acpi-hotplug'
[karo-tx-linux.git] / drivers / acpi / pci_root.c
index 5917839321b8bb01254f57e0cde630f637ff76b2..d3874f4256534d06aeb0fdb9f364e5f5851963f3 100644 (file)
@@ -378,6 +378,7 @@ static int acpi_pci_root_add(struct acpi_device *device,
        struct acpi_pci_root *root;
        u32 flags, base_flags;
        acpi_handle handle = device->handle;
+       bool no_aspm = false, clear_aspm = false;
 
        root = kzalloc(sizeof(struct acpi_pci_root), GFP_KERNEL);
        if (!root)
@@ -437,27 +438,6 @@ static int acpi_pci_root_add(struct acpi_device *device,
        flags = base_flags = OSC_PCI_SEGMENT_GROUPS_SUPPORT;
        acpi_pci_osc_support(root, flags);
 
-       /*
-        * TBD: Need PCI interface for enumeration/configuration of roots.
-        */
-
-       /*
-        * Scan the Root Bridge
-        * --------------------
-        * Must do this prior to any attempt to bind the root device, as the
-        * PCI namespace does not get created until this call is made (and
-        * thus the root bridge's pci_dev does not exist).
-        */
-       root->bus = pci_acpi_scan_root(root);
-       if (!root->bus) {
-               dev_err(&device->dev,
-                       "Bus %04x:%02x not present in PCI namespace\n",
-                       root->segment, (unsigned int)root->secondary.start);
-               result = -ENODEV;
-               goto end;
-       }
-
-       /* Indicate support for various _OSC capabilities. */
        if (pci_ext_cfg_avail())
                flags |= OSC_EXT_PCI_CONFIG_SUPPORT;
        if (pcie_aspm_support_enabled()) {
@@ -471,7 +451,7 @@ static int acpi_pci_root_add(struct acpi_device *device,
                if (ACPI_FAILURE(status)) {
                        dev_info(&device->dev, "ACPI _OSC support "
                                "notification failed, disabling PCIe ASPM\n");
-                       pcie_no_aspm();
+                       no_aspm = true;
                        flags = base_flags;
                }
        }
@@ -503,7 +483,7 @@ static int acpi_pci_root_add(struct acpi_device *device,
                                 * We have ASPM control, but the FADT indicates
                                 * that it's unsupported. Clear it.
                                 */
-                               pcie_clear_aspm(root->bus);
+                               clear_aspm = true;
                        }
                } else {
                        dev_info(&device->dev,
@@ -512,7 +492,14 @@ static int acpi_pci_root_add(struct acpi_device *device,
                                acpi_format_exception(status), flags);
                        dev_info(&device->dev,
                                 "ACPI _OSC control for PCIe not granted, disabling ASPM\n");
-                       pcie_no_aspm();
+                       /*
+                        * We want to disable ASPM here, but aspm_disabled
+                        * needs to remain in its state from boot so that we
+                        * properly handle PCIe 1.1 devices.  So we set this
+                        * flag here, to defer the action until after the ACPI
+                        * root scan.
+                        */
+                       no_aspm = true;
                }
        } else {
                dev_info(&device->dev,
@@ -520,16 +507,40 @@ static int acpi_pci_root_add(struct acpi_device *device,
                         "(_OSC support mask: 0x%02x)\n", flags);
        }
 
+       /*
+        * TBD: Need PCI interface for enumeration/configuration of roots.
+        */
+
+       /*
+        * Scan the Root Bridge
+        * --------------------
+        * Must do this prior to any attempt to bind the root device, as the
+        * PCI namespace does not get created until this call is made (and
+        * thus the root bridge's pci_dev does not exist).
+        */
+       root->bus = pci_acpi_scan_root(root);
+       if (!root->bus) {
+               dev_err(&device->dev,
+                       "Bus %04x:%02x not present in PCI namespace\n",
+                       root->segment, (unsigned int)root->secondary.start);
+               result = -ENODEV;
+               goto end;
+       }
+
+       if (clear_aspm) {
+               dev_info(&device->dev, "Disabling ASPM (FADT indicates it is unsupported)\n");
+               pcie_clear_aspm(root->bus);
+       }
+       if (no_aspm)
+               pcie_no_aspm();
+
        pci_acpi_add_bus_pm_notifier(device, root->bus);
        if (device->wakeup.flags.run_wake)
                device_set_run_wake(root->bus->bridge, true);
 
        if (system_state != SYSTEM_BOOTING) {
                pcibios_resource_survey_bus(root->bus);
-               pci_assign_unassigned_bus_resources(root->bus);
-
-               /* need to after hot-added ioapic is registered */
-               pci_enable_bridges(root->bus);
+               pci_assign_unassigned_root_bus_resources(root->bus);
        }
 
        pci_bus_add_devices(root->bus);