diff options
Diffstat (limited to 'drivers')
| -rw-r--r-- | drivers/acpi/apei/apei-base.c | 32 |
1 files changed, 26 insertions, 6 deletions
diff --git a/drivers/acpi/apei/apei-base.c b/drivers/acpi/apei/apei-base.c index 2cd7bdd6c8b3..a85ac07f3da3 100644 --- a/drivers/acpi/apei/apei-base.c +++ b/drivers/acpi/apei/apei-base.c | |||
| @@ -449,7 +449,7 @@ int apei_resources_sub(struct apei_resources *resources1, | |||
| 449 | } | 449 | } |
| 450 | EXPORT_SYMBOL_GPL(apei_resources_sub); | 450 | EXPORT_SYMBOL_GPL(apei_resources_sub); |
| 451 | 451 | ||
| 452 | static int apei_get_nvs_callback(__u64 start, __u64 size, void *data) | 452 | static int apei_get_res_callback(__u64 start, __u64 size, void *data) |
| 453 | { | 453 | { |
| 454 | struct apei_resources *resources = data; | 454 | struct apei_resources *resources = data; |
| 455 | return apei_res_add(&resources->iomem, start, size); | 455 | return apei_res_add(&resources->iomem, start, size); |
| @@ -457,7 +457,15 @@ static int apei_get_nvs_callback(__u64 start, __u64 size, void *data) | |||
| 457 | 457 | ||
| 458 | static int apei_get_nvs_resources(struct apei_resources *resources) | 458 | static int apei_get_nvs_resources(struct apei_resources *resources) |
| 459 | { | 459 | { |
| 460 | return acpi_nvs_for_each_region(apei_get_nvs_callback, resources); | 460 | return acpi_nvs_for_each_region(apei_get_res_callback, resources); |
| 461 | } | ||
| 462 | |||
| 463 | int (*arch_apei_filter_addr)(int (*func)(__u64 start, __u64 size, | ||
| 464 | void *data), void *data); | ||
| 465 | static int apei_get_arch_resources(struct apei_resources *resources) | ||
| 466 | |||
| 467 | { | ||
| 468 | return arch_apei_filter_addr(apei_get_res_callback, resources); | ||
| 461 | } | 469 | } |
| 462 | 470 | ||
| 463 | /* | 471 | /* |
| @@ -470,7 +478,7 @@ int apei_resources_request(struct apei_resources *resources, | |||
| 470 | { | 478 | { |
| 471 | struct apei_res *res, *res_bak = NULL; | 479 | struct apei_res *res, *res_bak = NULL; |
| 472 | struct resource *r; | 480 | struct resource *r; |
| 473 | struct apei_resources nvs_resources; | 481 | struct apei_resources nvs_resources, arch_res; |
| 474 | int rc; | 482 | int rc; |
| 475 | 483 | ||
| 476 | rc = apei_resources_sub(resources, &apei_resources_all); | 484 | rc = apei_resources_sub(resources, &apei_resources_all); |
| @@ -485,10 +493,20 @@ int apei_resources_request(struct apei_resources *resources, | |||
| 485 | apei_resources_init(&nvs_resources); | 493 | apei_resources_init(&nvs_resources); |
| 486 | rc = apei_get_nvs_resources(&nvs_resources); | 494 | rc = apei_get_nvs_resources(&nvs_resources); |
| 487 | if (rc) | 495 | if (rc) |
| 488 | goto res_fini; | 496 | goto nvs_res_fini; |
| 489 | rc = apei_resources_sub(resources, &nvs_resources); | 497 | rc = apei_resources_sub(resources, &nvs_resources); |
| 490 | if (rc) | 498 | if (rc) |
| 491 | goto res_fini; | 499 | goto nvs_res_fini; |
| 500 | |||
| 501 | if (arch_apei_filter_addr) { | ||
| 502 | apei_resources_init(&arch_res); | ||
| 503 | rc = apei_get_arch_resources(&arch_res); | ||
| 504 | if (rc) | ||
| 505 | goto arch_res_fini; | ||
| 506 | rc = apei_resources_sub(resources, &arch_res); | ||
| 507 | if (rc) | ||
| 508 | goto arch_res_fini; | ||
| 509 | } | ||
| 492 | 510 | ||
| 493 | rc = -EINVAL; | 511 | rc = -EINVAL; |
| 494 | list_for_each_entry(res, &resources->iomem, list) { | 512 | list_for_each_entry(res, &resources->iomem, list) { |
| @@ -536,7 +554,9 @@ err_unmap_iomem: | |||
| 536 | break; | 554 | break; |
| 537 | release_mem_region(res->start, res->end - res->start); | 555 | release_mem_region(res->start, res->end - res->start); |
| 538 | } | 556 | } |
| 539 | res_fini: | 557 | arch_res_fini: |
| 558 | apei_resources_fini(&arch_res); | ||
| 559 | nvs_res_fini: | ||
| 540 | apei_resources_fini(&nvs_resources); | 560 | apei_resources_fini(&nvs_resources); |
| 541 | return rc; | 561 | return rc; |
| 542 | } | 562 | } |
