From: Alban <albeu@free.fr>
To: Marc Zyngier <marc.zyngier@arm.com>
Cc: Aban Bedel <albeu@free.fr>, <linux-mips@linux-mips.org>,
Ralf Baechle <ralf@linux-mips.org>,
Thomas Gleixner <tglx@linutronix.de>,
Jason Cooper <jason@lakedaemon.net>,
Alexander Couzens <lynxis@fe80.eu>,
Joel Porquet <joel@porquet.org>,
"Andrew Bresticker" <abrestic@chromium.org>,
<linux-kernel@vger.kernel.org>
Subject: Re: [PATCH 4/6] MIPS: ath79: irq: Move the MISC driver to drivers/irqchip
Date: Wed, 20 Jan 2016 20:51:13 +0100 [thread overview]
Message-ID: <20160120205113.4b706e2f@tock> (raw)
In-Reply-To: <20160120123841.039345ad@sofa.wild-wind.fr.eu.org>
On Wed, 20 Jan 2016 12:38:41 +0000
Marc Zyngier <marc.zyngier@arm.com> wrote:
> On Tue, 17 Nov 2015 20:34:54 +0100
> Alban Bedel <albeu@free.fr> wrote:
>
> Hi Alban,
>
> > The driver stays the same but the initialization changes a bit.
> > For OF boards we now get the memory map from the OF node and use
> > a linear mapping instead of the legacy mapping. For legacy boards
> > we still use a legacy mapping and just pass down all the parameters
> > from the board init code.
> >
> > Signed-off-by: Alban Bedel <albeu@free.fr>
> > ---
> > arch/mips/ath79/irq.c | 163 +++------------------------
> > arch/mips/include/asm/mach-ath79/ath79.h | 3 +
> > drivers/irqchip/Makefile | 1 +
> > drivers/irqchip/irq-ath79-misc.c | 182 +++++++++++++++++++++++++++++++
> > 4 files changed, 201 insertions(+), 148 deletions(-)
> > create mode 100644 drivers/irqchip/irq-ath79-misc.c
> >
>
> [...]
>
> > diff --git a/drivers/irqchip/irq-ath79-misc.c b/drivers/irqchip/irq-ath79-misc.c
> > new file mode 100644
> > index 0000000..bd2121f1
> > --- /dev/null
> > +++ b/drivers/irqchip/irq-ath79-misc.c
> > @@ -0,0 +1,182 @@
> > +/*
> > + * Atheros AR71xx/AR724x/AR913x MISC interrupt controller
> > + *
> > + * Copyright (C) 2015 Alban Bedel <albeu@free.fr>
> > + * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
> > + * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
> > + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
> > + *
> > + * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
> > + *
> > + * This program is free software; you can redistribute it and/or modify it
> > + * under the terms of the GNU General Public License version 2 as published
> > + * by the Free Software Foundation.
> > + */
> > +
> > +#include <linux/irqchip.h>
> > +#include <linux/of_address.h>
> > +#include <linux/of_irq.h>
> > +
> > +#define AR71XX_RESET_REG_MISC_INT_STATUS 0
> > +#define AR71XX_RESET_REG_MISC_INT_ENABLE 4
> > +
> > +#define ATH79_MISC_IRQ_COUNT 32
> > +
> > +static void ath79_misc_irq_handler(struct irq_desc *desc)
> > +{
> > + struct irq_domain *domain = irq_desc_get_handler_data(desc);
> > + void __iomem *base = domain->host_data;
> > + u32 pending;
> > +
> > + pending = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS) &
> > + __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
> > +
> > + if (!pending) {
> > + spurious_interrupt();
> > + return;
> > + }
> > +
> > + while (pending) {
> > + int bit = __ffs(pending);
> > +
> > + generic_handle_irq(irq_linear_revmap(domain, bit));
> > + pending &= ~BIT(bit);
> > + }
> > +}
>
> Given that this function is used as a chained handler, it seems to be
> missing the usual chained_irq_enter/exit...
I'll fix this.
> > +
> > +static void ar71xx_misc_irq_unmask(struct irq_data *d)
> > +{
> > + void __iomem *base = irq_data_get_irq_chip_data(d);
> > + unsigned int irq = d->hwirq;
> > + u32 t;
> > +
> > + t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
> > + __raw_writel(t | BIT(irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
> > +
> > + /* flush write */
> > + __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
> > +}
> > +
> > +static void ar71xx_misc_irq_mask(struct irq_data *d)
> > +{
> > + void __iomem *base = irq_data_get_irq_chip_data(d);
> > + unsigned int irq = d->hwirq;
> > + u32 t;
> > +
> > + t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
> > + __raw_writel(t & ~BIT(irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
> > +
> > + /* flush write */
> > + __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
> > +}
> > +
> > +static void ar724x_misc_irq_ack(struct irq_data *d)
> > +{
> > + void __iomem *base = irq_data_get_irq_chip_data(d);
> > + unsigned int irq = d->hwirq;
> > + u32 t;
> > +
> > + t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
> > + __raw_writel(t & ~BIT(irq), base + AR71XX_RESET_REG_MISC_INT_STATUS);
> > +
> > + /* flush write */
> > + __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
> > +}
> > +
> > +static struct irq_chip ath79_misc_irq_chip = {
> > + .name = "MISC",
> > + .irq_unmask = ar71xx_misc_irq_unmask,
> > + .irq_mask = ar71xx_misc_irq_mask,
> > +};
> > +
> > +static int misc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
> > +{
> > + irq_set_chip_and_handler(irq, &ath79_misc_irq_chip, handle_level_irq);
> > + irq_set_chip_data(irq, d->host_data);
> > + return 0;
> > +}
> > +
> > +static const struct irq_domain_ops misc_irq_domain_ops = {
> > + .xlate = irq_domain_xlate_onecell,
> > + .map = misc_map,
> > +};
> > +
> > +static void __init ath79_misc_intc_domain_init(
> > + struct irq_domain *domain, int irq)
> > +{
> > + void __iomem *base = domain->host_data;
> > +
> > + /* Disable and clear all interrupts */
> > + __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE);
> > + __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);
> > +
> > + irq_set_chained_handler_and_data(irq, ath79_misc_irq_handler, domain);
> > +}
> > +
> > +static int __init ath79_misc_intc_of_init(
> > + struct device_node *node, struct device_node *parent)
> > +{
> > + struct irq_domain *domain;
> > + void __iomem *base;
> > + int irq;
> > +
> > + irq = irq_of_parse_and_map(node, 0);
> > + if (!irq) {
> > + pr_err("Failed to get MISC IRQ\n");
> > + return -EINVAL;
> > + }
> > +
> > + base = of_iomap(node, 0);
> > + if (!base) {
> > + pr_err("Failed to get MISC IRQ registers\n");
> > + return -ENOMEM;
> > + }
> > +
> > + domain = irq_domain_add_linear(node, ATH79_MISC_IRQ_COUNT,
> > + &misc_irq_domain_ops, base);
> > + if (!domain) {
> > + pr_err("Failed to add MISC irqdomain\n");
> > + return -EINVAL;
> > + }
> > +
> > + ath79_misc_intc_domain_init(domain, irq);
> > + return 0;
> > +}
> > +
> > +static int __init ar7100_misc_intc_of_init(
> > + struct device_node *node, struct device_node *parent)
> > +{
> > + ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask;
> > + return ath79_misc_intc_of_init(node, parent);
> > +}
> > +
> > +IRQCHIP_DECLARE(ar7100_misc_intc, "qca,ar7100-misc-intc",
> > + ar7100_misc_intc_of_init);
> > +
> > +static int __init ar7240_misc_intc_of_init(
> > + struct device_node *node, struct device_node *parent)
> > +{
> > + ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack;
> > + return ath79_misc_intc_of_init(node, parent);
> > +}
> > +
> > +IRQCHIP_DECLARE(ar7240_misc_intc, "qca,ar7240-misc-intc",
> > + ar7240_misc_intc_of_init);
> > +
> > +void __init ath79_misc_irq_init(void __iomem *regs, int irq,
> > + int irq_base, bool is_ar71xx)
> > +{
> > + struct irq_domain *domain;
> > +
> > + if (is_ar71xx)
> > + ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask;
> > + else
> > + ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack;
> > +
> > + domain = irq_domain_add_legacy(NULL, ATH79_MISC_IRQ_COUNT,
> > + irq_base, 0, &misc_irq_domain_ops, regs);
> > + if (!domain)
> > + panic("Failed to create MISC irqdomain");
> > +
> > + ath79_misc_intc_domain_init(domain, irq);
> > +}
>
> Other than that, this looks OK.
>
> Thanks,
Great, thanks for the review.
Alban
WARNING: multiple messages have this Message-ID (diff)
From: Alban <albeu@free.fr>
To: Marc Zyngier <marc.zyngier@arm.com>
Cc: Aban Bedel <albeu@free.fr>,
linux-mips@linux-mips.org, Ralf Baechle <ralf@linux-mips.org>,
Thomas Gleixner <tglx@linutronix.de>,
Jason Cooper <jason@lakedaemon.net>,
Alexander Couzens <lynxis@fe80.eu>,
Joel Porquet <joel@porquet.org>,
Andrew Bresticker <abrestic@chromium.org>,
linux-kernel@vger.kernel.org
Subject: Re: [PATCH 4/6] MIPS: ath79: irq: Move the MISC driver to drivers/irqchip
Date: Wed, 20 Jan 2016 20:51:13 +0100 [thread overview]
Message-ID: <20160120205113.4b706e2f@tock> (raw)
Message-ID: <20160120195113.KyFiFJjKuawRU4ZojhzbzoPNYfe5PWIwwPDHzF5Oe9M@z> (raw)
In-Reply-To: <20160120123841.039345ad@sofa.wild-wind.fr.eu.org>
On Wed, 20 Jan 2016 12:38:41 +0000
Marc Zyngier <marc.zyngier@arm.com> wrote:
> On Tue, 17 Nov 2015 20:34:54 +0100
> Alban Bedel <albeu@free.fr> wrote:
>
> Hi Alban,
>
> > The driver stays the same but the initialization changes a bit.
> > For OF boards we now get the memory map from the OF node and use
> > a linear mapping instead of the legacy mapping. For legacy boards
> > we still use a legacy mapping and just pass down all the parameters
> > from the board init code.
> >
> > Signed-off-by: Alban Bedel <albeu@free.fr>
> > ---
> > arch/mips/ath79/irq.c | 163 +++------------------------
> > arch/mips/include/asm/mach-ath79/ath79.h | 3 +
> > drivers/irqchip/Makefile | 1 +
> > drivers/irqchip/irq-ath79-misc.c | 182 +++++++++++++++++++++++++++++++
> > 4 files changed, 201 insertions(+), 148 deletions(-)
> > create mode 100644 drivers/irqchip/irq-ath79-misc.c
> >
>
> [...]
>
> > diff --git a/drivers/irqchip/irq-ath79-misc.c b/drivers/irqchip/irq-ath79-misc.c
> > new file mode 100644
> > index 0000000..bd2121f1
> > --- /dev/null
> > +++ b/drivers/irqchip/irq-ath79-misc.c
> > @@ -0,0 +1,182 @@
> > +/*
> > + * Atheros AR71xx/AR724x/AR913x MISC interrupt controller
> > + *
> > + * Copyright (C) 2015 Alban Bedel <albeu@free.fr>
> > + * Copyright (C) 2010-2011 Jaiganesh Narayanan <jnarayanan@atheros.com>
> > + * Copyright (C) 2008-2011 Gabor Juhos <juhosg@openwrt.org>
> > + * Copyright (C) 2008 Imre Kaloz <kaloz@openwrt.org>
> > + *
> > + * Parts of this file are based on Atheros' 2.6.15/2.6.31 BSP
> > + *
> > + * This program is free software; you can redistribute it and/or modify it
> > + * under the terms of the GNU General Public License version 2 as published
> > + * by the Free Software Foundation.
> > + */
> > +
> > +#include <linux/irqchip.h>
> > +#include <linux/of_address.h>
> > +#include <linux/of_irq.h>
> > +
> > +#define AR71XX_RESET_REG_MISC_INT_STATUS 0
> > +#define AR71XX_RESET_REG_MISC_INT_ENABLE 4
> > +
> > +#define ATH79_MISC_IRQ_COUNT 32
> > +
> > +static void ath79_misc_irq_handler(struct irq_desc *desc)
> > +{
> > + struct irq_domain *domain = irq_desc_get_handler_data(desc);
> > + void __iomem *base = domain->host_data;
> > + u32 pending;
> > +
> > + pending = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS) &
> > + __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
> > +
> > + if (!pending) {
> > + spurious_interrupt();
> > + return;
> > + }
> > +
> > + while (pending) {
> > + int bit = __ffs(pending);
> > +
> > + generic_handle_irq(irq_linear_revmap(domain, bit));
> > + pending &= ~BIT(bit);
> > + }
> > +}
>
> Given that this function is used as a chained handler, it seems to be
> missing the usual chained_irq_enter/exit...
I'll fix this.
> > +
> > +static void ar71xx_misc_irq_unmask(struct irq_data *d)
> > +{
> > + void __iomem *base = irq_data_get_irq_chip_data(d);
> > + unsigned int irq = d->hwirq;
> > + u32 t;
> > +
> > + t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
> > + __raw_writel(t | BIT(irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
> > +
> > + /* flush write */
> > + __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
> > +}
> > +
> > +static void ar71xx_misc_irq_mask(struct irq_data *d)
> > +{
> > + void __iomem *base = irq_data_get_irq_chip_data(d);
> > + unsigned int irq = d->hwirq;
> > + u32 t;
> > +
> > + t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
> > + __raw_writel(t & ~BIT(irq), base + AR71XX_RESET_REG_MISC_INT_ENABLE);
> > +
> > + /* flush write */
> > + __raw_readl(base + AR71XX_RESET_REG_MISC_INT_ENABLE);
> > +}
> > +
> > +static void ar724x_misc_irq_ack(struct irq_data *d)
> > +{
> > + void __iomem *base = irq_data_get_irq_chip_data(d);
> > + unsigned int irq = d->hwirq;
> > + u32 t;
> > +
> > + t = __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
> > + __raw_writel(t & ~BIT(irq), base + AR71XX_RESET_REG_MISC_INT_STATUS);
> > +
> > + /* flush write */
> > + __raw_readl(base + AR71XX_RESET_REG_MISC_INT_STATUS);
> > +}
> > +
> > +static struct irq_chip ath79_misc_irq_chip = {
> > + .name = "MISC",
> > + .irq_unmask = ar71xx_misc_irq_unmask,
> > + .irq_mask = ar71xx_misc_irq_mask,
> > +};
> > +
> > +static int misc_map(struct irq_domain *d, unsigned int irq, irq_hw_number_t hw)
> > +{
> > + irq_set_chip_and_handler(irq, &ath79_misc_irq_chip, handle_level_irq);
> > + irq_set_chip_data(irq, d->host_data);
> > + return 0;
> > +}
> > +
> > +static const struct irq_domain_ops misc_irq_domain_ops = {
> > + .xlate = irq_domain_xlate_onecell,
> > + .map = misc_map,
> > +};
> > +
> > +static void __init ath79_misc_intc_domain_init(
> > + struct irq_domain *domain, int irq)
> > +{
> > + void __iomem *base = domain->host_data;
> > +
> > + /* Disable and clear all interrupts */
> > + __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_ENABLE);
> > + __raw_writel(0, base + AR71XX_RESET_REG_MISC_INT_STATUS);
> > +
> > + irq_set_chained_handler_and_data(irq, ath79_misc_irq_handler, domain);
> > +}
> > +
> > +static int __init ath79_misc_intc_of_init(
> > + struct device_node *node, struct device_node *parent)
> > +{
> > + struct irq_domain *domain;
> > + void __iomem *base;
> > + int irq;
> > +
> > + irq = irq_of_parse_and_map(node, 0);
> > + if (!irq) {
> > + pr_err("Failed to get MISC IRQ\n");
> > + return -EINVAL;
> > + }
> > +
> > + base = of_iomap(node, 0);
> > + if (!base) {
> > + pr_err("Failed to get MISC IRQ registers\n");
> > + return -ENOMEM;
> > + }
> > +
> > + domain = irq_domain_add_linear(node, ATH79_MISC_IRQ_COUNT,
> > + &misc_irq_domain_ops, base);
> > + if (!domain) {
> > + pr_err("Failed to add MISC irqdomain\n");
> > + return -EINVAL;
> > + }
> > +
> > + ath79_misc_intc_domain_init(domain, irq);
> > + return 0;
> > +}
> > +
> > +static int __init ar7100_misc_intc_of_init(
> > + struct device_node *node, struct device_node *parent)
> > +{
> > + ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask;
> > + return ath79_misc_intc_of_init(node, parent);
> > +}
> > +
> > +IRQCHIP_DECLARE(ar7100_misc_intc, "qca,ar7100-misc-intc",
> > + ar7100_misc_intc_of_init);
> > +
> > +static int __init ar7240_misc_intc_of_init(
> > + struct device_node *node, struct device_node *parent)
> > +{
> > + ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack;
> > + return ath79_misc_intc_of_init(node, parent);
> > +}
> > +
> > +IRQCHIP_DECLARE(ar7240_misc_intc, "qca,ar7240-misc-intc",
> > + ar7240_misc_intc_of_init);
> > +
> > +void __init ath79_misc_irq_init(void __iomem *regs, int irq,
> > + int irq_base, bool is_ar71xx)
> > +{
> > + struct irq_domain *domain;
> > +
> > + if (is_ar71xx)
> > + ath79_misc_irq_chip.irq_mask_ack = ar71xx_misc_irq_mask;
> > + else
> > + ath79_misc_irq_chip.irq_ack = ar724x_misc_irq_ack;
> > +
> > + domain = irq_domain_add_legacy(NULL, ATH79_MISC_IRQ_COUNT,
> > + irq_base, 0, &misc_irq_domain_ops, regs);
> > + if (!domain)
> > + panic("Failed to create MISC irqdomain");
> > +
> > + ath79_misc_intc_domain_init(domain, irq);
> > +}
>
> Other than that, this looks OK.
>
> Thanks,
Great, thanks for the review.
Alban
next prev parent reply other threads:[~2016-01-20 19:51 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-11-17 19:34 [PATCH 0/6] MIPS: ath79: Move the IRQ drivers to drivers/irqchip Alban Bedel
2015-11-17 19:34 ` [PATCH 1/6] MIPS: ath79: Fix the size of the MISC INTC registers in ar9132.dtsi Alban Bedel
2015-11-17 19:34 ` [PATCH 2/6] MIPS: ath79: irq: Remove useless #ifdef CONFIG_IRQCHIP Alban Bedel
2015-11-17 19:34 ` [PATCH 3/6] MIPS: ath79: irq: Prepare moving the MISC driver to drivers/irqchip Alban Bedel
2015-11-17 19:34 ` [PATCH 4/6] MIPS: ath79: irq: Move " Alban Bedel
2015-11-17 20:03 ` Jason Cooper
2015-11-17 20:06 ` Thomas Gleixner
2015-11-17 20:09 ` Jason Cooper
2015-12-30 13:53 ` Alban
2015-12-30 13:53 ` Alban
2016-01-20 8:15 ` Alban
2016-01-20 8:15 ` Alban
2016-01-20 12:38 ` Marc Zyngier
2016-01-20 12:38 ` Marc Zyngier
2016-01-20 19:51 ` Alban [this message]
2016-01-20 19:51 ` Alban
2015-11-17 19:34 ` [PATCH 5/6] MIPS: ath79: Allow using ath79_ddr_wb_flush() from drivers Alban Bedel
2015-11-17 19:34 ` [PATCH 6/6] MIPS: ath79: irq: Move the CPU IRQ driver to drivers/irqchip Alban Bedel
2016-01-20 12:49 ` Marc Zyngier
2016-01-20 12:49 ` Marc Zyngier
2016-01-20 19:46 ` Alban
2016-01-20 19:46 ` Alban
2016-01-21 8:52 ` Marc Zyngier
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20160120205113.4b706e2f@tock \
--to=albeu@free.fr \
--cc=abrestic@chromium.org \
--cc=jason@lakedaemon.net \
--cc=joel@porquet.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-mips@linux-mips.org \
--cc=lynxis@fe80.eu \
--cc=marc.zyngier@arm.com \
--cc=ralf@linux-mips.org \
--cc=tglx@linutronix.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.