Sun Jun 11 12:56:37 2017 UTC ()
Fix an issue with interrupt controller lookup wrt cascading interrupt
controllers.


(jmcneill)
diff -r1.10 -r1.11 src/sys/dev/fdt/fdt_intr.c

cvs diff -r1.10 -r1.11 src/sys/dev/fdt/fdt_intr.c (expand / switch to context diff)
--- src/sys/dev/fdt/fdt_intr.c 2017/06/02 13:12:33 1.10
+++ src/sys/dev/fdt/fdt_intr.c 2017/06/11 12:56:36 1.11
@@ -1,4 +1,4 @@
-/* $NetBSD: fdt_intr.c,v 1.10 2017/06/02 13:12:33 jmcneill Exp $ */
+/* $NetBSD: fdt_intr.c,v 1.11 2017/06/11 12:56:36 jmcneill Exp $ */
 
 /*-
  * Copyright (c) 2015 Jared D. McNeill <jmcneill@invisible.ca>
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: fdt_intr.c,v 1.10 2017/06/02 13:12:33 jmcneill Exp $");
+__KERNEL_RCSID(0, "$NetBSD: fdt_intr.c,v 1.11 2017/06/11 12:56:36 jmcneill Exp $");
 
 #include <sys/param.h>
 #include <sys/bus.h>
@@ -44,6 +44,11 @@
 	struct fdtbus_interrupt_controller *ic_next;
 };
 
+struct fdtbus_interrupt_cookie {
+	struct fdtbus_interrupt_controller *c_ic;
+	void *c_ih;
+};
+
 static struct fdtbus_interrupt_controller *fdtbus_ic = NULL;
 
 static bool	has_interrupt_map(int);
@@ -79,7 +84,7 @@
 }
 
 static struct fdtbus_interrupt_controller *
-fdtbus_get_interrupt_controller_ic(int phandle)
+fdtbus_get_interrupt_controller(int phandle)
 {
 	struct fdtbus_interrupt_controller * ic;
 	for (ic = fdtbus_ic; ic; ic = ic->ic_next) {
@@ -90,17 +95,6 @@
 	return NULL;
 }
 
-static struct fdtbus_interrupt_controller *
-fdtbus_get_interrupt_controller(int phandle)
-{
-	const int ic_phandle = fdtbus_get_interrupt_parent(phandle);
-	if (ic_phandle < 0) {
-		return NULL;
-	}
-
-	return fdtbus_get_interrupt_controller_ic(ic_phandle);
-}
-
 int
 fdtbus_register_interrupt_controller(device_t dev, int phandle,
     const struct fdtbus_interrupt_controller_func *funcs)
@@ -123,8 +117,10 @@
     int (*func)(void *), void *arg)
 {
 	struct fdtbus_interrupt_controller *ic;
+	struct fdtbus_interrupt_cookie *c = NULL;
 	u_int *specifier;
 	int ihandle;
+	void *ih;
 
 	specifier = get_specifier_by_index(phandle, index, &ihandle);
 	if (specifier == NULL)
@@ -134,17 +130,23 @@
 	if (ic == NULL)
 		return NULL;
 
-	return ic->ic_funcs->establish(ic->ic_dev, specifier,
+	ih = ic->ic_funcs->establish(ic->ic_dev, specifier,
 	    ipl, flags, func, arg);
+	if (ih != NULL) {
+		c = kmem_alloc(sizeof(*c), KM_SLEEP);
+		c->c_ic = ic;
+		c->c_ih = ih;
+	}
+
+	return c;
 }
 
 void
-fdtbus_intr_disestablish(int phandle, void *ih)
+fdtbus_intr_disestablish(int phandle, void *cookie)
 {
-	struct fdtbus_interrupt_controller *ic;
-
-	ic = fdtbus_get_interrupt_controller(phandle);
-	KASSERT(ic != NULL);
+	struct fdtbus_interrupt_cookie *c = cookie;
+	struct fdtbus_interrupt_controller *ic = c->c_ic;
+	void *ih = c->c_ih;
 
 	return ic->ic_funcs->disestablish(ic->ic_dev, ih);
 }