From f9551a9c083b8acc1db38e234a630655bae8e771 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 24 Nov 2015 15:49:40 +0100 Subject: irqchip/renesas-intc-irqpin: Remove obsolete platform data support Since commit 4baadb9e05c68962 ("ARM: shmobile: r8a7778: remove obsolete setup code"), all Renesas SoCs with a renesas-intc-irqpin module are only supported in generic DT-only ARM multi-platform builds. The driver doesn't need to use platform data anymore, hence remove platform data configuration. Signed-off-by: Geert Uytterhoeven Acked-by: Marc Zyngier Acked-by: Thomas Gleixner Link: https://lkml.kernel.org/r/1448376581-9202-2-git-send-email-geert+renesas@glider.be Signed-off-by: Jason Cooper --- drivers/irqchip/irq-renesas-intc-irqpin.c | 38 ++++++++++--------------------- 1 file changed, 12 insertions(+), 26 deletions(-) (limited to 'drivers/irqchip') diff --git a/drivers/irqchip/irq-renesas-intc-irqpin.c b/drivers/irqchip/irq-renesas-intc-irqpin.c index c325806561be..7aefa500d210 100644 --- a/drivers/irqchip/irq-renesas-intc-irqpin.c +++ b/drivers/irqchip/irq-renesas-intc-irqpin.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #define INTC_IRQPIN_MAX 8 /* maximum 8 interrupts per driver instance */ @@ -75,7 +74,7 @@ struct intc_irqpin_irq { struct intc_irqpin_priv { struct intc_irqpin_iomem iomem[INTC_IRQPIN_REG_NR]; struct intc_irqpin_irq irq[INTC_IRQPIN_MAX]; - struct renesas_intc_irqpin_config config; + unsigned int sense_bitfield_width; unsigned int number_of_irqs; struct platform_device *pdev; struct irq_chip irq_chip; @@ -171,7 +170,7 @@ static void intc_irqpin_mask_unmask_prio(struct intc_irqpin_priv *p, static int intc_irqpin_set_sense(struct intc_irqpin_priv *p, int irq, int value) { /* The SENSE register is assumed to be 32-bit. */ - int bitfield_width = p->config.sense_bitfield_width; + int bitfield_width = p->sense_bitfield_width; int shift = 32 - (irq + 1) * bitfield_width; dev_dbg(&p->pdev->dev, "sense irq = %d, mode = %d\n", irq, value); @@ -378,7 +377,6 @@ MODULE_DEVICE_TABLE(of, intc_irqpin_dt_ids); static int intc_irqpin_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; - struct renesas_intc_irqpin_config *pdata = dev->platform_data; const struct of_device_id *of_id; struct intc_irqpin_priv *p; struct intc_irqpin_iomem *i; @@ -388,6 +386,7 @@ static int intc_irqpin_probe(struct platform_device *pdev) void (*enable_fn)(struct irq_data *d); void (*disable_fn)(struct irq_data *d); const char *name = dev_name(dev); + bool control_parent; int ref_irq; int ret; int k; @@ -399,16 +398,11 @@ static int intc_irqpin_probe(struct platform_device *pdev) } /* deal with driver instance configuration */ - if (pdata) { - memcpy(&p->config, pdata, sizeof(*pdata)); - } else { - of_property_read_u32(dev->of_node, "sense-bitfield-width", - &p->config.sense_bitfield_width); - p->config.control_parent = of_property_read_bool(dev->of_node, - "control-parent"); - } - if (!p->config.sense_bitfield_width) - p->config.sense_bitfield_width = 4; /* default to 4 bits */ + of_property_read_u32(dev->of_node, "sense-bitfield-width", + &p->sense_bitfield_width); + control_parent = of_property_read_bool(dev->of_node, "control-parent"); + if (!p->sense_bitfield_width) + p->sense_bitfield_width = 4; /* default to 4 bits */ p->pdev = pdev; platform_set_drvdata(pdev, p); @@ -515,7 +509,7 @@ static int intc_irqpin_probe(struct platform_device *pdev) } /* use more severe masking method if requested */ - if (p->config.control_parent) { + if (control_parent) { enable_fn = intc_irqpin_irq_enable_force; disable_fn = intc_irqpin_irq_disable_force; } else if (!p->shared_irqs) { @@ -534,10 +528,9 @@ static int intc_irqpin_probe(struct platform_device *pdev) irq_chip->irq_set_wake = intc_irqpin_irq_set_wake; irq_chip->flags = IRQCHIP_MASK_ON_SUSPEND; - p->irq_domain = irq_domain_add_simple(dev->of_node, - p->number_of_irqs, - p->config.irq_base, - &intc_irqpin_irq_domain_ops, p); + p->irq_domain = irq_domain_add_simple(dev->of_node, p->number_of_irqs, + 0, &intc_irqpin_irq_domain_ops, + p); if (!p->irq_domain) { ret = -ENXIO; dev_err(dev, "cannot initialize irq domain\n"); @@ -572,13 +565,6 @@ static int intc_irqpin_probe(struct platform_device *pdev) dev_info(dev, "driving %d irqs\n", p->number_of_irqs); - /* warn in case of mismatch if irq base is specified */ - if (p->config.irq_base) { - if (p->config.irq_base != p->irq[0].domain_irq) - dev_warn(dev, "irq base mismatch (%d/%d)\n", - p->config.irq_base, p->irq[0].domain_irq); - } - return 0; err1: -- cgit v1.2.3 From 1affe5946f7293b3747bfe7ef25dc5cfe9869012 Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 24 Nov 2015 15:49:41 +0100 Subject: irqchip/renesas-intc-irqpin: Remove intc_irqpin_priv.number_of_irqs intc_irqpin_priv.number_of_irqs is used inside intc_irqpin_probe() only, so it can just become a local variable. Signed-off-by: Geert Uytterhoeven Acked-by: Marc Zyngier Acked-by: Thomas Gleixner Link: https://lkml.kernel.org/r/1448376581-9202-3-git-send-email-geert+renesas@glider.be Signed-off-by: Jason Cooper --- drivers/irqchip/irq-renesas-intc-irqpin.c | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'drivers/irqchip') diff --git a/drivers/irqchip/irq-renesas-intc-irqpin.c b/drivers/irqchip/irq-renesas-intc-irqpin.c index 7aefa500d210..7f6cf19aa6ac 100644 --- a/drivers/irqchip/irq-renesas-intc-irqpin.c +++ b/drivers/irqchip/irq-renesas-intc-irqpin.c @@ -75,7 +75,6 @@ struct intc_irqpin_priv { struct intc_irqpin_iomem iomem[INTC_IRQPIN_REG_NR]; struct intc_irqpin_irq irq[INTC_IRQPIN_MAX]; unsigned int sense_bitfield_width; - unsigned int number_of_irqs; struct platform_device *pdev; struct irq_chip irq_chip; struct irq_domain *irq_domain; @@ -387,6 +386,7 @@ static int intc_irqpin_probe(struct platform_device *pdev) void (*disable_fn)(struct irq_data *d); const char *name = dev_name(dev); bool control_parent; + unsigned int nirqs; int ref_irq; int ret; int k; @@ -437,8 +437,8 @@ static int intc_irqpin_probe(struct platform_device *pdev) p->irq[k].requested_irq = irq->start; } - p->number_of_irqs = k; - if (p->number_of_irqs < 1) { + nirqs = k; + if (nirqs < 1) { dev_err(dev, "not enough IRQ resources\n"); ret = -EINVAL; goto err0; @@ -492,7 +492,7 @@ static int intc_irqpin_probe(struct platform_device *pdev) } /* mask all interrupts using priority */ - for (k = 0; k < p->number_of_irqs; k++) + for (k = 0; k < nirqs; k++) intc_irqpin_mask_unmask_prio(p, k, 1); /* clear all pending interrupts */ @@ -501,7 +501,7 @@ static int intc_irqpin_probe(struct platform_device *pdev) /* scan for shared interrupt lines */ ref_irq = p->irq[0].requested_irq; p->shared_irqs = true; - for (k = 1; k < p->number_of_irqs; k++) { + for (k = 1; k < nirqs; k++) { if (ref_irq != p->irq[k].requested_irq) { p->shared_irqs = false; break; @@ -528,9 +528,8 @@ static int intc_irqpin_probe(struct platform_device *pdev) irq_chip->irq_set_wake = intc_irqpin_irq_set_wake; irq_chip->flags = IRQCHIP_MASK_ON_SUSPEND; - p->irq_domain = irq_domain_add_simple(dev->of_node, p->number_of_irqs, - 0, &intc_irqpin_irq_domain_ops, - p); + p->irq_domain = irq_domain_add_simple(dev->of_node, nirqs, 0, + &intc_irqpin_irq_domain_ops, p); if (!p->irq_domain) { ret = -ENXIO; dev_err(dev, "cannot initialize irq domain\n"); @@ -548,7 +547,7 @@ static int intc_irqpin_probe(struct platform_device *pdev) } } else { /* request interrupts one by one */ - for (k = 0; k < p->number_of_irqs; k++) { + for (k = 0; k < nirqs; k++) { if (devm_request_irq(dev, p->irq[k].requested_irq, intc_irqpin_irq_handler, 0, name, &p->irq[k])) { @@ -560,10 +559,10 @@ static int intc_irqpin_probe(struct platform_device *pdev) } /* unmask all interrupts on prio level */ - for (k = 0; k < p->number_of_irqs; k++) + for (k = 0; k < nirqs; k++) intc_irqpin_mask_unmask_prio(p, k, 0); - dev_info(dev, "driving %d irqs\n", p->number_of_irqs); + dev_info(dev, "driving %d irqs\n", nirqs); return 0; -- cgit v1.2.3 From 86e57ca735a72b44aab90a649157a678b7069a6d Mon Sep 17 00:00:00 2001 From: Geert Uytterhoeven Date: Tue, 24 Nov 2015 16:08:13 +0100 Subject: irqchip/renesas-intc-irqpin: Improve clock error handling and reporting If the Renesas External IRQ Pin driver cannot find a functional clock, it prints a warning, .e.g. renesas_intc_irqpin fe78001c.interrupt-controller: unable to get clock and continues, as the clock is optional, depending on the SoC type. This warning may confuse users. To fix this, add a flag to indicate that the clock is mandatory or optional, and add a few more compatible entries: - If the clock is mandatory (on R-Mobile A1 or SH-Mobile AG5), a missing clock is now treated as a fatal error, - If the clock is optional (on R-Car Gen1, or using the generic "renesas,intc-irqpin" compatible value), the warning is no longer printed. This requires making struct intc_irqpin_irlm_config more generic by renaming it to intc_irqpin_config, and adding a flag to indicate if IRLM is needed. The new clock flag is merged with the existing shared_irqs boolean into a bitfield to save space. Suggested-by: Magnus Damm Signed-off-by: Geert Uytterhoeven Link: https://lkml.kernel.org/r/1448377693-19597-1-git-send-email-geert+renesas@glider.be Signed-off-by: Jason Cooper --- drivers/irqchip/irq-renesas-intc-irqpin.c | 45 ++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 12 deletions(-) (limited to 'drivers/irqchip') diff --git a/drivers/irqchip/irq-renesas-intc-irqpin.c b/drivers/irqchip/irq-renesas-intc-irqpin.c index 7f6cf19aa6ac..713177d97c7a 100644 --- a/drivers/irqchip/irq-renesas-intc-irqpin.c +++ b/drivers/irqchip/irq-renesas-intc-irqpin.c @@ -79,12 +79,15 @@ struct intc_irqpin_priv { struct irq_chip irq_chip; struct irq_domain *irq_domain; struct clk *clk; - bool shared_irqs; + unsigned shared_irqs:1; + unsigned needs_clk:1; u8 shared_irq_mask; }; -struct intc_irqpin_irlm_config { +struct intc_irqpin_config { unsigned int irlm_bit; + unsigned needs_irlm:1; + unsigned needs_clk:1; }; static unsigned long intc_irqpin_read32(void __iomem *iomem) @@ -359,8 +362,15 @@ static const struct irq_domain_ops intc_irqpin_irq_domain_ops = { .xlate = irq_domain_xlate_twocell, }; -static const struct intc_irqpin_irlm_config intc_irqpin_irlm_r8a777x = { +static const struct intc_irqpin_config intc_irqpin_irlm_r8a777x = { .irlm_bit = 23, /* ICR0.IRLM0 */ + .needs_irlm = 1, + .needs_clk = 0, +}; + +static const struct intc_irqpin_config intc_irqpin_rmobile = { + .needs_irlm = 0, + .needs_clk = 1, }; static const struct of_device_id intc_irqpin_dt_ids[] = { @@ -369,12 +379,17 @@ static const struct of_device_id intc_irqpin_dt_ids[] = { .data = &intc_irqpin_irlm_r8a777x }, { .compatible = "renesas,intc-irqpin-r8a7779", .data = &intc_irqpin_irlm_r8a777x }, + { .compatible = "renesas,intc-irqpin-r8a7740", + .data = &intc_irqpin_rmobile }, + { .compatible = "renesas,intc-irqpin-sh73a0", + .data = &intc_irqpin_rmobile }, {}, }; MODULE_DEVICE_TABLE(of, intc_irqpin_dt_ids); static int intc_irqpin_probe(struct platform_device *pdev) { + const struct intc_irqpin_config *config = NULL; struct device *dev = &pdev->dev; const struct of_device_id *of_id; struct intc_irqpin_priv *p; @@ -407,9 +422,19 @@ static int intc_irqpin_probe(struct platform_device *pdev) p->pdev = pdev; platform_set_drvdata(pdev, p); + of_id = of_match_device(intc_irqpin_dt_ids, dev); + if (of_id && of_id->data) { + config = of_id->data; + p->needs_clk = config->needs_clk; + } + p->clk = devm_clk_get(dev, NULL); if (IS_ERR(p->clk)) { - dev_warn(dev, "unable to get clock\n"); + if (p->needs_clk) { + dev_err(dev, "unable to get clock\n"); + ret = PTR_ERR(p->clk); + goto err0; + } p->clk = NULL; } @@ -479,14 +504,10 @@ static int intc_irqpin_probe(struct platform_device *pdev) } /* configure "individual IRQ mode" where needed */ - of_id = of_match_device(intc_irqpin_dt_ids, dev); - if (of_id && of_id->data) { - const struct intc_irqpin_irlm_config *irlm_config = of_id->data; - + if (config && config->needs_irlm) { if (io[INTC_IRQPIN_REG_IRLM]) intc_irqpin_read_modify_write(p, INTC_IRQPIN_REG_IRLM, - irlm_config->irlm_bit, - 1, 1); + config->irlm_bit, 1, 1); else dev_warn(dev, "unable to select IRLM mode\n"); } @@ -500,10 +521,10 @@ static int intc_irqpin_probe(struct platform_device *pdev) /* scan for shared interrupt lines */ ref_irq = p->irq[0].requested_irq; - p->shared_irqs = true; + p->shared_irqs = 1; for (k = 1; k < nirqs; k++) { if (ref_irq != p->irq[k].requested_irq) { - p->shared_irqs = false; + p->shared_irqs = 0; break; } } -- cgit v1.2.3 From bbbb03c1a82eea24e9b15b2f96ecb0cc882ddd2c Mon Sep 17 00:00:00 2001 From: Chen-Yu Tsai Date: Thu, 3 Dec 2015 16:20:12 +0800 Subject: irqchip/sunxi-nmi: Support sun9i A80 NMI controller The A80 moves the NMI controller into the PRCM address space, and also rearranges the registers. Signed-off-by: Chen-Yu Tsai Acked-by: Maxime Ripard Reviewed-by: Hans de Goede Link: https://lkml.kernel.org/r/1449130813-22400-4-git-send-email-wens@csie.org Signed-off-by: Jason Cooper --- drivers/irqchip/irq-sunxi-nmi.c | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'drivers/irqchip') diff --git a/drivers/irqchip/irq-sunxi-nmi.c b/drivers/irqchip/irq-sunxi-nmi.c index 4ef178078e5b..0820f67cc9a7 100644 --- a/drivers/irqchip/irq-sunxi-nmi.c +++ b/drivers/irqchip/irq-sunxi-nmi.c @@ -50,6 +50,12 @@ static struct sunxi_sc_nmi_reg_offs sun6i_reg_offs = { .enable = 0x34, }; +static struct sunxi_sc_nmi_reg_offs sun9i_reg_offs = { + .ctrl = 0x00, + .pend = 0x08, + .enable = 0x04, +}; + static inline void sunxi_sc_nmi_write(struct irq_chip_generic *gc, u32 off, u32 val) { @@ -207,3 +213,10 @@ static int __init sun7i_sc_nmi_irq_init(struct device_node *node, return sunxi_sc_nmi_irq_init(node, &sun7i_reg_offs); } IRQCHIP_DECLARE(sun7i_sc_nmi, "allwinner,sun7i-a20-sc-nmi", sun7i_sc_nmi_irq_init); + +static int __init sun9i_nmi_irq_init(struct device_node *node, + struct device_node *parent) +{ + return sunxi_sc_nmi_irq_init(node, &sun9i_reg_offs); +} +IRQCHIP_DECLARE(sun9i_nmi, "allwinner,sun9i-a80-nmi", sun9i_nmi_irq_init); -- cgit v1.2.3