summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMark Kettenis <kettenis@cvs.openbsd.org>2024-08-04 12:01:19 +0000
committerMark Kettenis <kettenis@cvs.openbsd.org>2024-08-04 12:01:19 +0000
commit98da328a75457f56d3474e27ef458c08969bcc4e (patch)
tree56a984b352ad26f87bf8b11c0001c66e9be9cb83 /sys
parent9f3fc8ca933f5bcf3e520692f249983c5e340040 (diff)
The devicetree spec says in section 2.4:
If an interrupt-generating device does not have an interrupt-parent property, its interrupt parent is assumed to be its devicetree parent. Implement this aspect of the spec in the same way as Linux does by not just looking at the immediate parent but keep on walking up the tree until we hit a node with an "interrupt-controller" property or a node that has an "interrupt-parent" property. ok patrick@
Diffstat (limited to 'sys')
-rw-r--r--sys/arch/arm64/arm64/intr.c31
1 files changed, 17 insertions, 14 deletions
diff --git a/sys/arch/arm64/arm64/intr.c b/sys/arch/arm64/arm64/intr.c
index 9e69fd001ca..8e7d610bb4b 100644
--- a/sys/arch/arm64/arm64/intr.c
+++ b/sys/arch/arm64/arm64/intr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: intr.c,v 1.28 2024/05/26 13:37:31 kettenis Exp $ */
+/* $OpenBSD: intr.c,v 1.29 2024/08/04 12:01:18 kettenis Exp $ */
/*
* Copyright (c) 2011 Dale Rahn <drahn@openbsd.org>
*
@@ -26,7 +26,7 @@
#include <dev/ofw/openfirm.h>
-uint32_t arm_intr_get_parent(int);
+int arm_intr_get_parent(int);
uint32_t arm_intr_map_msi(int, uint64_t *);
void *arm_intr_prereg_establish_fdt(void *, int *, int, struct cpu_info *,
@@ -94,17 +94,21 @@ arm_cpu_fiq(void *frame)
/*
* Find the interrupt parent by walking up the tree.
*/
-uint32_t
+int
arm_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
@@ -291,8 +295,6 @@ arm_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);
@@ -341,7 +343,8 @@ arm_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;
@@ -356,9 +359,9 @@ arm_intr_establish_fdt_idx_cpu(int node, int idx, int level, struct cpu_info *ci
/* Old style. */
if (!extended) {
- phandle = arm_intr_get_parent(node);
+ parent = arm_intr_get_parent(node);
LIST_FOREACH(ic, &interrupt_controllers, ic_list) {
- if (ic->ic_phandle == phandle)
+ if (ic->ic_node == parent)
break;
}
@@ -569,12 +572,12 @@ arm_intr_parent_establish_fdt(void *cookie, int *cell, int level,
{
struct interrupt_controller *ic = cookie;
struct machine_intr_handle *ih;
- uint32_t phandle;
+ int parent;
void *val;
- phandle = arm_intr_get_parent(ic->ic_node);
+ parent = arm_intr_get_parent(ic->ic_node);
LIST_FOREACH(ic, &interrupt_controllers, ic_list) {
- if (ic->ic_phandle == phandle)
+ if (ic->ic_node == parent)
break;
}
if (ic == NULL)