From nobody Thu Sep 24 15:11:58 2026 Received: from canpmsgout06.his.huawei.com (canpmsgout06.his.huawei.com [113.46.200.221]) (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 B7489542EF9; Tue, 22 Sep 2026 12:43:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.221 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790081030; cv=none; b=EQFyExFtwStJviEuGED1v4OOl46Tes3u20Xu9xidTZbkPYQ+kdJ+3htyaENAasFR7TjWlbhxa1/Z/xS/d0NMrhQ8SvpvwSHjqhO7YGsMXjYGuI5ZmAP4x9gCysvbyD+qeLAeCSW9IiUyherXR4OVEko0Vn9zu7xcGfFQOAaONiw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790081030; c=relaxed/simple; bh=SFifmtolDLhp7/hIPyEN4KkxrXXW9qcorg+HFcP9k3Y=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=MNk1i333KIOk8Hg7lWernpNedi1QKBMFM+ej0W+f6eBvvvLRpAsNmexqqpNXoyZolDjYepCrTExmbShsX45WG71Ly1nu/Gm4hiI9vfPVCRe1Zm0Ze0S+eAQl5Fu5/7DEJBP7oh2F17I+cCIbGUMNFnjfJV5MWgrkvArmS+useoY= 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=w5ItmmVB; arc=none smtp.client-ip=113.46.200.221 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="w5ItmmVB" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=yKGqqQI+Uhtn74jATxL7vYZkfUPEKo/fbFgxPKC8IXg=; b=w5ItmmVBe04bQA2BUp49OUOIW6odv8MFOXXRQrz3DNZbrNuf+H2Uq6ZF2mb2uNqZQ93ewKtSe 7SSv20mBDSXelAc8R9B94s+fV1tNPWBPk2zEixk4mDo866cNEMQBJKd72mCAUSUJwMhyQRZbXhV yh16vzKwzKN3NdIJylU/BKA= Received: from mail.maildlp.com (unknown [172.19.162.197]) by canpmsgout06.his.huawei.com (SkyGuard) with ESMTPS id 4hpzx96r6xzRhQs; Tue, 22 Sep 2026 20:31:41 +0800 (CST) Received: from kwepemf100001.china.huawei.com (unknown [7.202.181.215]) by mail.maildlp.com (Postfix) with ESMTPS id 55B3740579; Tue, 22 Sep 2026 20:43:43 +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.2562.45; Tue, 22 Sep 2026 20:43:42 +0800 From: Lifeng Zheng To: , , , , , , , CC: , , , , , , , , , Subject: [PATCH v4 1/8] ACPI: CPPC: Prepare cpc_register_resource for Package-type entries Date: Tue, 22 Sep 2026 20:41:14 +0800 Message-ID: <20260922124121.3426219-2-zhenglifeng1@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20260922124121.3426219-1-zhenglifeng1@huawei.com> References: <20260922124121.3426219-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: kwepems200001.china.huawei.com (7.221.188.67) 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. No functional change intended; the new Package fields are not yet consumed by any caller. Signed-off-by: Lifeng Zheng --- include/acpi/cppc_acpi.h | 8 ++++++++ 1 file changed, 8 insertions(+) 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 Thu Sep 24 15:11:58 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 D44BE399004; Tue, 22 Sep 2026 12:43:46 +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=1790081030; cv=none; b=D189l7s6DJFz9eGQDtGwUDa42AxelNBFL6p/uqCLp3JFz6mIGO5if0KM8xfuUgoMqGl1pTgTv+JX6VRtLDhw7V6dFyg1L+Vz/aEly3o9jFXkiFH+jtVfgnO1PmpePx5eHa7ECLV59jrFghTmkzHyMl1oAvgKo7cONnf7qK0Bgos= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790081030; c=relaxed/simple; bh=5XmVZl6186sCsRh37nU8yJgLh37NFG4kCSw+UJtUTbg=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=OHY4o3PF1dG+bv+mjyh+JC+mQfW4TM9Gz3YfxPvwvg97FiI+zWoFz/18rShw64dqNE50YZFBq7eFTueeeDYhiP73l7kkEhq5+g9DdT7FplV3L0XigNZBVPpElnQkjarn5BI/lp+BekQ4fRCOUsv15iozBUax3/XKu1o+wN19oRg= 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=5mAzYbIC; 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="5mAzYbIC" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=lWkWSvLfhkBwzal7ykQjYimAjO7pZ2iSPFmIW5hs0fs=; b=5mAzYbICq9LwWe+HzF9E0o9vRQ7jX9bxZxM+9bpzMm1wDF8ihpAendXo4vmtsMxjKfM+mShTF Ys8nTL/JMFm4WuS/a0a9qqZ+9gk01bR/xAe0MzREh5zyMjFVuMDmn4Fd+p+qlz6mkLBy32yCzxQ ym8SuuHt3V/GwiY75IimmGk= Received: from mail.maildlp.com (unknown [172.19.163.163]) by canpmsgout08.his.huawei.com (SkyGuard) with ESMTPS id 4hpzx76l3GzmV7C; Tue, 22 Sep 2026 20:31:39 +0800 (CST) Received: from kwepemf100001.china.huawei.com (unknown [7.202.181.215]) by mail.maildlp.com (Postfix) with ESMTPS id F26B240588; Tue, 22 Sep 2026 20:43:43 +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.2562.45; Tue, 22 Sep 2026 20:43:43 +0800 From: Lifeng Zheng To: , , , , , , , CC: , , , , , , , , , Subject: [PATCH v4 2/8] ACPI: CPPC: Refactor element parsing into parse_cpc_element() Date: Tue, 22 Sep 2026 20:41:15 +0800 Message-ID: <20260922124121.3426219-3-zhenglifeng1@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20260922124121.3426219-1-zhenglifeng1@huawei.com> References: <20260922124121.3426219-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: kwepems200001.china.huawei.com (7.221.188.67) 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 9f572f481241..47ececf214c4 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -650,6 +650,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. * @@ -690,7 +793,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; @@ -778,80 +880,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 && (i - 2) =3D=3D RESOURCE_PR= IORITY) { /* * ACPI 6.6, s8.4.6.1.2.7 defines Resource Priority as a * Package of Resource Priority Register Descriptor sub-packages. @@ -862,9 +891,10 @@ int acpi_cppc_processor_probe(struct acpi_processor *p= r) cpc_ptr->cpc_regs[i-2].type =3D ACPI_TYPE_INTEGER; cpc_ptr->cpc_regs[i-2].cpc_entry.int_value =3D 0; } 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 Thu Sep 24 15:11:58 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 23546545DA0; Tue, 22 Sep 2026 12:43:55 +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=1790081038; cv=none; b=Is6G/ALmE+g/NGDWAC8sjRLoMnh75E1CiIAgx1du0SY6iX+dPRogQrnBNvvXVa574iDnb7ukxcwUiDwNJL4BAKZI+VbUlcjRfKuHd16CnhMuEgAM/orwbTUwiBhOTFwgfcFeCoJoX6e9rBYuxT7SoMNpObzvXLPXCbq3uoIM+Ac= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790081038; c=relaxed/simple; bh=kDpK7Seh/MxWoKpik6r7NblQ5wfpHGUwrsILNj5QaYs=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=nixFFgGZ0gV/ogwXlQUK+McJae3+uKMIu2tf0aWhHtfqhwq8FE1jAQEkKIxo2In2yhtW9B/nw+W1jgX2xx3vjwMzv6GcApHq4Qx63IJbqz3Mq0reMCpijGQQxvuozhsvV5tRGOJxSIXSHHZxbwbUFaxsbfS8I4Fnjyc4VBzHYAw= 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=D66CmRTe; 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="D66CmRTe" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=FCtyezrfFYHAsq12yeCIgaKi9Rbow+xBWuIlKanOkyk=; b=D66CmRTe0YZORKY7r8ATMMk2H/F/vX4IrE3iMes4ZC5WIuOJUw8idDe2tMPcYt9MQ1cx40+wf Kemo7oJQAFNmsyHd1FCNNxywrW5f1FZpCUX8l5j/zhWG4HONjLcobSD6wMr9dCpayYajAqrgO62 TnJudJ+lMKD4BghxDsUpFls= Received: from mail.maildlp.com (unknown [172.19.163.214]) by canpmsgout07.his.huawei.com (SkyGuard) with ESMTPS id 4hpzyL1RMTzLlSh; Tue, 22 Sep 2026 20:32:42 +0800 (CST) Received: from kwepemf100001.china.huawei.com (unknown [7.202.181.215]) by mail.maildlp.com (Postfix) with ESMTPS id A6CC940580; Tue, 22 Sep 2026 20:43:44 +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.2562.45; Tue, 22 Sep 2026 20:43:43 +0800 From: Lifeng Zheng To: , , , , , , , CC: , , , , , , , , , Subject: [PATCH v4 3/8] ACPI: CPPC: Refactor resource cleanup into free_reg_resource() Date: Tue, 22 Sep 2026 20:41:16 +0800 Message-ID: <20260922124121.3426219-4-zhenglifeng1@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20260922124121.3426219-1-zhenglifeng1@huawei.com> References: <20260922124121.3426219-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: kwepems200001.china.huawei.com (7.221.188.67) 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 47ececf214c4..dce15d875c62 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -753,6 +753,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. * @@ -965,12 +989,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: @@ -989,7 +1010,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]) { @@ -1007,12 +1027,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 Thu Sep 24 15:11:58 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 543995448B0; Tue, 22 Sep 2026 12:43:53 +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=1790081037; cv=none; b=sUjZiarY6RmafTSnODWgb9l7DA4AXewnGuwLwn4u1qh/h5AYCEf2qOLxUZnBB9bO0qF1p//FQcdEiaK69zThpi/y5tQL0UCtO2nakZJpFg9YQ2yCF9R/dvSSyIYS5P8zyQDFY2u1LVMSnin4KGoDcXTNPsifBLryQMBG98gq7FA= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790081037; c=relaxed/simple; bh=Pdyn01ETs/TPNcRKTejGGKn3Lvp/cyjB3+r4JaYkOxI=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Qnma+3+M8oSNf2WvLYux8ex3BXSZXp+kS3kNP21xqyKG4Ek93BfI1dhuc1Vyty3sPfGYlpUkqWSUI2Jv0XM0wWNQxL3cuDpMz8j6EdZWBdSA7mP0NMj1sbAQp2QXT/4XvNOXVExJPwNPaYjMw//6A6fQat6qnGJeiMNcSEB72eM= 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=D6xeNl5n; 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="D6xeNl5n" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=Rh83EaNYRqmAhG/BdnqS5kQ6Bg6zMu3GoGaveSHo+e0=; b=D6xeNl5nPVjjO2LcB1lYJMIA5fK4YwH5bIyrbi+bPHim8aYr55+V3yOSyHIhpis4BvreIJ2/c KlZS8guvxYz1uXFsMhJthZUUzN/4mTMmTvqA2E2yK+RWzF027XecBDE/POson7If0jVp9g9/ZLu EFKdUAn4KDyE5zYmPSqx4IQ= Received: from mail.maildlp.com (unknown [172.19.163.104]) by canpmsgout04.his.huawei.com (SkyGuard) with ESMTPS id 4hpzyK4JW2z1prQt; Tue, 22 Sep 2026 20:32:41 +0800 (CST) Received: from kwepemf100001.china.huawei.com (unknown [7.202.181.215]) by mail.maildlp.com (Postfix) with ESMTPS id 55A3E4058C; Tue, 22 Sep 2026 20:43:45 +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.2562.45; Tue, 22 Sep 2026 20:43:44 +0800 From: Lifeng Zheng To: , , , , , , , CC: , , , , , , , , , Subject: [PATCH v4 4/8] ACPI: CPPC: Parse Resource Priority Register entries from _CPC package Date: Tue, 22 Sep 2026 20:41:17 +0800 Message-ID: <20260922124121.3426219-5-zhenglifeng1@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20260922124121.3426219-1-zhenglifeng1@huawei.com> References: <20260922124121.3426219-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: kwepems200001.china.huawei.com (7.221.188.67) 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 | 137 ++++++++++++++++++++++++++++++++++++--- include/acpi/cppc_acpi.h | 13 ++++ 2 files changed, 142 insertions(+), 8 deletions(-) diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index dce15d875c62..b5563d75d6c5 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -777,6 +777,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. * @@ -815,6 +900,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; @@ -823,6 +909,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"); @@ -904,16 +991,50 @@ 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 - if (cpc_obj->type =3D=3D ACPI_TYPE_PACKAGE && (i - 2) =3D=3D RESOURCE_PR= IORITY) { + /* + * 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) { + 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; + } + /* - * 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. + * Assign values immediately after successful allocation to ensure that + * resources can be properly released. */ - 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].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); + ret =3D -ENODATA; + 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 Thu Sep 24 15:11:58 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 8610F5437D4; Tue, 22 Sep 2026 12:43:48 +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=1790081031; cv=none; b=Hp28XORusErYq4SV0Rn8KxkxQq43ATIufQB1zEOuesCjy1lJj4Jo6L0j+/iu7IGBeb44gF7WXKI6Fw7UxFT1ZLsHnfQJIhK2RhVzHiWc6p49Yffa2lUyEyvt+AtF9fT+6f5DfMw+jTWfpuwEGSeuVSX6paRqpgWmu2p50Q1ZqlU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790081031; c=relaxed/simple; bh=4ebNe8xcy+gZy/jwfzhaVB/U/5i290Lkrm0E7UMx678=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Y7QIEdpN87ixsd+bcPuR0JefwUmA/e2cT9dT5Kjy3iEZ01LShZ4uVcR7kq1GOo1X8Iah2jlSuuIy41qDtR4DzmLnNR9II8PsH3Y114Zjk1vo98/FV3KQERo9CTbM3lfKbtEiEZuc1gl5+/7nubR/4IzZPEgIjNOj8s54t3u465w= 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=ZhLquWVk; 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="ZhLquWVk" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=fucjSwjA3JlEtRmLOfGwAv2I4I9v7+l/r2xRlHpKvLw=; b=ZhLquWVkaf/1p07znDq0mzUNM06de/4FoVIQ4KTNXnry5Qw7mI2NvWgK2Gx0aiHjiSB7/qqzi 26XgnupFWt1GwjdYuygHgiK5ihVer827jrG3a0G9S74IIQ/PGwkyIYBBRlfCLK9RzH95EGOMrwy J/ZiEWhIdtDxoD23IhH8f7A= Received: from mail.maildlp.com (unknown [172.19.163.15]) by canpmsgout08.his.huawei.com (SkyGuard) with ESMTPS id 4hpzx971YxzmV7C; Tue, 22 Sep 2026 20:31:41 +0800 (CST) Received: from kwepemf100001.china.huawei.com (unknown [7.202.181.215]) by mail.maildlp.com (Postfix) with ESMTPS id 084D440586; Tue, 22 Sep 2026 20:43:46 +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.2562.45; Tue, 22 Sep 2026 20:43:45 +0800 From: Lifeng Zheng To: , , , , , , , CC: , , , , , , , , , Subject: [PATCH v4 5/8] ACPI: CPPC: Store optional flag in cpc_register_resource Date: Tue, 22 Sep 2026 20:41:18 +0800 Message-ID: <20260922124121.3426219-6-zhenglifeng1@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20260922124121.3426219-1-zhenglifeng1@huawei.com> References: <20260922124121.3426219-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: kwepems200001.china.huawei.com (7.221.188.67) 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 | 14 +++++++++----- include/acpi/cppc_acpi.h | 1 + 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index b5563d75d6c5..53c71888108d 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -137,11 +137,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 @@ -844,6 +844,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; @@ -852,6 +853,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) @@ -990,6 +992,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 @@ -1060,6 +1063,7 @@ int acpi_cppc_processor_probe(struct acpi_processor *= pr) * LOWEST_FREQ and NOMINAL_FREQ regs as unsupported */ for (i =3D num_ent - 2; i < MAX_CPC_REG_ENT; i++) { + cpc_ptr->cpc_regs[i].optional =3D true; cpc_ptr->cpc_regs[i].type =3D ACPI_TYPE_INTEGER; cpc_ptr->cpc_regs[i].cpc_entry.int_value =3D 0; } @@ -1410,7 +1414,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 Thu Sep 24 15:11:58 2026 Received: from canpmsgout12.his.huawei.com (canpmsgout12.his.huawei.com [113.46.200.227]) (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 A17EB5476C9; Tue, 22 Sep 2026 12:43:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.227 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790081039; cv=none; b=IxTZ22zKY42vYxhcTBAg8wZRMrZQmA4s06lN9ErWYnAv/MHJUha29HQoy5WxwdpbzPfjmXLsmbDMRTwrNJJQCmz3HARNYnQtm4NNBAb08uVmdPK8pmKGu8wKBg4TyfhUKOq5Mv/uqczGAx/uLp9wUTFsLcEZ41kMAR5xt+lK0JU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790081039; c=relaxed/simple; bh=N4HtkiWf7I6T2lTSMu8KrEBHfC1CNXw2MeRawSnuvXU=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=ER++QxDI7+37RuOAtKSOLUJAQ/bckzaVE6brCaN9AUN+SVo6GfzsxBsOZCWD8dl7spgRmPdEKZTcysmbRTcCr+C60ifyEyW/69DR51DmovFsp3/kh5vfr60VbIuDSjMnouvt3GoQ8lCYjamyP1/PRR12uvJOSOc0hBVL9wYoDAY= 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=A6MLL1lL; arc=none smtp.client-ip=113.46.200.227 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="A6MLL1lL" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=uuTlAjbFVG3K4wNEikSMGRwn8CiTCyTwtRqd8LgITfc=; b=A6MLL1lLoqRqLjMnIUrkIz7uyVDYEI7+6iMBwg379KlmGhDk2YI4eNS+GqCXAfUABQafn2U9p k5VwnFEKgWv6vb/w2CNZrvQOGeiOxdDzfuxq9C5JYIKiIW6RBiO/lRBs+NB+Uo26BE3mTyy9vEe zicGgEAClSO49nqGfFRLpLY= Received: from mail.maildlp.com (unknown [172.19.162.92]) by canpmsgout12.his.huawei.com (SkyGuard) with ESMTPS id 4hpzyP0v8lznTWH; Tue, 22 Sep 2026 20:32:45 +0800 (CST) Received: from kwepemf100001.china.huawei.com (unknown [7.202.181.215]) by mail.maildlp.com (Postfix) with ESMTPS id A739A40586; Tue, 22 Sep 2026 20:43:46 +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.2562.45; Tue, 22 Sep 2026 20:43:45 +0800 From: Lifeng Zheng To: , , , , , , , CC: , , , , , , , , , Subject: [PATCH v4 6/8] ACPI: CPPC: Factor out cpc_read_reg() and cpc_write_reg() Date: Tue, 22 Sep 2026 20:41:19 +0800 Message-ID: <20260922124121.3426219-7-zhenglifeng1@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20260922124121.3426219-1-zhenglifeng1@huawei.com> References: <20260922124121.3426219-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: kwepems200001.china.huawei.com (7.221.188.67) 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 53c71888108d..2c2b25ec3e27 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -1374,7 +1374,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; @@ -1399,35 +1399,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; @@ -1452,18 +1469,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"); @@ -1471,11 +1486,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 Thu Sep 24 15:11:58 2026 Received: from canpmsgout01.his.huawei.com (canpmsgout01.his.huawei.com [113.46.200.216]) (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 8B9FB5437CC; Tue, 22 Sep 2026 12:43:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.216 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790081034; cv=none; b=p00P96TZh7OyJC+WUoxrTIG1aqZusNAjpHhb0pKaMt0W/SL9kWpMbWIbDFZSucUsotMTjKaySh/YK6AuMt4kCtShD7pjbNYk9DP9+gV+F7mHF5FY/RsvaFfFK+cO9CLdMOjMNkF/qnALOX4m1Cfxe/VdZVrUAPaZmDgLrnvSeYc= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790081034; c=relaxed/simple; bh=mYSr0K4zrRaOvDJ4RTYqmqbIJNYtzjYqJJKzjZAl1Uc=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=blXOp7ooHQN0xSGewDE2/AvYrTIMcjE+Uh/3s3Q4kdm2b8QkoYmLv2ottqSKEucD8y4DNq0cqHtgcotdNhjDYACHI9ZVfkSlH9qEqwSjHk6tdcRjFCNnAeNTnnfmvNoSVMUumV4d8OdJWskNaChICcuAKeF5SzbjOuUBkE5MkQA= 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=QSbzwbf5; arc=none smtp.client-ip=113.46.200.216 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="QSbzwbf5" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=ruZedv3T9GAEEFlS4qhDZuZMFHjSElM+C872GQj8Nko=; b=QSbzwbf5iOXNxfklN5dHFd3rXrPZuGllejWqonfeOcTDr4n84cDEbRHt0PiuX2K2PROHirnS8 4vzdRt0Lio/69yN+qiIP/kH0qVoM2ptPPNhUiC0UMUE1FZyHGFSv8H3ZXIgz7KAXReLlfyS3Y9Q WQYTcun5eo3ywMZJfSTSJvA= Received: from mail.maildlp.com (unknown [172.19.163.104]) by canpmsgout01.his.huawei.com (SkyGuard) with ESMTPS id 4hpzxT1PnQz1T4LY; Tue, 22 Sep 2026 20:31:57 +0800 (CST) Received: from kwepemf100001.china.huawei.com (unknown [7.202.181.215]) by mail.maildlp.com (Postfix) with ESMTPS id 64DAD4058C; Tue, 22 Sep 2026 20:43:47 +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.2562.45; Tue, 22 Sep 2026 20:43:46 +0800 From: Lifeng Zheng To: , , , , , , , CC: , , , , , , , , , Subject: [PATCH v4 7/8] ACPI: CPPC: Add Resource Priority accessors Date: Tue, 22 Sep 2026 20:41:20 +0800 Message-ID: <20260922124121.3426219-8-zhenglifeng1@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20260922124121.3426219-1-zhenglifeng1@huawei.com> References: <20260922124121.3426219-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: kwepems200001.china.huawei.com (7.221.188.67) 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 | 264 +++++++++++++++++++++++++++++++++++++++ include/acpi/cppc_acpi.h | 37 ++++++ 2 files changed, 301 insertions(+) diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index 2c2b25ec3e27..f90d727798e8 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -2284,6 +2284,270 @@ 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) { + *num_resources =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 Thu Sep 24 15:11:58 2026 Received: from canpmsgout06.his.huawei.com (canpmsgout06.his.huawei.com [113.46.200.221]) (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 7D8C55448BD; Tue, 22 Sep 2026 12:43:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=113.46.200.221 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790081035; cv=none; b=nBFCVC7L4XMZUr0Dg9KNNLr7fsyuRtCAfPwrDDenIcU2w8Mqm3m1pkoXIdT6nM866vo4dNXg7RjT9rUvdi+JTdpFUxC/lrhnrHWGsTjib2DHjc+SU8aUKx3ey5NO22yrAYrtCsl9eLQG55szWKT8wVwTpVEqzKMTpRaX2es15BU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1790081035; c=relaxed/simple; bh=/B5NYFLugt9DIQ2id6d1oXbGd3V3fWNDJUDlnSTzymY=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=Y/CnW6Q21+YBq0x6zj6dwpa/wEqCgoNhtZyHo7kYaInR0BZrhxgpuqLxCzd/oW9XJfb/dC/CGKohaXQuz/OCQQYaRwV0r4NqjH6i/z06ZiHreEBo8bhKD+gvDGSkdllBC47FJv/h/C7+S5PcHTHvoi7EcR+yBhMTpiSR1QZ+2Tc= 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=m+8mqWQQ; arc=none smtp.client-ip=113.46.200.221 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="m+8mqWQQ" dkim-signature: v=1; a=rsa-sha256; d=huawei.com; s=dkim; c=relaxed/relaxed; q=dns/txt; h=From; bh=gk+Cw3lijNognwTB0VP6k3qTqQ7UBTDBC3Vxl2cQR8E=; b=m+8mqWQQVbQgZoOlCrVCz8CmyNI/Z2D1VSRnG8AMhyJPbU0kbVXBPfIKIOG+JeMqRTwqRgpq2 E1YvK4PVmpiYTFG+i23vW96EavlHxk/XOO/D7Lj5FCyVROi9Pilu5nAc8z86jU1iGk3tZU0Vz40 0cTY9heOSsDiiViZnPBMMmw= Received: from mail.maildlp.com (unknown [172.19.163.104]) by canpmsgout06.his.huawei.com (SkyGuard) with ESMTPS id 4hpzxG4zTGzRhQs; Tue, 22 Sep 2026 20:31:46 +0800 (CST) Received: from kwepemf100001.china.huawei.com (unknown [7.202.181.215]) by mail.maildlp.com (Postfix) with ESMTPS id 176054058C; Tue, 22 Sep 2026 20:43:48 +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.2562.45; Tue, 22 Sep 2026 20:43:47 +0800 From: Lifeng Zheng To: , , , , , , , CC: , , , , , , , , , Subject: [PATCH v4 8/8] cpufreq: cppc: Expose Resource Priority attributes via sysfs Date: Tue, 22 Sep 2026 20:41:21 +0800 Message-ID: <20260922124121.3426219-9-zhenglifeng1@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20260922124121.3426219-1-zhenglifeng1@huawei.com> References: <20260922124121.3426219-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: kwepems200001.china.huawei.com (7.221.188.67) 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 | 281 ++++++++++++++++++++++++++++++++- include/acpi/cppc_acpi.h | 1 + 2 files changed, 280 insertions(+), 2 deletions(-) diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c index f6cea0c54dd9..497c10e806ac 100644 --- a/drivers/cpufreq/cppc_cpufreq.c +++ b/drivers/cpufreq/cppc_cpufreq.c @@ -640,12 +640,15 @@ static void cppc_cpufreq_put_cpu_data(struct cpufreq_= policy *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; struct cppc_cpudata *cpu_data; struct cppc_perf_caps *caps; - int ret; + int ret, retval; =20 cpu_data =3D cppc_cpufreq_get_cpu_data(cpu); if (!cpu_data) { @@ -715,7 +718,19 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy= *policy) } =20 cppc_cpufreq_cpu_fie_init(policy); - return 0; + + ret =3D cppc_create_res_prio_sysfs(policy); + if (!ret) + return 0; + + cppc_cpufreq_cpu_fie_exit(policy); + + cpu_data->perf_ctrls.desired_perf =3D caps->lowest_perf; + + retval =3D cppc_set_perf(cpu, &cpu_data->perf_ctrls); + if (retval) + pr_debug("Err setting perf value:%d on CPU:%d. ret:%d\n", + caps->lowest_perf, cpu, retval); =20 out: cppc_cpufreq_put_cpu_data(policy); @@ -729,6 +744,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 +1042,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) { + kobject_put(&data->kobj); + 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) { + for (; i >=3D 0; i--) + 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