]> xenbits.xensource.com Git - people/julieng/freebsd.git/commitdiff
Only decode fdt data which belongs to the GIC controller.
authorian <ian@FreeBSD.org>
Sun, 18 Oct 2015 20:37:10 +0000 (20:37 +0000)
committerian <ian@FreeBSD.org>
Sun, 18 Oct 2015 20:37:10 +0000 (20:37 +0000)
The interrupts-extended property is a list of controller-specific
interrupt tuples for more than one controller.  The decode routine of
every PIC gets called in the pre-INTRNG code (nexus doesn't know which
device instance belongs to which fdt node), so the GIC code has to
check each FDT node it is asked to decode to ensure it is the owner.

Because in the pre-INTRNG world there can only be one instance of a GIC,
it's safe to cache the results of a positive lookup in a static variable
to avoid the expensive lookups on subsequent calls.

Submitted by: Svatopluk Kraus <onwahe@gmail.com>
Differential Revision: https://reviews.freebsd.org/D2345

sys/arm/arm/gic.c
sys/arm/include/intr.h

index 9ceac4865ea33f84d1dedc6c34ad8a4be7e08d48..a1ce111f9f1492fc9927fc8ed1b14512d3ad071e 100644 (file)
@@ -36,6 +36,8 @@ __FBSDID("$FreeBSD$");
 
 #include "opt_platform.h"
 
+#include "opt_platform.h"
+
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/bus.h>
@@ -288,10 +290,23 @@ arm_gic_init_secondary(device_t dev)
  
 #ifndef ARM_INTRNG
 int
-gic_decode_fdt(uint32_t iparent, uint32_t *intr, int *interrupt,
+gic_decode_fdt(phandle_t iparent, pcell_t *intr, int *interrupt,
     int *trig, int *pol)
 {
        static u_int num_intr_cells;
+       static phandle_t self;
+       struct ofw_compat_data *ocd;
+
+       if (self == 0) {
+               for (ocd = compat_data; ocd->ocd_str != NULL; ocd++) {
+                       if (fdt_is_compatible(iparent, ocd->ocd_str)) {
+                               self = iparent;
+                               break;
+                       }
+               }
+       }
+       if (self != iparent)
+               return (ENXIO);
 
        if (num_intr_cells == 0) {
                if (OF_searchencprop(OF_node_from_xref(iparent),
index ed075dfd39c118a2bb4e45d6a30af3715d795ac9..2bb479acb7f7cb2595a078aa548c75ca29ac1c39 100644 (file)
@@ -179,10 +179,9 @@ extern int (*arm_config_irq)(int irq, enum intr_trigger trig,
     enum intr_polarity pol);
 
 void arm_pic_init_secondary(void);
-int  gic_decode_fdt(uint32_t iparentnode, uint32_t *intrcells, int *interrupt,
-    int *trig, int *pol);
 
 #ifdef FDT
+int gic_decode_fdt(phandle_t, pcell_t *, int *, int *, int *);
 int arm_fdt_map_irq(phandle_t, pcell_t *, int);
 #endif