diff options
author | Len Brown <len.brown@intel.com> | 2012-01-18 00:46:30 -0500 |
---|---|---|
committer | Len Brown <len.brown@intel.com> | 2012-01-18 00:46:30 -0500 |
commit | cb7971756b901abd61d47f6eb1011066abfb348d (patch) | |
tree | c822e575f95c6f8ee5814648f6ccc1fb3226f6fc /drivers | |
parent | 037d76f40430ba1269dc7d1fee22382cd9672997 (diff) | |
parent | 700130b41f4ee54520ac2ef2f7f1d072789711a4 (diff) |
Merge branch 'atomicio-remove' into release
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/acpi/apei/apei-base.c | 102 | ||||
-rw-r--r-- | drivers/acpi/apei/apei-internal.h | 3 | ||||
-rw-r--r-- | drivers/acpi/apei/ghes.c | 10 | ||||
-rw-r--r-- | drivers/acpi/osl.c | 40 |
4 files changed, 130 insertions, 25 deletions
diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c index 4abb6c74a938..e45350cb6ac8 100644 --- a/drivers/acpi/apei/apei-base.c +++ b/drivers/acpi/apei/apei-base.c | |||
@@ -34,13 +34,13 @@ | |||
34 | #include <linux/module.h> | 34 | #include <linux/module.h> |
35 | #include <linux/init.h> | 35 | #include <linux/init.h> |
36 | #include <linux/acpi.h> | 36 | #include <linux/acpi.h> |
37 | #include <linux/acpi_io.h> | ||
37 | #include <linux/slab.h> | 38 | #include <linux/slab.h> |
38 | #include <linux/io.h> | 39 | #include <linux/io.h> |
39 | #include <linux/kref.h> | 40 | #include <linux/kref.h> |
40 | #include <linux/rculist.h> | 41 | #include <linux/rculist.h> |
41 | #include <linux/interrupt.h> | 42 | #include <linux/interrupt.h> |
42 | #include <linux/debugfs.h> | 43 | #include <linux/debugfs.h> |
43 | #include <acpi/atomicio.h> | ||
44 | 44 | ||
45 | #include "apei-internal.h" | 45 | #include "apei-internal.h" |
46 | 46 | ||
@@ -70,7 +70,7 @@ int __apei_exec_read_register(struct acpi_whea_header *entry, u64 *val) | |||
70 | { | 70 | { |
71 | int rc; | 71 | int rc; |
72 | 72 | ||
73 | rc = acpi_atomic_read(val, &entry->register_region); | 73 | rc = apei_read(val, &entry->register_region); |
74 | if (rc) | 74 | if (rc) |
75 | return rc; | 75 | return rc; |
76 | *val >>= entry->register_region.bit_offset; | 76 | *val >>= entry->register_region.bit_offset; |
@@ -116,13 +116,13 @@ int __apei_exec_write_register(struct acpi_whea_header *entry, u64 val) | |||
116 | val <<= entry->register_region.bit_offset; | 116 | val <<= entry->register_region.bit_offset; |
117 | if (entry->flags & APEI_EXEC_PRESERVE_REGISTER) { | 117 | if (entry->flags & APEI_EXEC_PRESERVE_REGISTER) { |
118 | u64 valr = 0; | 118 | u64 valr = 0; |
119 | rc = acpi_atomic_read(&valr, &entry->register_region); | 119 | rc = apei_read(&valr, &entry->register_region); |
120 | if (rc) | 120 | if (rc) |
121 | return rc; | 121 | return rc; |
122 | valr &= ~(entry->mask << entry->register_region.bit_offset); | 122 | valr &= ~(entry->mask << entry->register_region.bit_offset); |
123 | val |= valr; | 123 | val |= valr; |
124 | } | 124 | } |
125 | rc = acpi_atomic_write(val, &entry->register_region); | 125 | rc = apei_write(val, &entry->register_region); |
126 | 126 | ||
127 | return rc; | 127 | return rc; |
128 | } | 128 | } |
@@ -243,7 +243,7 @@ static int pre_map_gar_callback(struct apei_exec_context *ctx, | |||
243 | u8 ins = entry->instruction; | 243 | u8 ins = entry->instruction; |
244 | 244 | ||
245 | if (ctx->ins_table[ins].flags & APEI_EXEC_INS_ACCESS_REGISTER) | 245 | if (ctx->ins_table[ins].flags & APEI_EXEC_INS_ACCESS_REGISTER) |
246 | return acpi_pre_map_gar(&entry->register_region); | 246 | return acpi_os_map_generic_address(&entry->register_region); |
247 | 247 | ||
248 | return 0; | 248 | return 0; |
249 | } | 249 | } |
@@ -276,7 +276,7 @@ static int post_unmap_gar_callback(struct apei_exec_context *ctx, | |||
276 | u8 ins = entry->instruction; | 276 | u8 ins = entry->instruction; |
277 | 277 | ||
278 | if (ctx->ins_table[ins].flags & APEI_EXEC_INS_ACCESS_REGISTER) | 278 | if (ctx->ins_table[ins].flags & APEI_EXEC_INS_ACCESS_REGISTER) |
279 | acpi_post_unmap_gar(&entry->register_region); | 279 | acpi_os_unmap_generic_address(&entry->register_region); |
280 | 280 | ||
281 | return 0; | 281 | return 0; |
282 | } | 282 | } |
@@ -591,6 +591,96 @@ static int apei_check_gar(struct acpi_generic_address *reg, u64 *paddr) | |||
591 | return 0; | 591 | return 0; |
592 | } | 592 | } |
593 | 593 | ||
594 | /* read GAR in interrupt (including NMI) or process context */ | ||
595 | int apei_read(u64 *val, struct acpi_generic_address *reg) | ||
596 | { | ||
597 | int rc; | ||
598 | u64 address; | ||
599 | u32 tmp, width = reg->bit_width; | ||
600 | acpi_status status; | ||
601 | |||
602 | rc = apei_check_gar(reg, &address); | ||
603 | if (rc) | ||
604 | return rc; | ||
605 | |||
606 | if (width == 64) | ||
607 | width = 32; /* Break into two 32-bit transfers */ | ||
608 | |||
609 | *val = 0; | ||
610 | switch(reg->space_id) { | ||
611 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | ||
612 | status = acpi_os_read_memory((acpi_physical_address) | ||
613 | address, &tmp, width); | ||
614 | if (ACPI_FAILURE(status)) | ||
615 | return -EIO; | ||
616 | *val = tmp; | ||
617 | |||
618 | if (reg->bit_width == 64) { | ||
619 | /* Read the top 32 bits */ | ||
620 | status = acpi_os_read_memory((acpi_physical_address) | ||
621 | (address + 4), &tmp, 32); | ||
622 | if (ACPI_FAILURE(status)) | ||
623 | return -EIO; | ||
624 | *val |= ((u64)tmp << 32); | ||
625 | } | ||
626 | break; | ||
627 | case ACPI_ADR_SPACE_SYSTEM_IO: | ||
628 | status = acpi_os_read_port(address, (u32 *)val, reg->bit_width); | ||
629 | if (ACPI_FAILURE(status)) | ||
630 | return -EIO; | ||
631 | break; | ||
632 | default: | ||
633 | return -EINVAL; | ||
634 | } | ||
635 | |||
636 | return 0; | ||
637 | } | ||
638 | EXPORT_SYMBOL_GPL(apei_read); | ||
639 | |||
640 | /* write GAR in interrupt (including NMI) or process context */ | ||
641 | int apei_write(u64 val, struct acpi_generic_address *reg) | ||
642 | { | ||
643 | int rc; | ||
644 | u64 address; | ||
645 | u32 width = reg->bit_width; | ||
646 | acpi_status status; | ||
647 | |||
648 | rc = apei_check_gar(reg, &address); | ||
649 | if (rc) | ||
650 | return rc; | ||
651 | |||
652 | if (width == 64) | ||
653 | width = 32; /* Break into two 32-bit transfers */ | ||
654 | |||
655 | switch (reg->space_id) { | ||
656 | case ACPI_ADR_SPACE_SYSTEM_MEMORY: | ||
657 | status = acpi_os_write_memory((acpi_physical_address) | ||
658 | address, ACPI_LODWORD(val), | ||
659 | width); | ||
660 | if (ACPI_FAILURE(status)) | ||
661 | return -EIO; | ||
662 | |||
663 | if (reg->bit_width == 64) { | ||
664 | status = acpi_os_write_memory((acpi_physical_address) | ||
665 | (address + 4), | ||
666 | ACPI_HIDWORD(val), 32); | ||
667 | if (ACPI_FAILURE(status)) | ||
668 | return -EIO; | ||
669 | } | ||
670 | break; | ||
671 | case ACPI_ADR_SPACE_SYSTEM_IO: | ||
672 | status = acpi_os_write_port(address, val, reg->bit_width); | ||
673 | if (ACPI_FAILURE(status)) | ||
674 | return -EIO; | ||
675 | break; | ||
676 | default: | ||
677 | return -EINVAL; | ||
678 | } | ||
679 | |||
680 | return 0; | ||
681 | } | ||
682 | EXPORT_SYMBOL_GPL(apei_write); | ||
683 | |||
594 | static int collect_res_callback(struct apei_exec_context *ctx, | 684 | static int collect_res_callback(struct apei_exec_context *ctx, |
595 | struct acpi_whea_header *entry, | 685 | struct acpi_whea_header *entry, |
596 | void *data) | 686 | void *data) |
diff --git a/drivers/acpi/apei/apei-internal.h b/drivers/acpi/apei/apei-internal.h index d778edd34fba..cca240a33038 100644 --- a/drivers/acpi/apei/apei-internal.h +++ b/drivers/acpi/apei/apei-internal.h | |||
@@ -68,6 +68,9 @@ static inline int apei_exec_run_optional(struct apei_exec_context *ctx, u8 actio | |||
68 | /* IP has been set in instruction function */ | 68 | /* IP has been set in instruction function */ |
69 | #define APEI_EXEC_SET_IP 1 | 69 | #define APEI_EXEC_SET_IP 1 |
70 | 70 | ||
71 | int apei_read(u64 *val, struct acpi_generic_address *reg); | ||
72 | int apei_write(u64 val, struct acpi_generic_address *reg); | ||
73 | |||
71 | int __apei_exec_read_register(struct acpi_whea_header *entry, u64 *val); | 74 | int __apei_exec_read_register(struct acpi_whea_header *entry, u64 *val); |
72 | int __apei_exec_write_register(struct acpi_whea_header *entry, u64 val); | 75 | int __apei_exec_write_register(struct acpi_whea_header *entry, u64 val); |
73 | int apei_exec_read_register(struct apei_exec_context *ctx, | 76 | int apei_exec_read_register(struct apei_exec_context *ctx, |
diff --git a/drivers/acpi/apei/ghes.c b/drivers/acpi/apei/ghes.c index aaf36090de1e..b3207e16670e 100644 --- a/drivers/acpi/apei/ghes.c +++ b/drivers/acpi/apei/ghes.c | |||
@@ -33,6 +33,7 @@ | |||
33 | #include <linux/module.h> | 33 | #include <linux/module.h> |
34 | #include <linux/init.h> | 34 | #include <linux/init.h> |
35 | #include <linux/acpi.h> | 35 | #include <linux/acpi.h> |
36 | #include <linux/acpi_io.h> | ||
36 | #include <linux/io.h> | 37 | #include <linux/io.h> |
37 | #include <linux/interrupt.h> | 38 | #include <linux/interrupt.h> |
38 | #include <linux/timer.h> | 39 | #include <linux/timer.h> |
@@ -48,7 +49,6 @@ | |||
48 | #include <linux/pci.h> | 49 | #include <linux/pci.h> |
49 | #include <linux/aer.h> | 50 | #include <linux/aer.h> |
50 | #include <acpi/apei.h> | 51 | #include <acpi/apei.h> |
51 | #include <acpi/atomicio.h> | ||
52 | #include <acpi/hed.h> | 52 | #include <acpi/hed.h> |
53 | #include <asm/mce.h> | 53 | #include <asm/mce.h> |
54 | #include <asm/tlbflush.h> | 54 | #include <asm/tlbflush.h> |
@@ -301,7 +301,7 @@ static struct ghes *ghes_new(struct acpi_hest_generic *generic) | |||
301 | if (!ghes) | 301 | if (!ghes) |
302 | return ERR_PTR(-ENOMEM); | 302 | return ERR_PTR(-ENOMEM); |
303 | ghes->generic = generic; | 303 | ghes->generic = generic; |
304 | rc = acpi_pre_map_gar(&generic->error_status_address); | 304 | rc = acpi_os_map_generic_address(&generic->error_status_address); |
305 | if (rc) | 305 | if (rc) |
306 | goto err_free; | 306 | goto err_free; |
307 | error_block_length = generic->error_block_length; | 307 | error_block_length = generic->error_block_length; |
@@ -321,7 +321,7 @@ static struct ghes *ghes_new(struct acpi_hest_generic *generic) | |||
321 | return ghes; | 321 | return ghes; |
322 | 322 | ||
323 | err_unmap: | 323 | err_unmap: |
324 | acpi_post_unmap_gar(&generic->error_status_address); | 324 | acpi_os_unmap_generic_address(&generic->error_status_address); |
325 | err_free: | 325 | err_free: |
326 | kfree(ghes); | 326 | kfree(ghes); |
327 | return ERR_PTR(rc); | 327 | return ERR_PTR(rc); |
@@ -330,7 +330,7 @@ err_free: | |||
330 | static void ghes_fini(struct ghes *ghes) | 330 | static void ghes_fini(struct ghes *ghes) |
331 | { | 331 | { |
332 | kfree(ghes->estatus); | 332 | kfree(ghes->estatus); |
333 | acpi_post_unmap_gar(&ghes->generic->error_status_address); | 333 | acpi_os_unmap_generic_address(&ghes->generic->error_status_address); |
334 | } | 334 | } |
335 | 335 | ||
336 | enum { | 336 | enum { |
@@ -401,7 +401,7 @@ static int ghes_read_estatus(struct ghes *ghes, int silent) | |||
401 | u32 len; | 401 | u32 len; |
402 | int rc; | 402 | int rc; |
403 | 403 | ||
404 | rc = acpi_atomic_read(&buf_paddr, &g->error_status_address); | 404 | rc = apei_read(&buf_paddr, &g->error_status_address); |
405 | if (rc) { | 405 | if (rc) { |
406 | if (!silent && printk_ratelimit()) | 406 | if (!silent && printk_ratelimit()) |
407 | pr_warning(FW_WARN GHES_PFX | 407 | pr_warning(FW_WARN GHES_PFX |
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 3e57fbdf50a3..fcc12d842bcc 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -153,17 +153,21 @@ static u32 acpi_osi_handler(acpi_string interface, u32 supported) | |||
153 | return supported; | 153 | return supported; |
154 | } | 154 | } |
155 | 155 | ||
156 | static void __init acpi_request_region (struct acpi_generic_address *addr, | 156 | static void __init acpi_request_region (struct acpi_generic_address *gas, |
157 | unsigned int length, char *desc) | 157 | unsigned int length, char *desc) |
158 | { | 158 | { |
159 | if (!addr->address || !length) | 159 | u64 addr; |
160 | |||
161 | /* Handle possible alignment issues */ | ||
162 | memcpy(&addr, &gas->address, sizeof(addr)); | ||
163 | if (!addr || !length) | ||
160 | return; | 164 | return; |
161 | 165 | ||
162 | /* Resources are never freed */ | 166 | /* Resources are never freed */ |
163 | if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_IO) | 167 | if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_IO) |
164 | request_region(addr->address, length, desc); | 168 | request_region(addr, length, desc); |
165 | else if (addr->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) | 169 | else if (gas->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) |
166 | request_mem_region(addr->address, length, desc); | 170 | request_mem_region(addr, length, desc); |
167 | } | 171 | } |
168 | 172 | ||
169 | static int __init acpi_reserve_resources(void) | 173 | static int __init acpi_reserve_resources(void) |
@@ -414,35 +418,42 @@ void __init early_acpi_os_unmap_memory(void __iomem *virt, acpi_size size) | |||
414 | __acpi_unmap_table(virt, size); | 418 | __acpi_unmap_table(virt, size); |
415 | } | 419 | } |
416 | 420 | ||
417 | static int acpi_os_map_generic_address(struct acpi_generic_address *addr) | 421 | int acpi_os_map_generic_address(struct acpi_generic_address *gas) |
418 | { | 422 | { |
423 | u64 addr; | ||
419 | void __iomem *virt; | 424 | void __iomem *virt; |
420 | 425 | ||
421 | if (addr->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) | 426 | if (gas->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) |
422 | return 0; | 427 | return 0; |
423 | 428 | ||
424 | if (!addr->address || !addr->bit_width) | 429 | /* Handle possible alignment issues */ |
430 | memcpy(&addr, &gas->address, sizeof(addr)); | ||
431 | if (!addr || !gas->bit_width) | ||
425 | return -EINVAL; | 432 | return -EINVAL; |
426 | 433 | ||
427 | virt = acpi_os_map_memory(addr->address, addr->bit_width / 8); | 434 | virt = acpi_os_map_memory(addr, gas->bit_width / 8); |
428 | if (!virt) | 435 | if (!virt) |
429 | return -EIO; | 436 | return -EIO; |
430 | 437 | ||
431 | return 0; | 438 | return 0; |
432 | } | 439 | } |
440 | EXPORT_SYMBOL(acpi_os_map_generic_address); | ||
433 | 441 | ||
434 | static void acpi_os_unmap_generic_address(struct acpi_generic_address *addr) | 442 | void acpi_os_unmap_generic_address(struct acpi_generic_address *gas) |
435 | { | 443 | { |
444 | u64 addr; | ||
436 | struct acpi_ioremap *map; | 445 | struct acpi_ioremap *map; |
437 | 446 | ||
438 | if (addr->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) | 447 | if (gas->space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) |
439 | return; | 448 | return; |
440 | 449 | ||
441 | if (!addr->address || !addr->bit_width) | 450 | /* Handle possible alignment issues */ |
451 | memcpy(&addr, &gas->address, sizeof(addr)); | ||
452 | if (!addr || !gas->bit_width) | ||
442 | return; | 453 | return; |
443 | 454 | ||
444 | mutex_lock(&acpi_ioremap_lock); | 455 | mutex_lock(&acpi_ioremap_lock); |
445 | map = acpi_map_lookup(addr->address, addr->bit_width / 8); | 456 | map = acpi_map_lookup(addr, gas->bit_width / 8); |
446 | if (!map) { | 457 | if (!map) { |
447 | mutex_unlock(&acpi_ioremap_lock); | 458 | mutex_unlock(&acpi_ioremap_lock); |
448 | return; | 459 | return; |
@@ -452,6 +463,7 @@ static void acpi_os_unmap_generic_address(struct acpi_generic_address *addr) | |||
452 | 463 | ||
453 | acpi_os_map_cleanup(map); | 464 | acpi_os_map_cleanup(map); |
454 | } | 465 | } |
466 | EXPORT_SYMBOL(acpi_os_unmap_generic_address); | ||
455 | 467 | ||
456 | #ifdef ACPI_FUTURE_USAGE | 468 | #ifdef ACPI_FUTURE_USAGE |
457 | acpi_status | 469 | acpi_status |