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)  * (c) Copyright 2003, 2006 Hewlett-Packard Development Company, L.P.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4)  *	Alex Williamson <alex.williamson@hp.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5)  *	Bjorn Helgaas <bjorn.helgaas@hp.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #include <linux/acpi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) #include <asm/acpi-ext.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16)  * Device CSRs that do not appear in PCI config space should be described
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17)  * via ACPI.  This would normally be done with Address Space Descriptors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18)  * marked as "consumer-only," but old versions of Windows and Linux ignore
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19)  * the producer/consumer flag, so HP invented a vendor-defined resource to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20)  * describe the location and size of CSR space.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) struct acpi_vendor_uuid hp_ccsr_uuid = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	.subtype = 2,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	.data = { 0xf9, 0xad, 0xe9, 0x69, 0x4f, 0x92, 0x5f, 0xab, 0xf6, 0x4a,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 	    0x24, 0xd2, 0x01, 0x37, 0x0e, 0xad },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) static acpi_status hp_ccsr_locate(acpi_handle obj, u64 *base, u64 *length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) 	acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	struct acpi_resource *resource;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 	struct acpi_resource_vendor_typed *vendor;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 	status = acpi_get_vendor_resource(obj, METHOD_NAME__CRS, &hp_ccsr_uuid,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 		&buffer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	resource = buffer.pointer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 	vendor = &resource->data.vendor_typed;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 	if (ACPI_FAILURE(status) || vendor->byte_length < 16) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 		status = AE_NOT_FOUND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 		goto exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	memcpy(base, vendor->byte_data, sizeof(*base));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 	memcpy(length, vendor->byte_data + 8, sizeof(*length));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50)   exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	kfree(buffer.pointer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) 	return status;
^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) struct csr_space {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	u64	base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) 	u64	length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) static acpi_status find_csr_space(struct acpi_resource *resource, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) 	struct csr_space *space = data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 	struct acpi_resource_address64 addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) 	acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	status = acpi_resource_to_address64(resource, &addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 	if (ACPI_SUCCESS(status) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	    addr.resource_type == ACPI_MEMORY_RANGE &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	    addr.address.address_length &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 	    addr.producer_consumer == ACPI_CONSUMER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 		space->base = addr.address.minimum;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 		space->length = addr.address.address_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 		return AE_CTRL_TERMINATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 	return AE_OK;		/* keep looking */
^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) static acpi_status hp_crs_locate(acpi_handle obj, u64 *base, u64 *length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	struct csr_space space = { 0, 0 };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 	acpi_walk_resources(obj, METHOD_NAME__CRS, find_csr_space, &space);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) 	if (!space.length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) 		return AE_NOT_FOUND;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 	*base = space.base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	*length = space.length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 	return AE_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) acpi_status hp_acpi_csr_space(acpi_handle obj, u64 *csr_base, u64 *csr_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) 	acpi_status status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	status = hp_ccsr_locate(obj, csr_base, csr_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 	if (ACPI_SUCCESS(status))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 		return status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 	return hp_crs_locate(obj, csr_base, csr_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) EXPORT_SYMBOL(hp_acpi_csr_space);