include/linux/platform_data/x86/intel_pmc_ipc.h

Source file repositories/reference/linux-study-clean/include/linux/platform_data/x86/intel_pmc_ipc.h

File Facts

System
Linux kernel
Corpus path
include/linux/platform_data/x86/intel_pmc_ipc.h
Extension
.h
Size
2418 bytes
Lines
99
Domain
Core OS
Bucket
Core Kernel Interface
Inferred role
Core OS: implementation source
Status
source implementation candidate

Why This File Exists

Core operating-system implementation surface: boot, tasks, memory, VFS, syscall-facing interfaces, synchronization, credentials, and isolation.

Dependency Surface

Detected Declarations

Annotated Snippet

struct pmc_ipc_cmd {
	u32 cmd;
	u32 sub_cmd;
	u32 size;
	u32 wbuf[4];
};

struct pmc_ipc_rbuf {
	u32 buf[4];
};

/**
 * intel_pmc_ipc() - PMC IPC Mailbox accessor
 * @ipc_cmd:  Prepared input command to send
 * @rbuf:     Allocated array for returned IPC data
 *
 * Return: 0 on success. Non-zero on mailbox error
 */
static inline int intel_pmc_ipc(struct pmc_ipc_cmd *ipc_cmd, struct pmc_ipc_rbuf *rbuf)
{
#ifdef CONFIG_ACPI
	struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL };
	union acpi_object params[PMC_IPCS_PARAM_COUNT] = {
		{.type = ACPI_TYPE_INTEGER,},
		{.type = ACPI_TYPE_INTEGER,},
		{.type = ACPI_TYPE_INTEGER,},
		{.type = ACPI_TYPE_INTEGER,},
		{.type = ACPI_TYPE_INTEGER,},
		{.type = ACPI_TYPE_INTEGER,},
		{.type = ACPI_TYPE_INTEGER,},
	};
	struct acpi_object_list arg_list = { PMC_IPCS_PARAM_COUNT, params };
	int status;

	if (!ipc_cmd || !rbuf)
		return -EINVAL;

	/*
	 * 0: IPC Command
	 * 1: IPC Sub Command
	 * 2: Size
	 * 3-6: Write Buffer for offset
	 */
	params[0].integer.value = ipc_cmd->cmd;
	params[1].integer.value = ipc_cmd->sub_cmd;
	params[2].integer.value = ipc_cmd->size;
	params[3].integer.value = ipc_cmd->wbuf[0];
	params[4].integer.value = ipc_cmd->wbuf[1];
	params[5].integer.value = ipc_cmd->wbuf[2];
	params[6].integer.value = ipc_cmd->wbuf[3];

	status = acpi_evaluate_object(NULL, "\\IPCS", &arg_list, &buffer);
	if (ACPI_FAILURE(status))
		return -ENODEV;

	union acpi_object *obj __free(kfree) = buffer.pointer;

	if (obj && obj->type == ACPI_TYPE_PACKAGE &&
	    obj->package.count == VALID_IPC_RESPONSE) {
		const union acpi_object *objs = obj->package.elements;

		if ((u8)objs[0].integer.value != 0)
			return -EINVAL;

		rbuf->buf[0] = objs[1].integer.value;
		rbuf->buf[1] = objs[2].integer.value;
		rbuf->buf[2] = objs[3].integer.value;
		rbuf->buf[3] = objs[4].integer.value;
	} else {
		return -EINVAL;
	}

	return 0;
#else
	return -ENODEV;
#endif /* CONFIG_ACPI */
}

#endif /* INTEL_PMC_IPC_H */

Annotation

Implementation Notes