Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * Address translation interface via ACPI DSM.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright (C) 2018 Intel Corporation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  * Specification for this interface is available at:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8)  *	https://cdrdv2.intel.com/v1/dl/getContent/603354
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #include <linux/adxl.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #define ADXL_REVISION			0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #define ADXL_IDX_GET_ADDR_PARAMS	0x1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #define ADXL_IDX_FORWARD_TRANSLATE	0x2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #define ACPI_ADXL_PATH			"\\_SB.ADXL"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  * The specification doesn't provide a limit on how many
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * components are in a memory address. But since we allocate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  * memory based on the number the BIOS tells us, we should
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * defend against insane values.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) #define ADXL_MAX_COMPONENTS		500
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) #undef pr_fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) #define pr_fmt(fmt) "ADXL: " fmt
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) static acpi_handle handle;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) static union acpi_object *params;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) static const guid_t adxl_guid =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	GUID_INIT(0xAA3C050A, 0x7EA4, 0x4C1F,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 		  0xAF, 0xDA, 0x12, 0x67, 0xDF, 0xD3, 0xD4, 0x8D);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) static int adxl_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) static char **adxl_component_names;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) static union acpi_object *adxl_dsm(int cmd, union acpi_object argv[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 	union acpi_object *obj, *o;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	obj = acpi_evaluate_dsm_typed(handle, &adxl_guid, ADXL_REVISION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 				      cmd, argv, ACPI_TYPE_PACKAGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	if (!obj) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		pr_info("DSM call failed for cmd=%d\n", cmd);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 		return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	if (obj->package.count != 2) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 		pr_info("Bad pkg count %d\n", obj->package.count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	o = obj->package.elements;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	if (o->type != ACPI_TYPE_INTEGER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 		pr_info("Bad 1st element type %d\n", o->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 	if (o->integer.value) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 		pr_info("Bad ret val %llu\n", o->integer.value);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 	o = obj->package.elements + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	if (o->type != ACPI_TYPE_PACKAGE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 		pr_info("Bad 2nd element type %d\n", o->type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 		goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	return obj;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 	ACPI_FREE(obj);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78)  * adxl_get_component_names - get list of memory component names
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79)  * Returns NULL terminated list of string names
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81)  * Give the caller a pointer to the list of memory component names
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82)  * e.g. { "SystemAddress", "ProcessorSocketId", "ChannelId", ... NULL }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83)  * Caller should count how many strings in order to allocate a buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84)  * for the return from adxl_decode().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) const char * const *adxl_get_component_names(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	return (const char * const *)adxl_component_names;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) EXPORT_SYMBOL_GPL(adxl_get_component_names);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93)  * adxl_decode - ask BIOS to decode a system address to memory address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94)  * @addr: the address to decode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95)  * @component_values: pointer to array of values for each component
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96)  * Returns 0 on success, negative error code otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98)  * The index of each value returned in the array matches the index of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99)  * each component name returned by adxl_get_component_names().
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)  * Components that are not defined for this address translation (e.g.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)  * mirror channel number for a non-mirrored address) are set to ~0ull.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) int adxl_decode(u64 addr, u64 component_values[])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	union acpi_object argv4[2], *results, *r;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	int i, cnt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 	if (!adxl_component_names)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		return -EOPNOTSUPP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 	argv4[0].type = ACPI_TYPE_PACKAGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 	argv4[0].package.count = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 	argv4[0].package.elements = &argv4[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	argv4[1].integer.type = ACPI_TYPE_INTEGER;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 	argv4[1].integer.value = addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	results = adxl_dsm(ADXL_IDX_FORWARD_TRANSLATE, argv4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	if (!results)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 	r = results->package.elements + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 	cnt = r->package.count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 	if (cnt != adxl_count) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 		ACPI_FREE(results);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 	r = r->package.elements;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	for (i = 0; i < cnt; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		component_values[i] = r[i].integer.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	ACPI_FREE(results);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) EXPORT_SYMBOL_GPL(adxl_decode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static int __init adxl_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	char *path = ACPI_ADXL_PATH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) 	union acpi_object *p;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 	acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	status = acpi_get_handle(NULL, path, &handle);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 	if (ACPI_FAILURE(status)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 		pr_debug("No ACPI handle for path %s\n", path);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	if (!acpi_has_method(handle, "_DSM")) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) 		pr_info("No DSM method\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	if (!acpi_check_dsm(handle, &adxl_guid, ADXL_REVISION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) 			    ADXL_IDX_GET_ADDR_PARAMS |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 			    ADXL_IDX_FORWARD_TRANSLATE)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) 		pr_info("DSM method does not support forward translate\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 	params = adxl_dsm(ADXL_IDX_GET_ADDR_PARAMS, NULL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	if (!params) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 		pr_info("Failed to get component names\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 	p = params->package.elements + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) 	adxl_count = p->package.count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) 	if (adxl_count > ADXL_MAX_COMPONENTS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 		pr_info("Insane number of address component names %d\n", adxl_count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) 		ACPI_FREE(params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 		return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) 	p = p->package.elements;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 	/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 	 * Allocate one extra for NULL termination.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 	adxl_component_names = kcalloc(adxl_count + 1, sizeof(char *), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 	if (!adxl_component_names) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 		ACPI_FREE(params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) 	for (i = 0; i < adxl_count; i++)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 		adxl_component_names[i] = p[i].string.pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) subsys_initcall(adxl_init);