diff options
55 files changed, 535 insertions, 423 deletions
diff --git a/Documentation/acpi/enumeration.txt b/Documentation/acpi/enumeration.txt index 54469bc81b1c..94a656131885 100644 --- a/Documentation/acpi/enumeration.txt +++ b/Documentation/acpi/enumeration.txt | |||
@@ -63,8 +63,8 @@ from ACPI tables. | |||
63 | Currently the kernel is not able to automatically determine from which ACPI | 63 | Currently the kernel is not able to automatically determine from which ACPI |
64 | device it should make the corresponding platform device so we need to add | 64 | device it should make the corresponding platform device so we need to add |
65 | the ACPI device explicitly to acpi_platform_device_ids list defined in | 65 | the ACPI device explicitly to acpi_platform_device_ids list defined in |
66 | drivers/acpi/scan.c. This limitation is only for the platform devices, SPI | 66 | drivers/acpi/acpi_platform.c. This limitation is only for the platform |
67 | and I2C devices are created automatically as described below. | 67 | devices, SPI and I2C devices are created automatically as described below. |
68 | 68 | ||
69 | SPI serial bus support | 69 | SPI serial bus support |
70 | ~~~~~~~~~~~~~~~~~~~~~~ | 70 | ~~~~~~~~~~~~~~~~~~~~~~ |
diff --git a/Documentation/acpi/scan_handlers.txt b/Documentation/acpi/scan_handlers.txt new file mode 100644 index 000000000000..3246ccf15992 --- /dev/null +++ b/Documentation/acpi/scan_handlers.txt | |||
@@ -0,0 +1,77 @@ | |||
1 | ACPI Scan Handlers | ||
2 | |||
3 | Copyright (C) 2012, Intel Corporation | ||
4 | Author: Rafael J. Wysocki <rafael.j.wysocki@intel.com> | ||
5 | |||
6 | During system initialization and ACPI-based device hot-add, the ACPI namespace | ||
7 | is scanned in search of device objects that generally represent various pieces | ||
8 | of hardware. This causes a struct acpi_device object to be created and | ||
9 | registered with the driver core for every device object in the ACPI namespace | ||
10 | and the hierarchy of those struct acpi_device objects reflects the namespace | ||
11 | layout (i.e. parent device objects in the namespace are represented by parent | ||
12 | struct acpi_device objects and analogously for their children). Those struct | ||
13 | acpi_device objects are referred to as "device nodes" in what follows, but they | ||
14 | should not be confused with struct device_node objects used by the Device Trees | ||
15 | parsing code (although their role is analogous to the role of those objects). | ||
16 | |||
17 | During ACPI-based device hot-remove device nodes representing pieces of hardware | ||
18 | being removed are unregistered and deleted. | ||
19 | |||
20 | The core ACPI namespace scanning code in drivers/acpi/scan.c carries out basic | ||
21 | initialization of device nodes, such as retrieving common configuration | ||
22 | information from the device objects represented by them and populating them with | ||
23 | appropriate data, but some of them require additional handling after they have | ||
24 | been registered. For example, if the given device node represents a PCI host | ||
25 | bridge, its registration should cause the PCI bus under that bridge to be | ||
26 | enumerated and PCI devices on that bus to be registered with the driver core. | ||
27 | Similarly, if the device node represents a PCI interrupt link, it is necessary | ||
28 | to configure that link so that the kernel can use it. | ||
29 | |||
30 | Those additional configuration tasks usually depend on the type of the hardware | ||
31 | component represented by the given device node which can be determined on the | ||
32 | basis of the device node's hardware ID (HID). They are performed by objects | ||
33 | called ACPI scan handlers represented by the following structure: | ||
34 | |||
35 | struct acpi_scan_handler { | ||
36 | const struct acpi_device_id *ids; | ||
37 | struct list_head list_node; | ||
38 | int (*attach)(struct acpi_device *dev, const struct acpi_device_id *id); | ||
39 | void (*detach)(struct acpi_device *dev); | ||
40 | }; | ||
41 | |||
42 | where ids is the list of IDs of device nodes the given handler is supposed to | ||
43 | take care of, list_node is the hook to the global list of ACPI scan handlers | ||
44 | maintained by the ACPI core and the .attach() and .detach() callbacks are | ||
45 | executed, respectively, after registration of new device nodes and before | ||
46 | unregistration of device nodes the handler attached to previously. | ||
47 | |||
48 | The namespace scanning function, acpi_bus_scan(), first registers all of the | ||
49 | device nodes in the given namespace scope with the driver core. Then, it tries | ||
50 | to match a scan handler against each of them using the ids arrays of the | ||
51 | available scan handlers. If a matching scan handler is found, its .attach() | ||
52 | callback is executed for the given device node. If that callback returns 1, | ||
53 | that means that the handler has claimed the device node and is now responsible | ||
54 | for carrying out any additional configuration tasks related to it. It also will | ||
55 | be responsible for preparing the device node for unregistration in that case. | ||
56 | The device node's handler field is then populated with the address of the scan | ||
57 | handler that has claimed it. | ||
58 | |||
59 | If the .attach() callback returns 0, it means that the device node is not | ||
60 | interesting to the given scan handler and may be matched against the next scan | ||
61 | handler in the list. If it returns a (negative) error code, that means that | ||
62 | the namespace scan should be terminated due to a serious error. The error code | ||
63 | returned should then reflect the type of the error. | ||
64 | |||
65 | The namespace trimming function, acpi_bus_trim(), first executes .detach() | ||
66 | callbacks from the scan handlers of all device nodes in the given namespace | ||
67 | scope (if they have scan handlers). Next, it unregisters all of the device | ||
68 | nodes in that scope. | ||
69 | |||
70 | ACPI scan handlers can be added to the list maintained by the ACPI core with the | ||
71 | help of the acpi_scan_add_handler() function taking a pointer to the new scan | ||
72 | handler as an argument. The order in which scan handlers are added to the list | ||
73 | is the order in which they are matched against device nodes during namespace | ||
74 | scans. | ||
75 | |||
76 | All scan handles must be added to the list before acpi_bus_scan() is run for the | ||
77 | first time and they cannot be removed from it. | ||
diff --git a/arch/ia64/hp/common/aml_nfw.c b/arch/ia64/hp/common/aml_nfw.c index 6192f7188654..916ffe770bcf 100644 --- a/arch/ia64/hp/common/aml_nfw.c +++ b/arch/ia64/hp/common/aml_nfw.c | |||
@@ -191,7 +191,7 @@ static int aml_nfw_add(struct acpi_device *device) | |||
191 | return aml_nfw_add_global_handler(); | 191 | return aml_nfw_add_global_handler(); |
192 | } | 192 | } |
193 | 193 | ||
194 | static int aml_nfw_remove(struct acpi_device *device, int type) | 194 | static int aml_nfw_remove(struct acpi_device *device) |
195 | { | 195 | { |
196 | return aml_nfw_remove_global_handler(); | 196 | return aml_nfw_remove_global_handler(); |
197 | } | 197 | } |
diff --git a/arch/x86/platform/olpc/olpc-xo15-sci.c b/arch/x86/platform/olpc/olpc-xo15-sci.c index 2fdca25905ae..fef7d0ba7e3a 100644 --- a/arch/x86/platform/olpc/olpc-xo15-sci.c +++ b/arch/x86/platform/olpc/olpc-xo15-sci.c | |||
@@ -195,7 +195,7 @@ err_sysfs: | |||
195 | return r; | 195 | return r; |
196 | } | 196 | } |
197 | 197 | ||
198 | static int xo15_sci_remove(struct acpi_device *device, int type) | 198 | static int xo15_sci_remove(struct acpi_device *device) |
199 | { | 199 | { |
200 | acpi_disable_gpe(NULL, xo15_sci_gpe); | 200 | acpi_disable_gpe(NULL, xo15_sci_gpe); |
201 | acpi_remove_gpe_handler(NULL, xo15_sci_gpe, xo15_sci_gpe_handler); | 201 | acpi_remove_gpe_handler(NULL, xo15_sci_gpe, xo15_sci_gpe_handler); |
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index 38c5078da11d..78105b3a5262 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig | |||
@@ -337,7 +337,7 @@ config X86_PM_TIMER | |||
337 | systems require this timer. | 337 | systems require this timer. |
338 | 338 | ||
339 | config ACPI_CONTAINER | 339 | config ACPI_CONTAINER |
340 | tristate "Container and Module Devices (EXPERIMENTAL)" | 340 | bool "Container and Module Devices (EXPERIMENTAL)" |
341 | depends on EXPERIMENTAL | 341 | depends on EXPERIMENTAL |
342 | default (ACPI_HOTPLUG_MEMORY || ACPI_HOTPLUG_CPU || ACPI_HOTPLUG_IO) | 342 | default (ACPI_HOTPLUG_MEMORY || ACPI_HOTPLUG_CPU || ACPI_HOTPLUG_IO) |
343 | help | 343 | help |
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c index d5fdd36190cc..6d5bf649196d 100644 --- a/drivers/acpi/ac.c +++ b/drivers/acpi/ac.c | |||
@@ -60,7 +60,7 @@ static int acpi_ac_open_fs(struct inode *inode, struct file *file); | |||
60 | #endif | 60 | #endif |
61 | 61 | ||
62 | static int acpi_ac_add(struct acpi_device *device); | 62 | static int acpi_ac_add(struct acpi_device *device); |
63 | static int acpi_ac_remove(struct acpi_device *device, int type); | 63 | static int acpi_ac_remove(struct acpi_device *device); |
64 | static void acpi_ac_notify(struct acpi_device *device, u32 event); | 64 | static void acpi_ac_notify(struct acpi_device *device, u32 event); |
65 | 65 | ||
66 | static const struct acpi_device_id ac_device_ids[] = { | 66 | static const struct acpi_device_id ac_device_ids[] = { |
@@ -337,7 +337,7 @@ static int acpi_ac_resume(struct device *dev) | |||
337 | } | 337 | } |
338 | #endif | 338 | #endif |
339 | 339 | ||
340 | static int acpi_ac_remove(struct acpi_device *device, int type) | 340 | static int acpi_ac_remove(struct acpi_device *device) |
341 | { | 341 | { |
342 | struct acpi_ac *ac = NULL; | 342 | struct acpi_ac *ac = NULL; |
343 | 343 | ||
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index 03d18f290118..034d3e72aa92 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c | |||
@@ -54,7 +54,7 @@ MODULE_LICENSE("GPL"); | |||
54 | #define MEMORY_POWER_OFF_STATE 2 | 54 | #define MEMORY_POWER_OFF_STATE 2 |
55 | 55 | ||
56 | static int acpi_memory_device_add(struct acpi_device *device); | 56 | static int acpi_memory_device_add(struct acpi_device *device); |
57 | static int acpi_memory_device_remove(struct acpi_device *device, int type); | 57 | static int acpi_memory_device_remove(struct acpi_device *device); |
58 | 58 | ||
59 | static const struct acpi_device_id memory_device_ids[] = { | 59 | static const struct acpi_device_id memory_device_ids[] = { |
60 | {ACPI_MEMORY_DEVICE_HID, 0}, | 60 | {ACPI_MEMORY_DEVICE_HID, 0}, |
@@ -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 | ||
156 | static int | 156 | static int acpi_memory_get_device(acpi_handle handle, |
157 | acpi_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 | ||
191 | static int acpi_memory_check_device(struct acpi_memory_device *mem_device) | 198 | static 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 | ||
366 | static void acpi_memory_device_free(struct acpi_memory_device *mem_device) | 384 | static void acpi_memory_device_free(struct acpi_memory_device *mem_device) |
@@ -415,7 +433,7 @@ static int acpi_memory_device_add(struct acpi_device *device) | |||
415 | return result; | 433 | return result; |
416 | } | 434 | } |
417 | 435 | ||
418 | static int acpi_memory_device_remove(struct acpi_device *device, int type) | 436 | static int acpi_memory_device_remove(struct acpi_device *device) |
419 | { | 437 | { |
420 | struct acpi_memory_device *mem_device = NULL; | 438 | struct acpi_memory_device *mem_device = NULL; |
421 | int result; | 439 | int result; |
diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index 16fa979f7180..31de1043eea0 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c | |||
@@ -482,8 +482,7 @@ static int acpi_pad_add(struct acpi_device *device) | |||
482 | return 0; | 482 | return 0; |
483 | } | 483 | } |
484 | 484 | ||
485 | static int acpi_pad_remove(struct acpi_device *device, | 485 | static int acpi_pad_remove(struct acpi_device *device) |
486 | int type) | ||
487 | { | 486 | { |
488 | mutex_lock(&isolated_cpus_lock); | 487 | mutex_lock(&isolated_cpus_lock); |
489 | acpi_pad_idle_cpus(0); | 488 | acpi_pad_idle_cpus(0); |
diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index 2d1fb4c21605..26fce4b8a632 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c | |||
@@ -22,6 +22,30 @@ | |||
22 | 22 | ||
23 | ACPI_MODULE_NAME("platform"); | 23 | ACPI_MODULE_NAME("platform"); |
24 | 24 | ||
25 | /* Flags for acpi_create_platform_device */ | ||
26 | #define ACPI_PLATFORM_CLK BIT(0) | ||
27 | |||
28 | /* | ||
29 | * The following ACPI IDs are known to be suitable for representing as | ||
30 | * platform devices. | ||
31 | */ | ||
32 | static const struct acpi_device_id acpi_platform_device_ids[] = { | ||
33 | |||
34 | { "PNP0D40" }, | ||
35 | |||
36 | /* Haswell LPSS devices */ | ||
37 | { "INT33C0", ACPI_PLATFORM_CLK }, | ||
38 | { "INT33C1", ACPI_PLATFORM_CLK }, | ||
39 | { "INT33C2", ACPI_PLATFORM_CLK }, | ||
40 | { "INT33C3", ACPI_PLATFORM_CLK }, | ||
41 | { "INT33C4", ACPI_PLATFORM_CLK }, | ||
42 | { "INT33C5", ACPI_PLATFORM_CLK }, | ||
43 | { "INT33C6", ACPI_PLATFORM_CLK }, | ||
44 | { "INT33C7", ACPI_PLATFORM_CLK }, | ||
45 | |||
46 | { } | ||
47 | }; | ||
48 | |||
25 | static int acpi_create_platform_clks(struct acpi_device *adev) | 49 | static int acpi_create_platform_clks(struct acpi_device *adev) |
26 | { | 50 | { |
27 | static struct platform_device *pdev; | 51 | static struct platform_device *pdev; |
@@ -39,8 +63,7 @@ static int acpi_create_platform_clks(struct acpi_device *adev) | |||
39 | /** | 63 | /** |
40 | * acpi_create_platform_device - Create platform device for ACPI device node | 64 | * acpi_create_platform_device - Create platform device for ACPI device node |
41 | * @adev: ACPI device node to create a platform device for. | 65 | * @adev: ACPI device node to create a platform device for. |
42 | * @flags: ACPI_PLATFORM_* flags that affect the creation of the platform | 66 | * @id: ACPI device ID used to match @adev. |
43 | * devices. | ||
44 | * | 67 | * |
45 | * Check if the given @adev can be represented as a platform device and, if | 68 | * Check if the given @adev can be represented as a platform device and, if |
46 | * that's the case, create and register a platform device, populate its common | 69 | * that's the case, create and register a platform device, populate its common |
@@ -48,9 +71,10 @@ static int acpi_create_platform_clks(struct acpi_device *adev) | |||
48 | * | 71 | * |
49 | * Name of the platform device will be the same as @adev's. | 72 | * Name of the platform device will be the same as @adev's. |
50 | */ | 73 | */ |
51 | struct platform_device *acpi_create_platform_device(struct acpi_device *adev, | 74 | static int acpi_create_platform_device(struct acpi_device *adev, |
52 | unsigned long flags) | 75 | const struct acpi_device_id *id) |
53 | { | 76 | { |
77 | unsigned long flags = id->driver_data; | ||
54 | struct platform_device *pdev = NULL; | 78 | struct platform_device *pdev = NULL; |
55 | struct acpi_device *acpi_parent; | 79 | struct acpi_device *acpi_parent; |
56 | struct platform_device_info pdevinfo; | 80 | struct platform_device_info pdevinfo; |
@@ -59,25 +83,28 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev, | |||
59 | struct resource *resources; | 83 | struct resource *resources; |
60 | int count; | 84 | int count; |
61 | 85 | ||
62 | if ((flags & ACPI_PLATFORM_CLK) && acpi_create_platform_clks(adev)) { | 86 | if (flags & ACPI_PLATFORM_CLK) { |
63 | dev_err(&adev->dev, "failed to create clocks\n"); | 87 | int ret = acpi_create_platform_clks(adev); |
64 | return NULL; | 88 | if (ret) { |
89 | dev_err(&adev->dev, "failed to create clocks\n"); | ||
90 | return ret; | ||
91 | } | ||
65 | } | 92 | } |
66 | 93 | ||
67 | /* If the ACPI node already has a physical device attached, skip it. */ | 94 | /* If the ACPI node already has a physical device attached, skip it. */ |
68 | if (adev->physical_node_count) | 95 | if (adev->physical_node_count) |
69 | return NULL; | 96 | return 0; |
70 | 97 | ||
71 | INIT_LIST_HEAD(&resource_list); | 98 | INIT_LIST_HEAD(&resource_list); |
72 | count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL); | 99 | count = acpi_dev_get_resources(adev, &resource_list, NULL, NULL); |
73 | if (count <= 0) | 100 | if (count <= 0) |
74 | return NULL; | 101 | return 0; |
75 | 102 | ||
76 | resources = kmalloc(count * sizeof(struct resource), GFP_KERNEL); | 103 | resources = kmalloc(count * sizeof(struct resource), GFP_KERNEL); |
77 | if (!resources) { | 104 | if (!resources) { |
78 | dev_err(&adev->dev, "No memory for resources\n"); | 105 | dev_err(&adev->dev, "No memory for resources\n"); |
79 | acpi_dev_free_resource_list(&resource_list); | 106 | acpi_dev_free_resource_list(&resource_list); |
80 | return NULL; | 107 | return -ENOMEM; |
81 | } | 108 | } |
82 | count = 0; | 109 | count = 0; |
83 | list_for_each_entry(rentry, &resource_list, node) | 110 | list_for_each_entry(rentry, &resource_list, node) |
@@ -123,5 +150,15 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev, | |||
123 | } | 150 | } |
124 | 151 | ||
125 | kfree(resources); | 152 | kfree(resources); |
126 | return pdev; | 153 | return 1; |
154 | } | ||
155 | |||
156 | static struct acpi_scan_handler platform_handler = { | ||
157 | .ids = acpi_platform_device_ids, | ||
158 | .attach = acpi_create_platform_device, | ||
159 | }; | ||
160 | |||
161 | void __init acpi_platform_init(void) | ||
162 | { | ||
163 | acpi_scan_add_handler(&platform_handler); | ||
127 | } | 164 | } |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 7efaeaa53b88..c5cd5b5513e6 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -1111,7 +1111,7 @@ fail: | |||
1111 | return result; | 1111 | return result; |
1112 | } | 1112 | } |
1113 | 1113 | ||
1114 | static int acpi_battery_remove(struct acpi_device *device, int type) | 1114 | static int acpi_battery_remove(struct acpi_device *device) |
1115 | { | 1115 | { |
1116 | struct acpi_battery *battery = NULL; | 1116 | struct acpi_battery *battery = NULL; |
1117 | 1117 | ||
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index f0d936b65e37..86c7d5445c38 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c | |||
@@ -75,7 +75,7 @@ static const struct acpi_device_id button_device_ids[] = { | |||
75 | MODULE_DEVICE_TABLE(acpi, button_device_ids); | 75 | MODULE_DEVICE_TABLE(acpi, button_device_ids); |
76 | 76 | ||
77 | static int acpi_button_add(struct acpi_device *device); | 77 | static int acpi_button_add(struct acpi_device *device); |
78 | static int acpi_button_remove(struct acpi_device *device, int type); | 78 | static int acpi_button_remove(struct acpi_device *device); |
79 | static void acpi_button_notify(struct acpi_device *device, u32 event); | 79 | static void acpi_button_notify(struct acpi_device *device, u32 event); |
80 | 80 | ||
81 | #ifdef CONFIG_PM_SLEEP | 81 | #ifdef CONFIG_PM_SLEEP |
@@ -433,7 +433,7 @@ static int acpi_button_add(struct acpi_device *device) | |||
433 | return error; | 433 | return error; |
434 | } | 434 | } |
435 | 435 | ||
436 | static int acpi_button_remove(struct acpi_device *device, int type) | 436 | static int acpi_button_remove(struct acpi_device *device) |
437 | { | 437 | { |
438 | struct acpi_button *button = acpi_driver_data(device); | 438 | struct acpi_button *button = acpi_driver_data(device); |
439 | 439 | ||
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index cc79d3e53a39..5523ba7d764d 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c | |||
@@ -34,46 +34,34 @@ | |||
34 | #include <linux/acpi.h> | 34 | #include <linux/acpi.h> |
35 | #include <acpi/acpi_bus.h> | 35 | #include <acpi/acpi_bus.h> |
36 | #include <acpi/acpi_drivers.h> | 36 | #include <acpi/acpi_drivers.h> |
37 | #include <acpi/container.h> | ||
38 | 37 | ||
39 | #define PREFIX "ACPI: " | 38 | #define PREFIX "ACPI: " |
40 | 39 | ||
41 | #define ACPI_CONTAINER_DEVICE_NAME "ACPI container device" | ||
42 | #define ACPI_CONTAINER_CLASS "container" | ||
43 | |||
44 | #define INSTALL_NOTIFY_HANDLER 1 | ||
45 | #define UNINSTALL_NOTIFY_HANDLER 2 | ||
46 | |||
47 | #define _COMPONENT ACPI_CONTAINER_COMPONENT | 40 | #define _COMPONENT ACPI_CONTAINER_COMPONENT |
48 | ACPI_MODULE_NAME("container"); | 41 | ACPI_MODULE_NAME("container"); |
49 | 42 | ||
50 | MODULE_AUTHOR("Anil S Keshavamurthy"); | ||
51 | MODULE_DESCRIPTION("ACPI container driver"); | ||
52 | MODULE_LICENSE("GPL"); | ||
53 | |||
54 | static int acpi_container_add(struct acpi_device *device); | ||
55 | static int acpi_container_remove(struct acpi_device *device, int type); | ||
56 | |||
57 | static const struct acpi_device_id container_device_ids[] = { | 43 | static const struct acpi_device_id container_device_ids[] = { |
58 | {"ACPI0004", 0}, | 44 | {"ACPI0004", 0}, |
59 | {"PNP0A05", 0}, | 45 | {"PNP0A05", 0}, |
60 | {"PNP0A06", 0}, | 46 | {"PNP0A06", 0}, |
61 | {"", 0}, | 47 | {"", 0}, |
62 | }; | 48 | }; |
63 | MODULE_DEVICE_TABLE(acpi, container_device_ids); | ||
64 | 49 | ||
65 | static struct acpi_driver acpi_container_driver = { | 50 | static int container_device_attach(struct acpi_device *device, |
66 | .name = "container", | 51 | const struct acpi_device_id *not_used) |
67 | .class = ACPI_CONTAINER_CLASS, | 52 | { |
53 | /* | ||
54 | * FIXME: This is necessary, so that acpi_eject_store() doesn't return | ||
55 | * -ENODEV for containers. | ||
56 | */ | ||
57 | return 1; | ||
58 | } | ||
59 | |||
60 | static struct acpi_scan_handler container_device_handler = { | ||
68 | .ids = container_device_ids, | 61 | .ids = container_device_ids, |
69 | .ops = { | 62 | .attach = container_device_attach, |
70 | .add = acpi_container_add, | ||
71 | .remove = acpi_container_remove, | ||
72 | }, | ||
73 | }; | 63 | }; |
74 | 64 | ||
75 | /*******************************************************************/ | ||
76 | |||
77 | static int is_device_present(acpi_handle handle) | 65 | static int is_device_present(acpi_handle handle) |
78 | { | 66 | { |
79 | acpi_handle temp; | 67 | acpi_handle temp; |
@@ -92,49 +80,6 @@ static int is_device_present(acpi_handle handle) | |||
92 | return ((sta & ACPI_STA_DEVICE_PRESENT) == ACPI_STA_DEVICE_PRESENT); | 80 | return ((sta & ACPI_STA_DEVICE_PRESENT) == ACPI_STA_DEVICE_PRESENT); |
93 | } | 81 | } |
94 | 82 | ||
95 | static bool is_container_device(const char *hid) | ||
96 | { | ||
97 | const struct acpi_device_id *container_id; | ||
98 | |||
99 | for (container_id = container_device_ids; | ||
100 | container_id->id[0]; container_id++) { | ||
101 | if (!strcmp((char *)container_id->id, hid)) | ||
102 | return true; | ||
103 | } | ||
104 | |||
105 | return false; | ||
106 | } | ||
107 | |||
108 | /*******************************************************************/ | ||
109 | static int acpi_container_add(struct acpi_device *device) | ||
110 | { | ||
111 | struct acpi_container *container; | ||
112 | |||
113 | container = kzalloc(sizeof(struct acpi_container), GFP_KERNEL); | ||
114 | if (!container) | ||
115 | return -ENOMEM; | ||
116 | |||
117 | container->handle = device->handle; | ||
118 | strcpy(acpi_device_name(device), ACPI_CONTAINER_DEVICE_NAME); | ||
119 | strcpy(acpi_device_class(device), ACPI_CONTAINER_CLASS); | ||
120 | device->driver_data = container; | ||
121 | |||
122 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device <%s> bid <%s>\n", | ||
123 | acpi_device_name(device), acpi_device_bid(device))); | ||
124 | |||
125 | return 0; | ||
126 | } | ||
127 | |||
128 | static int acpi_container_remove(struct acpi_device *device, int type) | ||
129 | { | ||
130 | acpi_status status = AE_OK; | ||
131 | struct acpi_container *pc = NULL; | ||
132 | |||
133 | pc = acpi_driver_data(device); | ||
134 | kfree(pc); | ||
135 | return status; | ||
136 | } | ||
137 | |||
138 | static void container_notify_cb(acpi_handle handle, u32 type, void *context) | 83 | static void container_notify_cb(acpi_handle handle, u32 type, void *context) |
139 | { | 84 | { |
140 | struct acpi_device *device = NULL; | 85 | struct acpi_device *device = NULL; |
@@ -143,6 +88,8 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context) | |||
143 | acpi_status status; | 88 | acpi_status status; |
144 | u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */ | 89 | u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */ |
145 | 90 | ||
91 | acpi_scan_lock_acquire(); | ||
92 | |||
146 | switch (type) { | 93 | switch (type) { |
147 | case ACPI_NOTIFY_BUS_CHECK: | 94 | case ACPI_NOTIFY_BUS_CHECK: |
148 | /* Fall through */ | 95 | /* Fall through */ |
@@ -158,7 +105,7 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context) | |||
158 | /* device exist and this is a remove request */ | 105 | /* device exist and this is a remove request */ |
159 | device->flags.eject_pending = 1; | 106 | device->flags.eject_pending = 1; |
160 | kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); | 107 | kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); |
161 | return; | 108 | goto out; |
162 | } | 109 | } |
163 | break; | 110 | break; |
164 | } | 111 | } |
@@ -185,98 +132,59 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context) | |||
185 | if (!acpi_bus_get_device(handle, &device) && device) { | 132 | if (!acpi_bus_get_device(handle, &device) && device) { |
186 | device->flags.eject_pending = 1; | 133 | device->flags.eject_pending = 1; |
187 | kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); | 134 | kobject_uevent(&device->dev.kobj, KOBJ_OFFLINE); |
188 | return; | 135 | goto out; |
189 | } | 136 | } |
190 | break; | 137 | break; |
191 | 138 | ||
192 | default: | 139 | default: |
193 | /* non-hotplug event; possibly handled by other handler */ | 140 | /* non-hotplug event; possibly handled by other handler */ |
194 | return; | 141 | goto out; |
195 | } | 142 | } |
196 | 143 | ||
197 | /* Inform firmware that the hotplug operation has completed */ | 144 | /* Inform firmware that the hotplug operation has completed */ |
198 | (void) acpi_evaluate_hotplug_ost(handle, type, ost_code, NULL); | 145 | (void) acpi_evaluate_hotplug_ost(handle, type, ost_code, NULL); |
199 | return; | 146 | |
147 | out: | ||
148 | acpi_scan_lock_release(); | ||
200 | } | 149 | } |
201 | 150 | ||
202 | static acpi_status | 151 | static bool is_container(acpi_handle handle) |
203 | container_walk_namespace_cb(acpi_handle handle, | ||
204 | u32 lvl, void *context, void **rv) | ||
205 | { | 152 | { |
206 | char *hid = NULL; | ||
207 | struct acpi_device_info *info; | 153 | struct acpi_device_info *info; |
208 | acpi_status status; | 154 | bool ret = false; |
209 | int *action = context; | ||
210 | 155 | ||
211 | status = acpi_get_object_info(handle, &info); | 156 | if (ACPI_FAILURE(acpi_get_object_info(handle, &info))) |
212 | if (ACPI_FAILURE(status)) { | 157 | return false; |
213 | return AE_OK; | ||
214 | } | ||
215 | |||
216 | if (info->valid & ACPI_VALID_HID) | ||
217 | hid = info->hardware_id.string; | ||
218 | |||
219 | if (hid == NULL) { | ||
220 | goto end; | ||
221 | } | ||
222 | 158 | ||
223 | if (!is_container_device(hid)) | 159 | if (info->valid & ACPI_VALID_HID) { |
224 | goto end; | 160 | const struct acpi_device_id *id; |
225 | 161 | ||
226 | switch (*action) { | 162 | for (id = container_device_ids; id->id[0]; id++) { |
227 | case INSTALL_NOTIFY_HANDLER: | 163 | ret = !strcmp((char *)id->id, info->hardware_id.string); |
228 | acpi_install_notify_handler(handle, | 164 | if (ret) |
229 | ACPI_SYSTEM_NOTIFY, | 165 | break; |
230 | container_notify_cb, NULL); | 166 | } |
231 | break; | ||
232 | case UNINSTALL_NOTIFY_HANDLER: | ||
233 | acpi_remove_notify_handler(handle, | ||
234 | ACPI_SYSTEM_NOTIFY, | ||
235 | container_notify_cb); | ||
236 | break; | ||
237 | default: | ||
238 | break; | ||
239 | } | 167 | } |
240 | |||
241 | end: | ||
242 | kfree(info); | 168 | kfree(info); |
243 | 169 | return ret; | |
244 | return AE_OK; | ||
245 | } | 170 | } |
246 | 171 | ||
247 | static int __init acpi_container_init(void) | 172 | static acpi_status acpi_container_register_notify_handler(acpi_handle handle, |
173 | u32 lvl, void *ctxt, | ||
174 | void **retv) | ||
248 | { | 175 | { |
249 | int result = 0; | 176 | if (is_container(handle)) |
250 | int action = INSTALL_NOTIFY_HANDLER; | 177 | acpi_install_notify_handler(handle, ACPI_SYSTEM_NOTIFY, |
251 | 178 | container_notify_cb, NULL); | |
252 | result = acpi_bus_register_driver(&acpi_container_driver); | ||
253 | if (result < 0) { | ||
254 | return (result); | ||
255 | } | ||
256 | |||
257 | /* register notify handler to every container device */ | ||
258 | acpi_walk_namespace(ACPI_TYPE_DEVICE, | ||
259 | ACPI_ROOT_OBJECT, | ||
260 | ACPI_UINT32_MAX, | ||
261 | container_walk_namespace_cb, NULL, &action, NULL); | ||
262 | 179 | ||
263 | return (0); | 180 | return AE_OK; |
264 | } | 181 | } |
265 | 182 | ||
266 | static void __exit acpi_container_exit(void) | 183 | void __init acpi_container_init(void) |
267 | { | 184 | { |
268 | int action = UNINSTALL_NOTIFY_HANDLER; | 185 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, ACPI_UINT32_MAX, |
269 | 186 | acpi_container_register_notify_handler, NULL, | |
187 | NULL, NULL); | ||
270 | 188 | ||
271 | acpi_walk_namespace(ACPI_TYPE_DEVICE, | 189 | acpi_scan_add_handler(&container_device_handler); |
272 | ACPI_ROOT_OBJECT, | ||
273 | ACPI_UINT32_MAX, | ||
274 | container_walk_namespace_cb, NULL, &action, NULL); | ||
275 | |||
276 | acpi_bus_unregister_driver(&acpi_container_driver); | ||
277 | |||
278 | return; | ||
279 | } | 190 | } |
280 | |||
281 | module_init(acpi_container_init); | ||
282 | module_exit(acpi_container_exit); | ||
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 78648f811049..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 | ||
@@ -825,7 +838,7 @@ static ssize_t show_docked(struct device *dev, | |||
825 | 838 | ||
826 | struct dock_station *dock_station = dev->platform_data; | 839 | struct dock_station *dock_station = dev->platform_data; |
827 | 840 | ||
828 | if (ACPI_SUCCESS(acpi_bus_get_device(dock_station->handle, &tmp))) | 841 | if (!acpi_bus_get_device(dock_station->handle, &tmp)) |
829 | return snprintf(buf, PAGE_SIZE, "1\n"); | 842 | return snprintf(buf, PAGE_SIZE, "1\n"); |
830 | return snprintf(buf, PAGE_SIZE, "0\n"); | 843 | return snprintf(buf, PAGE_SIZE, "0\n"); |
831 | } | 844 | } |
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index 354007d490d1..d45b2871d33b 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -852,7 +852,7 @@ static int acpi_ec_add(struct acpi_device *device) | |||
852 | return ret; | 852 | return ret; |
853 | } | 853 | } |
854 | 854 | ||
855 | static int acpi_ec_remove(struct acpi_device *device, int type) | 855 | static int acpi_ec_remove(struct acpi_device *device) |
856 | { | 856 | { |
857 | struct acpi_ec *ec; | 857 | struct acpi_ec *ec; |
858 | struct acpi_ec_query_handler *handler, *tmp; | 858 | struct acpi_ec_query_handler *handler, *tmp; |
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c index 3bd6a54702d6..f815da82c765 100644 --- a/drivers/acpi/fan.c +++ b/drivers/acpi/fan.c | |||
@@ -45,7 +45,7 @@ MODULE_DESCRIPTION("ACPI Fan Driver"); | |||
45 | MODULE_LICENSE("GPL"); | 45 | MODULE_LICENSE("GPL"); |
46 | 46 | ||
47 | static int acpi_fan_add(struct acpi_device *device); | 47 | static int acpi_fan_add(struct acpi_device *device); |
48 | static int acpi_fan_remove(struct acpi_device *device, int type); | 48 | static int acpi_fan_remove(struct acpi_device *device); |
49 | 49 | ||
50 | static const struct acpi_device_id fan_device_ids[] = { | 50 | static const struct acpi_device_id fan_device_ids[] = { |
51 | {"PNP0C0B", 0}, | 51 | {"PNP0C0B", 0}, |
@@ -172,7 +172,7 @@ static int acpi_fan_add(struct acpi_device *device) | |||
172 | return result; | 172 | return result; |
173 | } | 173 | } |
174 | 174 | ||
175 | static int acpi_fan_remove(struct acpi_device *device, int type) | 175 | static int acpi_fan_remove(struct acpi_device *device) |
176 | { | 176 | { |
177 | struct thermal_cooling_device *cdev = acpi_driver_data(device); | 177 | struct thermal_cooling_device *cdev = acpi_driver_data(device); |
178 | 178 | ||
diff --git a/drivers/acpi/hed.c b/drivers/acpi/hed.c index a0cc796932f7..13b1d39d7cdf 100644 --- a/drivers/acpi/hed.c +++ b/drivers/acpi/hed.c | |||
@@ -70,7 +70,7 @@ static int acpi_hed_add(struct acpi_device *device) | |||
70 | return 0; | 70 | return 0; |
71 | } | 71 | } |
72 | 72 | ||
73 | static int acpi_hed_remove(struct acpi_device *device, int type) | 73 | static int acpi_hed_remove(struct acpi_device *device) |
74 | { | 74 | { |
75 | hed_handle = NULL; | 75 | hed_handle = NULL; |
76 | return 0; | 76 | return 0; |
diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index da233477d260..79092328cf06 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h | |||
@@ -25,8 +25,16 @@ | |||
25 | 25 | ||
26 | int init_acpi_device_notify(void); | 26 | int init_acpi_device_notify(void); |
27 | int acpi_scan_init(void); | 27 | int acpi_scan_init(void); |
28 | void acpi_pci_root_init(void); | ||
29 | void acpi_pci_link_init(void); | ||
30 | void acpi_platform_init(void); | ||
28 | int acpi_sysfs_init(void); | 31 | int acpi_sysfs_init(void); |
29 | void acpi_csrt_init(void); | 32 | void acpi_csrt_init(void); |
33 | #ifdef CONFIG_ACPI_CONTAINER | ||
34 | void acpi_container_init(void); | ||
35 | #else | ||
36 | static inline void acpi_container_init(void) {} | ||
37 | #endif | ||
30 | 38 | ||
31 | #ifdef CONFIG_DEBUG_FS | 39 | #ifdef CONFIG_DEBUG_FS |
32 | extern struct dentry *acpi_debugfs_dir; | 40 | extern struct dentry *acpi_debugfs_dir; |
@@ -86,7 +94,6 @@ struct acpi_ec { | |||
86 | 94 | ||
87 | extern struct acpi_ec *first_ec; | 95 | extern struct acpi_ec *first_ec; |
88 | 96 | ||
89 | int acpi_pci_root_init(void); | ||
90 | int acpi_ec_init(void); | 97 | int acpi_ec_init(void); |
91 | int acpi_ec_ecdt_probe(void); | 98 | int acpi_ec_ecdt_probe(void); |
92 | int acpi_boot_ec_enable(void); | 99 | int acpi_boot_ec_enable(void); |
@@ -118,10 +125,4 @@ static inline void suspend_nvs_restore(void) {} | |||
118 | -------------------------------------------------------------------------- */ | 125 | -------------------------------------------------------------------------- */ |
119 | struct platform_device; | 126 | struct platform_device; |
120 | 127 | ||
121 | /* Flags for acpi_create_platform_device */ | ||
122 | #define ACPI_PLATFORM_CLK BIT(0) | ||
123 | |||
124 | struct platform_device *acpi_create_platform_device(struct acpi_device *adev, | ||
125 | unsigned long flags); | ||
126 | |||
127 | #endif /* _ACPI_INTERNAL_H_ */ | 128 | #endif /* _ACPI_INTERNAL_H_ */ |
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c index a12808259dfb..ab764ed34a50 100644 --- a/drivers/acpi/pci_link.c +++ b/drivers/acpi/pci_link.c | |||
@@ -53,23 +53,19 @@ ACPI_MODULE_NAME("pci_link"); | |||
53 | #define ACPI_PCI_LINK_FILE_STATUS "state" | 53 | #define ACPI_PCI_LINK_FILE_STATUS "state" |
54 | #define ACPI_PCI_LINK_MAX_POSSIBLE 16 | 54 | #define ACPI_PCI_LINK_MAX_POSSIBLE 16 |
55 | 55 | ||
56 | static int acpi_pci_link_add(struct acpi_device *device); | 56 | static int acpi_pci_link_add(struct acpi_device *device, |
57 | static int acpi_pci_link_remove(struct acpi_device *device, int type); | 57 | const struct acpi_device_id *not_used); |
58 | static void acpi_pci_link_remove(struct acpi_device *device); | ||
58 | 59 | ||
59 | static const struct acpi_device_id link_device_ids[] = { | 60 | static const struct acpi_device_id link_device_ids[] = { |
60 | {"PNP0C0F", 0}, | 61 | {"PNP0C0F", 0}, |
61 | {"", 0}, | 62 | {"", 0}, |
62 | }; | 63 | }; |
63 | MODULE_DEVICE_TABLE(acpi, link_device_ids); | ||
64 | 64 | ||
65 | static struct acpi_driver acpi_pci_link_driver = { | 65 | static struct acpi_scan_handler pci_link_handler = { |
66 | .name = "pci_link", | ||
67 | .class = ACPI_PCI_LINK_CLASS, | ||
68 | .ids = link_device_ids, | 66 | .ids = link_device_ids, |
69 | .ops = { | 67 | .attach = acpi_pci_link_add, |
70 | .add = acpi_pci_link_add, | 68 | .detach = acpi_pci_link_remove, |
71 | .remove = acpi_pci_link_remove, | ||
72 | }, | ||
73 | }; | 69 | }; |
74 | 70 | ||
75 | /* | 71 | /* |
@@ -692,7 +688,8 @@ int acpi_pci_link_free_irq(acpi_handle handle) | |||
692 | Driver Interface | 688 | Driver Interface |
693 | -------------------------------------------------------------------------- */ | 689 | -------------------------------------------------------------------------- */ |
694 | 690 | ||
695 | static int acpi_pci_link_add(struct acpi_device *device) | 691 | static int acpi_pci_link_add(struct acpi_device *device, |
692 | const struct acpi_device_id *not_used) | ||
696 | { | 693 | { |
697 | int result; | 694 | int result; |
698 | struct acpi_pci_link *link; | 695 | struct acpi_pci_link *link; |
@@ -746,7 +743,7 @@ static int acpi_pci_link_add(struct acpi_device *device) | |||
746 | if (result) | 743 | if (result) |
747 | kfree(link); | 744 | kfree(link); |
748 | 745 | ||
749 | return result; | 746 | return result < 0 ? result : 1; |
750 | } | 747 | } |
751 | 748 | ||
752 | static int acpi_pci_link_resume(struct acpi_pci_link *link) | 749 | static int acpi_pci_link_resume(struct acpi_pci_link *link) |
@@ -766,7 +763,7 @@ static void irqrouter_resume(void) | |||
766 | } | 763 | } |
767 | } | 764 | } |
768 | 765 | ||
769 | static int acpi_pci_link_remove(struct acpi_device *device, int type) | 766 | static void acpi_pci_link_remove(struct acpi_device *device) |
770 | { | 767 | { |
771 | struct acpi_pci_link *link; | 768 | struct acpi_pci_link *link; |
772 | 769 | ||
@@ -777,7 +774,6 @@ static int acpi_pci_link_remove(struct acpi_device *device, int type) | |||
777 | mutex_unlock(&acpi_link_lock); | 774 | mutex_unlock(&acpi_link_lock); |
778 | 775 | ||
779 | kfree(link); | 776 | kfree(link); |
780 | return 0; | ||
781 | } | 777 | } |
782 | 778 | ||
783 | /* | 779 | /* |
@@ -874,20 +870,10 @@ static struct syscore_ops irqrouter_syscore_ops = { | |||
874 | .resume = irqrouter_resume, | 870 | .resume = irqrouter_resume, |
875 | }; | 871 | }; |
876 | 872 | ||
877 | static int __init irqrouter_init_ops(void) | 873 | void __init acpi_pci_link_init(void) |
878 | { | ||
879 | if (!acpi_disabled && !acpi_noirq) | ||
880 | register_syscore_ops(&irqrouter_syscore_ops); | ||
881 | |||
882 | return 0; | ||
883 | } | ||
884 | |||
885 | device_initcall(irqrouter_init_ops); | ||
886 | |||
887 | static int __init acpi_pci_link_init(void) | ||
888 | { | 874 | { |
889 | if (acpi_noirq) | 875 | if (acpi_noirq) |
890 | return 0; | 876 | return; |
891 | 877 | ||
892 | if (acpi_irq_balance == -1) { | 878 | if (acpi_irq_balance == -1) { |
893 | /* no command line switch: enable balancing in IOAPIC mode */ | 879 | /* no command line switch: enable balancing in IOAPIC mode */ |
@@ -896,11 +882,6 @@ static int __init acpi_pci_link_init(void) | |||
896 | else | 882 | else |
897 | acpi_irq_balance = 0; | 883 | acpi_irq_balance = 0; |
898 | } | 884 | } |
899 | 885 | register_syscore_ops(&irqrouter_syscore_ops); | |
900 | if (acpi_bus_register_driver(&acpi_pci_link_driver) < 0) | 886 | acpi_scan_add_handler(&pci_link_handler); |
901 | return -ENODEV; | ||
902 | |||
903 | return 0; | ||
904 | } | 887 | } |
905 | |||
906 | subsys_initcall(acpi_pci_link_init); | ||
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index 22a8458b4ec9..b3cc69c5caf1 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c | |||
@@ -45,8 +45,9 @@ | |||
45 | ACPI_MODULE_NAME("pci_root"); | 45 | ACPI_MODULE_NAME("pci_root"); |
46 | #define ACPI_PCI_ROOT_CLASS "pci_bridge" | 46 | #define ACPI_PCI_ROOT_CLASS "pci_bridge" |
47 | #define ACPI_PCI_ROOT_DEVICE_NAME "PCI Root Bridge" | 47 | #define ACPI_PCI_ROOT_DEVICE_NAME "PCI Root Bridge" |
48 | static int acpi_pci_root_add(struct acpi_device *device); | 48 | static int acpi_pci_root_add(struct acpi_device *device, |
49 | static int acpi_pci_root_remove(struct acpi_device *device, int type); | 49 | const struct acpi_device_id *not_used); |
50 | static void acpi_pci_root_remove(struct acpi_device *device); | ||
50 | 51 | ||
51 | #define ACPI_PCIE_REQ_SUPPORT (OSC_EXT_PCI_CONFIG_SUPPORT \ | 52 | #define ACPI_PCIE_REQ_SUPPORT (OSC_EXT_PCI_CONFIG_SUPPORT \ |
52 | | OSC_ACTIVE_STATE_PWR_SUPPORT \ | 53 | | OSC_ACTIVE_STATE_PWR_SUPPORT \ |
@@ -57,16 +58,11 @@ static const struct acpi_device_id root_device_ids[] = { | |||
57 | {"PNP0A03", 0}, | 58 | {"PNP0A03", 0}, |
58 | {"", 0}, | 59 | {"", 0}, |
59 | }; | 60 | }; |
60 | MODULE_DEVICE_TABLE(acpi, root_device_ids); | ||
61 | 61 | ||
62 | static struct acpi_driver acpi_pci_root_driver = { | 62 | static struct acpi_scan_handler pci_root_handler = { |
63 | .name = "pci_root", | ||
64 | .class = ACPI_PCI_ROOT_CLASS, | ||
65 | .ids = root_device_ids, | 63 | .ids = root_device_ids, |
66 | .ops = { | 64 | .attach = acpi_pci_root_add, |
67 | .add = acpi_pci_root_add, | 65 | .detach = acpi_pci_root_remove, |
68 | .remove = acpi_pci_root_remove, | ||
69 | }, | ||
70 | }; | 66 | }; |
71 | 67 | ||
72 | /* Lock to protect both acpi_pci_roots and acpi_pci_drivers lists */ | 68 | /* Lock to protect both acpi_pci_roots and acpi_pci_drivers lists */ |
@@ -428,7 +424,8 @@ out: | |||
428 | } | 424 | } |
429 | EXPORT_SYMBOL(acpi_pci_osc_control_set); | 425 | EXPORT_SYMBOL(acpi_pci_osc_control_set); |
430 | 426 | ||
431 | static int acpi_pci_root_add(struct acpi_device *device) | 427 | static int acpi_pci_root_add(struct acpi_device *device, |
428 | const struct acpi_device_id *not_used) | ||
432 | { | 429 | { |
433 | unsigned long long segment, bus; | 430 | unsigned long long segment, bus; |
434 | acpi_status status; | 431 | acpi_status status; |
@@ -614,7 +611,7 @@ static int acpi_pci_root_add(struct acpi_device *device) | |||
614 | pci_enable_bridges(root->bus); | 611 | pci_enable_bridges(root->bus); |
615 | 612 | ||
616 | pci_bus_add_devices(root->bus); | 613 | pci_bus_add_devices(root->bus); |
617 | return 0; | 614 | return 1; |
618 | 615 | ||
619 | out_del_root: | 616 | out_del_root: |
620 | mutex_lock(&acpi_pci_root_lock); | 617 | mutex_lock(&acpi_pci_root_lock); |
@@ -627,7 +624,7 @@ end: | |||
627 | return result; | 624 | return result; |
628 | } | 625 | } |
629 | 626 | ||
630 | static int acpi_pci_root_remove(struct acpi_device *device, int type) | 627 | static void acpi_pci_root_remove(struct acpi_device *device) |
631 | { | 628 | { |
632 | acpi_status status; | 629 | acpi_status status; |
633 | acpi_handle handle; | 630 | acpi_handle handle; |
@@ -655,19 +652,14 @@ static int acpi_pci_root_remove(struct acpi_device *device, int type) | |||
655 | list_del(&root->node); | 652 | list_del(&root->node); |
656 | mutex_unlock(&acpi_pci_root_lock); | 653 | mutex_unlock(&acpi_pci_root_lock); |
657 | kfree(root); | 654 | kfree(root); |
658 | return 0; | ||
659 | } | 655 | } |
660 | 656 | ||
661 | int __init acpi_pci_root_init(void) | 657 | void __init acpi_pci_root_init(void) |
662 | { | 658 | { |
663 | acpi_hest_init(); | 659 | acpi_hest_init(); |
664 | 660 | ||
665 | if (acpi_pci_disabled) | 661 | if (!acpi_pci_disabled) { |
666 | return 0; | 662 | pci_acpi_crs_quirks(); |
667 | 663 | acpi_scan_add_handler(&pci_root_handler); | |
668 | pci_acpi_crs_quirks(); | 664 | } |
669 | if (acpi_bus_register_driver(&acpi_pci_root_driver) < 0) | ||
670 | return -ENODEV; | ||
671 | |||
672 | return 0; | ||
673 | } | 665 | } |
diff --git a/drivers/acpi/pci_slot.c b/drivers/acpi/pci_slot.c index d22585f21aeb..2c630c006c2f 100644 --- a/drivers/acpi/pci_slot.c +++ b/drivers/acpi/pci_slot.c | |||
@@ -50,13 +50,12 @@ module_param(debug, bool, 0644); | |||
50 | ACPI_MODULE_NAME("pci_slot"); | 50 | ACPI_MODULE_NAME("pci_slot"); |
51 | 51 | ||
52 | #define MY_NAME "pci_slot" | 52 | #define MY_NAME "pci_slot" |
53 | #define err(format, arg...) printk(KERN_ERR "%s: " format , MY_NAME , ## arg) | 53 | #define err(format, arg...) pr_err("%s: " format , MY_NAME , ## arg) |
54 | #define info(format, arg...) printk(KERN_INFO "%s: " format , MY_NAME , ## arg) | 54 | #define info(format, arg...) pr_info("%s: " format , MY_NAME , ## arg) |
55 | #define dbg(format, arg...) \ | 55 | #define dbg(format, arg...) \ |
56 | do { \ | 56 | do { \ |
57 | if (debug) \ | 57 | if (debug) \ |
58 | printk(KERN_DEBUG "%s: " format, \ | 58 | pr_debug("%s: " format, MY_NAME , ## arg); \ |
59 | MY_NAME , ## arg); \ | ||
60 | } while (0) | 59 | } while (0) |
61 | 60 | ||
62 | #define SLOT_NAME_SIZE 21 /* Inspired by #define in acpiphp.h */ | 61 | #define SLOT_NAME_SIZE 21 /* Inspired by #define in acpiphp.h */ |
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index 9c5929a17d3a..cbf1f122666b 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c | |||
@@ -81,7 +81,7 @@ MODULE_DESCRIPTION("ACPI Processor Driver"); | |||
81 | MODULE_LICENSE("GPL"); | 81 | MODULE_LICENSE("GPL"); |
82 | 82 | ||
83 | static int acpi_processor_add(struct acpi_device *device); | 83 | static int acpi_processor_add(struct acpi_device *device); |
84 | static int acpi_processor_remove(struct acpi_device *device, int type); | 84 | static int acpi_processor_remove(struct acpi_device *device); |
85 | static void acpi_processor_notify(struct acpi_device *device, u32 event); | 85 | static void acpi_processor_notify(struct acpi_device *device, u32 event); |
86 | static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr); | 86 | static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr); |
87 | static int acpi_processor_handle_eject(struct acpi_processor *pr); | 87 | static int acpi_processor_handle_eject(struct acpi_processor *pr); |
@@ -610,7 +610,7 @@ err_free_pr: | |||
610 | return result; | 610 | return result; |
611 | } | 611 | } |
612 | 612 | ||
613 | static int acpi_processor_remove(struct acpi_device *device, int type) | 613 | static int acpi_processor_remove(struct acpi_device *device) |
614 | { | 614 | { |
615 | struct acpi_processor *pr = NULL; | 615 | struct acpi_processor *pr = NULL; |
616 | 616 | ||
@@ -623,7 +623,7 @@ static int acpi_processor_remove(struct acpi_device *device, int type) | |||
623 | if (pr->id >= nr_cpu_ids) | 623 | if (pr->id >= nr_cpu_ids) |
624 | goto free; | 624 | goto free; |
625 | 625 | ||
626 | if (type == ACPI_BUS_REMOVAL_EJECT) { | 626 | if (device->removal_type == ACPI_BUS_REMOVAL_EJECT) { |
627 | if (acpi_processor_handle_eject(pr)) | 627 | if (acpi_processor_handle_eject(pr)) |
628 | return -EINVAL; | 628 | return -EINVAL; |
629 | } | 629 | } |
@@ -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 | ||
757 | static acpi_status is_processor_device(acpi_handle handle) | 767 | static acpi_status is_processor_device(acpi_handle handle) |
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c index ff0740e0a9c2..e523245643ac 100644 --- a/drivers/acpi/sbs.c +++ b/drivers/acpi/sbs.c | |||
@@ -130,7 +130,7 @@ struct acpi_sbs { | |||
130 | 130 | ||
131 | #define to_acpi_sbs(x) container_of(x, struct acpi_sbs, charger) | 131 | #define to_acpi_sbs(x) container_of(x, struct acpi_sbs, charger) |
132 | 132 | ||
133 | static int acpi_sbs_remove(struct acpi_device *device, int type); | 133 | static int acpi_sbs_remove(struct acpi_device *device); |
134 | static int acpi_battery_get_state(struct acpi_battery *battery); | 134 | static int acpi_battery_get_state(struct acpi_battery *battery); |
135 | 135 | ||
136 | static inline int battery_scale(int log) | 136 | static inline int battery_scale(int log) |
@@ -949,11 +949,11 @@ static int acpi_sbs_add(struct acpi_device *device) | |||
949 | acpi_smbus_register_callback(sbs->hc, acpi_sbs_callback, sbs); | 949 | acpi_smbus_register_callback(sbs->hc, acpi_sbs_callback, sbs); |
950 | end: | 950 | end: |
951 | if (result) | 951 | if (result) |
952 | acpi_sbs_remove(device, 0); | 952 | acpi_sbs_remove(device); |
953 | return result; | 953 | return result; |
954 | } | 954 | } |
955 | 955 | ||
956 | static int acpi_sbs_remove(struct acpi_device *device, int type) | 956 | static int acpi_sbs_remove(struct acpi_device *device) |
957 | { | 957 | { |
958 | struct acpi_sbs *sbs; | 958 | struct acpi_sbs *sbs; |
959 | int id; | 959 | int id; |
diff --git a/drivers/acpi/sbshc.c b/drivers/acpi/sbshc.c index cf6129a8af7c..b78bc605837e 100644 --- a/drivers/acpi/sbshc.c +++ b/drivers/acpi/sbshc.c | |||
@@ -33,7 +33,7 @@ struct acpi_smb_hc { | |||
33 | }; | 33 | }; |
34 | 34 | ||
35 | static int acpi_smbus_hc_add(struct acpi_device *device); | 35 | static int acpi_smbus_hc_add(struct acpi_device *device); |
36 | static int acpi_smbus_hc_remove(struct acpi_device *device, int type); | 36 | static int acpi_smbus_hc_remove(struct acpi_device *device); |
37 | 37 | ||
38 | static const struct acpi_device_id sbs_device_ids[] = { | 38 | static const struct acpi_device_id sbs_device_ids[] = { |
39 | {"ACPI0001", 0}, | 39 | {"ACPI0001", 0}, |
@@ -296,7 +296,7 @@ static int acpi_smbus_hc_add(struct acpi_device *device) | |||
296 | 296 | ||
297 | extern void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit); | 297 | extern void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit); |
298 | 298 | ||
299 | static int acpi_smbus_hc_remove(struct acpi_device *device, int type) | 299 | static int acpi_smbus_hc_remove(struct acpi_device *device) |
300 | { | 300 | { |
301 | struct acpi_smb_hc *hc; | 301 | struct acpi_smb_hc *hc; |
302 | 302 | ||
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index c4358716aadc..daee7497efd3 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -29,30 +29,10 @@ extern struct acpi_device *acpi_root; | |||
29 | 29 | ||
30 | static const char *dummy_hid = "device"; | 30 | static const char *dummy_hid = "device"; |
31 | 31 | ||
32 | /* | ||
33 | * The following ACPI IDs are known to be suitable for representing as | ||
34 | * platform devices. | ||
35 | */ | ||
36 | static const struct acpi_device_id acpi_platform_device_ids[] = { | ||
37 | |||
38 | { "PNP0D40" }, | ||
39 | |||
40 | /* Haswell LPSS devices */ | ||
41 | { "INT33C0", ACPI_PLATFORM_CLK }, | ||
42 | { "INT33C1", ACPI_PLATFORM_CLK }, | ||
43 | { "INT33C2", ACPI_PLATFORM_CLK }, | ||
44 | { "INT33C3", ACPI_PLATFORM_CLK }, | ||
45 | { "INT33C4", ACPI_PLATFORM_CLK }, | ||
46 | { "INT33C5", ACPI_PLATFORM_CLK }, | ||
47 | { "INT33C6", ACPI_PLATFORM_CLK }, | ||
48 | { "INT33C7", ACPI_PLATFORM_CLK }, | ||
49 | |||
50 | { } | ||
51 | }; | ||
52 | |||
53 | static LIST_HEAD(acpi_device_list); | 32 | static LIST_HEAD(acpi_device_list); |
54 | static LIST_HEAD(acpi_bus_id_list); | 33 | static LIST_HEAD(acpi_bus_id_list); |
55 | static DEFINE_MUTEX(acpi_scan_lock); | 34 | static DEFINE_MUTEX(acpi_scan_lock); |
35 | static LIST_HEAD(acpi_scan_handlers_list); | ||
56 | DEFINE_MUTEX(acpi_device_lock); | 36 | DEFINE_MUTEX(acpi_device_lock); |
57 | LIST_HEAD(acpi_wakeup_device_list); | 37 | LIST_HEAD(acpi_wakeup_device_list); |
58 | 38 | ||
@@ -62,6 +42,27 @@ struct acpi_device_bus_id{ | |||
62 | struct list_head node; | 42 | struct list_head node; |
63 | }; | 43 | }; |
64 | 44 | ||
45 | void acpi_scan_lock_acquire(void) | ||
46 | { | ||
47 | mutex_lock(&acpi_scan_lock); | ||
48 | } | ||
49 | EXPORT_SYMBOL_GPL(acpi_scan_lock_acquire); | ||
50 | |||
51 | void acpi_scan_lock_release(void) | ||
52 | { | ||
53 | mutex_unlock(&acpi_scan_lock); | ||
54 | } | ||
55 | EXPORT_SYMBOL_GPL(acpi_scan_lock_release); | ||
56 | |||
57 | int acpi_scan_add_handler(struct acpi_scan_handler *handler) | ||
58 | { | ||
59 | if (!handler || !handler->attach) | ||
60 | return -EINVAL; | ||
61 | |||
62 | list_add_tail(&handler->list_node, &acpi_scan_handlers_list); | ||
63 | return 0; | ||
64 | } | ||
65 | |||
65 | /* | 66 | /* |
66 | * Creates hid/cid(s) string needed for modalias and uevent | 67 | * Creates hid/cid(s) string needed for modalias and uevent |
67 | * e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get: | 68 | * e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get: |
@@ -116,7 +117,7 @@ static DEVICE_ATTR(modalias, 0444, acpi_device_modalias_show, NULL); | |||
116 | */ | 117 | */ |
117 | void acpi_bus_hot_remove_device(void *context) | 118 | void acpi_bus_hot_remove_device(void *context) |
118 | { | 119 | { |
119 | struct acpi_eject_event *ej_event = (struct acpi_eject_event *) context; | 120 | struct acpi_eject_event *ej_event = context; |
120 | struct acpi_device *device = ej_event->device; | 121 | struct acpi_device *device = ej_event->device; |
121 | acpi_handle handle = device->handle; | 122 | acpi_handle handle = device->handle; |
122 | acpi_handle temp; | 123 | acpi_handle temp; |
@@ -125,19 +126,23 @@ void acpi_bus_hot_remove_device(void *context) | |||
125 | acpi_status status = AE_OK; | 126 | acpi_status status = AE_OK; |
126 | u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */ | 127 | u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */ |
127 | 128 | ||
129 | mutex_lock(&acpi_scan_lock); | ||
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 | |||
128 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 138 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
129 | "Hot-removing device %s...\n", dev_name(&device->dev))); | 139 | "Hot-removing device %s...\n", dev_name(&device->dev))); |
130 | 140 | ||
131 | acpi_bus_trim(device); | 141 | acpi_bus_trim(device); |
132 | /* Device node has been released. */ | 142 | /* Device node has been unregistered. */ |
143 | put_device(&device->dev); | ||
133 | device = NULL; | 144 | device = NULL; |
134 | 145 | ||
135 | /* power off device */ | ||
136 | status = acpi_evaluate_object(handle, "_PS3", NULL, NULL); | ||
137 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) | ||
138 | printk(KERN_WARNING PREFIX | ||
139 | "Power-off device failed\n"); | ||
140 | |||
141 | if (ACPI_SUCCESS(acpi_get_handle(handle, "_LCK", &temp))) { | 146 | if (ACPI_SUCCESS(acpi_get_handle(handle, "_LCK", &temp))) { |
142 | arg_list.count = 1; | 147 | arg_list.count = 1; |
143 | arg_list.pointer = &arg; | 148 | arg_list.pointer = &arg; |
@@ -157,18 +162,15 @@ void acpi_bus_hot_remove_device(void *context) | |||
157 | status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL); | 162 | status = acpi_evaluate_object(handle, "_EJ0", &arg_list, NULL); |
158 | if (ACPI_FAILURE(status)) { | 163 | if (ACPI_FAILURE(status)) { |
159 | if (status != AE_NOT_FOUND) | 164 | if (status != AE_NOT_FOUND) |
160 | printk(KERN_WARNING PREFIX | 165 | acpi_handle_warn(handle, "Eject failed\n"); |
161 | "Eject device failed\n"); | ||
162 | goto err_out; | ||
163 | } | ||
164 | 166 | ||
165 | kfree(context); | 167 | /* Tell the firmware the hot-remove operation has failed. */ |
166 | return; | 168 | acpi_evaluate_hotplug_ost(handle, ej_event->event, |
169 | ost_code, NULL); | ||
170 | } | ||
167 | 171 | ||
168 | err_out: | 172 | out: |
169 | /* Inform firmware the hot-remove operation has completed w/ error */ | 173 | mutex_unlock(&acpi_scan_lock); |
170 | (void) acpi_evaluate_hotplug_ost(handle, | ||
171 | ej_event->event, ost_code, NULL); | ||
172 | kfree(context); | 174 | kfree(context); |
173 | return; | 175 | return; |
174 | } | 176 | } |
@@ -213,12 +215,10 @@ acpi_eject_store(struct device *d, struct device_attribute *attr, | |||
213 | if ((!count) || (buf[0] != '1')) { | 215 | if ((!count) || (buf[0] != '1')) { |
214 | return -EINVAL; | 216 | return -EINVAL; |
215 | } | 217 | } |
216 | #ifndef FORCE_EJECT | 218 | if (!acpi_device->driver && !acpi_device->handler) { |
217 | if (acpi_device->driver == NULL) { | ||
218 | ret = -ENODEV; | 219 | ret = -ENODEV; |
219 | goto err; | 220 | goto err; |
220 | } | 221 | } |
221 | #endif | ||
222 | status = acpi_get_type(acpi_device->handle, &type); | 222 | status = acpi_get_type(acpi_device->handle, &type); |
223 | if (ACPI_FAILURE(status) || (!acpi_device->flags.ejectable)) { | 223 | if (ACPI_FAILURE(status) || (!acpi_device->flags.ejectable)) { |
224 | ret = -ENODEV; | 224 | ret = -ENODEV; |
@@ -231,6 +231,7 @@ acpi_eject_store(struct device *d, struct device_attribute *attr, | |||
231 | goto err; | 231 | goto err; |
232 | } | 232 | } |
233 | 233 | ||
234 | get_device(&acpi_device->dev); | ||
234 | ej_event->device = acpi_device; | 235 | ej_event->device = acpi_device; |
235 | if (acpi_device->flags.eject_pending) { | 236 | if (acpi_device->flags.eject_pending) { |
236 | /* event originated from ACPI eject notification */ | 237 | /* event originated from ACPI eject notification */ |
@@ -243,7 +244,11 @@ acpi_eject_store(struct device *d, struct device_attribute *attr, | |||
243 | ej_event->event, ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); | 244 | ej_event->event, ACPI_OST_SC_EJECT_IN_PROGRESS, NULL); |
244 | } | 245 | } |
245 | 246 | ||
246 | 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 | } | ||
247 | err: | 252 | err: |
248 | return ret; | 253 | return ret; |
249 | } | 254 | } |
@@ -637,8 +642,9 @@ static int acpi_device_probe(struct device * dev) | |||
637 | ret = acpi_device_install_notify_handler(acpi_dev); | 642 | ret = acpi_device_install_notify_handler(acpi_dev); |
638 | if (ret) { | 643 | if (ret) { |
639 | if (acpi_drv->ops.remove) | 644 | if (acpi_drv->ops.remove) |
640 | acpi_drv->ops.remove(acpi_dev, | 645 | acpi_drv->ops.remove(acpi_dev); |
641 | acpi_dev->removal_type); | 646 | acpi_dev->driver = NULL; |
647 | acpi_dev->driver_data = NULL; | ||
642 | return ret; | 648 | return ret; |
643 | } | 649 | } |
644 | } | 650 | } |
@@ -660,7 +666,7 @@ static int acpi_device_remove(struct device * dev) | |||
660 | if (acpi_drv->ops.notify) | 666 | if (acpi_drv->ops.notify) |
661 | acpi_device_remove_notify_handler(acpi_dev); | 667 | acpi_device_remove_notify_handler(acpi_dev); |
662 | if (acpi_drv->ops.remove) | 668 | if (acpi_drv->ops.remove) |
663 | acpi_drv->ops.remove(acpi_dev, acpi_dev->removal_type); | 669 | acpi_drv->ops.remove(acpi_dev); |
664 | } | 670 | } |
665 | acpi_dev->driver = NULL; | 671 | acpi_dev->driver = NULL; |
666 | acpi_dev->driver_data = NULL; | 672 | acpi_dev->driver_data = NULL; |
@@ -792,10 +798,12 @@ static void acpi_device_unregister(struct acpi_device *device) | |||
792 | 798 | ||
793 | device_del(&device->dev); | 799 | device_del(&device->dev); |
794 | /* | 800 | /* |
795 | * Drop the reference counts of all power resources the device depends | 801 | * Transition the device to D3cold to drop the reference counts of all |
796 | * on and turn off the ones that have no more references. | 802 | * power resources the device depends on and turn off the ones that have |
803 | * no more references. | ||
797 | */ | 804 | */ |
798 | acpi_power_transition(device, ACPI_STATE_D3_COLD); | 805 | acpi_device_set_power(device, ACPI_STATE_D3_COLD); |
806 | device->handle = NULL; | ||
799 | put_device(&device->dev); | 807 | put_device(&device->dev); |
800 | } | 808 | } |
801 | 809 | ||
@@ -883,29 +891,23 @@ EXPORT_SYMBOL(acpi_bus_unregister_driver); | |||
883 | -------------------------------------------------------------------------- */ | 891 | -------------------------------------------------------------------------- */ |
884 | static struct acpi_device *acpi_bus_get_parent(acpi_handle handle) | 892 | static struct acpi_device *acpi_bus_get_parent(acpi_handle handle) |
885 | { | 893 | { |
894 | struct acpi_device *device = NULL; | ||
886 | acpi_status status; | 895 | acpi_status status; |
887 | int ret; | ||
888 | struct acpi_device *device; | ||
889 | 896 | ||
890 | /* | 897 | /* |
891 | * Fixed hardware devices do not appear in the namespace and do not | 898 | * Fixed hardware devices do not appear in the namespace and do not |
892 | * have handles, but we fabricate acpi_devices for them, so we have | 899 | * have handles, but we fabricate acpi_devices for them, so we have |
893 | * to deal with them specially. | 900 | * to deal with them specially. |
894 | */ | 901 | */ |
895 | if (handle == NULL) | 902 | if (!handle) |
896 | return acpi_root; | 903 | return acpi_root; |
897 | 904 | ||
898 | do { | 905 | do { |
899 | status = acpi_get_parent(handle, &handle); | 906 | status = acpi_get_parent(handle, &handle); |
900 | if (status == AE_NULL_ENTRY) | ||
901 | return NULL; | ||
902 | if (ACPI_FAILURE(status)) | 907 | if (ACPI_FAILURE(status)) |
903 | return acpi_root; | 908 | return status == AE_NULL_ENTRY ? NULL : acpi_root; |
904 | 909 | } while (acpi_bus_get_device(handle, &device)); | |
905 | ret = acpi_bus_get_device(handle, &device); | 910 | return device; |
906 | if (ret == 0) | ||
907 | return device; | ||
908 | } while (1); | ||
909 | } | 911 | } |
910 | 912 | ||
911 | acpi_status | 913 | acpi_status |
@@ -1441,19 +1443,21 @@ void acpi_init_device_object(struct acpi_device *device, acpi_handle handle, | |||
1441 | acpi_device_get_busid(device); | 1443 | acpi_device_get_busid(device); |
1442 | acpi_device_set_id(device); | 1444 | acpi_device_set_id(device); |
1443 | acpi_bus_get_flags(device); | 1445 | acpi_bus_get_flags(device); |
1446 | device->flags.match_driver = false; | ||
1444 | device_initialize(&device->dev); | 1447 | device_initialize(&device->dev); |
1445 | dev_set_uevent_suppress(&device->dev, true); | 1448 | dev_set_uevent_suppress(&device->dev, true); |
1446 | } | 1449 | } |
1447 | 1450 | ||
1448 | void acpi_device_add_finalize(struct acpi_device *device) | 1451 | void acpi_device_add_finalize(struct acpi_device *device) |
1449 | { | 1452 | { |
1453 | device->flags.match_driver = true; | ||
1450 | dev_set_uevent_suppress(&device->dev, false); | 1454 | dev_set_uevent_suppress(&device->dev, false); |
1451 | kobject_uevent(&device->dev.kobj, KOBJ_ADD); | 1455 | kobject_uevent(&device->dev.kobj, KOBJ_ADD); |
1452 | } | 1456 | } |
1453 | 1457 | ||
1454 | static int acpi_add_single_object(struct acpi_device **child, | 1458 | static int acpi_add_single_object(struct acpi_device **child, |
1455 | acpi_handle handle, int type, | 1459 | acpi_handle handle, int type, |
1456 | unsigned long long sta, bool match_driver) | 1460 | unsigned long long sta) |
1457 | { | 1461 | { |
1458 | int result; | 1462 | int result; |
1459 | struct acpi_device *device; | 1463 | struct acpi_device *device; |
@@ -1469,7 +1473,6 @@ static int acpi_add_single_object(struct acpi_device **child, | |||
1469 | acpi_bus_get_power_flags(device); | 1473 | acpi_bus_get_power_flags(device); |
1470 | acpi_bus_get_wakeup_device_flags(device); | 1474 | acpi_bus_get_wakeup_device_flags(device); |
1471 | 1475 | ||
1472 | device->flags.match_driver = match_driver; | ||
1473 | result = acpi_device_add(device, acpi_device_release); | 1476 | result = acpi_device_add(device, acpi_device_release); |
1474 | if (result) { | 1477 | if (result) { |
1475 | acpi_device_release(&device->dev); | 1478 | acpi_device_release(&device->dev); |
@@ -1562,12 +1565,10 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used, | |||
1562 | return AE_CTRL_DEPTH; | 1565 | return AE_CTRL_DEPTH; |
1563 | } | 1566 | } |
1564 | 1567 | ||
1565 | acpi_add_single_object(&device, handle, type, sta, false); | 1568 | acpi_add_single_object(&device, handle, type, sta); |
1566 | if (!device) | 1569 | if (!device) |
1567 | return AE_CTRL_DEPTH; | 1570 | return AE_CTRL_DEPTH; |
1568 | 1571 | ||
1569 | device->flags.match_driver = true; | ||
1570 | |||
1571 | out: | 1572 | out: |
1572 | if (!*return_value) | 1573 | if (!*return_value) |
1573 | *return_value = device; | 1574 | *return_value = device; |
@@ -1575,33 +1576,68 @@ static acpi_status acpi_bus_check_add(acpi_handle handle, u32 lvl_not_used, | |||
1575 | return AE_OK; | 1576 | return AE_OK; |
1576 | } | 1577 | } |
1577 | 1578 | ||
1579 | static int acpi_scan_do_attach_handler(struct acpi_device *device, char *id) | ||
1580 | { | ||
1581 | struct acpi_scan_handler *handler; | ||
1582 | |||
1583 | list_for_each_entry(handler, &acpi_scan_handlers_list, list_node) { | ||
1584 | const struct acpi_device_id *devid; | ||
1585 | |||
1586 | for (devid = handler->ids; devid->id[0]; devid++) { | ||
1587 | int ret; | ||
1588 | |||
1589 | if (strcmp((char *)devid->id, id)) | ||
1590 | continue; | ||
1591 | |||
1592 | ret = handler->attach(device, devid); | ||
1593 | if (ret > 0) { | ||
1594 | device->handler = handler; | ||
1595 | return ret; | ||
1596 | } else if (ret < 0) { | ||
1597 | return ret; | ||
1598 | } | ||
1599 | } | ||
1600 | } | ||
1601 | return 0; | ||
1602 | } | ||
1603 | |||
1604 | static int acpi_scan_attach_handler(struct acpi_device *device) | ||
1605 | { | ||
1606 | struct acpi_hardware_id *hwid; | ||
1607 | int ret = 0; | ||
1608 | |||
1609 | list_for_each_entry(hwid, &device->pnp.ids, list) { | ||
1610 | ret = acpi_scan_do_attach_handler(device, hwid->id); | ||
1611 | if (ret) | ||
1612 | break; | ||
1613 | |||
1614 | } | ||
1615 | return ret; | ||
1616 | } | ||
1617 | |||
1578 | static acpi_status acpi_bus_device_attach(acpi_handle handle, u32 lvl_not_used, | 1618 | static acpi_status acpi_bus_device_attach(acpi_handle handle, u32 lvl_not_used, |
1579 | void *not_used, void **ret_not_used) | 1619 | void *not_used, void **ret_not_used) |
1580 | { | 1620 | { |
1581 | const struct acpi_device_id *id; | ||
1582 | acpi_status status = AE_OK; | ||
1583 | struct acpi_device *device; | 1621 | struct acpi_device *device; |
1584 | unsigned long long sta_not_used; | 1622 | unsigned long long sta_not_used; |
1585 | int type_not_used; | 1623 | int ret; |
1586 | 1624 | ||
1587 | /* | 1625 | /* |
1588 | * Ignore errors ignored by acpi_bus_check_add() to avoid terminating | 1626 | * Ignore errors ignored by acpi_bus_check_add() to avoid terminating |
1589 | * namespace walks prematurely. | 1627 | * namespace walks prematurely. |
1590 | */ | 1628 | */ |
1591 | if (acpi_bus_type_and_status(handle, &type_not_used, &sta_not_used)) | 1629 | if (acpi_bus_type_and_status(handle, &ret, &sta_not_used)) |
1592 | return AE_OK; | 1630 | return AE_OK; |
1593 | 1631 | ||
1594 | if (acpi_bus_get_device(handle, &device)) | 1632 | if (acpi_bus_get_device(handle, &device)) |
1595 | return AE_CTRL_DEPTH; | 1633 | return AE_CTRL_DEPTH; |
1596 | 1634 | ||
1597 | id = __acpi_match_device(device, acpi_platform_device_ids); | 1635 | ret = acpi_scan_attach_handler(device); |
1598 | if (id) { | 1636 | if (ret) |
1599 | /* This is a known good platform device. */ | 1637 | return ret > 0 ? AE_OK : AE_CTRL_DEPTH; |
1600 | acpi_create_platform_device(device, id->driver_data); | 1638 | |
1601 | } else if (device_attach(&device->dev) < 0) { | 1639 | ret = device_attach(&device->dev); |
1602 | status = AE_CTRL_DEPTH; | 1640 | return ret >= 0 ? AE_OK : AE_CTRL_DEPTH; |
1603 | } | ||
1604 | return status; | ||
1605 | } | 1641 | } |
1606 | 1642 | ||
1607 | /** | 1643 | /** |
@@ -1615,14 +1651,14 @@ static acpi_status acpi_bus_device_attach(acpi_handle handle, u32 lvl_not_used, | |||
1615 | * there has been a real error. There just have been no suitable ACPI objects | 1651 | * there has been a real error. There just have been no suitable ACPI objects |
1616 | * in the table trunk from which the kernel could create a device and add an | 1652 | * in the table trunk from which the kernel could create a device and add an |
1617 | * appropriate driver. | 1653 | * appropriate driver. |
1654 | * | ||
1655 | * Must be called under acpi_scan_lock. | ||
1618 | */ | 1656 | */ |
1619 | int acpi_bus_scan(acpi_handle handle) | 1657 | int acpi_bus_scan(acpi_handle handle) |
1620 | { | 1658 | { |
1621 | void *device = NULL; | 1659 | void *device = NULL; |
1622 | int error = 0; | 1660 | int error = 0; |
1623 | 1661 | ||
1624 | mutex_lock(&acpi_scan_lock); | ||
1625 | |||
1626 | if (ACPI_SUCCESS(acpi_bus_check_add(handle, 0, NULL, &device))) | 1662 | if (ACPI_SUCCESS(acpi_bus_check_add(handle, 0, NULL, &device))) |
1627 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, | 1663 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, |
1628 | acpi_bus_check_add, NULL, NULL, &device); | 1664 | acpi_bus_check_add, NULL, NULL, &device); |
@@ -1633,7 +1669,6 @@ int acpi_bus_scan(acpi_handle handle) | |||
1633 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, | 1669 | acpi_walk_namespace(ACPI_TYPE_ANY, handle, ACPI_UINT32_MAX, |
1634 | acpi_bus_device_attach, NULL, NULL, NULL); | 1670 | acpi_bus_device_attach, NULL, NULL, NULL); |
1635 | 1671 | ||
1636 | mutex_unlock(&acpi_scan_lock); | ||
1637 | return error; | 1672 | return error; |
1638 | } | 1673 | } |
1639 | EXPORT_SYMBOL(acpi_bus_scan); | 1674 | EXPORT_SYMBOL(acpi_bus_scan); |
@@ -1644,8 +1679,17 @@ static acpi_status acpi_bus_device_detach(acpi_handle handle, u32 lvl_not_used, | |||
1644 | struct acpi_device *device = NULL; | 1679 | struct acpi_device *device = NULL; |
1645 | 1680 | ||
1646 | if (!acpi_bus_get_device(handle, &device)) { | 1681 | if (!acpi_bus_get_device(handle, &device)) { |
1682 | struct acpi_scan_handler *dev_handler = device->handler; | ||
1683 | |||
1647 | device->removal_type = ACPI_BUS_REMOVAL_EJECT; | 1684 | device->removal_type = ACPI_BUS_REMOVAL_EJECT; |
1648 | device_release_driver(&device->dev); | 1685 | if (dev_handler) { |
1686 | if (dev_handler->detach) | ||
1687 | dev_handler->detach(device); | ||
1688 | |||
1689 | device->handler = NULL; | ||
1690 | } else { | ||
1691 | device_release_driver(&device->dev); | ||
1692 | } | ||
1649 | } | 1693 | } |
1650 | return AE_OK; | 1694 | return AE_OK; |
1651 | } | 1695 | } |
@@ -1661,10 +1705,14 @@ static acpi_status acpi_bus_remove(acpi_handle handle, u32 lvl_not_used, | |||
1661 | return AE_OK; | 1705 | return AE_OK; |
1662 | } | 1706 | } |
1663 | 1707 | ||
1708 | /** | ||
1709 | * acpi_bus_trim - Remove ACPI device node and all of its descendants | ||
1710 | * @start: Root of the ACPI device nodes subtree to remove. | ||
1711 | * | ||
1712 | * Must be called under acpi_scan_lock. | ||
1713 | */ | ||
1664 | void acpi_bus_trim(struct acpi_device *start) | 1714 | void acpi_bus_trim(struct acpi_device *start) |
1665 | { | 1715 | { |
1666 | mutex_lock(&acpi_scan_lock); | ||
1667 | |||
1668 | /* | 1716 | /* |
1669 | * Execute acpi_bus_device_detach() as a post-order callback to detach | 1717 | * Execute acpi_bus_device_detach() as a post-order callback to detach |
1670 | * all ACPI drivers from the device nodes being removed. | 1718 | * all ACPI drivers from the device nodes being removed. |
@@ -1679,33 +1727,45 @@ void acpi_bus_trim(struct acpi_device *start) | |||
1679 | acpi_walk_namespace(ACPI_TYPE_ANY, start->handle, ACPI_UINT32_MAX, NULL, | 1727 | acpi_walk_namespace(ACPI_TYPE_ANY, start->handle, ACPI_UINT32_MAX, NULL, |
1680 | acpi_bus_remove, NULL, NULL); | 1728 | acpi_bus_remove, NULL, NULL); |
1681 | acpi_bus_remove(start->handle, 0, NULL, NULL); | 1729 | acpi_bus_remove(start->handle, 0, NULL, NULL); |
1682 | |||
1683 | mutex_unlock(&acpi_scan_lock); | ||
1684 | } | 1730 | } |
1685 | EXPORT_SYMBOL_GPL(acpi_bus_trim); | 1731 | EXPORT_SYMBOL_GPL(acpi_bus_trim); |
1686 | 1732 | ||
1687 | static int acpi_bus_scan_fixed(void) | 1733 | static int acpi_bus_scan_fixed(void) |
1688 | { | 1734 | { |
1689 | int result = 0; | 1735 | int result = 0; |
1690 | struct acpi_device *device = NULL; | ||
1691 | 1736 | ||
1692 | /* | 1737 | /* |
1693 | * Enumerate all fixed-feature devices. | 1738 | * Enumerate all fixed-feature devices. |
1694 | */ | 1739 | */ |
1695 | if ((acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON) == 0) { | 1740 | if (!(acpi_gbl_FADT.flags & ACPI_FADT_POWER_BUTTON)) { |
1741 | struct acpi_device *device = NULL; | ||
1742 | |||
1696 | result = acpi_add_single_object(&device, NULL, | 1743 | result = acpi_add_single_object(&device, NULL, |
1697 | ACPI_BUS_TYPE_POWER_BUTTON, | 1744 | ACPI_BUS_TYPE_POWER_BUTTON, |
1698 | ACPI_STA_DEFAULT, true); | 1745 | ACPI_STA_DEFAULT); |
1746 | if (result) | ||
1747 | return result; | ||
1748 | |||
1749 | result = device_attach(&device->dev); | ||
1750 | if (result < 0) | ||
1751 | return result; | ||
1752 | |||
1699 | device_init_wakeup(&device->dev, true); | 1753 | device_init_wakeup(&device->dev, true); |
1700 | } | 1754 | } |
1701 | 1755 | ||
1702 | if ((acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON) == 0) { | 1756 | if (!(acpi_gbl_FADT.flags & ACPI_FADT_SLEEP_BUTTON)) { |
1757 | struct acpi_device *device = NULL; | ||
1758 | |||
1703 | result = acpi_add_single_object(&device, NULL, | 1759 | result = acpi_add_single_object(&device, NULL, |
1704 | ACPI_BUS_TYPE_SLEEP_BUTTON, | 1760 | ACPI_BUS_TYPE_SLEEP_BUTTON, |
1705 | ACPI_STA_DEFAULT, true); | 1761 | ACPI_STA_DEFAULT); |
1762 | if (result) | ||
1763 | return result; | ||
1764 | |||
1765 | result = device_attach(&device->dev); | ||
1706 | } | 1766 | } |
1707 | 1767 | ||
1708 | return result; | 1768 | return result < 0 ? result : 0; |
1709 | } | 1769 | } |
1710 | 1770 | ||
1711 | int __init acpi_scan_init(void) | 1771 | int __init acpi_scan_init(void) |
@@ -1719,25 +1779,32 @@ int __init acpi_scan_init(void) | |||
1719 | } | 1779 | } |
1720 | 1780 | ||
1721 | acpi_pci_root_init(); | 1781 | acpi_pci_root_init(); |
1782 | acpi_pci_link_init(); | ||
1783 | acpi_platform_init(); | ||
1722 | acpi_csrt_init(); | 1784 | acpi_csrt_init(); |
1785 | acpi_container_init(); | ||
1723 | 1786 | ||
1787 | mutex_lock(&acpi_scan_lock); | ||
1724 | /* | 1788 | /* |
1725 | * Enumerate devices in the ACPI namespace. | 1789 | * Enumerate devices in the ACPI namespace. |
1726 | */ | 1790 | */ |
1727 | result = acpi_bus_scan(ACPI_ROOT_OBJECT); | 1791 | result = acpi_bus_scan(ACPI_ROOT_OBJECT); |
1728 | if (result) | 1792 | if (result) |
1729 | return result; | 1793 | goto out; |
1730 | 1794 | ||
1731 | result = acpi_bus_get_device(ACPI_ROOT_OBJECT, &acpi_root); | 1795 | result = acpi_bus_get_device(ACPI_ROOT_OBJECT, &acpi_root); |
1732 | if (result) | 1796 | if (result) |
1733 | return result; | 1797 | goto out; |
1734 | 1798 | ||
1735 | result = acpi_bus_scan_fixed(); | 1799 | result = acpi_bus_scan_fixed(); |
1736 | if (result) { | 1800 | if (result) { |
1737 | acpi_device_unregister(acpi_root); | 1801 | acpi_device_unregister(acpi_root); |
1738 | return result; | 1802 | goto out; |
1739 | } | 1803 | } |
1740 | 1804 | ||
1741 | acpi_update_all_gpes(); | 1805 | acpi_update_all_gpes(); |
1742 | return 0; | 1806 | |
1807 | out: | ||
1808 | mutex_unlock(&acpi_scan_lock); | ||
1809 | return result; | ||
1743 | } | 1810 | } |
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 506fbd4b5733..da079d4e0baa 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c | |||
@@ -97,7 +97,7 @@ module_param(psv, int, 0644); | |||
97 | MODULE_PARM_DESC(psv, "Disable or override all passive trip points."); | 97 | MODULE_PARM_DESC(psv, "Disable or override all passive trip points."); |
98 | 98 | ||
99 | static int acpi_thermal_add(struct acpi_device *device); | 99 | static int acpi_thermal_add(struct acpi_device *device); |
100 | static int acpi_thermal_remove(struct acpi_device *device, int type); | 100 | static int acpi_thermal_remove(struct acpi_device *device); |
101 | static void acpi_thermal_notify(struct acpi_device *device, u32 event); | 101 | static void acpi_thermal_notify(struct acpi_device *device, u32 event); |
102 | 102 | ||
103 | static const struct acpi_device_id thermal_device_ids[] = { | 103 | static const struct acpi_device_id thermal_device_ids[] = { |
@@ -1111,7 +1111,7 @@ end: | |||
1111 | return result; | 1111 | return result; |
1112 | } | 1112 | } |
1113 | 1113 | ||
1114 | static int acpi_thermal_remove(struct acpi_device *device, int type) | 1114 | static int acpi_thermal_remove(struct acpi_device *device) |
1115 | { | 1115 | { |
1116 | struct acpi_thermal *tz = NULL; | 1116 | struct acpi_thermal *tz = NULL; |
1117 | 1117 | ||
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c index ac9a69cd45f5..5be60ad8381f 100644 --- a/drivers/acpi/video.c +++ b/drivers/acpi/video.c | |||
@@ -88,7 +88,7 @@ module_param(use_bios_initial_backlight, bool, 0644); | |||
88 | 88 | ||
89 | static int register_count = 0; | 89 | static int register_count = 0; |
90 | static int acpi_video_bus_add(struct acpi_device *device); | 90 | static int acpi_video_bus_add(struct acpi_device *device); |
91 | static int acpi_video_bus_remove(struct acpi_device *device, int type); | 91 | static int acpi_video_bus_remove(struct acpi_device *device); |
92 | static void acpi_video_bus_notify(struct acpi_device *device, u32 event); | 92 | static void acpi_video_bus_notify(struct acpi_device *device, u32 event); |
93 | 93 | ||
94 | static const struct acpi_device_id video_device_ids[] = { | 94 | static const struct acpi_device_id video_device_ids[] = { |
@@ -1740,7 +1740,7 @@ static int acpi_video_bus_add(struct acpi_device *device) | |||
1740 | return error; | 1740 | return error; |
1741 | } | 1741 | } |
1742 | 1742 | ||
1743 | static int acpi_video_bus_remove(struct acpi_device *device, int type) | 1743 | static int acpi_video_bus_remove(struct acpi_device *device) |
1744 | { | 1744 | { |
1745 | struct acpi_video_bus *video = NULL; | 1745 | struct acpi_video_bus *video = NULL; |
1746 | 1746 | ||
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c index fe6d4be48296..e3f9a99b8522 100644 --- a/drivers/char/hpet.c +++ b/drivers/char/hpet.c | |||
@@ -1041,7 +1041,7 @@ static int hpet_acpi_add(struct acpi_device *device) | |||
1041 | return hpet_alloc(&data); | 1041 | return hpet_alloc(&data); |
1042 | } | 1042 | } |
1043 | 1043 | ||
1044 | static int hpet_acpi_remove(struct acpi_device *device, int type) | 1044 | static int hpet_acpi_remove(struct acpi_device *device) |
1045 | { | 1045 | { |
1046 | /* XXX need to unregister clocksource, dealloc mem, etc */ | 1046 | /* XXX need to unregister clocksource, dealloc mem, etc */ |
1047 | return -EINVAL; | 1047 | return -EINVAL; |
diff --git a/drivers/char/sonypi.c b/drivers/char/sonypi.c index d780295a1473..6386a98e43c1 100644 --- a/drivers/char/sonypi.c +++ b/drivers/char/sonypi.c | |||
@@ -1142,7 +1142,7 @@ static int sonypi_acpi_add(struct acpi_device *device) | |||
1142 | return 0; | 1142 | return 0; |
1143 | } | 1143 | } |
1144 | 1144 | ||
1145 | static int sonypi_acpi_remove(struct acpi_device *device, int type) | 1145 | static int sonypi_acpi_remove(struct acpi_device *device) |
1146 | { | 1146 | { |
1147 | sonypi_acpi_device = NULL; | 1147 | sonypi_acpi_device = NULL; |
1148 | return 0; | 1148 | return 0; |
diff --git a/drivers/hwmon/acpi_power_meter.c b/drivers/hwmon/acpi_power_meter.c index 1672e2a5db46..6351aba8819c 100644 --- a/drivers/hwmon/acpi_power_meter.c +++ b/drivers/hwmon/acpi_power_meter.c | |||
@@ -911,7 +911,7 @@ exit: | |||
911 | return res; | 911 | return res; |
912 | } | 912 | } |
913 | 913 | ||
914 | static int acpi_power_meter_remove(struct acpi_device *device, int type) | 914 | static int acpi_power_meter_remove(struct acpi_device *device) |
915 | { | 915 | { |
916 | struct acpi_power_meter_resource *resource; | 916 | struct acpi_power_meter_resource *resource; |
917 | 917 | ||
diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c index 56dbcfb3e301..b25c64302cbc 100644 --- a/drivers/hwmon/asus_atk0110.c +++ b/drivers/hwmon/asus_atk0110.c | |||
@@ -190,7 +190,7 @@ struct atk_acpi_input_buf { | |||
190 | }; | 190 | }; |
191 | 191 | ||
192 | static int atk_add(struct acpi_device *device); | 192 | static int atk_add(struct acpi_device *device); |
193 | static int atk_remove(struct acpi_device *device, int type); | 193 | static int atk_remove(struct acpi_device *device); |
194 | static void atk_print_sensor(struct atk_data *data, union acpi_object *obj); | 194 | static void atk_print_sensor(struct atk_data *data, union acpi_object *obj); |
195 | static int atk_read_value(struct atk_sensor_data *sensor, u64 *value); | 195 | static int atk_read_value(struct atk_sensor_data *sensor, u64 *value); |
196 | static void atk_free_sensors(struct atk_data *data); | 196 | static void atk_free_sensors(struct atk_data *data); |
@@ -1416,7 +1416,7 @@ out: | |||
1416 | return err; | 1416 | return err; |
1417 | } | 1417 | } |
1418 | 1418 | ||
1419 | static int atk_remove(struct acpi_device *device, int type) | 1419 | static int atk_remove(struct acpi_device *device) |
1420 | { | 1420 | { |
1421 | struct atk_data *data = device->driver_data; | 1421 | struct atk_data *data = device->driver_data; |
1422 | dev_dbg(&device->dev, "removing...\n"); | 1422 | dev_dbg(&device->dev, "removing...\n"); |
diff --git a/drivers/i2c/busses/i2c-scmi.c b/drivers/i2c/busses/i2c-scmi.c index 6aafa3d88ff0..c447e8d40b78 100644 --- a/drivers/i2c/busses/i2c-scmi.c +++ b/drivers/i2c/busses/i2c-scmi.c | |||
@@ -406,7 +406,7 @@ err: | |||
406 | return -EIO; | 406 | return -EIO; |
407 | } | 407 | } |
408 | 408 | ||
409 | static int acpi_smbus_cmi_remove(struct acpi_device *device, int type) | 409 | static int acpi_smbus_cmi_remove(struct acpi_device *device) |
410 | { | 410 | { |
411 | struct acpi_smbus_cmi *smbus_cmi = acpi_driver_data(device); | 411 | struct acpi_smbus_cmi *smbus_cmi = acpi_driver_data(device); |
412 | 412 | ||
diff --git a/drivers/input/misc/atlas_btns.c b/drivers/input/misc/atlas_btns.c index 26f13131639a..5d4402365a52 100644 --- a/drivers/input/misc/atlas_btns.c +++ b/drivers/input/misc/atlas_btns.c | |||
@@ -121,7 +121,7 @@ static int atlas_acpi_button_add(struct acpi_device *device) | |||
121 | return err; | 121 | return err; |
122 | } | 122 | } |
123 | 123 | ||
124 | static int atlas_acpi_button_remove(struct acpi_device *device, int type) | 124 | static int atlas_acpi_button_remove(struct acpi_device *device) |
125 | { | 125 | { |
126 | acpi_status status; | 126 | acpi_status status; |
127 | 127 | ||
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 | ||
1297 | out: | 1299 | out: |
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/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c index fcde4e528819..d9f9a0dbc6f3 100644 --- a/drivers/platform/x86/asus-laptop.c +++ b/drivers/platform/x86/asus-laptop.c | |||
@@ -1910,7 +1910,7 @@ fail_platform: | |||
1910 | return result; | 1910 | return result; |
1911 | } | 1911 | } |
1912 | 1912 | ||
1913 | static int asus_acpi_remove(struct acpi_device *device, int type) | 1913 | static int asus_acpi_remove(struct acpi_device *device) |
1914 | { | 1914 | { |
1915 | struct asus_laptop *asus = acpi_driver_data(device); | 1915 | struct asus_laptop *asus = acpi_driver_data(device); |
1916 | 1916 | ||
diff --git a/drivers/platform/x86/classmate-laptop.c b/drivers/platform/x86/classmate-laptop.c index c87ff16873f9..36e5e6c13db4 100644 --- a/drivers/platform/x86/classmate-laptop.c +++ b/drivers/platform/x86/classmate-laptop.c | |||
@@ -432,7 +432,7 @@ failed_sensitivity: | |||
432 | return error; | 432 | return error; |
433 | } | 433 | } |
434 | 434 | ||
435 | static int cmpc_accel_remove_v4(struct acpi_device *acpi, int type) | 435 | static int cmpc_accel_remove_v4(struct acpi_device *acpi) |
436 | { | 436 | { |
437 | struct input_dev *inputdev; | 437 | struct input_dev *inputdev; |
438 | struct cmpc_accel *accel; | 438 | struct cmpc_accel *accel; |
@@ -668,7 +668,7 @@ failed_file: | |||
668 | return error; | 668 | return error; |
669 | } | 669 | } |
670 | 670 | ||
671 | static int cmpc_accel_remove(struct acpi_device *acpi, int type) | 671 | static int cmpc_accel_remove(struct acpi_device *acpi) |
672 | { | 672 | { |
673 | struct input_dev *inputdev; | 673 | struct input_dev *inputdev; |
674 | struct cmpc_accel *accel; | 674 | struct cmpc_accel *accel; |
@@ -753,7 +753,7 @@ static int cmpc_tablet_add(struct acpi_device *acpi) | |||
753 | cmpc_tablet_idev_init); | 753 | cmpc_tablet_idev_init); |
754 | } | 754 | } |
755 | 755 | ||
756 | static int cmpc_tablet_remove(struct acpi_device *acpi, int type) | 756 | static int cmpc_tablet_remove(struct acpi_device *acpi) |
757 | { | 757 | { |
758 | return cmpc_remove_acpi_notify_device(acpi); | 758 | return cmpc_remove_acpi_notify_device(acpi); |
759 | } | 759 | } |
@@ -1000,7 +1000,7 @@ out_bd: | |||
1000 | return retval; | 1000 | return retval; |
1001 | } | 1001 | } |
1002 | 1002 | ||
1003 | static int cmpc_ipml_remove(struct acpi_device *acpi, int type) | 1003 | static int cmpc_ipml_remove(struct acpi_device *acpi) |
1004 | { | 1004 | { |
1005 | struct ipml200_dev *ipml; | 1005 | struct ipml200_dev *ipml; |
1006 | 1006 | ||
@@ -1079,7 +1079,7 @@ static int cmpc_keys_add(struct acpi_device *acpi) | |||
1079 | cmpc_keys_idev_init); | 1079 | cmpc_keys_idev_init); |
1080 | } | 1080 | } |
1081 | 1081 | ||
1082 | static int cmpc_keys_remove(struct acpi_device *acpi, int type) | 1082 | static int cmpc_keys_remove(struct acpi_device *acpi) |
1083 | { | 1083 | { |
1084 | return cmpc_remove_acpi_notify_device(acpi); | 1084 | return cmpc_remove_acpi_notify_device(acpi); |
1085 | } | 1085 | } |
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index 528e9495458d..98935f945f53 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c | |||
@@ -1501,7 +1501,7 @@ fail_platform: | |||
1501 | return result; | 1501 | return result; |
1502 | } | 1502 | } |
1503 | 1503 | ||
1504 | static int eeepc_acpi_remove(struct acpi_device *device, int type) | 1504 | static int eeepc_acpi_remove(struct acpi_device *device) |
1505 | { | 1505 | { |
1506 | struct eeepc_laptop *eeepc = acpi_driver_data(device); | 1506 | struct eeepc_laptop *eeepc = acpi_driver_data(device); |
1507 | 1507 | ||
diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index c4c1a5444b38..1c9386e7c58c 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c | |||
@@ -733,7 +733,7 @@ err_stop: | |||
733 | return result; | 733 | return result; |
734 | } | 734 | } |
735 | 735 | ||
736 | static int acpi_fujitsu_remove(struct acpi_device *device, int type) | 736 | static int acpi_fujitsu_remove(struct acpi_device *device) |
737 | { | 737 | { |
738 | struct fujitsu_t *fujitsu = acpi_driver_data(device); | 738 | struct fujitsu_t *fujitsu = acpi_driver_data(device); |
739 | struct input_dev *input = fujitsu->input; | 739 | struct input_dev *input = fujitsu->input; |
@@ -938,7 +938,7 @@ err_stop: | |||
938 | return result; | 938 | return result; |
939 | } | 939 | } |
940 | 940 | ||
941 | static int acpi_fujitsu_hotkey_remove(struct acpi_device *device, int type) | 941 | static int acpi_fujitsu_hotkey_remove(struct acpi_device *device) |
942 | { | 942 | { |
943 | struct fujitsu_hotkey_t *fujitsu_hotkey = acpi_driver_data(device); | 943 | struct fujitsu_hotkey_t *fujitsu_hotkey = acpi_driver_data(device); |
944 | struct input_dev *input = fujitsu_hotkey->input; | 944 | struct input_dev *input = fujitsu_hotkey->input; |
diff --git a/drivers/platform/x86/fujitsu-tablet.c b/drivers/platform/x86/fujitsu-tablet.c index 174ca01c4aa7..570926c10014 100644 --- a/drivers/platform/x86/fujitsu-tablet.c +++ b/drivers/platform/x86/fujitsu-tablet.c | |||
@@ -431,7 +431,7 @@ static int acpi_fujitsu_add(struct acpi_device *adev) | |||
431 | return 0; | 431 | return 0; |
432 | } | 432 | } |
433 | 433 | ||
434 | static int acpi_fujitsu_remove(struct acpi_device *adev, int type) | 434 | static int acpi_fujitsu_remove(struct acpi_device *adev) |
435 | { | 435 | { |
436 | free_irq(fujitsu.irq, fujitsu_interrupt); | 436 | free_irq(fujitsu.irq, fujitsu_interrupt); |
437 | release_region(fujitsu.io_base, fujitsu.io_length); | 437 | release_region(fujitsu.io_base, fujitsu.io_length); |
diff --git a/drivers/platform/x86/hp_accel.c b/drivers/platform/x86/hp_accel.c index 18d74f29dcb2..e64a7a870d42 100644 --- a/drivers/platform/x86/hp_accel.c +++ b/drivers/platform/x86/hp_accel.c | |||
@@ -337,7 +337,7 @@ static int lis3lv02d_add(struct acpi_device *device) | |||
337 | return ret; | 337 | return ret; |
338 | } | 338 | } |
339 | 339 | ||
340 | static int lis3lv02d_remove(struct acpi_device *device, int type) | 340 | static int lis3lv02d_remove(struct acpi_device *device) |
341 | { | 341 | { |
342 | if (!device) | 342 | if (!device) |
343 | return -EINVAL; | 343 | return -EINVAL; |
diff --git a/drivers/platform/x86/ideapad-laptop.c b/drivers/platform/x86/ideapad-laptop.c index 64bfb30a52e9..17f00b8dc5cb 100644 --- a/drivers/platform/x86/ideapad-laptop.c +++ b/drivers/platform/x86/ideapad-laptop.c | |||
@@ -834,7 +834,7 @@ platform_failed: | |||
834 | return ret; | 834 | return ret; |
835 | } | 835 | } |
836 | 836 | ||
837 | static int ideapad_acpi_remove(struct acpi_device *adevice, int type) | 837 | static int ideapad_acpi_remove(struct acpi_device *adevice) |
838 | { | 838 | { |
839 | struct ideapad_private *priv = dev_get_drvdata(&adevice->dev); | 839 | struct ideapad_private *priv = dev_get_drvdata(&adevice->dev); |
840 | int i; | 840 | int i; |
diff --git a/drivers/platform/x86/intel_menlow.c b/drivers/platform/x86/intel_menlow.c index 3271ac85115e..d6cfc1558c2f 100644 --- a/drivers/platform/x86/intel_menlow.c +++ b/drivers/platform/x86/intel_menlow.c | |||
@@ -200,7 +200,7 @@ static int intel_menlow_memory_add(struct acpi_device *device) | |||
200 | 200 | ||
201 | } | 201 | } |
202 | 202 | ||
203 | static int intel_menlow_memory_remove(struct acpi_device *device, int type) | 203 | static int intel_menlow_memory_remove(struct acpi_device *device) |
204 | { | 204 | { |
205 | struct thermal_cooling_device *cdev = acpi_driver_data(device); | 205 | struct thermal_cooling_device *cdev = acpi_driver_data(device); |
206 | 206 | ||
diff --git a/drivers/platform/x86/panasonic-laptop.c b/drivers/platform/x86/panasonic-laptop.c index 8e8caa767d6a..4add9a31bf60 100644 --- a/drivers/platform/x86/panasonic-laptop.c +++ b/drivers/platform/x86/panasonic-laptop.c | |||
@@ -176,7 +176,7 @@ enum SINF_BITS { SINF_NUM_BATTERIES = 0, | |||
176 | /* R1 handles SINF_AC_CUR_BRIGHT as SINF_CUR_BRIGHT, doesn't know AC state */ | 176 | /* R1 handles SINF_AC_CUR_BRIGHT as SINF_CUR_BRIGHT, doesn't know AC state */ |
177 | 177 | ||
178 | static int acpi_pcc_hotkey_add(struct acpi_device *device); | 178 | static int acpi_pcc_hotkey_add(struct acpi_device *device); |
179 | static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type); | 179 | static int acpi_pcc_hotkey_remove(struct acpi_device *device); |
180 | static void acpi_pcc_hotkey_notify(struct acpi_device *device, u32 event); | 180 | static void acpi_pcc_hotkey_notify(struct acpi_device *device, u32 event); |
181 | 181 | ||
182 | static const struct acpi_device_id pcc_device_ids[] = { | 182 | static const struct acpi_device_id pcc_device_ids[] = { |
@@ -663,7 +663,7 @@ static int __init acpi_pcc_init(void) | |||
663 | return 0; | 663 | return 0; |
664 | } | 664 | } |
665 | 665 | ||
666 | static int acpi_pcc_hotkey_remove(struct acpi_device *device, int type) | 666 | static int acpi_pcc_hotkey_remove(struct acpi_device *device) |
667 | { | 667 | { |
668 | struct pcc_acpi *pcc = acpi_driver_data(device); | 668 | struct pcc_acpi *pcc = acpi_driver_data(device); |
669 | 669 | ||
diff --git a/drivers/platform/x86/sony-laptop.c b/drivers/platform/x86/sony-laptop.c index b8ad71f7863f..ceb41eff4230 100644 --- a/drivers/platform/x86/sony-laptop.c +++ b/drivers/platform/x86/sony-laptop.c | |||
@@ -2740,7 +2740,7 @@ outwalk: | |||
2740 | return result; | 2740 | return result; |
2741 | } | 2741 | } |
2742 | 2742 | ||
2743 | static int sony_nc_remove(struct acpi_device *device, int type) | 2743 | static int sony_nc_remove(struct acpi_device *device) |
2744 | { | 2744 | { |
2745 | struct sony_nc_value *item; | 2745 | struct sony_nc_value *item; |
2746 | 2746 | ||
@@ -4111,7 +4111,7 @@ found: | |||
4111 | * ACPI driver | 4111 | * ACPI driver |
4112 | * | 4112 | * |
4113 | *****************/ | 4113 | *****************/ |
4114 | static int sony_pic_remove(struct acpi_device *device, int type) | 4114 | static int sony_pic_remove(struct acpi_device *device) |
4115 | { | 4115 | { |
4116 | struct sony_pic_ioport *io, *tmp_io; | 4116 | struct sony_pic_ioport *io, *tmp_io; |
4117 | struct sony_pic_irq *irq, *tmp_irq; | 4117 | struct sony_pic_irq *irq, *tmp_irq; |
diff --git a/drivers/platform/x86/topstar-laptop.c b/drivers/platform/x86/topstar-laptop.c index d727bfee89a6..4ab618c63b45 100644 --- a/drivers/platform/x86/topstar-laptop.c +++ b/drivers/platform/x86/topstar-laptop.c | |||
@@ -157,7 +157,7 @@ add_err: | |||
157 | return -ENODEV; | 157 | return -ENODEV; |
158 | } | 158 | } |
159 | 159 | ||
160 | static int acpi_topstar_remove(struct acpi_device *device, int type) | 160 | static int acpi_topstar_remove(struct acpi_device *device) |
161 | { | 161 | { |
162 | struct topstar_hkey *tps_hkey = acpi_driver_data(device); | 162 | struct topstar_hkey *tps_hkey = acpi_driver_data(device); |
163 | 163 | ||
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index c2727895794c..904476b2fa8f 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c | |||
@@ -1118,7 +1118,7 @@ static int toshiba_acpi_setup_backlight(struct toshiba_acpi_dev *dev) | |||
1118 | return 0; | 1118 | return 0; |
1119 | } | 1119 | } |
1120 | 1120 | ||
1121 | static int toshiba_acpi_remove(struct acpi_device *acpi_dev, int type) | 1121 | static int toshiba_acpi_remove(struct acpi_device *acpi_dev) |
1122 | { | 1122 | { |
1123 | struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev); | 1123 | struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev); |
1124 | 1124 | ||
@@ -1250,7 +1250,7 @@ static int toshiba_acpi_add(struct acpi_device *acpi_dev) | |||
1250 | return 0; | 1250 | return 0; |
1251 | 1251 | ||
1252 | error: | 1252 | error: |
1253 | toshiba_acpi_remove(acpi_dev, 0); | 1253 | toshiba_acpi_remove(acpi_dev); |
1254 | return ret; | 1254 | return ret; |
1255 | } | 1255 | } |
1256 | 1256 | ||
diff --git a/drivers/platform/x86/toshiba_bluetooth.c b/drivers/platform/x86/toshiba_bluetooth.c index e95be0b74859..74dd01ae343b 100644 --- a/drivers/platform/x86/toshiba_bluetooth.c +++ b/drivers/platform/x86/toshiba_bluetooth.c | |||
@@ -32,7 +32,7 @@ MODULE_LICENSE("GPL"); | |||
32 | 32 | ||
33 | 33 | ||
34 | static int toshiba_bt_rfkill_add(struct acpi_device *device); | 34 | static int toshiba_bt_rfkill_add(struct acpi_device *device); |
35 | static int toshiba_bt_rfkill_remove(struct acpi_device *device, int type); | 35 | static int toshiba_bt_rfkill_remove(struct acpi_device *device); |
36 | static void toshiba_bt_rfkill_notify(struct acpi_device *device, u32 event); | 36 | static void toshiba_bt_rfkill_notify(struct acpi_device *device, u32 event); |
37 | 37 | ||
38 | static const struct acpi_device_id bt_device_ids[] = { | 38 | static const struct acpi_device_id bt_device_ids[] = { |
@@ -122,7 +122,7 @@ static int toshiba_bt_rfkill_add(struct acpi_device *device) | |||
122 | return result; | 122 | return result; |
123 | } | 123 | } |
124 | 124 | ||
125 | static int toshiba_bt_rfkill_remove(struct acpi_device *device, int type) | 125 | static int toshiba_bt_rfkill_remove(struct acpi_device *device) |
126 | { | 126 | { |
127 | /* clean up */ | 127 | /* clean up */ |
128 | return 0; | 128 | return 0; |
diff --git a/drivers/platform/x86/wmi.c b/drivers/platform/x86/wmi.c index 42a4dcc25f92..e4ac38aca580 100644 --- a/drivers/platform/x86/wmi.c +++ b/drivers/platform/x86/wmi.c | |||
@@ -92,7 +92,7 @@ module_param(debug_dump_wdg, bool, 0444); | |||
92 | MODULE_PARM_DESC(debug_dump_wdg, | 92 | MODULE_PARM_DESC(debug_dump_wdg, |
93 | "Dump available WMI interfaces [0/1]"); | 93 | "Dump available WMI interfaces [0/1]"); |
94 | 94 | ||
95 | static int acpi_wmi_remove(struct acpi_device *device, int type); | 95 | static int acpi_wmi_remove(struct acpi_device *device); |
96 | static int acpi_wmi_add(struct acpi_device *device); | 96 | static int acpi_wmi_add(struct acpi_device *device); |
97 | static void acpi_wmi_notify(struct acpi_device *device, u32 event); | 97 | static void acpi_wmi_notify(struct acpi_device *device, u32 event); |
98 | 98 | ||
@@ -917,7 +917,7 @@ static void acpi_wmi_notify(struct acpi_device *device, u32 event) | |||
917 | } | 917 | } |
918 | } | 918 | } |
919 | 919 | ||
920 | static int acpi_wmi_remove(struct acpi_device *device, int type) | 920 | static int acpi_wmi_remove(struct acpi_device *device) |
921 | { | 921 | { |
922 | acpi_remove_address_space_handler(device->handle, | 922 | acpi_remove_address_space_handler(device->handle, |
923 | ACPI_ADR_SPACE_EC, &acpi_wmi_ec_space_handler); | 923 | ACPI_ADR_SPACE_EC, &acpi_wmi_ec_space_handler); |
diff --git a/drivers/platform/x86/xo15-ebook.c b/drivers/platform/x86/xo15-ebook.c index 16d340c3b852..4b1377bd5944 100644 --- a/drivers/platform/x86/xo15-ebook.c +++ b/drivers/platform/x86/xo15-ebook.c | |||
@@ -150,7 +150,7 @@ static int ebook_switch_add(struct acpi_device *device) | |||
150 | return error; | 150 | return error; |
151 | } | 151 | } |
152 | 152 | ||
153 | static int ebook_switch_remove(struct acpi_device *device, int type) | 153 | static int ebook_switch_remove(struct acpi_device *device) |
154 | { | 154 | { |
155 | struct ebook_switch *button = acpi_driver_data(device); | 155 | struct ebook_switch *button = acpi_driver_data(device); |
156 | 156 | ||
diff --git a/drivers/staging/quickstart/quickstart.c b/drivers/staging/quickstart/quickstart.c index cac320738142..adb8da564cf6 100644 --- a/drivers/staging/quickstart/quickstart.c +++ b/drivers/staging/quickstart/quickstart.c | |||
@@ -296,7 +296,7 @@ fail_config: | |||
296 | return ret; | 296 | return ret; |
297 | } | 297 | } |
298 | 298 | ||
299 | static int quickstart_acpi_remove(struct acpi_device *device, int type) | 299 | static int quickstart_acpi_remove(struct acpi_device *device) |
300 | { | 300 | { |
301 | acpi_status status; | 301 | acpi_status status; |
302 | struct quickstart_acpi *quickstart; | 302 | struct quickstart_acpi *quickstart; |
diff --git a/drivers/video/backlight/apple_bl.c b/drivers/video/backlight/apple_bl.c index f088d4c07381..d84329676689 100644 --- a/drivers/video/backlight/apple_bl.c +++ b/drivers/video/backlight/apple_bl.c | |||
@@ -196,7 +196,7 @@ static int apple_bl_add(struct acpi_device *dev) | |||
196 | return 0; | 196 | return 0; |
197 | } | 197 | } |
198 | 198 | ||
199 | static int apple_bl_remove(struct acpi_device *dev, int type) | 199 | static int apple_bl_remove(struct acpi_device *dev) |
200 | { | 200 | { |
201 | backlight_device_unregister(apple_backlight_device); | 201 | backlight_device_unregister(apple_backlight_device); |
202 | 202 | ||
diff --git a/drivers/xen/xen-acpi-pad.c b/drivers/xen/xen-acpi-pad.c index da39191e7278..c763479ed85e 100644 --- a/drivers/xen/xen-acpi-pad.c +++ b/drivers/xen/xen-acpi-pad.c | |||
@@ -140,8 +140,7 @@ static int acpi_pad_add(struct acpi_device *device) | |||
140 | return 0; | 140 | return 0; |
141 | } | 141 | } |
142 | 142 | ||
143 | static int acpi_pad_remove(struct acpi_device *device, | 143 | static int acpi_pad_remove(struct acpi_device *device) |
144 | int type) | ||
145 | { | 144 | { |
146 | mutex_lock(&xen_cpu_lock); | 145 | mutex_lock(&xen_cpu_lock); |
147 | xen_acpi_pad_idle_cpus(0); | 146 | xen_acpi_pad_idle_cpus(0); |
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 36ed7e025bfc..227ba7dc293d 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h | |||
@@ -84,19 +84,29 @@ struct acpi_driver; | |||
84 | struct acpi_device; | 84 | struct acpi_device; |
85 | 85 | ||
86 | /* | 86 | /* |
87 | * ACPI Scan Handler | ||
88 | * ----------------- | ||
89 | */ | ||
90 | |||
91 | struct acpi_scan_handler { | ||
92 | const struct acpi_device_id *ids; | ||
93 | struct list_head list_node; | ||
94 | int (*attach)(struct acpi_device *dev, const struct acpi_device_id *id); | ||
95 | void (*detach)(struct acpi_device *dev); | ||
96 | }; | ||
97 | |||
98 | /* | ||
87 | * ACPI Driver | 99 | * ACPI Driver |
88 | * ----------- | 100 | * ----------- |
89 | */ | 101 | */ |
90 | 102 | ||
91 | typedef int (*acpi_op_add) (struct acpi_device * device); | 103 | typedef int (*acpi_op_add) (struct acpi_device * device); |
92 | typedef int (*acpi_op_remove) (struct acpi_device * device, int type); | 104 | typedef int (*acpi_op_remove) (struct acpi_device * device); |
93 | typedef int (*acpi_op_start) (struct acpi_device * device); | ||
94 | typedef void (*acpi_op_notify) (struct acpi_device * device, u32 event); | 105 | typedef void (*acpi_op_notify) (struct acpi_device * device, u32 event); |
95 | 106 | ||
96 | struct acpi_device_ops { | 107 | struct acpi_device_ops { |
97 | acpi_op_add add; | 108 | acpi_op_add add; |
98 | acpi_op_remove remove; | 109 | acpi_op_remove remove; |
99 | acpi_op_start start; | ||
100 | acpi_op_notify notify; | 110 | acpi_op_notify notify; |
101 | }; | 111 | }; |
102 | 112 | ||
@@ -271,6 +281,7 @@ struct acpi_device { | |||
271 | struct acpi_device_wakeup wakeup; | 281 | struct acpi_device_wakeup wakeup; |
272 | struct acpi_device_perf performance; | 282 | struct acpi_device_perf performance; |
273 | struct acpi_device_dir dir; | 283 | struct acpi_device_dir dir; |
284 | struct acpi_scan_handler *handler; | ||
274 | struct acpi_driver *driver; | 285 | struct acpi_driver *driver; |
275 | void *driver_data; | 286 | void *driver_data; |
276 | struct device dev; | 287 | struct device dev; |
@@ -384,6 +395,10 @@ int acpi_bus_receive_event(struct acpi_bus_event *event); | |||
384 | static inline int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data) | 395 | static inline int acpi_bus_generate_proc_event(struct acpi_device *device, u8 type, int data) |
385 | { return 0; } | 396 | { return 0; } |
386 | #endif | 397 | #endif |
398 | |||
399 | void acpi_scan_lock_acquire(void); | ||
400 | void acpi_scan_lock_release(void); | ||
401 | int acpi_scan_add_handler(struct acpi_scan_handler *handler); | ||
387 | int acpi_bus_register_driver(struct acpi_driver *driver); | 402 | int acpi_bus_register_driver(struct acpi_driver *driver); |
388 | void acpi_bus_unregister_driver(struct acpi_driver *driver); | 403 | void acpi_bus_unregister_driver(struct acpi_driver *driver); |
389 | int acpi_bus_scan(acpi_handle handle); | 404 | int acpi_bus_scan(acpi_handle handle); |
diff --git a/include/acpi/container.h b/include/acpi/container.h deleted file mode 100644 index a703f14e049e..000000000000 --- a/include/acpi/container.h +++ /dev/null | |||
@@ -1,12 +0,0 @@ | |||
1 | #ifndef __ACPI_CONTAINER_H | ||
2 | #define __ACPI_CONTAINER_H | ||
3 | |||
4 | #include <linux/kernel.h> | ||
5 | |||
6 | struct acpi_container { | ||
7 | acpi_handle handle; | ||
8 | unsigned long sun; | ||
9 | int state; | ||
10 | }; | ||
11 | |||
12 | #endif /* __ACPI_CONTAINER_H */ | ||
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index c6ccd9fa8f08..bcbdd7484e58 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -363,8 +363,7 @@ extern acpi_status acpi_pci_osc_control_set(acpi_handle handle, | |||
363 | #if defined(CONFIG_ACPI_HOTPLUG_CPU) && \ | 363 | #if defined(CONFIG_ACPI_HOTPLUG_CPU) && \ |
364 | (defined(CONFIG_ACPI_HOTPLUG_MEMORY) || \ | 364 | (defined(CONFIG_ACPI_HOTPLUG_MEMORY) || \ |
365 | defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE)) && \ | 365 | defined(CONFIG_ACPI_HOTPLUG_MEMORY_MODULE)) && \ |
366 | (defined(CONFIG_ACPI_CONTAINER) || \ | 366 | defined(CONFIG_ACPI_CONTAINER) |
367 | defined(CONFIG_ACPI_CONTAINER_MODULE)) | ||
368 | #define ACPI_HOTPLUG_OST | 367 | #define ACPI_HOTPLUG_OST |
369 | #endif | 368 | #endif |
370 | 369 | ||