diff options
author | Leif Lindholm <leif.lindholm@linaro.org> | 2015-08-03 18:15:56 +0100 |
---|---|---|
committer | Graeme Gregory <graeme.gregory@linaro.org> | 2015-08-31 11:58:20 +0100 |
commit | 06c62331b3db95a28ee122971cd8c7315dad0f99 (patch) | |
tree | 24d7c5ade012a3871ffcd46ee6e82b68fdc8e828 | |
parent | e9e27bca081bd9f4447d4f0b962284a5b1e4ca65 (diff) |
arm64: acpi: identify SPCR device by _CRS instead of _ADRacpi-topic-spcr
The first version of SPCR handling code identified the correct device
by comparing the address in SPCR with _ADR objects, through walking
the namespace.
Instead, use the required _CRS object for this matching, making the
functionality more portable.
Signed-off-by: Leif Lindholm <leif.lindholm@linaro.org>
-rw-r--r-- | arch/arm64/kernel/acpi.c | 32 |
1 files changed, 19 insertions, 13 deletions
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c index c098e3f2044a..8fa692efe865 100644 --- a/arch/arm64/kernel/acpi.c +++ b/arch/arm64/kernel/acpi.c @@ -309,31 +309,37 @@ static int __init acpi_parse_spcr(struct acpi_table_header *table) static acpi_status acpi_spcr_device_scan(acpi_handle handle, u32 level, void *context, void **retv) { - unsigned long long adr; + unsigned long long adr = 0; struct acpi_buffer name_buffer = { ACPI_ALLOCATE_BUFFER, NULL }; acpi_status status = AE_OK; struct acpi_device *adev; + struct list_head resource_list; + struct resource_entry *rentry; status = acpi_get_name(handle, ACPI_FULL_PATHNAME, &name_buffer); if (ACPI_FAILURE(status)) return status; + adev = acpi_bus_get_acpi_device(handle); + if (!adev) { + pr_err("Err locating SPCR device from ACPI handle\n"); + return AE_OK; /* skip this one */ + } + /* - * does thie APCI entry have an associated Address? + * Read device address from _CRS. */ - status = acpi_evaluate_integer(handle, "_ADR", NULL, &adr); - if (ACPI_FAILURE(status)) - return AE_OK; /* not device we are interested in... */ - - if (adr == spcr_serial_addr) { - - adev = acpi_bus_get_acpi_device(handle); + INIT_LIST_HEAD(&resource_list); + if (acpi_dev_get_resources(adev, &resource_list, NULL, NULL) <= 0) + return AE_OK; - if (!adev) { - pr_err("Err locating SPCR device from ACPI handle\n"); - return AE_OK; /* skip this one */ - } + list_for_each_entry(rentry, &resource_list, node) { + if (resource_type(rentry->res) == IORESOURCE_MEM) + adr = rentry->res->start; + } + acpi_dev_free_resource_list(&resource_list); + if (adr == spcr_serial_addr) { acpi_spcr_serial_device = adev; pr_info("SPCR serial console: %s (0x%llx)\n", |