diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index f370be8715ae..9f572f481241 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -134,7 +134,7 @@ static DEFINE_PER_CPU(struct cpc_desc *, cpc_desc_ptr); * cpc_regs[] with the corresponding index. 0 means mandatory and 1 * means optional. */ -#define REG_OPTIONAL (0x1FC7D0) +#define REG_OPTIONAL (0x7FC7D0) /* * Use the index of the register in per-cpu cpc_regs[] to check if @@ -185,8 +185,13 @@ show_cppc_data(cppc_get_perf_caps, cppc_perf_caps, nominal_freq); show_cppc_data(cppc_get_perf_ctrs, cppc_perf_fb_ctrs, wraparound_time); -/* Check for valid access_width, otherwise, fallback to using bit_width */ -#define GET_BIT_WIDTH(reg) ((reg)->access_width ? (8 << ((reg)->access_width - 1)) : (reg)->bit_width) +/* + * PCC reuses the access_width field as the subspace id, so only decode access + * size for non-PCC registers. Otherwise, use the bit_width. + */ +#define GET_BIT_WIDTH(reg) (((reg)->access_width && \ + (reg)->space_id != ACPI_ADR_SPACE_PLATFORM_COMM) ? \ + (8 << ((reg)->access_width - 1)) : (reg)->bit_width) /* Shift and apply the mask for CPC reads/writes */ #define MASK_VAL_READ(reg, val) (((val) >> (reg)->bit_offset) & \ @@ -751,18 +756,19 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) /* * Disregard _CPC if the number of entries in the return package is not * as expected, but support future revisions being proper supersets of - * the v3 and only causing more entries to be returned by _CPC. + * the v4 and only causing more entries to be returned by _CPC. */ if ((cpc_rev == CPPC_V2_REV && num_ent != CPPC_V2_NUM_ENT) || (cpc_rev == CPPC_V3_REV && num_ent != CPPC_V3_NUM_ENT) || - (cpc_rev > CPPC_V3_REV && num_ent <= CPPC_V3_NUM_ENT)) { + (cpc_rev == CPPC_V4_REV && num_ent != CPPC_V4_NUM_ENT) || + (cpc_rev > CPPC_V4_REV && num_ent <= CPPC_V4_NUM_ENT)) { pr_debug("Unexpected number of _CPC return package entries (%d) for CPU:%d\n", num_ent, pr->id); goto out_free; } - if (cpc_rev > CPPC_V3_REV) { - num_ent = CPPC_V3_NUM_ENT; - cpc_rev = CPPC_V3_REV; + if (cpc_rev > CPPC_V4_REV) { + num_ent = CPPC_V4_NUM_ENT; + cpc_rev = CPPC_V4_REV; } cpc_ptr->num_entries = num_ent; @@ -845,6 +851,16 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) cpc_ptr->cpc_regs[i-2].type = ACPI_TYPE_BUFFER; memcpy(&cpc_ptr->cpc_regs[i-2].cpc_entry.reg, gas_t, sizeof(*gas_t)); + } else if (cpc_obj->type == ACPI_TYPE_PACKAGE && (i - 2) == RESOURCE_PRIORITY) { + /* + * ACPI 6.6, s8.4.6.1.2.7 defines Resource Priority as a + * Package of Resource Priority Register Descriptor sub-packages. + * Parsing the full structure is not yet supported. + * Mark the register as unsupported for now. + */ + pr_debug("CPU:%d Resource Priority not supported\n", pr->id); + cpc_ptr->cpc_regs[i-2].type = ACPI_TYPE_INTEGER; + cpc_ptr->cpc_regs[i-2].cpc_entry.int_value = 0; } else { pr_debug("Invalid entry type (%d) in _CPC for CPU:%d\n", i, pr->id); @@ -1045,7 +1061,6 @@ static int cpc_read(int cpu, struct cpc_register_resource *reg_res, u64 *val) * 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) @@ -1118,7 +1133,6 @@ static int cpc_write(int cpu, struct cpc_register_resource *reg_res, u64 val) * 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) diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c index a0ba64e45e8a..4c06c3ffd0cb 100644 --- a/drivers/acpi/pci_root.c +++ b/drivers/acpi/pci_root.c @@ -755,6 +755,10 @@ static int acpi_pci_root_add(struct acpi_device *device, pci_lock_rescan_remove(); pci_bus_add_devices(root->bus); pci_unlock_rescan_remove(); + + /* Clear _DEP dependencies to allow consumers to enumerate */ + acpi_dev_clear_dependencies(device); + return 1; remove_dmar: diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c index ee5facccbe10..390ab5f1d313 100644 --- a/drivers/acpi/processor_idle.c +++ b/drivers/acpi/processor_idle.c @@ -1355,6 +1355,15 @@ void acpi_processor_register_idle_driver(void) int ret = -ENODEV; int cpu; + /* + * If a cpuidle driver is already registered, there is no need to + * evaluate _CST or attempt to register the ACPI idle driver. + */ + if (cpuidle_get_driver()) { + pr_debug("cpuidle driver %pS already registered.\n", cpuidle_get_driver()); + return; + } + acpi_processor_update_max_cstate(); /* diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index 1463eb3a4f6e..075798d70ff1 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -867,6 +867,7 @@ static const char * const acpi_honor_dep_ids[] = { "RSCV0005", /* RISC-V SBI MPXY MBOX */ "RSCV0006", /* RISC-V RPMI SYSMSI */ "PNP0C0F", /* PCI Link Device */ + "ACPI0016", /* CXL/PCIe host bridge: CXL root (ACPI0017) depends on PCI root attach */ NULL }; diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h index d1f02ceec4f9..8693890a7275 100644 --- a/include/acpi/cppc_acpi.h +++ b/include/acpi/cppc_acpi.h @@ -17,16 +17,18 @@ #include #include -/* CPPCv2 and CPPCv3 support */ +/* CPPCv2, CPPCv3 and CPPCv4 support */ #define CPPC_V2_REV 2 #define CPPC_V3_REV 3 +#define CPPC_V4_REV 4 #define CPPC_V2_NUM_ENT 21 #define CPPC_V3_NUM_ENT 23 +#define CPPC_V4_NUM_ENT 25 #define PCC_CMD_COMPLETE_MASK (1 << 0) #define PCC_ERROR_MASK (1 << 2) -#define MAX_CPC_REG_ENT 21 +#define MAX_CPC_REG_ENT 23 /* CPPC specific PCC commands. */ #define CMD_READ 0 @@ -109,6 +111,8 @@ enum cppc_regs { REFERENCE_PERF, LOWEST_FREQ, NOMINAL_FREQ, + OSPM_NOMINAL_PERF, + RESOURCE_PRIORITY, }; /*