summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sys/arch/riscv64/riscv64/intr.c25
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;
}