aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/acpi/apei
diff options
context:
space:
mode:
authorLuck, Tony <tony.luck@intel.com>2012-01-23 18:27:56 -0500
committerLen Brown <len.brown@intel.com>2012-01-23 19:39:10 -0500
commit459413db33d6c99fc13d60f88899fb72d2530ed3 (patch)
tree3d4d5a9d0785e61dbc4dd85e9348ad48b9ed29f9 /drivers/acpi/apei
parent29924b9f8f39e37275cff93740835d28b9e6fb36 (diff)
Use acpi_os_map_memory() instead of ioremap() in einj driver
ioremap() has become more picky and is now spitting out console messages like: ioremap error for 0xbddbd000-0xbddbe000, requested 0x10, got 0x0 when loading the einj driver. What we are trying to so here is map a couple of data structures that the EINJ table points to. Perhaps acpi_os_map_memory() is a better tool for this? Most importantly it works, but as a side benefit it maps the structures into kernel virtual space so we can access them with normal C memory dereferences, so instead of using: writel(param1, &v5param->apicid); we can use the more natural: v5param->apicid = param1; Signed-off-by: Tony Luck <tony.luck@intel.com> Signed-off-by: Len Brown <len.brown@intel.com>
Diffstat (limited to 'drivers/acpi/apei')
-rw-r--r--drivers/acpi/apei/einj.c82
1 files changed, 38 insertions, 44 deletions
diff --git a/drivers/acpi/apei/einj.c b/drivers/acpi/apei/einj.c
index c89b0e5a229..4ca087dd5f4 100644
--- a/drivers/acpi/apei/einj.c
+++ b/drivers/acpi/apei/einj.c
@@ -141,21 +141,6 @@ static DEFINE_MUTEX(einj_mutex);
141 141
142static void *einj_param; 142static void *einj_param;
143 143
144#ifndef readq
145static inline __u64 readq(volatile void __iomem *addr)
146{
147 return ((__u64)readl(addr+4) << 32) + readl(addr);
148}
149#endif
150
151#ifndef writeq
152static inline void writeq(__u64 val, volatile void __iomem *addr)
153{
154 writel(val, addr);
155 writel(val >> 32, addr+4);
156}
157#endif
158
159static void einj_exec_ctx_init(struct apei_exec_context *ctx) 144static void einj_exec_ctx_init(struct apei_exec_context *ctx)
160{ 145{
161 apei_exec_ctx_init(ctx, einj_ins_type, ARRAY_SIZE(einj_ins_type), 146 apei_exec_ctx_init(ctx, einj_ins_type, ARRAY_SIZE(einj_ins_type),
@@ -204,22 +189,21 @@ static int einj_timedout(u64 *t)
204static void check_vendor_extension(u64 paddr, 189static void check_vendor_extension(u64 paddr,
205 struct set_error_type_with_address *v5param) 190 struct set_error_type_with_address *v5param)
206{ 191{
207 int offset = readl(&v5param->vendor_extension); 192 int offset = v5param->vendor_extension;
208 struct vendor_error_type_extension *v; 193 struct vendor_error_type_extension *v;
209 u32 sbdf; 194 u32 sbdf;
210 195
211 if (!offset) 196 if (!offset)
212 return; 197 return;
213 v = ioremap(paddr + offset, sizeof(*v)); 198 v = acpi_os_map_memory(paddr + offset, sizeof(*v));
214 if (!v) 199 if (!v)
215 return; 200 return;
216 sbdf = readl(&v->pcie_sbdf); 201 sbdf = v->pcie_sbdf;
217 sprintf(vendor_dev, "%x:%x:%x.%x vendor_id=%x device_id=%x rev_id=%x\n", 202 sprintf(vendor_dev, "%x:%x:%x.%x vendor_id=%x device_id=%x rev_id=%x\n",
218 sbdf >> 24, (sbdf >> 16) & 0xff, 203 sbdf >> 24, (sbdf >> 16) & 0xff,
219 (sbdf >> 11) & 0x1f, (sbdf >> 8) & 0x7, 204 (sbdf >> 11) & 0x1f, (sbdf >> 8) & 0x7,
220 readw(&v->vendor_id), readw(&v->device_id), 205 v->vendor_id, v->device_id, v->rev_id);
221 readb(&v->rev_id)); 206 acpi_os_unmap_memory(v, sizeof(*v));
222 iounmap(v);
223} 207}
224 208
225static void *einj_get_parameter_address(void) 209static void *einj_get_parameter_address(void)
@@ -247,7 +231,7 @@ static void *einj_get_parameter_address(void)
247 if (paddrv5) { 231 if (paddrv5) {
248 struct set_error_type_with_address *v5param; 232 struct set_error_type_with_address *v5param;
249 233
250 v5param = ioremap(paddrv5, sizeof(*v5param)); 234 v5param = acpi_os_map_memory(paddrv5, sizeof(*v5param));
251 if (v5param) { 235 if (v5param) {
252 acpi5 = 1; 236 acpi5 = 1;
253 check_vendor_extension(paddrv5, v5param); 237 check_vendor_extension(paddrv5, v5param);
@@ -257,11 +241,11 @@ static void *einj_get_parameter_address(void)
257 if (paddrv4) { 241 if (paddrv4) {
258 struct einj_parameter *v4param; 242 struct einj_parameter *v4param;
259 243
260 v4param = ioremap(paddrv4, sizeof(*v4param)); 244 v4param = acpi_os_map_memory(paddrv4, sizeof(*v4param));
261 if (!v4param) 245 if (!v4param)
262 return NULL; 246 return NULL;
263 if (readq(&v4param->reserved1) || readq(&v4param->reserved2)) { 247 if (v4param->reserved1 || v4param->reserved2) {
264 iounmap(v4param); 248 acpi_os_unmap_memory(v4param, sizeof(*v4param));
265 return NULL; 249 return NULL;
266 } 250 }
267 return v4param; 251 return v4param;
@@ -440,41 +424,41 @@ static int __einj_error_inject(u32 type, u64 param1, u64 param2)
440 if (acpi5) { 424 if (acpi5) {
441 struct set_error_type_with_address *v5param = einj_param; 425 struct set_error_type_with_address *v5param = einj_param;
442 426
443 writel(type, &v5param->type); 427 v5param->type = type;
444 if (type & 0x80000000) { 428 if (type & 0x80000000) {
445 switch (vendor_flags) { 429 switch (vendor_flags) {
446 case SETWA_FLAGS_APICID: 430 case SETWA_FLAGS_APICID:
447 writel(param1, &v5param->apicid); 431 v5param->apicid = param1;
448 break; 432 break;
449 case SETWA_FLAGS_MEM: 433 case SETWA_FLAGS_MEM:
450 writeq(param1, &v5param->memory_address); 434 v5param->memory_address = param1;
451 writeq(param2, &v5param->memory_address_range); 435 v5param->memory_address_range = param2;
452 break; 436 break;
453 case SETWA_FLAGS_PCIE_SBDF: 437 case SETWA_FLAGS_PCIE_SBDF:
454 writel(param1, &v5param->pcie_sbdf); 438 v5param->pcie_sbdf = param1;
455 break; 439 break;
456 } 440 }
457 writel(vendor_flags, &v5param->flags); 441 v5param->flags = vendor_flags;
458 } else { 442 } else {
459 switch (type) { 443 switch (type) {
460 case ACPI_EINJ_PROCESSOR_CORRECTABLE: 444 case ACPI_EINJ_PROCESSOR_CORRECTABLE:
461 case ACPI_EINJ_PROCESSOR_UNCORRECTABLE: 445 case ACPI_EINJ_PROCESSOR_UNCORRECTABLE:
462 case ACPI_EINJ_PROCESSOR_FATAL: 446 case ACPI_EINJ_PROCESSOR_FATAL:
463 writel(param1, &v5param->apicid); 447 v5param->apicid = param1;
464 writel(SETWA_FLAGS_APICID, &v5param->flags); 448 v5param->flags = SETWA_FLAGS_APICID;
465 break; 449 break;
466 case ACPI_EINJ_MEMORY_CORRECTABLE: 450 case ACPI_EINJ_MEMORY_CORRECTABLE:
467 case ACPI_EINJ_MEMORY_UNCORRECTABLE: 451 case ACPI_EINJ_MEMORY_UNCORRECTABLE:
468 case ACPI_EINJ_MEMORY_FATAL: 452 case ACPI_EINJ_MEMORY_FATAL:
469 writeq(param1, &v5param->memory_address); 453 v5param->memory_address = param1;
470 writeq(param2, &v5param->memory_address_range); 454 v5param->memory_address_range = param2;
471 writel(SETWA_FLAGS_MEM, &v5param->flags); 455 v5param->flags = SETWA_FLAGS_MEM;
472 break; 456 break;
473 case ACPI_EINJ_PCIX_CORRECTABLE: 457 case ACPI_EINJ_PCIX_CORRECTABLE:
474 case ACPI_EINJ_PCIX_UNCORRECTABLE: 458 case ACPI_EINJ_PCIX_UNCORRECTABLE:
475 case ACPI_EINJ_PCIX_FATAL: 459 case ACPI_EINJ_PCIX_FATAL:
476 writel(param1, &v5param->pcie_sbdf); 460 v5param->pcie_sbdf = param1;
477 writel(SETWA_FLAGS_PCIE_SBDF, &v5param->flags); 461 v5param->flags = SETWA_FLAGS_PCIE_SBDF;
478 break; 462 break;
479 } 463 }
480 } 464 }
@@ -484,8 +468,8 @@ static int __einj_error_inject(u32 type, u64 param1, u64 param2)
484 return rc; 468 return rc;
485 if (einj_param) { 469 if (einj_param) {
486 struct einj_parameter *v4param = einj_param; 470 struct einj_parameter *v4param = einj_param;
487 writeq(param1, &v4param->param1); 471 v4param->param1 = param1;
488 writeq(param2, &v4param->param2); 472 v4param->param2 = param2;
489 } 473 }
490 } 474 }
491 rc = apei_exec_run(&ctx, ACPI_EINJ_EXECUTE_OPERATION); 475 rc = apei_exec_run(&ctx, ACPI_EINJ_EXECUTE_OPERATION);
@@ -736,8 +720,13 @@ static int __init einj_init(void)
736 return 0; 720 return 0;
737 721
738err_unmap: 722err_unmap:
739 if (einj_param) 723 if (einj_param) {
740 iounmap(einj_param); 724 acpi_size size = (acpi5) ?
725 sizeof(struct set_error_type_with_address) :
726 sizeof(struct einj_parameter);
727
728 acpi_os_unmap_memory(einj_param, size);
729 }
741 apei_exec_post_unmap_gars(&ctx); 730 apei_exec_post_unmap_gars(&ctx);
742err_release: 731err_release:
743 apei_resources_release(&einj_resources); 732 apei_resources_release(&einj_resources);
@@ -753,8 +742,13 @@ static void __exit einj_exit(void)
753{ 742{
754 struct apei_exec_context ctx; 743 struct apei_exec_context ctx;
755 744
756 if (einj_param) 745 if (einj_param) {
757 iounmap(einj_param); 746 acpi_size size = (acpi5) ?
747 sizeof(struct set_error_type_with_address) :
748 sizeof(struct einj_parameter);
749
750 acpi_os_unmap_memory(einj_param, size);
751 }
758 einj_exec_ctx_init(&ctx); 752 einj_exec_ctx_init(&ctx);
759 apei_exec_post_unmap_gars(&ctx); 753 apei_exec_post_unmap_gars(&ctx);
760 apei_resources_release(&einj_resources); 754 apei_resources_release(&einj_resources);