summaryrefslogtreecommitdiff
path: root/drivers/acpi/pci_root.c
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2012-11-09 17:00:02 (GMT)
committerBjorn Helgaas <bhelgaas@google.com>2012-11-09 17:00:02 (GMT)
commitfa20f6f240e127bc914ca980a4b10c723c55fec9 (patch)
tree1a8267f53240b763a9d555a410341c3d7e432721 /drivers/acpi/pci_root.c
parent13a84687092f47a6d67b1b17940eb3127ae888b3 (diff)
parentf426cef3bc58806284e0fee55d29262b10279f9c (diff)
downloadlinux-fsl-qoriq-fa20f6f240e127bc914ca980a4b10c723c55fec9.tar.xz
Merge branch 'pci/yinghai-for-pci-root-bus-hotplug' into next
* pci/yinghai-for-pci-root-bus-hotplug: PCI/ACPI: Remove acpi_root_driver in reverse order PCI/ACPI: Delete host bridge _PRT during hot remove path PCI/ACPI: Make acpi_pci_root_remove() stop/remove pci root bus PCI: Add pci_stop_and_remove_root_bus() PCI/ACPI: Assign unassigned resource for hot-added root bus PCI: Move out pci_enable_bridges out of assign_unsigned_bus_res PCI: Move pci_rescan_bus() back to probe.c PCI: Separate out pci_assign_unassigned_bus_resources()
Diffstat (limited to 'drivers/acpi/pci_root.c')
-rw-r--r--drivers/acpi/pci_root.c21
1 files changed, 20 insertions, 1 deletions
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index bce469c..012f40d 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -644,12 +644,19 @@ static int acpi_pci_root_start(struct acpi_device *device)
struct acpi_pci_root *root = acpi_driver_data(device);
struct acpi_pci_driver *driver;
+ if (system_state != SYSTEM_BOOTING)
+ pci_assign_unassigned_bus_resources(root->bus);
+
mutex_lock(&acpi_pci_root_lock);
list_for_each_entry(driver, &acpi_pci_drivers, node)
if (driver->add)
driver->add(root);
mutex_unlock(&acpi_pci_root_lock);
+ /* need to after hot-added ioapic is registered */
+ if (system_state != SYSTEM_BOOTING)
+ pci_enable_bridges(root->bus);
+
pci_bus_add_devices(root->bus);
return 0;
@@ -657,17 +664,29 @@ static int acpi_pci_root_start(struct acpi_device *device)
static int acpi_pci_root_remove(struct acpi_device *device, int type)
{
+ acpi_status status;
+ acpi_handle handle;
struct acpi_pci_root *root = acpi_driver_data(device);
struct acpi_pci_driver *driver;
+ pci_stop_root_bus(root->bus);
+
mutex_lock(&acpi_pci_root_lock);
- list_for_each_entry(driver, &acpi_pci_drivers, node)
+ list_for_each_entry_reverse(driver, &acpi_pci_drivers, node)
if (driver->remove)
driver->remove(root);
+ mutex_unlock(&acpi_pci_root_lock);
device_set_run_wake(root->bus->bridge, false);
pci_acpi_remove_bus_pm_notifier(device);
+ status = acpi_get_handle(device->handle, METHOD_NAME__PRT, &handle);
+ if (ACPI_SUCCESS(status))
+ acpi_pci_irq_del_prt(root->bus);
+
+ pci_remove_root_bus(root->bus);
+
+ mutex_lock(&acpi_pci_root_lock);
list_del(&root->node);
mutex_unlock(&acpi_pci_root_lock);
kfree(root);