]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
ACPI: CPPC: Optimize cppc_get_perf()
authorLifeng Zheng <zhenglifeng1@huawei.com>
Fri, 11 Apr 2025 09:38:49 +0000 (17:38 +0800)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Wed, 30 Apr 2025 20:01:30 +0000 (22:01 +0200)
Optimize cppc_get_perf() with three changes:

 1. Change the error kind to "no such device" when pcc_ss_id < 0, as
    other register value getting functions.

 2. Add a check to ensure the pointer 'perf' is no null.

 3. Add a check to verify if the register is supported to be read before
    using it. The logic is:

    (1) If the register is of the integer type, check whether the
        register is optional and its value is 0. If yes, the register
        is not supported.

    (2) If the register is of other types, a null one is not supported.

 4. Return the result of cpc_read() instead of 0.

Reviewed-by: Pierre Gondois <pierre.gondois@arm.com>
Signed-off-by: Lifeng Zheng <zhenglifeng1@huawei.com>
Reviewed-by: Mario Limonciello <mario.limonciello@amd.com>
Link: https://patch.msgid.link/20250411093855.982491-3-zhenglifeng1@huawei.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/acpi/cppc_acpi.c

index 34df037556996f70423520047af3f626d07e7237..a0774517642f2ce239c21c2da585188d3caf75d3 100644 (file)
@@ -1184,6 +1184,9 @@ static int cppc_get_perf(int cpunum, enum cppc_regs reg_idx, u64 *perf)
        struct cpc_desc *cpc_desc = per_cpu(cpc_desc_ptr, cpunum);
        struct cpc_register_resource *reg;
 
+       if (perf == NULL)
+               return -EINVAL;
+
        if (!cpc_desc) {
                pr_debug("No CPC descriptor for CPU:%d\n", cpunum);
                return -ENODEV;
@@ -1191,20 +1194,29 @@ static int cppc_get_perf(int cpunum, enum cppc_regs reg_idx, u64 *perf)
 
        reg = &cpc_desc->cpc_regs[reg_idx];
 
+       if ((reg->type == ACPI_TYPE_INTEGER && IS_OPTIONAL_CPC_REG(reg_idx) &&
+            !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 (CPC_IN_PCC(reg)) {
                int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpunum);
                struct cppc_pcc_data *pcc_ss_data = NULL;
-               int ret = 0;
+               int ret;
 
-               if (pcc_ss_id < 0)
-                       return -EIO;
+               if (pcc_ss_id < 0) {
+                       pr_debug("Invalid pcc_ss_id\n");
+                       return -ENODEV;
+               }
 
                pcc_ss_data = pcc_data[pcc_ss_id];
 
                down_write(&pcc_ss_data->pcc_lock);
 
                if (send_pcc_cmd(pcc_ss_id, CMD_READ) >= 0)
-                       cpc_read(cpunum, reg, perf);
+                       ret = cpc_read(cpunum, reg, perf);
                else
                        ret = -EIO;
 
@@ -1213,9 +1225,7 @@ static int cppc_get_perf(int cpunum, enum cppc_regs reg_idx, u64 *perf)
                return ret;
        }
 
-       cpc_read(cpunum, reg, perf);
-
-       return 0;
+       return cpc_read(cpunum, reg, perf);
 }
 
 /**