aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/acpi/acpi_memhotplug.c56
-rw-r--r--drivers/acpi/container.c12
-rw-r--r--drivers/acpi/dock.c19
-rw-r--r--drivers/acpi/processor_driver.c24
-rw-r--r--drivers/acpi/scan.c69
-rw-r--r--drivers/pci/hotplug/acpiphp_glue.c6
-rw-r--r--drivers/pci/hotplug/sgi_hotplug.c5
-rw-r--r--include/acpi/acpi_bus.h3
8 files changed, 139 insertions, 55 deletions
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
index 94c823b25138..034d3e72aa92 100644
--- a/drivers/acpi/acpi_memhotplug.c
+++ b/drivers/acpi/acpi_memhotplug.c
@@ -153,14 +153,16 @@ acpi_memory_get_device_resources(struct acpi_memory_device *mem_device)
153 return 0; 153 return 0;
154} 154}
155 155
156static int 156static int acpi_memory_get_device(acpi_handle handle,
157acpi_memory_get_device(acpi_handle handle, 157 struct acpi_memory_device **mem_device)
158 struct acpi_memory_device **mem_device)
159{ 158{
160 struct acpi_device *device = NULL; 159 struct acpi_device *device = NULL;
161 int result; 160 int result = 0;
162 161
163 if (!acpi_bus_get_device(handle, &device) && device) 162 acpi_scan_lock_acquire();
163
164 acpi_bus_get_device(handle, &device);
165 if (device)
164 goto end; 166 goto end;
165 167
166 /* 168 /*
@@ -169,23 +171,28 @@ acpi_memory_get_device(acpi_handle handle,
169 */ 171 */
170 result = acpi_bus_scan(handle); 172 result = acpi_bus_scan(handle);
171 if (result) { 173 if (result) {
172 acpi_handle_warn(handle, "Cannot add acpi bus\n"); 174 acpi_handle_warn(handle, "ACPI namespace scan failed\n");
173 return -EINVAL; 175 result = -EINVAL;
176 goto out;
174 } 177 }
175 result = acpi_bus_get_device(handle, &device); 178 result = acpi_bus_get_device(handle, &device);
176 if (result) { 179 if (result) {
177 acpi_handle_warn(handle, "Missing device object\n"); 180 acpi_handle_warn(handle, "Missing device object\n");
178 return -EINVAL; 181 result = -EINVAL;
182 goto out;
179 } 183 }
180 184
181 end: 185 end:
182 *mem_device = acpi_driver_data(device); 186 *mem_device = acpi_driver_data(device);
183 if (!(*mem_device)) { 187 if (!(*mem_device)) {
184 dev_err(&device->dev, "driver data not found\n"); 188 dev_err(&device->dev, "driver data not found\n");
185 return -ENODEV; 189 result = -ENODEV;
190 goto out;
186 } 191 }
187 192
188 return 0; 193 out:
194 acpi_scan_lock_release();
195 return result;
189} 196}
190 197
191static int acpi_memory_check_device(struct acpi_memory_device *mem_device) 198static int acpi_memory_check_device(struct acpi_memory_device *mem_device)
@@ -305,6 +312,7 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
305 struct acpi_device *device; 312 struct acpi_device *device;
306 struct acpi_eject_event *ej_event = NULL; 313 struct acpi_eject_event *ej_event = NULL;
307 u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */ 314 u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */
315 acpi_status status;
308 316
309 switch (event) { 317 switch (event) {
310 case ACPI_NOTIFY_BUS_CHECK: 318 case ACPI_NOTIFY_BUS_CHECK:
@@ -327,29 +335,40 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
327 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 335 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
328 "\nReceived EJECT REQUEST notification for device\n")); 336 "\nReceived EJECT REQUEST notification for device\n"));
329 337
338 status = AE_ERROR;
339 acpi_scan_lock_acquire();
340
330 if (acpi_bus_get_device(handle, &device)) { 341 if (acpi_bus_get_device(handle, &device)) {
331 acpi_handle_err(handle, "Device doesn't exist\n"); 342 acpi_handle_err(handle, "Device doesn't exist\n");
332 break; 343 goto unlock;
333 } 344 }
334 mem_device = acpi_driver_data(device); 345 mem_device = acpi_driver_data(device);
335 if (!mem_device) { 346 if (!mem_device) {
336 acpi_handle_err(handle, "Driver Data is NULL\n"); 347 acpi_handle_err(handle, "Driver Data is NULL\n");
337 break; 348 goto unlock;
338 } 349 }
339 350
340 ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL); 351 ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL);
341 if (!ej_event) { 352 if (!ej_event) {
342 pr_err(PREFIX "No memory, dropping EJECT\n"); 353 pr_err(PREFIX "No memory, dropping EJECT\n");
343 break; 354 goto unlock;
344 } 355 }
345 356
357 get_device(&device->dev);
346 ej_event->device = device; 358 ej_event->device = device;
347 ej_event->event = ACPI_NOTIFY_EJECT_REQUEST; 359 ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
348 acpi_os_hotplug_execute(acpi_bus_hot_remove_device, 360 /* The eject is carried out asynchronously. */
349 (void *)ej_event); 361 status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device,
362 ej_event);
363 if (ACPI_FAILURE(status)) {
364 put_device(&device->dev);
365 kfree(ej_event);
366 }
350 367
351 /* eject is performed asynchronously */ 368 unlock:
352 return; 369 acpi_scan_lock_release();
370 if (ACPI_SUCCESS(status))
371 return;
353 default: 372 default:
354 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 373 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
355 "Unsupported event [0x%x]\n", event)); 374 "Unsupported event [0x%x]\n", event));
@@ -360,7 +379,6 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data)
360 379
361 /* Inform firmware that the hotplug operation has completed */ 380 /* Inform firmware that the hotplug operation has completed */
362 (void) acpi_evaluate_hotplug_ost(handle, event, ost_code, NULL); 381 (void) acpi_evaluate_hotplug_ost(handle, event, ost_code, NULL);
363 return;
364} 382}
365 383
366static void acpi_memory_device_free(struct acpi_memory_device *mem_device) 384static void acpi_memory_device_free(struct acpi_memory_device *mem_device)
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index 4cc2937cc022..5523ba7d764d 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -88,6 +88,8 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
88 acpi_status status; 88 acpi_status status;
89 u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */ 89 u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */
90 90
91 acpi_scan_lock_acquire();
92
91 switch (type) { 93 switch (type) {
92 case ACPI_NOTIFY_BUS_CHECK: 94 case ACPI_NOTIFY_BUS_CHECK:
93 /* Fall through */ 95 /* Fall through */
@@ -103,7 +105,7 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
103 /* device exist and this is a remove request */ 105 /* device exist and this is a remove request */
104 device->flags.eject_pending = 1; 106 device->flags.eject_pending = 1;
105 kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); 107 kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
106 return; 108 goto out;
107 } 109 }
108 break; 110 break;
109 } 111 }
@@ -130,18 +132,20 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context)
130 if (!acpi_bus_get_device(handle, &device) && device) { 132 if (!acpi_bus_get_device(handle, &device) && device) {
131 device->flags.eject_pending = 1; 133 device->flags.eject_pending = 1;
132 kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); 134 kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE);
133 return; 135 goto out;
134 } 136 }
135 break; 137 break;
136 138
137 default: 139 default:
138 /* non-hotplug event; possibly handled by other handler */ 140 /* non-hotplug event; possibly handled by other handler */
139 return; 141 goto out;
140 } 142 }
141 143
142 /* Inform firmware that the hotplug operation has completed */ 144 /* Inform firmware that the hotplug operation has completed */
143 (void) acpi_evaluate_hotplug_ost(handle, type, ost_code, NULL); 145 (void) acpi_evaluate_hotplug_ost(handle, type, ost_code, NULL);
144 return; 146
147 out:
148 acpi_scan_lock_release();
145} 149}
146 150
147static bool is_container(acpi_handle handle) 151static bool is_container(acpi_handle handle)
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 68d720af71ed..4fdea381ef21 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -744,7 +744,9 @@ static void acpi_dock_deferred_cb(void *context)
744{ 744{
745 struct dock_data *data = context; 745 struct dock_data *data = context;
746 746
747 acpi_scan_lock_acquire();
747 dock_notify(data->handle, data->event, data->ds); 748 dock_notify(data->handle, data->event, data->ds);
749 acpi_scan_lock_release();
748 kfree(data); 750 kfree(data);
749} 751}
750 752
@@ -757,20 +759,31 @@ static int acpi_dock_notifier_call(struct notifier_block *this,
757 if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK 759 if (event != ACPI_NOTIFY_BUS_CHECK && event != ACPI_NOTIFY_DEVICE_CHECK
758 && event != ACPI_NOTIFY_EJECT_REQUEST) 760 && event != ACPI_NOTIFY_EJECT_REQUEST)
759 return 0; 761 return 0;
762
763 acpi_scan_lock_acquire();
764
760 list_for_each_entry(dock_station, &dock_stations, sibling) { 765 list_for_each_entry(dock_station, &dock_stations, sibling) {
761 if (dock_station->handle == handle) { 766 if (dock_station->handle == handle) {
762 struct dock_data *dd; 767 struct dock_data *dd;
768 acpi_status status;
763 769
764 dd = kmalloc(sizeof(*dd), GFP_KERNEL); 770 dd = kmalloc(sizeof(*dd), GFP_KERNEL);
765 if (!dd) 771 if (!dd)
766 return 0; 772 break;
773
767 dd->handle = handle; 774 dd->handle = handle;
768 dd->event = event; 775 dd->event = event;
769 dd->ds = dock_station; 776 dd->ds = dock_station;
770 acpi_os_hotplug_execute(acpi_dock_deferred_cb, dd); 777 status = acpi_os_hotplug_execute(acpi_dock_deferred_cb,
771 return 0 ; 778 dd);
779 if (ACPI_FAILURE(status))
780 kfree(dd);
781
782 break;
772 } 783 }
773 } 784 }
785
786 acpi_scan_lock_release();
774 return 0; 787 return 0;
775} 788}
776 789
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c
index c5d2fd85dbe0..cbf1f122666b 100644
--- a/drivers/acpi/processor_driver.c
+++ b/drivers/acpi/processor_driver.c
@@ -683,8 +683,11 @@ static void acpi_processor_hotplug_notify(acpi_handle handle,
683 struct acpi_device *device = NULL; 683 struct acpi_device *device = NULL;
684 struct acpi_eject_event *ej_event = NULL; 684 struct acpi_eject_event *ej_event = NULL;
685 u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */ 685 u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */
686 acpi_status status;
686 int result; 687 int result;
687 688
689 acpi_scan_lock_acquire();
690
688 switch (event) { 691 switch (event) {
689 case ACPI_NOTIFY_BUS_CHECK: 692 case ACPI_NOTIFY_BUS_CHECK:
690 case ACPI_NOTIFY_DEVICE_CHECK: 693 case ACPI_NOTIFY_DEVICE_CHECK:
@@ -733,25 +736,32 @@ static void acpi_processor_hotplug_notify(acpi_handle handle,
733 break; 736 break;
734 } 737 }
735 738
739 get_device(&device->dev);
736 ej_event->device = device; 740 ej_event->device = device;
737 ej_event->event = ACPI_NOTIFY_EJECT_REQUEST; 741 ej_event->event = ACPI_NOTIFY_EJECT_REQUEST;
738 acpi_os_hotplug_execute(acpi_bus_hot_remove_device, 742 /* The eject is carried out asynchronously. */
739 (void *)ej_event); 743 status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device,
740 744 ej_event);
741 /* eject is performed asynchronously */ 745 if (ACPI_FAILURE(status)) {
742 return; 746 put_device(&device->dev);
747 kfree(ej_event);
748 break;
749 }
750 goto out;
743 751
744 default: 752 default:
745 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 753 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
746 "Unsupported event [0x%x]\n", event)); 754 "Unsupported event [0x%x]\n", event));
747 755
748 /* non-hotplug event; possibly handled by other handler */ 756 /* non-hotplug event; possibly handled by other handler */
749 return; 757 goto out;
750 } 758 }
751 759
752 /* Inform firmware that the hotplug operation has completed */ 760 /* Inform firmware that the hotplug operation has completed */
753 (void) acpi_evaluate_hotplug_ost(handle, event, ost_code, NULL); 761 (void) acpi_evaluate_hotplug_ost(handle, event, ost_code, NULL);
754 return; 762
763 out:
764 acpi_scan_lock_release();
755} 765}
756 766
757static acpi_status is_processor_device(acpi_handle handle) 767static acpi_status is_processor_device(acpi_handle handle)
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index c7676ee8eca4..d16a94ef0baf 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -42,6 +42,18 @@ struct acpi_device_bus_id{
42 struct list_head node; 42 struct list_head node;
43}; 43};
44 44
45void acpi_scan_lock_acquire(void)
46{
47 mutex_lock(&acpi_scan_lock);
48}
49EXPORT_SYMBOL_GPL(acpi_scan_lock_acquire);
50
51void acpi_scan_lock_release(void)
52{
53 mutex_unlock(&acpi_scan_lock);
54}
55EXPORT_SYMBOL_GPL(acpi_scan_lock_release);
56
45int acpi_scan_add_handler(struct acpi_scan_handler *handler) 57int acpi_scan_add_handler(struct acpi_scan_handler *handler)
46{ 58{
47 if (!handler || !handler->attach) 59 if (!handler || !handler->attach)
@@ -95,8 +107,6 @@ acpi_device_modalias_show(struct device *dev, struct device_attribute *attr, cha
95} 107}
96static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL); 108static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL);
97 109
98static void __acpi_bus_trim(struct acpi_device *start);
99
100/** 110/**
101 * acpi_bus_hot_remove_device: hot-remove a device and its children 111 * acpi_bus_hot_remove_device: hot-remove a device and its children
102 * @context: struct acpi_eject_event pointer (freed in this func) 112 * @context: struct acpi_eject_event pointer (freed in this func)
@@ -107,7 +117,7 @@ static void __acpi_bus_trim(struct acpi_device *start);
107 */ 117 */
108void acpi_bus_hot_remove_device(void *context) 118void acpi_bus_hot_remove_device(void *context)
109{ 119{
110 struct acpi_eject_event *ej_event = (struct acpi_eject_event *) context; 120 struct acpi_eject_event *ej_event = context;
111 struct acpi_device *device = ej_event->device; 121 struct acpi_device *device = ej_event->device;
112 acpi_handle handle = device->handle; 122 acpi_handle handle = device->handle;
113 acpi_handle temp; 123 acpi_handle temp;
@@ -118,11 +128,19 @@ void acpi_bus_hot_remove_device(void *context)
118 128
119 mutex_lock(&acpi_scan_lock); 129 mutex_lock(&acpi_scan_lock);
120 130
131 /* If there is no handle, the device node has been unregistered. */
132 if (!device->handle) {
133 dev_dbg(&device->dev, "ACPI handle missing\n");
134 put_device(&device->dev);
135 goto out;
136 }
137
121 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 138 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
122 "Hot-removing device %s...\n", dev_name(&device->dev))); 139 "Hot-removing device %s...\n", dev_name(&device->dev)));
123 140
124 __acpi_bus_trim(device); 141 acpi_bus_trim(device);
125 /* Device node has been released. */ 142 /* Device node has been unregistered. */
143 put_device(&device->dev);
126 device = NULL; 144 device = NULL;
127 145
128 if (ACPI_SUCCESS(acpi_get_handle(handle, "_LCK", &temp))) { 146 if (ACPI_SUCCESS(acpi_get_handle(handle, "_LCK", &temp))) {
@@ -151,6 +169,7 @@ void acpi_bus_hot_remove_device(void *context)
151 ost_code, NULL); 169 ost_code, NULL);
152 } 170 }
153 171
172 out:
154 mutex_unlock(&acpi_scan_lock); 173 mutex_unlock(&acpi_scan_lock);
155 kfree(context); 174 kfree(context);
156 return; 175 return;
@@ -212,6 +231,7 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
212 goto err; 231 goto err;
213 } 232 }
214 233
234 get_device(&acpi_device->dev);
215 ej_event->device = acpi_device; 235 ej_event->device = acpi_device;
216 if (acpi_device->flags.eject_pending) { 236 if (acpi_device->flags.eject_pending) {
217 /* event originated from ACPI eject notification */ 237 /* event originated from ACPI eject notification */
@@ -224,7 +244,11 @@ acpi_eject_store(struct device *d, struct device_attribute *attr,
224 ej_event->event, ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); 244 ej_event->event, ACPI_OST_SC_EJECT_IN_PROGRESS, NULL);
225 } 245 }
226 246
227 acpi_os_hotplug_execute(acpi_bus_hot_remove_device, (void *)ej_event); 247 status = acpi_os_hotplug_execute(acpi_bus_hot_remove_device, ej_event);
248 if (ACPI_FAILURE(status)) {
249 put_device(&acpi_device->dev);
250 kfree(ej_event);
251 }
228err: 252err:
229 return ret; 253 return ret;
230} 254}
@@ -779,6 +803,7 @@ static void acpi_device_unregister(struct acpi_device *device)
779 * no more references. 803 * no more references.
780 */ 804 */
781 acpi_device_set_power(device, ACPI_STATE_D3_COLD); 805 acpi_device_set_power(device, ACPI_STATE_D3_COLD);
806 device->handle = NULL;
782 put_device(&device->dev); 807 put_device(&device->dev);
783} 808}
784 809
@@ -1623,14 +1648,14 @@ static acpi_status acpi_bus_device_attach(acpi_handle handle, u32 lvl_not_used,
1623 * there has been a real error. There just have been no suitable ACPI objects 1648 * there has been a real error. There just have been no suitable ACPI objects
1624 * in the table trunk from which the kernel could create a device and add an 1649 * in the table trunk from which the kernel could create a device and add an
1625 * appropriate driver. 1650 * appropriate driver.
1651 *
1652 * Must be called under acpi_scan_lock.
1626 */ 1653 */
1627int acpi_bus_scan(acpi_handle handle) 1654int acpi_bus_scan(acpi_handle handle)
1628{ 1655{
1629 void *device = NULL; 1656 void *device = NULL;
1630 int error = 0; 1657 int error = 0;
1631 1658
1632 mutex_lock(&acpi_scan_lock);
1633
1634 if (ACPI_SUCCESS(acpi_bus_check_add(handle, 0, NULL, &device))) 1659 if (ACPI_SUCCESS(acpi_bus_check_add(handle, 0, NULL, &device)))
1635 acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, 1660 acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
1636 acpi_bus_check_add, NULL, NULL, &device); 1661 acpi_bus_check_add, NULL, NULL, &device);
@@ -1641,7 +1666,6 @@ int acpi_bus_scan(acpi_handle handle)
1641 acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, 1666 acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX,
1642 acpi_bus_device_attach, NULL, NULL, NULL); 1667 acpi_bus_device_attach, NULL, NULL, NULL);
1643 1668
1644 mutex_unlock(&acpi_scan_lock);
1645 return error; 1669 return error;
1646} 1670}
1647EXPORT_SYMBOL(acpi_bus_scan); 1671EXPORT_SYMBOL(acpi_bus_scan);
@@ -1678,7 +1702,13 @@ static acpi_status acpi_bus_remove(acpi_handle handle, u32 lvl_not_used,
1678 return AE_OK; 1702 return AE_OK;
1679} 1703}
1680 1704
1681static void __acpi_bus_trim(struct acpi_device *start) 1705/**
1706 * acpi_bus_trim - Remove ACPI device node and all of its descendants
1707 * @start: Root of the ACPI device nodes subtree to remove.
1708 *
1709 * Must be called under acpi_scan_lock.
1710 */
1711void acpi_bus_trim(struct acpi_device *start)
1682{ 1712{
1683 /* 1713 /*
1684 * Execute acpi_bus_device_detach() as a post-order callback to detach 1714 * Execute acpi_bus_device_detach() as a post-order callback to detach
@@ -1695,13 +1725,6 @@ static void __acpi_bus_trim(struct acpi_device *start)
1695 acpi_bus_remove, NULL, NULL); 1725 acpi_bus_remove, NULL, NULL);
1696 acpi_bus_remove(start->handle, 0, NULL, NULL); 1726 acpi_bus_remove(start->handle, 0, NULL, NULL);
1697} 1727}
1698
1699void acpi_bus_trim(struct acpi_device *start)
1700{
1701 mutex_lock(&acpi_scan_lock);
1702 __acpi_bus_trim(start);
1703 mutex_unlock(&acpi_scan_lock);
1704}
1705EXPORT_SYMBOL_GPL(acpi_bus_trim); 1728EXPORT_SYMBOL_GPL(acpi_bus_trim);
1706 1729
1707static int acpi_bus_scan_fixed(void) 1730static int acpi_bus_scan_fixed(void)
@@ -1758,23 +1781,27 @@ int __init acpi_scan_init(void)
1758 acpi_csrt_init(); 1781 acpi_csrt_init();
1759 acpi_container_init(); 1782 acpi_container_init();
1760 1783
1784 mutex_lock(&acpi_scan_lock);
1761 /* 1785 /*
1762 * Enumerate devices in the ACPI namespace. 1786 * Enumerate devices in the ACPI namespace.
1763 */ 1787 */
1764 result = acpi_bus_scan(ACPI_ROOT_OBJECT); 1788 result = acpi_bus_scan(ACPI_ROOT_OBJECT);
1765 if (result) 1789 if (result)
1766 return result; 1790 goto out;
1767 1791
1768 result = acpi_bus_get_device(ACPI_ROOT_OBJECT, &acpi_root); 1792 result = acpi_bus_get_device(ACPI_ROOT_OBJECT, &acpi_root);
1769 if (result) 1793 if (result)
1770 return result; 1794 goto out;
1771 1795
1772 result = acpi_bus_scan_fixed(); 1796 result = acpi_bus_scan_fixed();
1773 if (result) { 1797 if (result) {
1774 acpi_device_unregister(acpi_root); 1798 acpi_device_unregister(acpi_root);
1775 return result; 1799 goto out;
1776 } 1800 }
1777 1801
1778 acpi_update_all_gpes(); 1802 acpi_update_all_gpes();
1779 return 0; 1803
1804 out:
1805 mutex_unlock(&acpi_scan_lock);
1806 return result;
1780} 1807}
diff --git a/drivers/pci/hotplug/acpiphp_glue.c b/drivers/pci/hotplug/acpiphp_glue.c
index d1a6f4a25da8..a951c22921d1 100644
--- a/drivers/pci/hotplug/acpiphp_glue.c
+++ b/drivers/pci/hotplug/acpiphp_glue.c
@@ -1218,6 +1218,8 @@ static void _handle_hotplug_event_bridge(struct work_struct *work)
1218 handle = hp_work->handle; 1218 handle = hp_work->handle;
1219 type = hp_work->type; 1219 type = hp_work->type;
1220 1220
1221 acpi_scan_lock_acquire();
1222
1221 if (acpi_bus_get_device(handle, &device)) { 1223 if (acpi_bus_get_device(handle, &device)) {
1222 /* This bridge must have just been physically inserted */ 1224 /* This bridge must have just been physically inserted */
1223 handle_bridge_insertion(handle, type); 1225 handle_bridge_insertion(handle, type);
@@ -1295,6 +1297,7 @@ static void _handle_hotplug_event_bridge(struct work_struct *work)
1295 } 1297 }
1296 1298
1297out: 1299out:
1300 acpi_scan_lock_release();
1298 kfree(hp_work); /* allocated in handle_hotplug_event_bridge */ 1301 kfree(hp_work); /* allocated in handle_hotplug_event_bridge */
1299} 1302}
1300 1303
@@ -1341,6 +1344,8 @@ static void _handle_hotplug_event_func(struct work_struct *work)
1341 1344
1342 func = (struct acpiphp_func *)context; 1345 func = (struct acpiphp_func *)context;
1343 1346
1347 acpi_scan_lock_acquire();
1348
1344 switch (type) { 1349 switch (type) {
1345 case ACPI_NOTIFY_BUS_CHECK: 1350 case ACPI_NOTIFY_BUS_CHECK:
1346 /* bus re-enumerate */ 1351 /* bus re-enumerate */
@@ -1371,6 +1376,7 @@ static void _handle_hotplug_event_func(struct work_struct *work)
1371 break; 1376 break;
1372 } 1377 }
1373 1378
1379 acpi_scan_lock_release();
1374 kfree(hp_work); /* allocated in handle_hotplug_event_func */ 1380 kfree(hp_work); /* allocated in handle_hotplug_event_func */
1375} 1381}
1376 1382
diff --git a/drivers/pci/hotplug/sgi_hotplug.c b/drivers/pci/hotplug/sgi_hotplug.c
index ae606b3e991e..574421bc2fa6 100644
--- a/drivers/pci/hotplug/sgi_hotplug.c
+++ b/drivers/pci/hotplug/sgi_hotplug.c
@@ -425,6 +425,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
425 pdevice = NULL; 425 pdevice = NULL;
426 } 426 }
427 427
428 acpi_scan_lock_acquire();
428 /* 429 /*
429 * Walk the rootbus node's immediate children looking for 430 * Walk the rootbus node's immediate children looking for
430 * the slot's device node(s). There can be more than 431 * the slot's device node(s). There can be more than
@@ -458,6 +459,7 @@ static int enable_slot(struct hotplug_slot *bss_hotplug_slot)
458 } 459 }
459 } 460 }
460 } 461 }
462 acpi_scan_lock_release();
461 } 463 }
462 464
463 /* Call the driver for the new device */ 465 /* Call the driver for the new device */
@@ -508,6 +510,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
508 /* Get the rootbus node pointer */ 510 /* Get the rootbus node pointer */
509 phandle = PCI_CONTROLLER(slot->pci_bus)->acpi_handle; 511 phandle = PCI_CONTROLLER(slot->pci_bus)->acpi_handle;
510 512
513 acpi_scan_lock_acquire();
511 /* 514 /*
512 * Walk the rootbus node's immediate children looking for 515 * Walk the rootbus node's immediate children looking for
513 * the slot's device node(s). There can be more than 516 * the slot's device node(s). There can be more than
@@ -538,7 +541,7 @@ static int disable_slot(struct hotplug_slot *bss_hotplug_slot)
538 acpi_bus_trim(device); 541 acpi_bus_trim(device);
539 } 542 }
540 } 543 }
541 544 acpi_scan_lock_release();
542 } 545 }
543 546
544 /* Free the SN resources assigned to the Linux device.*/ 547 /* Free the SN resources assigned to the Linux device.*/
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h
index 41850cb21730..227ba7dc293d 100644
--- a/include/acpi/acpi_bus.h
+++ b/include/acpi/acpi_bus.h
@@ -395,6 +395,9 @@ int acpi_bus_receive_event(struct acpi_bus_event *event);
395static inline int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data) 395static inline int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data)
396 { return 0; } 396 { return 0; }
397#endif 397#endif
398
399void acpi_scan_lock_acquire(void);
400void acpi_scan_lock_release(void);
398int acpi_scan_add_handler(struct acpi_scan_handler *handler); 401int acpi_scan_add_handler(struct acpi_scan_handler *handler);
399int acpi_bus_register_driver(struct acpi_driver *driver); 402int acpi_bus_register_driver(struct acpi_driver *driver);
400void acpi_bus_unregister_driver(struct acpi_driver *driver); 403void acpi_bus_unregister_driver(struct acpi_driver *driver);