From nobody Sat Jul 25 06:11:30 2026 Received: from canpmsgout02.his.huawei.com (canpmsgout02.his.huawei.com [113.46.200.217]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8ECE619E992; Fri, 17 Jul 2026 02:46:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.217 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784256420; cv=none; b=cYEpX5tlODUCoOK2LcBWUXlWwYKi1MoIYm29M98w+51r6fCIIkkRgnq9Si+w36OXgsI+pQrS+5JcX7uWlxNNKkmdZZCTnDmlq0z+diAsNrILeMaHYeb2WlcMRTQEJzAjFlTfuc4jm0+PnYi+9DGrZerhtYrhqK/tZ2uwyb+/l7Y= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784256420; c=relaxed/simple; bh=d1hTAeGLKYZJ1VeMNgcpy42nXEMYfzFIvAGGJNmdp08=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=VEytjbhYF+l+lK4tZxQML6GS2bb6VHeoruGZS+lcKLR7XHR1wBQSyJKQFkCOkotwi2FOBBmVvfvyjKunitMQ1lVCShM6g3VSQlF/Uu+6IphGxcTG1LOkxH0XhiUuFJOktntEHZhK1KT7jFdgSXs+x8eHgxHQWYwaPox/bC29HI8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b=MOJ1UX40; arc=none smtp.client-ip=113.46.200.217 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b="MOJ1UX40" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=fjApW9cD3YHn24BaFclPyPFjS5WhEYtBx2272uoKIvU=; b=MOJ1UX40vzbzNpO4eeKMlvuswwype1vP+ArMFH/bhaEHqI8OeS2QgA/p4PyNTLTEjVW41CAAy iNfcPVsDb1z+3XjfoDjZ6mxmvhggaU73U8Mk2Pup4BEzlvh7zVaW2KwLn3VxLR5H3NFSIshUmJZ suNXzXklcVTo05tOh9HMAb0= Received: from mail.maildlp.com (unknown [172.19.162.223]) by canpmsgout02.his.huawei.com (SkyGuard) with ESMTPS id 4h1YwZ1XJyzcZy9; Fri, 17 Jul 2026 10:37:34 +0800 (CST) Received: from kwepemf100001.china.huawei.com (unknown [7.202.181.215]) by mail.maildlp.com (Postfix) with ESMTPS id 4F31540577; Fri, 17 Jul 2026 10:46:53 +0800 (CST) Received: from localhost.localdomain (10.50.163.32) by kwepemf100001.china.huawei.com (7.202.181.215) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.36; Fri, 17 Jul 2026 10:46:52 +0800 From: Lifeng Zheng To: , , , , , , CC: , , , , , , , , , , Subject: [PATCH 1/8] ACPI: CPPC: Prepare cpc_register_resource for Package-type entries Date: Fri, 17 Jul 2026 10:44:55 +0800 Message-ID: <20260717024502.3520445-2-zhenglifeng1@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20260717024502.3520445-1-zhenglifeng1@huawei.com> References: <20260717024502.3520445-1-zhenglifeng1@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: kwepems100002.china.huawei.com (7.221.188.206) To kwepemf100001.china.huawei.com (7.202.181.215) Content-Type: text/plain; charset="utf-8" CPPC v4 (ACPI 6.6, Section 8.4.6.1.2.7) introduces the Resource Priority entry, which is a Package of sub-packages rather than a plain Integer or Buffer register. The existing cpc_register_resource union only accommodates Integer and Buffer (register descriptor) fields. Add a Package variant to the cpc_entry union so that nested structures such as RESOURCE_PRIORITY can store their element count and a dynamically allocated array of child cpc_register_resource descriptors. Update the CPC_SUPPORTED() macro to recognise Package-type entries with a non-zero element count, and switch the unsupported-Package fallback from a zero Integer to an empty Package (count =3D 0, elements =3D NULL) so that CPC_SUPPORTED() correctly reports such entries as unsupported. No functional change intended; the new Package fields are not yet consumed by any caller. Signed-off-by: Lifeng Zheng --- drivers/acpi/cppc_acpi.c | 19 +++++++++++++------ include/acpi/cppc_acpi.h | 8 ++++++++ 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index 9f572f481241..d7e654f2a66c 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -124,10 +124,16 @@ static DEFINE_PER_CPU(struct cpc_desc *, cpc_desc_ptr= ); (reg)->bit_offset =3D=3D 0 && \ (reg)->access_width =3D=3D 0) =20 -/* Evaluates to True if an optional cpc field is supported */ -#define CPC_SUPPORTED(cpc) ((cpc)->type =3D=3D ACPI_TYPE_INTEGER ? \ - !!(cpc)->cpc_entry.int_value : \ - !IS_NULL_REG(&(cpc)->cpc_entry.reg)) +/* + * Evaluates to True if an optional cpc field is supported. + * Integer: non-zero value; Buffer: non-NULL register; Package: non-empty. + */ +#define CPC_SUPPORTED(cpc) (((cpc)->type =3D=3D ACPI_TYPE_INTEGER && \ + !!(cpc)->cpc_entry.int_value) || \ + ((cpc)->type =3D=3D ACPI_TYPE_BUFFER && \ + !IS_NULL_REG(&(cpc)->cpc_entry.reg)) || \ + ((cpc)->type =3D=3D ACPI_TYPE_PACKAGE && \ + (cpc)->cpc_entry.package.count !=3D 0)) =20 /* * Each bit indicates the optionality of the register in per-cpu @@ -859,8 +865,9 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) * 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 =3D ACPI_TYPE_INTEGER; - cpc_ptr->cpc_regs[i-2].cpc_entry.int_value =3D 0; + cpc_ptr->cpc_regs[i-2].type =3D ACPI_TYPE_PACKAGE; + cpc_ptr->cpc_regs[i-2].cpc_entry.package.count =3D 0; + cpc_ptr->cpc_regs[i-2].cpc_entry.package.elements =3D NULL; } else { pr_debug("Invalid entry type (%d) in _CPC for CPU:%d\n", i, pr->id); diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h index 8693890a7275..1839582b80be 100644 --- a/include/acpi/cppc_acpi.h +++ b/include/acpi/cppc_acpi.h @@ -71,6 +71,14 @@ struct cpc_register_resource { union { struct cpc_reg reg; u64 int_value; + /* + * CPPC v4: nested Package (e.g. RESOURCE_PRIORITY), + * elements dynamically allocated + */ + struct { + u32 count; + struct cpc_register_resource *elements; + } package; } cpc_entry; }; =20 --=20 2.33.0 From nobody Sat Jul 25 06:11:30 2026 Received: from canpmsgout08.his.huawei.com (canpmsgout08.his.huawei.com [113.46.200.223]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 374F121CA02; Fri, 17 Jul 2026 02:46:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.223 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784256420; cv=none; b=tbKZ99I97ZoZkPzjriPEMCqKaE7oGJdDTW7U6iIETG1cgyMqvTc3SnKo4RO8OP2/GkDBNEz/Vk1cWcSItQGXppWzyetP3u/PJ52HmvMn43uK2paFe0oshEtJYTAS3hHP4L7H+H2+xzc8fi0aygSUbjpFGtv1RLZ/RKfmmND2IpI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784256420; c=relaxed/simple; bh=olF9a4EONmT3wmMzi5gFMPTNyXmxoXS05pYXBZQSqho=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=m2+llFz+m1BMRZNaQS9+l5lCbnG/RabPuY2j89UfLn/HfajV8nGq4UCA+ogwgItuKIsqbvzGvO0mJ3YWFiqrEHsKk62+Skvst/zvvsDxxkiK9TPUBzAESH7Q+O1nUPrWTRenRPxpv2hZMHlwfOetxPlkTE4ssqiRnnAaQ3upyqY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b=CwXWakcl; arc=none smtp.client-ip=113.46.200.223 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b="CwXWakcl" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=vbibo70FmBhbGnWi1JjnPXlxEwMTIDDJ5Czhw0vvY2I=; b=CwXWakclhi9fKsD98CA4L+c0sSnw6m7IPsP/F45zwZOV4EPxGF+KiKJ1LFrIWJzrwiX6zARfp IrPBwv28Jv2U5vtKT2NQLhTxdclYtrVRAmufh1rKEVUTn8A/en1RzQYn8hr8dYgphcCqD5+0NnF DaT5OH4RzSVr9nHXmW/wKgg= Received: from mail.maildlp.com (unknown [172.19.163.127]) by canpmsgout08.his.huawei.com (SkyGuard) with ESMTPS id 4h1YwZ1YLgzmVXM; Fri, 17 Jul 2026 10:37:34 +0800 (CST) Received: from kwepemf100001.china.huawei.com (unknown [7.202.181.215]) by mail.maildlp.com (Postfix) with ESMTPS id C73E4402AB; Fri, 17 Jul 2026 10:46:53 +0800 (CST) Received: from localhost.localdomain (10.50.163.32) by kwepemf100001.china.huawei.com (7.202.181.215) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.36; Fri, 17 Jul 2026 10:46:53 +0800 From: Lifeng Zheng To: , , , , , , CC: , , , , , , , , , , Subject: [PATCH 2/8] ACPI: CPPC: Refactor element parsing into parse_cpc_element() Date: Fri, 17 Jul 2026 10:44:56 +0800 Message-ID: <20260717024502.3520445-3-zhenglifeng1@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20260717024502.3520445-1-zhenglifeng1@huawei.com> References: <20260717024502.3520445-1-zhenglifeng1@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: kwepems100002.china.huawei.com (7.221.188.206) To kwepemf100001.china.huawei.com (7.202.181.215) Content-Type: text/plain; charset="utf-8" acpi_cppc_processor_probe() contains a large inline block (~70 lines) that handles ACPI_TYPE_INTEGER and ACPI_TYPE_BUFFER entries in the _CPC package. This block will need to be reused for parsing individual elements inside the nested RESOURCE_PRIORITY sub-packages that CPPC v4 defines (Section 8.4.6.1.2.7). Extract the Integer / Buffer handling into a standalone parse_cpc_element() helper so that both the top-level _CPC loop and the upcoming package parser can share the same logic for register validation, PCC subspace tracking, SystemMemory ioremap, and SystemIO / FFH checks. No functional change; the new function reproduces the original behaviour exactly. Signed-off-by: Lifeng Zheng --- drivers/acpi/cppc_acpi.c | 186 +++++++++++++++++++++++---------------- 1 file changed, 108 insertions(+), 78 deletions(-) diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index d7e654f2a66c..ac4d4d002d40 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -656,6 +656,109 @@ static int pcc_data_alloc(int pcc_ss_id) return 0; } =20 +/** + * parse_cpc_element - Parse a single CPC element into a cpc_register_reso= urce. + * @cpc_obj: Pointer to the ACPI object representing the CPC elem= ent. + * @cpc_reg: Output CPC register resource to populate. + * @pcc_subspace_id: In/out pointer to PCC subspace ID; extracted once on= first + * PCC-type register and validated for consistency ther= eafter. + * @cpu: CPU number, used for debug messages. + * @entry_num: Index within the CPC table entries, used for diagnos= tics. + * + * Handles ACPI_TYPE_INTEGER (static value) and ACPI_TYPE_BUFFER (register + * descriptor). Sets up PCC subspace tracking, ioremap for SystemMemory, + * and validates SystemIO / FFH register parameters. + * + * Return: 0 on success, -ENODATA on invalid or unsupported data. + */ +static int parse_cpc_element(union acpi_object *cpc_obj, + struct cpc_register_resource *cpc_reg, + int *pcc_subspace_id, u32 cpu, unsigned int entry_num) +{ + struct cpc_reg *gas_t; + + if (cpc_obj->type =3D=3D ACPI_TYPE_INTEGER) { + cpc_reg->type =3D ACPI_TYPE_INTEGER; + cpc_reg->cpc_entry.int_value =3D cpc_obj->integer.value; + } else if (cpc_obj->type =3D=3D ACPI_TYPE_BUFFER) { + gas_t =3D (struct cpc_reg *)cpc_obj->buffer.pointer; + + /* + * The PCC Subspace index is encoded inside + * the CPC table entries. The same PCC index + * will be used for all the PCC entries, + * so extract it only once. + */ + if (gas_t->space_id =3D=3D ACPI_ADR_SPACE_PLATFORM_COMM) { + if (*pcc_subspace_id < 0) { + *pcc_subspace_id =3D gas_t->access_width; + if (pcc_data_alloc(*pcc_subspace_id)) + return -ENODATA; + } else if (*pcc_subspace_id !=3D gas_t->access_width) { + pr_debug("Mismatched PCC ids in _CPC for CPU:%d\n", + cpu); + return -ENODATA; + } + } else if (gas_t->space_id =3D=3D ACPI_ADR_SPACE_SYSTEM_MEMORY) { + if (gas_t->address) { + void __iomem *addr; + size_t access_width; + + if (!osc_cpc_flexible_adr_space_confirmed) { + pr_debug("Flexible address space capability not supported\n"); + if (!cpc_supported_by_cpu()) + return -ENODATA; + } + + access_width =3D GET_BIT_WIDTH(gas_t) / 8; + addr =3D ioremap(gas_t->address, access_width); + if (!addr) + return -ENODATA; + cpc_reg->sys_mem_vaddr =3D addr; + } + } else if (gas_t->space_id =3D=3D ACPI_ADR_SPACE_SYSTEM_IO) { + if (gas_t->access_width < 1 || gas_t->access_width > 3) { + /* + * 1 =3D 8-bit, 2 =3D 16-bit, and 3 =3D 32-bit. + * SystemIO doesn't implement 64-bit + * registers. + */ + pr_debug("Invalid access width %d for SystemIO register in _CPC\n", + gas_t->access_width); + return -ENODATA; + } + if (gas_t->address & OVER_16BTS_MASK) { + /* SystemIO registers use 16-bit integer addresses */ + pr_debug("Invalid IO port %llu for SystemIO register in _CPC\n", + gas_t->address); + return -ENODATA; + } + if (!osc_cpc_flexible_adr_space_confirmed) { + pr_debug("Flexible address space capability not supported\n"); + if (!cpc_supported_by_cpu()) + return -ENODATA; + } + } else { + if (gas_t->space_id !=3D ACPI_ADR_SPACE_FIXED_HARDWARE || + !cpc_ffh_supported()) { + /* Support only PCC, SystemMemory, SystemIO, and FFH type regs. */ + pr_debug("Unsupported register type (%d) in _CPC\n", + gas_t->space_id); + return -ENODATA; + } + } + + cpc_reg->type =3D ACPI_TYPE_BUFFER; + memcpy(&cpc_reg->cpc_entry.reg, gas_t, sizeof(*gas_t)); + } else { + pr_debug("Invalid entry type (%d) in _CPC for CPU:%d\n", + entry_num, cpu); + return -ENODATA; + } + + return 0; +} + /* * An example CPC table looks like the following. * @@ -696,7 +799,6 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) struct acpi_buffer output =3D {ACPI_ALLOCATE_BUFFER, NULL}; union acpi_object *out_obj, *cpc_obj; struct cpc_desc *cpc_ptr; - struct cpc_reg *gas_t; struct device *cpu_dev; acpi_handle handle =3D pr->handle; unsigned int num_ent, i, cpc_rev; @@ -784,80 +886,7 @@ int acpi_cppc_processor_probe(struct acpi_processor *p= r) for (i =3D 2; i < num_ent; i++) { cpc_obj =3D &out_obj->package.elements[i]; =20 - if (cpc_obj->type =3D=3D ACPI_TYPE_INTEGER) { - cpc_ptr->cpc_regs[i-2].type =3D ACPI_TYPE_INTEGER; - cpc_ptr->cpc_regs[i-2].cpc_entry.int_value =3D cpc_obj->integer.value; - } else if (cpc_obj->type =3D=3D ACPI_TYPE_BUFFER) { - gas_t =3D (struct cpc_reg *) - cpc_obj->buffer.pointer; - - /* - * The PCC Subspace index is encoded inside - * the CPC table entries. The same PCC index - * will be used for all the PCC entries, - * so extract it only once. - */ - if (gas_t->space_id =3D=3D ACPI_ADR_SPACE_PLATFORM_COMM) { - if (pcc_subspace_id < 0) { - pcc_subspace_id =3D gas_t->access_width; - if (pcc_data_alloc(pcc_subspace_id)) - goto out_free; - } else if (pcc_subspace_id !=3D gas_t->access_width) { - pr_debug("Mismatched PCC ids in _CPC for CPU:%d\n", - pr->id); - goto out_free; - } - } else if (gas_t->space_id =3D=3D ACPI_ADR_SPACE_SYSTEM_MEMORY) { - if (gas_t->address) { - void __iomem *addr; - size_t access_width; - - if (!osc_cpc_flexible_adr_space_confirmed) { - pr_debug("Flexible address space capability not supported\n"); - if (!cpc_supported_by_cpu()) - goto out_free; - } - - access_width =3D GET_BIT_WIDTH(gas_t) / 8; - addr =3D ioremap(gas_t->address, access_width); - if (!addr) - goto out_free; - cpc_ptr->cpc_regs[i-2].sys_mem_vaddr =3D addr; - } - } else if (gas_t->space_id =3D=3D ACPI_ADR_SPACE_SYSTEM_IO) { - if (gas_t->access_width < 1 || gas_t->access_width > 3) { - /* - * 1 =3D 8-bit, 2 =3D 16-bit, and 3 =3D 32-bit. - * SystemIO doesn't implement 64-bit - * registers. - */ - pr_debug("Invalid access width %d for SystemIO register in _CPC\n", - gas_t->access_width); - goto out_free; - } - if (gas_t->address & OVER_16BTS_MASK) { - /* SystemIO registers use 16-bit integer addresses */ - pr_debug("Invalid IO port %llu for SystemIO register in _CPC\n", - gas_t->address); - goto out_free; - } - if (!osc_cpc_flexible_adr_space_confirmed) { - pr_debug("Flexible address space capability not supported\n"); - if (!cpc_supported_by_cpu()) - goto out_free; - } - } else { - if (gas_t->space_id !=3D ACPI_ADR_SPACE_FIXED_HARDWARE || !cpc_ffh_sup= ported()) { - /* Support only PCC, SystemMemory, SystemIO, and FFH type regs. */ - pr_debug("Unsupported register type (%d) in _CPC\n", - gas_t->space_id); - goto out_free; - } - } - - cpc_ptr->cpc_regs[i-2].type =3D ACPI_TYPE_BUFFER; - memcpy(&cpc_ptr->cpc_regs[i-2].cpc_entry.reg, gas_t, sizeof(*gas_t)); - } else if (cpc_obj->type =3D=3D ACPI_TYPE_PACKAGE && (i - 2) =3D=3D RESO= URCE_PRIORITY) { + if (cpc_obj->type =3D=3D ACPI_TYPE_PACKAGE) { /* * ACPI 6.6, s8.4.6.1.2.7 defines Resource Priority as a * Package of Resource Priority Register Descriptor sub-packages. @@ -869,9 +898,10 @@ int acpi_cppc_processor_probe(struct acpi_processor *p= r) cpc_ptr->cpc_regs[i-2].cpc_entry.package.count =3D 0; cpc_ptr->cpc_regs[i-2].cpc_entry.package.elements =3D NULL; } else { - pr_debug("Invalid entry type (%d) in _CPC for CPU:%d\n", - i, pr->id); - goto out_free; + ret =3D parse_cpc_element(cpc_obj, &cpc_ptr->cpc_regs[i-2], + &pcc_subspace_id, pr->id, i); + if (ret) + goto out_free; } } per_cpu(cpu_pcc_subspace_idx, pr->id) =3D pcc_subspace_id; --=20 2.33.0 From nobody Sat Jul 25 06:11:30 2026 Received: from canpmsgout03.his.huawei.com (canpmsgout03.his.huawei.com [113.46.200.218]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 797E722A80D; Fri, 17 Jul 2026 02:46:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.218 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784256420; cv=none; b=Tfb1Fvo28+7+v5QVMepHoT6+4b2Wu4G9AQIcsN0/bHLDYDFYbO+3hos8teJLzuCjfWrm6a+jMX64eBHnVP8AmHA5McS/vu95A3Kqv9dF4oaQ5UreYa7ATpQ3BcAYaevlFYZKU9bbLq5gj8lEWN9IYQyUThZKe+/GzuF0l0oXvac= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784256420; c=relaxed/simple; bh=uFzWyoEP0LY8WqMpLfSonKkCk/Yi7nl5d/qURvVgh6M=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=IDh/KE/LV87L3ms8524BviTBbq3f6E//GFr+dmgbtRSscUK3srf1zOtIr04GOUsSigwykYZRzcxszuA8xJwSxrfYuWyKoGBalL1ox33VighuyJ/CNHdEGPa77elVFyqAe//Wi33xZtmbkS72oqRwfX3ZaZfWi6vlm8haiu5haYU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b=Sa7QzRkz; arc=none smtp.client-ip=113.46.200.218 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b="Sa7QzRkz" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=58zYSO7RrOaHioCSn5ndyn/HuJQ2XrwleS0HIZkFe6w=; b=Sa7QzRkzOqN37i9aptDSGN1Q4gybA6UfL9+rrfQAcDWoTTs+Qb9smOwtPKi6BZI33Jgvcv2uY GKneNXwkSnSdBB0gTyV+FTwIVf/0MeI0sSL5wceD3NbGZeXRClgFAsBT1q71LwzJ/4OStLOFCJh NG1ONK7fbpv243KcB8L5d7U= Received: from mail.maildlp.com (unknown [172.19.162.140]) by canpmsgout03.his.huawei.com (SkyGuard) with ESMTPS id 4h1Yx23zzhzpStj; Fri, 17 Jul 2026 10:37:58 +0800 (CST) Received: from kwepemf100001.china.huawei.com (unknown [7.202.181.215]) by mail.maildlp.com (Postfix) with ESMTPS id 2F5142012A; Fri, 17 Jul 2026 10:46:54 +0800 (CST) Received: from localhost.localdomain (10.50.163.32) by kwepemf100001.china.huawei.com (7.202.181.215) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.36; Fri, 17 Jul 2026 10:46:53 +0800 From: Lifeng Zheng To: , , , , , , CC: , , , , , , , , , , Subject: [PATCH 3/8] ACPI: CPPC: Refactor resource cleanup into free_reg_resource() Date: Fri, 17 Jul 2026 10:44:57 +0800 Message-ID: <20260717024502.3520445-4-zhenglifeng1@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20260717024502.3520445-1-zhenglifeng1@huawei.com> References: <20260717024502.3520445-1-zhenglifeng1@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: kwepems100002.china.huawei.com (7.221.188.206) To kwepemf100001.china.huawei.com (7.202.181.215) Content-Type: text/plain; charset="utf-8" Both the error path of acpi_cppc_processor_probe() and the normal cleanup in acpi_cppc_processor_exit() iterate over the cpc_regs[] array and iounmap() any SystemMemory virtual addresses that were set up during probe. CPPC v4 adds Package-type entries that own dynamically allocated sub-elements which also need to be freed. Inlining this recursive cleanup at every call-site would be error-prone and repetitive. Extract the per-register cleanup logic into free_reg_resource(), which releases any iomapped address and, for Package-type entries, recursively frees all child elements and the elements array itself. Convert both the probe error path and _exit() to use the new helper. No functional change for existing Integer / Buffer entries. Signed-off-by: Lifeng Zheng --- drivers/acpi/cppc_acpi.c | 41 ++++++++++++++++++++++++++++------------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index ac4d4d002d40..bad959f46f90 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -759,6 +759,30 @@ static int parse_cpc_element(union acpi_object *cpc_ob= j, return 0; } =20 +/** + * free_reg_resource - Free resources held by a CPC register resource. + * @cpc_reg: Pointer to the CPC register resource to clean up. + * + * Releases any iomapped SystemMemory address and, for Package-type + * resources, recursively frees all nested elements before freeing the + * elements array itself. + */ +static void free_reg_resource(struct cpc_register_resource *cpc_reg) +{ + void __iomem *addr =3D cpc_reg->sys_mem_vaddr; + int i; + + if (addr) + iounmap(addr); + + if (cpc_reg->type =3D=3D ACPI_TYPE_PACKAGE) { + for (i =3D 0; i < cpc_reg->cpc_entry.package.count; i++) + free_reg_resource(&cpc_reg->cpc_entry.package.elements[i]); + + kfree(cpc_reg->cpc_entry.package.elements); + } +} + /* * An example CPC table looks like the following. * @@ -972,12 +996,9 @@ int acpi_cppc_processor_probe(struct acpi_processor *p= r) =20 out_free: /* Free all the mapped sys mem areas for this CPU */ - for (i =3D 2; i < cpc_ptr->num_entries; i++) { - void __iomem *addr =3D cpc_ptr->cpc_regs[i-2].sys_mem_vaddr; + for (i =3D 2; i < cpc_ptr->num_entries; i++) + free_reg_resource(&cpc_ptr->cpc_regs[i-2]); =20 - if (addr) - iounmap(addr); - } kfree(cpc_ptr); =20 out_buf_free: @@ -996,7 +1017,6 @@ void acpi_cppc_processor_exit(struct acpi_processor *p= r) { struct cpc_desc *cpc_ptr; unsigned int i; - void __iomem *addr; int pcc_ss_id =3D per_cpu(cpu_pcc_subspace_idx, pr->id); =20 if (pcc_ss_id >=3D 0 && pcc_data[pcc_ss_id]) { @@ -1014,12 +1034,9 @@ void acpi_cppc_processor_exit(struct acpi_processor = *pr) if (!cpc_ptr) return; =20 - /* Free all the mapped sys mem areas for this CPU */ - for (i =3D 2; i < cpc_ptr->num_entries; i++) { - addr =3D cpc_ptr->cpc_regs[i-2].sys_mem_vaddr; - if (addr) - iounmap(addr); - } + /* Free all the mapped sys mem areas and nested package resources for thi= s CPU */ + for (i =3D 2; i < cpc_ptr->num_entries; i++) + free_reg_resource(&cpc_ptr->cpc_regs[i-2]); =20 kobject_put(&cpc_ptr->kobj); kfree(cpc_ptr); --=20 2.33.0 From nobody Sat Jul 25 06:11:30 2026 Received: from canpmsgout03.his.huawei.com (canpmsgout03.his.huawei.com [113.46.200.218]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A17BF2F6904; Fri, 17 Jul 2026 02:46:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.218 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784256419; cv=none; b=Yhc2uh7v1CQG7iJATxhHy9HrRGip8HJzq0MXodgenQTNQanyp7ys81W5GFMc6nGy781mN3fKzzeho3AUwpHQz/cu4JcxWJe9ohIck9ONwRCwNkeX8MDrUVBJHu3snP6S8zZAGsUPwFpRz2Qk/vmFZv1vwDA0TC/G0w8JsurSScM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784256419; c=relaxed/simple; bh=Rei6F/hkoOIzoTd3qUEbc5eiOdSSAglxANLtiAgKYWM=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=eo7bM/IekbnNXyszIB3DYkBWPzLJE5zXj3OW1c4KBfRFI19Y9J9u1hLAsDCxsxCb7ae/yOjw/rGGNK/L0U8ewjz/aHKSd4SekfqyoIz/MNWsX2uIKfI0L0SEvxewp1m3mJaNIUY7bZVF1uPN4e5F8JF438STEokfxUkpXFEEcac= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b=JUCOnNfz; arc=none smtp.client-ip=113.46.200.218 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b="JUCOnNfz" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=V5ZuUxdsgeD6UhUHtccbb56NeGfSX/d7pY4rRojKRgU=; b=JUCOnNfzT6z0xwWb6SR9zv1SJDWFjZyGxwuOq1FS0HCDUG3JJv+QirbstRxbhvKZOo7RyHWJz hTge/dzy/zvVEec1cfg+wf0It6HcTDlFC/Os2sagp/DSw3YkgIqXvBiJSM8peBOGl7UgTUOFLRd 62bGPJtztalGUKkyiX90v8Q= Received: from mail.maildlp.com (unknown [172.19.162.197]) by canpmsgout03.his.huawei.com (SkyGuard) with ESMTPS id 4h1Yx30WhRzpStj; Fri, 17 Jul 2026 10:37:59 +0800 (CST) Received: from kwepemf100001.china.huawei.com (unknown [7.202.181.215]) by mail.maildlp.com (Postfix) with ESMTPS id A9D2840579; Fri, 17 Jul 2026 10:46:54 +0800 (CST) Received: from localhost.localdomain (10.50.163.32) by kwepemf100001.china.huawei.com (7.202.181.215) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.36; Fri, 17 Jul 2026 10:46:54 +0800 From: Lifeng Zheng To: , , , , , , CC: , , , , , , , , , , Subject: [PATCH 4/8] ACPI: CPPC: Parse Resource Priority Register entries from _CPC package Date: Fri, 17 Jul 2026 10:44:58 +0800 Message-ID: <20260717024502.3520445-5-zhenglifeng1@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20260717024502.3520445-1-zhenglifeng1@huawei.com> References: <20260717024502.3520445-1-zhenglifeng1@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: kwepems100002.china.huawei.com (7.221.188.206) To kwepemf100001.china.huawei.com (7.202.181.215) Content-Type: text/plain; charset="utf-8" CPPC v4 (ACPI 6.6, Section 8.4.6.1.2.7) defines the Resource Priority entry as a Package of sub-packages, each containing: - CONTROLLED_RESOURCES: a Package of integer resource IDs - ENABLE_VALUE / ENABLE_REGISTER: enable/disable control - PRIORITY_COUNT / PRIORITY_REGISTER: priority level setting These allow OSPM to set relative priority among processors for shared resources such as boost, throttle, L2/L3 cache, and memory bandwidth. Implement parse_priority_regs() which: 1. Validates each sub-package has the expected element count (RESOURCE_PRIORITY_NUM). 2. Allocates cpc_register_resource arrays for the sub-package elements and the nested CONTROLLED_RESOURCES list. 3. Parses CONTROLLED_RESOURCES as integers and the remaining entries (ENABLE_REGISTER, PRIORITY_REGISTER, etc.) via parse_cpc_element() so that register descriptors, PCC subspace tracking, and ioremap are handled consistently. 4. Wires the parser into the main _CPC probe loop, replacing the previous "package type not supported" stub with full parsing for RESOURCE_PRIORITY while rejecting unexpected Package entries. The probe and _exit() error/cleanup paths already use free_reg_resource(), which recursively frees Package-type entries, so no additional cleanup changes are needed. Add the resource_priority_regs enumeration that defines the indices into each Resource Priority sub-package (CONTROLLED_RESOURCES, ENABLE_VALUE, ENABLE_REGISTER, PRIORITY_COUNT, PRIORITY_REGISTER) and RESOURCE_PRIORITY_NUM as the element count sentinel. Signed-off-by: Lifeng Zheng --- drivers/acpi/cppc_acpi.c | 133 ++++++++++++++++++++++++++++++++++++--- include/acpi/cppc_acpi.h | 13 ++++ 2 files changed, 139 insertions(+), 7 deletions(-) diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index bad959f46f90..32829bb822dd 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -783,6 +783,91 @@ static void free_reg_resource(struct cpc_register_reso= urce *cpc_reg) } } =20 +/** + * parse_priority_regs - Parse the RESOURCE_PRIORITY nested package struct= ure. + * @cpc_obj: ACPI Package object for the RESOURCE_PRIORITY entry. + * @regs: Output array of cpc_register_resource to fill. + * @pcc_subspace_id: In/out pointer to PCC subspace ID. + * @cpu: CPU number, used for debug messages. + * + * The RESOURCE_PRIORITY entry (CPPC v4) is a Package of sub-packages. + * Each sub-package has RESOURCE_PRIORITY_NUM elements: + * [0] =3D Package of integers (CONTROLLED_RESOURCES list) + * [1] =3D ENABLE_VALUE, [2] =3D ENABLE_REGISTER, + * [3] =3D PRIORITY_COUNT, [4] =3D PRIORITY_REGISTER + * + * Return: 0 on success, -ENODATA on malformed data, -ENOMEM on allocation= failure. + */ +static int parse_priority_regs(union acpi_object *cpc_obj, + struct cpc_register_resource *regs, + int *pcc_subspace_id, u32 cpu) +{ + struct cpc_register_resource *reg_elements; + union acpi_object reg_desc_obj; + unsigned int i, j, resources_count; + int ret; + + for (i =3D 0; i < cpc_obj->package.count; i++) { + reg_desc_obj =3D cpc_obj->package.elements[i]; + if (reg_desc_obj.type !=3D ACPI_TYPE_PACKAGE || + reg_desc_obj.package.count !=3D RESOURCE_PRIORITY_NUM) { + pr_debug("Malformed priority regs sub-pkg: type %d count %d, expected %= d for CPU:%d\n", + reg_desc_obj.type, reg_desc_obj.package.count, + RESOURCE_PRIORITY_NUM, cpu); + return -ENODATA; + } + + reg_elements =3D kzalloc_objs(struct cpc_register_resource, RESOURCE_PRI= ORITY_NUM); + if (!reg_elements) { + pr_debug("Failed to allocate reg_elements for CPU:%d\n", cpu); + return -ENOMEM; + } + + /* + * Assign values immediately after successful allocation to ensure that = resources + * can be properly released. + */ + regs[i].type =3D ACPI_TYPE_PACKAGE; + regs[i].cpc_entry.package.count =3D RESOURCE_PRIORITY_NUM; + regs[i].cpc_entry.package.elements =3D reg_elements; + + resources_count =3D reg_desc_obj.package.elements[0].package.count; + + if (reg_desc_obj.package.elements[0].type !=3D ACPI_TYPE_PACKAGE || + !resources_count) { + pr_debug("Invalid priority sub-elements: type %d count %d for CPU:%d\n", + reg_desc_obj.package.elements[0].type, resources_count, cpu); + return -ENODATA; + } + + reg_elements[0].cpc_entry.package.elements =3D + kzalloc_objs(struct cpc_register_resource, resources_count); + if (!reg_elements[0].cpc_entry.package.elements) { + pr_debug("Failed to allocate %d priority sub-elements for CPU:%d\n", + resources_count, cpu); + return -ENOMEM; + } + + reg_elements[0].type =3D ACPI_TYPE_PACKAGE; + reg_elements[0].cpc_entry.package.count =3D resources_count; + + for (j =3D 0; j < reg_elements[0].cpc_entry.package.count; j++) { + reg_elements[0].cpc_entry.package.elements[j].type =3D ACPI_TYPE_INTEGE= R; + reg_elements[0].cpc_entry.package.elements[j].cpc_entry.int_value =3D + reg_desc_obj.package.elements[0].package.elements[j].integer.value; + } + + for (j =3D 1; j < RESOURCE_PRIORITY_NUM; j++) { + ret =3D parse_cpc_element(®_desc_obj.package.elements[j], ®_eleme= nts[j], + pcc_subspace_id, cpu, RESOURCE_PRIORITY); + if (ret) + return ret; + } + } + + return 0; +} + /* * An example CPC table looks like the following. * @@ -821,6 +906,7 @@ static void free_reg_resource(struct cpc_register_resou= rce *cpc_reg) int acpi_cppc_processor_probe(struct acpi_processor *pr) { struct acpi_buffer output =3D {ACPI_ALLOCATE_BUFFER, NULL}; + struct cpc_register_resource *pkg_elements; union acpi_object *out_obj, *cpc_obj; struct cpc_desc *cpc_ptr; struct device *cpu_dev; @@ -829,6 +915,7 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) int pcc_subspace_id =3D -1; acpi_status status; int ret =3D -ENODATA; + u32 pkg_count; =20 if (!osc_sb_cppc2_support_acked) { pr_debug("CPPC v2 _OSC not acked\n"); @@ -910,17 +997,49 @@ int acpi_cppc_processor_probe(struct acpi_processor *= pr) for (i =3D 2; i < num_ent; i++) { cpc_obj =3D &out_obj->package.elements[i]; =20 + /* + * Package-type entries are used for nested structures such as + * RESOURCE_PRIORITY (CPPC v4). Only RESOURCE_PRIORITY is + * currently supported; any other Package entry is rejected. + */ if (cpc_obj->type =3D=3D ACPI_TYPE_PACKAGE) { - /* - * 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 =3D ACPI_TYPE_PACKAGE; cpc_ptr->cpc_regs[i-2].cpc_entry.package.count =3D 0; cpc_ptr->cpc_regs[i-2].cpc_entry.package.elements =3D NULL; + + pkg_count =3D cpc_obj->package.count; + if (!pkg_count) { + pr_debug("Empty package entry at index %d for CPU:%d\n", + i, pr->id); + continue; + } + + pkg_elements =3D kzalloc_objs(struct cpc_register_resource, pkg_count); + if (!pkg_elements) { + ret =3D -ENOMEM; + goto out_free; + } + + /* + * Assign values immediately after successful allocation to ensure that + * resources can be properly released. + */ + cpc_ptr->cpc_regs[i-2].cpc_entry.package.count =3D pkg_count; + cpc_ptr->cpc_regs[i-2].cpc_entry.package.elements =3D pkg_elements; + + if (i - 2 =3D=3D RESOURCE_PRIORITY) { + ret =3D parse_priority_regs(cpc_obj, pkg_elements, + &pcc_subspace_id, pr->id); + if (ret) + goto out_free; + + pr_debug("Parsed RESOURCE_PRIORITY (%d sub-pkgs) for CPU:%d\n", + pkg_count, pr->id); + } else { + pr_debug("Unexpected ACPI_TYPE_PACKAGE at index %d for CPU:%d\n", + i, pr->id); + goto out_free; + } } else { ret =3D parse_cpc_element(cpc_obj, &cpc_ptr->cpc_regs[i-2], &pcc_subspace_id, pr->id, i); diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h index 1839582b80be..19f8a722654b 100644 --- a/include/acpi/cppc_acpi.h +++ b/include/acpi/cppc_acpi.h @@ -123,6 +123,19 @@ enum cppc_regs { RESOURCE_PRIORITY, }; =20 +/* + * Indices into each sub-package of the RESOURCE_PRIORITY entry. + * RESOURCE_PRIORITY_NUM serves as the element count / loop bound. + */ +enum resource_priority_regs { + CONTROLLED_RESOURCES, /* Package of integer resource IDs */ + ENABLE_VALUE, /* Enable/disable value */ + ENABLE_REGISTER, /* Register for enable/disable control */ + PRIORITY_COUNT, /* Number of priority levels */ + PRIORITY_REGISTER, /* Register for priority setting */ + RESOURCE_PRIORITY_NUM, /* Number of elements (sentinel) */ +}; + /* * Categorization of registers as described * in the ACPI v.5.1 spec. --=20 2.33.0 From nobody Sat Jul 25 06:11:30 2026 Received: from canpmsgout07.his.huawei.com (canpmsgout07.his.huawei.com [113.46.200.222]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CBE7A33FE09; Fri, 17 Jul 2026 02:47:02 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.222 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784256425; cv=none; b=MZXxcQtBxnqqSGtZop7dED2LB6DTNisRXFtWBzEmAx/PPzgpDSjnGOD6srb4L5BRU6hZFZKM5t++tmp+FJ4qPBZqOuDhReIxenBCfh7apk9sHYDTRfohY9+yTd+xZ0m0ytKy+xLMm4iFNk459gVeHHco7p/tedi46FN8iN9jX8o= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784256425; c=relaxed/simple; bh=ShnPJq0w4Lw/TFzFvC1q6W2dEMyyQCs9adQwQJ5ATxI=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=td3/C4+JiKmuDctH/HkeVr5KWfCzDavRhJ08rZUNW+XCtR6nONz8HTPaZEYyn2ql1P9dKLZNXmEtsrrqX/wXsDUOOPZlTeQiYF6NrWxrL6JFOsA9Tw2tAURvglkQmHGWSGhIwZ4Dp6DX8A6WJEc0EvLRAmAY5FqlP1hsxlbbRZI= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b=YRztWVmO; arc=none smtp.client-ip=113.46.200.222 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b="YRztWVmO" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=HprlmLQnZeTXTYVZls+0B6vKsVoZrXEBrxGuF4830oA=; b=YRztWVmOOEYOrR0KylnttINVy3z2m4tPpBlMiaVPqawy3hb9JVvredwCTCA7ThjQ2NTdocgTc syW7YoqIpFwyTKb9t2BYogcOBdr/hvDkiYU2EHYdtSL2i+M6rL0DkFTQaXMUkhLYkrtnpgKqvHK dxx1ShWxGVkaTwjp/k6fvbk= Received: from mail.maildlp.com (unknown [172.19.163.127]) by canpmsgout07.his.huawei.com (SkyGuard) with ESMTPS id 4h1Ywb5GvpzLlY1; Fri, 17 Jul 2026 10:37:35 +0800 (CST) Received: from kwepemf100001.china.huawei.com (unknown [7.202.181.215]) by mail.maildlp.com (Postfix) with ESMTPS id 25B17402AB; Fri, 17 Jul 2026 10:46:55 +0800 (CST) Received: from localhost.localdomain (10.50.163.32) by kwepemf100001.china.huawei.com (7.202.181.215) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.36; Fri, 17 Jul 2026 10:46:54 +0800 From: Lifeng Zheng To: , , , , , , CC: , , , , , , , , , , Subject: [PATCH 5/8] ACPI: CPPC: Store optional flag in cpc_register_resource Date: Fri, 17 Jul 2026 10:44:59 +0800 Message-ID: <20260717024502.3520445-6-zhenglifeng1@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20260717024502.3520445-1-zhenglifeng1@huawei.com> References: <20260717024502.3520445-1-zhenglifeng1@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: kwepems100002.china.huawei.com (7.221.188.206) To kwepemf100001.china.huawei.com (7.202.181.215) Content-Type: text/plain; charset="utf-8" The current optionality check uses a compile-time bitmask (REG_OPTIONAL) applied at call sites via IS_OPTIONAL_CPC_REG(reg_idx). This requires every caller to know the register index, which will not work for registers accessed without a fixed index (e.g. entries inside Resource Priority sub-packages). Add a boolean 'optional' field to cpc_register_resource so that each register element carries its own optionality. Populate the field during _CPC probe (for main registers) and parse_priority_regs() (for Resource Priority sub-packages), using the existing REG_OPTIONAL and RES_PRIO_OPTIONAL bitmasks respectively. Replace the IS_OPTIONAL_CPC_REG() check in cppc_get_reg_val() with a direct test of reg->optional, and remove the IS_OPTIONAL_CPC_REG() macro. Signed-off-by: Lifeng Zheng --- drivers/acpi/cppc_acpi.c | 13 ++++++++----- include/acpi/cppc_acpi.h | 1 + 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index 32829bb822dd..3f1b61c984d4 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -143,11 +143,11 @@ static DEFINE_PER_CPU(struct cpc_desc *, cpc_desc_ptr= ); #define REG_OPTIONAL (0x7FC7D0) =20 /* - * Use the index of the register in per-cpu cpc_regs[] to check if - * it's an optional one. + * Each bit indicates the optionality of the register in resource + * priority register descriptor with the corresponding index. 0 means + * mandatory and 1 means optional. */ -#define IS_OPTIONAL_CPC_REG(reg_idx) (REG_OPTIONAL & (1U << (reg_idx))) - +#define RES_PRIO_OPTIONAL (0x6) /* * Arbitrary Retries in case the remote processor is slow to respond * to PCC commands. Keeping it high enough to cover emulators where @@ -850,6 +850,7 @@ static int parse_priority_regs(union acpi_object *cpc_o= bj, =20 reg_elements[0].type =3D ACPI_TYPE_PACKAGE; reg_elements[0].cpc_entry.package.count =3D resources_count; + reg_elements[0].optional =3D RES_PRIO_OPTIONAL & 1U; =20 for (j =3D 0; j < reg_elements[0].cpc_entry.package.count; j++) { reg_elements[0].cpc_entry.package.elements[j].type =3D ACPI_TYPE_INTEGE= R; @@ -858,6 +859,7 @@ static int parse_priority_regs(union acpi_object *cpc_o= bj, } =20 for (j =3D 1; j < RESOURCE_PRIORITY_NUM; j++) { + reg_elements[j].optional =3D RES_PRIO_OPTIONAL & (1U << j); ret =3D parse_cpc_element(®_desc_obj.package.elements[j], ®_eleme= nts[j], pcc_subspace_id, cpu, RESOURCE_PRIORITY); if (ret) @@ -996,6 +998,7 @@ int acpi_cppc_processor_probe(struct acpi_processor *pr) /* Iterate through remaining entries in _CPC */ for (i =3D 2; i < num_ent; i++) { cpc_obj =3D &out_obj->package.elements[i]; + cpc_ptr->cpc_regs[i-2].optional =3D REG_OPTIONAL & (1U << (i-2)); =20 /* * Package-type entries are used for nested structures such as @@ -1415,7 +1418,7 @@ static int cppc_get_reg_val(int cpu, enum cppc_regs r= eg_idx, u64 *val) =20 reg =3D &cpc_desc->cpc_regs[reg_idx]; =20 - if ((reg->type =3D=3D ACPI_TYPE_INTEGER && IS_OPTIONAL_CPC_REG(reg_idx) && + if ((reg->type =3D=3D ACPI_TYPE_INTEGER && reg->optional && !reg->cpc_entry.int_value) || (reg->type !=3D ACPI_TYPE_INTEGER && IS_NULL_REG(®->cpc_entry.reg))) { pr_debug("CPC register is not supported\n"); diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h index 19f8a722654b..c0b8d52016cd 100644 --- a/include/acpi/cppc_acpi.h +++ b/include/acpi/cppc_acpi.h @@ -80,6 +80,7 @@ struct cpc_register_resource { struct cpc_register_resource *elements; } package; } cpc_entry; + bool optional; }; =20 /* Container to hold the CPC details for each CPU */ --=20 2.33.0 From nobody Sat Jul 25 06:11:30 2026 Received: from canpmsgout05.his.huawei.com (canpmsgout05.his.huawei.com [113.46.200.220]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CA0E52FDC53; Fri, 17 Jul 2026 02:46:57 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.220 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784256421; cv=none; b=t5aYQJt2SuCYjHcZtKjtb9NqmZe27R6TAhrKWdRC57x/c0pusPV9JSX+2DbtrxmKjk3JYF3K1BE/eEuAHz6ycnM7pUFrZluRRYnXj3Hc52Wz59k1rzsewywc8YwIExC3b3fh9gdzE2vDrX/774n8RRycWGKwVvREoapCZY2mF/g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784256421; c=relaxed/simple; bh=aj2/1FoBAbPQ5UNkEYCQD0HUBE7zR3L/cqMz8pIQrmw=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=KE0In6vduPVvAHqtF/mTrgAJaOgiRyK3vIkSPMxsDbvVtkaDskov3yTM6p0MfCbKlLEU5L8qXwYOogY8/a3jYNYpTIh1PiP7dpwghDYHoAc6DH7xgmm2bPC5BZKeoRPjB4Al2OjQoUPV4GK07qggdeFTuLezTQO05B3+XmxFFgw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b=emLOYlTI; arc=none smtp.client-ip=113.46.200.220 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b="emLOYlTI" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=m3qOPmBnKIpyYgkwdWQ0ZW/IYIyKdTGwEkjgt1jSqPA=; b=emLOYlTIKz9BppCM6jXFkpWIjoRJEdLhtydojpD+vOW7pL9hjJP9/msimP732nmGi5OXqoAKk nXoXVhXRBQcgK21nHYuCR64urbO4fUkD/Yi2O0RmLTjDjwIKVAA/DAOyGsJpQQGMlWAFAmuwSET 2a93wi43+s1+GZAmudwatio= Received: from mail.maildlp.com (unknown [172.19.162.140]) by canpmsgout05.his.huawei.com (SkyGuard) with ESMTPS id 4h1YwG5Lbhz12LDF; Fri, 17 Jul 2026 10:37:18 +0800 (CST) Received: from kwepemf100001.china.huawei.com (unknown [7.202.181.215]) by mail.maildlp.com (Postfix) with ESMTPS id 8DC482012A; Fri, 17 Jul 2026 10:46:55 +0800 (CST) Received: from localhost.localdomain (10.50.163.32) by kwepemf100001.china.huawei.com (7.202.181.215) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.36; Fri, 17 Jul 2026 10:46:54 +0800 From: Lifeng Zheng To: , , , , , , CC: , , , , , , , , , , Subject: [PATCH 6/8] ACPI: CPPC: Factor out cpc_read_reg() and cpc_write_reg() Date: Fri, 17 Jul 2026 10:45:00 +0800 Message-ID: <20260717024502.3520445-7-zhenglifeng1@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20260717024502.3520445-1-zhenglifeng1@huawei.com> References: <20260717024502.3520445-1-zhenglifeng1@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: kwepems100002.china.huawei.com (7.221.188.206) To kwepemf100001.china.huawei.com (7.202.181.215) Content-Type: text/plain; charset="utf-8" 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 --- 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_res= ource *reg_res, u64 val) return ret_val; } =20 -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 =3D per_cpu(cpu_pcc_subspace_idx, cpu); struct cppc_pcc_data *pcc_ss_data =3D NULL; @@ -1403,35 +1403,52 @@ static int cppc_get_reg_val_in_pcc(int cpu, struct = cpc_register_resource *reg, u return ret; } =20 -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 o= r Buffer. + * @cpu: CPU number. + * @reg: Pointer to the CPC register element. + * @val: Output value. + * + * Return: 0 on success, -EOPNOTSUPP if null/unsupported, negative on erro= r. + */ +static int cpc_read_reg(int cpu, struct cpc_register_resource *reg, u64 *v= al) { - struct cpc_desc *cpc_desc =3D per_cpu(cpc_desc_ptr, cpu); - struct cpc_register_resource *reg; - if (val =3D=3D NULL) return -EINVAL; =20 - if (!cpc_desc) { - pr_debug("No CPC descriptor for CPU:%d\n", cpu); - return -ENODEV; - } - - reg =3D &cpc_desc->cpc_regs[reg_idx]; - - if ((reg->type =3D=3D ACPI_TYPE_INTEGER && reg->optional && - !reg->cpc_entry.int_value) || (reg->type !=3D ACPI_TYPE_INTEGER && - IS_NULL_REG(®->cpc_entry.reg))) { - pr_debug("CPC register is not supported\n"); - return -EOPNOTSUPP; + if (reg->type =3D=3D ACPI_TYPE_INTEGER) { + if (reg->optional && !reg->cpc_entry.int_value) + goto err_unsupported; + } else if (reg->type =3D=3D ACPI_TYPE_BUFFER) { + if (IS_NULL_REG(®->cpc_entry.reg)) + goto err_unsupported; + } else { + goto err_unsupported; } =20 if (CPC_IN_PCC(reg)) - return cppc_get_reg_val_in_pcc(cpu, reg, val); + return cpc_read_in_pcc(cpu, reg, val); =20 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 =3D 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); } =20 -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, u6= 4 val) { int pcc_ss_id =3D per_cpu(cpu_pcc_subspace_idx, cpu); struct cppc_pcc_data *pcc_ss_data =3D NULL; @@ -1456,18 +1473,16 @@ static int cppc_set_reg_val_in_pcc(int cpu, struct = cpc_register_resource *reg, u return ret; } =20 -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 v= al) { - struct cpc_desc *cpc_desc =3D 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 =3D &cpc_desc->cpc_regs[reg_idx]; - /* if a register is writeable, it must be a buffer and not null */ if ((reg->type !=3D ACPI_TYPE_BUFFER) || IS_NULL_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) } =20 if (CPC_IN_PCC(reg)) - return cppc_set_reg_val_in_pcc(cpu, reg, val); + return cpc_write_in_pcc(cpu, reg, val); =20 return cpc_write(cpu, reg, val); } =20 +static int cppc_set_reg_val(int cpu, enum cppc_regs reg_idx, u64 val) +{ + struct cpc_desc *cpc_desc =3D 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. --=20 2.33.0 From nobody Sat Jul 25 06:11:30 2026 Received: from canpmsgout08.his.huawei.com (canpmsgout08.his.huawei.com [113.46.200.223]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id EC4543368AC; Fri, 17 Jul 2026 02:46:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.223 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784256421; cv=none; b=ThGQMlAy62WHUfCYXyP3M6z0xbEal/o6VmL7JEO6thcP2CwXG++n43+z1cZqZeNmPenEGCzSmlrZFNB9j4VndT4u04GUm1+7cfAVYf2I46xfQ7bvpeM14ZNlD48Q5rfSaOSr/W9A+/Yz4KbQ3z0Fm38ZW0OaOJgpXQtRdEl71ls= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784256421; c=relaxed/simple; bh=QLjM8FnRXihnazvZTTLO52EcH+JhFQmjjXlIuaavDWQ=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=YkKEGS+yDWT42HbZ4yLdJt/dpKXNbKk//F+eWvCKqvMpewlJtgWbN4VrfN7d6SFHVaFGZYulWhPYSLNx4d5tLlj/cRMsEX0qR/MShv28jTh8DsKmAMbe9xUicQlozpisw/mazaPdhu40Ph18XFgHof8IDcJqspKAq6mRYJDlY3Y= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b=0B+dAauN; arc=none smtp.client-ip=113.46.200.223 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b="0B+dAauN" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=55vgiX8bG+7dxgGMkDi2A44i6/q6XKIq9uwXEsscTkc=; b=0B+dAauNevX7MBxTWEKBBhj8VHaGffs0fsUZFt7Nv+ln8HZpPp0BgaHPpV/i8U3CqPTRlT3nR bb9XVcfvDgvC4VQjXsgt3b/WYJZtJ8i8op78qVG139fvduLJno2ba5vQm1M8396w58bHSjeX9FY EXxzfb6nJDSfTv1xcQBEc0s= Received: from mail.maildlp.com (unknown [172.19.163.15]) by canpmsgout08.his.huawei.com (SkyGuard) with ESMTPS id 4h1Ywc3LTqzmVXM; Fri, 17 Jul 2026 10:37:36 +0800 (CST) Received: from kwepemf100001.china.huawei.com (unknown [7.202.181.215]) by mail.maildlp.com (Postfix) with ESMTPS id 0F63040586; Fri, 17 Jul 2026 10:46:56 +0800 (CST) Received: from localhost.localdomain (10.50.163.32) by kwepemf100001.china.huawei.com (7.202.181.215) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.36; Fri, 17 Jul 2026 10:46:55 +0800 From: Lifeng Zheng To: , , , , , , CC: , , , , , , , , , , Subject: [PATCH 7/8] ACPI: CPPC: Add Resource Priority accessors Date: Fri, 17 Jul 2026 10:45:01 +0800 Message-ID: <20260717024502.3520445-8-zhenglifeng1@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20260717024502.3520445-1-zhenglifeng1@huawei.com> References: <20260717024502.3520445-1-zhenglifeng1@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: kwepems100002.china.huawei.com (7.221.188.206) To kwepemf100001.china.huawei.com (7.202.181.215) Content-Type: text/plain; charset="utf-8" CPPC v4 (ACPI 6.6, Section 8.4.6.1.2.7) defines the Resource Priority mechanism that lets OSPM control relative priority among processors for shared resources such as processor boost, throttle, L2/L3 cache, and memory bandwidth. Add the following exported APIs for user-space and driver consumers: - cppc_get_resource_priority_count() -- number of sub-packages - cppc_get_resource_priority_resources() -- resource type IDs - cppc_get/set_res_priority_enable() -- enable/disable a group - cppc_get_res_priority_count() -- priority levels in a group - cppc_get/set_res_priority() -- read/write the priority value These wrappers navigate the nested Package structure parsed earlier by parse_priority_regs() and delegate register I/O to cpc_read_reg() / cpc_write_reg(). Provide stubs returning -EOPNOTSUPP for the !CONFIG_ACPI_CPPC_LIB case. Signed-off-by: Lifeng Zheng --- drivers/acpi/cppc_acpi.c | 262 +++++++++++++++++++++++++++++++++++++++ include/acpi/cppc_acpi.h | 37 ++++++ 2 files changed, 299 insertions(+) diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index 0037fca47eea..05b34a4eef68 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -2288,6 +2288,268 @@ int cppc_set_perf_limited(int cpu, u64 bits_to_clea= r) } EXPORT_SYMBOL_GPL(cppc_set_perf_limited); =20 +/** + * get_res_prio_subpkg - Get pointer to the elements array of a RESOURCE_P= RIORITY sub-package. + * @cpu: CPU number. + * @index: Sub-package index (0 to count-1). + * + * Return: Pointer to the sub-package's elements array, or NULL on error. + * + * The layout within each sub-package element is: + * elements[CONTROLLED_RESOURCES] =3D [0] + * elements[ENABLE_VALUE] =3D [1] + * elements[ENABLE_REGISTER] =3D [2] + * elements[PRIORITY_COUNT] =3D [3] + * elements[PRIORITY_REGISTER] =3D [4] + */ +static struct cpc_register_resource *get_res_prio_subpkg(int cpu, int inde= x) +{ + struct cpc_desc *cpc_desc =3D per_cpu(cpc_desc_ptr, cpu); + struct cpc_register_resource *rp_pkg; + + if (!cpc_desc) + return NULL; + + rp_pkg =3D &cpc_desc->cpc_regs[RESOURCE_PRIORITY]; + if (rp_pkg->type !=3D ACPI_TYPE_PACKAGE) + return NULL; + + if (index < 0 || index >=3D rp_pkg->cpc_entry.package.count) + return NULL; + + return rp_pkg->cpc_entry.package.elements[index].cpc_entry.package.elemen= ts; +} + +/** + * cppc_get_resource_priority_count - Get number of Resource Priority sub-= packages. + * @cpu: CPU number. + * @count: Output number of resource priority groups. + * + * Return: 0 on success, -EOPNOTSUPP if RESOURCE_PRIORITY not provided by = firmware. + */ +int cppc_get_resource_priority_count(int cpu, int *count) +{ + struct cpc_desc *cpc_desc =3D per_cpu(cpc_desc_ptr, cpu); + struct cpc_register_resource *rp_pkg; + + if (!count) + return -EINVAL; + + if (!cpc_desc) + return -ENODEV; + + rp_pkg =3D &cpc_desc->cpc_regs[RESOURCE_PRIORITY]; + if (rp_pkg->type !=3D ACPI_TYPE_PACKAGE) + return -EOPNOTSUPP; + + *count =3D rp_pkg->cpc_entry.package.count; + if (*count <=3D 0) + return -EOPNOTSUPP; + + return 0; +} +EXPORT_SYMBOL_GPL(cppc_get_resource_priority_count); + +/** + * cppc_get_resource_priority_resources - Read Controlled Resources list f= or a sub-package. + * @cpu: CPU number. + * @index: Sub-package index (0 to count-1). + * @resources: Output array of resource type IDs (caller-allocated). + * @num_resources: Input =3D array capacity, output =3D actual count. + * + * Return: 0 on success, -EOPNOTSUPP, -EINVAL, etc. + */ +int cppc_get_resource_priority_resources(int cpu, int index, + u32 *resources, int *num_resources) +{ + struct cpc_register_resource *elems; + struct cpc_register_resource *cr_pkg; + int i, cr_count; + + if (!resources || !num_resources || *num_resources <=3D 0) + return -EINVAL; + + elems =3D get_res_prio_subpkg(cpu, index); + if (!elems) + return -EOPNOTSUPP; + + cr_pkg =3D &elems[CONTROLLED_RESOURCES]; + if (cr_pkg->type !=3D ACPI_TYPE_PACKAGE) + return -EOPNOTSUPP; + + cr_count =3D cr_pkg->cpc_entry.package.count; + if (cr_count <=3D 0) + return 0; + + *num_resources =3D min(cr_count, *num_resources); + + for (i =3D 0; i < *num_resources; i++) + resources[i] =3D cr_pkg->cpc_entry.package.elements[i].cpc_entry.int_val= ue; + + return 0; +} +EXPORT_SYMBOL_GPL(cppc_get_resource_priority_resources); + +/** + * cppc_get_res_priority_enable - Read enable state of a Resource Priority= register. + * @cpu: CPU number. + * @index: Sub-package index. + * @enable: Output true if enabled, false if disabled. + * + * Compares the current ENABLE_REGISTER value against ENABLE_VALUE. + * If ENABLE_REGISTER is null/unsupported, returns -EOPNOTSUPP. + * + * Return: 0 on success, negative error otherwise. + */ +int cppc_get_res_priority_enable(int cpu, int index, bool *enable) +{ + struct cpc_register_resource *elems; + struct cpc_register_resource *enable_reg; + u64 reg_val, enable_val; + int ret; + + if (!enable) + return -EINVAL; + + elems =3D get_res_prio_subpkg(cpu, index); + if (!elems) + return -EOPNOTSUPP; + + enable_reg =3D &elems[ENABLE_REGISTER]; + if (enable_reg->type !=3D ACPI_TYPE_BUFFER || + IS_NULL_REG(&enable_reg->cpc_entry.reg)) + return -EOPNOTSUPP; + + ret =3D cpc_read_reg(cpu, enable_reg, ®_val); + if (ret) + return ret; + + ret =3D cpc_read_reg(cpu, &elems[ENABLE_VALUE], &enable_val); + if (ret) + return ret; + + *enable =3D (reg_val =3D=3D enable_val); + return 0; +} +EXPORT_SYMBOL_GPL(cppc_get_res_priority_enable); + +/** + * cppc_set_res_priority_enable - Set enable state of a Resource Priority = register. + * @cpu: CPU number. + * @index: Sub-package index. + * @enable: true to enable (write ENABLE_VALUE), false to disable (write 0= ). + * + * Return: 0 on success, negative error otherwise. + */ +int cppc_set_res_priority_enable(int cpu, int index, bool enable) +{ + struct cpc_register_resource *elems; + struct cpc_register_resource *enable_reg; + u64 val; + int ret; + + elems =3D get_res_prio_subpkg(cpu, index); + if (!elems) + return -EOPNOTSUPP; + + enable_reg =3D &elems[ENABLE_REGISTER]; + + if (enable) { + ret =3D cpc_read_reg(cpu, &elems[ENABLE_VALUE], &val); + if (ret) + return ret; + } else { + val =3D 0; + } + + return cpc_write_reg(cpu, enable_reg, val); +} +EXPORT_SYMBOL_GPL(cppc_set_res_priority_enable); + +/** + * cppc_get_res_priority_count - Read priority count for a Resource Priori= ty register. + * @cpu: CPU number. + * @index: Sub-package index. + * @count: Output priority count (>=3D 2 per spec). + * + * Return: 0 on success, negative error otherwise. + */ +int cppc_get_res_priority_count(int cpu, int index, u64 *count) +{ + struct cpc_register_resource *elems; + + if (!count) + return -EINVAL; + + elems =3D get_res_prio_subpkg(cpu, index); + if (!elems) + return -EOPNOTSUPP; + + return cpc_read_reg(cpu, &elems[PRIORITY_COUNT], count); +} +EXPORT_SYMBOL_GPL(cppc_get_res_priority_count); + +/** + * cppc_get_res_priority - Read priority value for a Resource Priority reg= ister. + * @cpu: CPU number. + * @index: Sub-package index. + * @priority: Output priority value. + * + * Return: 0 on success, negative error otherwise. + */ +int cppc_get_res_priority(int cpu, int index, u64 *priority) +{ + struct cpc_register_resource *elems; + struct cpc_register_resource *prio_reg; + + if (!priority) + return -EINVAL; + + elems =3D get_res_prio_subpkg(cpu, index); + if (!elems) + return -EOPNOTSUPP; + + prio_reg =3D &elems[PRIORITY_REGISTER]; + if (prio_reg->type !=3D ACPI_TYPE_BUFFER || + IS_NULL_REG(&prio_reg->cpc_entry.reg)) + return -EOPNOTSUPP; + + return cpc_read_reg(cpu, prio_reg, priority); +} +EXPORT_SYMBOL_GPL(cppc_get_res_priority); + +/** + * cppc_set_res_priority - Write priority value for a Resource Priority re= gister. + * @cpu: CPU number. + * @index: Sub-package index. + * @priority: Priority value to write (valid range: [0, PriorityCount - 1]= ). + * + * Return: 0 on success, negative error otherwise. + */ +int cppc_set_res_priority(int cpu, int index, u64 priority) +{ + struct cpc_register_resource *elems; + struct cpc_register_resource *prio_reg; + u64 prio_count; + int ret; + + elems =3D get_res_prio_subpkg(cpu, index); + if (!elems) + return -EOPNOTSUPP; + + ret =3D cpc_read_reg(cpu, &elems[PRIORITY_COUNT], &prio_count); + if (ret) + return ret; + + if (priority >=3D prio_count) + return -EINVAL; + + prio_reg =3D &elems[PRIORITY_REGISTER]; + + return cpc_write_reg(cpu, prio_reg, priority); +} +EXPORT_SYMBOL_GPL(cppc_set_res_priority); + /** * cppc_get_transition_latency - returns frequency transition latency in ns * @cpu_num: CPU number for per_cpu(). diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h index c0b8d52016cd..86a4764c504d 100644 --- a/include/acpi/cppc_acpi.h +++ b/include/acpi/cppc_acpi.h @@ -208,6 +208,14 @@ extern int cppc_get_auto_sel(int cpu, bool *enable); extern int cppc_set_auto_sel(int cpu, bool enable); extern int cppc_get_perf_limited(int cpu, u64 *perf_limited); extern int cppc_set_perf_limited(int cpu, u64 bits_to_clear); +extern int cppc_get_resource_priority_count(int cpu, int *count); +extern int cppc_get_resource_priority_resources(int cpu, int index, + u32 *resources, int *num_resources); +extern int cppc_get_res_priority_enable(int cpu, int index, bool *enable); +extern int cppc_set_res_priority_enable(int cpu, int index, bool enable); +extern int cppc_get_res_priority_count(int cpu, int index, u64 *count); +extern int cppc_get_res_priority(int cpu, int index, u64 *priority); +extern int cppc_set_res_priority(int cpu, int index, u64 priority); extern int amd_get_highest_perf(unsigned int cpu, u32 *highest_perf); extern int amd_get_boost_ratio_numerator(unsigned int cpu, u64 *numerator); extern int amd_detect_prefcore(bool *detected); @@ -312,6 +320,35 @@ static inline int cppc_set_perf_limited(int cpu, u64 b= its_to_clear) { return -EOPNOTSUPP; } +static inline int cppc_get_resource_priority_count(int cpu, int *count) +{ + return -EOPNOTSUPP; +} +static inline int cppc_get_resource_priority_resources(int cpu, int index, + u32 *resources, int *num_resources) +{ + return -EOPNOTSUPP; +} +static inline int cppc_get_res_priority_enable(int cpu, int index, bool *e= nable) +{ + return -EOPNOTSUPP; +} +static inline int cppc_set_res_priority_enable(int cpu, int index, bool en= able) +{ + return -EOPNOTSUPP; +} +static inline int cppc_get_res_priority_count(int cpu, int index, u64 *cou= nt) +{ + return -EOPNOTSUPP; +} +static inline int cppc_get_res_priority(int cpu, int index, u64 *priority) +{ + return -EOPNOTSUPP; +} +static inline int cppc_set_res_priority(int cpu, int index, u64 priority) +{ + return -EOPNOTSUPP; +} static inline int amd_get_highest_perf(unsigned int cpu, u32 *highest_perf) { return -ENODEV; --=20 2.33.0 From nobody Sat Jul 25 06:11:30 2026 Received: from canpmsgout04.his.huawei.com (canpmsgout04.his.huawei.com [113.46.200.219]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id CAEFC3321DC; Fri, 17 Jul 2026 02:46:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.219 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784256423; cv=none; b=d0BQms4Te+FrWaucFQS32oNfDJ6zVOmYqBR2rWeYe4BNRxBj5JgAa6EyK80nBpAXqoRj/R3F7Tjk5bBvPTyMYldFZTklvQ338DKqhLUg6Akf8H888NRda8Asf4Mb0p4Q+1Jv0CWDg7SF2iOAhVN/aiIA4orjzSCCQrZ1tuP2JX4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1784256423; c=relaxed/simple; bh=zUcUM3MRbzLzhno4sw57SwuOi6DBkYcipcWWUbp/8t4=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=XhIRSkBAHNm3Vv0ZgXle+cw8vaMR4EeeDR0mbVDr+LLLoWUZUBiEhf+BRGmKM/L5AeYYDLCs9TWU2JMWkAzW3lFpDLabSrczrr1Np40fKoUJR2wDE05iZ6oNxBxpz0y61Ba8HR0WgkZL3xoJyvwchtr9yRIeJIBI07STkQWMA2w= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b=zb7+r/TH; arc=none smtp.client-ip=113.46.200.219 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (1024-bit key) header.d=huawei.com header.i=@huawei.com header.b="zb7+r/TH" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=XCy/abM2ZuGeg2jlHJvx263rK6jJzqTC7h0W6+VwUJw=; b=zb7+r/THk/A8p2tuLBd9eJ2nJ3fUPKOz1dEyLPIKGDQsqWg6eQRJWeVnpLwVZJtDFSIVvaWyo ZkaRPndKD/+uqAyYLOmSYdwNUxgyWtYWaH9SaMEkriO4sXx0f9Bg1UPz4LW5mqEqXAyvHMhEHuH zltaqXE8vhW2jaPzX7CTxu4= Received: from mail.maildlp.com (unknown [172.19.163.104]) by canpmsgout04.his.huawei.com (SkyGuard) with ESMTPS id 4h1Ywb0kSZz1prLg; Fri, 17 Jul 2026 10:37:35 +0800 (CST) Received: from kwepemf100001.china.huawei.com (unknown [7.202.181.215]) by mail.maildlp.com (Postfix) with ESMTPS id 886C94058C; Fri, 17 Jul 2026 10:46:56 +0800 (CST) Received: from localhost.localdomain (10.50.163.32) by kwepemf100001.china.huawei.com (7.202.181.215) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1544.36; Fri, 17 Jul 2026 10:46:55 +0800 From: Lifeng Zheng To: , , , , , , CC: , , , , , , , , , , Subject: [PATCH 8/8] cpufreq: cppc: Expose Resource Priority attributes via sysfs Date: Fri, 17 Jul 2026 10:45:02 +0800 Message-ID: <20260717024502.3520445-9-zhenglifeng1@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20260717024502.3520445-1-zhenglifeng1@huawei.com> References: <20260717024502.3520445-1-zhenglifeng1@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: kwepems100002.china.huawei.com (7.221.188.206) To kwepemf100001.china.huawei.com (7.202.181.215) Content-Type: text/plain; charset="utf-8" Add a "resource_priority" kobject directory under each cpufreq policy that has CPPC v4 Resource Priority entries. Inside it, create a sub-directory per resource priority group (indexed 0..N-1) with the following sysfs attributes: controlled_resources (RO) -- resource type IDs as human-readable names enable (RW) -- enable/disable the priority group priority_count (RO) -- number of priority levels priority (RW) -- current priority value Create the sysfs hierarchy in cppc_cpufreq_cpu_init() and tear it down in cppc_cpufreq_cpu_exit(). A void *res_prio_data pointer in cppc_cpudata tracks the allocation. These attributes allow administrators and power-management daemons to inspect and tune Resource Priority settings at runtime without requiring platform-specific tools. Signed-off-by: Lifeng Zheng --- drivers/cpufreq/cppc_cpufreq.c | 270 +++++++++++++++++++++++++++++++++ include/acpi/cppc_acpi.h | 1 + 2 files changed, 271 insertions(+) diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c index f6cea0c54dd9..ed88f4e55ced 100644 --- a/drivers/cpufreq/cppc_cpufreq.c +++ b/drivers/cpufreq/cppc_cpufreq.c @@ -640,6 +640,9 @@ static void cppc_cpufreq_put_cpu_data(struct cpufreq_po= licy *policy) policy->driver_data =3D NULL; } =20 +static int cppc_create_res_prio_sysfs(struct cpufreq_policy *policy); +static void cppc_remove_res_prio_sysfs(struct cpufreq_policy *policy); + static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy) { unsigned int cpu =3D policy->cpu; @@ -715,6 +718,11 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy= *policy) } =20 cppc_cpufreq_cpu_fie_init(policy); + + ret =3D cppc_create_res_prio_sysfs(policy); + if (ret) + goto out; + return 0; =20 out: @@ -729,6 +737,7 @@ static void cppc_cpufreq_cpu_exit(struct cpufreq_policy= *policy) unsigned int cpu =3D policy->cpu; int ret; =20 + cppc_remove_res_prio_sysfs(policy); cppc_cpufreq_cpu_fie_exit(policy); =20 cpu_data->perf_ctrls.desired_perf =3D caps->lowest_perf; @@ -1026,6 +1035,267 @@ static struct freq_attr *cppc_cpufreq_attr[] =3D { NULL, }; =20 +/* =3D=3D=3D=3D=3D=3D Resource Priority sysfs interface (CPPC v4) =3D=3D= =3D=3D=3D=3D */ + +struct cppc_res_prio_group { + struct kobject kobj; + int index; + unsigned int cpu; +}; + +struct cppc_res_prio_data { + struct kobject kobj; + int num_groups; + struct cppc_res_prio_group groups[]; +}; + +static const char * const resource_type_names[] =3D { + NULL, + "processor_boost", + "processor_throttle", + "l2_cache", + "l3_cache", + "memory_bandwidth", +}; + +#define RESOURCE_TYPE_MAX 5 + +static const char *resource_type_to_name(u32 id) +{ + if (id >=3D 1 && id <=3D RESOURCE_TYPE_MAX) + return resource_type_names[id]; + return NULL; +} + +static ssize_t controlled_resources_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + struct cppc_res_prio_group *grp =3D + container_of(kobj, struct cppc_res_prio_group, kobj); + u32 resources[32]; + int num =3D ARRAY_SIZE(resources); + int ret, i, pos =3D 0; + + ret =3D cppc_get_resource_priority_resources(grp->cpu, grp->index, + resources, &num); + if (ret) + return ret; + + if (num =3D=3D 0) + return sysfs_emit(buf, "\n"); + + for (i =3D 0; i < num; i++) { + const char *name =3D resource_type_to_name(resources[i]); + + if (name) + pos +=3D sysfs_emit_at(buf, pos, "%s", name); + else + pos +=3D sysfs_emit_at(buf, pos, "unknown(0x%02x)", resources[i]); + + if (i < num - 1) + pos +=3D sysfs_emit_at(buf, pos, " "); + } + + pos +=3D sysfs_emit_at(buf, pos, "\n"); + return pos; +} + +static ssize_t enable_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + struct cppc_res_prio_group *grp =3D + container_of(kobj, struct cppc_res_prio_group, kobj); + bool val; + int ret; + + ret =3D cppc_get_res_priority_enable(grp->cpu, grp->index, &val); + if (ret =3D=3D -EOPNOTSUPP) + return sysfs_emit(buf, "\n"); + if (ret) + return ret; + + return sysfs_emit(buf, "%d\n", val); +} + +static ssize_t enable_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) +{ + struct cppc_res_prio_group *grp =3D + container_of(kobj, struct cppc_res_prio_group, kobj); + bool val; + int ret; + + ret =3D kstrtobool(buf, &val); + if (ret) + return ret; + + ret =3D cppc_set_res_priority_enable(grp->cpu, grp->index, val); + if (ret) + return ret; + + return count; +} + +static ssize_t priority_count_show(struct kobject *kobj, + struct kobj_attribute *attr, + char *buf) +{ + struct cppc_res_prio_group *grp =3D + container_of(kobj, struct cppc_res_prio_group, kobj); + u64 val; + int ret; + + ret =3D cppc_get_res_priority_count(grp->cpu, grp->index, &val); + if (ret =3D=3D -EOPNOTSUPP) + return sysfs_emit(buf, "\n"); + if (ret) + return ret; + + return sysfs_emit(buf, "%llu\n", val); +} + +static ssize_t priority_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + struct cppc_res_prio_group *grp =3D + container_of(kobj, struct cppc_res_prio_group, kobj); + u64 val; + int ret; + + ret =3D cppc_get_res_priority(grp->cpu, grp->index, &val); + if (ret =3D=3D -EOPNOTSUPP) + return sysfs_emit(buf, "\n"); + if (ret) + return ret; + + return sysfs_emit(buf, "%llu\n", val); +} + +static ssize_t priority_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t count) +{ + struct cppc_res_prio_group *grp =3D + container_of(kobj, struct cppc_res_prio_group, kobj); + u64 val; + int ret; + + ret =3D kstrtou64(buf, 0, &val); + if (ret) + return ret; + + ret =3D cppc_set_res_priority(grp->cpu, grp->index, val); + if (ret) + return ret; + + return count; +} + +static struct kobj_attribute attr_controlled_resources =3D + __ATTR(controlled_resources, 0444, controlled_resources_show, NULL); +static struct kobj_attribute attr_enable =3D + __ATTR(enable, 0644, enable_show, enable_store); +static struct kobj_attribute attr_priority_count =3D + __ATTR(priority_count, 0444, priority_count_show, NULL); +static struct kobj_attribute attr_priority =3D + __ATTR(priority, 0644, priority_show, priority_store); + +static struct attribute *res_prio_group_attrs[] =3D { + &attr_controlled_resources.attr, + &attr_enable.attr, + &attr_priority_count.attr, + &attr_priority.attr, + NULL, +}; + +ATTRIBUTE_GROUPS(res_prio_group); + +static void cppc_res_prio_group_release(struct kobject *kobj) +{ + /* + * cppc_res_prio_group is embedded in the flexible array of + * cppc_res_prio_data and freed when the parent is released. + */ +} + +static const struct kobj_type cppc_res_prio_group_ktype =3D { + .release =3D cppc_res_prio_group_release, + .sysfs_ops =3D &kobj_sysfs_ops, + .default_groups =3D res_prio_group_groups, +}; + +static void cppc_res_prio_release(struct kobject *kobj) +{ + struct cppc_res_prio_data *data =3D + container_of(kobj, struct cppc_res_prio_data, kobj); + + kfree(data); +} + +static const struct kobj_type cppc_res_prio_ktype =3D { + .release =3D cppc_res_prio_release, + .sysfs_ops =3D &kobj_sysfs_ops, +}; + +static void cppc_remove_res_prio_sysfs(struct cpufreq_policy *policy) +{ + struct cppc_cpudata *cpu_data =3D policy->driver_data; + struct cppc_res_prio_data *data =3D cpu_data->res_prio_data; + int i; + + if (!data) + return; + + for (i =3D 0; i < data->num_groups; i++) + kobject_put(&data->groups[i].kobj); + + kobject_put(&data->kobj); + cpu_data->res_prio_data =3D NULL; +} + +static int cppc_create_res_prio_sysfs(struct cpufreq_policy *policy) +{ + struct cppc_cpudata *cpu_data =3D policy->driver_data; + struct cppc_res_prio_data *data; + int num, i, ret; + + ret =3D cppc_get_resource_priority_count(policy->cpu, &num); + if (ret || num <=3D 0) + return 0; + + data =3D kzalloc(struct_size(data, groups, num), GFP_KERNEL); + if (!data) + return -ENOMEM; + + data->num_groups =3D num; + + ret =3D kobject_init_and_add(&data->kobj, &cppc_res_prio_ktype, + &policy->kobj, "resource_priority"); + if (ret) { + kfree(data); + return ret; + } + + for (i =3D 0; i < num; i++) { + data->groups[i].index =3D i; + data->groups[i].cpu =3D policy->cpu; + + ret =3D kobject_init_and_add(&data->groups[i].kobj, + &cppc_res_prio_group_ktype, + &data->kobj, "%d", i); + if (ret) { + while (--i >=3D 0) + kobject_put(&data->groups[i].kobj); + kobject_put(&data->kobj); + return ret; + } + } + + cpu_data->res_prio_data =3D data; + return 0; +} + static struct cpufreq_driver cppc_cpufreq_driver =3D { .flags =3D CPUFREQ_CONST_LOOPS | CPUFREQ_NEED_UPDATE_LIMITS, .verify =3D cppc_verify_policy, diff --git a/include/acpi/cppc_acpi.h b/include/acpi/cppc_acpi.h index 86a4764c504d..481fca627389 100644 --- a/include/acpi/cppc_acpi.h +++ b/include/acpi/cppc_acpi.h @@ -175,6 +175,7 @@ struct cppc_cpudata { struct cppc_perf_fb_ctrs perf_fb_ctrs; unsigned int shared_type; cpumask_var_t shared_cpu_map; + void *res_prio_data; }; =20 #ifdef CONFIG_ACPI_CPPC_LIB --=20 2.33.0