summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorian <ian@FreeBSD.org>2015-10-18 20:37:10 +0000
committerian <ian@FreeBSD.org>2015-10-18 20:37:10 +0000
commit7b5d098c90f0f2e5151f5a80014ba3932988a132 (patch)
tree485e9d3eca52f784256a5582c1edc3e4a43c9279
parentd9b26080f66dd6280463f8a250fec9578a516ccd (diff)
downloadFreeBSD-src-7b5d098c90f0f2e5151f5a80014ba3932988a132.zip
FreeBSD-src-7b5d098c90f0f2e5151f5a80014ba3932988a132.tar.gz
Only decode fdt data which belongs to the GIC controller.
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
-rw-r--r--sys/arm/arm/gic.c17
-rw-r--r--sys/arm/include/intr.h3
2 files changed, 17 insertions, 3 deletions
diff --git a/sys/arm/arm/gic.c b/sys/arm/arm/gic.c
index 9ceac48..a1ce111 100644
--- a/sys/arm/arm/gic.c
+++ b/sys/arm/arm/gic.c
@@ -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),
diff --git a/sys/arm/include/intr.h b/sys/arm/include/intr.h
index ed075df..2bb479a 100644
--- a/sys/arm/include/intr.h
+++ b/sys/arm/include/intr.h
@@ -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
OpenPOWER on IntegriCloud