162306a36Sopenharmony_ci// SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
262306a36Sopenharmony_ci/******************************************************************************
362306a36Sopenharmony_ci *
462306a36Sopenharmony_ci * Module Name: exserial - field_unit support for serial address spaces
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * Copyright (C) 2000 - 2023, Intel Corp.
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci *****************************************************************************/
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#include <acpi/acpi.h>
1162306a36Sopenharmony_ci#include "accommon.h"
1262306a36Sopenharmony_ci#include "acdispat.h"
1362306a36Sopenharmony_ci#include "acinterp.h"
1462306a36Sopenharmony_ci#include "amlcode.h"
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci#define _COMPONENT          ACPI_EXECUTER
1762306a36Sopenharmony_ciACPI_MODULE_NAME("exserial")
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci/*******************************************************************************
2062306a36Sopenharmony_ci *
2162306a36Sopenharmony_ci * FUNCTION:    acpi_ex_read_gpio
2262306a36Sopenharmony_ci *
2362306a36Sopenharmony_ci * PARAMETERS:  obj_desc            - The named field to read
2462306a36Sopenharmony_ci *              buffer              - Where the return data is returned
2562306a36Sopenharmony_ci *
2662306a36Sopenharmony_ci * RETURN:      Status
2762306a36Sopenharmony_ci *
2862306a36Sopenharmony_ci * DESCRIPTION: Read from a named field that references a Generic Serial Bus
2962306a36Sopenharmony_ci *              field
3062306a36Sopenharmony_ci *
3162306a36Sopenharmony_ci ******************************************************************************/
3262306a36Sopenharmony_ciacpi_status acpi_ex_read_gpio(union acpi_operand_object *obj_desc, void *buffer)
3362306a36Sopenharmony_ci{
3462306a36Sopenharmony_ci	acpi_status status;
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci	ACPI_FUNCTION_TRACE_PTR(ex_read_gpio, obj_desc);
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci	/*
3962306a36Sopenharmony_ci	 * For GPIO (general_purpose_io), the Address will be the bit offset
4062306a36Sopenharmony_ci	 * from the previous Connection() operator, making it effectively a
4162306a36Sopenharmony_ci	 * pin number index. The bit_length is the length of the field, which
4262306a36Sopenharmony_ci	 * is thus the number of pins.
4362306a36Sopenharmony_ci	 */
4462306a36Sopenharmony_ci	ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
4562306a36Sopenharmony_ci			  "GPIO FieldRead [FROM]:  Pin %u Bits %u\n",
4662306a36Sopenharmony_ci			  obj_desc->field.pin_number_index,
4762306a36Sopenharmony_ci			  obj_desc->field.bit_length));
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci	/* Lock entire transaction if requested */
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci	acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags);
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci	/* Perform the read */
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_ci	status = acpi_ex_access_region(obj_desc, 0, (u64 *)buffer, ACPI_READ);
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci	acpi_ex_release_global_lock(obj_desc->common_field.field_flags);
5862306a36Sopenharmony_ci	return_ACPI_STATUS(status);
5962306a36Sopenharmony_ci}
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci/*******************************************************************************
6262306a36Sopenharmony_ci *
6362306a36Sopenharmony_ci * FUNCTION:    acpi_ex_write_gpio
6462306a36Sopenharmony_ci *
6562306a36Sopenharmony_ci * PARAMETERS:  source_desc         - Contains data to write. Expect to be
6662306a36Sopenharmony_ci *                                    an Integer object.
6762306a36Sopenharmony_ci *              obj_desc            - The named field
6862306a36Sopenharmony_ci *              result_desc         - Where the return value is returned, if any
6962306a36Sopenharmony_ci *
7062306a36Sopenharmony_ci * RETURN:      Status
7162306a36Sopenharmony_ci *
7262306a36Sopenharmony_ci * DESCRIPTION: Write to a named field that references a General Purpose I/O
7362306a36Sopenharmony_ci *              field.
7462306a36Sopenharmony_ci *
7562306a36Sopenharmony_ci ******************************************************************************/
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_ciacpi_status
7862306a36Sopenharmony_ciacpi_ex_write_gpio(union acpi_operand_object *source_desc,
7962306a36Sopenharmony_ci		   union acpi_operand_object *obj_desc,
8062306a36Sopenharmony_ci		   union acpi_operand_object **return_buffer)
8162306a36Sopenharmony_ci{
8262306a36Sopenharmony_ci	acpi_status status;
8362306a36Sopenharmony_ci	void *buffer;
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci	ACPI_FUNCTION_TRACE_PTR(ex_write_gpio, obj_desc);
8662306a36Sopenharmony_ci
8762306a36Sopenharmony_ci	/*
8862306a36Sopenharmony_ci	 * For GPIO (general_purpose_io), we will bypass the entire field
8962306a36Sopenharmony_ci	 * mechanism and handoff the bit address and bit width directly to
9062306a36Sopenharmony_ci	 * the handler. The Address will be the bit offset
9162306a36Sopenharmony_ci	 * from the previous Connection() operator, making it effectively a
9262306a36Sopenharmony_ci	 * pin number index. The bit_length is the length of the field, which
9362306a36Sopenharmony_ci	 * is thus the number of pins.
9462306a36Sopenharmony_ci	 */
9562306a36Sopenharmony_ci	if (source_desc->common.type != ACPI_TYPE_INTEGER) {
9662306a36Sopenharmony_ci		return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
9762306a36Sopenharmony_ci	}
9862306a36Sopenharmony_ci
9962306a36Sopenharmony_ci	ACPI_DEBUG_PRINT((ACPI_DB_BFIELD,
10062306a36Sopenharmony_ci			  "GPIO FieldWrite [FROM]: (%s:%X), Value %.8X  [TO]: Pin %u Bits %u\n",
10162306a36Sopenharmony_ci			  acpi_ut_get_type_name(source_desc->common.type),
10262306a36Sopenharmony_ci			  source_desc->common.type,
10362306a36Sopenharmony_ci			  (u32)source_desc->integer.value,
10462306a36Sopenharmony_ci			  obj_desc->field.pin_number_index,
10562306a36Sopenharmony_ci			  obj_desc->field.bit_length));
10662306a36Sopenharmony_ci
10762306a36Sopenharmony_ci	buffer = &source_desc->integer.value;
10862306a36Sopenharmony_ci
10962306a36Sopenharmony_ci	/* Lock entire transaction if requested */
11062306a36Sopenharmony_ci
11162306a36Sopenharmony_ci	acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags);
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci	/* Perform the write */
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci	status = acpi_ex_access_region(obj_desc, 0, (u64 *)buffer, ACPI_WRITE);
11662306a36Sopenharmony_ci	acpi_ex_release_global_lock(obj_desc->common_field.field_flags);
11762306a36Sopenharmony_ci	return_ACPI_STATUS(status);
11862306a36Sopenharmony_ci}
11962306a36Sopenharmony_ci
12062306a36Sopenharmony_ci/*******************************************************************************
12162306a36Sopenharmony_ci *
12262306a36Sopenharmony_ci * FUNCTION:    acpi_ex_read_serial_bus
12362306a36Sopenharmony_ci *
12462306a36Sopenharmony_ci * PARAMETERS:  obj_desc            - The named field to read
12562306a36Sopenharmony_ci *              return_buffer       - Where the return value is returned, if any
12662306a36Sopenharmony_ci *
12762306a36Sopenharmony_ci * RETURN:      Status
12862306a36Sopenharmony_ci *
12962306a36Sopenharmony_ci * DESCRIPTION: Read from a named field that references a serial bus
13062306a36Sopenharmony_ci *              (SMBus, IPMI, or GSBus).
13162306a36Sopenharmony_ci *
13262306a36Sopenharmony_ci ******************************************************************************/
13362306a36Sopenharmony_ci
13462306a36Sopenharmony_ciacpi_status
13562306a36Sopenharmony_ciacpi_ex_read_serial_bus(union acpi_operand_object *obj_desc,
13662306a36Sopenharmony_ci			union acpi_operand_object **return_buffer)
13762306a36Sopenharmony_ci{
13862306a36Sopenharmony_ci	acpi_status status;
13962306a36Sopenharmony_ci	u32 buffer_length;
14062306a36Sopenharmony_ci	union acpi_operand_object *buffer_desc;
14162306a36Sopenharmony_ci	u32 function;
14262306a36Sopenharmony_ci	u16 accessor_type;
14362306a36Sopenharmony_ci
14462306a36Sopenharmony_ci	ACPI_FUNCTION_TRACE_PTR(ex_read_serial_bus, obj_desc);
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_ci	/*
14762306a36Sopenharmony_ci	 * This is an SMBus, GSBus or IPMI read. We must create a buffer to
14862306a36Sopenharmony_ci	 * hold the data and then directly access the region handler.
14962306a36Sopenharmony_ci	 *
15062306a36Sopenharmony_ci	 * Note: SMBus and GSBus protocol value is passed in upper 16-bits
15162306a36Sopenharmony_ci	 * of Function
15262306a36Sopenharmony_ci	 *
15362306a36Sopenharmony_ci	 * Common buffer format:
15462306a36Sopenharmony_ci	 *     Status;    (Byte 0 of the data buffer)
15562306a36Sopenharmony_ci	 *     Length;    (Byte 1 of the data buffer)
15662306a36Sopenharmony_ci	 *     Data[x-1]: (Bytes 2-x of the arbitrary length data buffer)
15762306a36Sopenharmony_ci	 */
15862306a36Sopenharmony_ci	switch (obj_desc->field.region_obj->region.space_id) {
15962306a36Sopenharmony_ci	case ACPI_ADR_SPACE_SMBUS:
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci		buffer_length = ACPI_SMBUS_BUFFER_SIZE;
16262306a36Sopenharmony_ci		function = ACPI_READ | (obj_desc->field.attribute << 16);
16362306a36Sopenharmony_ci		break;
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_ci	case ACPI_ADR_SPACE_IPMI:
16662306a36Sopenharmony_ci
16762306a36Sopenharmony_ci		buffer_length = ACPI_IPMI_BUFFER_SIZE;
16862306a36Sopenharmony_ci		function = ACPI_READ;
16962306a36Sopenharmony_ci		break;
17062306a36Sopenharmony_ci
17162306a36Sopenharmony_ci	case ACPI_ADR_SPACE_GSBUS:
17262306a36Sopenharmony_ci
17362306a36Sopenharmony_ci		accessor_type = obj_desc->field.attribute;
17462306a36Sopenharmony_ci		if (accessor_type == AML_FIELD_ATTRIB_RAW_PROCESS_BYTES) {
17562306a36Sopenharmony_ci			ACPI_ERROR((AE_INFO,
17662306a36Sopenharmony_ci				    "Invalid direct read using bidirectional write-then-read protocol"));
17762306a36Sopenharmony_ci
17862306a36Sopenharmony_ci			return_ACPI_STATUS(AE_AML_PROTOCOL);
17962306a36Sopenharmony_ci		}
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ci		status =
18262306a36Sopenharmony_ci		    acpi_ex_get_protocol_buffer_length(accessor_type,
18362306a36Sopenharmony_ci						       &buffer_length);
18462306a36Sopenharmony_ci		if (ACPI_FAILURE(status)) {
18562306a36Sopenharmony_ci			ACPI_ERROR((AE_INFO,
18662306a36Sopenharmony_ci				    "Invalid protocol ID for GSBus: 0x%4.4X",
18762306a36Sopenharmony_ci				    accessor_type));
18862306a36Sopenharmony_ci
18962306a36Sopenharmony_ci			return_ACPI_STATUS(status);
19062306a36Sopenharmony_ci		}
19162306a36Sopenharmony_ci
19262306a36Sopenharmony_ci		/* Add header length to get the full size of the buffer */
19362306a36Sopenharmony_ci
19462306a36Sopenharmony_ci		buffer_length += ACPI_SERIAL_HEADER_SIZE;
19562306a36Sopenharmony_ci		function = ACPI_READ | (accessor_type << 16);
19662306a36Sopenharmony_ci		break;
19762306a36Sopenharmony_ci
19862306a36Sopenharmony_ci	case ACPI_ADR_SPACE_PLATFORM_RT:
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_ci		buffer_length = ACPI_PRM_INPUT_BUFFER_SIZE;
20162306a36Sopenharmony_ci		function = ACPI_READ;
20262306a36Sopenharmony_ci		break;
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci	default:
20562306a36Sopenharmony_ci		return_ACPI_STATUS(AE_AML_INVALID_SPACE_ID);
20662306a36Sopenharmony_ci	}
20762306a36Sopenharmony_ci
20862306a36Sopenharmony_ci	/* Create the local transfer buffer that is returned to the caller */
20962306a36Sopenharmony_ci
21062306a36Sopenharmony_ci	buffer_desc = acpi_ut_create_buffer_object(buffer_length);
21162306a36Sopenharmony_ci	if (!buffer_desc) {
21262306a36Sopenharmony_ci		return_ACPI_STATUS(AE_NO_MEMORY);
21362306a36Sopenharmony_ci	}
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_ci	/* Lock entire transaction if requested */
21662306a36Sopenharmony_ci
21762306a36Sopenharmony_ci	acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags);
21862306a36Sopenharmony_ci
21962306a36Sopenharmony_ci	/* Call the region handler for the write-then-read */
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_ci	status = acpi_ex_access_region(obj_desc, 0,
22262306a36Sopenharmony_ci				       ACPI_CAST_PTR(u64,
22362306a36Sopenharmony_ci						     buffer_desc->buffer.
22462306a36Sopenharmony_ci						     pointer), function);
22562306a36Sopenharmony_ci	acpi_ex_release_global_lock(obj_desc->common_field.field_flags);
22662306a36Sopenharmony_ci
22762306a36Sopenharmony_ci	*return_buffer = buffer_desc;
22862306a36Sopenharmony_ci	return_ACPI_STATUS(status);
22962306a36Sopenharmony_ci}
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_ci/*******************************************************************************
23262306a36Sopenharmony_ci *
23362306a36Sopenharmony_ci * FUNCTION:    acpi_ex_write_serial_bus
23462306a36Sopenharmony_ci *
23562306a36Sopenharmony_ci * PARAMETERS:  source_desc         - Contains data to write
23662306a36Sopenharmony_ci *              obj_desc            - The named field
23762306a36Sopenharmony_ci *              return_buffer       - Where the return value is returned, if any
23862306a36Sopenharmony_ci *
23962306a36Sopenharmony_ci * RETURN:      Status
24062306a36Sopenharmony_ci *
24162306a36Sopenharmony_ci * DESCRIPTION: Write to a named field that references a serial bus
24262306a36Sopenharmony_ci *              (SMBus, IPMI, GSBus).
24362306a36Sopenharmony_ci *
24462306a36Sopenharmony_ci ******************************************************************************/
24562306a36Sopenharmony_ci
24662306a36Sopenharmony_ciacpi_status
24762306a36Sopenharmony_ciacpi_ex_write_serial_bus(union acpi_operand_object *source_desc,
24862306a36Sopenharmony_ci			 union acpi_operand_object *obj_desc,
24962306a36Sopenharmony_ci			 union acpi_operand_object **return_buffer)
25062306a36Sopenharmony_ci{
25162306a36Sopenharmony_ci	acpi_status status;
25262306a36Sopenharmony_ci	u32 buffer_length;
25362306a36Sopenharmony_ci	u32 data_length;
25462306a36Sopenharmony_ci	void *buffer;
25562306a36Sopenharmony_ci	union acpi_operand_object *buffer_desc;
25662306a36Sopenharmony_ci	u32 function;
25762306a36Sopenharmony_ci	u16 accessor_type;
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_ci	ACPI_FUNCTION_TRACE_PTR(ex_write_serial_bus, obj_desc);
26062306a36Sopenharmony_ci
26162306a36Sopenharmony_ci	/*
26262306a36Sopenharmony_ci	 * This is an SMBus, GSBus or IPMI write. We will bypass the entire
26362306a36Sopenharmony_ci	 * field mechanism and handoff the buffer directly to the handler.
26462306a36Sopenharmony_ci	 * For these address spaces, the buffer is bidirectional; on a
26562306a36Sopenharmony_ci	 * write, return data is returned in the same buffer.
26662306a36Sopenharmony_ci	 *
26762306a36Sopenharmony_ci	 * Source must be a buffer of sufficient size, these are fixed size:
26862306a36Sopenharmony_ci	 * ACPI_SMBUS_BUFFER_SIZE, or ACPI_IPMI_BUFFER_SIZE.
26962306a36Sopenharmony_ci	 *
27062306a36Sopenharmony_ci	 * Note: SMBus and GSBus protocol type is passed in upper 16-bits
27162306a36Sopenharmony_ci	 * of Function
27262306a36Sopenharmony_ci	 *
27362306a36Sopenharmony_ci	 * Common buffer format:
27462306a36Sopenharmony_ci	 *     Status;    (Byte 0 of the data buffer)
27562306a36Sopenharmony_ci	 *     Length;    (Byte 1 of the data buffer)
27662306a36Sopenharmony_ci	 *     Data[x-1]: (Bytes 2-x of the arbitrary length data buffer)
27762306a36Sopenharmony_ci	 */
27862306a36Sopenharmony_ci	if (source_desc->common.type != ACPI_TYPE_BUFFER) {
27962306a36Sopenharmony_ci		ACPI_ERROR((AE_INFO,
28062306a36Sopenharmony_ci			    "SMBus/IPMI/GenericSerialBus write requires "
28162306a36Sopenharmony_ci			    "Buffer, found type %s",
28262306a36Sopenharmony_ci			    acpi_ut_get_object_type_name(source_desc)));
28362306a36Sopenharmony_ci
28462306a36Sopenharmony_ci		return_ACPI_STATUS(AE_AML_OPERAND_TYPE);
28562306a36Sopenharmony_ci	}
28662306a36Sopenharmony_ci
28762306a36Sopenharmony_ci	switch (obj_desc->field.region_obj->region.space_id) {
28862306a36Sopenharmony_ci	case ACPI_ADR_SPACE_SMBUS:
28962306a36Sopenharmony_ci
29062306a36Sopenharmony_ci		buffer_length = ACPI_SMBUS_BUFFER_SIZE;
29162306a36Sopenharmony_ci		function = ACPI_WRITE | (obj_desc->field.attribute << 16);
29262306a36Sopenharmony_ci		break;
29362306a36Sopenharmony_ci
29462306a36Sopenharmony_ci	case ACPI_ADR_SPACE_IPMI:
29562306a36Sopenharmony_ci
29662306a36Sopenharmony_ci		buffer_length = ACPI_IPMI_BUFFER_SIZE;
29762306a36Sopenharmony_ci		function = ACPI_WRITE;
29862306a36Sopenharmony_ci		break;
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_ci	case ACPI_ADR_SPACE_GSBUS:
30162306a36Sopenharmony_ci
30262306a36Sopenharmony_ci		accessor_type = obj_desc->field.attribute;
30362306a36Sopenharmony_ci		status =
30462306a36Sopenharmony_ci		    acpi_ex_get_protocol_buffer_length(accessor_type,
30562306a36Sopenharmony_ci						       &buffer_length);
30662306a36Sopenharmony_ci		if (ACPI_FAILURE(status)) {
30762306a36Sopenharmony_ci			ACPI_ERROR((AE_INFO,
30862306a36Sopenharmony_ci				    "Invalid protocol ID for GSBus: 0x%4.4X",
30962306a36Sopenharmony_ci				    accessor_type));
31062306a36Sopenharmony_ci
31162306a36Sopenharmony_ci			return_ACPI_STATUS(status);
31262306a36Sopenharmony_ci		}
31362306a36Sopenharmony_ci
31462306a36Sopenharmony_ci		/* Add header length to get the full size of the buffer */
31562306a36Sopenharmony_ci
31662306a36Sopenharmony_ci		buffer_length += ACPI_SERIAL_HEADER_SIZE;
31762306a36Sopenharmony_ci		function = ACPI_WRITE | (accessor_type << 16);
31862306a36Sopenharmony_ci		break;
31962306a36Sopenharmony_ci
32062306a36Sopenharmony_ci	case ACPI_ADR_SPACE_PLATFORM_RT:
32162306a36Sopenharmony_ci
32262306a36Sopenharmony_ci		buffer_length = ACPI_PRM_INPUT_BUFFER_SIZE;
32362306a36Sopenharmony_ci		function = ACPI_WRITE;
32462306a36Sopenharmony_ci		break;
32562306a36Sopenharmony_ci
32662306a36Sopenharmony_ci	case ACPI_ADR_SPACE_FIXED_HARDWARE:
32762306a36Sopenharmony_ci
32862306a36Sopenharmony_ci		buffer_length = ACPI_FFH_INPUT_BUFFER_SIZE;
32962306a36Sopenharmony_ci		function = ACPI_WRITE;
33062306a36Sopenharmony_ci		break;
33162306a36Sopenharmony_ci
33262306a36Sopenharmony_ci	default:
33362306a36Sopenharmony_ci		return_ACPI_STATUS(AE_AML_INVALID_SPACE_ID);
33462306a36Sopenharmony_ci	}
33562306a36Sopenharmony_ci
33662306a36Sopenharmony_ci	/* Create the transfer/bidirectional/return buffer */
33762306a36Sopenharmony_ci
33862306a36Sopenharmony_ci	buffer_desc = acpi_ut_create_buffer_object(buffer_length);
33962306a36Sopenharmony_ci	if (!buffer_desc) {
34062306a36Sopenharmony_ci		return_ACPI_STATUS(AE_NO_MEMORY);
34162306a36Sopenharmony_ci	}
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_ci	/* Copy the input buffer data to the transfer buffer */
34462306a36Sopenharmony_ci
34562306a36Sopenharmony_ci	buffer = buffer_desc->buffer.pointer;
34662306a36Sopenharmony_ci	data_length = ACPI_MIN(buffer_length, source_desc->buffer.length);
34762306a36Sopenharmony_ci	memcpy(buffer, source_desc->buffer.pointer, data_length);
34862306a36Sopenharmony_ci
34962306a36Sopenharmony_ci	/* Lock entire transaction if requested */
35062306a36Sopenharmony_ci
35162306a36Sopenharmony_ci	acpi_ex_acquire_global_lock(obj_desc->common_field.field_flags);
35262306a36Sopenharmony_ci
35362306a36Sopenharmony_ci	/*
35462306a36Sopenharmony_ci	 * Perform the write (returns status and perhaps data in the
35562306a36Sopenharmony_ci	 * same buffer)
35662306a36Sopenharmony_ci	 */
35762306a36Sopenharmony_ci	status = acpi_ex_access_region(obj_desc, 0, (u64 *)buffer, function);
35862306a36Sopenharmony_ci	acpi_ex_release_global_lock(obj_desc->common_field.field_flags);
35962306a36Sopenharmony_ci
36062306a36Sopenharmony_ci	*return_buffer = buffer_desc;
36162306a36Sopenharmony_ci	return_ACPI_STATUS(status);
36262306a36Sopenharmony_ci}
363