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-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3)  * apple.c - Apple ACPI quirks
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  * Copyright (C) 2017 Lukas Wunner <lukas@wunner.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/bitmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/platform_data/x86/apple.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/uuid.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) /* Apple _DSM device properties GUID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) static const guid_t apple_prp_guid =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 	GUID_INIT(0xa0b5b7c6, 0x1318, 0x441c,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) 		  0xb0, 0xc9, 0xfe, 0x69, 0x5e, 0xaf, 0x94, 0x9b);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  * acpi_extract_apple_properties - retrieve and convert Apple _DSM properties
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  * @adev: ACPI device for which to retrieve the properties
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  * Invoke Apple's custom _DSM once to check the protocol version and once more
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22)  * to retrieve the properties.  They are marshalled up in a single package as
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23)  * alternating key/value elements, unlike _DSD which stores them as a package
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24)  * of 2-element packages.  Convert to _DSD format and make them available under
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25)  * the primary fwnode.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) void acpi_extract_apple_properties(struct acpi_device *adev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 	unsigned int i, j = 0, newsize = 0, numprops, numvalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) 	union acpi_object *props, *newprops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	unsigned long *valid = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	void *free_space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	if (!x86_apple_machine)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 	props = acpi_evaluate_dsm_typed(adev->handle, &apple_prp_guid, 1, 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 					NULL, ACPI_TYPE_BUFFER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	if (!props)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	if (!props->buffer.length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	if (props->buffer.pointer[0] != 3) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		acpi_handle_info(adev->handle, FW_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 				 "unsupported properties version %*ph\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 				 props->buffer.length, props->buffer.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	ACPI_FREE(props);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 	props = acpi_evaluate_dsm_typed(adev->handle, &apple_prp_guid, 1, 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) 					NULL, ACPI_TYPE_PACKAGE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) 	if (!props)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 	numprops = props->package.count / 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 	if (!numprops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	valid = bitmap_zalloc(numprops, GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	if (!valid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	/* newsize = key length + value length of each tuple */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	for (i = 0; i < numprops; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 		union acpi_object *key = &props->package.elements[i * 2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 		union acpi_object *val = &props->package.elements[i * 2 + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		if ( key->type != ACPI_TYPE_STRING ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		    (val->type != ACPI_TYPE_INTEGER &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		     val->type != ACPI_TYPE_BUFFER))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 			continue; /* skip invalid properties */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 		__set_bit(i, valid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 		newsize += key->string.length + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 		if ( val->type == ACPI_TYPE_BUFFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 			newsize += val->buffer.length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	numvalid = bitmap_weight(valid, numprops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	if (numprops > numvalid)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		acpi_handle_info(adev->handle, FW_INFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 				 "skipped %u properties: wrong type\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 				 numprops - numvalid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	if (numvalid == 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	/* newsize += top-level package + 3 objects for each key/value tuple */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) 	newsize	+= (1 + 3 * numvalid) * sizeof(union acpi_object);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 	newprops = ACPI_ALLOCATE_ZEROED(newsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	if (!newprops)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 		goto out_free;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	/* layout: top-level package | packages | key/value tuples | strings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	newprops->type = ACPI_TYPE_PACKAGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 	newprops->package.count = numvalid;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	newprops->package.elements = &newprops[1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	free_space = &newprops[1 + 3 * numvalid];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	for_each_set_bit(i, valid, numprops) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 		union acpi_object *key = &props->package.elements[i * 2];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 		union acpi_object *val = &props->package.elements[i * 2 + 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 		unsigned int k = 1 + numvalid + j * 2; /* index into newprops */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 		unsigned int v = k + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 		newprops[1 + j].type = ACPI_TYPE_PACKAGE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 		newprops[1 + j].package.count = 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) 		newprops[1 + j].package.elements = &newprops[k];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) 		newprops[k].type = ACPI_TYPE_STRING;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) 		newprops[k].string.length = key->string.length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 		newprops[k].string.pointer = free_space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		memcpy(free_space, key->string.pointer, key->string.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 		free_space += key->string.length + 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 		newprops[v].type = val->type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 		if (val->type == ACPI_TYPE_INTEGER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) 			newprops[v].integer.value = val->integer.value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 		} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) 			newprops[v].buffer.length = val->buffer.length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) 			newprops[v].buffer.pointer = free_space;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 			memcpy(free_space, val->buffer.pointer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) 			       val->buffer.length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 			free_space += val->buffer.length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) 		j++; /* count valid properties */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 	WARN_ON(free_space != (void *)newprops + newsize);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	adev->data.pointer = newprops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 	acpi_data_add_props(&adev->data, &apple_prp_guid, newprops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) out_free:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) 	ACPI_FREE(props);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 	bitmap_free(valid);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }