diff options
| -rw-r--r-- | arch/ia64/include/asm/acpi.h | 6 | ||||
| -rw-r--r-- | arch/ia64/kernel/acpi.c | 14 | ||||
| -rw-r--r-- | arch/x86/include/asm/acpi.h | 5 | ||||
| -rw-r--r-- | arch/x86/kernel/acpi/sleep.c | 13 | ||||
| -rw-r--r-- | arch/x86/kernel/acpi/sleep.h | 2 | ||||
| -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 | 42 | ||||
| -rw-r--r-- | drivers/acpi/button.c | 11 | ||||
| -rw-r--r-- | drivers/acpi/debugfs.c | 20 | ||||
| -rw-r--r-- | drivers/acpi/osl.c | 27 | ||||
| -rw-r--r-- | drivers/acpi/scan.c | 1 | ||||
| -rw-r--r-- | drivers/acpi/sleep.c | 28 | ||||
| -rw-r--r-- | drivers/pci/pci-acpi.c | 16 | ||||
| -rw-r--r-- | include/acpi/acpi_bus.h | 1 |
15 files changed, 109 insertions, 101 deletions
diff --git a/arch/ia64/include/asm/acpi.h b/arch/ia64/include/asm/acpi.h index 837dc82a013e..a06dfb13d518 100644 --- a/arch/ia64/include/asm/acpi.h +++ b/arch/ia64/include/asm/acpi.h | |||
| @@ -128,9 +128,9 @@ static inline const char *acpi_get_sysname (void) | |||
| 128 | int acpi_request_vector (u32 int_type); | 128 | int acpi_request_vector (u32 int_type); |
| 129 | int acpi_gsi_to_irq (u32 gsi, unsigned int *irq); | 129 | int acpi_gsi_to_irq (u32 gsi, unsigned int *irq); |
| 130 | 130 | ||
| 131 | /* routines for saving/restoring kernel state */ | 131 | /* Low-level suspend routine. */ |
| 132 | extern int acpi_save_state_mem(void); | 132 | extern int acpi_suspend_lowlevel(void); |
| 133 | extern void acpi_restore_state_mem(void); | 133 | |
| 134 | extern unsigned long acpi_wakeup_address; | 134 | extern unsigned long acpi_wakeup_address; |
| 135 | 135 | ||
| 136 | /* | 136 | /* |
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c index 90ebceb899a0..a54d054ed4b0 100644 --- a/arch/ia64/kernel/acpi.c +++ b/arch/ia64/kernel/acpi.c | |||
| @@ -1034,18 +1034,8 @@ int acpi_unregister_ioapic(acpi_handle handle, u32 gsi_base) | |||
| 1034 | EXPORT_SYMBOL(acpi_unregister_ioapic); | 1034 | EXPORT_SYMBOL(acpi_unregister_ioapic); |
| 1035 | 1035 | ||
| 1036 | /* | 1036 | /* |
| 1037 | * acpi_save_state_mem() - save kernel state | 1037 | * acpi_suspend_lowlevel() - save kernel state and suspend. |
| 1038 | * | 1038 | * |
| 1039 | * TBD when when IA64 starts to support suspend... | 1039 | * TBD when when IA64 starts to support suspend... |
| 1040 | */ | 1040 | */ |
| 1041 | int acpi_save_state_mem(void) { return 0; } | 1041 | int acpi_suspend_lowlevel(void) { return 0; } |
| 1042 | |||
| 1043 | /* | ||
| 1044 | * acpi_restore_state() | ||
| 1045 | */ | ||
| 1046 | void acpi_restore_state_mem(void) {} | ||
| 1047 | |||
| 1048 | /* | ||
| 1049 | * do_suspend_lowlevel() | ||
| 1050 | */ | ||
| 1051 | void do_suspend_lowlevel(void) {} | ||
diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index 211ca3f7fd16..aa92684aa674 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h | |||
| @@ -112,9 +112,8 @@ static inline void acpi_disable_pci(void) | |||
| 112 | acpi_noirq_set(); | 112 | acpi_noirq_set(); |
| 113 | } | 113 | } |
| 114 | 114 | ||
| 115 | /* routines for saving/restoring kernel state */ | 115 | /* Low-level suspend routine. */ |
| 116 | extern int acpi_save_state_mem(void); | 116 | extern int acpi_suspend_lowlevel(void); |
| 117 | extern void acpi_restore_state_mem(void); | ||
| 118 | 117 | ||
| 119 | extern unsigned long acpi_wakeup_address; | 118 | extern unsigned long acpi_wakeup_address; |
| 120 | 119 | ||
diff --git a/arch/x86/kernel/acpi/sleep.c b/arch/x86/kernel/acpi/sleep.c index 68d1537b8c81..5f1b747f6ef1 100644 --- a/arch/x86/kernel/acpi/sleep.c +++ b/arch/x86/kernel/acpi/sleep.c | |||
| @@ -29,14 +29,14 @@ static char temp_stack[4096]; | |||
| 29 | #endif | 29 | #endif |
| 30 | 30 | ||
| 31 | /** | 31 | /** |
| 32 | * acpi_save_state_mem - save kernel state | 32 | * acpi_suspend_lowlevel - save kernel state |
| 33 | * | 33 | * |
| 34 | * Create an identity mapped page table and copy the wakeup routine to | 34 | * Create an identity mapped page table and copy the wakeup routine to |
| 35 | * low memory. | 35 | * low memory. |
| 36 | * | 36 | * |
| 37 | * Note that this is too late to change acpi_wakeup_address. | 37 | * Note that this is too late to change acpi_wakeup_address. |
| 38 | */ | 38 | */ |
| 39 | int acpi_save_state_mem(void) | 39 | int acpi_suspend_lowlevel(void) |
| 40 | { | 40 | { |
| 41 | struct wakeup_header *header; | 41 | struct wakeup_header *header; |
| 42 | 42 | ||
| @@ -107,17 +107,10 @@ int acpi_save_state_mem(void) | |||
| 107 | saved_magic = 0x123456789abcdef0L; | 107 | saved_magic = 0x123456789abcdef0L; |
| 108 | #endif /* CONFIG_64BIT */ | 108 | #endif /* CONFIG_64BIT */ |
| 109 | 109 | ||
| 110 | do_suspend_lowlevel(); | ||
| 110 | return 0; | 111 | return 0; |
| 111 | } | 112 | } |
| 112 | 113 | ||
| 113 | /* | ||
| 114 | * acpi_restore_state - undo effects of acpi_save_state_mem | ||
| 115 | */ | ||
| 116 | void acpi_restore_state_mem(void) | ||
| 117 | { | ||
| 118 | } | ||
| 119 | |||
| 120 | |||
| 121 | /** | 114 | /** |
| 122 | * acpi_reserve_wakeup_memory - do _very_ early ACPI initialisation | 115 | * acpi_reserve_wakeup_memory - do _very_ early ACPI initialisation |
| 123 | * | 116 | * |
diff --git a/arch/x86/kernel/acpi/sleep.h b/arch/x86/kernel/acpi/sleep.h index adbcbaa6f1df..31ce13f20297 100644 --- a/arch/x86/kernel/acpi/sleep.h +++ b/arch/x86/kernel/acpi/sleep.h | |||
| @@ -14,3 +14,5 @@ extern char swsusp_pg_dir[PAGE_SIZE]; | |||
| 14 | 14 | ||
| 15 | extern unsigned long acpi_copy_wakeup_routine(unsigned long); | 15 | extern unsigned long acpi_copy_wakeup_routine(unsigned long); |
| 16 | extern void wakeup_long64(void); | 16 | extern void wakeup_long64(void); |
| 17 | |||
| 18 | extern void do_suspend_lowlevel(void); | ||
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 3b20a3401b64..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 | ||
| @@ -221,27 +223,49 @@ acpi_setup_gpe_for_wake(acpi_handle wake_device, | |||
| 221 | goto unlock_and_exit; | 223 | goto unlock_and_exit; |
| 222 | } | 224 | } |
| 223 | 225 | ||
| 226 | if (wake_device == ACPI_ROOT_OBJECT) { | ||
| 227 | goto out; | ||
| 228 | } | ||
| 229 | |||
| 224 | /* | 230 | /* |
| 225 | * If there is no method or handler for this GPE, then the | 231 | * If there is no method or handler for this GPE, then the |
| 226 | * wake_device will be notified whenever this GPE fires (aka | 232 | * wake_device will be notified whenever this GPE fires (aka |
| 227 | * "implicit notify") Note: The GPE is assumed to be | 233 | * "implicit notify") Note: The GPE is assumed to be |
| 228 | * level-triggered (for windows compatibility). | 234 | * level-triggered (for windows compatibility). |
| 229 | */ | 235 | */ |
| 230 | if (((gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK) == | 236 | gpe_dispatch_mask = gpe_event_info->flags & ACPI_GPE_DISPATCH_MASK; |
| 231 | ACPI_GPE_DISPATCH_NONE) && (wake_device != ACPI_ROOT_OBJECT)) { | 237 | if (gpe_dispatch_mask != ACPI_GPE_DISPATCH_NONE |
| 238 | && gpe_dispatch_mask != ACPI_GPE_DISPATCH_NOTIFY) { | ||
| 239 | goto out; | ||
| 240 | } | ||
| 232 | 241 | ||
| 233 | /* Validate wake_device is of type Device */ | 242 | /* Validate wake_device is of type Device */ |
| 234 | 243 | ||
| 235 | device_node = ACPI_CAST_PTR(struct acpi_namespace_node, | 244 | device_node = ACPI_CAST_PTR(struct acpi_namespace_node, wake_device); |
| 236 | wake_device); | 245 | if (device_node->type != ACPI_TYPE_DEVICE) { |
| 237 | if (device_node->type != ACPI_TYPE_DEVICE) { | 246 | goto unlock_and_exit; |
| 238 | goto unlock_and_exit; | 247 | } |
| 239 | } | 248 | |
| 249 | if (gpe_dispatch_mask == ACPI_GPE_DISPATCH_NONE) { | ||
| 240 | gpe_event_info->flags = (ACPI_GPE_DISPATCH_NOTIFY | | 250 | gpe_event_info->flags = (ACPI_GPE_DISPATCH_NOTIFY | |
| 241 | ACPI_GPE_LEVEL_TRIGGERED); | 251 | ACPI_GPE_LEVEL_TRIGGERED); |
| 242 | gpe_event_info->dispatch.device_node = device_node; | 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. */ | ||
| 256 | |||
| 257 | notify_object = ACPI_ALLOCATE_ZEROED(sizeof(*notify_object)); | ||
| 258 | if (!notify_object) { | ||
| 259 | status = AE_NO_MEMORY; | ||
| 260 | goto unlock_and_exit; | ||
| 261 | } | ||
| 262 | |||
| 263 | notify_object->node = device_node; | ||
| 264 | notify_object->next = gpe_event_info->dispatch.device.next; | ||
| 265 | gpe_event_info->dispatch.device.next = notify_object; | ||
| 243 | } | 266 | } |
| 244 | 267 | ||
| 268 | out: | ||
| 245 | gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; | 269 | gpe_event_info->flags |= ACPI_GPE_CAN_WAKE; |
| 246 | status = AE_OK; | 270 | status = AE_OK; |
| 247 | 271 | ||
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 76bbb78a5ad9..12c28f4adb67 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c | |||
| @@ -98,6 +98,7 @@ struct acpi_button { | |||
| 98 | struct input_dev *input; | 98 | struct input_dev *input; |
| 99 | char phys[32]; /* for input device */ | 99 | char phys[32]; /* for input device */ |
| 100 | unsigned long pushed; | 100 | unsigned long pushed; |
| 101 | bool wakeup_enabled; | ||
| 101 | }; | 102 | }; |
| 102 | 103 | ||
| 103 | static const struct file_operations acpi_button_info_fops = { | 104 | static const struct file_operations acpi_button_info_fops = { |
| @@ -430,8 +431,10 @@ static int acpi_button_add(struct acpi_device *device) | |||
| 430 | /* Button's GPE is run-wake GPE */ | 431 | /* Button's GPE is run-wake GPE */ |
| 431 | acpi_enable_gpe(device->wakeup.gpe_device, | 432 | acpi_enable_gpe(device->wakeup.gpe_device, |
| 432 | device->wakeup.gpe_number); | 433 | device->wakeup.gpe_number); |
| 433 | device->wakeup.run_wake_count++; | 434 | if (!device_may_wakeup(&device->dev)) { |
| 434 | device_set_wakeup_enable(&device->dev, true); | 435 | device_set_wakeup_enable(&device->dev, true); |
| 436 | button->wakeup_enabled = true; | ||
| 437 | } | ||
| 435 | } | 438 | } |
| 436 | 439 | ||
| 437 | printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device)); | 440 | printk(KERN_INFO PREFIX "%s [%s]\n", name, acpi_device_bid(device)); |
| @@ -453,8 +456,8 @@ static int acpi_button_remove(struct acpi_device *device, int type) | |||
| 453 | if (device->wakeup.flags.valid) { | 456 | if (device->wakeup.flags.valid) { |
| 454 | acpi_disable_gpe(device->wakeup.gpe_device, | 457 | acpi_disable_gpe(device->wakeup.gpe_device, |
| 455 | device->wakeup.gpe_number); | 458 | device->wakeup.gpe_number); |
| 456 | device->wakeup.run_wake_count--; | 459 | if (button->wakeup_enabled) |
| 457 | device_set_wakeup_enable(&device->dev, false); | 460 | device_set_wakeup_enable(&device->dev, false); |
| 458 | } | 461 | } |
| 459 | 462 | ||
| 460 | acpi_button_remove_fs(device); | 463 | acpi_button_remove_fs(device); |
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 52ca8721bc9c..45c6ac8790d7 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
| @@ -76,7 +76,6 @@ EXPORT_SYMBOL(acpi_in_debugger); | |||
| 76 | extern char line_buf[80]; | 76 | extern char line_buf[80]; |
| 77 | #endif /*ENABLE_DEBUGGER */ | 77 | #endif /*ENABLE_DEBUGGER */ |
| 78 | 78 | ||
| 79 | static unsigned int acpi_irq_irq; | ||
| 80 | static acpi_osd_handler acpi_irq_handler; | 79 | static acpi_osd_handler acpi_irq_handler; |
| 81 | static void *acpi_irq_context; | 80 | static void *acpi_irq_context; |
| 82 | static struct workqueue_struct *kacpid_wq; | 81 | static struct workqueue_struct *kacpid_wq; |
| @@ -532,11 +531,15 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler, | |||
| 532 | acpi_irq_stats_init(); | 531 | acpi_irq_stats_init(); |
| 533 | 532 | ||
| 534 | /* | 533 | /* |
| 535 | * Ignore the GSI from the core, and use the value in our copy of the | 534 | * ACPI interrupts different from the SCI in our copy of the FADT are |
| 536 | * FADT. It may not be the same if an interrupt source override exists | 535 | * not supported. |
| 537 | * for the SCI. | ||
| 538 | */ | 536 | */ |
| 539 | gsi = acpi_gbl_FADT.sci_interrupt; | 537 | if (gsi != acpi_gbl_FADT.sci_interrupt) |
| 538 | return AE_BAD_PARAMETER; | ||
| 539 | |||
| 540 | if (acpi_irq_handler) | ||
| 541 | return AE_ALREADY_ACQUIRED; | ||
| 542 | |||
| 540 | if (acpi_gsi_to_irq(gsi, &irq) < 0) { | 543 | if (acpi_gsi_to_irq(gsi, &irq) < 0) { |
| 541 | printk(KERN_ERR PREFIX "SCI (ACPI GSI %d) not registered\n", | 544 | printk(KERN_ERR PREFIX "SCI (ACPI GSI %d) not registered\n", |
| 542 | gsi); | 545 | gsi); |
| @@ -547,20 +550,20 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler, | |||
| 547 | acpi_irq_context = context; | 550 | acpi_irq_context = context; |
| 548 | if (request_irq(irq, acpi_irq, IRQF_SHARED, "acpi", acpi_irq)) { | 551 | if (request_irq(irq, acpi_irq, IRQF_SHARED, "acpi", acpi_irq)) { |
| 549 | printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq); | 552 | printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq); |
| 553 | acpi_irq_handler = NULL; | ||
| 550 | return AE_NOT_ACQUIRED; | 554 | return AE_NOT_ACQUIRED; |
| 551 | } | 555 | } |
| 552 | acpi_irq_irq = irq; | ||
| 553 | 556 | ||
| 554 | return AE_OK; | 557 | return AE_OK; |
| 555 | } | 558 | } |
| 556 | 559 | ||
| 557 | acpi_status acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler) | 560 | acpi_status acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler) |
| 558 | { | 561 | { |
| 559 | if (irq) { | 562 | if (irq != acpi_gbl_FADT.sci_interrupt) |
| 560 | free_irq(irq, acpi_irq); | 563 | return AE_BAD_PARAMETER; |
| 561 | acpi_irq_handler = NULL; | 564 | |
| 562 | acpi_irq_irq = 0; | 565 | free_irq(irq, acpi_irq); |
| 563 | } | 566 | acpi_irq_handler = NULL; |
| 564 | 567 | ||
| 565 | return AE_OK; | 568 | return AE_OK; |
| 566 | } | 569 | } |
| @@ -1619,7 +1622,7 @@ acpi_status __init acpi_os_initialize1(void) | |||
| 1619 | acpi_status acpi_os_terminate(void) | 1622 | acpi_status acpi_os_terminate(void) |
| 1620 | { | 1623 | { |
| 1621 | if (acpi_irq_handler) { | 1624 | if (acpi_irq_handler) { |
| 1622 | acpi_os_remove_interrupt_handler(acpi_irq_irq, | 1625 | acpi_os_remove_interrupt_handler(acpi_gbl_FADT.sci_interrupt, |
| 1623 | acpi_irq_handler); | 1626 | acpi_irq_handler); |
| 1624 | } | 1627 | } |
| 1625 | 1628 | ||
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index b99e62494607..b136c9c1e531 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c | |||
| @@ -797,7 +797,6 @@ static void acpi_bus_set_run_wake_flags(struct acpi_device *device) | |||
| 797 | acpi_status status; | 797 | acpi_status status; |
| 798 | acpi_event_status event_status; | 798 | acpi_event_status event_status; |
| 799 | 799 | ||
| 800 | device->wakeup.run_wake_count = 0; | ||
| 801 | device->wakeup.flags.notifier_present = 0; | 800 | device->wakeup.flags.notifier_present = 0; |
| 802 | 801 | ||
| 803 | /* Power button, Lid switch always enable wakeup */ | 802 | /* Power button, Lid switch always enable wakeup */ |
diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index d6a8cd14de2e..84f57143ad7c 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c | |||
| @@ -199,8 +199,6 @@ static void acpi_pm_end(void) | |||
| 199 | #endif /* CONFIG_ACPI_SLEEP */ | 199 | #endif /* CONFIG_ACPI_SLEEP */ |
| 200 | 200 | ||
| 201 | #ifdef CONFIG_SUSPEND | 201 | #ifdef CONFIG_SUSPEND |
| 202 | extern void do_suspend_lowlevel(void); | ||
| 203 | |||
| 204 | static u32 acpi_suspend_states[] = { | 202 | static u32 acpi_suspend_states[] = { |
| 205 | [PM_SUSPEND_ON] = ACPI_STATE_S0, | 203 | [PM_SUSPEND_ON] = ACPI_STATE_S0, |
| 206 | [PM_SUSPEND_STANDBY] = ACPI_STATE_S1, | 204 | [PM_SUSPEND_STANDBY] = ACPI_STATE_S1, |
| @@ -243,20 +241,11 @@ static int acpi_suspend_begin(suspend_state_t pm_state) | |||
| 243 | static int acpi_suspend_enter(suspend_state_t pm_state) | 241 | static int acpi_suspend_enter(suspend_state_t pm_state) |
| 244 | { | 242 | { |
| 245 | acpi_status status = AE_OK; | 243 | acpi_status status = AE_OK; |
| 246 | unsigned long flags = 0; | ||
| 247 | u32 acpi_state = acpi_target_sleep_state; | 244 | u32 acpi_state = acpi_target_sleep_state; |
| 245 | int error; | ||
| 248 | 246 | ||
| 249 | ACPI_FLUSH_CPU_CACHE(); | 247 | ACPI_FLUSH_CPU_CACHE(); |
| 250 | 248 | ||
| 251 | /* Do arch specific saving of state. */ | ||
| 252 | if (acpi_state == ACPI_STATE_S3) { | ||
| 253 | int error = acpi_save_state_mem(); | ||
| 254 | |||
| 255 | if (error) | ||
| 256 | return error; | ||
| 257 | } | ||
| 258 | |||
| 259 | local_irq_save(flags); | ||
| 260 | switch (acpi_state) { | 249 | switch (acpi_state) { |
| 261 | case ACPI_STATE_S1: | 250 | case ACPI_STATE_S1: |
| 262 | barrier(); | 251 | barrier(); |
| @@ -264,7 +253,10 @@ static int acpi_suspend_enter(suspend_state_t pm_state) | |||
| 264 | break; | 253 | break; |
| 265 | 254 | ||
| 266 | case ACPI_STATE_S3: | 255 | case ACPI_STATE_S3: |
| 267 | do_suspend_lowlevel(); | 256 | error = acpi_suspend_lowlevel(); |
| 257 | if (error) | ||
| 258 | return error; | ||
| 259 | pr_info(PREFIX "Low-level resume complete\n"); | ||
| 268 | break; | 260 | break; |
| 269 | } | 261 | } |
| 270 | 262 | ||
| @@ -290,13 +282,6 @@ static int acpi_suspend_enter(suspend_state_t pm_state) | |||
| 290 | /* Allow EC transactions to happen. */ | 282 | /* Allow EC transactions to happen. */ |
| 291 | acpi_ec_unblock_transactions_early(); | 283 | acpi_ec_unblock_transactions_early(); |
| 292 | 284 | ||
| 293 | local_irq_restore(flags); | ||
| 294 | printk(KERN_DEBUG "Back to C!\n"); | ||
| 295 | |||
| 296 | /* restore processor state */ | ||
| 297 | if (acpi_state == ACPI_STATE_S3) | ||
| 298 | acpi_restore_state_mem(); | ||
| 299 | |||
| 300 | suspend_nvs_restore(); | 285 | suspend_nvs_restore(); |
| 301 | 286 | ||
| 302 | return ACPI_SUCCESS(status) ? 0 : -EFAULT; | 287 | return ACPI_SUCCESS(status) ? 0 : -EFAULT; |
| @@ -472,16 +457,13 @@ static int acpi_hibernation_begin(void) | |||
| 472 | static int acpi_hibernation_enter(void) | 457 | static int acpi_hibernation_enter(void) |
| 473 | { | 458 | { |
| 474 | acpi_status status = AE_OK; | 459 | acpi_status status = AE_OK; |
| 475 | unsigned long flags = 0; | ||
| 476 | 460 | ||
| 477 | ACPI_FLUSH_CPU_CACHE(); | 461 | ACPI_FLUSH_CPU_CACHE(); |
| 478 | 462 | ||
| 479 | local_irq_save(flags); | ||
| 480 | /* This shouldn't return. If it returns, we have a problem */ | 463 | /* This shouldn't return. If it returns, we have a problem */ |
| 481 | status = acpi_enter_sleep_state(ACPI_STATE_S4); | 464 | status = acpi_enter_sleep_state(ACPI_STATE_S4); |
| 482 | /* Reprogram control registers and execute _BFS */ | 465 | /* Reprogram control registers and execute _BFS */ |
| 483 | acpi_leave_sleep_state_prep(ACPI_STATE_S4); | 466 | acpi_leave_sleep_state_prep(ACPI_STATE_S4); |
| 484 | local_irq_restore(flags); | ||
| 485 | 467 | ||
| 486 | return ACPI_SUCCESS(status) ? 0 : -EFAULT; | 468 | return ACPI_SUCCESS(status) ? 0 : -EFAULT; |
| 487 | } | 469 | } |
diff --git a/drivers/pci/pci-acpi.c b/drivers/pci/pci-acpi.c index 6fe0772e0e7d..7c3b18e78cee 100644 --- a/drivers/pci/pci-acpi.c +++ b/drivers/pci/pci-acpi.c | |||
| @@ -293,19 +293,11 @@ static int acpi_dev_run_wake(struct device *phys_dev, bool enable) | |||
| 293 | } | 293 | } |
| 294 | 294 | ||
| 295 | if (enable) { | 295 | if (enable) { |
| 296 | if (!dev->wakeup.run_wake_count++) { | 296 | acpi_enable_wakeup_device_power(dev, ACPI_STATE_S0); |
| 297 | acpi_enable_wakeup_device_power(dev, ACPI_STATE_S0); | 297 | acpi_enable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number); |
| 298 | acpi_enable_gpe(dev->wakeup.gpe_device, | ||
| 299 | dev->wakeup.gpe_number); | ||
| 300 | } | ||
| 301 | } else if (dev->wakeup.run_wake_count > 0) { | ||
| 302 | if (!--dev->wakeup.run_wake_count) { | ||
| 303 | acpi_disable_gpe(dev->wakeup.gpe_device, | ||
| 304 | dev->wakeup.gpe_number); | ||
| 305 | acpi_disable_wakeup_device_power(dev); | ||
| 306 | } | ||
| 307 | } else { | 298 | } else { |
| 308 | error = -EALREADY; | 299 | acpi_disable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number); |
| 300 | acpi_disable_wakeup_device_power(dev); | ||
| 309 | } | 301 | } |
| 310 | 302 | ||
| 311 | return error; | 303 | return error; |
diff --git a/include/acpi/acpi_bus.h b/include/acpi/acpi_bus.h index 78ca429929f7..f50ebb9bc53b 100644 --- a/include/acpi/acpi_bus.h +++ b/include/acpi/acpi_bus.h | |||
| @@ -250,7 +250,6 @@ struct acpi_device_wakeup { | |||
| 250 | struct acpi_handle_list resources; | 250 | struct acpi_handle_list resources; |
| 251 | struct acpi_device_wakeup_flags flags; | 251 | struct acpi_device_wakeup_flags flags; |
| 252 | int prepare_count; | 252 | int prepare_count; |
| 253 | int run_wake_count; | ||
| 254 | }; | 253 | }; |
| 255 | 254 | ||
| 256 | /* Device */ | 255 | /* Device */ |
