aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/ia64/include/asm/acpi.h6
-rw-r--r--arch/ia64/kernel/acpi.c14
-rw-r--r--arch/x86/include/asm/acpi.h5
-rw-r--r--arch/x86/kernel/acpi/sleep.c13
-rw-r--r--arch/x86/kernel/acpi/sleep.h2
-rw-r--r--drivers/acpi/acpica/aclocal.h7
-rw-r--r--drivers/acpi/acpica/evgpe.c17
-rw-r--r--drivers/acpi/acpica/evxfgpe.c42
-rw-r--r--drivers/acpi/button.c11
-rw-r--r--drivers/acpi/debugfs.c20
-rw-r--r--drivers/acpi/osl.c27
-rw-r--r--drivers/acpi/scan.c1
-rw-r--r--drivers/acpi/sleep.c28
-rw-r--r--drivers/pci/pci-acpi.c16
-rw-r--r--include/acpi/acpi_bus.h1
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)
128int acpi_request_vector (u32 int_type); 128int acpi_request_vector (u32 int_type);
129int acpi_gsi_to_irq (u32 gsi, unsigned int *irq); 129int acpi_gsi_to_irq (u32 gsi, unsigned int *irq);
130 130
131/* routines for saving/restoring kernel state */ 131/* Low-level suspend routine. */
132extern int acpi_save_state_mem(void); 132extern int acpi_suspend_lowlevel(void);
133extern void acpi_restore_state_mem(void); 133
134extern unsigned long acpi_wakeup_address; 134extern 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)
1034EXPORT_SYMBOL(acpi_unregister_ioapic); 1034EXPORT_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 */
1041int acpi_save_state_mem(void) { return 0; } 1041int acpi_suspend_lowlevel(void) { return 0; }
1042
1043/*
1044 * acpi_restore_state()
1045 */
1046void acpi_restore_state_mem(void) {}
1047
1048/*
1049 * do_suspend_lowlevel()
1050 */
1051void 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. */
116extern int acpi_save_state_mem(void); 116extern int acpi_suspend_lowlevel(void);
117extern void acpi_restore_state_mem(void);
118 117
119extern unsigned long acpi_wakeup_address; 118extern 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 */
39int acpi_save_state_mem(void) 39int 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 */
116void 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
15extern unsigned long acpi_copy_wakeup_routine(unsigned long); 15extern unsigned long acpi_copy_wakeup_routine(unsigned long);
16extern void wakeup_long64(void); 16extern void wakeup_long64(void);
17
18extern 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
419struct acpi_gpe_notify_object {
420 struct acpi_namespace_node *node;
421 struct acpi_gpe_notify_object *next;
422};
423
419union acpi_gpe_dispatch_info { 424union 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
103static const struct file_operations acpi_button_info_fops = { 104static 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);
76extern char line_buf[80]; 76extern char line_buf[80];
77#endif /*ENABLE_DEBUGGER */ 77#endif /*ENABLE_DEBUGGER */
78 78
79static unsigned int acpi_irq_irq;
80static acpi_osd_handler acpi_irq_handler; 79static acpi_osd_handler acpi_irq_handler;
81static void *acpi_irq_context; 80static void *acpi_irq_context;
82static struct workqueue_struct *kacpid_wq; 81static 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
557acpi_status acpi_os_remove_interrupt_handler(u32 irq, acpi_osd_handler handler) 560acpi_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)
1619acpi_status acpi_os_terminate(void) 1622acpi_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
202extern void do_suspend_lowlevel(void);
203
204static u32 acpi_suspend_states[] = { 202static 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)
243static int acpi_suspend_enter(suspend_state_t pm_state) 241static 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)
472static int acpi_hibernation_enter(void) 457static 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 */