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
---
By my interpretation of the spec, the use of _ADR for this purpose is incorrect. Regardless, this patch makes automatic SPCR console identification work on Juno and FVP.
arch/arm64/kernel/acpi.c | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-)
diff --git a/arch/arm64/kernel/acpi.c b/arch/arm64/kernel/acpi.c index c5c6e49..64129b8 100644 --- a/arch/arm64/kernel/acpi.c +++ b/arch/arm64/kernel/acpi.c @@ -313,31 +313,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",