diff options
| author | Anup Patel <anup.patel@oss.qualcomm.com> | 2026-02-13 11:23:38 +0530 |
|---|---|---|
| committer | Anup Patel <anup@brainfault.org> | 2026-03-22 10:52:45 +0530 |
| commit | 5a300b32d546d226e55361e47d07b1c9171f07c8 (patch) | |
| tree | 7bf83d20da7ff79fac2f2f838a5f183fdf842699 /lib | |
| parent | 6d68f3bebd206314a5b194004249524dbc0da075 (diff) | |
| download | opensbi-5a300b32d546d226e55361e47d07b1c9171f07c8.tar.gz opensbi-5a300b32d546d226e55361e47d07b1c9171f07c8.tar.bz2 opensbi-5a300b32d546d226e55361e47d07b1c9171f07c8.zip | |
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 <anup.patel@oss.qualcomm.com>
Link: https://lore.kernel.org/r/20260213055342.3124872-5-anup.patel@oss.qualcomm.com
Signed-off-by: Anup Patel <anup@brainfault.org>
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/utils/irqchip/fdt_irqchip_aplic.c | 54 |
1 files changed, 53 insertions, 1 deletions
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 <sbi_utils/irqchip/fdt_irqchip.h> #include <sbi_utils/irqchip/aplic.h> +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; |
