Current driver supports only Function Index 1 & 2 as mentioned in the ACPI ADXL DSM Interface. Added a function for ACPI Function Index 3. Signed-off-by: Rithvik Rama <rithvik.rama@xxxxxxxxx> --- drivers/acpi/acpi_adxl.c | 54 +++++++++++++++++++++++++++++++++++++++- include/linux/adxl.h | 1 + 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/acpi_adxl.c b/drivers/acpi/acpi_adxl.c index 13c8f7b50c46..5bf53662b737 100644 --- a/drivers/acpi/acpi_adxl.c +++ b/drivers/acpi/acpi_adxl.c @@ -14,6 +14,7 @@ #define ADXL_REVISION 0x1 #define ADXL_IDX_GET_ADDR_PARAMS 0x1 #define ADXL_IDX_FORWARD_TRANSLATE 0x2 +#define ADXL_IDX_REVERSE_TRANSLATE 0X3 #define ACPI_ADXL_PATH "\\_SB.ADXL" /* @@ -135,6 +136,56 @@ int adxl_decode(u64 addr, u64 component_values[]) } EXPORT_SYMBOL_GPL(adxl_decode); +/** + * adxl_reverse_decode - Ask BIOS to decode a memory address to system address + * @component_values: pointer to array of values for each component + * Returns 0 on success, negative error code otherwise + * + */ + +int adxl_reverse_decode(u64 component_values[]) +{ + union acpi_object *argv4, *results, *r; + int i, cnt; + + argv4 = kzalloc((adxl_count+1)*sizeof(*argv4), GFP_KERNEL); + if (!argv4) + return -ENOMEM; + + if (!adxl_component_names) + return -EOPNOTSUPP; + + argv4[0].type = ACPI_TYPE_PACKAGE; + argv4[0].package.count = adxl_count; + argv4[0].package.elements = &argv4[1]; + + /* + * Loop through supported memory component values + */ + for (i = 1; i <= adxl_count; i++) { + argv4[i].integer.type = ACPI_TYPE_INTEGER; + argv4[i].integer.value = component_values[i-1]; + } + + results = adxl_dsm(ADXL_IDX_REVERSE_TRANSLATE, argv4); + if (!results) + return -EINVAL; + + r = results->package.elements + 1; + cnt = r->package.count; + if (cnt != adxl_count) { + ACPI_FREE(results); + return -EINVAL; + } + r = r->package.elements; + for (i = 0; i < cnt; i++) + component_values[i] = r[i].integer.value; + + ACPI_FREE(results); + return 0; +} +EXPORT_SYMBOL_GPL(adxl_reverse_decode); + static int __init adxl_init(void) { char *path = ACPI_ADXL_PATH; @@ -155,7 +206,8 @@ static int __init adxl_init(void) if (!acpi_check_dsm(handle, &adxl_guid, ADXL_REVISION, ADXL_IDX_GET_ADDR_PARAMS | - ADXL_IDX_FORWARD_TRANSLATE)) { + ADXL_IDX_FORWARD_TRANSLATE | + ADXL_IDX_REVERSE_TRANSLATE)) { pr_info("DSM method does not support forward translate\n"); return -ENODEV; } diff --git a/include/linux/adxl.h b/include/linux/adxl.h index 2a629acb4c3f..f3fea64a270c 100644 --- a/include/linux/adxl.h +++ b/include/linux/adxl.h @@ -9,5 +9,6 @@ const char * const *adxl_get_component_names(void); int adxl_decode(u64 addr, u64 component_values[]); +int adxl_reverse_decode(u64 component_values[]); #endif /* _LINUX_ADXL_H */ -- 2.34.1