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; } }
/* * Initialize handlers for the set of interrupts caused by hardware errors * and power system events. */ static int __init init_ras_IRQ(void) { struct device_node *np; unsigned int *ireg, len, i; int virq; if ((np = of_find_node_by_path("/event-sources/internal-errors")) && (ireg = (unsigned int *)get_property(np, "open-pic-interrupt", &len))) { for (i=0; i<(len / sizeof(*ireg)); 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); break; } request_irq(irq_offset_up(virq), ras_error_interrupt, 0, "RAS_ERROR", NULL); ireg++; } } of_node_put(np); if ((np = of_find_node_by_path("/event-sources/epow-events")) && (ireg = (unsigned int *)get_property(np, "open-pic-interrupt", &len))) { for (i=0; i<(len / sizeof(*ireg)); 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); break; } request_irq(irq_offset_up(virq), ras_epow_interrupt, 0, "RAS_EPOW", NULL); ireg++; } } of_node_put(np); return 1; }
static int __init hvsi_console_init(void) { struct device_node *vty; hvsi_wait = poll_for_state; /* no irqs yet; must poll */ /* search device tree for vty nodes */ for (vty = of_find_compatible_node(NULL, "serial", "hvterm-protocol"); vty != NULL; vty = of_find_compatible_node(vty, "serial", "hvterm-protocol")) { struct hvsi_struct *hp; uint32_t *vtermno; uint32_t *irq; vtermno = (uint32_t *)get_property(vty, "reg", NULL); irq = (uint32_t *)get_property(vty, "interrupts", NULL); if (!vtermno || !irq) continue; if (hvsi_count >= MAX_NR_HVSI_CONSOLES) { of_node_put(vty); break; } hp = &hvsi_ports[hvsi_count]; INIT_WORK(&hp->writer, hvsi_write_worker, hp); INIT_WORK(&hp->handshaker, hvsi_handshaker, hp); init_waitqueue_head(&hp->emptyq); init_waitqueue_head(&hp->stateq); spin_lock_init(&hp->lock); hp->index = hvsi_count; hp->inbuf_end = hp->inbuf; hp->state = HVSI_CLOSED; hp->vtermno = *vtermno; hp->virq = virt_irq_create_mapping(irq[0]); if (hp->virq == NO_IRQ) { printk(KERN_ERR "%s: couldn't create irq mapping for 0x%x\n", __FUNCTION__, hp->virq); continue; } else hp->virq = irq_offset_up(hp->virq); hvsi_count++; } if (hvsi_count) register_console(&hvsi_con_driver); return 0; }