void __init sh7372_init_irq(void) { void __iomem *intevtsa; int n; intcs_ffd2 = ioremap_nocache(0xffd20000, PAGE_SIZE); intevtsa = intcs_ffd2 + 0x100; intcs_ffd5 = ioremap_nocache(0xffd50000, PAGE_SIZE); register_intc_controller(&intca_desc); register_intc_controller(&intca_irq_pins_lo_desc); register_intc_controller(&intca_irq_pins_hi_desc); register_intc_controller(&intcs_desc); /* setup dummy cascade chip for INTCS */ n = evt2irq(0xf80); irq_alloc_desc_at(n, numa_node_id()); irq_set_chip_and_handler_name(n, &dummy_irq_chip, handle_level_irq, "level"); set_irq_flags(n, IRQF_VALID); /* yuck */ /* demux using INTEVTSA */ irq_set_handler_data(n, (void *)intevtsa); irq_set_chained_handler(n, intcs_demux); /* unmask INTCS in INTAMASK */ iowrite16(0, intcs_ffd2 + 0x104); }
/* * The shift value is now the number of bits to shift, not the number of * bits/4. This is to make it easier to read the value directly from the * datasheets. The IPR address is calculated using the ipr_offset table. */ void register_ipr_controller(struct ipr_desc *desc) { int i; desc->chip.irq_mask = disable_ipr_irq; desc->chip.irq_unmask = enable_ipr_irq; for (i = 0; i < desc->nr_irqs; i++) { struct ipr_data *p = desc->ipr_data + i; int res; BUG_ON(p->ipr_idx >= desc->nr_offsets); BUG_ON(!desc->ipr_offsets[p->ipr_idx]); res = irq_alloc_desc_at(p->irq, numa_node_id()); if (unlikely(res != p->irq && res != -EEXIST)) { printk(KERN_INFO "can not get irq_desc for %d\n", p->irq); continue; } disable_irq_nosync(p->irq); irq_set_chip_and_handler_name(p->irq, &desc->chip, handle_level_irq, "level"); irq_set_chip_data(p->irq, p); disable_ipr_irq(irq_get_irq_data(p->irq)); } }
/* * Dynamic IRQ allocation and deallocation */ unsigned int create_irq_nr(unsigned int irq_want, int node) { int irq = irq_alloc_desc_at(irq_want, node); if (irq < 0) return 0; activate_irq(irq); return irq; }
/* * Interrupt descriptors are allocated as-needed, but low-numbered ones are * reserved by the generic x86 code. So we ignore irq_alloc_desc_at if it * tells us the irq is already used: other errors (ie. ENOMEM) we take * seriously. */ int lguest_setup_irq(unsigned int irq) { int err; /* Returns -ve error or vector number. */ err = irq_alloc_desc_at(irq, 0); if (err < 0 && err != -EEXIST) return err; irq_set_chip_and_handler_name(irq, &lguest_irq_controller, handle_level_irq, "level"); return 0; }
/* * With CONFIG_SPARSE_IRQ, interrupt descriptors are allocated as-needed, so * rather than set them in lguest_init_IRQ we are called here every time an * lguest device needs an interrupt. * * FIXME: irq_alloc_desc_at() can fail due to lack of memory, we should * pass that up! */ void lguest_setup_irq(unsigned int irq) { irq_alloc_desc_at(irq, 0); irq_set_chip_and_handler_name(irq, &lguest_irq_controller, handle_level_irq, "level"); }