}
 static DEVICE_ATTR_RW(msi_bus);
 
-static DEFINE_MUTEX(pci_remove_rescan_mutex);
 static ssize_t bus_rescan_store(struct bus_type *bus, const char *buf,
                                size_t count)
 {
                return -EINVAL;
 
        if (val) {
-               mutex_lock(&pci_remove_rescan_mutex);
+               pci_lock_rescan_remove();
                while ((b = pci_find_next_bus(b)) != NULL)
                        pci_rescan_bus(b);
-               mutex_unlock(&pci_remove_rescan_mutex);
+               pci_unlock_rescan_remove();
        }
        return count;
 }
                return -EINVAL;
 
        if (val) {
-               mutex_lock(&pci_remove_rescan_mutex);
+               pci_lock_rescan_remove();
                pci_rescan_bus(pdev->bus);
-               mutex_unlock(&pci_remove_rescan_mutex);
+               pci_unlock_rescan_remove();
        }
        return count;
 }
 
 static void remove_callback(struct device *dev)
 {
-       struct pci_dev *pdev = to_pci_dev(dev);
-
-       mutex_lock(&pci_remove_rescan_mutex);
-       pci_stop_and_remove_bus_device(pdev);
-       mutex_unlock(&pci_remove_rescan_mutex);
+       pci_stop_and_remove_bus_device_locked(to_pci_dev(dev));
 }
 
 static ssize_t
                return -EINVAL;
 
        if (val) {
-               mutex_lock(&pci_remove_rescan_mutex);
+               pci_lock_rescan_remove();
                if (!pci_is_root_bus(bus) && list_empty(&bus->devices))
                        pci_rescan_bus_bridge_resize(bus->self);
                else
                        pci_rescan_bus(bus);
-               mutex_unlock(&pci_remove_rescan_mutex);
+               pci_unlock_rescan_remove();
        }
        return count;
 }
 
 EXPORT_SYMBOL(pci_scan_bridge);
 EXPORT_SYMBOL_GPL(pci_scan_child_bus);
 
+/*
+ * pci_rescan_bus(), pci_rescan_bus_bridge_resize() and PCI device removal
+ * routines should always be executed under this mutex.
+ */
+static DEFINE_MUTEX(pci_rescan_remove_lock);
+
+void pci_lock_rescan_remove(void)
+{
+       mutex_lock(&pci_rescan_remove_lock);
+}
+EXPORT_SYMBOL_GPL(pci_lock_rescan_remove);
+
+void pci_unlock_rescan_remove(void)
+{
+       mutex_unlock(&pci_rescan_remove_lock);
+}
+EXPORT_SYMBOL_GPL(pci_unlock_rescan_remove);
+
 static int __init pci_sort_bf_cmp(const struct device *d_a, const struct device *d_b)
 {
        const struct pci_dev *a = to_pci_dev(d_a);
 
 }
 EXPORT_SYMBOL(pci_stop_and_remove_bus_device);
 
+void pci_stop_and_remove_bus_device_locked(struct pci_dev *dev)
+{
+       pci_lock_rescan_remove();
+       pci_stop_and_remove_bus_device(dev);
+       pci_unlock_rescan_remove();
+}
+EXPORT_SYMBOL_GPL(pci_stop_and_remove_bus_device_locked);
+
 void pci_stop_root_bus(struct pci_bus *bus)
 {
        struct pci_dev *child, *tmp;
 
 void pci_dev_put(struct pci_dev *dev);
 void pci_remove_bus(struct pci_bus *b);
 void pci_stop_and_remove_bus_device(struct pci_dev *dev);
+void pci_stop_and_remove_bus_device_locked(struct pci_dev *dev);
 void pci_stop_root_bus(struct pci_bus *bus);
 void pci_remove_root_bus(struct pci_bus *bus);
 void pci_setup_cardbus(struct pci_bus *bus);
 int pci_bus_find_capability(struct pci_bus *bus, unsigned int devfn, int cap);
 unsigned int pci_rescan_bus_bridge_resize(struct pci_dev *bridge);
 unsigned int pci_rescan_bus(struct pci_bus *bus);
+void pci_lock_rescan_remove(void);
+void pci_unlock_rescan_remove(void);
 
 /* Vital product data routines */
 ssize_t pci_read_vpd(struct pci_dev *dev, loff_t pos, size_t count, void *buf);