xref: /netbsd/sys/external/bsd/drm2/linux/linux_acpi.c (revision 6bc5d83f)
1*6bc5d83fSriastradh /*	$NetBSD: linux_acpi.c,v 1.2 2022/02/28 17:15:30 riastradh Exp $	*/
267337615Sriastradh 
367337615Sriastradh /*-
467337615Sriastradh  * Copyright (c) 2022 The NetBSD Foundation, Inc.
567337615Sriastradh  * All rights reserved.
667337615Sriastradh  *
767337615Sriastradh  * Redistribution and use in source and binary forms, with or without
867337615Sriastradh  * modification, are permitted provided that the following conditions
967337615Sriastradh  * are met:
1067337615Sriastradh  * 1. Redistributions of source code must retain the above copyright
1167337615Sriastradh  *    notice, this list of conditions and the following disclaimer.
1267337615Sriastradh  * 2. Redistributions in binary form must reproduce the above copyright
1367337615Sriastradh  *    notice, this list of conditions and the following disclaimer in the
1467337615Sriastradh  *    documentation and/or other materials provided with the distribution.
1567337615Sriastradh  *
1667337615Sriastradh  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
1767337615Sriastradh  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
1867337615Sriastradh  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1967337615Sriastradh  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
2067337615Sriastradh  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
2167337615Sriastradh  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
2267337615Sriastradh  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2367337615Sriastradh  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2467337615Sriastradh  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2567337615Sriastradh  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
2667337615Sriastradh  * POSSIBILITY OF SUCH DAMAGE.
2767337615Sriastradh  */
2867337615Sriastradh 
2967337615Sriastradh #include <sys/cdefs.h>
30*6bc5d83fSriastradh __KERNEL_RCSID(0, "$NetBSD: linux_acpi.c,v 1.2 2022/02/28 17:15:30 riastradh Exp $");
31*6bc5d83fSriastradh 
32*6bc5d83fSriastradh #include <dev/acpi/acpireg.h>
3367337615Sriastradh 
3467337615Sriastradh #include <linux/acpi.h>
3567337615Sriastradh 
36*6bc5d83fSriastradh #define	_COMPONENT	ACPI_BUS_COMPONENT
37*6bc5d83fSriastradh ACPI_MODULE_NAME("linux_acpi")
38*6bc5d83fSriastradh 
3967337615Sriastradh union acpi_object *
acpi_evaluate_dsm(acpi_handle handle,const guid_t * uuid,u64 rev,u64 func,union acpi_object * argv4)4067337615Sriastradh acpi_evaluate_dsm(acpi_handle handle, const guid_t *uuid, u64 rev, u64 func,
4167337615Sriastradh     union acpi_object *argv4)
4267337615Sriastradh {
4367337615Sriastradh 	ACPI_OBJECT_LIST arg;
4467337615Sriastradh 	ACPI_OBJECT params[4];
4567337615Sriastradh 	ACPI_BUFFER buf;
4667337615Sriastradh 	ACPI_STATUS rv;
4767337615Sriastradh 
4867337615Sriastradh 	if (handle == NULL)
4967337615Sriastradh 		handle = ACPI_ROOT_OBJECT;
5067337615Sriastradh 
5167337615Sriastradh 	arg.Count = 4;
5267337615Sriastradh 	arg.Pointer = params;
5367337615Sriastradh 	params[0].Type = ACPI_TYPE_BUFFER;
5467337615Sriastradh 	params[0].Buffer.Length = 16;
5567337615Sriastradh 	params[0].Buffer.Pointer = (char *)__UNCONST(uuid);
5667337615Sriastradh 	params[1].Type = ACPI_TYPE_INTEGER;
5767337615Sriastradh 	params[1].Integer.Value = rev;
5867337615Sriastradh 	params[2].Type = ACPI_TYPE_INTEGER;
5967337615Sriastradh 	params[2].Integer.Value = func;
6067337615Sriastradh 	if (argv4 != NULL) {
6167337615Sriastradh 		params[3] = *argv4;
6267337615Sriastradh 	} else {
6367337615Sriastradh 		params[3].Type = ACPI_TYPE_PACKAGE;
6467337615Sriastradh 		params[3].Package.Count = 0;
6567337615Sriastradh 		params[3].Package.Elements = NULL;
6667337615Sriastradh 	}
6767337615Sriastradh 
6867337615Sriastradh 	buf.Pointer = NULL;
6967337615Sriastradh 	buf.Length = ACPI_ALLOCATE_LOCAL_BUFFER;
7067337615Sriastradh 
7167337615Sriastradh 	rv = AcpiEvaluateObject(handle, "_DSM", &arg, &buf);
7267337615Sriastradh 	if (ACPI_SUCCESS(rv))
7367337615Sriastradh 		return (ACPI_OBJECT *)buf.Pointer;
7467337615Sriastradh 	return NULL;
7567337615Sriastradh }
7667337615Sriastradh 
7767337615Sriastradh 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)7867337615Sriastradh acpi_evaluate_dsm_typed(acpi_handle handle, const guid_t *uuid, u64 rev,
7967337615Sriastradh     u64 func, union acpi_object *argv4, acpi_object_type type)
8067337615Sriastradh {
8167337615Sriastradh 	union acpi_object *obj;
8267337615Sriastradh 
8367337615Sriastradh 	obj = acpi_evaluate_dsm(handle, uuid, rev, func, argv4);
8467337615Sriastradh 	if (obj != NULL && obj->Type != type) {
8567337615Sriastradh 		ACPI_FREE(obj);
8667337615Sriastradh 		obj = NULL;
8767337615Sriastradh 	}
8867337615Sriastradh 	return obj;
8967337615Sriastradh }
9067337615Sriastradh 
9167337615Sriastradh #define	ACPI_INIT_DSM_ARGV4(cnt, eles)		\
9267337615Sriastradh {						\
9367337615Sriastradh 	.Package.Type = ACPI_TYPE_PACKAGE,	\
9467337615Sriastradh 	.Package.Count = (cnt),			\
9567337615Sriastradh 	.Package.Elements = (eles)		\
9667337615Sriastradh }
9767337615Sriastradh 
9867337615Sriastradh bool
acpi_check_dsm(acpi_handle handle,const guid_t * uuid,u64 rev,u64 funcs)9967337615Sriastradh acpi_check_dsm(acpi_handle handle, const guid_t *uuid, u64 rev, u64 funcs)
10067337615Sriastradh {
10167337615Sriastradh 	ACPI_OBJECT *obj;
10267337615Sriastradh 	uint64_t mask = 0;
10367337615Sriastradh 	int i;
10467337615Sriastradh 
10567337615Sriastradh 	if (funcs == 0)
10667337615Sriastradh 		return false;
10767337615Sriastradh 
10867337615Sriastradh 	obj = acpi_evaluate_dsm(handle, uuid, rev, 0, NULL);
10967337615Sriastradh 	if (obj == NULL)
11067337615Sriastradh 		return false;
11167337615Sriastradh 
11267337615Sriastradh 	if (obj->Type == ACPI_TYPE_INTEGER)
11367337615Sriastradh 		mask = obj->Integer.Value;
11467337615Sriastradh 	else if (obj->Type == ACPI_TYPE_BUFFER)
11567337615Sriastradh 		for (i = 0; i < obj->Buffer.Length && i < 8; i++)
11667337615Sriastradh 			mask |= (uint64_t)obj->Buffer.Pointer[i] << (i * 8);
11767337615Sriastradh 	ACPI_FREE(obj);
11867337615Sriastradh 
11967337615Sriastradh 	if ((mask & 0x1) == 0x1 && (mask & funcs) == funcs)
12067337615Sriastradh 		return true;
12167337615Sriastradh 	return false;
12267337615Sriastradh }
123