diff options
| -rw-r--r-- | drivers/acpi/pci_root.c | 36 | 
1 files changed, 19 insertions, 17 deletions
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 4bec13d9c2b..d710585e4a7 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -27,7 +27,7 @@  #include <linux/module.h>  #include <linux/init.h>  #include <linux/types.h> -#include <linux/spinlock.h> +#include <linux/mutex.h>  #include <linux/pm.h>  #include <linux/pm_runtime.h>  #include <linux/pci.h> @@ -71,6 +71,8 @@ static struct acpi_driver acpi_pci_root_driver = {  		},  }; +/* Lock to protect both acpi_pci_roots and acpi_pci_drivers lists */ +static DEFINE_MUTEX(acpi_pci_root_lock);  static LIST_HEAD(acpi_pci_roots);  static LIST_HEAD(acpi_pci_drivers); @@ -81,34 +83,30 @@ int acpi_pci_register_driver(struct acpi_pci_driver *driver)  	int n = 0;  	struct acpi_pci_root *root; +	mutex_lock(&acpi_pci_root_lock);  	list_add_tail(&driver->node, &acpi_pci_drivers); - -	if (!driver->add) -		return 0; - -	list_for_each_entry(root, &acpi_pci_roots, node) { -		driver->add(root->device->handle); -		n++; -	} +	if (driver->add) +		list_for_each_entry(root, &acpi_pci_roots, node) { +			driver->add(root->device->handle); +			n++; +		} +	mutex_unlock(&acpi_pci_root_lock);  	return n;  } -  EXPORT_SYMBOL(acpi_pci_register_driver);  void acpi_pci_unregister_driver(struct acpi_pci_driver *driver)  {  	struct acpi_pci_root *root; +	mutex_lock(&acpi_pci_root_lock);  	list_del(&driver->node); - -	if (!driver->remove) -		return; - -	list_for_each_entry(root, &acpi_pci_roots, node) -		driver->remove(root->device->handle); +	if (driver->remove) +		list_for_each_entry(root, &acpi_pci_roots, node) +			driver->remove(root->device->handle); +	mutex_unlock(&acpi_pci_root_lock);  } -  EXPORT_SYMBOL(acpi_pci_unregister_driver);  acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus) @@ -628,9 +626,11 @@ static int acpi_pci_root_start(struct acpi_device *device)  	struct acpi_pci_root *root = acpi_driver_data(device);  	struct acpi_pci_driver *driver; +	mutex_lock(&acpi_pci_root_lock);  	list_for_each_entry(driver, &acpi_pci_drivers, node)  		if (driver->add)  			driver->add(device->handle); +	mutex_unlock(&acpi_pci_root_lock);  	pci_bus_add_devices(root->bus); @@ -642,9 +642,11 @@ static int acpi_pci_root_remove(struct acpi_device *device, int type)  	struct acpi_pci_root *root = acpi_driver_data(device);  	struct acpi_pci_driver *driver; +	mutex_lock(&acpi_pci_root_lock);  	list_for_each_entry(driver, &acpi_pci_drivers, node)  		if (driver->remove)  			driver->remove(root->device->handle); +	mutex_unlock(&acpi_pci_root_lock);  	device_set_run_wake(root->bus->bridge, false);  	pci_acpi_remove_bus_pm_notifier(device);  |