unsigned int irq_of_parse_and_map(struct device_node *dev, int index)
struct of_irq oirq;
of_irq_map_one(dev, index, &oirq)
return irq_create_of_mapping(oirq.controller, oirq.specifier, oirq.size);
=>unsigned int irq_create_of_mapping(struct device_node *controller, const u32 *intspec, unsigned int intsize)
host = irq_find_host(controller);
host->ops->xlate(host, controller, intspec, intsize, &hwirq, &type))
/* Create mapping */
virq = irq_create_mapping(host, hwirq);
=>unsigned int irq_create_mapping(struct irq_host *host, irq_hw_number_t hwirq)
/* Check if mapping already exist, if it does, call
* host->ops->map() to update the flags
*/
virq = irq_find_mapping(host, hwirq);
if (virq != NO_IRQ) {
if (host->ops->remap)
host->ops->remap(host, virq, hwirq);
pr_debug("irq: -> existing mapping on virq %d\n", virq);
return virq;
}
/* Allocate a virtual interrupt number */
hint = hwirq % irq_virq_count;
virq = irq_alloc_virt(host, 1, hint);
irq_setup_virq(host, virq, hwirq)
=>int irq_setup_virq(struct irq_host *host, unsigned int virq, irq_hw_number_t hwirq)
struct irq_desc *desc = irq_to_desc_alloc_node(virq, 0);
/* Clear IRQ_NOREQUEST flag */
desc->status &= ~IRQ_NOREQUEST;
/* map it */
smp_wmb();
irq_map[virq].hwirq = hwirq;
smp_mb();
host->ops->map(host, virq, hwirq)
=>static struct irq_host_ops mpic_host_ops = {//在irq_alloc_host里面设置
.match = mpic_host_match,
.map = mpic_host_map,
.xlate = mpic_host_xlate,
};
=>int mpic_host_map(struct irq_host *h, unsigned int virq, irq_hw_number_t hw)
struct mpic *mpic = h->host_data;
struct irq_chip *chip;
set_irq_chip_data(virq, mpic);
set_irq_chip_and_handler(virq, chip, handle_fasteoi_irq);//设置中断处理函数
/* Set default irq type */
set_irq_type(virq, IRQ_TYPE_NONE);
return 0;
return virq;
/* Set type if specified and different than the current one */
if (type != IRQ_TYPE_NONE &&
type != (irq_to_desc(virq)->status & IRQF_TRIGGER_MASK))
set_irq_type(virq, type);
return virq;