From 5a300b32d546d226e55361e47d07b1c9171f07c8 Mon Sep 17 00:00:00 2001 From: Anup Patel Date: Fri, 13 Feb 2026 11:23:38 +0530 Subject: [PATCH] lib: utils/irqchip: Add IDC to hartindex map in struct aplic_data A platform can have multiple APLICs in direct-mode targetting different subset of harts. Add APLIC ID to hartindex map in struct aplic_data to capture the set of harts targeted by a given APLIC in direct-mode. Signed-off-by: Anup Patel Link: https://lore.kernel.org/r/20260213055342.3124872-5-anup.patel@oss.qualcomm.com Signed-off-by: Anup Patel --- include/sbi_utils/irqchip/aplic.h | 1 + lib/utils/irqchip/fdt_irqchip_aplic.c | 54 ++++++++++++++++++++++++++- 2 files changed, 54 insertions(+), 1 deletion(-) diff --git a/include/sbi_utils/irqchip/aplic.h b/include/sbi_utils/irqchip/aplic.h index cbfcd3fd..ad613778 100644 --- a/include/sbi_utils/irqchip/aplic.h +++ b/include/sbi_utils/irqchip/aplic.h @@ -45,6 +45,7 @@ struct aplic_data { bool has_msicfg_smode; struct aplic_msicfg_data msicfg_smode; struct aplic_delegate_data delegate[APLIC_MAX_DELEGATE]; + u32 *idc_map; }; int aplic_cold_irqchip_init(struct aplic_data *aplic); diff --git a/lib/utils/irqchip/fdt_irqchip_aplic.c b/lib/utils/irqchip/fdt_irqchip_aplic.c index 81ebe67d..4d7b1e77 100644 --- a/lib/utils/irqchip/fdt_irqchip_aplic.c +++ b/lib/utils/irqchip/fdt_irqchip_aplic.c @@ -16,6 +16,43 @@ #include #include +static int irqchip_aplic_update_idc_map(const void *fdt, int nodeoff, + struct aplic_data *pd) +{ + int i, err, count, cpu_offset, cpu_intc_offset; + u32 phandle, hartid, hartindex; + const fdt32_t *val; + + val = fdt_getprop(fdt, nodeoff, "interrupts-extended", &count); + if (!val || count < sizeof(fdt32_t)) + return SBI_EINVAL; + count = count / sizeof(fdt32_t); + + for (i = 0; i < count; i += 2) { + phandle = fdt32_to_cpu(val[i]); + + cpu_intc_offset = fdt_node_offset_by_phandle(fdt, phandle); + if (cpu_intc_offset < 0) + continue; + + cpu_offset = fdt_parent_offset(fdt, cpu_intc_offset); + if (cpu_offset < 0) + continue; + + err = fdt_parse_hart_id(fdt, cpu_offset, &hartid); + if (err) + continue; + + hartindex = sbi_hartid_to_hartindex(hartid); + if (hartindex == -1U) + continue; + + pd->idc_map[i / 2] = hartindex; + } + + return 0; +} + static int irqchip_aplic_cold_init(const void *fdt, int nodeoff, const struct fdt_match *match) { @@ -30,12 +67,27 @@ static int irqchip_aplic_cold_init(const void *fdt, int nodeoff, if (rc) goto fail_free_data; + if (pd->num_idc) { + pd->idc_map = sbi_zalloc(sizeof(*pd->idc_map) * pd->num_idc); + if (!pd->idc_map) { + rc = SBI_ENOMEM; + goto fail_free_data; + } + + rc = irqchip_aplic_update_idc_map(fdt, nodeoff, pd); + if (rc) + goto fail_free_idc_map; + } + rc = aplic_cold_irqchip_init(pd); if (rc) - goto fail_free_data; + goto fail_free_idc_map; return 0; +fail_free_idc_map: + if (pd->num_idc) + sbi_free(pd->idc_map); fail_free_data: sbi_free(pd); return rc;