static void request_ras_irqs(struct device_node *np, char *propname, irqreturn_t (*handler)(int, void *, struct pt_regs *), const char *name) { unsigned int *ireg, len, i; int virq, n_intr; ireg = (unsigned int *)get_property(np, propname, &len); if (ireg == NULL) return; n_intr = prom_n_intr_cells(np); len /= n_intr * sizeof(*ireg); for (i = 0; i < len; i++) { virq = virt_irq_create_mapping(*ireg); if (virq == NO_IRQ) { printk(KERN_ERR "Unable to allocate interrupt " "number for %s\n", np->full_name); return; } if (request_irq(irq_offset_up(virq), handler, 0, name, NULL)) { printk(KERN_ERR "Unable to request interrupt %d for " "%s\n", irq_offset_up(virq), np->full_name); return; } ireg += n_intr; } }
/* * New version of finish_node_interrupts. */ static unsigned long __init finish_node_interrupts(struct device_node *np, unsigned long mem_start) { unsigned int *ints; int intlen, intrcells; int i, j, n, offset; unsigned int *irq; struct device_node *ic; ints = (unsigned int *) get_property(np, "interrupts", &intlen); if (ints == NULL) return mem_start; intrcells = prom_n_intr_cells(np); intlen /= intrcells * sizeof(unsigned int); np->n_intrs = intlen; np->intrs = (struct interrupt_info *) mem_start; mem_start += intlen * sizeof(struct interrupt_info); for (i = 0; i < intlen; ++i) { np->intrs[i].line = 0; np->intrs[i].sense = 1; n = map_interrupt(&irq, &ic, np, ints, intrcells); if (n <= 0) continue; offset = 0; /* * On a CHRP we have an 8259 which is subordinate to * the openpic in the interrupt tree, but we want the * openpic's interrupt numbers offsetted, not the 8259's. * So we apply the offset if the controller is at the * root of the interrupt tree, i.e. has no interrupt-parent. * This doesn't cope with the general case of multiple * cascaded interrupt controllers, but then neither will * irq.c at the moment either. -- paulus */ if (num_interrupt_controllers > 1 && ic != NULL && get_property(ic, "interrupt-parent", NULL) == NULL) offset = 16; np->intrs[i].line = irq[0] + offset; if (n > 1) np->intrs[i].sense = irq[1]; if (n > 2) { printk("hmmm, got %d intr cells for %s:", n, np->full_name); for (j = 0; j < n; ++j) printk(" %d", irq[j]); printk("\n"); } ints += intrcells; } return mem_start; }