at master 2.4 kB view raw
1/* SPDX-License-Identifier: GPL-2.0 */ 2/* 3 * Intel Core SoC Power Management Controller Header File 4 * 5 * Copyright (c) 2025, Intel Corporation. 6 * All Rights Reserved. 7 * 8 */ 9#ifndef INTEL_PMC_IPC_H 10#define INTEL_PMC_IPC_H 11#include <linux/acpi.h> 12#include <linux/cleanup.h> 13 14#define IPC_SOC_REGISTER_ACCESS 0xAA 15#define IPC_SOC_SUB_CMD_READ 0x00 16#define IPC_SOC_SUB_CMD_WRITE 0x01 17#define PMC_IPCS_PARAM_COUNT 7 18#define VALID_IPC_RESPONSE 5 19 20struct pmc_ipc_cmd { 21 u32 cmd; 22 u32 sub_cmd; 23 u32 size; 24 u32 wbuf[4]; 25}; 26 27struct pmc_ipc_rbuf { 28 u32 buf[4]; 29}; 30 31/** 32 * intel_pmc_ipc() - PMC IPC Mailbox accessor 33 * @ipc_cmd: Prepared input command to send 34 * @rbuf: Allocated array for returned IPC data 35 * 36 * Return: 0 on success. Non-zero on mailbox error 37 */ 38static inline int intel_pmc_ipc(struct pmc_ipc_cmd *ipc_cmd, struct pmc_ipc_rbuf *rbuf) 39{ 40#ifdef CONFIG_ACPI 41 struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; 42 union acpi_object params[PMC_IPCS_PARAM_COUNT] = { 43 {.type = ACPI_TYPE_INTEGER,}, 44 {.type = ACPI_TYPE_INTEGER,}, 45 {.type = ACPI_TYPE_INTEGER,}, 46 {.type = ACPI_TYPE_INTEGER,}, 47 {.type = ACPI_TYPE_INTEGER,}, 48 {.type = ACPI_TYPE_INTEGER,}, 49 {.type = ACPI_TYPE_INTEGER,}, 50 }; 51 struct acpi_object_list arg_list = { PMC_IPCS_PARAM_COUNT, params }; 52 int status; 53 54 if (!ipc_cmd || !rbuf) 55 return -EINVAL; 56 57 /* 58 * 0: IPC Command 59 * 1: IPC Sub Command 60 * 2: Size 61 * 3-6: Write Buffer for offset 62 */ 63 params[0].integer.value = ipc_cmd->cmd; 64 params[1].integer.value = ipc_cmd->sub_cmd; 65 params[2].integer.value = ipc_cmd->size; 66 params[3].integer.value = ipc_cmd->wbuf[0]; 67 params[4].integer.value = ipc_cmd->wbuf[1]; 68 params[5].integer.value = ipc_cmd->wbuf[2]; 69 params[6].integer.value = ipc_cmd->wbuf[3]; 70 71 status = acpi_evaluate_object(NULL, "\\IPCS", &arg_list, &buffer); 72 if (ACPI_FAILURE(status)) 73 return -ENODEV; 74 75 union acpi_object *obj __free(kfree) = buffer.pointer; 76 77 if (obj && obj->type == ACPI_TYPE_PACKAGE && 78 obj->package.count == VALID_IPC_RESPONSE) { 79 const union acpi_object *objs = obj->package.elements; 80 81 if ((u8)objs[0].integer.value != 0) 82 return -EINVAL; 83 84 rbuf->buf[0] = objs[1].integer.value; 85 rbuf->buf[1] = objs[2].integer.value; 86 rbuf->buf[2] = objs[3].integer.value; 87 rbuf->buf[3] = objs[4].integer.value; 88 } else { 89 return -EINVAL; 90 } 91 92 return 0; 93#else 94 return -ENODEV; 95#endif /* CONFIG_ACPI */ 96} 97 98#endif /* INTEL_PMC_IPC_H */