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 4bec13d9c2bf..d710585e4a7f 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
| @@ -27,7 +27,7 @@ | |||
| 27 | #include <linux/module.h> | 27 | #include <linux/module.h> |
| 28 | #include <linux/init.h> | 28 | #include <linux/init.h> |
| 29 | #include <linux/types.h> | 29 | #include <linux/types.h> |
| 30 | #include <linux/spinlock.h> | 30 | #include <linux/mutex.h> |
| 31 | #include <linux/pm.h> | 31 | #include <linux/pm.h> |
| 32 | #include <linux/pm_runtime.h> | 32 | #include <linux/pm_runtime.h> |
| 33 | #include <linux/pci.h> | 33 | #include <linux/pci.h> |
| @@ -71,6 +71,8 @@ static struct acpi_driver acpi_pci_root_driver = { | |||
| 71 | }, | 71 | }, |
| 72 | }; | 72 | }; |
| 73 | 73 | ||
| 74 | /* Lock to protect both acpi_pci_roots and acpi_pci_drivers lists */ | ||
| 75 | static DEFINE_MUTEX(acpi_pci_root_lock); | ||
| 74 | static LIST_HEAD(acpi_pci_roots); | 76 | static LIST_HEAD(acpi_pci_roots); |
| 75 | static LIST_HEAD(acpi_pci_drivers); | 77 | static LIST_HEAD(acpi_pci_drivers); |
| 76 | 78 | ||
| @@ -81,34 +83,30 @@ int acpi_pci_register_driver(struct acpi_pci_driver *driver) | |||
| 81 | int n = 0; | 83 | int n = 0; |
| 82 | struct acpi_pci_root *root; | 84 | struct acpi_pci_root *root; |
| 83 | 85 | ||
| 86 | mutex_lock(&acpi_pci_root_lock); | ||
| 84 | list_add_tail(&driver->node, &acpi_pci_drivers); | 87 | list_add_tail(&driver->node, &acpi_pci_drivers); |
| 85 | 88 | if (driver->add) | |
| 86 | if (!driver->add) | 89 | list_for_each_entry(root, &acpi_pci_roots, node) { |
| 87 | return 0; | 90 | driver->add(root->device->handle); |
| 88 | 91 | n++; | |
| 89 | list_for_each_entry(root, &acpi_pci_roots, node) { | 92 | } |
| 90 | driver->add(root->device->handle); | 93 | mutex_unlock(&acpi_pci_root_lock); |
| 91 | n++; | ||
| 92 | } | ||
| 93 | 94 | ||
| 94 | return n; | 95 | return n; |
| 95 | } | 96 | } |
| 96 | |||
| 97 | EXPORT_SYMBOL(acpi_pci_register_driver); | 97 | EXPORT_SYMBOL(acpi_pci_register_driver); |
| 98 | 98 | ||
| 99 | void acpi_pci_unregister_driver(struct acpi_pci_driver *driver) | 99 | void acpi_pci_unregister_driver(struct acpi_pci_driver *driver) |
| 100 | { | 100 | { |
| 101 | struct acpi_pci_root *root; | 101 | struct acpi_pci_root *root; |
| 102 | 102 | ||
| 103 | mutex_lock(&acpi_pci_root_lock); | ||
| 103 | list_del(&driver->node); | 104 | list_del(&driver->node); |
| 104 | 105 | if (driver->remove) | |
| 105 | if (!driver->remove) | 106 | list_for_each_entry(root, &acpi_pci_roots, node) |
| 106 | return; | 107 | driver->remove(root->device->handle); |
| 107 | 108 | mutex_unlock(&acpi_pci_root_lock); | |
| 108 | list_for_each_entry(root, &acpi_pci_roots, node) | ||
| 109 | driver->remove(root->device->handle); | ||
| 110 | } | 109 | } |
| 111 | |||
| 112 | EXPORT_SYMBOL(acpi_pci_unregister_driver); | 110 | EXPORT_SYMBOL(acpi_pci_unregister_driver); |
| 113 | 111 | ||
| 114 | acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus) | 112 | 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) | |||
| 628 | struct acpi_pci_root *root = acpi_driver_data(device); | 626 | struct acpi_pci_root *root = acpi_driver_data(device); |
| 629 | struct acpi_pci_driver *driver; | 627 | struct acpi_pci_driver *driver; |
| 630 | 628 | ||
| 629 | mutex_lock(&acpi_pci_root_lock); | ||
| 631 | list_for_each_entry(driver, &acpi_pci_drivers, node) | 630 | list_for_each_entry(driver, &acpi_pci_drivers, node) |
| 632 | if (driver->add) | 631 | if (driver->add) |
| 633 | driver->add(device->handle); | 632 | driver->add(device->handle); |
| 633 | mutex_unlock(&acpi_pci_root_lock); | ||
| 634 | 634 | ||
| 635 | pci_bus_add_devices(root->bus); | 635 | pci_bus_add_devices(root->bus); |
| 636 | 636 | ||
| @@ -642,9 +642,11 @@ static int acpi_pci_root_remove(struct acpi_device *device, int type) | |||
| 642 | struct acpi_pci_root *root = acpi_driver_data(device); | 642 | struct acpi_pci_root *root = acpi_driver_data(device); |
| 643 | struct acpi_pci_driver *driver; | 643 | struct acpi_pci_driver *driver; |
| 644 | 644 | ||
| 645 | mutex_lock(&acpi_pci_root_lock); | ||
| 645 | list_for_each_entry(driver, &acpi_pci_drivers, node) | 646 | list_for_each_entry(driver, &acpi_pci_drivers, node) |
| 646 | if (driver->remove) | 647 | if (driver->remove) |
| 647 | driver->remove(root->device->handle); | 648 | driver->remove(root->device->handle); |
| 649 | mutex_unlock(&acpi_pci_root_lock); | ||
| 648 | 650 | ||
| 649 | device_set_run_wake(root->bus->bridge, false); | 651 | device_set_run_wake(root->bus->bridge, false); |
| 650 | pci_acpi_remove_bus_pm_notifier(device); | 652 | pci_acpi_remove_bus_pm_notifier(device); |
