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/button.c | 11 | ||||
| -rw-r--r-- | drivers/acpi/nvs.c | 22 | ||||
| -rw-r--r-- | drivers/acpi/osl.c | 139 | ||||
| -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 | ||||
| -rw-r--r-- | include/linux/acpi_io.h | 3 |
13 files changed, 127 insertions, 134 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/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/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 c90c76aa7f8b..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; |
| @@ -105,11 +104,11 @@ struct acpi_ioremap { | |||
| 105 | void __iomem *virt; | 104 | void __iomem *virt; |
| 106 | acpi_physical_address phys; | 105 | acpi_physical_address phys; |
| 107 | acpi_size size; | 106 | acpi_size size; |
| 108 | struct kref ref; | 107 | unsigned long refcount; |
| 109 | }; | 108 | }; |
| 110 | 109 | ||
| 111 | static LIST_HEAD(acpi_ioremaps); | 110 | static LIST_HEAD(acpi_ioremaps); |
| 112 | static DEFINE_SPINLOCK(acpi_ioremap_lock); | 111 | static DEFINE_MUTEX(acpi_ioremap_lock); |
| 113 | 112 | ||
| 114 | static void __init acpi_osi_setup_late(void); | 113 | static void __init acpi_osi_setup_late(void); |
| 115 | 114 | ||
| @@ -285,6 +284,22 @@ acpi_map_vaddr_lookup(acpi_physical_address phys, unsigned int size) | |||
| 285 | return NULL; | 284 | return NULL; |
| 286 | } | 285 | } |
| 287 | 286 | ||
| 287 | void __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 | } | ||
| 301 | EXPORT_SYMBOL_GPL(acpi_os_get_iomem); | ||
| 302 | |||
| 288 | /* 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. */ |
| 289 | static struct acpi_ioremap * | 304 | static struct acpi_ioremap * |
| 290 | acpi_map_lookup_virt(void __iomem *virt, acpi_size size) | 305 | acpi_map_lookup_virt(void __iomem *virt, acpi_size size) |
| @@ -302,8 +317,7 @@ acpi_map_lookup_virt(void __iomem *virt, acpi_size size) | |||
| 302 | void __iomem *__init_refok | 317 | void __iomem *__init_refok |
| 303 | acpi_os_map_memory(acpi_physical_address phys, acpi_size size) | 318 | acpi_os_map_memory(acpi_physical_address phys, acpi_size size) |
| 304 | { | 319 | { |
| 305 | struct acpi_ioremap *map, *tmp_map; | 320 | struct acpi_ioremap *map; |
| 306 | unsigned long flags; | ||
| 307 | void __iomem *virt; | 321 | void __iomem *virt; |
| 308 | acpi_physical_address pg_off; | 322 | acpi_physical_address pg_off; |
| 309 | acpi_size pg_sz; | 323 | acpi_size pg_sz; |
| @@ -316,14 +330,25 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size) | |||
| 316 | if (!acpi_gbl_permanent_mmap) | 330 | if (!acpi_gbl_permanent_mmap) |
| 317 | return __acpi_map_table((unsigned long)phys, size); | 331 | return __acpi_map_table((unsigned long)phys, size); |
| 318 | 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 | |||
| 319 | map = kzalloc(sizeof(*map), GFP_KERNEL); | 341 | map = kzalloc(sizeof(*map), GFP_KERNEL); |
| 320 | if (!map) | 342 | if (!map) { |
| 343 | mutex_unlock(&acpi_ioremap_lock); | ||
| 321 | return NULL; | 344 | return NULL; |
| 345 | } | ||
| 322 | 346 | ||
| 323 | pg_off = round_down(phys, PAGE_SIZE); | 347 | pg_off = round_down(phys, PAGE_SIZE); |
| 324 | pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off; | 348 | pg_sz = round_up(phys + size, PAGE_SIZE) - pg_off; |
| 325 | virt = acpi_os_ioremap(pg_off, pg_sz); | 349 | virt = acpi_os_ioremap(pg_off, pg_sz); |
| 326 | if (!virt) { | 350 | if (!virt) { |
| 351 | mutex_unlock(&acpi_ioremap_lock); | ||
| 327 | kfree(map); | 352 | kfree(map); |
| 328 | return NULL; | 353 | return NULL; |
| 329 | } | 354 | } |
| @@ -332,62 +357,51 @@ acpi_os_map_memory(acpi_physical_address phys, acpi_size size) | |||
| 332 | map->virt = virt; | 357 | map->virt = virt; |
| 333 | map->phys = pg_off; | 358 | map->phys = pg_off; |
| 334 | map->size = pg_sz; | 359 | map->size = pg_sz; |
| 335 | kref_init(&map->ref); | 360 | map->refcount = 1; |
| 336 | 361 | ||
| 337 | spin_lock_irqsave(&acpi_ioremap_lock, flags); | ||
| 338 | /* Check if page has already been mapped. */ | ||
| 339 | tmp_map = acpi_map_lookup(phys, size); | ||
| 340 | if (tmp_map) { | ||
| 341 | kref_get(&tmp_map->ref); | ||
| 342 | spin_unlock_irqrestore(&acpi_ioremap_lock, flags); | ||
| 343 | iounmap(map->virt); | ||
| 344 | kfree(map); | ||
| 345 | return tmp_map->virt + (phys - tmp_map->phys); | ||
| 346 | } | ||
| 347 | list_add_tail_rcu(&map->list, &acpi_ioremaps); | 362 | list_add_tail_rcu(&map->list, &acpi_ioremaps); |
| 348 | spin_unlock_irqrestore(&acpi_ioremap_lock, flags); | ||
| 349 | 363 | ||
| 364 | out: | ||
| 365 | mutex_unlock(&acpi_ioremap_lock); | ||
| 350 | return map->virt + (phys - map->phys); | 366 | return map->virt + (phys - map->phys); |
| 351 | } | 367 | } |
| 352 | EXPORT_SYMBOL_GPL(acpi_os_map_memory); | 368 | EXPORT_SYMBOL_GPL(acpi_os_map_memory); |
| 353 | 369 | ||
| 354 | static void acpi_kref_del_iomap(struct kref *ref) | 370 | static void acpi_os_drop_map_ref(struct acpi_ioremap *map) |
| 355 | { | 371 | { |
| 356 | struct acpi_ioremap *map; | 372 | if (!--map->refcount) |
| 373 | list_del_rcu(&map->list); | ||
| 374 | } | ||
| 357 | 375 | ||
| 358 | map = container_of(ref, struct acpi_ioremap, ref); | 376 | static void acpi_os_map_cleanup(struct acpi_ioremap *map) |
| 359 | list_del_rcu(&map->list); | 377 | { |
| 378 | if (!map->refcount) { | ||
| 379 | synchronize_rcu(); | ||
| 380 | iounmap(map->virt); | ||
| 381 | kfree(map); | ||
| 382 | } | ||
| 360 | } | 383 | } |
| 361 | 384 | ||
| 362 | void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size) | 385 | void __ref acpi_os_unmap_memory(void __iomem *virt, acpi_size size) |
| 363 | { | 386 | { |
| 364 | struct acpi_ioremap *map; | 387 | struct acpi_ioremap *map; |
| 365 | unsigned long flags; | ||
| 366 | int del; | ||
| 367 | 388 | ||
| 368 | if (!acpi_gbl_permanent_mmap) { | 389 | if (!acpi_gbl_permanent_mmap) { |
| 369 | __acpi_unmap_table(virt, size); | 390 | __acpi_unmap_table(virt, size); |
| 370 | return; | 391 | return; |
| 371 | } | 392 | } |
| 372 | 393 | ||
| 373 | spin_lock_irqsave(&acpi_ioremap_lock, flags); | 394 | mutex_lock(&acpi_ioremap_lock); |
| 374 | map = acpi_map_lookup_virt(virt, size); | 395 | map = acpi_map_lookup_virt(virt, size); |
| 375 | if (!map) { | 396 | if (!map) { |
| 376 | spin_unlock_irqrestore(&acpi_ioremap_lock, flags); | 397 | mutex_unlock(&acpi_ioremap_lock); |
| 377 | printk(KERN_ERR PREFIX "%s: bad address %p\n", __func__, virt); | 398 | WARN(true, PREFIX "%s: bad address %p\n", __func__, virt); |
| 378 | dump_stack(); | ||
| 379 | return; | 399 | return; |
| 380 | } | 400 | } |
| 401 | acpi_os_drop_map_ref(map); | ||
| 402 | mutex_unlock(&acpi_ioremap_lock); | ||
| 381 | 403 | ||
| 382 | del = kref_put(&map->ref, acpi_kref_del_iomap); | 404 | acpi_os_map_cleanup(map); |
| 383 | spin_unlock_irqrestore(&acpi_ioremap_lock, flags); | ||
| 384 | |||
| 385 | if (!del) | ||
| 386 | return; | ||
| 387 | |||
| 388 | synchronize_rcu(); | ||
| 389 | iounmap(map->virt); | ||
| 390 | kfree(map); | ||
| 391 | } | 405 | } |
| 392 | EXPORT_SYMBOL_GPL(acpi_os_unmap_memory); | 406 | EXPORT_SYMBOL_GPL(acpi_os_unmap_memory); |
| 393 | 407 | ||
| @@ -397,7 +411,7 @@ void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size) | |||
| 397 | __acpi_unmap_table(virt, size); | 411 | __acpi_unmap_table(virt, size); |
| 398 | } | 412 | } |
| 399 | 413 | ||
| 400 | int acpi_os_map_generic_address(struct acpi_generic_address *addr) | 414 | static int acpi_os_map_generic_address(struct acpi_generic_address *addr) |
| 401 | { | 415 | { |
| 402 | void __iomem *virt; | 416 | void __iomem *virt; |
| 403 | 417 | ||
| @@ -413,13 +427,10 @@ int acpi_os_map_generic_address(struct acpi_generic_address *addr) | |||
| 413 | 427 | ||
| 414 | return 0; | 428 | return 0; |
| 415 | } | 429 | } |
| 416 | EXPORT_SYMBOL_GPL(acpi_os_map_generic_address); | ||
| 417 | 430 | ||
| 418 | void acpi_os_unmap_generic_address(struct acpi_generic_address *addr) | 431 | static void acpi_os_unmap_generic_address(struct acpi_generic_address *addr) |
| 419 | { | 432 | { |
| 420 | void __iomem *virt; | 433 | struct acpi_ioremap *map; |
| 421 | unsigned long flags; | ||
| 422 | acpi_size size = addr->bit_width / 8; | ||
| 423 | 434 | ||
| 424 | if (addr->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) | 435 | if (addr->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) |
| 425 | return; | 436 | return; |
| @@ -427,13 +438,17 @@ void acpi_os_unmap_generic_address(struct acpi_generic_address *addr) | |||
| 427 | if (!addr->address || !addr->bit_width) | 438 | if (!addr->address || !addr->bit_width) |
| 428 | return; | 439 | return; |
| 429 | 440 | ||
| 430 | spin_lock_irqsave(&acpi_ioremap_lock, flags); | 441 | mutex_lock(&acpi_ioremap_lock); |
| 431 | virt = acpi_map_vaddr_lookup(addr->address, size); | 442 | map = acpi_map_lookup(addr->address, addr->bit_width / 8); |
| 432 | 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); | ||
| 433 | 449 | ||
| 434 | acpi_os_unmap_memory(virt, size); | 450 | acpi_os_map_cleanup(map); |
| 435 | } | 451 | } |
| 436 | EXPORT_SYMBOL_GPL(acpi_os_unmap_generic_address); | ||
| 437 | 452 | ||
| 438 | #ifdef ACPI_FUTURE_USAGE | 453 | #ifdef ACPI_FUTURE_USAGE |
| 439 | acpi_status | 454 | acpi_status |
| @@ -516,11 +531,15 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler, | |||
| 516 | acpi_irq_stats_init(); | 531 | acpi_irq_stats_init(); |
| 517 | 532 | ||
| 518 | /* | 533 | /* |
| 519 | * 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 |
| 520 | * FADT. It may not be the same if an interrupt source override exists | 535 | * not supported. |
| 521 | * for the SCI. | ||
| 522 | */ | 536 | */ |
| 523 | 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 | |||
| 524 | if (acpi_gsi_to_irq(gsi, &irq) < 0) { | 543 | if (acpi_gsi_to_irq(gsi, &irq) < 0) { |
| 525 | printk(KERN_ERR PREFIX "SCI (ACPI GSI %d) not registered\n", | 544 | printk(KERN_ERR PREFIX "SCI (ACPI GSI %d) not registered\n", |
| 526 | gsi); | 545 | gsi); |
| @@ -531,20 +550,20 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler, | |||
| 531 | acpi_irq_context = context; | 550 | acpi_irq_context = context; |
| 532 | if (request_irq(irq, acpi_irq, IRQF_SHARED, "acpi", acpi_irq)) { | 551 | if (request_irq(irq, acpi_irq, IRQF_SHARED, "acpi", acpi_irq)) { |
| 533 | 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; | ||
| 534 | return AE_NOT_ACQUIRED; | 554 | return AE_NOT_ACQUIRED; |
| 535 | } | 555 | } |
| 536 | acpi_irq_irq = irq; | ||
| 537 | 556 | ||
| 538 | return AE_OK; | 557 | return AE_OK; |
| 539 | } | 558 | } |
| 540 | 559 | ||
| 541 | 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) |
| 542 | { | 561 | { |
| 543 | if (irq) { | 562 | if (irq != acpi_gbl_FADT.sci_interrupt) |
| 544 | free_irq(irq, acpi_irq); | 563 | return AE_BAD_PARAMETER; |
| 545 | acpi_irq_handler = NULL; | 564 | |
| 546 | acpi_irq_irq = 0; | 565 | free_irq(irq, acpi_irq); |
| 547 | } | 566 | acpi_irq_handler = NULL; |
| 548 | 567 | ||
| 549 | return AE_OK; | 568 | return AE_OK; |
| 550 | } | 569 | } |
| @@ -1603,7 +1622,7 @@ acpi_status __init acpi_os_initialize1(void) | |||
| 1603 | acpi_status acpi_os_terminate(void) | 1622 | acpi_status acpi_os_terminate(void) |
| 1604 | { | 1623 | { |
| 1605 | if (acpi_irq_handler) { | 1624 | if (acpi_irq_handler) { |
| 1606 | acpi_os_remove_interrupt_handler(acpi_irq_irq, | 1625 | acpi_os_remove_interrupt_handler(acpi_gbl_FADT.sci_interrupt, |
| 1607 | acpi_irq_handler); | 1626 | acpi_irq_handler); |
| 1608 | } | 1627 | } |
| 1609 | 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 */ |
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 | ||
| 13 | int acpi_os_map_generic_address(struct acpi_generic_address *addr); | 13 | void __iomem *acpi_os_get_iomem(acpi_physical_address phys, unsigned int size); |
| 14 | void acpi_os_unmap_generic_address(struct acpi_generic_address *addr); | ||
| 15 | 14 | ||
| 16 | #endif | 15 | #endif |
