PERFORCE change 139921 for review
Oleksandr Tymoshenko
gonzo at FreeBSD.org
Sat Apr 12 17:43:27 UTC 2008
http://perforce.freebsd.org/chv.cgi?CH=139921
Change 139921 by gonzo at gonzo_jeeves on 2008/04/12 17:42:32
o We can share interrupts, so don't panic if there are several
requests for the same IRQ.
o Implement PIC-specific mask/unmask functions intead of generic stubs.
o New IRQ handling logic: take into account FILTER_SCHEDULE_THREAD,
reset thread flag before handling new IRQ.
o Do not map MEM/IOPORT resources on this level - it's up to nexus
device.
o Minor style(9) fixes
Affected files ...
.. //depot/projects/mips2-jnpr/src/sys/mips/mips32/idt/obio.c#3 edit
Differences ...
==== //depot/projects/mips2-jnpr/src/sys/mips/mips32/idt/obio.c#3 (text+ko) ====
@@ -76,6 +76,30 @@
static int obio_teardown_intr(device_t, device_t, struct resource *,
void *);
+static void obio_mask_irq(unsigned int irq)
+{
+ int ip_bit, mask, mask_register;
+
+ /* mask IRQ */
+ mask_register = ICU_IRQ_MASK_REG(irq);
+ ip_bit = ICU_IP_BIT(irq);
+
+ mask = ICU_REG_READ(mask_register);
+ ICU_REG_WRITE(mask_register, mask | ip_bit);
+}
+
+static void obio_unmask_irq(unsigned int irq)
+{
+ int ip_bit, mask, mask_register;
+
+ /* unmask IRQ */
+ mask_register = ICU_IRQ_MASK_REG(irq);
+ ip_bit = ICU_IP_BIT(irq);
+
+ mask = ICU_REG_READ(mask_register);
+ ICU_REG_WRITE(mask_register, mask & ~ip_bit);
+}
+
static int
obio_probe(device_t dev)
{
@@ -199,20 +223,9 @@
struct resource *r)
{
- /*
- * If this is a memory resource, track the direct mapping
- * in the uncached MIPS KSEG1 segment.
- */
- if (type == SYS_RES_MEMORY) {
- void *vaddr;
-
- vaddr = (void *)MIPS_PHYS_TO_KSEG1((intptr_t)rman_get_start(r));
- rman_set_virtual(r, vaddr);
- rman_set_bustag(r, MIPS_BUS_SPACE_MEM);
- rman_set_bushandle(r, (bus_space_handle_t)vaddr);
- }
-
- return (rman_activate_resource(r));
+ /* XXX: should we mask/unmask IRQ here? */
+ return (BUS_ACTIVATE_RESOURCE(device_get_parent(bus), child,
+ type, rid, r));
}
static int
@@ -220,7 +233,9 @@
struct resource *r)
{
- return (rman_deactivate_resource(r));
+ /* XXX: should we mask/unmask IRQ here? */
+ return (BUS_DEACTIVATE_RESOURCE(device_get_parent(bus), child,
+ type, rid, r));
}
static int
@@ -259,14 +274,12 @@
event = sc->sc_eventstab[irq];
if (event == NULL) {
error = intr_event_create(&event, (void *)irq, 0,
- (mask_fn)mips_mask_irq, (mask_fn)mips_unmask_irq,
+ (mask_fn)obio_mask_irq, (mask_fn)obio_unmask_irq,
NULL, NULL,
"obio intr%d:", irq);
sc->sc_eventstab[irq] = event;
}
- else
- panic("obio: Can't share IRQs");
intr_event_add_handler(event, device_get_nameunit(child), filt,
handler, arg, intr_priority(flags), flags, cookiep);
@@ -304,9 +317,8 @@
ICU_REG_WRITE(mask_register, mask | ip_bit);
result = intr_event_remove_handler(cookie);
- if (!result) {
+ if (!result)
sc->sc_eventstab[irq] = NULL;
- }
return (result);
}
@@ -318,9 +330,8 @@
struct intr_event *event;
struct intr_handler *ih;
uint32_t irqstat, ipend, imask, xpend;
- int irq, thread = 0, group, i;
+ int irq, thread, group, i, ret;
- /* TODO: handle all IRQs */
irqstat = 0;
irq = 0;
for (group = 2; group <= 6; group++) {
@@ -328,6 +339,7 @@
imask = ICU_REG_READ(ICU_GROUP_MASK_REG(group));
xpend = ipend;
ipend &= ~imask;
+
while ((i = fls(xpend)) != 0) {
xpend &= ~(1 << (i - 1));
irq = IP_IRQ(group, i - 1);
@@ -337,23 +349,48 @@
ipend &= ~(1 << (i - 1));
irq = IP_IRQ(group, i - 1);
event = sc->sc_eventstab[irq];
- if (event && !TAILQ_EMPTY(&event->ie_handlers)) {
- /* Execute fast handlers. */
- TAILQ_FOREACH(ih, &event->ie_handlers,
- ih_next) {
- if (ih->ih_filter == NULL)
+ thread = 0;
+#ifndef INTR_FILTER
+ obio_mask_irq(irq);
+#endif
+ if (!event || TAILQ_EMPTY(&event->ie_handlers)) {
+#ifdef INTR_FILTER
+ obio_unmask_irq(irq);
+#endif
+ continue;
+ }
+
+#ifdef INTR_FILTER
+ /* TODO: frame instead of NULL? */
+ intr_event_handle(event, NULL);
+ /* XXX: Log stray IRQs */
+#else
+ /* Execute fast handlers. */
+ TAILQ_FOREACH(ih, &event->ie_handlers,
+ ih_next) {
+ if (ih->ih_filter == NULL)
+ thread = 1;
+ else
+ ret = ih->ih_filter(ih->ih_argument);
+ /*
+ * Wrapper handler special case: see
+ * intr_execute_handlers() in
+ * i386/intr_machdep.c
+ */
+ if (!thread) {
+ if (ret == FILTER_SCHEDULE_THREAD)
thread = 1;
- else
- ih->ih_filter(ih->ih_argument);
}
}
/* Schedule thread if needed. */
if (thread)
intr_event_schedule_thread(event);
-
+ else
+ obio_unmask_irq(irq);
}
}
+#endif
#if 0
ipend = ICU_REG_READ(ICU_IPEND2);
printf("ipend2 = %08x!\n", ipend);
More information about the p4-projects
mailing list