On Mon, Oct 30 2017 at 12:56:33 pm GMT, Aleksandar Markovic <aleksandar.markovic@xxxxxxxxx> wrote: > From: Miodrag Dinic <miodrag.dinic@xxxxxxxx> > > Add device driver for a virtual programmable interrupt controller > > The virtual PIC is designed as a device tree-based interrupt controller. > > The compatible string used by OS for binding the driver is > "google,goldfish-pic". > > Signed-off-by: Miodrag Dinic <miodrag.dinic@xxxxxxxx> > Signed-off-by: Goran Ferenc <goran.ferenc@xxxxxxxx> > Signed-off-by: Aleksandar Markovic <aleksandar.markovic@xxxxxxxx> [...] > diff --git a/drivers/irqchip/irq-goldfish-pic.c b/drivers/irqchip/irq-goldfish-pic.c > new file mode 100644 > index 0000000..48fb773 > --- /dev/null > +++ b/drivers/irqchip/irq-goldfish-pic.c [...] > +static int __init goldfish_pic_of_init(struct device_node *of_node, > + struct device_node *parent) > +{ > + struct goldfish_pic_data *gfpic; > + struct irq_chip_generic *gc; > + struct irq_chip_type *ct; > + unsigned int parent_irq; > + int ret = 0; > + > + gfpic = kzalloc(sizeof(*gfpic), GFP_KERNEL); > + if (!gfpic) { > + ret = -ENOMEM; > + goto out_err; > + } > + > + parent_irq = irq_of_parse_and_map(of_node, 0); > + if (!parent_irq) { > + pr_err("Failed to map Goldfish PIC parent IRQ\n"); > + ret = -EINVAL; > + goto out_free; > + } > + > + gfpic->base = of_iomap(of_node, 0); > + if (!gfpic->base) { > + pr_err("Failed to map Goldfish PIC base\n"); > + ret = -ENOMEM; > + goto out_unmap_irq; > + } > + > + /* Mask interrupts. */ > + writel(1, gfpic->base + GFPIC_REG_IRQ_DISABLE_ALL); > + > + gc = irq_alloc_generic_chip("GFPIC", 1, GFPIC_IRQ_BASE, gfpic->base, > + handle_level_irq); > + > + ct = gc->chip_types; And what if the allocation fails? > + ct->regs.enable = GFPIC_REG_IRQ_ENABLE; > + ct->regs.disable = GFPIC_REG_IRQ_DISABLE; > + ct->chip.irq_unmask = irq_gc_unmask_enable_reg; > + ct->chip.irq_mask = irq_gc_mask_disable_reg; > + > + irq_setup_generic_chip(gc, IRQ_MSK(GFPIC_NR_IRQS), 0, 0, > + IRQ_NOPROBE | IRQ_LEVEL); > + > + gfpic->irq_domain = irq_domain_add_legacy(of_node, GFPIC_NR_IRQS, > + GFPIC_IRQ_BASE, 0, > + &goldfish_irq_domain_ops, > + NULL); > + if (!gfpic->irq_domain) { > + pr_err("Failed to add irqdomain for Goldfish PIC\n"); > + ret = -EINVAL; > + goto out_iounmap; > + } > + > + irq_set_chained_handler_and_data(parent_irq, > + goldfish_pic_cascade, gfpic); > + > + pr_info("Successfully registered Goldfish PIC\n"); > + return 0; > + > +out_iounmap: > + iounmap(gfpic->base); > +out_unmap_irq: > + irq_dispose_mapping(parent_irq); > +out_free: > + kfree(gfpic); > +out_err: > + return ret; > +} > + > +IRQCHIP_DECLARE(google_gf_pic, "google,goldfish-pic", goldfish_pic_of_init); Thanks, M. -- Jazz is not dead. It just smells funny.