Subject: [PATCH] ACPI, PCI: Stop pci devices before acpi_pci_driver remove calling During stop pci drivers, it still need to access ioapic and iommu. So need to make sure those drivers need to be stop at first. Also change the acpi_pci_drivers remove calling sequence to reverse. Signed-off-by: Yinghai Lu --- drivers/acpi/pci_root.c | 11 +++++++---- drivers/pci/remove.c | 2 +- include/linux/pci.h | 1 + 3 files changed, 9 insertions(+), 5 deletions(-) Index: linux-2.6/drivers/acpi/pci_root.c =================================================================== --- linux-2.6.orig/drivers/acpi/pci_root.c +++ linux-2.6/drivers/acpi/pci_root.c @@ -657,10 +657,6 @@ static int acpi_pci_root_remove(struct a mutex_lock(&acpi_pci_root_lock); - list_for_each_entry(driver, &acpi_pci_drivers, node) - if (driver->remove) - driver->remove(root->device->handle); - /* that root bus could be removed already */ if (!pci_find_bus(root->segment, root->secondary.start)) { dev_printk(KERN_DEBUG, &device->dev, @@ -668,6 +664,13 @@ static int acpi_pci_root_remove(struct a goto out; } + /* stop normal pci drivers before we stop ioapic and dmar etc */ + pci_stop_bus_devices(root->bus); + + list_for_each_entry_reverse(driver, &acpi_pci_drivers, node) + if (driver->remove) + driver->remove(root->device->handle); + device_set_run_wake(root->bus->bridge, false); pci_acpi_remove_bus_pm_notifier(device); Index: linux-2.6/drivers/pci/remove.c =================================================================== --- linux-2.6.orig/drivers/pci/remove.c +++ linux-2.6/drivers/pci/remove.c @@ -117,7 +117,7 @@ static void __pci_remove_bus_devices(str __pci_remove_bus_device(dev); } -static void pci_stop_bus_devices(struct pci_bus *bus) +void pci_stop_bus_devices(struct pci_bus *bus) { struct pci_dev *dev, *tmp; Index: linux-2.6/include/linux/pci.h =================================================================== --- linux-2.6.orig/include/linux/pci.h +++ linux-2.6/include/linux/pci.h @@ -782,6 +782,7 @@ extern void pci_dev_put(struct pci_dev * extern void pci_remove_bus(struct pci_bus *b); extern void __pci_remove_bus_device(struct pci_dev *dev); extern void pci_stop_and_remove_bus_device(struct pci_dev *dev); +void pci_stop_bus_devices(struct pci_bus *bus); void pci_stop_and_remove_bus(struct pci_bus *bus); extern void pci_stop_bus_device(struct pci_dev *dev); void pci_setup_cardbus(struct pci_bus *bus);