__init void amiga_init_IRQ(void) { int i; for (i = 0; i < AMI_IRQS; i++) ami_ablecount[i] = 0; /* turn off PCMCIA interrupts */ if (AMIGAHW_PRESENT(PCMCIA)) gayle.inten = GAYLE_IRQ_IDE; /* turn off all interrupts... */ amiga_custom.intena = 0x7fff; amiga_custom.intreq = 0x7fff; #ifdef CONFIG_APUS /* Clear any inter-CPU interrupt requests. Circumvents bug in Blizzard IPL emulation HW (or so it appears). */ APUS_WRITE(APUS_INT_LVL, INTLVL_SETRESET | INTLVL_MASK); /* Init IPL emulation. */ APUS_WRITE(APUS_REG_INT, REGINT_INTMASTER | REGINT_ENABLEIPL); APUS_WRITE(APUS_IPL_EMU, IPLEMU_DISABLEINT); APUS_WRITE(APUS_IPL_EMU, IPLEMU_SETRESET | IPLEMU_IPLMASK); #endif /* ... and enable the master interrupt bit */ amiga_custom.intena = IF_SETCLR | IF_INTEN; cia_init_IRQ(&ciaa_base); cia_init_IRQ(&ciab_base); }
void amiga_do_irq_list(int irq, struct pt_regs *fp, struct irq_server *server) { irq_node_t *node, *slow_nodes; unsigned short flags; kstat.irqs[0][SYS_IRQS + irq]++; if (server->count++) server->reentrance = 1; /* serve first fast and normal handlers */ for (node = ami_irq_list[irq]; node && (!(node->flags & IRQ_FLG_SLOW)); node = node->next) node->handler(irq, node->dev_id, fp); custom.intreq = ami_intena_vals[irq]; if (!node) { server->count--; return; } #ifdef CONFIG_APUS APUS_WRITE(APUS_IPL_EMU, IPLEMU_SETRESET | IPLEMU_DISABLEINT); APUS_WRITE(APUS_IPL_EMU, IPLEMU_IPLMASK); APUS_WRITE(APUS_IPL_EMU, (IPLEMU_SETRESET | (~(fp->mq) & IPLEMU_IPLMASK))); APUS_WRITE(APUS_IPL_EMU, IPLEMU_DISABLEINT); #else save_flags(flags); restore_flags((flags & ~0x0700) | (fp->sr & 0x0700)); #endif /* if slow handlers exists, serve them now */ slow_nodes = node; for (;;) { for (; node; node = node->next) node->handler(irq, node->dev_id, fp); /* if reentrance occurred, serve slow handlers again */ custom.intena = ami_intena_vals[irq]; if (!server->reentrance) { server->count--; custom.intena = IF_SETCLR | ami_intena_vals[irq]; return; } server->reentrance = 0; custom.intena = IF_SETCLR | ami_intena_vals[irq]; node = slow_nodes; } }
__init void amiga_init_IRQ(void) { int i; /* initialize handlers */ for (i = 0; i < AMI_STD_IRQS; i++) { if (ami_servers[i]) { ami_irq_list[i] = NULL; } else { ami_irq_list[i] = new_irq_node(); ami_irq_list[i]->handler = ami_badint; ami_irq_list[i]->flags = 0; ami_irq_list[i]->dev_id = NULL; ami_irq_list[i]->devname = NULL; ami_irq_list[i]->next = NULL; } } for (i = 0; i < AMI_IRQS; i++) ami_ablecount[i] = 0; /* turn off PCMCIA interrupts */ if (AMIGAHW_PRESENT(PCMCIA)) pcmcia_disable_irq(); /* turn off all interrupts... */ custom.intena = 0x7fff; custom.intreq = 0x7fff; #ifdef CONFIG_APUS /* Clear any inter-CPU interrupt requests. Circumvents bug in Blizzard IPL emulation HW (or so it appears). */ APUS_WRITE(APUS_INT_LVL, INTLVL_SETRESET | INTLVL_MASK); /* Init IPL emulation. */ APUS_WRITE(APUS_REG_INT, REGINT_INTMASTER | REGINT_ENABLEIPL); APUS_WRITE(APUS_IPL_EMU, IPLEMU_DISABLEINT); APUS_WRITE(APUS_IPL_EMU, IPLEMU_SETRESET | IPLEMU_IPLMASK); #endif /* ... and enable the master interrupt bit */ custom.intena = IF_SETCLR | IF_INTEN; cia_init_IRQ(&ciaa_base); cia_init_IRQ(&ciab_base); }