aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTaku Izumi <izumi.taku@jp.fujitsu.com>2012-09-18 02:21:31 -0400
committerBjorn Helgaas <bhelgaas@google.com>2012-09-24 17:29:40 -0400
commitd0020f65220c237f300355873125df5efe2c2740 (patch)
tree8ab5df845900638034f30daf2b78d33c0924223b
parentc8e9afb124f61e0c9901801f4c95ae4208bd4536 (diff)
PCI/ACPI: Protect acpi_pci_drivers list with mutex
Use mutex to protect global acpi_pci_drivers list against PCI host bridge hotplug operations. Signed-off-by: Jiang Liu <jiang.liu@huawei.com> Signed-off-by: Yinghai Lu <yinghai@kernel.org> Signed-off-by: Taku Izumi <izumi.taku@jp.fujitsu.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-rw-r--r--drivers/acpi/pci_root.c36
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 */
75static DEFINE_MUTEX(acpi_pci_root_lock);
74static LIST_HEAD(acpi_pci_roots); 76static LIST_HEAD(acpi_pci_roots);
75static LIST_HEAD(acpi_pci_drivers); 77static 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
97EXPORT_SYMBOL(acpi_pci_register_driver); 97EXPORT_SYMBOL(acpi_pci_register_driver);
98 98
99void acpi_pci_unregister_driver(struct acpi_pci_driver *driver) 99void 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
112EXPORT_SYMBOL(acpi_pci_unregister_driver); 110EXPORT_SYMBOL(acpi_pci_unregister_driver);
113 111
114acpi_handle acpi_get_pci_rootbridge_handle(unsigned int seg, unsigned int bus) 112acpi_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);