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/nvs.c22
-rw-r--r--drivers/acpi/osl.c112
-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
-rw-r--r--include/linux/acpi_io.h3
17 files changed, 178 insertions, 142 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/nvs.c b/drivers/acpi/nvs.c
index fa5a1df42b79..096787b43c96 100644
--- a/drivers/acpi/nvs.c
+++ b/drivers/acpi/nvs.c
@@ -26,6 +26,7 @@ struct nvs_page {
26 unsigned int size; 26 unsigned int size;
27 void *kaddr; 27 void *kaddr;
28 void *data; 28 void *data;
29 bool unmap;
29 struct list_head node; 30 struct list_head node;
30}; 31};
31 32
@@ -44,6 +45,9 @@ int suspend_nvs_register(unsigned long start, unsigned long size)
44{ 45{
45 struct nvs_page *entry, *next; 46 struct nvs_page *entry, *next;
46 47
48 pr_info("PM: Registering ACPI NVS region at %lx (%ld bytes)\n",
49 start, size);
50
47 while (size > 0) { 51 while (size > 0) {
48 unsigned int nr_bytes; 52 unsigned int nr_bytes;
49 53
@@ -81,7 +85,13 @@ void suspend_nvs_free(void)
81 free_page((unsigned long)entry->data); 85 free_page((unsigned long)entry->data);
82 entry->data = NULL; 86 entry->data = NULL;
83 if (entry->kaddr) { 87 if (entry->kaddr) {
84 iounmap(entry->kaddr); 88 if (entry->unmap) {
89 iounmap(entry->kaddr);
90 entry->unmap = false;
91 } else {
92 acpi_os_unmap_memory(entry->kaddr,
93 entry->size);
94 }
85 entry->kaddr = NULL; 95 entry->kaddr = NULL;
86 } 96 }
87 } 97 }
@@ -115,8 +125,14 @@ int suspend_nvs_save(void)
115 125
116 list_for_each_entry(entry, &nvs_list, node) 126 list_for_each_entry(entry, &nvs_list, node)
117 if (entry->data) { 127 if (entry->data) {
118 entry->kaddr = acpi_os_ioremap(entry->phys_start, 128 unsigned long phys = entry->phys_start;
119 entry->size); 129 unsigned int size = entry->size;
130
131 entry->kaddr = acpi_os_get_iomem(phys, size);
132 if (!entry->kaddr) {
133 entry->kaddr = acpi_os_ioremap(phys, size);
134 entry->unmap = !!entry->kaddr;
135 }
120 if (!entry->kaddr) { 136 if (!entry->kaddr) {
121 suspend_nvs_free(); 137 suspend_nvs_free();
122 return -ENOMEM; 138 return -ENOMEM;
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 187dff96356b..45c6ac8790d7 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -104,11 +104,11 @@ struct acpi_ioremap {
104 void __iomem *virt; 104 void __iomem *virt;
105 acpi_physical_address phys; 105 acpi_physical_address phys;
106 acpi_size size; 106 acpi_size size;
107 struct kref ref; 107 unsigned long refcount;
108}; 108};
109 109
110static LIST_HEAD(acpi_ioremaps); 110static LIST_HEAD(acpi_ioremaps);
111static DEFINE_SPINLOCK(acpi_ioremap_lock); 111static DEFINE_MUTEX(acpi_ioremap_lock);
112 112
113static void __init acpi_osi_setup_late(void); 113static void __init acpi_osi_setup_late(void);
114 114
@@ -284,6 +284,22 @@ acpi_map_vaddr_lookup(acpi_physical_address phys, unsigned int size)
284 return NULL; 284 return NULL;
285} 285}
286 286
287void __iomem *acpi_os_get_iomem(acpi_physical_address phys, unsigned int size)
288{
289 struct acpi_ioremap *map;
290 void __iomem *virt = NULL;
291
292 mutex_lock(&acpi_ioremap_lock);
293 map = acpi_map_lookup(phys, size);
294 if (map) {
295 virt = map->virt + (phys - map->phys);
296 map->refcount++;
297 }
298 mutex_unlock(&acpi_ioremap_lock);
299 return virt;
300}
301EXPORT_SYMBOL_GPL(acpi_os_get_iomem);
302
287/* Must be called with 'acpi_ioremap_lock' or RCU read lock held. */ 303/* Must be called with 'acpi_ioremap_lock' or RCU read lock held. */
288static struct acpi_ioremap * 304static struct acpi_ioremap *
289acpi_map_lookup_virt(void __iomem *virt, acpi_size size) 305acpi_map_lookup_virt(void __iomem *virt, acpi_size size)
@@ -301,8 +317,7 @@ acpi_map_lookup_virt(void __iomem *virt, acpi_size size)
301void __iomem *__init_refok 317void __iomem *__init_refok
302acpi_os_map_memory(acpi_physical_address phys, acpi_size size) 318acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
303{ 319{
304 struct acpi_ioremap *map, *tmp_map; 320 struct acpi_ioremap *map;
305 unsigned long flags;
306 void __iomem *virt; 321 void __iomem *virt;
307 acpi_physical_address pg_off; 322 acpi_physical_address pg_off;
308 acpi_size pg_sz; 323 acpi_size pg_sz;
@@ -315,14 +330,25 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
315 if (!acpi_gbl_permanent_mmap) 330 if (!acpi_gbl_permanent_mmap)
316 return __acpi_map_table((unsigned long)phys, size); 331 return __acpi_map_table((unsigned long)phys, size);
317 332
333 mutex_lock(&acpi_ioremap_lock);
334 /* Check if there's a suitable mapping already. */
335 map = acpi_map_lookup(phys, size);
336 if (map) {
337 map->refcount++;
338 goto out;
339 }
340
318 map = kzalloc(sizeof(*map), GFP_KERNEL); 341 map = kzalloc(sizeof(*map), GFP_KERNEL);
319 if (!map) 342 if (!map) {
343 mutex_unlock(&acpi_ioremap_lock);
320 return NULL; 344 return NULL;
345 }
321 346
322 pg_off = round_down(phys, PAGE_SIZE); 347 pg_off = round_down(phys, PAGE_SIZE);
323 pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off; 348 pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off;
324 virt = acpi_os_ioremap(pg_off, pg_sz); 349 virt = acpi_os_ioremap(pg_off, pg_sz);
325 if (!virt) { 350 if (!virt) {
351 mutex_unlock(&acpi_ioremap_lock);
326 kfree(map); 352 kfree(map);
327 return NULL; 353 return NULL;
328 } 354 }
@@ -331,62 +357,51 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
331 map->virt = virt; 357 map->virt = virt;
332 map->phys = pg_off; 358 map->phys = pg_off;
333 map->size = pg_sz; 359 map->size = pg_sz;
334 kref_init(&map->ref); 360 map->refcount = 1;
335 361
336 spin_lock_irqsave(&acpi_ioremap_lock, flags);
337 /* Check if page has already been mapped. */
338 tmp_map = acpi_map_lookup(phys, size);
339 if (tmp_map) {
340 kref_get(&tmp_map->ref);
341 spin_unlock_irqrestore(&acpi_ioremap_lock, flags);
342 iounmap(map->virt);
343 kfree(map);
344 return tmp_map->virt + (phys - tmp_map->phys);
345 }
346 list_add_tail_rcu(&map->list, &acpi_ioremaps); 362 list_add_tail_rcu(&map->list, &acpi_ioremaps);
347 spin_unlock_irqrestore(&acpi_ioremap_lock, flags);
348 363
364 out:
365 mutex_unlock(&acpi_ioremap_lock);
349 return map->virt + (phys - map->phys); 366 return map->virt + (phys - map->phys);
350} 367}
351EXPORT_SYMBOL_GPL(acpi_os_map_memory); 368EXPORT_SYMBOL_GPL(acpi_os_map_memory);
352 369
353static void acpi_kref_del_iomap(struct kref *ref) 370static void acpi_os_drop_map_ref(struct acpi_ioremap *map)
354{ 371{
355 struct acpi_ioremap *map; 372 if (!--map->refcount)
373 list_del_rcu(&map->list);
374}
356 375
357 map = container_of(ref, struct acpi_ioremap, ref); 376static void acpi_os_map_cleanup(struct acpi_ioremap *map)
358 list_del_rcu(&map->list); 377{
378 if (!map->refcount) {
379 synchronize_rcu();
380 iounmap(map->virt);
381 kfree(map);
382 }
359} 383}
360 384
361void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size) 385void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
362{ 386{
363 struct acpi_ioremap *map; 387 struct acpi_ioremap *map;
364 unsigned long flags;
365 int del;
366 388
367 if (!acpi_gbl_permanent_mmap) { 389 if (!acpi_gbl_permanent_mmap) {
368 __acpi_unmap_table(virt, size); 390 __acpi_unmap_table(virt, size);
369 return; 391 return;
370 } 392 }
371 393
372 spin_lock_irqsave(&acpi_ioremap_lock, flags); 394 mutex_lock(&acpi_ioremap_lock);
373 map = acpi_map_lookup_virt(virt, size); 395 map = acpi_map_lookup_virt(virt, size);
374 if (!map) { 396 if (!map) {
375 spin_unlock_irqrestore(&acpi_ioremap_lock, flags); 397 mutex_unlock(&acpi_ioremap_lock);
376 printk(KERN_ERR PREFIX "%s: bad address %p\n", __func__, virt); 398 WARN(true, PREFIX "%s: bad address %p\n", __func__, virt);
377 dump_stack();
378 return; 399 return;
379 } 400 }
401 acpi_os_drop_map_ref(map);
402 mutex_unlock(&acpi_ioremap_lock);
380 403
381 del = kref_put(&map->ref, acpi_kref_del_iomap); 404 acpi_os_map_cleanup(map);
382 spin_unlock_irqrestore(&acpi_ioremap_lock, flags);
383
384 if (!del)
385 return;
386
387 synchronize_rcu();
388 iounmap(map->virt);
389 kfree(map);
390} 405}
391EXPORT_SYMBOL_GPL(acpi_os_unmap_memory); 406EXPORT_SYMBOL_GPL(acpi_os_unmap_memory);
392 407
@@ -396,7 +411,7 @@ void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size)
396 __acpi_unmap_table(virt, size); 411 __acpi_unmap_table(virt, size);
397} 412}
398 413
399int acpi_os_map_generic_address(struct acpi_generic_address *addr) 414static int acpi_os_map_generic_address(struct acpi_generic_address *addr)
400{ 415{
401 void __iomem *virt; 416 void __iomem *virt;
402 417
@@ -412,13 +427,10 @@ int acpi_os_map_generic_address(struct acpi_generic_address *addr)
412 427
413 return 0; 428 return 0;
414} 429}
415EXPORT_SYMBOL_GPL(acpi_os_map_generic_address);
416 430
417void acpi_os_unmap_generic_address(struct acpi_generic_address *addr) 431static void acpi_os_unmap_generic_address(struct acpi_generic_address *addr)
418{ 432{
419 void __iomem *virt; 433 struct acpi_ioremap *map;
420 unsigned long flags;
421 acpi_size size = addr->bit_width / 8;
422 434
423 if (addr->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) 435 if (addr->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY)
424 return; 436 return;
@@ -426,13 +438,17 @@ void acpi_os_unmap_generic_address(struct acpi_generic_address *addr)
426 if (!addr->address || !addr->bit_width) 438 if (!addr->address || !addr->bit_width)
427 return; 439 return;
428 440
429 spin_lock_irqsave(&acpi_ioremap_lock, flags); 441 mutex_lock(&acpi_ioremap_lock);
430 virt = acpi_map_vaddr_lookup(addr->address, size); 442 map = acpi_map_lookup(addr->address, addr->bit_width / 8);
431 spin_unlock_irqrestore(&acpi_ioremap_lock, flags); 443 if (!map) {
444 mutex_unlock(&acpi_ioremap_lock);
445 return;
446 }
447 acpi_os_drop_map_ref(map);
448 mutex_unlock(&acpi_ioremap_lock);
432 449
433 acpi_os_unmap_memory(virt, size); 450 acpi_os_map_cleanup(map);
434} 451}
435EXPORT_SYMBOL_GPL(acpi_os_unmap_generic_address);
436 452
437#ifdef ACPI_FUTURE_USAGE 453#ifdef ACPI_FUTURE_USAGE
438acpi_status 454acpi_status
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 */
diff --git a/include/linux/acpi_io.h b/include/linux/acpi_io.h
index 7180013a4a3a..4afd7102459d 100644
--- a/include/linux/acpi_io.h
+++ b/include/linux/acpi_io.h
@@ -10,7 +10,6 @@ static inline void __iomem *acpi_os_ioremap(acpi_physical_address phys,
10 return ioremap_cache(phys, size); 10 return ioremap_cache(phys, size);
11} 11}
12 12
13int acpi_os_map_generic_address(struct acpi_generic_address *addr); 13void __iomem *acpi_os_get_iomem(acpi_physical_address phys, unsigned int size);
14void acpi_os_unmap_generic_address(struct acpi_generic_address *addr);
15 14
16#endif 15#endif