Merge 6.9-rc7 into char-misc-testing
[linux-2.6-block.git] / drivers / acpi / cppc_acpi.c
index 4bfbe55553f410119378fc3bbf8c73b9d6717a05..a40b6f3946efeb6b46fccd445053a5c48e069254 100644 (file)
@@ -170,8 +170,8 @@ show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, wraparound_time);
 #define GET_BIT_WIDTH(reg) ((reg)->access_width ? (8 << ((reg)->access_width - 1)) : (reg)->bit_width)
 
 /* Shift and apply the mask for CPC reads/writes */
-#define MASK_VAL(reg, val) ((val) >> ((reg)->bit_offset &                      \
-                                       GENMASK(((reg)->bit_width), 0)))
+#define MASK_VAL(reg, val) (((val) >> (reg)->bit_offset) &                     \
+                                       GENMASK(((reg)->bit_width) - 1, 0))
 
 static ssize_t show_feedback_ctrs(struct kobject *kobj,
                struct kobj_attribute *attr, char *buf)
@@ -1002,14 +1002,14 @@ static int cpc_read(int cpu, struct cpc_register_resource *reg_res, u64 *val)
        }
 
        *val = 0;
+       size = GET_BIT_WIDTH(reg);
 
        if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
-               u32 width = GET_BIT_WIDTH(reg);
                u32 val_u32;
                acpi_status status;
 
                status = acpi_os_read_port((acpi_io_address)reg->address,
-                                          &val_u32, width);
+                                          &val_u32, size);
                if (ACPI_FAILURE(status)) {
                        pr_debug("Error: Failed to read SystemIO port %llx\n",
                                 reg->address);
@@ -1018,17 +1018,22 @@ static int cpc_read(int cpu, struct cpc_register_resource *reg_res, u64 *val)
 
                *val = val_u32;
                return 0;
-       } else if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM && pcc_ss_id >= 0)
+       } else if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM && pcc_ss_id >= 0) {
+               /*
+                * For registers in PCC space, the register size is determined
+                * by the bit width field; the access size is used to indicate
+                * the PCC subspace id.
+                */
+               size = reg->bit_width;
                vaddr = GET_PCC_VADDR(reg->address, pcc_ss_id);
+       }
        else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
                vaddr = reg_res->sys_mem_vaddr;
        else if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE)
                return cpc_read_ffh(cpu, reg, val);
        else
                return acpi_os_read_memory((acpi_physical_address)reg->address,
-                               val, reg->bit_width);
-
-       size = GET_BIT_WIDTH(reg);
+                               val, size);
 
        switch (size) {
        case 8:
@@ -1044,8 +1049,13 @@ static int cpc_read(int cpu, struct cpc_register_resource *reg_res, u64 *val)
                *val = readq_relaxed(vaddr);
                break;
        default:
-               pr_debug("Error: Cannot read %u bit width from PCC for ss: %d\n",
-                        reg->bit_width, pcc_ss_id);
+               if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
+                       pr_debug("Error: Cannot read %u bit width from system memory: 0x%llx\n",
+                               size, reg->address);
+               } else if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) {
+                       pr_debug("Error: Cannot read %u bit width from PCC for ss: %d\n",
+                               size, pcc_ss_id);
+               }
                return -EFAULT;
        }
 
@@ -1063,12 +1073,13 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val)
        int pcc_ss_id = per_cpu(cpu_pcc_subspace_idx, cpu);
        struct cpc_reg *reg = &reg_res->cpc_entry.reg;
 
+       size = GET_BIT_WIDTH(reg);
+
        if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_IO) {
-               u32 width = GET_BIT_WIDTH(reg);
                acpi_status status;
 
                status = acpi_os_write_port((acpi_io_address)reg->address,
-                                           (u32)val, width);
+                                           (u32)val, size);
                if (ACPI_FAILURE(status)) {
                        pr_debug("Error: Failed to write SystemIO port %llx\n",
                                 reg->address);
@@ -1076,17 +1087,22 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val)
                }
 
                return 0;
-       } else if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM && pcc_ss_id >= 0)
+       } else if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM && pcc_ss_id >= 0) {
+               /*
+                * For registers in PCC space, the register size is determined
+                * by the bit width field; the access size is used to indicate
+                * the PCC subspace id.
+                */
+               size = reg->bit_width;
                vaddr = GET_PCC_VADDR(reg->address, pcc_ss_id);
+       }
        else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
                vaddr = reg_res->sys_mem_vaddr;
        else if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE)
                return cpc_write_ffh(cpu, reg, val);
        else
                return acpi_os_write_memory((acpi_physical_address)reg->address,
-                               val, reg->bit_width);
-
-       size = GET_BIT_WIDTH(reg);
+                               val, size);
 
        if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY)
                val = MASK_VAL(reg, val);
@@ -1105,8 +1121,13 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val)
                writeq_relaxed(val, vaddr);
                break;
        default:
-               pr_debug("Error: Cannot write %u bit width to PCC for ss: %d\n",
-                        reg->bit_width, pcc_ss_id);
+               if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) {
+                       pr_debug("Error: Cannot write %u bit width to system memory: 0x%llx\n",
+                               size, reg->address);
+               } else if (reg->space_id == ACPI_ADR_SPACE_PLATFORM_COMM) {
+                       pr_debug("Error: Cannot write %u bit width to PCC for ss: %d\n",
+                               size, pcc_ss_id);
+               }
                ret_val = -EFAULT;
                break;
        }