Page MenuHomeFreeBSD

D6436.id.diff
No OneTemporary

D6436.id.diff

Index: head/sys/kern/subr_intr.c
===================================================================
--- head/sys/kern/subr_intr.c
+++ head/sys/kern/subr_intr.c
@@ -98,6 +98,15 @@
static void *irq_root_arg;
static u_int irq_root_ipicount;
+struct intr_pic_child {
+ SLIST_ENTRY(intr_pic_child) pc_next;
+ struct intr_pic *pc_pic;
+ intr_child_irq_filter_t *pc_filter;
+ void *pc_filter_arg;
+ uintptr_t pc_start;
+ uintptr_t pc_length;
+};
+
/* Interrupt controller definition. */
struct intr_pic {
SLIST_ENTRY(intr_pic) pic_next;
@@ -106,6 +115,8 @@
#define FLAG_PIC (1 << 0)
#define FLAG_MSI (1 << 1)
u_int pic_flags;
+ struct mtx pic_child_lock;
+ SLIST_HEAD(, intr_pic_child) pic_children;
};
static struct mtx pic_list_lock;
@@ -323,6 +334,29 @@
#endif
}
+int
+intr_child_irq_handler(struct intr_pic *parent, uintptr_t irq)
+{
+ struct intr_pic_child *child;
+ bool found;
+
+ found = false;
+ mtx_lock_spin(&parent->pic_child_lock);
+ SLIST_FOREACH(child, &parent->pic_children, pc_next) {
+ if (child->pc_start <= irq &&
+ irq < (child->pc_start + child->pc_length)) {
+ found = true;
+ break;
+ }
+ }
+ mtx_unlock_spin(&parent->pic_child_lock);
+
+ if (found)
+ return (child->pc_filter(child->pc_filter_arg, irq));
+
+ return (FILTER_STRAY);
+}
+
/*
* interrupt controller dispatch function for interrupts. It should
* be called straight from the interrupt controller, when associated interrupt
@@ -892,6 +926,7 @@
}
pic->pic_xref = xref;
pic->pic_dev = dev;
+ mtx_init(&pic->pic_child_lock, "pic child lock", NULL, MTX_SPIN);
SLIST_INSERT_HEAD(&pic_list, pic, pic_next);
mtx_unlock(&pic_list_lock);
@@ -1001,6 +1036,44 @@
return (0);
}
+/*
+ * Add a handler to manage a sub range of a parents interrupts.
+ */
+struct intr_pic *
+intr_pic_add_handler(device_t parent, struct intr_pic *pic,
+ intr_child_irq_filter_t *filter, void *arg, uintptr_t start,
+ uintptr_t length)
+{
+ struct intr_pic *parent_pic;
+ struct intr_pic_child *newchild;
+#ifdef INVARIANTS
+ struct intr_pic_child *child;
+#endif
+
+ parent_pic = pic_lookup(parent, 0);
+ if (parent_pic == NULL)
+ return (NULL);
+
+ newchild = malloc(sizeof(*newchild), M_INTRNG, M_WAITOK | M_ZERO);
+ newchild->pc_pic = pic;
+ newchild->pc_filter = filter;
+ newchild->pc_filter_arg = arg;
+ newchild->pc_start = start;
+ newchild->pc_length = length;
+
+ mtx_lock_spin(&parent_pic->pic_child_lock);
+#ifdef INVARIANTS
+ SLIST_FOREACH(child, &parent_pic->pic_children, pc_next) {
+ KASSERT(child->pc_pic != pic, ("%s: Adding a child PIC twice",
+ __func__));
+ }
+#endif
+ SLIST_INSERT_HEAD(&parent_pic->pic_children, newchild, pc_next);
+ mtx_unlock_spin(&parent_pic->pic_child_lock);
+
+ return (pic);
+}
+
int
intr_map_irq(device_t dev, intptr_t xref, struct intr_map_data *data,
u_int *irqp)
Index: head/sys/sys/intr.h
===================================================================
--- head/sys/sys/intr.h
+++ head/sys/sys/intr.h
@@ -74,6 +74,7 @@
#else
typedef int intr_irq_filter_t(void *arg);
#endif
+typedef int intr_child_irq_filter_t(void *arg, uintptr_t irq);
#define INTR_ISRC_NAMELEN (MAXCOMLEN + 1)
@@ -81,6 +82,8 @@
#define INTR_ISRCF_PPI 0x02 /* PPI interrupt */
#define INTR_ISRCF_BOUND 0x04 /* bound to a CPU */
+struct intr_pic;
+
/* Interrupt source definition. */
struct intr_irqsrc {
device_t isrc_dev; /* where isrc is mapped */
@@ -113,6 +116,8 @@
struct intr_pic *intr_pic_register(device_t, intptr_t);
int intr_pic_deregister(device_t, intptr_t);
int intr_pic_claim_root(device_t, intptr_t, intr_irq_filter_t *, void *, u_int);
+struct intr_pic *intr_pic_add_handler(device_t, struct intr_pic *,
+ intr_child_irq_filter_t *, void *, uintptr_t, uintptr_t);
extern device_t intr_irq_root_dev;
@@ -127,6 +132,7 @@
int intr_teardown_irq(device_t, struct resource *, void *);
int intr_describe_irq(device_t, struct resource *, void *, const char *);
+int intr_child_irq_handler(struct intr_pic *, uintptr_t);
/* MSI/MSI-X handling */
int intr_msi_register(device_t, intptr_t);

File Metadata

Mime Type
text/plain
Expires
Thu, Apr 2, 1:21 PM (5 h, 46 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30701488
Default Alt Text
D6436.id.diff (4 KB)

Event Timeline