[PATCH RFC v3 08/11] ACPI: PPTT: Add acpi_pptt_get_cache_size_from_id helper

Drew Fustini fustini at kernel.org
Tue Apr 14 18:54:02 PDT 2026


Add helper to look up a cache's size from its cache ID in the PPTT
table. This is needed by the RISC-V RQSC parser to determine the cache
size for CBQRI capacity controllers.

The implementation follows the pattern established by
find_acpi_cache_level_from_id() and acpi_pptt_get_cpumask_from_cache_id():
uses acpi_get_pptt(), upgrade_pptt_cache(), checks all three cache types,
and uses the do/while empty-detection loop.

Signed-off-by: Drew Fustini <fustini at kernel.org>
---
 drivers/acpi/pptt.c  | 63 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 include/linux/acpi.h |  8 +++++++
 2 files changed, 71 insertions(+)

diff --git a/drivers/acpi/pptt.c b/drivers/acpi/pptt.c
index de5f8c018333..36e375551b43 100644
--- a/drivers/acpi/pptt.c
+++ b/drivers/acpi/pptt.c
@@ -1063,3 +1063,66 @@ int acpi_pptt_get_cpumask_from_cache_id(u32 cache_id, cpumask_t *cpus)
 
 	return 0;
 }
+
+/**
+ * acpi_pptt_get_cache_size_from_id() - Get the size of the specified cache
+ * @cache_id: The id field of the cache
+ * @size: Where to store the cache size in bytes
+ *
+ * Determine the size of the cache identified by cache_id. This allows the
+ * property to be found even if the CPUs are offline.
+ *
+ * The PPTT table must be rev 3 or later.
+ *
+ * Return: -ENOENT if the PPTT doesn't exist, the revision isn't supported or
+ * the cache cannot be found. Otherwise returns 0 and sets *size.
+ */
+int acpi_pptt_get_cache_size_from_id(u32 cache_id, u32 *size)
+{
+	int cpu;
+	struct acpi_table_header *table;
+
+	table = acpi_get_pptt();
+	if (!table)
+		return -ENOENT;
+
+	if (table->revision < 3)
+		return -ENOENT;
+
+	for_each_possible_cpu(cpu) {
+		bool empty;
+		int level = 1;
+		u32 acpi_cpu_id = get_acpi_id_for_cpu(cpu);
+		struct acpi_pptt_processor *cpu_node;
+
+		cpu_node = acpi_find_processor_node(table, acpi_cpu_id);
+		if (!cpu_node)
+			continue;
+
+		do {
+			int cache_type[] = {CACHE_TYPE_INST, CACHE_TYPE_DATA, CACHE_TYPE_UNIFIED};
+
+			empty = true;
+			for (int i = 0; i < ARRAY_SIZE(cache_type); i++) {
+				struct acpi_pptt_cache *cache;
+				struct acpi_pptt_cache_v1_full *cache_v1;
+
+				cache = acpi_find_cache_node(table, acpi_cpu_id, cache_type[i],
+							     level, &cpu_node);
+				if (!cache)
+					continue;
+
+				empty = false;
+
+				cache_v1 = upgrade_pptt_cache(cache);
+				if (cache_v1 && cache_v1->cache_id == cache_id) {
+					*size = cache->size;
+					return 0;
+				}
+			}
+			level++;
+		} while (!empty);
+	}
+
+	return -ENOENT;
+}
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 4d2f0bed7a06..0596ec18f522 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -1547,6 +1547,7 @@ int find_acpi_cpu_topology_package(unsigned int cpu);
 int find_acpi_cpu_topology_hetero_id(unsigned int cpu);
 void acpi_pptt_get_cpus_from_container(u32 acpi_cpu_id, cpumask_t *cpus);
 int find_acpi_cache_level_from_id(u32 cache_id);
+int acpi_pptt_get_cache_size_from_id(u32 cache_id, u32 *size);
 int acpi_pptt_get_cpumask_from_cache_id(u32 cache_id, cpumask_t *cpus);
 #else
 static inline int acpi_pptt_cpu_is_thread(unsigned int cpu)
@@ -1571,10 +1572,17 @@ static inline int find_acpi_cpu_topology_hetero_id(unsigned int cpu)
 }
 static inline void acpi_pptt_get_cpus_from_container(u32 acpi_cpu_id,
 						     cpumask_t *cpus) { }
+
 static inline int find_acpi_cache_level_from_id(u32 cache_id)
 {
 	return -ENOENT;
 }
+
+static inline int acpi_pptt_get_cache_size_from_id(u32 cache_id, u32 *size)
+{
+	return -ENOENT;
+}
+
 static inline int acpi_pptt_get_cpumask_from_cache_id(u32 cache_id,
 						      cpumask_t *cpus)
 {

-- 
2.43.0




More information about the linux-riscv mailing list