]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
RISC-V: ACPI: Cache and retrieve the RINTC structure
authorSunil V L <sunilvl@ventanamicro.com>
Mon, 15 May 2023 05:49:16 +0000 (11:19 +0530)
committerPalmer Dabbelt <palmer@rivosinc.com>
Thu, 1 Jun 2023 15:45:03 +0000 (08:45 -0700)
RINTC structures in the MADT provide mapping between the hartid
and the CPU. This is required many times even at run time like
cpuinfo. So, instead of parsing the ACPI table every time, cache
the RINTC structures and provide a function to get the correct
RINTC structure for a given cpu.

Signed-off-by: Sunil V L <sunilvl@ventanamicro.com>
Acked-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Reviewed-by: Andrew Jones <ajones@ventanamicro.com>
Link: https://lore.kernel.org/r/20230515054928.2079268-10-sunilvl@ventanamicro.com
Signed-off-by: Palmer Dabbelt <palmer@rivosinc.com>
arch/riscv/include/asm/acpi.h
arch/riscv/kernel/acpi.c
arch/riscv/kernel/setup.c

index 9be52b6ffae105de18b0d426a60ad751894109f6..6519529c8bdf57d103bef3fed9cfce26b0d33e9c 100644 (file)
@@ -59,6 +59,16 @@ static inline bool acpi_has_cpu_in_madt(void)
 
 static inline void arch_fix_phys_package_id(int num, u32 slot) { }
 
+void acpi_init_rintc_map(void);
+struct acpi_madt_rintc *acpi_cpu_get_madt_rintc(int cpu);
+u32 get_acpi_id_for_cpu(int cpu);
+#else
+static inline void acpi_init_rintc_map(void) { }
+static inline struct acpi_madt_rintc *acpi_cpu_get_madt_rintc(int cpu)
+{
+       return NULL;
+}
+
 #endif /* CONFIG_ACPI */
 
 #endif /*_ASM_ACPI_H*/
index 7c080c8cbccf003cf32ccddec80431a828686947..df5a45a2eb934fb32c98a06e1e137cbb1d917451 100644 (file)
@@ -29,6 +29,8 @@ static bool param_acpi_off __initdata;
 static bool param_acpi_on __initdata;
 static bool param_acpi_force __initdata;
 
+static struct acpi_madt_rintc cpu_madt_rintc[NR_CPUS];
+
 static int __init parse_acpi(char *arg)
 {
        if (!arg)
@@ -150,6 +152,49 @@ void __init acpi_boot_table_init(void)
        }
 }
 
+static int acpi_parse_madt_rintc(union acpi_subtable_headers *header, const unsigned long end)
+{
+       struct acpi_madt_rintc *rintc = (struct acpi_madt_rintc *)header;
+       int cpuid;
+
+       if (!(rintc->flags & ACPI_MADT_ENABLED))
+               return 0;
+
+       cpuid = riscv_hartid_to_cpuid(rintc->hart_id);
+       /*
+        * When CONFIG_SMP is disabled, mapping won't be created for
+        * all cpus.
+        * CPUs more than num_possible_cpus, will be ignored.
+        */
+       if (cpuid >= 0 && cpuid < num_possible_cpus())
+               cpu_madt_rintc[cpuid] = *rintc;
+
+       return 0;
+}
+
+/*
+ * Instead of parsing (and freeing) the ACPI table, cache
+ * the RINTC structures since they are frequently used
+ * like in  cpuinfo.
+ */
+void __init acpi_init_rintc_map(void)
+{
+       if (acpi_table_parse_madt(ACPI_MADT_TYPE_RINTC, acpi_parse_madt_rintc, 0) <= 0) {
+               pr_err("No valid RINTC entries exist\n");
+               BUG();
+       }
+}
+
+struct acpi_madt_rintc *acpi_cpu_get_madt_rintc(int cpu)
+{
+       return &cpu_madt_rintc[cpu];
+}
+
+u32 get_acpi_id_for_cpu(int cpu)
+{
+       return acpi_cpu_get_madt_rintc(cpu)->uid;
+}
+
 /*
  * __acpi_map_table() will be called before paging_init(), so early_ioremap()
  * or early_memremap() should be called here to for ACPI table mapping.
index 45df7cc88b195d374d80d586630f174f25534c31..2ab4cdaa2e68452c38ad0223e991288f46f4f466 100644 (file)
@@ -22,6 +22,7 @@
 #include <linux/efi.h>
 #include <linux/crash_dump.h>
 
+#include <asm/acpi.h>
 #include <asm/alternative.h>
 #include <asm/cacheflush.h>
 #include <asm/cpu_ops.h>
@@ -298,6 +299,9 @@ void __init setup_arch(char **cmdline_p)
        setup_smp();
 #endif
 
+       if (!acpi_disabled)
+               acpi_init_rintc_map();
+
        riscv_init_cbo_blocksizes();
        riscv_fill_hwcap();
        apply_boot_alternatives();