diff options
Diffstat (limited to 'drivers/irqchip/irq-renesas-irqc.c')
-rw-r--r-- | drivers/irqchip/irq-renesas-irqc.c | 91 |
1 files changed, 32 insertions, 59 deletions
diff --git a/drivers/irqchip/irq-renesas-irqc.c b/drivers/irqchip/irq-renesas-irqc.c index a449a7c839b3..11abc09ef76c 100644 --- a/drivers/irqchip/irq-renesas-irqc.c +++ b/drivers/irqchip/irq-renesas-irqc.c @@ -7,7 +7,6 @@ #include <linux/init.h> #include <linux/platform_device.h> -#include <linux/spinlock.h> #include <linux/interrupt.h> #include <linux/ioport.h> #include <linux/io.h> @@ -48,7 +47,7 @@ struct irqc_priv { void __iomem *cpu_int_base; struct irqc_irq irq[IRQC_IRQ_MAX]; unsigned int number_of_irqs; - struct platform_device *pdev; + struct device *dev; struct irq_chip_generic *gc; struct irq_domain *irq_domain; atomic_t wakeup_path; @@ -61,8 +60,7 @@ static struct irqc_priv *irq_data_to_priv(struct irq_data *data) static void irqc_dbg(struct irqc_irq *i, char *str) { - dev_dbg(&i->p->pdev->dev, "%s (%d:%d)\n", - str, i->requested_irq, i->hw_irq); + dev_dbg(i->p->dev, "%s (%d:%d)\n", str, i->requested_irq, i->hw_irq); } static unsigned char irqc_sense[IRQ_TYPE_SENSE_MASK + 1] = { @@ -125,33 +123,22 @@ static irqreturn_t irqc_irq_handler(int irq, void *dev_id) static int irqc_probe(struct platform_device *pdev) { + struct device *dev = &pdev->dev; + const char *name = dev_name(dev); struct irqc_priv *p; - struct resource *io; struct resource *irq; - const char *name = dev_name(&pdev->dev); int ret; int k; - p = kzalloc(sizeof(*p), GFP_KERNEL); - if (!p) { - dev_err(&pdev->dev, "failed to allocate driver data\n"); - ret = -ENOMEM; - goto err0; - } + p = devm_kzalloc(dev, sizeof(*p), GFP_KERNEL); + if (!p) + return -ENOMEM; - p->pdev = pdev; + p->dev = dev; platform_set_drvdata(pdev, p); - pm_runtime_enable(&pdev->dev); - pm_runtime_get_sync(&pdev->dev); - - /* get hold of manadatory IOMEM */ - io = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!io) { - dev_err(&pdev->dev, "not enough IOMEM resources\n"); - ret = -EINVAL; - goto err1; - } + pm_runtime_enable(dev); + pm_runtime_get_sync(dev); /* allow any number of IRQs between 1 and IRQC_IRQ_MAX */ for (k = 0; k < IRQC_IRQ_MAX; k++) { @@ -166,42 +153,41 @@ static int irqc_probe(struct platform_device *pdev) p->number_of_irqs = k; if (p->number_of_irqs < 1) { - dev_err(&pdev->dev, "not enough IRQ resources\n"); + dev_err(dev, "not enough IRQ resources\n"); ret = -EINVAL; - goto err1; + goto err_runtime_pm_disable; } /* ioremap IOMEM and setup read/write callbacks */ - p->iomem = ioremap_nocache(io->start, resource_size(io)); - if (!p->iomem) { - dev_err(&pdev->dev, "failed to remap IOMEM\n"); - ret = -ENXIO; - goto err2; + p->iomem = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(p->iomem)) { + ret = PTR_ERR(p->iomem); + goto err_runtime_pm_disable; } p->cpu_int_base = p->iomem + IRQC_INT_CPU_BASE(0); /* SYS-SPI */ - p->irq_domain = irq_domain_add_linear(pdev->dev.of_node, - p->number_of_irqs, + p->irq_domain = irq_domain_add_linear(dev->of_node, p->number_of_irqs, &irq_generic_chip_ops, p); if (!p->irq_domain) { ret = -ENXIO; - dev_err(&pdev->dev, "cannot initialize irq domain\n"); - goto err2; + dev_err(dev, "cannot initialize irq domain\n"); + goto err_runtime_pm_disable; } ret = irq_alloc_domain_generic_chips(p->irq_domain, p->number_of_irqs, - 1, name, handle_level_irq, + 1, "irqc", handle_level_irq, 0, 0, IRQ_GC_INIT_NESTED_LOCK); if (ret) { - dev_err(&pdev->dev, "cannot allocate generic chip\n"); - goto err3; + dev_err(dev, "cannot allocate generic chip\n"); + goto err_remove_domain; } p->gc = irq_get_domain_generic_chip(p->irq_domain, 0); p->gc->reg_base = p->cpu_int_base; p->gc->chip_types[0].regs.enable = IRQC_EN_SET; p->gc->chip_types[0].regs.disable = IRQC_EN_STS; + p->gc->chip_types[0].chip.parent_device = dev; p->gc->chip_types[0].chip.irq_mask = irq_gc_mask_disable_reg; p->gc->chip_types[0].chip.irq_unmask = irq_gc_unmask_enable_reg; p->gc->chip_types[0].chip.irq_set_type = irqc_irq_set_type; @@ -210,46 +196,33 @@ static int irqc_probe(struct platform_device *pdev) /* request interrupts one by one */ for (k = 0; k < p->number_of_irqs; k++) { - if (request_irq(p->irq[k].requested_irq, irqc_irq_handler, - 0, name, &p->irq[k])) { - dev_err(&pdev->dev, "failed to request IRQ\n"); + if (devm_request_irq(dev, p->irq[k].requested_irq, + irqc_irq_handler, 0, name, &p->irq[k])) { + dev_err(dev, "failed to request IRQ\n"); ret = -ENOENT; - goto err4; + goto err_remove_domain; } } - dev_info(&pdev->dev, "driving %d irqs\n", p->number_of_irqs); + dev_info(dev, "driving %d irqs\n", p->number_of_irqs); return 0; -err4: - while (--k >= 0) - free_irq(p->irq[k].requested_irq, &p->irq[k]); -err3: +err_remove_domain: irq_domain_remove(p->irq_domain); -err2: - iounmap(p->iomem); -err1: - pm_runtime_put(&pdev->dev); - pm_runtime_disable(&pdev->dev); - kfree(p); -err0: +err_runtime_pm_disable: + pm_runtime_put(dev); + pm_runtime_disable(dev); return ret; } static int irqc_remove(struct platform_device *pdev) { struct irqc_priv *p = platform_get_drvdata(pdev); - int k; - - for (k = 0; k < p->number_of_irqs; k++) - free_irq(p->irq[k].requested_irq, &p->irq[k]); irq_domain_remove(p->irq_domain); - iounmap(p->iomem); pm_runtime_put(&pdev->dev); pm_runtime_disable(&pdev->dev); - kfree(p); return 0; } |