diff options
-rw-r--r-- | sys/arch/riscv64/riscv64/intr.c | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/sys/arch/riscv64/riscv64/intr.c b/sys/arch/riscv64/riscv64/intr.c index b7cb8c5eb2f..a6cd054305e 100644 --- a/sys/arch/riscv64/riscv64/intr.c +++ b/sys/arch/riscv64/riscv64/intr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: intr.c,v 1.11 2024/06/26 01:40:49 jsg Exp $ */ +/* $OpenBSD: intr.c,v 1.12 2024/08/06 09:07:15 kettenis Exp $ */ /* * Copyright (c) 2011 Dale Rahn <drahn@openbsd.org> @@ -27,7 +27,7 @@ #include <dev/ofw/openfirm.h> -uint32_t riscv_intr_get_parent(int); +int riscv_intr_get_parent(int); uint32_t riscv_intr_map_msi(int, uint64_t *); void *riscv_intr_prereg_establish_fdt(void *, int *, int, struct cpu_info *, @@ -74,17 +74,21 @@ riscv_cpu_intr(void *frame) /* * Find the interrupt parent by walking up the tree. */ -uint32_t +int riscv_intr_get_parent(int node) { - uint32_t phandle = 0; + uint32_t phandle; - while (node && !phandle) { + while (node) { phandle = OF_getpropint(node, "interrupt-parent", 0); + if (phandle) + return OF_getnodebyphandle(phandle); node = OF_parent(node); + if (OF_getpropbool(node, "interrupt-controller")) + return node; } - return phandle; + return 0; } uint32_t @@ -271,8 +275,6 @@ riscv_intr_register_fdt(struct interrupt_controller *ic) ic->ic_cells = OF_getpropint(ic->ic_node, "#interrupt-cells", 0); ic->ic_phandle = OF_getpropint(ic->ic_node, "phandle", 0); - if (ic->ic_phandle == 0) - return; KASSERT(ic->ic_cells <= MAX_INTERRUPT_CELLS); LIST_INSERT_HEAD(&interrupt_controllers, ic, ic_list); @@ -323,7 +325,8 @@ riscv_intr_establish_fdt_idx_cpu(int node, int idx, int level, struct cpu_info *ci, int (*func)(void *), void *cookie, char *name) { struct interrupt_controller *ic; - int i, len, ncells, extended = 1; + int i, len, ncells, parent; + int extended = 1; uint32_t *cell, *cells, phandle; struct machine_intr_handle *ih; void *val = NULL; @@ -338,9 +341,9 @@ riscv_intr_establish_fdt_idx_cpu(int node, int idx, int level, /* Old style. */ if (!extended) { - phandle = riscv_intr_get_parent(node); + parent = riscv_intr_get_parent(node); LIST_FOREACH(ic, &interrupt_controllers, ic_list) { - if (ic->ic_phandle == phandle) + if (ic->ic_node == parent) break; } |