xref: /netbsd-src/sys/external/bsd/drm2/linux/linux_acpi.c (revision 3eb670e5122747a42cecb74444eefeca7bfbf5a9)
1*3eb670e5Sriastradh /*	$NetBSD: linux_acpi.c,v 1.2 2022/02/28 17:15:30 riastradh Exp $	*/
2c981a879Sriastradh 
3c981a879Sriastradh /*-
4c981a879Sriastradh  * Copyright (c) 2022 The NetBSD Foundation, Inc.
5c981a879Sriastradh  * All rights reserved.
6c981a879Sriastradh  *
7c981a879Sriastradh  * Redistribution and use in source and binary forms, with or without
8c981a879Sriastradh  * modification, are permitted provided that the following conditions
9c981a879Sriastradh  * are met:
10c981a879Sriastradh  * 1. Redistributions of source code must retain the above copyright
11c981a879Sriastradh  *    notice, this list of conditions and the following disclaimer.
12c981a879Sriastradh  * 2. Redistributions in binary form must reproduce the above copyright
13c981a879Sriastradh  *    notice, this list of conditions and the following disclaimer in the
14c981a879Sriastradh  *    documentation and/or other materials provided with the distribution.
15c981a879Sriastradh  *
16c981a879Sriastradh  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17c981a879Sriastradh  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18c981a879Sriastradh  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19c981a879Sriastradh  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20c981a879Sriastradh  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21c981a879Sriastradh  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22c981a879Sriastradh  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23c981a879Sriastradh  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24c981a879Sriastradh  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25c981a879Sriastradh  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26c981a879Sriastradh  * POSSIBILITY OF SUCH DAMAGE.
27c981a879Sriastradh  */
28c981a879Sriastradh 
29c981a879Sriastradh #include <sys/cdefs.h>
30*3eb670e5Sriastradh __KERNEL_RCSID(0, "$NetBSD: linux_acpi.c,v 1.2 2022/02/28 17:15:30 riastradh Exp $");
31*3eb670e5Sriastradh 
32*3eb670e5Sriastradh #include <dev/acpi/acpireg.h>
33c981a879Sriastradh 
34c981a879Sriastradh #include <linux/acpi.h>
35c981a879Sriastradh 
36*3eb670e5Sriastradh #define	_COMPONENT	ACPI_BUS_COMPONENT
37*3eb670e5Sriastradh ACPI_MODULE_NAME("linux_acpi")
38*3eb670e5Sriastradh 
39c981a879Sriastradh union acpi_object *
acpi_evaluate_dsm(acpi_handle handle,const guid_t * uuid,u64 rev,u64 func,union acpi_object * argv4)40c981a879Sriastradh acpi_evaluate_dsm(acpi_handle handle, const guid_t *uuid, u64 rev, u64 func,
41c981a879Sriastradh     union acpi_object *argv4)
42c981a879Sriastradh {
43c981a879Sriastradh 	ACPI_OBJECT_LIST arg;
44c981a879Sriastradh 	ACPI_OBJECT params[4];
45c981a879Sriastradh 	ACPI_BUFFER buf;
46c981a879Sriastradh 	ACPI_STATUS rv;
47c981a879Sriastradh 
48c981a879Sriastradh 	if (handle == NULL)
49c981a879Sriastradh 		handle = ACPI_ROOT_OBJECT;
50c981a879Sriastradh 
51c981a879Sriastradh 	arg.Count = 4;
52c981a879Sriastradh 	arg.Pointer = params;
53c981a879Sriastradh 	params[0].Type = ACPI_TYPE_BUFFER;
54c981a879Sriastradh 	params[0].Buffer.Length = 16;
55c981a879Sriastradh 	params[0].Buffer.Pointer = (char *)__UNCONST(uuid);
56c981a879Sriastradh 	params[1].Type = ACPI_TYPE_INTEGER;
57c981a879Sriastradh 	params[1].Integer.Value = rev;
58c981a879Sriastradh 	params[2].Type = ACPI_TYPE_INTEGER;
59c981a879Sriastradh 	params[2].Integer.Value = func;
60c981a879Sriastradh 	if (argv4 != NULL) {
61c981a879Sriastradh 		params[3] = *argv4;
62c981a879Sriastradh 	} else {
63c981a879Sriastradh 		params[3].Type = ACPI_TYPE_PACKAGE;
64c981a879Sriastradh 		params[3].Package.Count = 0;
65c981a879Sriastradh 		params[3].Package.Elements = NULL;
66c981a879Sriastradh 	}
67c981a879Sriastradh 
68c981a879Sriastradh 	buf.Pointer = NULL;
69c981a879Sriastradh 	buf.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
70c981a879Sriastradh 
71c981a879Sriastradh 	rv = AcpiEvaluateObject(handle, "_DSM", &arg, &buf);
72c981a879Sriastradh 	if (ACPI_SUCCESS(rv))
73c981a879Sriastradh 		return (ACPI_OBJECT *)buf.Pointer;
74c981a879Sriastradh 	return NULL;
75c981a879Sriastradh }
76c981a879Sriastradh 
77c981a879Sriastradh union acpi_object *
acpi_evaluate_dsm_typed(acpi_handle handle,const guid_t * uuid,u64 rev,u64 func,union acpi_object * argv4,acpi_object_type type)78c981a879Sriastradh acpi_evaluate_dsm_typed(acpi_handle handle, const guid_t *uuid, u64 rev,
79c981a879Sriastradh     u64 func, union acpi_object *argv4, acpi_object_type type)
80c981a879Sriastradh {
81c981a879Sriastradh 	union acpi_object *obj;
82c981a879Sriastradh 
83c981a879Sriastradh 	obj = acpi_evaluate_dsm(handle, uuid, rev, func, argv4);
84c981a879Sriastradh 	if (obj != NULL && obj->Type != type) {
85c981a879Sriastradh 		ACPI_FREE(obj);
86c981a879Sriastradh 		obj = NULL;
87c981a879Sriastradh 	}
88c981a879Sriastradh 	return obj;
89c981a879Sriastradh }
90c981a879Sriastradh 
91c981a879Sriastradh #define	ACPI_INIT_DSM_ARGV4(cnt, eles)		\
92c981a879Sriastradh {						\
93c981a879Sriastradh 	.Package.Type = ACPI_TYPE_PACKAGE,	\
94c981a879Sriastradh 	.Package.Count = (cnt),			\
95c981a879Sriastradh 	.Package.Elements = (eles)		\
96c981a879Sriastradh }
97c981a879Sriastradh 
98c981a879Sriastradh bool
acpi_check_dsm(acpi_handle handle,const guid_t * uuid,u64 rev,u64 funcs)99c981a879Sriastradh acpi_check_dsm(acpi_handle handle, const guid_t *uuid, u64 rev, u64 funcs)
100c981a879Sriastradh {
101c981a879Sriastradh 	ACPI_OBJECT *obj;
102c981a879Sriastradh 	uint64_t mask = 0;
103c981a879Sriastradh 	int i;
104c981a879Sriastradh 
105c981a879Sriastradh 	if (funcs == 0)
106c981a879Sriastradh 		return false;
107c981a879Sriastradh 
108c981a879Sriastradh 	obj = acpi_evaluate_dsm(handle, uuid, rev, 0, NULL);
109c981a879Sriastradh 	if (obj == NULL)
110c981a879Sriastradh 		return false;
111c981a879Sriastradh 
112c981a879Sriastradh 	if (obj->Type == ACPI_TYPE_INTEGER)
113c981a879Sriastradh 		mask = obj->Integer.Value;
114c981a879Sriastradh 	else if (obj->Type == ACPI_TYPE_BUFFER)
115c981a879Sriastradh 		for (i = 0; i < obj->Buffer.Length && i < 8; i++)
116c981a879Sriastradh 			mask |= (uint64_t)obj->Buffer.Pointer[i] << (i * 8);
117c981a879Sriastradh 	ACPI_FREE(obj);
118c981a879Sriastradh 
119c981a879Sriastradh 	if ((mask & 0x1) == 0x1 && (mask & funcs) == funcs)
120c981a879Sriastradh 		return true;
121c981a879Sriastradh 	return false;
122c981a879Sriastradh }
123