[PATCH 6/8] ACPI: CPPC: Factor out cpc_read_reg() and cpc_write_reg()

From: Lifeng Zheng

Date: Thu Jul 16 2026 - 22:47:55 EST


cppc_get_reg_val() and cppc_set_reg_val() combine two responsibilities:
looking up the per-CPU cpc_desc and then performing the actual register
read/write (including null/optional checks and PCC handling).

Split out the register I/O logic into cpc_read_reg() and cpc_write_reg()
that accept a struct cpc_register_resource pointer directly. This allows
callers that already hold a register reference -- such as the upcoming
Resource Priority accessors -- to read or write a register without going
through the per-CPU descriptor lookup by index.

Also rename the PCC wrappers from cppc_get/set_reg_val_in_pcc() to
cpc_read/write_in_pcc() to align with the new naming convention.

Signed-off-by: Lifeng Zheng <zhenglifeng1@xxxxxxxxxx>
---
drivers/acpi/cppc_acpi.c | 89 ++++++++++++++++++++++++++--------------
1 file changed, 58 insertions(+), 31 deletions(-)

diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c
index 3f1b61c984d4..0037fca47eea 100644
--- a/drivers/acpi/cppc_acpi.c
+++ b/drivers/acpi/cppc_acpi.c
@@ -1378,7 +1378,7 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val)
return ret_val;
}

-static int cppc_get_reg_val_in_pcc(int cpu, struct cpc_register_resource *reg, u64 *val)
+static int cpc_read_in_pcc(int cpu, struct cpc_register_resource *reg, u64 *val)
{
int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu);
struct cppc_pcc_data *pcc_ss_data = NULL;
@@ -1403,35 +1403,52 @@ static int cppc_get_reg_val_in_pcc(int cpu, struct cpc_register_resource *reg, u
return ret;
}

-static int cppc_get_reg_val(int cpu, enum cppc_regs reg_idx, u64 *val)
+/**
+ * cpc_read_reg - Read value from a register element that may be Integer or Buffer.
+ * @cpu: CPU number.
+ * @reg: Pointer to the CPC register element.
+ * @val: Output value.
+ *
+ * Return: 0 on success, -EOPNOTSUPP if null/unsupported, negative on error.
+ */
+static int cpc_read_reg(int cpu, struct cpc_register_resource *reg, u64 *val)
{
- struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpu);
- struct cpc_register_resource *reg;
-
if (val == NULL)
return -EINVAL;

- if (!cpc_desc) {
- pr_debug("No CPC descriptor for CPU:%d\n", cpu);
- return -ENODEV;
- }
-
- reg = &cpc_desc->cpc_regs[reg_idx];
-
- if ((reg->type == ACPI_TYPE_INTEGER && reg->optional &&
- !reg->cpc_entry.int_value) || (reg->type != ACPI_TYPE_INTEGER &&
- IS_NULL_REG(&reg->cpc_entry.reg))) {
- pr_debug("CPC register is not supported\n");
- return -EOPNOTSUPP;
+ if (reg->type == ACPI_TYPE_INTEGER) {
+ if (reg->optional && !reg->cpc_entry.int_value)
+ goto err_unsupported;
+ } else if (reg->type == ACPI_TYPE_BUFFER) {
+ if (IS_NULL_REG(&reg->cpc_entry.reg))
+ goto err_unsupported;
+ } else {
+ goto err_unsupported;
}

if (CPC_IN_PCC(reg))
- return cppc_get_reg_val_in_pcc(cpu, reg, val);
+ return cpc_read_in_pcc(cpu, reg, val);

return cpc_read(cpu, reg, val);
+
+err_unsupported:
+ pr_debug("CPC register is not supported\n");
+ return -EOPNOTSUPP;
+}
+
+static int cppc_get_reg_val(int cpu, enum cppc_regs reg_idx, u64 *val)
+{
+ struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpu);
+
+ if (!cpc_desc) {
+ pr_debug("No CPC descriptor for CPU:%d\n", cpu);
+ return -ENODEV;
+ }
+
+ return cpc_read_reg(cpu, &cpc_desc->cpc_regs[reg_idx], val);
}

-static int cppc_set_reg_val_in_pcc(int cpu, struct cpc_register_resource *reg, u64 val)
+static int cpc_write_in_pcc(int cpu, struct cpc_register_resource *reg, u64 val)
{
int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu);
struct cppc_pcc_data *pcc_ss_data = NULL;
@@ -1456,18 +1473,16 @@ static int cppc_set_reg_val_in_pcc(int cpu, struct cpc_register_resource *reg, u
return ret;
}

-static int cppc_set_reg_val(int cpu, enum cppc_regs reg_idx, u64 val)
+/**
+ * cpc_write_reg - Write a CPC register.
+ * @cpu: CPU number.
+ * @reg: Pointer to the CPC register resource.
+ * @val: Value to write.
+ *
+ * Return: 0 on success, negative error code otherwise.
+ */
+static int cpc_write_reg(int cpu, struct cpc_register_resource *reg, u64 val)
{
- struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpu);
- struct cpc_register_resource *reg;
-
- if (!cpc_desc) {
- pr_debug("No CPC descriptor for CPU:%d\n", cpu);
- return -ENODEV;
- }
-
- reg = &cpc_desc->cpc_regs[reg_idx];
-
/* if a register is writeable, it must be a buffer and not null */
if ((reg->type != ACPI_TYPE_BUFFER) || IS_NULL_REG(&reg->cpc_entry.reg)) {
pr_debug("CPC register is not supported\n");
@@ -1475,11 +1490,23 @@ static int cppc_set_reg_val(int cpu, enum cppc_regs reg_idx, u64 val)
}

if (CPC_IN_PCC(reg))
- return cppc_set_reg_val_in_pcc(cpu, reg, val);
+ return cpc_write_in_pcc(cpu, reg, val);

return cpc_write(cpu, reg, val);
}

+static int cppc_set_reg_val(int cpu, enum cppc_regs reg_idx, u64 val)
+{
+ struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpu);
+
+ if (!cpc_desc) {
+ pr_debug("No CPC descriptor for CPU:%d\n", cpu);
+ return -ENODEV;
+ }
+
+ return cpc_write_reg(cpu, &cpc_desc->cpc_regs[reg_idx], val);
+}
+
/**
* cppc_get_desired_perf - Get the desired performance register value.
* @cpunum: CPU from which to get desired performance.
--
2.33.0