diff options
Diffstat (limited to 'drivers/acpi/osl.c')
-rw-r--r-- | drivers/acpi/osl.c | 72 |
1 files changed, 72 insertions, 0 deletions
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c index 7ca41bf023c9..8df9abfa947b 100644 --- a/drivers/acpi/osl.c +++ b/drivers/acpi/osl.c | |||
@@ -45,6 +45,8 @@ | |||
45 | #include <linux/uaccess.h> | 45 | #include <linux/uaccess.h> |
46 | #include <linux/io-64-nonatomic-lo-hi.h> | 46 | #include <linux/io-64-nonatomic-lo-hi.h> |
47 | 47 | ||
48 | #include "acpica/accommon.h" | ||
49 | #include "acpica/acnamesp.h" | ||
48 | #include "internal.h" | 50 | #include "internal.h" |
49 | 51 | ||
50 | #define _COMPONENT ACPI_OS_SERVICES | 52 | #define _COMPONENT ACPI_OS_SERVICES |
@@ -1490,6 +1492,76 @@ int acpi_check_region(resource_size_t start, resource_size_t n, | |||
1490 | } | 1492 | } |
1491 | EXPORT_SYMBOL(acpi_check_region); | 1493 | EXPORT_SYMBOL(acpi_check_region); |
1492 | 1494 | ||
1495 | static acpi_status acpi_deactivate_mem_region(acpi_handle handle, u32 level, | ||
1496 | void *_res, void **return_value) | ||
1497 | { | ||
1498 | struct acpi_mem_space_context **mem_ctx; | ||
1499 | union acpi_operand_object *handler_obj; | ||
1500 | union acpi_operand_object *region_obj2; | ||
1501 | union acpi_operand_object *region_obj; | ||
1502 | struct resource *res = _res; | ||
1503 | acpi_status status; | ||
1504 | |||
1505 | region_obj = acpi_ns_get_attached_object(handle); | ||
1506 | if (!region_obj) | ||
1507 | return AE_OK; | ||
1508 | |||
1509 | handler_obj = region_obj->region.handler; | ||
1510 | if (!handler_obj) | ||
1511 | return AE_OK; | ||
1512 | |||
1513 | if (region_obj->region.space_id != ACPI_ADR_SPACE_SYSTEM_MEMORY) | ||
1514 | return AE_OK; | ||
1515 | |||
1516 | if (!(region_obj->region.flags & AOPOBJ_SETUP_COMPLETE)) | ||
1517 | return AE_OK; | ||
1518 | |||
1519 | region_obj2 = acpi_ns_get_secondary_object(region_obj); | ||
1520 | if (!region_obj2) | ||
1521 | return AE_OK; | ||
1522 | |||
1523 | mem_ctx = (void *)®ion_obj2->extra.region_context; | ||
1524 | |||
1525 | if (!(mem_ctx[0]->address >= res->start && | ||
1526 | mem_ctx[0]->address < res->end)) | ||
1527 | return AE_OK; | ||
1528 | |||
1529 | status = handler_obj->address_space.setup(region_obj, | ||
1530 | ACPI_REGION_DEACTIVATE, | ||
1531 | NULL, (void **)mem_ctx); | ||
1532 | if (ACPI_SUCCESS(status)) | ||
1533 | region_obj->region.flags &= ~(AOPOBJ_SETUP_COMPLETE); | ||
1534 | |||
1535 | return status; | ||
1536 | } | ||
1537 | |||
1538 | /** | ||
1539 | * acpi_release_memory - Release any mappings done to a memory region | ||
1540 | * @handle: Handle to namespace node | ||
1541 | * @res: Memory resource | ||
1542 | * @level: A level that terminates the search | ||
1543 | * | ||
1544 | * Walks through @handle and unmaps all SystemMemory Operation Regions that | ||
1545 | * overlap with @res and that have already been activated (mapped). | ||
1546 | * | ||
1547 | * This is a helper that allows drivers to place special requirements on memory | ||
1548 | * region that may overlap with operation regions, primarily allowing them to | ||
1549 | * safely map the region as non-cached memory. | ||
1550 | * | ||
1551 | * The unmapped Operation Regions will be automatically remapped next time they | ||
1552 | * are called, so the drivers do not need to do anything else. | ||
1553 | */ | ||
1554 | acpi_status acpi_release_memory(acpi_handle handle, struct resource *res, | ||
1555 | u32 level) | ||
1556 | { | ||
1557 | if (!(res->flags & IORESOURCE_MEM)) | ||
1558 | return AE_TYPE; | ||
1559 | |||
1560 | return acpi_walk_namespace(ACPI_TYPE_REGION, handle, level, | ||
1561 | acpi_deactivate_mem_region, NULL, res, NULL); | ||
1562 | } | ||
1563 | EXPORT_SYMBOL_GPL(acpi_release_memory); | ||
1564 | |||
1493 | /* | 1565 | /* |
1494 | * Let drivers know whether the resource checks are effective | 1566 | * Let drivers know whether the resource checks are effective |
1495 | */ | 1567 | */ |