diff options
-rw-r--r-- | Documentation/ABI/testing/sysfs-devices-sun | 14 | ||||
-rw-r--r-- | arch/x86/kernel/acpi/sleep.c | 2 | ||||
-rw-r--r-- | drivers/acpi/acpi_memhotplug.c | 193 | ||||
-rw-r--r-- | drivers/acpi/acpi_pad.c | 8 | ||||
-rw-r--r-- | drivers/acpi/apei/ghes.c | 2 | ||||
-rw-r--r-- | drivers/acpi/battery.c | 77 | ||||
-rw-r--r-- | drivers/acpi/container.c | 27 | ||||
-rw-r--r-- | drivers/acpi/dock.c | 56 | ||||
-rw-r--r-- | drivers/acpi/ec.c | 97 | ||||
-rw-r--r-- | drivers/acpi/hed.c | 2 | ||||
-rw-r--r-- | drivers/acpi/internal.h | 4 | ||||
-rw-r--r-- | drivers/acpi/osl.c | 22 | ||||
-rw-r--r-- | drivers/acpi/pci_irq.c | 10 | ||||
-rw-r--r-- | drivers/acpi/power.c | 2 | ||||
-rw-r--r-- | drivers/acpi/proc.c | 11 | ||||
-rw-r--r-- | drivers/acpi/processor_driver.c | 74 | ||||
-rw-r--r-- | drivers/acpi/scan.c | 68 | ||||
-rw-r--r-- | drivers/acpi/sleep.c | 25 | ||||
-rw-r--r-- | drivers/acpi/thermal.c | 34 | ||||
-rw-r--r-- | drivers/acpi/utils.c | 38 | ||||
-rw-r--r-- | include/acpi/acpi_bus.h | 4 | ||||
-rw-r--r-- | include/linux/acpi.h | 49 | ||||
-rw-r--r-- | kernel/cpu.c | 8 |
23 files changed, 566 insertions, 261 deletions
diff --git a/Documentation/ABI/testing/sysfs-devices-sun b/Documentation/ABI/testing/sysfs-devices-sun new file mode 100644 index 000000000000..86be9848a77e --- /dev/null +++ b/Documentation/ABI/testing/sysfs-devices-sun | |||
@@ -0,0 +1,14 @@ | |||
1 | Whatt: /sys/devices/.../sun | ||
2 | Date: October 2012 | ||
3 | Contact: Yasuaki Ishimatsu <isimatu.yasuaki@jp.fujitsu.com> | ||
4 | Description: | ||
5 | The file contains a Slot-unique ID which provided by the _SUN | ||
6 | method in the ACPI namespace. The value is written in Advanced | ||
7 | Configuration and Power Interface Specification as follows: | ||
8 | |||
9 | "The _SUN value is required to be unique among the slots of | ||
10 | the same type. It is also recommended that this number match | ||
11 | the slot number printed on the physical slot whenever possible." | ||
12 | |||
13 | So reading the sysfs file, we can identify a physical position | ||
14 | of the slot in the system. | ||
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index 11676cf65aee..d5e0d717005a 100644 --- a/arch/x86/kernel/acpi/sleep.c +++ b/arch/x86/kernel/acpi/sleep.c | |||
@@ -101,6 +101,8 @@ static int __init acpi_sleep_setup(char *str) | |||
101 | #endif | 101 | #endif |
102 | if (strncmp(str, "nonvs", 5) == 0) | 102 | if (strncmp(str, "nonvs", 5) == 0) |
103 | acpi_nvs_nosave(); | 103 | acpi_nvs_nosave(); |
104 | if (strncmp(str, "nonvs_s3", 8) == 0) | ||
105 | acpi_nvs_nosave_s3(); | ||
104 | if (strncmp(str, "old_ordering", 12) == 0) | 106 | if (strncmp(str, "old_ordering", 12) == 0) |
105 | acpi_old_suspend_ordering(); | 107 | acpi_old_suspend_ordering(); |
106 | str = strchr(str, ','); | 108 | str = strchr(str, ','); |
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c index 24c807f96636..eb30e5ab4cab 100644 --- a/drivers/acpi/acpi_memhotplug.c +++ b/drivers/acpi/acpi_memhotplug.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/types.h> | 31 | #include <linux/types.h> |
32 | #include <linux/memory_hotplug.h> | 32 | #include <linux/memory_hotplug.h> |
33 | #include <linux/slab.h> | 33 | #include <linux/slab.h> |
34 | #include <linux/acpi.h> | ||
34 | #include <acpi/acpi_drivers.h> | 35 | #include <acpi/acpi_drivers.h> |
35 | 36 | ||
36 | #define ACPI_MEMORY_DEVICE_CLASS "memory" | 37 | #define ACPI_MEMORY_DEVICE_CLASS "memory" |
@@ -78,6 +79,7 @@ struct acpi_memory_info { | |||
78 | unsigned short caching; /* memory cache attribute */ | 79 | unsigned short caching; /* memory cache attribute */ |
79 | unsigned short write_protect; /* memory read/write attribute */ | 80 | unsigned short write_protect; /* memory read/write attribute */ |
80 | unsigned int enabled:1; | 81 | unsigned int enabled:1; |
82 | unsigned int failed:1; | ||
81 | }; | 83 | }; |
82 | 84 | ||
83 | struct acpi_memory_device { | 85 | struct acpi_memory_device { |
@@ -86,8 +88,6 @@ struct acpi_memory_device { | |||
86 | struct list_head res_list; | 88 | struct list_head res_list; |
87 | }; | 89 | }; |
88 | 90 | ||
89 | static int acpi_hotmem_initialized; | ||
90 | |||
91 | static acpi_status | 91 | static acpi_status |
92 | acpi_memory_get_resource(struct acpi_resource *resource, void *context) | 92 | acpi_memory_get_resource(struct acpi_resource *resource, void *context) |
93 | { | 93 | { |
@@ -125,12 +125,20 @@ acpi_memory_get_resource(struct acpi_resource *resource, void *context) | |||
125 | return AE_OK; | 125 | return AE_OK; |
126 | } | 126 | } |
127 | 127 | ||
128 | static void | ||
129 | acpi_memory_free_device_resources(struct acpi_memory_device *mem_device) | ||
130 | { | ||
131 | struct acpi_memory_info *info, *n; | ||
132 | |||
133 | list_for_each_entry_safe(info, n, &mem_device->res_list, list) | ||
134 | kfree(info); | ||
135 | INIT_LIST_HEAD(&mem_device->res_list); | ||
136 | } | ||
137 | |||
128 | static int | 138 | static int |
129 | acpi_memory_get_device_resources(struct acpi_memory_device *mem_device) | 139 | acpi_memory_get_device_resources(struct acpi_memory_device *mem_device) |
130 | { | 140 | { |
131 | acpi_status status; | 141 | acpi_status status; |
132 | struct acpi_memory_info *info, *n; | ||
133 | |||
134 | 142 | ||
135 | if (!list_empty(&mem_device->res_list)) | 143 | if (!list_empty(&mem_device->res_list)) |
136 | return 0; | 144 | return 0; |
@@ -138,9 +146,7 @@ acpi_memory_get_device_resources(struct acpi_memory_device *mem_device) | |||
138 | status = acpi_walk_resources(mem_device->device->handle, METHOD_NAME__CRS, | 146 | status = acpi_walk_resources(mem_device->device->handle, METHOD_NAME__CRS, |
139 | acpi_memory_get_resource, mem_device); | 147 | acpi_memory_get_resource, mem_device); |
140 | if (ACPI_FAILURE(status)) { | 148 | if (ACPI_FAILURE(status)) { |
141 | list_for_each_entry_safe(info, n, &mem_device->res_list, list) | 149 | acpi_memory_free_device_resources(mem_device); |
142 | kfree(info); | ||
143 | INIT_LIST_HEAD(&mem_device->res_list); | ||
144 | return -EINVAL; | 150 | return -EINVAL; |
145 | } | 151 | } |
146 | 152 | ||
@@ -170,7 +176,7 @@ acpi_memory_get_device(acpi_handle handle, | |||
170 | /* Get the parent device */ | 176 | /* Get the parent device */ |
171 | result = acpi_bus_get_device(phandle, &pdevice); | 177 | result = acpi_bus_get_device(phandle, &pdevice); |
172 | if (result) { | 178 | if (result) { |
173 | printk(KERN_WARNING PREFIX "Cannot get acpi bus device"); | 179 | acpi_handle_warn(phandle, "Cannot get acpi bus device\n"); |
174 | return -EINVAL; | 180 | return -EINVAL; |
175 | } | 181 | } |
176 | 182 | ||
@@ -180,14 +186,14 @@ acpi_memory_get_device(acpi_handle handle, | |||
180 | */ | 186 | */ |
181 | result = acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE); | 187 | result = acpi_bus_add(&device, pdevice, handle, ACPI_BUS_TYPE_DEVICE); |
182 | if (result) { | 188 | if (result) { |
183 | printk(KERN_WARNING PREFIX "Cannot add acpi bus"); | 189 | acpi_handle_warn(handle, "Cannot add acpi bus\n"); |
184 | return -EINVAL; | 190 | return -EINVAL; |
185 | } | 191 | } |
186 | 192 | ||
187 | end: | 193 | end: |
188 | *mem_device = acpi_driver_data(device); | 194 | *mem_device = acpi_driver_data(device); |
189 | if (!(*mem_device)) { | 195 | if (!(*mem_device)) { |
190 | printk(KERN_ERR "\n driver data not found"); | 196 | dev_err(&device->dev, "driver data not found\n"); |
191 | return -ENODEV; | 197 | return -ENODEV; |
192 | } | 198 | } |
193 | 199 | ||
@@ -224,7 +230,8 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device) | |||
224 | /* Get the range from the _CRS */ | 230 | /* Get the range from the _CRS */ |
225 | result = acpi_memory_get_device_resources(mem_device); | 231 | result = acpi_memory_get_device_resources(mem_device); |
226 | if (result) { | 232 | if (result) { |
227 | printk(KERN_ERR PREFIX "get_device_resources failed\n"); | 233 | dev_err(&mem_device->device->dev, |
234 | "get_device_resources failed\n"); | ||
228 | mem_device->state = MEMORY_INVALID_STATE; | 235 | mem_device->state = MEMORY_INVALID_STATE; |
229 | return result; | 236 | return result; |
230 | } | 237 | } |
@@ -251,13 +258,27 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device) | |||
251 | node = memory_add_physaddr_to_nid(info->start_addr); | 258 | node = memory_add_physaddr_to_nid(info->start_addr); |
252 | 259 | ||
253 | result = add_memory(node, info->start_addr, info->length); | 260 | result = add_memory(node, info->start_addr, info->length); |
254 | if (result) | 261 | |
262 | /* | ||
263 | * If the memory block has been used by the kernel, add_memory() | ||
264 | * returns -EEXIST. If add_memory() returns the other error, it | ||
265 | * means that this memory block is not used by the kernel. | ||
266 | */ | ||
267 | if (result && result != -EEXIST) { | ||
268 | info->failed = 1; | ||
255 | continue; | 269 | continue; |
256 | info->enabled = 1; | 270 | } |
271 | |||
272 | if (!result) | ||
273 | info->enabled = 1; | ||
274 | /* | ||
275 | * Add num_enable even if add_memory() returns -EEXIST, so the | ||
276 | * device is bound to this driver. | ||
277 | */ | ||
257 | num_enabled++; | 278 | num_enabled++; |
258 | } | 279 | } |
259 | if (!num_enabled) { | 280 | if (!num_enabled) { |
260 | printk(KERN_ERR PREFIX "add_memory failed\n"); | 281 | dev_err(&mem_device->device->dev, "add_memory failed\n"); |
261 | mem_device->state = MEMORY_INVALID_STATE; | 282 | mem_device->state = MEMORY_INVALID_STATE; |
262 | return -EINVAL; | 283 | return -EINVAL; |
263 | } | 284 | } |
@@ -272,68 +293,31 @@ static int acpi_memory_enable_device(struct acpi_memory_device *mem_device) | |||
272 | return 0; | 293 | return 0; |
273 | } | 294 | } |
274 | 295 | ||
275 | static int acpi_memory_powerdown_device(struct acpi_memory_device *mem_device) | 296 | static int acpi_memory_remove_memory(struct acpi_memory_device *mem_device) |
276 | { | 297 | { |
277 | acpi_status status; | 298 | int result = 0; |
278 | struct acpi_object_list arg_list; | 299 | struct acpi_memory_info *info, *n; |
279 | union acpi_object arg; | ||
280 | unsigned long long current_status; | ||
281 | |||
282 | |||
283 | /* Issue the _EJ0 command */ | ||
284 | arg_list.count = 1; | ||
285 | arg_list.pointer = &arg; | ||
286 | arg.type = ACPI_TYPE_INTEGER; | ||
287 | arg.integer.value = 1; | ||
288 | status = acpi_evaluate_object(mem_device->device->handle, | ||
289 | "_EJ0", &arg_list, NULL); | ||
290 | /* Return on _EJ0 failure */ | ||
291 | if (ACPI_FAILURE(status)) { | ||
292 | ACPI_EXCEPTION((AE_INFO, status, "_EJ0 failed")); | ||
293 | return -ENODEV; | ||
294 | } | ||
295 | |||
296 | /* Evalute _STA to check if the device is disabled */ | ||
297 | status = acpi_evaluate_integer(mem_device->device->handle, "_STA", | ||
298 | NULL, ¤t_status); | ||
299 | if (ACPI_FAILURE(status)) | ||
300 | return -ENODEV; | ||
301 | |||
302 | /* Check for device status. Device should be disabled */ | ||
303 | if (current_status & ACPI_STA_DEVICE_ENABLED) | ||
304 | return -EINVAL; | ||
305 | 300 | ||
306 | return 0; | 301 | list_for_each_entry_safe(info, n, &mem_device->res_list, list) { |
307 | } | 302 | if (info->failed) |
303 | /* The kernel does not use this memory block */ | ||
304 | continue; | ||
308 | 305 | ||
309 | static int acpi_memory_disable_device(struct acpi_memory_device *mem_device) | 306 | if (!info->enabled) |
310 | { | 307 | /* |
311 | int result; | 308 | * The kernel uses this memory block, but it may be not |
312 | struct acpi_memory_info *info, *n; | 309 | * managed by us. |
310 | */ | ||
311 | return -EBUSY; | ||
313 | 312 | ||
313 | result = remove_memory(info->start_addr, info->length); | ||
314 | if (result) | ||
315 | return result; | ||
314 | 316 | ||
315 | /* | 317 | list_del(&info->list); |
316 | * Ask the VM to offline this memory range. | ||
317 | * Note: Assume that this function returns zero on success | ||
318 | */ | ||
319 | list_for_each_entry_safe(info, n, &mem_device->res_list, list) { | ||
320 | if (info->enabled) { | ||
321 | result = remove_memory(info->start_addr, info->length); | ||
322 | if (result) | ||
323 | return result; | ||
324 | } | ||
325 | kfree(info); | 318 | kfree(info); |
326 | } | 319 | } |
327 | 320 | ||
328 | /* Power-off and eject the device */ | ||
329 | result = acpi_memory_powerdown_device(mem_device); | ||
330 | if (result) { | ||
331 | /* Set the status of the device to invalid */ | ||
332 | mem_device->state = MEMORY_INVALID_STATE; | ||
333 | return result; | ||
334 | } | ||
335 | |||
336 | mem_device->state = MEMORY_POWER_OFF_STATE; | ||
337 | return result; | 321 | return result; |
338 | } | 322 | } |
339 | 323 | ||
@@ -341,6 +325,7 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data) | |||
341 | { | 325 | { |
342 | struct acpi_memory_device *mem_device; | 326 | struct acpi_memory_device *mem_device; |
343 | struct acpi_device *device; | 327 | struct acpi_device *device; |
328 | struct acpi_eject_event *ej_event = NULL; | ||
344 | u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */ | 329 | u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */ |
345 | 330 | ||
346 | switch (event) { | 331 | switch (event) { |
@@ -353,7 +338,7 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data) | |||
353 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 338 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
354 | "\nReceived DEVICE CHECK notification for device\n")); | 339 | "\nReceived DEVICE CHECK notification for device\n")); |
355 | if (acpi_memory_get_device(handle, &mem_device)) { | 340 | if (acpi_memory_get_device(handle, &mem_device)) { |
356 | printk(KERN_ERR PREFIX "Cannot find driver data\n"); | 341 | acpi_handle_err(handle, "Cannot find driver data\n"); |
357 | break; | 342 | break; |
358 | } | 343 | } |
359 | 344 | ||
@@ -361,7 +346,7 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data) | |||
361 | break; | 346 | break; |
362 | 347 | ||
363 | if (acpi_memory_enable_device(mem_device)) { | 348 | if (acpi_memory_enable_device(mem_device)) { |
364 | printk(KERN_ERR PREFIX "Cannot enable memory device\n"); | 349 | acpi_handle_err(handle,"Cannot enable memory device\n"); |
365 | break; | 350 | break; |
366 | } | 351 | } |
367 | 352 | ||
@@ -373,40 +358,28 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data) | |||
373 | "\nReceived EJECT REQUEST notification for device\n")); | 358 | "\nReceived EJECT REQUEST notification for device\n")); |
374 | 359 | ||
375 | if (acpi_bus_get_device(handle, &device)) { | 360 | if (acpi_bus_get_device(handle, &device)) { |
376 | printk(KERN_ERR PREFIX "Device doesn't exist\n"); | 361 | acpi_handle_err(handle, "Device doesn't exist\n"); |
377 | break; | 362 | break; |
378 | } | 363 | } |
379 | mem_device = acpi_driver_data(device); | 364 | mem_device = acpi_driver_data(device); |
380 | if (!mem_device) { | 365 | if (!mem_device) { |
381 | printk(KERN_ERR PREFIX "Driver Data is NULL\n"); | 366 | acpi_handle_err(handle, "Driver Data is NULL\n"); |
382 | break; | 367 | break; |
383 | } | 368 | } |
384 | 369 | ||
385 | /* | 370 | ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL); |
386 | * Currently disabling memory device from kernel mode | 371 | if (!ej_event) { |
387 | * TBD: Can also be disabled from user mode scripts | 372 | pr_err(PREFIX "No memory, dropping EJECT\n"); |
388 | * TBD: Can also be disabled by Callback registration | ||
389 | * with generic sysfs driver | ||
390 | */ | ||
391 | if (acpi_memory_disable_device(mem_device)) { | ||
392 | printk(KERN_ERR PREFIX "Disable memory device\n"); | ||
393 | /* | ||
394 | * If _EJ0 was called but failed, _OST is not | ||
395 | * necessary. | ||
396 | */ | ||
397 | if (mem_device->state == MEMORY_INVALID_STATE) | ||
398 | return; | ||
399 | |||
400 | break; | 373 | break; |
401 | } | 374 | } |
402 | 375 | ||
403 | /* | 376 | ej_event->handle = handle; |
404 | * TBD: Invoke acpi_bus_remove to cleanup data structures | 377 | ej_event->event = ACPI_NOTIFY_EJECT_REQUEST; |
405 | */ | 378 | acpi_os_hotplug_execute(acpi_bus_hot_remove_device, |
379 | (void *)ej_event); | ||
406 | 380 | ||
407 | /* _EJ0 succeeded; _OST is not necessary */ | 381 | /* eject is performed asynchronously */ |
408 | return; | 382 | return; |
409 | |||
410 | default: | 383 | default: |
411 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 384 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
412 | "Unsupported event [0x%x]\n", event)); | 385 | "Unsupported event [0x%x]\n", event)); |
@@ -420,6 +393,15 @@ static void acpi_memory_device_notify(acpi_handle handle, u32 event, void *data) | |||
420 | return; | 393 | return; |
421 | } | 394 | } |
422 | 395 | ||
396 | static void acpi_memory_device_free(struct acpi_memory_device *mem_device) | ||
397 | { | ||
398 | if (!mem_device) | ||
399 | return; | ||
400 | |||
401 | acpi_memory_free_device_resources(mem_device); | ||
402 | kfree(mem_device); | ||
403 | } | ||
404 | |||
423 | static int acpi_memory_device_add(struct acpi_device *device) | 405 | static int acpi_memory_device_add(struct acpi_device *device) |
424 | { | 406 | { |
425 | int result; | 407 | int result; |
@@ -449,23 +431,16 @@ static int acpi_memory_device_add(struct acpi_device *device) | |||
449 | /* Set the device state */ | 431 | /* Set the device state */ |
450 | mem_device->state = MEMORY_POWER_ON_STATE; | 432 | mem_device->state = MEMORY_POWER_ON_STATE; |
451 | 433 | ||
452 | printk(KERN_DEBUG "%s \n", acpi_device_name(device)); | 434 | pr_debug("%s\n", acpi_device_name(device)); |
453 | |||
454 | /* | ||
455 | * Early boot code has recognized memory area by EFI/E820. | ||
456 | * If DSDT shows these memory devices on boot, hotplug is not necessary | ||
457 | * for them. So, it just returns until completion of this driver's | ||
458 | * start up. | ||
459 | */ | ||
460 | if (!acpi_hotmem_initialized) | ||
461 | return 0; | ||
462 | 435 | ||
463 | if (!acpi_memory_check_device(mem_device)) { | 436 | if (!acpi_memory_check_device(mem_device)) { |
464 | /* call add_memory func */ | 437 | /* call add_memory func */ |
465 | result = acpi_memory_enable_device(mem_device); | 438 | result = acpi_memory_enable_device(mem_device); |
466 | if (result) | 439 | if (result) { |
467 | printk(KERN_ERR PREFIX | 440 | dev_err(&device->dev, |
468 | "Error in acpi_memory_enable_device\n"); | 441 | "Error in acpi_memory_enable_device\n"); |
442 | acpi_memory_device_free(mem_device); | ||
443 | } | ||
469 | } | 444 | } |
470 | return result; | 445 | return result; |
471 | } | 446 | } |
@@ -473,13 +448,18 @@ static int acpi_memory_device_add(struct acpi_device *device) | |||
473 | static int acpi_memory_device_remove(struct acpi_device *device, int type) | 448 | static int acpi_memory_device_remove(struct acpi_device *device, int type) |
474 | { | 449 | { |
475 | struct acpi_memory_device *mem_device = NULL; | 450 | struct acpi_memory_device *mem_device = NULL; |
476 | 451 | int result; | |
477 | 452 | ||
478 | if (!device || !acpi_driver_data(device)) | 453 | if (!device || !acpi_driver_data(device)) |
479 | return -EINVAL; | 454 | return -EINVAL; |
480 | 455 | ||
481 | mem_device = acpi_driver_data(device); | 456 | mem_device = acpi_driver_data(device); |
482 | kfree(mem_device); | 457 | |
458 | result = acpi_memory_remove_memory(mem_device); | ||
459 | if (result) | ||
460 | return result; | ||
461 | |||
462 | acpi_memory_device_free(mem_device); | ||
483 | 463 | ||
484 | return 0; | 464 | return 0; |
485 | } | 465 | } |
@@ -568,7 +548,6 @@ static int __init acpi_memory_device_init(void) | |||
568 | return -ENODEV; | 548 | return -ENODEV; |
569 | } | 549 | } |
570 | 550 | ||
571 | acpi_hotmem_initialized = 1; | ||
572 | return 0; | 551 | return 0; |
573 | } | 552 | } |
574 | 553 | ||
diff --git a/drivers/acpi/acpi_pad.c b/drivers/acpi/acpi_pad.c index af4aad6ee2eb..16fa979f7180 100644 --- a/drivers/acpi/acpi_pad.c +++ b/drivers/acpi/acpi_pad.c | |||
@@ -286,7 +286,7 @@ static ssize_t acpi_pad_rrtime_store(struct device *dev, | |||
286 | struct device_attribute *attr, const char *buf, size_t count) | 286 | struct device_attribute *attr, const char *buf, size_t count) |
287 | { | 287 | { |
288 | unsigned long num; | 288 | unsigned long num; |
289 | if (strict_strtoul(buf, 0, &num)) | 289 | if (kstrtoul(buf, 0, &num)) |
290 | return -EINVAL; | 290 | return -EINVAL; |
291 | if (num < 1 || num >= 100) | 291 | if (num < 1 || num >= 100) |
292 | return -EINVAL; | 292 | return -EINVAL; |
@@ -309,7 +309,7 @@ static ssize_t acpi_pad_idlepct_store(struct device *dev, | |||
309 | struct device_attribute *attr, const char *buf, size_t count) | 309 | struct device_attribute *attr, const char *buf, size_t count) |
310 | { | 310 | { |
311 | unsigned long num; | 311 | unsigned long num; |
312 | if (strict_strtoul(buf, 0, &num)) | 312 | if (kstrtoul(buf, 0, &num)) |
313 | return -EINVAL; | 313 | return -EINVAL; |
314 | if (num < 1 || num >= 100) | 314 | if (num < 1 || num >= 100) |
315 | return -EINVAL; | 315 | return -EINVAL; |
@@ -332,7 +332,7 @@ static ssize_t acpi_pad_idlecpus_store(struct device *dev, | |||
332 | struct device_attribute *attr, const char *buf, size_t count) | 332 | struct device_attribute *attr, const char *buf, size_t count) |
333 | { | 333 | { |
334 | unsigned long num; | 334 | unsigned long num; |
335 | if (strict_strtoul(buf, 0, &num)) | 335 | if (kstrtoul(buf, 0, &num)) |
336 | return -EINVAL; | 336 | return -EINVAL; |
337 | mutex_lock(&isolated_cpus_lock); | 337 | mutex_lock(&isolated_cpus_lock); |
338 | acpi_pad_idle_cpus(num); | 338 | acpi_pad_idle_cpus(num); |
@@ -457,7 +457,7 @@ static void acpi_pad_notify(acpi_handle handle, u32 event, | |||
457 | dev_name(&device->dev), event, 0); | 457 | dev_name(&device->dev), event, 0); |
458 | break; | 458 | break; |
459 | default: | 459 | default: |
460 | printk(KERN_WARNING "Unsupported event [0x%x]\n", event); | 460 | pr_warn("Unsupported event [0x%x]\n", event); |
461 | break; | 461 | break; |
462 | } | 462 | } |
463 | } | 463 | } |
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index 1599566ed1fe..da93c003e953 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c | |||
@@ -994,7 +994,7 @@ err: | |||
994 | return rc; | 994 | return rc; |
995 | } | 995 | } |
996 | 996 | ||
997 | static int __devexit ghes_remove(struct platform_device *ghes_dev) | 997 | static int ghes_remove(struct platform_device *ghes_dev) |
998 | { | 998 | { |
999 | struct ghes *ghes; | 999 | struct ghes *ghes; |
1000 | struct acpi_hest_generic *generic; | 1000 | struct acpi_hest_generic *generic; |
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c index 45e3e1759fb8..7efaeaa53b88 100644 --- a/drivers/acpi/battery.c +++ b/drivers/acpi/battery.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/dmi.h> | 34 | #include <linux/dmi.h> |
35 | #include <linux/slab.h> | 35 | #include <linux/slab.h> |
36 | #include <linux/suspend.h> | 36 | #include <linux/suspend.h> |
37 | #include <asm/unaligned.h> | ||
37 | 38 | ||
38 | #ifdef CONFIG_ACPI_PROCFS_POWER | 39 | #ifdef CONFIG_ACPI_PROCFS_POWER |
39 | #include <linux/proc_fs.h> | 40 | #include <linux/proc_fs.h> |
@@ -95,6 +96,18 @@ enum { | |||
95 | ACPI_BATTERY_ALARM_PRESENT, | 96 | ACPI_BATTERY_ALARM_PRESENT, |
96 | ACPI_BATTERY_XINFO_PRESENT, | 97 | ACPI_BATTERY_XINFO_PRESENT, |
97 | ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, | 98 | ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, |
99 | /* On Lenovo Thinkpad models from 2010 and 2011, the power unit | ||
100 | switches between mWh and mAh depending on whether the system | ||
101 | is running on battery or not. When mAh is the unit, most | ||
102 | reported values are incorrect and need to be adjusted by | ||
103 | 10000/design_voltage. Verified on x201, t410, t410s, and x220. | ||
104 | Pre-2010 and 2012 models appear to always report in mWh and | ||
105 | are thus unaffected (tested with t42, t61, t500, x200, x300, | ||
106 | and x230). Also, in mid-2012 Lenovo issued a BIOS update for | ||
107 | the 2011 models that fixes the issue (tested on x220 with a | ||
108 | post-1.29 BIOS), but as of Nov. 2012, no such update is | ||
109 | available for the 2010 models. */ | ||
110 | ACPI_BATTERY_QUIRK_THINKPAD_MAH, | ||
98 | }; | 111 | }; |
99 | 112 | ||
100 | struct acpi_battery { | 113 | struct acpi_battery { |
@@ -438,6 +451,21 @@ static int acpi_battery_get_info(struct acpi_battery *battery) | |||
438 | kfree(buffer.pointer); | 451 | kfree(buffer.pointer); |
439 | if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)) | 452 | if (test_bit(ACPI_BATTERY_QUIRK_PERCENTAGE_CAPACITY, &battery->flags)) |
440 | battery->full_charge_capacity = battery->design_capacity; | 453 | battery->full_charge_capacity = battery->design_capacity; |
454 | if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags) && | ||
455 | battery->power_unit && battery->design_voltage) { | ||
456 | battery->design_capacity = battery->design_capacity * | ||
457 | 10000 / battery->design_voltage; | ||
458 | battery->full_charge_capacity = battery->full_charge_capacity * | ||
459 | 10000 / battery->design_voltage; | ||
460 | battery->design_capacity_warning = | ||
461 | battery->design_capacity_warning * | ||
462 | 10000 / battery->design_voltage; | ||
463 | /* Curiously, design_capacity_low, unlike the rest of them, | ||
464 | is correct. */ | ||
465 | /* capacity_granularity_* equal 1 on the systems tested, so | ||
466 | it's impossible to tell if they would need an adjustment | ||
467 | or not if their values were higher. */ | ||
468 | } | ||
441 | return result; | 469 | return result; |
442 | } | 470 | } |
443 | 471 | ||
@@ -486,6 +514,11 @@ static int acpi_battery_get_state(struct acpi_battery *battery) | |||
486 | && battery->capacity_now >= 0 && battery->capacity_now <= 100) | 514 | && battery->capacity_now >= 0 && battery->capacity_now <= 100) |
487 | battery->capacity_now = (battery->capacity_now * | 515 | battery->capacity_now = (battery->capacity_now * |
488 | battery->full_charge_capacity) / 100; | 516 | battery->full_charge_capacity) / 100; |
517 | if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags) && | ||
518 | battery->power_unit && battery->design_voltage) { | ||
519 | battery->capacity_now = battery->capacity_now * | ||
520 | 10000 / battery->design_voltage; | ||
521 | } | ||
489 | return result; | 522 | return result; |
490 | } | 523 | } |
491 | 524 | ||
@@ -595,6 +628,24 @@ static void sysfs_remove_battery(struct acpi_battery *battery) | |||
595 | mutex_unlock(&battery->sysfs_lock); | 628 | mutex_unlock(&battery->sysfs_lock); |
596 | } | 629 | } |
597 | 630 | ||
631 | static void find_battery(const struct dmi_header *dm, void *private) | ||
632 | { | ||
633 | struct acpi_battery *battery = (struct acpi_battery *)private; | ||
634 | /* Note: the hardcoded offsets below have been extracted from | ||
635 | the source code of dmidecode. */ | ||
636 | if (dm->type == DMI_ENTRY_PORTABLE_BATTERY && dm->length >= 8) { | ||
637 | const u8 *dmi_data = (const u8 *)(dm + 1); | ||
638 | int dmi_capacity = get_unaligned((const u16 *)(dmi_data + 6)); | ||
639 | if (dm->length >= 18) | ||
640 | dmi_capacity *= dmi_data[17]; | ||
641 | if (battery->design_capacity * battery->design_voltage / 1000 | ||
642 | != dmi_capacity && | ||
643 | battery->design_capacity * 10 == dmi_capacity) | ||
644 | set_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, | ||
645 | &battery->flags); | ||
646 | } | ||
647 | } | ||
648 | |||
598 | /* | 649 | /* |
599 | * According to the ACPI spec, some kinds of primary batteries can | 650 | * According to the ACPI spec, some kinds of primary batteries can |
600 | * report percentage battery remaining capacity directly to OS. | 651 | * report percentage battery remaining capacity directly to OS. |
@@ -620,6 +671,32 @@ static void acpi_battery_quirks(struct acpi_battery *battery) | |||
620 | battery->capacity_now = (battery->capacity_now * | 671 | battery->capacity_now = (battery->capacity_now * |
621 | battery->full_charge_capacity) / 100; | 672 | battery->full_charge_capacity) / 100; |
622 | } | 673 | } |
674 | |||
675 | if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, &battery->flags)) | ||
676 | return ; | ||
677 | |||
678 | if (battery->power_unit && dmi_name_in_vendors("LENOVO")) { | ||
679 | const char *s; | ||
680 | s = dmi_get_system_info(DMI_PRODUCT_VERSION); | ||
681 | if (s && !strnicmp(s, "ThinkPad", 8)) { | ||
682 | dmi_walk(find_battery, battery); | ||
683 | if (test_bit(ACPI_BATTERY_QUIRK_THINKPAD_MAH, | ||
684 | &battery->flags) && | ||
685 | battery->design_voltage) { | ||
686 | battery->design_capacity = | ||
687 | battery->design_capacity * | ||
688 | 10000 / battery->design_voltage; | ||
689 | battery->full_charge_capacity = | ||
690 | battery->full_charge_capacity * | ||
691 | 10000 / battery->design_voltage; | ||
692 | battery->design_capacity_warning = | ||
693 | battery->design_capacity_warning * | ||
694 | 10000 / battery->design_voltage; | ||
695 | battery->capacity_now = battery->capacity_now * | ||
696 | 10000 / battery->design_voltage; | ||
697 | } | ||
698 | } | ||
699 | } | ||
623 | } | 700 | } |
624 | 701 | ||
625 | static int acpi_battery_update(struct acpi_battery *battery) | 702 | static int acpi_battery_update(struct acpi_battery *battery) |
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c index 1f9f7d7d7bc5..811910b50b75 100644 --- a/drivers/acpi/container.c +++ b/drivers/acpi/container.c | |||
@@ -92,17 +92,24 @@ static int is_device_present(acpi_handle handle) | |||
92 | return ((sta & ACPI_STA_DEVICE_PRESENT) == ACPI_STA_DEVICE_PRESENT); | 92 | return ((sta & ACPI_STA_DEVICE_PRESENT) == ACPI_STA_DEVICE_PRESENT); |
93 | } | 93 | } |
94 | 94 | ||
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 | |||
95 | /*******************************************************************/ | 108 | /*******************************************************************/ |
96 | static int acpi_container_add(struct acpi_device *device) | 109 | static int acpi_container_add(struct acpi_device *device) |
97 | { | 110 | { |
98 | struct acpi_container *container; | 111 | struct acpi_container *container; |
99 | 112 | ||
100 | |||
101 | if (!device) { | ||
102 | printk(KERN_ERR PREFIX "device is NULL\n"); | ||
103 | return -EINVAL; | ||
104 | } | ||
105 | |||
106 | container = kzalloc(sizeof(struct acpi_container), GFP_KERNEL); | 113 | container = kzalloc(sizeof(struct acpi_container), GFP_KERNEL); |
107 | if (!container) | 114 | if (!container) |
108 | return -ENOMEM; | 115 | return -ENOMEM; |
@@ -164,7 +171,7 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context) | |||
164 | case ACPI_NOTIFY_BUS_CHECK: | 171 | case ACPI_NOTIFY_BUS_CHECK: |
165 | /* Fall through */ | 172 | /* Fall through */ |
166 | case ACPI_NOTIFY_DEVICE_CHECK: | 173 | case ACPI_NOTIFY_DEVICE_CHECK: |
167 | printk(KERN_WARNING "Container driver received %s event\n", | 174 | pr_debug("Container driver received %s event\n", |
168 | (type == ACPI_NOTIFY_BUS_CHECK) ? | 175 | (type == ACPI_NOTIFY_BUS_CHECK) ? |
169 | "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK"); | 176 | "ACPI_NOTIFY_BUS_CHECK" : "ACPI_NOTIFY_DEVICE_CHECK"); |
170 | 177 | ||
@@ -185,7 +192,7 @@ static void container_notify_cb(acpi_handle handle, u32 type, void *context) | |||
185 | 192 | ||
186 | result = container_device_add(&device, handle); | 193 | result = container_device_add(&device, handle); |
187 | if (result) { | 194 | if (result) { |
188 | printk(KERN_WARNING "Failed to add container\n"); | 195 | acpi_handle_warn(handle, "Failed to add container\n"); |
189 | break; | 196 | break; |
190 | } | 197 | } |
191 | 198 | ||
@@ -232,10 +239,8 @@ container_walk_namespace_cb(acpi_handle handle, | |||
232 | goto end; | 239 | goto end; |
233 | } | 240 | } |
234 | 241 | ||
235 | if (strcmp(hid, "ACPI0004") && strcmp(hid, "PNP0A05") && | 242 | if (!is_container_device(hid)) |
236 | strcmp(hid, "PNP0A06")) { | ||
237 | goto end; | 243 | goto end; |
238 | } | ||
239 | 244 | ||
240 | switch (*action) { | 245 | switch (*action) { |
241 | case INSTALL_NOTIFY_HANDLER: | 246 | case INSTALL_NOTIFY_HANDLER: |
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c index 88eb14304667..f32bd47b35e0 100644 --- a/drivers/acpi/dock.c +++ b/drivers/acpi/dock.c | |||
@@ -31,6 +31,7 @@ | |||
31 | #include <linux/platform_device.h> | 31 | #include <linux/platform_device.h> |
32 | #include <linux/jiffies.h> | 32 | #include <linux/jiffies.h> |
33 | #include <linux/stddef.h> | 33 | #include <linux/stddef.h> |
34 | #include <linux/acpi.h> | ||
34 | #include <acpi/acpi_bus.h> | 35 | #include <acpi/acpi_bus.h> |
35 | #include <acpi/acpi_drivers.h> | 36 | #include <acpi/acpi_drivers.h> |
36 | 37 | ||
@@ -460,12 +461,8 @@ static void handle_dock(struct dock_station *ds, int dock) | |||
460 | struct acpi_object_list arg_list; | 461 | struct acpi_object_list arg_list; |
461 | union acpi_object arg; | 462 | union acpi_object arg; |
462 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | 463 | struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; |
463 | struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL }; | ||
464 | 464 | ||
465 | acpi_get_name(ds->handle, ACPI_FULL_PATHNAME, &name_buffer); | 465 | acpi_handle_info(ds->handle, "%s\n", dock ? "docking" : "undocking"); |
466 | |||
467 | printk(KERN_INFO PREFIX "%s - %s\n", | ||
468 | (char *)name_buffer.pointer, dock ? "docking" : "undocking"); | ||
469 | 466 | ||
470 | /* _DCK method has one argument */ | 467 | /* _DCK method has one argument */ |
471 | arg_list.count = 1; | 468 | arg_list.count = 1; |
@@ -474,11 +471,10 @@ static void handle_dock(struct dock_station *ds, int dock) | |||
474 | arg.integer.value = dock; | 471 | arg.integer.value = dock; |
475 | status = acpi_evaluate_object(ds->handle, "_DCK", &arg_list, &buffer); | 472 | status = acpi_evaluate_object(ds->handle, "_DCK", &arg_list, &buffer); |
476 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) | 473 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) |
477 | ACPI_EXCEPTION((AE_INFO, status, "%s - failed to execute" | 474 | acpi_handle_err(ds->handle, "Failed to execute _DCK (0x%x)\n", |
478 | " _DCK\n", (char *)name_buffer.pointer)); | 475 | status); |
479 | 476 | ||
480 | kfree(buffer.pointer); | 477 | kfree(buffer.pointer); |
481 | kfree(name_buffer.pointer); | ||
482 | } | 478 | } |
483 | 479 | ||
484 | static inline void dock(struct dock_station *ds) | 480 | static inline void dock(struct dock_station *ds) |
@@ -525,9 +521,11 @@ static void dock_lock(struct dock_station *ds, int lock) | |||
525 | status = acpi_evaluate_object(ds->handle, "_LCK", &arg_list, NULL); | 521 | status = acpi_evaluate_object(ds->handle, "_LCK", &arg_list, NULL); |
526 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { | 522 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { |
527 | if (lock) | 523 | if (lock) |
528 | printk(KERN_WARNING PREFIX "Locking device failed\n"); | 524 | acpi_handle_warn(ds->handle, |
525 | "Locking device failed (0x%x)\n", status); | ||
529 | else | 526 | else |
530 | printk(KERN_WARNING PREFIX "Unlocking device failed\n"); | 527 | acpi_handle_warn(ds->handle, |
528 | "Unlocking device failed (0x%x)\n", status); | ||
531 | } | 529 | } |
532 | } | 530 | } |
533 | 531 | ||
@@ -667,7 +665,7 @@ static int handle_eject_request(struct dock_station *ds, u32 event) | |||
667 | dock_lock(ds, 0); | 665 | dock_lock(ds, 0); |
668 | eject_dock(ds); | 666 | eject_dock(ds); |
669 | if (dock_present(ds)) { | 667 | if (dock_present(ds)) { |
670 | printk(KERN_ERR PREFIX "Unable to undock!\n"); | 668 | acpi_handle_err(ds->handle, "Unable to undock!\n"); |
671 | return -EBUSY; | 669 | return -EBUSY; |
672 | } | 670 | } |
673 | complete_undock(ds); | 671 | complete_undock(ds); |
@@ -715,7 +713,7 @@ static void dock_notify(acpi_handle handle, u32 event, void *data) | |||
715 | begin_dock(ds); | 713 | begin_dock(ds); |
716 | dock(ds); | 714 | dock(ds); |
717 | if (!dock_present(ds)) { | 715 | if (!dock_present(ds)) { |
718 | printk(KERN_ERR PREFIX "Unable to dock!\n"); | 716 | acpi_handle_err(handle, "Unable to dock!\n"); |
719 | complete_dock(ds); | 717 | complete_dock(ds); |
720 | break; | 718 | break; |
721 | } | 719 | } |
@@ -743,7 +741,7 @@ static void dock_notify(acpi_handle handle, u32 event, void *data) | |||
743 | dock_event(ds, event, UNDOCK_EVENT); | 741 | dock_event(ds, event, UNDOCK_EVENT); |
744 | break; | 742 | break; |
745 | default: | 743 | default: |
746 | printk(KERN_ERR PREFIX "Unknown dock event %d\n", event); | 744 | acpi_handle_err(handle, "Unknown dock event %d\n", event); |
747 | } | 745 | } |
748 | } | 746 | } |
749 | 747 | ||
@@ -987,7 +985,7 @@ err_rmgroup: | |||
987 | sysfs_remove_group(&dd->dev.kobj, &dock_attribute_group); | 985 | sysfs_remove_group(&dd->dev.kobj, &dock_attribute_group); |
988 | err_unregister: | 986 | err_unregister: |
989 | platform_device_unregister(dd); | 987 | platform_device_unregister(dd); |
990 | printk(KERN_ERR "%s encountered error %d\n", __func__, ret); | 988 | acpi_handle_err(handle, "%s encountered error %d\n", __func__, ret); |
991 | return ret; | 989 | return ret; |
992 | } | 990 | } |
993 | 991 | ||
@@ -1016,51 +1014,39 @@ static int dock_remove(struct dock_station *ds) | |||
1016 | } | 1014 | } |
1017 | 1015 | ||
1018 | /** | 1016 | /** |
1019 | * find_dock - look for a dock station | 1017 | * find_dock_and_bay - look for dock stations and bays |
1020 | * @handle: acpi handle of a device | 1018 | * @handle: acpi handle of a device |
1021 | * @lvl: unused | 1019 | * @lvl: unused |
1022 | * @context: counter of dock stations found | 1020 | * @context: unused |
1023 | * @rv: unused | 1021 | * @rv: unused |
1024 | * | 1022 | * |
1025 | * This is called by acpi_walk_namespace to look for dock stations. | 1023 | * This is called by acpi_walk_namespace to look for dock stations and bays. |
1026 | */ | 1024 | */ |
1027 | static __init acpi_status | 1025 | static __init acpi_status |
1028 | find_dock(acpi_handle handle, u32 lvl, void *context, void **rv) | 1026 | find_dock_and_bay(acpi_handle handle, u32 lvl, void *context, void **rv) |
1029 | { | 1027 | { |
1030 | if (is_dock(handle)) | 1028 | if (is_dock(handle) || is_ejectable_bay(handle)) |
1031 | dock_add(handle); | 1029 | dock_add(handle); |
1032 | 1030 | ||
1033 | return AE_OK; | 1031 | return AE_OK; |
1034 | } | 1032 | } |
1035 | 1033 | ||
1036 | static __init acpi_status | ||
1037 | find_bay(acpi_handle handle, u32 lvl, void *context, void **rv) | ||
1038 | { | ||
1039 | /* If bay is a dock, it's already handled */ | ||
1040 | if (is_ejectable_bay(handle) && !is_dock(handle)) | ||
1041 | dock_add(handle); | ||
1042 | return AE_OK; | ||
1043 | } | ||
1044 | |||
1045 | static int __init dock_init(void) | 1034 | static int __init dock_init(void) |
1046 | { | 1035 | { |
1047 | if (acpi_disabled) | 1036 | if (acpi_disabled) |
1048 | return 0; | 1037 | return 0; |
1049 | 1038 | ||
1050 | /* look for a dock station */ | 1039 | /* look for dock stations and bays */ |
1051 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | 1040 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, |
1052 | ACPI_UINT32_MAX, find_dock, NULL, NULL, NULL); | 1041 | ACPI_UINT32_MAX, find_dock_and_bay, NULL, NULL, NULL); |
1053 | 1042 | ||
1054 | /* look for bay */ | ||
1055 | acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, | ||
1056 | ACPI_UINT32_MAX, find_bay, NULL, NULL, NULL); | ||
1057 | if (!dock_station_count) { | 1043 | if (!dock_station_count) { |
1058 | printk(KERN_INFO PREFIX "No dock devices found.\n"); | 1044 | pr_info(PREFIX "No dock devices found.\n"); |
1059 | return 0; | 1045 | return 0; |
1060 | } | 1046 | } |
1061 | 1047 | ||
1062 | register_acpi_bus_notifier(&dock_acpi_notifier); | 1048 | register_acpi_bus_notifier(&dock_acpi_notifier); |
1063 | printk(KERN_INFO PREFIX "%s: %d docks/bays found\n", | 1049 | pr_info(PREFIX "%s: %d docks/bays found\n", |
1064 | ACPI_DOCK_DRIVER_DESCRIPTION, dock_station_count); | 1050 | ACPI_DOCK_DRIVER_DESCRIPTION, dock_station_count); |
1065 | return 0; | 1051 | return 0; |
1066 | } | 1052 | } |
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c index a51df9681319..354007d490d1 100644 --- a/drivers/acpi/ec.c +++ b/drivers/acpi/ec.c | |||
@@ -158,10 +158,10 @@ static int ec_transaction_done(struct acpi_ec *ec) | |||
158 | { | 158 | { |
159 | unsigned long flags; | 159 | unsigned long flags; |
160 | int ret = 0; | 160 | int ret = 0; |
161 | spin_lock_irqsave(&ec->curr_lock, flags); | 161 | spin_lock_irqsave(&ec->lock, flags); |
162 | if (!ec->curr || ec->curr->done) | 162 | if (!ec->curr || ec->curr->done) |
163 | ret = 1; | 163 | ret = 1; |
164 | spin_unlock_irqrestore(&ec->curr_lock, flags); | 164 | spin_unlock_irqrestore(&ec->lock, flags); |
165 | return ret; | 165 | return ret; |
166 | } | 166 | } |
167 | 167 | ||
@@ -175,32 +175,38 @@ static void start_transaction(struct acpi_ec *ec) | |||
175 | static void advance_transaction(struct acpi_ec *ec, u8 status) | 175 | static void advance_transaction(struct acpi_ec *ec, u8 status) |
176 | { | 176 | { |
177 | unsigned long flags; | 177 | unsigned long flags; |
178 | spin_lock_irqsave(&ec->curr_lock, flags); | 178 | struct transaction *t = ec->curr; |
179 | if (!ec->curr) | 179 | |
180 | spin_lock_irqsave(&ec->lock, flags); | ||
181 | if (!t) | ||
180 | goto unlock; | 182 | goto unlock; |
181 | if (ec->curr->wlen > ec->curr->wi) { | 183 | if (t->wlen > t->wi) { |
182 | if ((status & ACPI_EC_FLAG_IBF) == 0) | 184 | if ((status & ACPI_EC_FLAG_IBF) == 0) |
183 | acpi_ec_write_data(ec, | 185 | acpi_ec_write_data(ec, |
184 | ec->curr->wdata[ec->curr->wi++]); | 186 | t->wdata[t->wi++]); |
185 | else | 187 | else |
186 | goto err; | 188 | goto err; |
187 | } else if (ec->curr->rlen > ec->curr->ri) { | 189 | } else if (t->rlen > t->ri) { |
188 | if ((status & ACPI_EC_FLAG_OBF) == 1) { | 190 | if ((status & ACPI_EC_FLAG_OBF) == 1) { |
189 | ec->curr->rdata[ec->curr->ri++] = acpi_ec_read_data(ec); | 191 | t->rdata[t->ri++] = acpi_ec_read_data(ec); |
190 | if (ec->curr->rlen == ec->curr->ri) | 192 | if (t->rlen == t->ri) |
191 | ec->curr->done = true; | 193 | t->done = true; |
192 | } else | 194 | } else |
193 | goto err; | 195 | goto err; |
194 | } else if (ec->curr->wlen == ec->curr->wi && | 196 | } else if (t->wlen == t->wi && |
195 | (status & ACPI_EC_FLAG_IBF) == 0) | 197 | (status & ACPI_EC_FLAG_IBF) == 0) |
196 | ec->curr->done = true; | 198 | t->done = true; |
197 | goto unlock; | 199 | goto unlock; |
198 | err: | 200 | err: |
199 | /* false interrupt, state didn't change */ | 201 | /* |
200 | if (in_interrupt()) | 202 | * If SCI bit is set, then don't think it's a false IRQ |
201 | ++ec->curr->irq_count; | 203 | * otherwise will take a not handled IRQ as a false one. |
204 | */ | ||
205 | if (in_interrupt() && !(status & ACPI_EC_FLAG_SCI)) | ||
206 | ++t->irq_count; | ||
207 | |||
202 | unlock: | 208 | unlock: |
203 | spin_unlock_irqrestore(&ec->curr_lock, flags); | 209 | spin_unlock_irqrestore(&ec->lock, flags); |
204 | } | 210 | } |
205 | 211 | ||
206 | static int acpi_ec_sync_query(struct acpi_ec *ec); | 212 | static int acpi_ec_sync_query(struct acpi_ec *ec); |
@@ -238,9 +244,9 @@ static int ec_poll(struct acpi_ec *ec) | |||
238 | if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) | 244 | if (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) |
239 | break; | 245 | break; |
240 | pr_debug(PREFIX "controller reset, restart transaction\n"); | 246 | pr_debug(PREFIX "controller reset, restart transaction\n"); |
241 | spin_lock_irqsave(&ec->curr_lock, flags); | 247 | spin_lock_irqsave(&ec->lock, flags); |
242 | start_transaction(ec); | 248 | start_transaction(ec); |
243 | spin_unlock_irqrestore(&ec->curr_lock, flags); | 249 | spin_unlock_irqrestore(&ec->lock, flags); |
244 | } | 250 | } |
245 | return -ETIME; | 251 | return -ETIME; |
246 | } | 252 | } |
@@ -253,17 +259,17 @@ static int acpi_ec_transaction_unlocked(struct acpi_ec *ec, | |||
253 | if (EC_FLAGS_MSI) | 259 | if (EC_FLAGS_MSI) |
254 | udelay(ACPI_EC_MSI_UDELAY); | 260 | udelay(ACPI_EC_MSI_UDELAY); |
255 | /* start transaction */ | 261 | /* start transaction */ |
256 | spin_lock_irqsave(&ec->curr_lock, tmp); | 262 | spin_lock_irqsave(&ec->lock, tmp); |
257 | /* following two actions should be kept atomic */ | 263 | /* following two actions should be kept atomic */ |
258 | ec->curr = t; | 264 | ec->curr = t; |
259 | start_transaction(ec); | 265 | start_transaction(ec); |
260 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) | 266 | if (ec->curr->command == ACPI_EC_COMMAND_QUERY) |
261 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); | 267 | clear_bit(EC_FLAGS_QUERY_PENDING, &ec->flags); |
262 | spin_unlock_irqrestore(&ec->curr_lock, tmp); | 268 | spin_unlock_irqrestore(&ec->lock, tmp); |
263 | ret = ec_poll(ec); | 269 | ret = ec_poll(ec); |
264 | spin_lock_irqsave(&ec->curr_lock, tmp); | 270 | spin_lock_irqsave(&ec->lock, tmp); |
265 | ec->curr = NULL; | 271 | ec->curr = NULL; |
266 | spin_unlock_irqrestore(&ec->curr_lock, tmp); | 272 | spin_unlock_irqrestore(&ec->lock, tmp); |
267 | return ret; | 273 | return ret; |
268 | } | 274 | } |
269 | 275 | ||
@@ -292,7 +298,7 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) | |||
292 | return -EINVAL; | 298 | return -EINVAL; |
293 | if (t->rdata) | 299 | if (t->rdata) |
294 | memset(t->rdata, 0, t->rlen); | 300 | memset(t->rdata, 0, t->rlen); |
295 | mutex_lock(&ec->lock); | 301 | mutex_lock(&ec->mutex); |
296 | if (test_bit(EC_FLAGS_BLOCKED, &ec->flags)) { | 302 | if (test_bit(EC_FLAGS_BLOCKED, &ec->flags)) { |
297 | status = -EINVAL; | 303 | status = -EINVAL; |
298 | goto unlock; | 304 | goto unlock; |
@@ -310,7 +316,8 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) | |||
310 | status = -ETIME; | 316 | status = -ETIME; |
311 | goto end; | 317 | goto end; |
312 | } | 318 | } |
313 | pr_debug(PREFIX "transaction start\n"); | 319 | pr_debug(PREFIX "transaction start (cmd=0x%02x, addr=0x%02x)\n", |
320 | t->command, t->wdata ? t->wdata[0] : 0); | ||
314 | /* disable GPE during transaction if storm is detected */ | 321 | /* disable GPE during transaction if storm is detected */ |
315 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { | 322 | if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { |
316 | /* It has to be disabled, so that it doesn't trigger. */ | 323 | /* It has to be disabled, so that it doesn't trigger. */ |
@@ -326,8 +333,9 @@ static int acpi_ec_transaction(struct acpi_ec *ec, struct transaction *t) | |||
326 | /* It is safe to enable the GPE outside of the transaction. */ | 333 | /* It is safe to enable the GPE outside of the transaction. */ |
327 | acpi_enable_gpe(NULL, ec->gpe); | 334 | acpi_enable_gpe(NULL, ec->gpe); |
328 | } else if (t->irq_count > ec_storm_threshold) { | 335 | } else if (t->irq_count > ec_storm_threshold) { |
329 | pr_info(PREFIX "GPE storm detected, " | 336 | pr_info(PREFIX "GPE storm detected(%d GPEs), " |
330 | "transactions will use polling mode\n"); | 337 | "transactions will use polling mode\n", |
338 | t->irq_count); | ||
331 | set_bit(EC_FLAGS_GPE_STORM, &ec->flags); | 339 | set_bit(EC_FLAGS_GPE_STORM, &ec->flags); |
332 | } | 340 | } |
333 | pr_debug(PREFIX "transaction end\n"); | 341 | pr_debug(PREFIX "transaction end\n"); |
@@ -335,7 +343,7 @@ end: | |||
335 | if (ec->global_lock) | 343 | if (ec->global_lock) |
336 | acpi_release_global_lock(glk); | 344 | acpi_release_global_lock(glk); |
337 | unlock: | 345 | unlock: |
338 | mutex_unlock(&ec->lock); | 346 | mutex_unlock(&ec->mutex); |
339 | return status; | 347 | return status; |
340 | } | 348 | } |
341 | 349 | ||
@@ -403,7 +411,7 @@ int ec_burst_disable(void) | |||
403 | 411 | ||
404 | EXPORT_SYMBOL(ec_burst_disable); | 412 | EXPORT_SYMBOL(ec_burst_disable); |
405 | 413 | ||
406 | int ec_read(u8 addr, u8 * val) | 414 | int ec_read(u8 addr, u8 *val) |
407 | { | 415 | { |
408 | int err; | 416 | int err; |
409 | u8 temp_data; | 417 | u8 temp_data; |
@@ -468,10 +476,10 @@ void acpi_ec_block_transactions(void) | |||
468 | if (!ec) | 476 | if (!ec) |
469 | return; | 477 | return; |
470 | 478 | ||
471 | mutex_lock(&ec->lock); | 479 | mutex_lock(&ec->mutex); |
472 | /* Prevent transactions from being carried out */ | 480 | /* Prevent transactions from being carried out */ |
473 | set_bit(EC_FLAGS_BLOCKED, &ec->flags); | 481 | set_bit(EC_FLAGS_BLOCKED, &ec->flags); |
474 | mutex_unlock(&ec->lock); | 482 | mutex_unlock(&ec->mutex); |
475 | } | 483 | } |
476 | 484 | ||
477 | void acpi_ec_unblock_transactions(void) | 485 | void acpi_ec_unblock_transactions(void) |
@@ -481,10 +489,10 @@ void acpi_ec_unblock_transactions(void) | |||
481 | if (!ec) | 489 | if (!ec) |
482 | return; | 490 | return; |
483 | 491 | ||
484 | mutex_lock(&ec->lock); | 492 | mutex_lock(&ec->mutex); |
485 | /* Allow transactions to be carried out again */ | 493 | /* Allow transactions to be carried out again */ |
486 | clear_bit(EC_FLAGS_BLOCKED, &ec->flags); | 494 | clear_bit(EC_FLAGS_BLOCKED, &ec->flags); |
487 | mutex_unlock(&ec->lock); | 495 | mutex_unlock(&ec->mutex); |
488 | } | 496 | } |
489 | 497 | ||
490 | void acpi_ec_unblock_transactions_early(void) | 498 | void acpi_ec_unblock_transactions_early(void) |
@@ -536,9 +544,9 @@ int acpi_ec_add_query_handler(struct acpi_ec *ec, u8 query_bit, | |||
536 | handler->handle = handle; | 544 | handler->handle = handle; |
537 | handler->func = func; | 545 | handler->func = func; |
538 | handler->data = data; | 546 | handler->data = data; |
539 | mutex_lock(&ec->lock); | 547 | mutex_lock(&ec->mutex); |
540 | list_add(&handler->node, &ec->list); | 548 | list_add(&handler->node, &ec->list); |
541 | mutex_unlock(&ec->lock); | 549 | mutex_unlock(&ec->mutex); |
542 | return 0; | 550 | return 0; |
543 | } | 551 | } |
544 | 552 | ||
@@ -547,14 +555,14 @@ EXPORT_SYMBOL_GPL(acpi_ec_add_query_handler); | |||
547 | void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit) | 555 | void acpi_ec_remove_query_handler(struct acpi_ec *ec, u8 query_bit) |
548 | { | 556 | { |
549 | struct acpi_ec_query_handler *handler, *tmp; | 557 | struct acpi_ec_query_handler *handler, *tmp; |
550 | mutex_lock(&ec->lock); | 558 | mutex_lock(&ec->mutex); |
551 | list_for_each_entry_safe(handler, tmp, &ec->list, node) { | 559 | list_for_each_entry_safe(handler, tmp, &ec->list, node) { |
552 | if (query_bit == handler->query_bit) { | 560 | if (query_bit == handler->query_bit) { |
553 | list_del(&handler->node); | 561 | list_del(&handler->node); |
554 | kfree(handler); | 562 | kfree(handler); |
555 | } | 563 | } |
556 | } | 564 | } |
557 | mutex_unlock(&ec->lock); | 565 | mutex_unlock(&ec->mutex); |
558 | } | 566 | } |
559 | 567 | ||
560 | EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler); | 568 | EXPORT_SYMBOL_GPL(acpi_ec_remove_query_handler); |
@@ -601,9 +609,9 @@ static void acpi_ec_gpe_query(void *ec_cxt) | |||
601 | struct acpi_ec *ec = ec_cxt; | 609 | struct acpi_ec *ec = ec_cxt; |
602 | if (!ec) | 610 | if (!ec) |
603 | return; | 611 | return; |
604 | mutex_lock(&ec->lock); | 612 | mutex_lock(&ec->mutex); |
605 | acpi_ec_sync_query(ec); | 613 | acpi_ec_sync_query(ec); |
606 | mutex_unlock(&ec->lock); | 614 | mutex_unlock(&ec->mutex); |
607 | } | 615 | } |
608 | 616 | ||
609 | static int ec_check_sci(struct acpi_ec *ec, u8 state) | 617 | static int ec_check_sci(struct acpi_ec *ec, u8 state) |
@@ -622,10 +630,11 @@ static u32 acpi_ec_gpe_handler(acpi_handle gpe_device, | |||
622 | u32 gpe_number, void *data) | 630 | u32 gpe_number, void *data) |
623 | { | 631 | { |
624 | struct acpi_ec *ec = data; | 632 | struct acpi_ec *ec = data; |
633 | u8 status = acpi_ec_read_status(ec); | ||
625 | 634 | ||
626 | pr_debug(PREFIX "~~~> interrupt\n"); | 635 | pr_debug(PREFIX "~~~> interrupt, status:0x%02x\n", status); |
627 | 636 | ||
628 | advance_transaction(ec, acpi_ec_read_status(ec)); | 637 | advance_transaction(ec, status); |
629 | if (ec_transaction_done(ec) && | 638 | if (ec_transaction_done(ec) && |
630 | (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) == 0) { | 639 | (acpi_ec_read_status(ec) & ACPI_EC_FLAG_IBF) == 0) { |
631 | wake_up(&ec->wait); | 640 | wake_up(&ec->wait); |
@@ -691,10 +700,10 @@ static struct acpi_ec *make_acpi_ec(void) | |||
691 | if (!ec) | 700 | if (!ec) |
692 | return NULL; | 701 | return NULL; |
693 | ec->flags = 1 << EC_FLAGS_QUERY_PENDING; | 702 | ec->flags = 1 << EC_FLAGS_QUERY_PENDING; |
694 | mutex_init(&ec->lock); | 703 | mutex_init(&ec->mutex); |
695 | init_waitqueue_head(&ec->wait); | 704 | init_waitqueue_head(&ec->wait); |
696 | INIT_LIST_HEAD(&ec->list); | 705 | INIT_LIST_HEAD(&ec->list); |
697 | spin_lock_init(&ec->curr_lock); | 706 | spin_lock_init(&ec->lock); |
698 | return ec; | 707 | return ec; |
699 | } | 708 | } |
700 | 709 | ||
@@ -853,12 +862,12 @@ static int acpi_ec_remove(struct acpi_device *device, int type) | |||
853 | 862 | ||
854 | ec = acpi_driver_data(device); | 863 | ec = acpi_driver_data(device); |
855 | ec_remove_handlers(ec); | 864 | ec_remove_handlers(ec); |
856 | mutex_lock(&ec->lock); | 865 | mutex_lock(&ec->mutex); |
857 | list_for_each_entry_safe(handler, tmp, &ec->list, node) { | 866 | list_for_each_entry_safe(handler, tmp, &ec->list, node) { |
858 | list_del(&handler->node); | 867 | list_del(&handler->node); |
859 | kfree(handler); | 868 | kfree(handler); |
860 | } | 869 | } |
861 | mutex_unlock(&ec->lock); | 870 | mutex_unlock(&ec->mutex); |
862 | release_region(ec->data_addr, 1); | 871 | release_region(ec->data_addr, 1); |
863 | release_region(ec->command_addr, 1); | 872 | release_region(ec->command_addr, 1); |
864 | device->driver_data = NULL; | 873 | device->driver_data = NULL; |
diff --git a/drivers/acpi/hed.c b/drivers/acpi/hed.c index 20a0f2c3ca3b..b514e81e8cfa 100644 --- a/drivers/acpi/hed.c +++ b/drivers/acpi/hed.c | |||
@@ -70,7 +70,7 @@ static int __devinit acpi_hed_add(struct acpi_device *device) | |||
70 | return 0; | 70 | return 0; |
71 | } | 71 | } |
72 | 72 | ||
73 | static int __devexit acpi_hed_remove(struct acpi_device *device, int type) | 73 | static int acpi_hed_remove(struct acpi_device *device, int type) |
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 57d41f6e1441..3c407cdc1ec1 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h | |||
@@ -58,11 +58,11 @@ struct acpi_ec { | |||
58 | unsigned long data_addr; | 58 | unsigned long data_addr; |
59 | unsigned long global_lock; | 59 | unsigned long global_lock; |
60 | unsigned long flags; | 60 | unsigned long flags; |
61 | struct mutex lock; | 61 | struct mutex mutex; |
62 | wait_queue_head_t wait; | 62 | wait_queue_head_t wait; |
63 | struct list_head list; | 63 | struct list_head list; |
64 | struct transaction *curr; | 64 | struct transaction *curr; |
65 | spinlock_t curr_lock; | 65 | spinlock_t lock; |
66 | }; | 66 | }; |
67 | 67 | ||
68 | extern struct acpi_ec *first_ec; | 68 | extern struct acpi_ec *first_ec; |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 9eaf708f5885..6dc4a2b1e956 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -932,7 +932,7 @@ static acpi_status __acpi_os_execute(acpi_execute_type type, | |||
932 | * having a static work_struct. | 932 | * having a static work_struct. |
933 | */ | 933 | */ |
934 | 934 | ||
935 | dpc = kmalloc(sizeof(struct acpi_os_dpc), GFP_ATOMIC); | 935 | dpc = kzalloc(sizeof(struct acpi_os_dpc), GFP_ATOMIC); |
936 | if (!dpc) | 936 | if (!dpc) |
937 | return AE_NO_MEMORY; | 937 | return AE_NO_MEMORY; |
938 | 938 | ||
@@ -944,17 +944,22 @@ static acpi_status __acpi_os_execute(acpi_execute_type type, | |||
944 | * because the hotplug code may call driver .remove() functions, | 944 | * because the hotplug code may call driver .remove() functions, |
945 | * which invoke flush_scheduled_work/acpi_os_wait_events_complete | 945 | * which invoke flush_scheduled_work/acpi_os_wait_events_complete |
946 | * to flush these workqueues. | 946 | * to flush these workqueues. |
947 | * | ||
948 | * To prevent lockdep from complaining unnecessarily, make sure that | ||
949 | * there is a different static lockdep key for each workqueue by using | ||
950 | * INIT_WORK() for each of them separately. | ||
947 | */ | 951 | */ |
948 | queue = hp ? kacpi_hotplug_wq : | 952 | if (hp) { |
949 | (type == OSL_NOTIFY_HANDLER ? kacpi_notify_wq : kacpid_wq); | 953 | queue = kacpi_hotplug_wq; |
950 | dpc->wait = hp ? 1 : 0; | 954 | dpc->wait = 1; |
951 | |||
952 | if (queue == kacpi_hotplug_wq) | ||
953 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); | 955 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); |
954 | else if (queue == kacpi_notify_wq) | 956 | } else if (type == OSL_NOTIFY_HANDLER) { |
957 | queue = kacpi_notify_wq; | ||
955 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); | 958 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); |
956 | else | 959 | } else { |
960 | queue = kacpid_wq; | ||
957 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); | 961 | INIT_WORK(&dpc->work, acpi_os_execute_deferred); |
962 | } | ||
958 | 963 | ||
959 | /* | 964 | /* |
960 | * On some machines, a software-initiated SMI causes corruption unless | 965 | * On some machines, a software-initiated SMI causes corruption unless |
@@ -986,6 +991,7 @@ acpi_status acpi_os_hotplug_execute(acpi_osd_exec_callback function, | |||
986 | { | 991 | { |
987 | return __acpi_os_execute(0, function, context, 1); | 992 | return __acpi_os_execute(0, function, context, 1); |
988 | } | 993 | } |
994 | EXPORT_SYMBOL(acpi_os_hotplug_execute); | ||
989 | 995 | ||
990 | void acpi_os_wait_events_complete(void) | 996 | void acpi_os_wait_events_complete(void) |
991 | { | 997 | { |
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c index 1be25a590dce..23a032490130 100644 --- a/drivers/acpi/pci_irq.c +++ b/drivers/acpi/pci_irq.c | |||
@@ -459,19 +459,19 @@ int acpi_pci_irq_enable(struct pci_dev *dev) | |||
459 | */ | 459 | */ |
460 | if (gsi < 0) { | 460 | if (gsi < 0) { |
461 | u32 dev_gsi; | 461 | u32 dev_gsi; |
462 | dev_warn(&dev->dev, "PCI INT %c: no GSI", pin_name(pin)); | ||
463 | /* Interrupt Line values above 0xF are forbidden */ | 462 | /* Interrupt Line values above 0xF are forbidden */ |
464 | if (dev->irq > 0 && (dev->irq <= 0xF) && | 463 | if (dev->irq > 0 && (dev->irq <= 0xF) && |
465 | (acpi_isa_irq_to_gsi(dev->irq, &dev_gsi) == 0)) { | 464 | (acpi_isa_irq_to_gsi(dev->irq, &dev_gsi) == 0)) { |
466 | printk(" - using ISA IRQ %d\n", dev->irq); | 465 | dev_warn(&dev->dev, "PCI INT %c: no GSI - using ISA IRQ %d\n", |
466 | pin_name(pin), dev->irq); | ||
467 | acpi_register_gsi(&dev->dev, dev_gsi, | 467 | acpi_register_gsi(&dev->dev, dev_gsi, |
468 | ACPI_LEVEL_SENSITIVE, | 468 | ACPI_LEVEL_SENSITIVE, |
469 | ACPI_ACTIVE_LOW); | 469 | ACPI_ACTIVE_LOW); |
470 | return 0; | ||
471 | } else { | 470 | } else { |
472 | printk("\n"); | 471 | dev_warn(&dev->dev, "PCI INT %c: no GSI\n", |
473 | return 0; | 472 | pin_name(pin)); |
474 | } | 473 | } |
474 | return 0; | ||
475 | } | 475 | } |
476 | 476 | ||
477 | rc = acpi_register_gsi(&dev->dev, gsi, triggering, polarity); | 477 | rc = acpi_register_gsi(&dev->dev, gsi, triggering, polarity); |
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c index 40e38a06ba85..7db61b8fa11f 100644 --- a/drivers/acpi/power.c +++ b/drivers/acpi/power.c | |||
@@ -473,7 +473,7 @@ int acpi_power_resource_register_device(struct device *dev, acpi_handle handle) | |||
473 | return ret; | 473 | return ret; |
474 | 474 | ||
475 | no_power_resource: | 475 | no_power_resource: |
476 | printk(KERN_DEBUG PREFIX "Invalid Power Resource to register!"); | 476 | printk(KERN_DEBUG PREFIX "Invalid Power Resource to register!\n"); |
477 | return -ENODEV; | 477 | return -ENODEV; |
478 | } | 478 | } |
479 | EXPORT_SYMBOL_GPL(acpi_power_resource_register_device); | 479 | EXPORT_SYMBOL_GPL(acpi_power_resource_register_device); |
diff --git a/drivers/acpi/proc.c b/drivers/acpi/proc.c index 27adb090bb30..ef98796b3824 100644 --- a/drivers/acpi/proc.c +++ b/drivers/acpi/proc.c | |||
@@ -362,16 +362,13 @@ acpi_system_write_wakeup_device(struct file *file, | |||
362 | struct list_head *node, *next; | 362 | struct list_head *node, *next; |
363 | char strbuf[5]; | 363 | char strbuf[5]; |
364 | char str[5] = ""; | 364 | char str[5] = ""; |
365 | unsigned int len = count; | ||
366 | 365 | ||
367 | if (len > 4) | 366 | if (count > 4) |
368 | len = 4; | 367 | count = 4; |
369 | if (len < 0) | ||
370 | return -EFAULT; | ||
371 | 368 | ||
372 | if (copy_from_user(strbuf, buffer, len)) | 369 | if (copy_from_user(strbuf, buffer, count)) |
373 | return -EFAULT; | 370 | return -EFAULT; |
374 | strbuf[len] = '\0'; | 371 | strbuf[count] = '\0'; |
375 | sscanf(strbuf, "%s", str); | 372 | sscanf(strbuf, "%s", str); |
376 | 373 | ||
377 | mutex_lock(&acpi_device_lock); | 374 | mutex_lock(&acpi_device_lock); |
diff --git a/drivers/acpi/processor_driver.c b/drivers/acpi/processor_driver.c index bd4e5dca3ff7..e83311bf1ebd 100644 --- a/drivers/acpi/processor_driver.c +++ b/drivers/acpi/processor_driver.c | |||
@@ -44,6 +44,7 @@ | |||
44 | #include <linux/moduleparam.h> | 44 | #include <linux/moduleparam.h> |
45 | #include <linux/cpuidle.h> | 45 | #include <linux/cpuidle.h> |
46 | #include <linux/slab.h> | 46 | #include <linux/slab.h> |
47 | #include <linux/acpi.h> | ||
47 | 48 | ||
48 | #include <asm/io.h> | 49 | #include <asm/io.h> |
49 | #include <asm/cpu.h> | 50 | #include <asm/cpu.h> |
@@ -282,7 +283,9 @@ static int acpi_processor_get_info(struct acpi_device *device) | |||
282 | /* Declared with "Processor" statement; match ProcessorID */ | 283 | /* Declared with "Processor" statement; match ProcessorID */ |
283 | status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer); | 284 | status = acpi_evaluate_object(pr->handle, NULL, NULL, &buffer); |
284 | if (ACPI_FAILURE(status)) { | 285 | if (ACPI_FAILURE(status)) { |
285 | printk(KERN_ERR PREFIX "Evaluating processor object\n"); | 286 | dev_err(&device->dev, |
287 | "Failed to evaluate processor object (0x%x)\n", | ||
288 | status); | ||
286 | return -ENODEV; | 289 | return -ENODEV; |
287 | } | 290 | } |
288 | 291 | ||
@@ -301,8 +304,9 @@ static int acpi_processor_get_info(struct acpi_device *device) | |||
301 | status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID, | 304 | status = acpi_evaluate_integer(pr->handle, METHOD_NAME__UID, |
302 | NULL, &value); | 305 | NULL, &value); |
303 | if (ACPI_FAILURE(status)) { | 306 | if (ACPI_FAILURE(status)) { |
304 | printk(KERN_ERR PREFIX | 307 | dev_err(&device->dev, |
305 | "Evaluating processor _UID [%#x]\n", status); | 308 | "Failed to evaluate processor _UID (0x%x)\n", |
309 | status); | ||
306 | return -ENODEV; | 310 | return -ENODEV; |
307 | } | 311 | } |
308 | device_declaration = 1; | 312 | device_declaration = 1; |
@@ -345,7 +349,7 @@ static int acpi_processor_get_info(struct acpi_device *device) | |||
345 | if (!object.processor.pblk_address) | 349 | if (!object.processor.pblk_address) |
346 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No PBLK (NULL address)\n")); | 350 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, "No PBLK (NULL address)\n")); |
347 | else if (object.processor.pblk_length != 6) | 351 | else if (object.processor.pblk_length != 6) |
348 | printk(KERN_ERR PREFIX "Invalid PBLK length [%d]\n", | 352 | dev_err(&device->dev, "Invalid PBLK length [%d]\n", |
349 | object.processor.pblk_length); | 353 | object.processor.pblk_length); |
350 | else { | 354 | else { |
351 | pr->throttling.address = object.processor.pblk_address; | 355 | pr->throttling.address = object.processor.pblk_address; |
@@ -430,8 +434,8 @@ static int acpi_cpu_soft_notify(struct notifier_block *nfb, | |||
430 | * Initialize missing things | 434 | * Initialize missing things |
431 | */ | 435 | */ |
432 | if (pr->flags.need_hotplug_init) { | 436 | if (pr->flags.need_hotplug_init) { |
433 | printk(KERN_INFO "Will online and init hotplugged " | 437 | pr_info("Will online and init hotplugged CPU: %d\n", |
434 | "CPU: %d\n", pr->id); | 438 | pr->id); |
435 | WARN(acpi_processor_start(pr), "Failed to start CPU:" | 439 | WARN(acpi_processor_start(pr), "Failed to start CPU:" |
436 | " %d\n", pr->id); | 440 | " %d\n", pr->id); |
437 | pr->flags.need_hotplug_init = 0; | 441 | pr->flags.need_hotplug_init = 0; |
@@ -492,14 +496,16 @@ static __ref int acpi_processor_start(struct acpi_processor *pr) | |||
492 | &pr->cdev->device.kobj, | 496 | &pr->cdev->device.kobj, |
493 | "thermal_cooling"); | 497 | "thermal_cooling"); |
494 | if (result) { | 498 | if (result) { |
495 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | 499 | dev_err(&device->dev, |
500 | "Failed to create sysfs link 'thermal_cooling'\n"); | ||
496 | goto err_thermal_unregister; | 501 | goto err_thermal_unregister; |
497 | } | 502 | } |
498 | result = sysfs_create_link(&pr->cdev->device.kobj, | 503 | result = sysfs_create_link(&pr->cdev->device.kobj, |
499 | &device->dev.kobj, | 504 | &device->dev.kobj, |
500 | "device"); | 505 | "device"); |
501 | if (result) { | 506 | if (result) { |
502 | printk(KERN_ERR PREFIX "Create sysfs link\n"); | 507 | dev_err(&pr->cdev->device, |
508 | "Failed to create sysfs link 'device'\n"); | ||
503 | goto err_remove_sysfs_thermal; | 509 | goto err_remove_sysfs_thermal; |
504 | } | 510 | } |
505 | 511 | ||
@@ -561,8 +567,9 @@ static int __cpuinit acpi_processor_add(struct acpi_device *device) | |||
561 | */ | 567 | */ |
562 | if (per_cpu(processor_device_array, pr->id) != NULL && | 568 | if (per_cpu(processor_device_array, pr->id) != NULL && |
563 | per_cpu(processor_device_array, pr->id) != device) { | 569 | per_cpu(processor_device_array, pr->id) != device) { |
564 | printk(KERN_WARNING "BIOS reported wrong ACPI id " | 570 | dev_warn(&device->dev, |
565 | "for the processor\n"); | 571 | "BIOS reported wrong ACPI id %d for the processor\n", |
572 | pr->id); | ||
566 | result = -ENODEV; | 573 | result = -ENODEV; |
567 | goto err_free_cpumask; | 574 | goto err_free_cpumask; |
568 | } | 575 | } |
@@ -695,8 +702,8 @@ int acpi_processor_device_add(acpi_handle handle, struct acpi_device **device) | |||
695 | static void acpi_processor_hotplug_notify(acpi_handle handle, | 702 | static void acpi_processor_hotplug_notify(acpi_handle handle, |
696 | u32 event, void *data) | 703 | u32 event, void *data) |
697 | { | 704 | { |
698 | struct acpi_processor *pr; | ||
699 | struct acpi_device *device = NULL; | 705 | struct acpi_device *device = NULL; |
706 | struct acpi_eject_event *ej_event = NULL; | ||
700 | u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */ | 707 | u32 ost_code = ACPI_OST_SC_NON_SPECIFIC_FAILURE; /* default */ |
701 | int result; | 708 | int result; |
702 | 709 | ||
@@ -716,7 +723,7 @@ static void acpi_processor_hotplug_notify(acpi_handle handle, | |||
716 | 723 | ||
717 | result = acpi_processor_device_add(handle, &device); | 724 | result = acpi_processor_device_add(handle, &device); |
718 | if (result) { | 725 | if (result) { |
719 | printk(KERN_ERR PREFIX "Unable to add the device\n"); | 726 | acpi_handle_err(handle, "Unable to add the device\n"); |
720 | break; | 727 | break; |
721 | } | 728 | } |
722 | 729 | ||
@@ -728,20 +735,29 @@ static void acpi_processor_hotplug_notify(acpi_handle handle, | |||
728 | "received ACPI_NOTIFY_EJECT_REQUEST\n")); | 735 | "received ACPI_NOTIFY_EJECT_REQUEST\n")); |
729 | 736 | ||
730 | if (acpi_bus_get_device(handle, &device)) { | 737 | if (acpi_bus_get_device(handle, &device)) { |
731 | printk(KERN_ERR PREFIX | 738 | acpi_handle_err(handle, |
732 | "Device don't exist, dropping EJECT\n"); | 739 | "Device don't exist, dropping EJECT\n"); |
733 | break; | 740 | break; |
734 | } | 741 | } |
735 | pr = acpi_driver_data(device); | 742 | if (!acpi_driver_data(device)) { |
736 | if (!pr) { | 743 | acpi_handle_err(handle, |
737 | printk(KERN_ERR PREFIX | 744 | "Driver data is NULL, dropping EJECT\n"); |
738 | "Driver data is NULL, dropping EJECT\n"); | ||
739 | break; | 745 | break; |
740 | } | 746 | } |
741 | 747 | ||
742 | /* REVISIT: update when eject is supported */ | 748 | ej_event = kmalloc(sizeof(*ej_event), GFP_KERNEL); |
743 | ost_code = ACPI_OST_SC_EJECT_NOT_SUPPORTED; | 749 | if (!ej_event) { |
744 | break; | 750 | acpi_handle_err(handle, "No memory, dropping EJECT\n"); |
751 | break; | ||
752 | } | ||
753 | |||
754 | ej_event->handle = handle; | ||
755 | ej_event->event = ACPI_NOTIFY_EJECT_REQUEST; | ||
756 | acpi_os_hotplug_execute(acpi_bus_hot_remove_device, | ||
757 | (void *)ej_event); | ||
758 | |||
759 | /* eject is performed asynchronously */ | ||
760 | return; | ||
745 | 761 | ||
746 | default: | 762 | default: |
747 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, | 763 | ACPI_DEBUG_PRINT((ACPI_DB_INFO, |
@@ -841,7 +857,7 @@ static acpi_status acpi_processor_hotadd_init(struct acpi_processor *pr) | |||
841 | * and do it when the CPU gets online the first time | 857 | * and do it when the CPU gets online the first time |
842 | * TBD: Cleanup above functions and try to do this more elegant. | 858 | * TBD: Cleanup above functions and try to do this more elegant. |
843 | */ | 859 | */ |
844 | printk(KERN_INFO "CPU %d got hotplugged\n", pr->id); | 860 | pr_info("CPU %d got hotplugged\n", pr->id); |
845 | pr->flags.need_hotplug_init = 1; | 861 | pr->flags.need_hotplug_init = 1; |
846 | 862 | ||
847 | return AE_OK; | 863 | return AE_OK; |
@@ -852,8 +868,22 @@ static int acpi_processor_handle_eject(struct acpi_processor *pr) | |||
852 | if (cpu_online(pr->id)) | 868 | if (cpu_online(pr->id)) |
853 | cpu_down(pr->id); | 869 | cpu_down(pr->id); |
854 | 870 | ||
871 | get_online_cpus(); | ||
872 | /* | ||
873 | * The cpu might become online again at this point. So we check whether | ||
874 | * the cpu has been onlined or not. If the cpu became online, it means | ||
875 | * that someone wants to use the cpu. So acpi_processor_handle_eject() | ||
876 | * returns -EAGAIN. | ||
877 | */ | ||
878 | if (unlikely(cpu_online(pr->id))) { | ||
879 | put_online_cpus(); | ||
880 | pr_warn("Failed to remove CPU %d, because other task " | ||
881 | "brought the CPU back online\n", pr->id); | ||
882 | return -EAGAIN; | ||
883 | } | ||
855 | arch_unregister_cpu(pr->id); | 884 | arch_unregister_cpu(pr->id); |
856 | acpi_unmap_lsapic(pr->id); | 885 | acpi_unmap_lsapic(pr->id); |
886 | put_online_cpus(); | ||
857 | return (0); | 887 | return (0); |
858 | } | 888 | } |
859 | #else | 889 | #else |
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 2976058e6e8e..67a7fa638f7f 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
@@ -108,6 +108,7 @@ void acpi_bus_hot_remove_device(void *context) | |||
108 | struct acpi_eject_event *ej_event = (struct acpi_eject_event *) context; | 108 | struct acpi_eject_event *ej_event = (struct acpi_eject_event *) context; |
109 | struct acpi_device *device; | 109 | struct acpi_device *device; |
110 | acpi_handle handle = ej_event->handle; | 110 | acpi_handle handle = ej_event->handle; |
111 | acpi_handle temp; | ||
111 | struct acpi_object_list arg_list; | 112 | struct acpi_object_list arg_list; |
112 | union acpi_object arg; | 113 | union acpi_object arg; |
113 | acpi_status status = AE_OK; | 114 | acpi_status status = AE_OK; |
@@ -128,13 +129,16 @@ void acpi_bus_hot_remove_device(void *context) | |||
128 | goto err_out; | 129 | goto err_out; |
129 | } | 130 | } |
130 | 131 | ||
132 | /* device has been freed */ | ||
133 | device = NULL; | ||
134 | |||
131 | /* power off device */ | 135 | /* power off device */ |
132 | status = acpi_evaluate_object(handle, "_PS3", NULL, NULL); | 136 | status = acpi_evaluate_object(handle, "_PS3", NULL, NULL); |
133 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) | 137 | if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) |
134 | printk(KERN_WARNING PREFIX | 138 | printk(KERN_WARNING PREFIX |
135 | "Power-off device failed\n"); | 139 | "Power-off device failed\n"); |
136 | 140 | ||
137 | if (device->flags.lockable) { | 141 | if (ACPI_SUCCESS(acpi_get_handle(handle, "_LCK", &temp))) { |
138 | arg_list.count = 1; | 142 | arg_list.count = 1; |
139 | arg_list.pointer = &arg; | 143 | arg_list.pointer = &arg; |
140 | arg.type = ACPI_TYPE_INTEGER; | 144 | arg.type = ACPI_TYPE_INTEGER; |
@@ -168,6 +172,7 @@ err_out: | |||
168 | kfree(context); | 172 | kfree(context); |
169 | return; | 173 | return; |
170 | } | 174 | } |
175 | EXPORT_SYMBOL(acpi_bus_hot_remove_device); | ||
171 | 176 | ||
172 | static ssize_t | 177 | static ssize_t |
173 | acpi_eject_store(struct device *d, struct device_attribute *attr, | 178 | acpi_eject_store(struct device *d, struct device_attribute *attr, |
@@ -227,6 +232,25 @@ acpi_device_hid_show(struct device *dev, struct device_attribute *attr, char *bu | |||
227 | } | 232 | } |
228 | static DEVICE_ATTR(hid, 0444, acpi_device_hid_show, NULL); | 233 | static DEVICE_ATTR(hid, 0444, acpi_device_hid_show, NULL); |
229 | 234 | ||
235 | static ssize_t acpi_device_uid_show(struct device *dev, | ||
236 | struct device_attribute *attr, char *buf) | ||
237 | { | ||
238 | struct acpi_device *acpi_dev = to_acpi_device(dev); | ||
239 | |||
240 | return sprintf(buf, "%s\n", acpi_dev->pnp.unique_id); | ||
241 | } | ||
242 | static DEVICE_ATTR(uid, 0444, acpi_device_uid_show, NULL); | ||
243 | |||
244 | static ssize_t acpi_device_adr_show(struct device *dev, | ||
245 | struct device_attribute *attr, char *buf) | ||
246 | { | ||
247 | struct acpi_device *acpi_dev = to_acpi_device(dev); | ||
248 | |||
249 | return sprintf(buf, "0x%08x\n", | ||
250 | (unsigned int)(acpi_dev->pnp.bus_address)); | ||
251 | } | ||
252 | static DEVICE_ATTR(adr, 0444, acpi_device_adr_show, NULL); | ||
253 | |||
230 | static ssize_t | 254 | static ssize_t |
231 | acpi_device_path_show(struct device *dev, struct device_attribute *attr, char *buf) { | 255 | acpi_device_path_show(struct device *dev, struct device_attribute *attr, char *buf) { |
232 | struct acpi_device *acpi_dev = to_acpi_device(dev); | 256 | struct acpi_device *acpi_dev = to_acpi_device(dev); |
@@ -270,11 +294,21 @@ static ssize_t description_show(struct device *dev, | |||
270 | } | 294 | } |
271 | static DEVICE_ATTR(description, 0444, description_show, NULL); | 295 | static DEVICE_ATTR(description, 0444, description_show, NULL); |
272 | 296 | ||
297 | static ssize_t | ||
298 | acpi_device_sun_show(struct device *dev, struct device_attribute *attr, | ||
299 | char *buf) { | ||
300 | struct acpi_device *acpi_dev = to_acpi_device(dev); | ||
301 | |||
302 | return sprintf(buf, "%lu\n", acpi_dev->pnp.sun); | ||
303 | } | ||
304 | static DEVICE_ATTR(sun, 0444, acpi_device_sun_show, NULL); | ||
305 | |||
273 | static int acpi_device_setup_files(struct acpi_device *dev) | 306 | static int acpi_device_setup_files(struct acpi_device *dev) |
274 | { | 307 | { |
275 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; | 308 | struct acpi_buffer buffer = {ACPI_ALLOCATE_BUFFER, NULL}; |
276 | acpi_status status; | 309 | acpi_status status; |
277 | acpi_handle temp; | 310 | acpi_handle temp; |
311 | unsigned long long sun; | ||
278 | int result = 0; | 312 | int result = 0; |
279 | 313 | ||
280 | /* | 314 | /* |
@@ -311,6 +345,21 @@ static int acpi_device_setup_files(struct acpi_device *dev) | |||
311 | goto end; | 345 | goto end; |
312 | } | 346 | } |
313 | 347 | ||
348 | if (dev->flags.bus_address) | ||
349 | result = device_create_file(&dev->dev, &dev_attr_adr); | ||
350 | if (dev->pnp.unique_id) | ||
351 | result = device_create_file(&dev->dev, &dev_attr_uid); | ||
352 | |||
353 | status = acpi_evaluate_integer(dev->handle, "_SUN", NULL, &sun); | ||
354 | if (ACPI_SUCCESS(status)) { | ||
355 | dev->pnp.sun = (unsigned long)sun; | ||
356 | result = device_create_file(&dev->dev, &dev_attr_sun); | ||
357 | if (result) | ||
358 | goto end; | ||
359 | } else { | ||
360 | dev->pnp.sun = (unsigned long)-1; | ||
361 | } | ||
362 | |||
314 | /* | 363 | /* |
315 | * If device has _EJ0, 'eject' file is created that is used to trigger | 364 | * If device has _EJ0, 'eject' file is created that is used to trigger |
316 | * hot-removal function from userland. | 365 | * hot-removal function from userland. |
@@ -342,6 +391,14 @@ static void acpi_device_remove_files(struct acpi_device *dev) | |||
342 | if (ACPI_SUCCESS(status)) | 391 | if (ACPI_SUCCESS(status)) |
343 | device_remove_file(&dev->dev, &dev_attr_eject); | 392 | device_remove_file(&dev->dev, &dev_attr_eject); |
344 | 393 | ||
394 | status = acpi_get_handle(dev->handle, "_SUN", &temp); | ||
395 | if (ACPI_SUCCESS(status)) | ||
396 | device_remove_file(&dev->dev, &dev_attr_sun); | ||
397 | |||
398 | if (dev->pnp.unique_id) | ||
399 | device_remove_file(&dev->dev, &dev_attr_uid); | ||
400 | if (dev->flags.bus_address) | ||
401 | device_remove_file(&dev->dev, &dev_attr_adr); | ||
345 | device_remove_file(&dev->dev, &dev_attr_modalias); | 402 | device_remove_file(&dev->dev, &dev_attr_modalias); |
346 | device_remove_file(&dev->dev, &dev_attr_hid); | 403 | device_remove_file(&dev->dev, &dev_attr_hid); |
347 | if (dev->handle) | 404 | if (dev->handle) |
@@ -418,6 +475,7 @@ static void acpi_device_release(struct device *dev) | |||
418 | struct acpi_device *acpi_dev = to_acpi_device(dev); | 475 | struct acpi_device *acpi_dev = to_acpi_device(dev); |
419 | 476 | ||
420 | acpi_free_ids(acpi_dev); | 477 | acpi_free_ids(acpi_dev); |
478 | kfree(acpi_dev->pnp.unique_id); | ||
421 | kfree(acpi_dev); | 479 | kfree(acpi_dev); |
422 | } | 480 | } |
423 | 481 | ||
@@ -1061,11 +1119,6 @@ static int acpi_bus_get_flags(struct acpi_device *device) | |||
1061 | device->flags.ejectable = 1; | 1119 | device->flags.ejectable = 1; |
1062 | } | 1120 | } |
1063 | 1121 | ||
1064 | /* Presence of _LCK indicates 'lockable' */ | ||
1065 | status = acpi_get_handle(device->handle, "_LCK", &temp); | ||
1066 | if (ACPI_SUCCESS(status)) | ||
1067 | device->flags.lockable = 1; | ||
1068 | |||
1069 | /* Power resources cannot be power manageable. */ | 1122 | /* Power resources cannot be power manageable. */ |
1070 | if (device->device_type == ACPI_BUS_TYPE_POWER) | 1123 | if (device->device_type == ACPI_BUS_TYPE_POWER) |
1071 | return 0; | 1124 | return 0; |
@@ -1260,6 +1313,9 @@ static void acpi_device_set_id(struct acpi_device *device) | |||
1260 | device->pnp.bus_address = info->address; | 1313 | device->pnp.bus_address = info->address; |
1261 | device->flags.bus_address = 1; | 1314 | device->flags.bus_address = 1; |
1262 | } | 1315 | } |
1316 | if (info->valid & ACPI_VALID_UID) | ||
1317 | device->pnp.unique_id = kstrdup(info->unique_id.string, | ||
1318 | GFP_KERNEL); | ||
1263 | 1319 | ||
1264 | kfree(info); | 1320 | kfree(info); |
1265 | 1321 | ||
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 13a285dffaca..1e25319164f1 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
@@ -103,6 +103,21 @@ void __init acpi_nvs_nosave(void) | |||
103 | } | 103 | } |
104 | 104 | ||
105 | /* | 105 | /* |
106 | * The ACPI specification wants us to save NVS memory regions during hibernation | ||
107 | * but says nothing about saving NVS during S3. Not all versions of Windows | ||
108 | * save NVS on S3 suspend either, and it is clear that not all systems need | ||
109 | * NVS to be saved at S3 time. To improve suspend/resume time, allow the | ||
110 | * user to disable saving NVS on S3 if their system does not require it, but | ||
111 | * continue to save/restore NVS for S4 as specified. | ||
112 | */ | ||
113 | static bool nvs_nosave_s3; | ||
114 | |||
115 | void __init acpi_nvs_nosave_s3(void) | ||
116 | { | ||
117 | nvs_nosave_s3 = true; | ||
118 | } | ||
119 | |||
120 | /* | ||
106 | * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the | 121 | * ACPI 1.0 wants us to execute _PTS before suspending devices, so we allow the |
107 | * user to request that behavior by using the 'acpi_old_suspend_ordering' | 122 | * user to request that behavior by using the 'acpi_old_suspend_ordering' |
108 | * kernel command line option that causes the following variable to be set. | 123 | * kernel command line option that causes the following variable to be set. |
@@ -248,7 +263,7 @@ static int acpi_suspend_begin(suspend_state_t pm_state) | |||
248 | u32 acpi_state = acpi_suspend_states[pm_state]; | 263 | u32 acpi_state = acpi_suspend_states[pm_state]; |
249 | int error = 0; | 264 | int error = 0; |
250 | 265 | ||
251 | error = nvs_nosave ? 0 : suspend_nvs_alloc(); | 266 | error = (nvs_nosave || nvs_nosave_s3) ? 0 : suspend_nvs_alloc(); |
252 | if (error) | 267 | if (error) |
253 | return error; | 268 | return error; |
254 | 269 | ||
@@ -524,6 +539,14 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = { | |||
524 | }, | 539 | }, |
525 | { | 540 | { |
526 | .callback = init_nvs_nosave, | 541 | .callback = init_nvs_nosave, |
542 | .ident = "Sony Vaio VPCEB1S1E", | ||
543 | .matches = { | ||
544 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | ||
545 | DMI_MATCH(DMI_PRODUCT_NAME, "VPCEB1S1E"), | ||
546 | }, | ||
547 | }, | ||
548 | { | ||
549 | .callback = init_nvs_nosave, | ||
527 | .ident = "Sony Vaio VGN-FW520F", | 550 | .ident = "Sony Vaio VGN-FW520F", |
528 | .matches = { | 551 | .matches = { |
529 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), | 552 | DMI_MATCH(DMI_SYS_VENDOR, "Sony Corporation"), |
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 804204d41999..6e8cc16b54c1 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c | |||
@@ -984,6 +984,38 @@ static void acpi_thermal_notify(struct acpi_device *device, u32 event) | |||
984 | } | 984 | } |
985 | } | 985 | } |
986 | 986 | ||
987 | /* | ||
988 | * On some platforms, the AML code has dependency about | ||
989 | * the evaluating order of _TMP and _CRT/_HOT/_PSV/_ACx. | ||
990 | * 1. On HP Pavilion G4-1016tx, _TMP must be invoked after | ||
991 | * /_CRT/_HOT/_PSV/_ACx, or else system will be power off. | ||
992 | * 2. On HP Compaq 6715b/6715s, the return value of _PSV is 0 | ||
993 | * if _TMP has never been evaluated. | ||
994 | * | ||
995 | * As this dependency is totally transparent to OS, evaluate | ||
996 | * all of them once, in the order of _CRT/_HOT/_PSV/_ACx, | ||
997 | * _TMP, before they are actually used. | ||
998 | */ | ||
999 | static void acpi_thermal_aml_dependency_fix(struct acpi_thermal *tz) | ||
1000 | { | ||
1001 | acpi_handle handle = tz->device->handle; | ||
1002 | unsigned long long value; | ||
1003 | int i; | ||
1004 | |||
1005 | acpi_evaluate_integer(handle, "_CRT", NULL, &value); | ||
1006 | acpi_evaluate_integer(handle, "_HOT", NULL, &value); | ||
1007 | acpi_evaluate_integer(handle, "_PSV", NULL, &value); | ||
1008 | for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { | ||
1009 | char name[5] = { '_', 'A', 'C', ('0' + i), '\0' }; | ||
1010 | acpi_status status; | ||
1011 | |||
1012 | status = acpi_evaluate_integer(handle, name, NULL, &value); | ||
1013 | if (status == AE_NOT_FOUND) | ||
1014 | break; | ||
1015 | } | ||
1016 | acpi_evaluate_integer(handle, "_TMP", NULL, &value); | ||
1017 | } | ||
1018 | |||
987 | static int acpi_thermal_get_info(struct acpi_thermal *tz) | 1019 | static int acpi_thermal_get_info(struct acpi_thermal *tz) |
988 | { | 1020 | { |
989 | int result = 0; | 1021 | int result = 0; |
@@ -992,6 +1024,8 @@ static int acpi_thermal_get_info(struct acpi_thermal *tz) | |||
992 | if (!tz) | 1024 | if (!tz) |
993 | return -EINVAL; | 1025 | return -EINVAL; |
994 | 1026 | ||
1027 | acpi_thermal_aml_dependency_fix(tz); | ||
1028 | |||
995 | /* Get trip points [_CRT, _PSV, etc.] (required) */ | 1029 | /* Get trip points [_CRT, _PSV, etc.] (required) */ |
996 | result = acpi_thermal_get_trip_points(tz); | 1030 | result = acpi_thermal_get_trip_points(tz); |
997 | if (result) | 1031 | if (result) |
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c index 462f7e300363..744371304313 100644 --- a/drivers/acpi/utils.c +++ b/drivers/acpi/utils.c | |||
@@ -28,6 +28,8 @@ | |||
28 | #include <linux/slab.h> | 28 | #include <linux/slab.h> |
29 | #include <linux/init.h> | 29 | #include <linux/init.h> |
30 | #include <linux/types.h> | 30 | #include <linux/types.h> |
31 | #include <linux/hardirq.h> | ||
32 | #include <linux/acpi.h> | ||
31 | #include <acpi/acpi_bus.h> | 33 | #include <acpi/acpi_bus.h> |
32 | #include <acpi/acpi_drivers.h> | 34 | #include <acpi/acpi_drivers.h> |
33 | 35 | ||
@@ -457,3 +459,39 @@ acpi_evaluate_hotplug_ost(acpi_handle handle, u32 source_event, | |||
457 | #endif | 459 | #endif |
458 | } | 460 | } |
459 | EXPORT_SYMBOL(acpi_evaluate_hotplug_ost); | 461 | EXPORT_SYMBOL(acpi_evaluate_hotplug_ost); |
462 | |||
463 | /** | ||
464 | * acpi_handle_printk: Print message with ACPI prefix and object path | ||
465 | * | ||
466 | * This function is called through acpi_handle_<level> macros and prints | ||
467 | * a message with ACPI prefix and object path. This function acquires | ||
468 | * the global namespace mutex to obtain an object path. In interrupt | ||
469 | * context, it shows the object path as <n/a>. | ||
470 | */ | ||
471 | void | ||
472 | acpi_handle_printk(const char *level, acpi_handle handle, const char *fmt, ...) | ||
473 | { | ||
474 | struct va_format vaf; | ||
475 | va_list args; | ||
476 | struct acpi_buffer buffer = { | ||
477 | .length = ACPI_ALLOCATE_BUFFER, | ||
478 | .pointer = NULL | ||
479 | }; | ||
480 | const char *path; | ||
481 | |||
482 | va_start(args, fmt); | ||
483 | vaf.fmt = fmt; | ||
484 | vaf.va = &args; | ||
485 | |||
486 | if (in_interrupt() || | ||
487 | acpi_get_name(handle, ACPI_FULL_PATHNAME, &buffer) != AE_OK) | ||
488 | path = "<n/a>"; | ||
489 | else | ||
490 | path = buffer.pointer; | ||
491 | |||
492 | printk("%sACPI: %s: %pV", level, path, &vaf); | ||
493 | |||
494 | va_end(args); | ||
495 | kfree(buffer.pointer); | ||
496 | } | ||
497 | EXPORT_SYMBOL(acpi_handle_printk); | ||
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index c4ed4c2389c7..7ced5dc20dd3 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h | |||
@@ -144,12 +144,11 @@ struct acpi_device_flags { | |||
144 | u32 bus_address:1; | 144 | u32 bus_address:1; |
145 | u32 removable:1; | 145 | u32 removable:1; |
146 | u32 ejectable:1; | 146 | u32 ejectable:1; |
147 | u32 lockable:1; | ||
148 | u32 suprise_removal_ok:1; | 147 | u32 suprise_removal_ok:1; |
149 | u32 power_manageable:1; | 148 | u32 power_manageable:1; |
150 | u32 performance_manageable:1; | 149 | u32 performance_manageable:1; |
151 | u32 eject_pending:1; | 150 | u32 eject_pending:1; |
152 | u32 reserved:23; | 151 | u32 reserved:24; |
153 | }; | 152 | }; |
154 | 153 | ||
155 | /* File System */ | 154 | /* File System */ |
@@ -180,6 +179,7 @@ struct acpi_device_pnp { | |||
180 | acpi_device_name device_name; /* Driver-determined */ | 179 | acpi_device_name device_name; /* Driver-determined */ |
181 | acpi_device_class device_class; /* " */ | 180 | acpi_device_class device_class; /* " */ |
182 | union acpi_object *str_obj; /* unicode string for _STR method */ | 181 | union acpi_object *str_obj; /* unicode string for _STR method */ |
182 | unsigned long sun; /* _SUN */ | ||
183 | }; | 183 | }; |
184 | 184 | ||
185 | #define acpi_device_bid(d) ((d)->pnp.bus_id) | 185 | #define acpi_device_bid(d) ((d)->pnp.bus_id) |
diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 3574e4a2bf14..0f8022baf3fd 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h | |||
@@ -279,10 +279,14 @@ int acpi_check_region(resource_size_t start, resource_size_t n, | |||
279 | 279 | ||
280 | int acpi_resources_are_enforced(void); | 280 | int acpi_resources_are_enforced(void); |
281 | 281 | ||
282 | #ifdef CONFIG_PM_SLEEP | 282 | #ifdef CONFIG_HIBERNATION |
283 | void __init acpi_no_s4_hw_signature(void); | 283 | void __init acpi_no_s4_hw_signature(void); |
284 | #endif | ||
285 | |||
286 | #ifdef CONFIG_PM_SLEEP | ||
284 | void __init acpi_old_suspend_ordering(void); | 287 | void __init acpi_old_suspend_ordering(void); |
285 | void __init acpi_nvs_nosave(void); | 288 | void __init acpi_nvs_nosave(void); |
289 | void __init acpi_nvs_nosave_s3(void); | ||
286 | #endif /* CONFIG_PM_SLEEP */ | 290 | #endif /* CONFIG_PM_SLEEP */ |
287 | 291 | ||
288 | struct acpi_osc_context { | 292 | struct acpi_osc_context { |
@@ -516,4 +520,47 @@ static inline int acpi_dev_pm_attach(struct device *dev, bool power_on) | |||
516 | static inline void acpi_dev_pm_detach(struct device *dev, bool power_off) {} | 520 | static inline void acpi_dev_pm_detach(struct device *dev, bool power_off) {} |
517 | #endif | 521 | #endif |
518 | 522 | ||
523 | #ifdef CONFIG_ACPI | ||
524 | __printf(3, 4) | ||
525 | void acpi_handle_printk(const char *level, acpi_handle handle, | ||
526 | const char *fmt, ...); | ||
527 | #else /* !CONFIG_ACPI */ | ||
528 | static inline __printf(3, 4) void | ||
529 | acpi_handle_printk(const char *level, void *handle, const char *fmt, ...) {} | ||
530 | #endif /* !CONFIG_ACPI */ | ||
531 | |||
532 | /* | ||
533 | * acpi_handle_<level>: Print message with ACPI prefix and object path | ||
534 | * | ||
535 | * These interfaces acquire the global namespace mutex to obtain an object | ||
536 | * path. In interrupt context, it shows the object path as <n/a>. | ||
537 | */ | ||
538 | #define acpi_handle_emerg(handle, fmt, ...) \ | ||
539 | acpi_handle_printk(KERN_EMERG, handle, fmt, ##__VA_ARGS__) | ||
540 | #define acpi_handle_alert(handle, fmt, ...) \ | ||
541 | acpi_handle_printk(KERN_ALERT, handle, fmt, ##__VA_ARGS__) | ||
542 | #define acpi_handle_crit(handle, fmt, ...) \ | ||
543 | acpi_handle_printk(KERN_CRIT, handle, fmt, ##__VA_ARGS__) | ||
544 | #define acpi_handle_err(handle, fmt, ...) \ | ||
545 | acpi_handle_printk(KERN_ERR, handle, fmt, ##__VA_ARGS__) | ||
546 | #define acpi_handle_warn(handle, fmt, ...) \ | ||
547 | acpi_handle_printk(KERN_WARNING, handle, fmt, ##__VA_ARGS__) | ||
548 | #define acpi_handle_notice(handle, fmt, ...) \ | ||
549 | acpi_handle_printk(KERN_NOTICE, handle, fmt, ##__VA_ARGS__) | ||
550 | #define acpi_handle_info(handle, fmt, ...) \ | ||
551 | acpi_handle_printk(KERN_INFO, handle, fmt, ##__VA_ARGS__) | ||
552 | |||
553 | /* REVISIT: Support CONFIG_DYNAMIC_DEBUG when necessary */ | ||
554 | #if defined(DEBUG) || defined(CONFIG_DYNAMIC_DEBUG) | ||
555 | #define acpi_handle_debug(handle, fmt, ...) \ | ||
556 | acpi_handle_printk(KERN_DEBUG, handle, fmt, ##__VA_ARGS__) | ||
557 | #else | ||
558 | #define acpi_handle_debug(handle, fmt, ...) \ | ||
559 | ({ \ | ||
560 | if (0) \ | ||
561 | acpi_handle_printk(KERN_DEBUG, handle, fmt, ##__VA_ARGS__); \ | ||
562 | 0; \ | ||
563 | }) | ||
564 | #endif | ||
565 | |||
519 | #endif /*_LINUX_ACPI_H*/ | 566 | #endif /*_LINUX_ACPI_H*/ |
diff --git a/kernel/cpu.c b/kernel/cpu.c index 42bd331ee0ab..f45657f1eb8e 100644 --- a/kernel/cpu.c +++ b/kernel/cpu.c | |||
@@ -348,11 +348,13 @@ static int __cpuinit _cpu_up(unsigned int cpu, int tasks_frozen) | |||
348 | unsigned long mod = tasks_frozen ? CPU_TASKS_FROZEN : 0; | 348 | unsigned long mod = tasks_frozen ? CPU_TASKS_FROZEN : 0; |
349 | struct task_struct *idle; | 349 | struct task_struct *idle; |
350 | 350 | ||
351 | if (cpu_online(cpu) || !cpu_present(cpu)) | ||
352 | return -EINVAL; | ||
353 | |||
354 | cpu_hotplug_begin(); | 351 | cpu_hotplug_begin(); |
355 | 352 | ||
353 | if (cpu_online(cpu) || !cpu_present(cpu)) { | ||
354 | ret = -EINVAL; | ||
355 | goto out; | ||
356 | } | ||
357 | |||
356 | idle = idle_thread_get(cpu); | 358 | idle = idle_thread_get(cpu); |
357 | if (IS_ERR(idle)) { | 359 | if (IS_ERR(idle)) { |
358 | ret = PTR_ERR(idle); | 360 | ret = PTR_ERR(idle); |