aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAnup Patel <anup.patel@oss.qualcomm.com>2026-02-13 11:23:38 +0530
committerAnup Patel <anup@brainfault.org>2026-03-22 10:52:45 +0530
commit5a300b32d546d226e55361e47d07b1c9171f07c8 (patch)
tree7bf83d20da7ff79fac2f2f838a5f183fdf842699 /lib
parent6d68f3bebd206314a5b194004249524dbc0da075 (diff)
downloadopensbi-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.c54
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;