diff options
| author | Ingo Molnar <mingo@elte.hu> | 2011-03-15 03:29:44 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2011-03-15 03:29:44 -0400 |
| commit | 8460b3e5bc64955aeefdd8357b3bf7b5ff79b3f2 (patch) | |
| tree | 7e5f6d050b72ab08a4497e82a4a103fefb086e80 /drivers/acpi | |
| parent | 56396e6823fe9b42fe9cf9403d6ed67756255f70 (diff) | |
| parent | 521cb40b0c44418a4fd36dc633f575813d59a43d (diff) | |
Merge commit 'v2.6.38' into x86/mm
Conflicts:
arch/x86/mm/numa_64.c
Merge reason: Resolve the conflict, update the branch to .38.
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'drivers/acpi')
| -rw-r--r-- | drivers/acpi/acpica/aclocal.h | 7 | ||||
| -rw-r--r-- | drivers/acpi/acpica/evgpe.c | 17 | ||||
| -rw-r--r-- | drivers/acpi/acpica/evxfgpe.c | 67 | ||||
| -rw-r--r-- | drivers/acpi/debugfs.c | 20 | ||||
| -rw-r--r-- | drivers/acpi/osl.c | 25 | ||||
| -rw-r--r-- | drivers/acpi/video_detect.c | 5 | ||||
| -rw-r--r-- | drivers/acpi/wakeup.c | 6 |
7 files changed, 108 insertions, 39 deletions
diff --git a/drivers/acpi/acpica/aclocal.h b/drivers/acpi/acpica/aclocal.h index 54784bb42cec..edc25867ad9d 100644 --- a/drivers/acpi/acpica/aclocal.h +++ b/drivers/acpi/acpica/aclocal.h | |||
| @@ -416,10 +416,15 @@ struct acpi_gpe_handler_info { | |||
| 416 | u8 originally_enabled; /* True if GPE was originally enabled */ | 416 | u8 originally_enabled; /* True if GPE was originally enabled */ |
| 417 | }; | 417 | }; |
| 418 | 418 | ||
| 419 | struct acpi_gpe_notify_object { | ||
| 420 | struct acpi_namespace_node *node; | ||
| 421 | struct acpi_gpe_notify_object *next; | ||
| 422 | }; | ||
| 423 | |||
| 419 | union acpi_gpe_dispatch_info { | 424 | union acpi_gpe_dispatch_info { |
| 420 | struct acpi_namespace_node *method_node; /* Method node for this GPE level */ | 425 | struct acpi_namespace_node *method_node; /* Method node for this GPE level */ |
| 421 | struct acpi_gpe_handler_info *handler; /* Installed GPE handler */ | 426 | struct acpi_gpe_handler_info *handler; /* Installed GPE handler */ |
| 422 | struct acpi_namespace_node *device_node; /* Parent _PRW device for implicit notify */ | 427 | struct acpi_gpe_notify_object device; /* List of _PRW devices for implicit notify */ |
| 423 | }; | 428 | }; |
| 424 | 429 | ||
| 425 | /* | 430 | /* |
diff --git a/drivers/acpi/acpica/evgpe.c b/drivers/acpi/acpica/evgpe.c index 14988a86066f..f4725212eb48 100644 --- a/drivers/acpi/acpica/evgpe.c +++ b/drivers/acpi/acpica/evgpe.c | |||
| @@ -457,6 +457,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) | |||
| 457 | acpi_status status; | 457 | acpi_status status; |
| 458 | struct acpi_gpe_event_info *local_gpe_event_info; | 458 | struct acpi_gpe_event_info *local_gpe_event_info; |
| 459 | struct acpi_evaluate_info *info; | 459 | struct acpi_evaluate_info *info; |
| 460 | struct acpi_gpe_notify_object *notify_object; | ||
| 460 | 461 | ||
| 461 | ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method); | 462 | ACPI_FUNCTION_TRACE(ev_asynch_execute_gpe_method); |
| 462 | 463 | ||
| @@ -508,10 +509,18 @@ static void ACPI_SYSTEM_XFACE acpi_ev_asynch_execute_gpe_method(void *context) | |||
| 508 | * from this thread -- because handlers may in turn run other | 509 | * from this thread -- because handlers may in turn run other |
| 509 | * control methods. | 510 | * control methods. |
| 510 | */ | 511 | */ |
| 511 | status = | 512 | status = acpi_ev_queue_notify_request( |
| 512 | acpi_ev_queue_notify_request(local_gpe_event_info->dispatch. | 513 | local_gpe_event_info->dispatch.device.node, |
| 513 | device_node, | 514 | ACPI_NOTIFY_DEVICE_WAKE); |
| 514 | ACPI_NOTIFY_DEVICE_WAKE); | 515 | |
| 516 | notify_object = local_gpe_event_info->dispatch.device.next; | ||
| 517 | while (ACPI_SUCCESS(status) && notify_object) { | ||
| 518 | status = acpi_ev_queue_notify_request( | ||
| 519 | notify_object->node, | ||
| 520 | ACPI_NOTIFY_DEVICE_WAKE); | ||
| 521 | notify_object = notify_object->next; | ||
| 522 | } | ||
| 523 | |||
| 515 | break; | 524 | break; |
| 516 | 525 | ||
| 517 | case ACPI_GPE_DISPATCH_METHOD: | 526 | case ACPI_GPE_DISPATCH_METHOD: |
diff --git a/drivers/acpi/acpica/evxfgpe.c b/drivers/acpi/acpica/evxfgpe.c index e9562a7cb2f9..52aaff3df562 100644 --- a/drivers/acpi/acpica/evxfgpe.c +++ b/drivers/acpi/acpica/evxfgpe.c | |||
| @@ -198,7 +198,9 @@ acpi_setup_gpe_for_wake(acpi_handle wake_device, | |||
| 198 | acpi_status status = AE_BAD_PARAMETER; | 198 | acpi_status status = AE_BAD_PARAMETER; |
| 199 | struct acpi_gpe_event_info *gpe_event_info; | 199 | struct acpi_gpe_event_info *gpe_event_info; |
| 200 | struct acpi_namespace_node *device_node; | 200 | struct acpi_namespace_node *device_node; |
| 201 | struct acpi_gpe_notify_object *notify_object; | ||
| 201 | acpi_cpu_flags flags; | 202 | acpi_cpu_flags flags; |
| 203 | u8 gpe_dispatch_mask; | ||
| 202 | 204 | ||
| 203 | ACPI_FUNCTION_TRACE(acpi_setup_gpe_for_wake); | 205 | ACPI_FUNCTION_TRACE(acpi_setup_gpe_for_wake); |
| 204 | 206 | ||
| @@ -212,37 +214,62 @@ acpi_setup_gpe_for_wake(acpi_handle wake_device, | |||
| 212 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 214 | return_ACPI_STATUS(AE_BAD_PARAMETER); |
| 213 | } | 215 | } |
| 214 | 216 | ||
| 217 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | ||
| 218 | |||
| 219 | /* Ensure that we have a valid GPE number */ | ||
| 220 | |||
| 221 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | ||
| 222 | if (!gpe_event_info) { | ||
| 223 | goto unlock_and_exit; | ||
| 224 | } | ||
| 225 | |||
| 226 | if (wake_device == ACPI_ROOT_OBJECT) { | ||
| 227 | goto out; | ||
| 228 | } | ||
| 229 | |||
| 230 | /* | ||
| 231 | * If there is no method or handler for this GPE, then the | ||
| 232 | * wake_device will be notified whenever this GPE fires (aka | ||
| 233 | * "implicit notify") Note: The GPE is assumed to be | ||
| 234 | * level-triggered (for windows compatibility). | ||
| 235 | */ | ||
| 236 | gpe_dispatch_mask = gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK; | ||
| 237 | if (gpe_dispatch_mask != ACPI_GPE_DISPATCH_NONE | ||
| 238 | && gpe_dispatch_mask != ACPI_GPE_DISPATCH_NOTIFY) { | ||
| 239 | goto out; | ||
| 240 | } | ||
| 241 | |||
| 215 | /* Validate wake_device is of type Device */ | 242 | /* Validate wake_device is of type Device */ |
| 216 | 243 | ||
| 217 | device_node = ACPI_CAST_PTR(struct acpi_namespace_node, wake_device); | 244 | device_node = ACPI_CAST_PTR(struct acpi_namespace_node, wake_device); |
| 218 | if (device_node->type != ACPI_TYPE_DEVICE) { | 245 | if (device_node->type != ACPI_TYPE_DEVICE) { |
| 219 | return_ACPI_STATUS(AE_BAD_PARAMETER); | 246 | goto unlock_and_exit; |
| 220 | } | 247 | } |
| 221 | 248 | ||
| 222 | flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); | 249 | if (gpe_dispatch_mask == ACPI_GPE_DISPATCH_NONE) { |
| 250 | gpe_event_info->flags = (ACPI_GPE_DISPATCH_NOTIFY | | ||
| 251 | ACPI_GPE_LEVEL_TRIGGERED); | ||
| 252 | gpe_event_info->dispatch.device.node = device_node; | ||
| 253 | gpe_event_info->dispatch.device.next = NULL; | ||
| 254 | } else { | ||
| 255 | /* There are multiple devices to notify implicitly. */ | ||
| 223 | 256 | ||
| 224 | /* Ensure that we have a valid GPE number */ | 257 | notify_object = ACPI_ALLOCATE_ZEROED(sizeof(*notify_object)); |
| 225 | 258 | if (!notify_object) { | |
| 226 | gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); | 259 | status = AE_NO_MEMORY; |
| 227 | if (gpe_event_info) { | 260 | goto unlock_and_exit; |
| 228 | /* | ||
| 229 | * If there is no method or handler for this GPE, then the | ||
| 230 | * wake_device will be notified whenever this GPE fires (aka | ||
| 231 | * "implicit notify") Note: The GPE is assumed to be | ||
| 232 | * level-triggered (for windows compatibility). | ||
| 233 | */ | ||
| 234 | if ((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == | ||
| 235 | ACPI_GPE_DISPATCH_NONE) { | ||
| 236 | gpe_event_info->flags = | ||
| 237 | (ACPI_GPE_DISPATCH_NOTIFY | | ||
| 238 | ACPI_GPE_LEVEL_TRIGGERED); | ||
| 239 | gpe_event_info->dispatch.device_node = device_node; | ||
| 240 | } | 261 | } |
| 241 | 262 | ||
| 242 | gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; | 263 | notify_object->node = device_node; |
| 243 | status = AE_OK; | 264 | notify_object->next = gpe_event_info->dispatch.device.next; |
| 265 | gpe_event_info->dispatch.device.next = notify_object; | ||
| 244 | } | 266 | } |
| 245 | 267 | ||
| 268 | out: | ||
| 269 | gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; | ||
| 270 | status = AE_OK; | ||
| 271 | |||
| 272 | unlock_and_exit: | ||
| 246 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); | 273 | acpi_os_release_lock(acpi_gbl_gpe_lock, flags); |
| 247 | return_ACPI_STATUS(status); | 274 | return_ACPI_STATUS(status); |
| 248 | } | 275 | } |
diff --git a/drivers/acpi/debugfs.c b/drivers/acpi/debugfs.c index 5df67f1d6c61..384f7abcff77 100644 --- a/drivers/acpi/debugfs.c +++ b/drivers/acpi/debugfs.c | |||
| @@ -26,7 +26,9 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf, | |||
| 26 | size_t count, loff_t *ppos) | 26 | size_t count, loff_t *ppos) |
| 27 | { | 27 | { |
| 28 | static char *buf; | 28 | static char *buf; |
| 29 | static int uncopied_bytes; | 29 | static u32 max_size; |
| 30 | static u32 uncopied_bytes; | ||
| 31 | |||
| 30 | struct acpi_table_header table; | 32 | struct acpi_table_header table; |
| 31 | acpi_status status; | 33 | acpi_status status; |
| 32 | 34 | ||
| @@ -37,19 +39,24 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf, | |||
| 37 | if (copy_from_user(&table, user_buf, | 39 | if (copy_from_user(&table, user_buf, |
| 38 | sizeof(struct acpi_table_header))) | 40 | sizeof(struct acpi_table_header))) |
| 39 | return -EFAULT; | 41 | return -EFAULT; |
| 40 | uncopied_bytes = table.length; | 42 | uncopied_bytes = max_size = table.length; |
| 41 | buf = kzalloc(uncopied_bytes, GFP_KERNEL); | 43 | buf = kzalloc(max_size, GFP_KERNEL); |
| 42 | if (!buf) | 44 | if (!buf) |
| 43 | return -ENOMEM; | 45 | return -ENOMEM; |
| 44 | } | 46 | } |
| 45 | 47 | ||
| 46 | if (uncopied_bytes < count) { | 48 | if (buf == NULL) |
| 47 | kfree(buf); | 49 | return -EINVAL; |
| 50 | |||
| 51 | if ((*ppos > max_size) || | ||
| 52 | (*ppos + count > max_size) || | ||
| 53 | (*ppos + count < count) || | ||
| 54 | (count > uncopied_bytes)) | ||
| 48 | return -EINVAL; | 55 | return -EINVAL; |
| 49 | } | ||
| 50 | 56 | ||
| 51 | if (copy_from_user(buf + (*ppos), user_buf, count)) { | 57 | if (copy_from_user(buf + (*ppos), user_buf, count)) { |
| 52 | kfree(buf); | 58 | kfree(buf); |
| 59 | buf = NULL; | ||
| 53 | return -EFAULT; | 60 | return -EFAULT; |
| 54 | } | 61 | } |
| 55 | 62 | ||
| @@ -59,6 +66,7 @@ static ssize_t cm_write(struct file *file, const char __user * user_buf, | |||
| 59 | if (!uncopied_bytes) { | 66 | if (!uncopied_bytes) { |
| 60 | status = acpi_install_method(buf); | 67 | status = acpi_install_method(buf); |
| 61 | kfree(buf); | 68 | kfree(buf); |
| 69 | buf = NULL; | ||
| 62 | if (ACPI_FAILURE(status)) | 70 | if (ACPI_FAILURE(status)) |
| 63 | return -EINVAL; | 71 | return -EINVAL; |
| 64 | add_taint(TAINT_OVERRIDDEN_ACPI_TABLE); | 72 | add_taint(TAINT_OVERRIDDEN_ACPI_TABLE); |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index b0931818cf98..c90c76aa7f8b 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
| @@ -636,17 +636,21 @@ EXPORT_SYMBOL(acpi_os_write_port); | |||
| 636 | acpi_status | 636 | acpi_status |
| 637 | acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width) | 637 | acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width) |
| 638 | { | 638 | { |
| 639 | u32 dummy; | ||
| 640 | void __iomem *virt_addr; | 639 | void __iomem *virt_addr; |
| 641 | int size = width / 8, unmap = 0; | 640 | unsigned int size = width / 8; |
| 641 | bool unmap = false; | ||
| 642 | u32 dummy; | ||
| 642 | 643 | ||
| 643 | rcu_read_lock(); | 644 | rcu_read_lock(); |
| 644 | virt_addr = acpi_map_vaddr_lookup(phys_addr, size); | 645 | virt_addr = acpi_map_vaddr_lookup(phys_addr, size); |
| 645 | rcu_read_unlock(); | ||
| 646 | if (!virt_addr) { | 646 | if (!virt_addr) { |
| 647 | rcu_read_unlock(); | ||
| 647 | virt_addr = acpi_os_ioremap(phys_addr, size); | 648 | virt_addr = acpi_os_ioremap(phys_addr, size); |
| 648 | unmap = 1; | 649 | if (!virt_addr) |
| 650 | return AE_BAD_ADDRESS; | ||
| 651 | unmap = true; | ||
| 649 | } | 652 | } |
| 653 | |||
| 650 | if (!value) | 654 | if (!value) |
| 651 | value = &dummy; | 655 | value = &dummy; |
| 652 | 656 | ||
| @@ -666,6 +670,8 @@ acpi_os_read_memory(acpi_physical_address phys_addr, u32 * value, u32 width) | |||
| 666 | 670 | ||
| 667 | if (unmap) | 671 | if (unmap) |
| 668 | iounmap(virt_addr); | 672 | iounmap(virt_addr); |
| 673 | else | ||
| 674 | rcu_read_unlock(); | ||
| 669 | 675 | ||
| 670 | return AE_OK; | 676 | return AE_OK; |
| 671 | } | 677 | } |
| @@ -674,14 +680,17 @@ acpi_status | |||
| 674 | acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width) | 680 | acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width) |
| 675 | { | 681 | { |
| 676 | void __iomem *virt_addr; | 682 | void __iomem *virt_addr; |
| 677 | int size = width / 8, unmap = 0; | 683 | unsigned int size = width / 8; |
| 684 | bool unmap = false; | ||
| 678 | 685 | ||
| 679 | rcu_read_lock(); | 686 | rcu_read_lock(); |
| 680 | virt_addr = acpi_map_vaddr_lookup(phys_addr, size); | 687 | virt_addr = acpi_map_vaddr_lookup(phys_addr, size); |
| 681 | rcu_read_unlock(); | ||
| 682 | if (!virt_addr) { | 688 | if (!virt_addr) { |
| 689 | rcu_read_unlock(); | ||
| 683 | virt_addr = acpi_os_ioremap(phys_addr, size); | 690 | virt_addr = acpi_os_ioremap(phys_addr, size); |
| 684 | unmap = 1; | 691 | if (!virt_addr) |
| 692 | return AE_BAD_ADDRESS; | ||
| 693 | unmap = true; | ||
| 685 | } | 694 | } |
| 686 | 695 | ||
| 687 | switch (width) { | 696 | switch (width) { |
| @@ -700,6 +709,8 @@ acpi_os_write_memory(acpi_physical_address phys_addr, u32 value, u32 width) | |||
| 700 | 709 | ||
| 701 | if (unmap) | 710 | if (unmap) |
| 702 | iounmap(virt_addr); | 711 | iounmap(virt_addr); |
| 712 | else | ||
| 713 | rcu_read_unlock(); | ||
| 703 | 714 | ||
| 704 | return AE_OK; | 715 | return AE_OK; |
| 705 | } | 716 | } |
diff --git a/drivers/acpi/video_detect.c b/drivers/acpi/video_detect.c index 42d3d72dae85..5af3479714f6 100644 --- a/drivers/acpi/video_detect.c +++ b/drivers/acpi/video_detect.c | |||
| @@ -82,6 +82,11 @@ long acpi_is_video_device(struct acpi_device *device) | |||
| 82 | if (!device) | 82 | if (!device) |
| 83 | return 0; | 83 | return 0; |
| 84 | 84 | ||
| 85 | /* Is this device able to support video switching ? */ | ||
| 86 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOD", &h_dummy)) || | ||
| 87 | ACPI_SUCCESS(acpi_get_handle(device->handle, "_DOS", &h_dummy))) | ||
| 88 | video_caps |= ACPI_VIDEO_OUTPUT_SWITCHING; | ||
| 89 | |||
| 85 | /* Is this device able to retrieve a video ROM ? */ | 90 | /* Is this device able to retrieve a video ROM ? */ |
| 86 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy))) | 91 | if (ACPI_SUCCESS(acpi_get_handle(device->handle, "_ROM", &h_dummy))) |
| 87 | video_caps |= ACPI_VIDEO_ROM_AVAILABLE; | 92 | video_caps |= ACPI_VIDEO_ROM_AVAILABLE; |
diff --git a/drivers/acpi/wakeup.c b/drivers/acpi/wakeup.c index ed6501452507..7bfbe40bc43b 100644 --- a/drivers/acpi/wakeup.c +++ b/drivers/acpi/wakeup.c | |||
| @@ -86,8 +86,12 @@ int __init acpi_wakeup_device_init(void) | |||
| 86 | struct acpi_device *dev = container_of(node, | 86 | struct acpi_device *dev = container_of(node, |
| 87 | struct acpi_device, | 87 | struct acpi_device, |
| 88 | wakeup_list); | 88 | wakeup_list); |
| 89 | if (device_can_wakeup(&dev->dev)) | 89 | if (device_can_wakeup(&dev->dev)) { |
| 90 | /* Button GPEs are supposed to be always enabled. */ | ||
| 91 | acpi_enable_gpe(dev->wakeup.gpe_device, | ||
| 92 | dev->wakeup.gpe_number); | ||
| 90 | device_set_wakeup_enable(&dev->dev, true); | 93 | device_set_wakeup_enable(&dev->dev, true); |
| 94 | } | ||
| 91 | } | 95 | } |
| 92 | mutex_unlock(&acpi_device_lock); | 96 | mutex_unlock(&acpi_device_lock); |
| 93 | return 0; | 97 | return 0; |
