* [PATCH 1/3] ARM: at91/aic: add device tree support for AIC
@ 2011-11-24 21:56 Nicolas Ferre
2011-11-24 21:56 ` [PATCH 2/3] ARM: at91/gpio: add irqdomain to gpio interrupts Nicolas Ferre
` (3 more replies)
0 siblings, 4 replies; 12+ messages in thread
From: Nicolas Ferre @ 2011-11-24 21:56 UTC (permalink / raw)
To: linux-arm-kernel, robherring2, grant.likely
Cc: linux-kernel, devicetree-discuss, plagnioj, Nicolas Ferre
Ioremap registers from DT specification and adding
of a simple irq domain for AIC interrupts.
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
arch/arm/Kconfig | 1 +
arch/arm/mach-at91/irq.c | 41 ++++++++++++++++++++++++++++++++++++++++-
2 files changed, 41 insertions(+), 1 deletions(-)
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 44789ef..293c152 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -318,6 +318,7 @@ config ARCH_AT91
select ARCH_REQUIRE_GPIOLIB
select HAVE_CLK
select CLKDEV_LOOKUP
+ select IRQ_DOMAIN
help
This enables support for systems based on the Atmel AT91RM9200,
AT91SAM9 and AT91CAP9 processors.
diff --git a/arch/arm/mach-at91/irq.c b/arch/arm/mach-at91/irq.c
index be6b639..80783b0 100644
--- a/arch/arm/mach-at91/irq.c
+++ b/arch/arm/mach-at91/irq.c
@@ -24,6 +24,8 @@
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/types.h>
+#include <linux/of_address.h>
+#include <linux/irqdomain.h>
#include <mach/hardware.h>
#include <asm/irq.h>
@@ -34,6 +36,7 @@
#include <asm/mach/map.h>
void __iomem *at91_aic_base;
+static struct irq_domain at91_aic_domain;
static void at91_aic_mask_irq(struct irq_data *d)
{
@@ -127,14 +130,44 @@ static struct irq_chip at91_aic_chip = {
.irq_set_wake = at91_aic_set_wake,
};
+#if defined(CONFIG_OF)
+static struct of_device_id aic_ids[] = {
+ { .compatible = "atmel,at91rm9200-aic" },
+ { /*sentinel*/ }
+};
+
+static int __init at91_aic_of_init(void)
+{
+ struct device_node *np;
+
+ np = of_find_matching_node(NULL, aic_ids);
+ if (np == NULL)
+ return -ENODEV;
+
+ at91_aic_base = of_iomap(np, 0);
+ at91_aic_domain.of_node = np;
+ /* Keep refcount of the node */
+
+ return 0;
+}
+#else
+static int __init at91_aic_of_init(void)
+{
+ return -ENOSYS;
+}
+#endif
+
/*
* Initialize the AIC interrupt controller.
*/
void __init at91_aic_init(unsigned int priority[NR_AIC_IRQS])
{
unsigned int i;
+ int ret;
- at91_aic_base = ioremap(AT91_AIC, 512);
+ ret = at91_aic_of_init();
+ if (ret < 0)
+ at91_aic_base = ioremap(AT91_AIC, 512);
if (!at91_aic_base)
panic("Impossible to ioremap AT91_AIC\n");
@@ -169,4 +202,10 @@ void __init at91_aic_init(unsigned int priority[NR_AIC_IRQS])
/* Disable and clear all interrupts initially */
at91_aic_write(AT91_AIC_IDCR, 0xFFFFFFFF);
at91_aic_write(AT91_AIC_ICCR, 0xFFFFFFFF);
+
+ /* Add irq domain for AIC */
+ at91_aic_domain.irq_base = at91_aic_domain.hwirq_base = 0;
+ at91_aic_domain.nr_irq = NR_AIC_IRQS;
+ at91_aic_domain.ops = &irq_domain_simple_ops;
+ irq_domain_add(&at91_aic_domain);
}
--
1.7.5.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 2/3] ARM: at91/gpio: add irqdomain to gpio interrupts
2011-11-24 21:56 [PATCH 1/3] ARM: at91/aic: add device tree support for AIC Nicolas Ferre
@ 2011-11-24 21:56 ` Nicolas Ferre
2011-11-25 15:36 ` Rob Herring
2011-11-24 21:56 ` [PATCH 3/3] ARM: at91/board-dt: remove AIC irq domain from board file Nicolas Ferre
` (2 subsequent siblings)
3 siblings, 1 reply; 12+ messages in thread
From: Nicolas Ferre @ 2011-11-24 21:56 UTC (permalink / raw)
To: linux-arm-kernel, robherring2, grant.likely
Cc: linux-kernel, devicetree-discuss, plagnioj, Nicolas Ferre
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
---
arch/arm/mach-at91/gpio.c | 19 +++++++++++++++++++
1 files changed, 19 insertions(+), 0 deletions(-)
diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c
index 74d6783..45a39d0 100644
--- a/arch/arm/mach-at91/gpio.c
+++ b/arch/arm/mach-at91/gpio.c
@@ -20,6 +20,7 @@
#include <linux/list.h>
#include <linux/module.h>
#include <linux/io.h>
+#include <linux/irqdomain.h>
#include <mach/hardware.h>
#include <mach/at91_pio.h>
@@ -32,6 +33,7 @@ struct at91_gpio_chip {
int id; /* ID of register bank */
void __iomem *regbase; /* Base of register bank */
struct clk *clock; /* associated clock */
+ struct irq_domain domain; /* associated irq domain */
};
#define to_at91_gpio_chip(c) container_of(c, struct at91_gpio_chip, chip)
@@ -483,6 +485,20 @@ postcore_initcall(at91_gpio_debugfs_init);
/*--------------------------------------------------------------------------*/
/*
+ * irqdomain initialization: pile up irqdomains on top of AIC range
+ */
+static void __init at91_gpio_irqdomain(struct at91_gpio_chip *at91_gpio)
+{
+ struct irq_domain *gpio_irq_d = &at91_gpio->domain;
+
+ gpio_irq_d->irq_base =
+ gpio_irq_d->hwirq_base = gpio_to_irq(at91_gpio->chip.base);
+ gpio_irq_d->nr_irq = at91_gpio->chip.ngpio;
+ gpio_irq_d->ops = &irq_domain_simple_ops;
+ irq_domain_add(gpio_irq_d);
+}
+
+/*
* This lock class tells lockdep that GPIO irqs are in a different
* category than their parents, so it won't report false recursion.
*/
@@ -517,6 +533,9 @@ void __init at91_gpio_irq_setup(void)
set_irq_flags(irq, IRQF_VALID);
}
+ /* setup irq domain for this GPIO controller */
+ at91_gpio_irqdomain(this);
+
/* The toplevel handler handles one bank of GPIOs, except
* AT91SAM9263_ID_PIOCDE handles three... PIOC is first in
* the list, so we only set up that handler.
--
1.7.5.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH 3/3] ARM: at91/board-dt: remove AIC irq domain from board file
2011-11-24 21:56 [PATCH 1/3] ARM: at91/aic: add device tree support for AIC Nicolas Ferre
2011-11-24 21:56 ` [PATCH 2/3] ARM: at91/gpio: add irqdomain to gpio interrupts Nicolas Ferre
@ 2011-11-24 21:56 ` Nicolas Ferre
2011-11-24 22:26 ` [PATCH 1/3] ARM: at91/aic: add device tree support for AIC Jamie Iles
2011-11-29 18:07 ` [PATCH v2 " Nicolas Ferre
3 siblings, 0 replies; 12+ messages in thread
From: Nicolas Ferre @ 2011-11-24 21:56 UTC (permalink / raw)
To: linux-arm-kernel, robherring2, grant.likely
Cc: linux-kernel, devicetree-discuss, plagnioj, Nicolas Ferre
Adding of irqdomain in AIC code make the specification
of the irq domain in board file useless.
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---
arch/arm/mach-at91/board-dt.c | 15 +--------------
1 files changed, 1 insertions(+), 14 deletions(-)
diff --git a/arch/arm/mach-at91/board-dt.c b/arch/arm/mach-at91/board-dt.c
index bb6b434..119eda6 100644
--- a/arch/arm/mach-at91/board-dt.c
+++ b/arch/arm/mach-at91/board-dt.c
@@ -15,8 +15,6 @@
#include <linux/init.h>
#include <linux/module.h>
#include <linux/gpio.h>
-#include <linux/irqdomain.h>
-#include <linux/of_irq.h>
#include <linux/of_platform.h>
#include <mach/hardware.h>
@@ -88,17 +86,6 @@ static void __init ek_add_device_nand(void)
at91_add_device_nand(&ek_nand_data);
}
-static const struct of_device_id aic_of_match[] __initconst = {
- { .compatible = "atmel,at91rm9200-aic", },
- {},
-};
-
-static void __init at91_dt_init_irq(void)
-{
- irq_domain_generate_simple(aic_of_match, 0xfffff000, 0);
- at91_init_irq_default();
-}
-
static void __init at91_dt_device_init(void)
{
of_platform_populate(NULL, of_default_bus_match_table, NULL, NULL);
@@ -118,7 +105,7 @@ DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM (Device Tree)")
.timer = &at91sam926x_timer,
.map_io = at91_map_io,
.init_early = ek_init_early,
- .init_irq = at91_dt_init_irq,
+ .init_irq = at91_init_irq_default,
.init_machine = at91_dt_device_init,
.dt_compat = at91_dt_board_compat,
MACHINE_END
--
1.7.5.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH 1/3] ARM: at91/aic: add device tree support for AIC
2011-11-24 21:56 [PATCH 1/3] ARM: at91/aic: add device tree support for AIC Nicolas Ferre
2011-11-24 21:56 ` [PATCH 2/3] ARM: at91/gpio: add irqdomain to gpio interrupts Nicolas Ferre
2011-11-24 21:56 ` [PATCH 3/3] ARM: at91/board-dt: remove AIC irq domain from board file Nicolas Ferre
@ 2011-11-24 22:26 ` Jamie Iles
2011-11-25 13:51 ` Jean-Christophe PLAGNIOL-VILLARD
2011-11-29 18:07 ` [PATCH v2 " Nicolas Ferre
3 siblings, 1 reply; 12+ messages in thread
From: Jamie Iles @ 2011-11-24 22:26 UTC (permalink / raw)
To: Nicolas Ferre
Cc: linux-arm-kernel, robherring2, grant.likely, devicetree-discuss,
linux-kernel
Hi Nicolas,
On Thu, Nov 24, 2011 at 10:56:27PM +0100, Nicolas Ferre wrote:
> Ioremap registers from DT specification and adding
> of a simple irq domain for AIC interrupts.
>
> Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
> Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
> ---
Apologies if I've missed it somewhere but I think this needs to be
documented in Documentation/devicetree.
[...]
> diff --git a/arch/arm/mach-at91/irq.c b/arch/arm/mach-at91/irq.c
> index be6b639..80783b0 100644
> --- a/arch/arm/mach-at91/irq.c
> +++ b/arch/arm/mach-at91/irq.c
> @@ -24,6 +24,8 @@
> #include <linux/module.h>
> #include <linux/mm.h>
> #include <linux/types.h>
> +#include <linux/of_address.h>
> +#include <linux/irqdomain.h>
>
> #include <mach/hardware.h>
> #include <asm/irq.h>
> @@ -34,6 +36,7 @@
> #include <asm/mach/map.h>
>
> void __iomem *at91_aic_base;
> +static struct irq_domain at91_aic_domain;
>
> static void at91_aic_mask_irq(struct irq_data *d)
> {
> @@ -127,14 +130,44 @@ static struct irq_chip at91_aic_chip = {
> .irq_set_wake = at91_aic_set_wake,
> };
>
> +#if defined(CONFIG_OF)
> +static struct of_device_id aic_ids[] = {
> + { .compatible = "atmel,at91rm9200-aic" },
> + { /*sentinel*/ }
> +};
> +
> +static int __init at91_aic_of_init(void)
> +{
> + struct device_node *np;
> +
> + np = of_find_matching_node(NULL, aic_ids);
> + if (np == NULL)
> + return -ENODEV;
> +
> + at91_aic_base = of_iomap(np, 0);
> + at91_aic_domain.of_node = np;
I think this needs to be:
at91_aic_domain.of_node = of_node_get(np);
to keep the reference count.
> + /* Keep refcount of the node */
> +
> + return 0;
> +}
> +#else
> +static int __init at91_aic_of_init(void)
> +{
> + return -ENOSYS;
> +}
> +#endif
I think it's preferred if you use of_irq_init() here as it can handle
the ordering of IRQ controllers. There are GIC and VIC bindings in
-next that use this and provide a way for non-DT platforms to still use
the drivers.
> /*
> * Initialize the AIC interrupt controller.
> */
> void __init at91_aic_init(unsigned int priority[NR_AIC_IRQS])
> {
> unsigned int i;
> + int ret;
>
> - at91_aic_base = ioremap(AT91_AIC, 512);
> + ret = at91_aic_of_init();
> + if (ret < 0)
> + at91_aic_base = ioremap(AT91_AIC, 512);
>
> if (!at91_aic_base)
> panic("Impossible to ioremap AT91_AIC\n");
> @@ -169,4 +202,10 @@ void __init at91_aic_init(unsigned int priority[NR_AIC_IRQS])
> /* Disable and clear all interrupts initially */
> at91_aic_write(AT91_AIC_IDCR, 0xFFFFFFFF);
> at91_aic_write(AT91_AIC_ICCR, 0xFFFFFFFF);
> +
> + /* Add irq domain for AIC */
> + at91_aic_domain.irq_base = at91_aic_domain.hwirq_base = 0;
> + at91_aic_domain.nr_irq = NR_AIC_IRQS;
> + at91_aic_domain.ops = &irq_domain_simple_ops;
irq_domain_simple_ops is only exported when CONFIG_OF_IRQ=y, so this
probably won't work for !CONFIG_USE_OF.
> + irq_domain_add(&at91_aic_domain);
> }
> --
> 1.7.5.4
>
> _______________________________________________
> devicetree-discuss mailing list
> devicetree-discuss@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/devicetree-discuss
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/3] ARM: at91/aic: add device tree support for AIC
2011-11-24 22:26 ` [PATCH 1/3] ARM: at91/aic: add device tree support for AIC Jamie Iles
@ 2011-11-25 13:51 ` Jean-Christophe PLAGNIOL-VILLARD
2011-11-25 15:28 ` Jamie Iles
0 siblings, 1 reply; 12+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2011-11-25 13:51 UTC (permalink / raw)
To: Jamie Iles
Cc: Nicolas Ferre, devicetree-discuss, linux-kernel, linux-arm-kernel
On 22:26 Thu 24 Nov , Jamie Iles wrote:
> Hi Nicolas,
>
> On Thu, Nov 24, 2011 at 10:56:27PM +0100, Nicolas Ferre wrote:
> > Ioremap registers from DT specification and adding
> > of a simple irq domain for AIC interrupts.
> >
> > Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
> > Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
> > ---
>
> Apologies if I've missed it somewhere but I think this needs to be
> documented in Documentation/devicetree.
>
> [...]
> > diff --git a/arch/arm/mach-at91/irq.c b/arch/arm/mach-at91/irq.c
> > index be6b639..80783b0 100644
> > --- a/arch/arm/mach-at91/irq.c
> > +++ b/arch/arm/mach-at91/irq.c
> > @@ -24,6 +24,8 @@
> > #include <linux/module.h>
> > #include <linux/mm.h>
> > #include <linux/types.h>
> > +#include <linux/of_address.h>
> > +#include <linux/irqdomain.h>
> >
> > #include <mach/hardware.h>
> > #include <asm/irq.h>
> > @@ -34,6 +36,7 @@
> > #include <asm/mach/map.h>
> >
> > void __iomem *at91_aic_base;
> > +static struct irq_domain at91_aic_domain;
> >
> > static void at91_aic_mask_irq(struct irq_data *d)
> > {
> > @@ -127,14 +130,44 @@ static struct irq_chip at91_aic_chip = {
> > .irq_set_wake = at91_aic_set_wake,
> > };
> >
> > +#if defined(CONFIG_OF)
> > +static struct of_device_id aic_ids[] = {
> > + { .compatible = "atmel,at91rm9200-aic" },
> > + { /*sentinel*/ }
> > +};
> > +
> > +static int __init at91_aic_of_init(void)
> > +{
> > + struct device_node *np;
> > +
> > + np = of_find_matching_node(NULL, aic_ids);
> > + if (np == NULL)
> > + return -ENODEV;
> > +
> > + at91_aic_base = of_iomap(np, 0);
> > + at91_aic_domain.of_node = np;
>
> I think this needs to be:
>
> at91_aic_domain.of_node = of_node_get(np);
>
> to keep the reference count.
>
> > + /* Keep refcount of the node */
> > +
> > + return 0;
> > +}
> > +#else
> > +static int __init at91_aic_of_init(void)
> > +{
> > + return -ENOSYS;
> > +}
> > +#endif
>
> I think it's preferred if you use of_irq_init() here as it can handle
> the ordering of IRQ controllers. There are GIC and VIC bindings in
> -next that use this and provide a way for non-DT platforms to still use
> the drivers.
which is the case here as if the of_init fail we failback to the non-dt init
and this IP is AT91 only
Best Regards,
J.
>
> > /*
> > * Initialize the AIC interrupt controller.
> > */
> > void __init at91_aic_init(unsigned int priority[NR_AIC_IRQS])
> > {
> > unsigned int i;
> > + int ret;
> >
> > - at91_aic_base = ioremap(AT91_AIC, 512);
> > + ret = at91_aic_of_init();
> > + if (ret < 0)
> > + at91_aic_base = ioremap(AT91_AIC, 512);
> >
> > if (!at91_aic_base)
> > panic("Impossible to ioremap AT91_AIC\n");
> > @@ -169,4 +202,10 @@ void __init at91_aic_init(unsigned int priority[NR_AIC_IRQS])
> > /* Disable and clear all interrupts initially */
> > at91_aic_write(AT91_AIC_IDCR, 0xFFFFFFFF);
> > at91_aic_write(AT91_AIC_ICCR, 0xFFFFFFFF);
> > +
> > + /* Add irq domain for AIC */
> > + at91_aic_domain.irq_base = at91_aic_domain.hwirq_base = 0;
> > + at91_aic_domain.nr_irq = NR_AIC_IRQS;
> > + at91_aic_domain.ops = &irq_domain_simple_ops;
>
> irq_domain_simple_ops is only exported when CONFIG_OF_IRQ=y, so this
> probably won't work for !CONFIG_USE_OF.
so we need to use
if (IS_BUILT_IN(CONFIG_USE_OF)) {
}
Best Regards,
J.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/3] ARM: at91/aic: add device tree support for AIC
2011-11-25 13:51 ` Jean-Christophe PLAGNIOL-VILLARD
@ 2011-11-25 15:28 ` Jamie Iles
2011-11-29 13:04 ` Nicolas Ferre
0 siblings, 1 reply; 12+ messages in thread
From: Jamie Iles @ 2011-11-25 15:28 UTC (permalink / raw)
To: Jean-Christophe PLAGNIOL-VILLARD
Cc: Jamie Iles, Nicolas Ferre, devicetree-discuss, linux-kernel,
linux-arm-kernel
On Fri, Nov 25, 2011 at 02:51:06PM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
> On 22:26 Thu 24 Nov , Jamie Iles wrote:
> > Hi Nicolas,
> > On Thu, Nov 24, 2011 at 10:56:27PM +0100, Nicolas Ferre wrote:
[...]
> > > +#if defined(CONFIG_OF)
> > > +static struct of_device_id aic_ids[] = {
> > > + { .compatible = "atmel,at91rm9200-aic" },
> > > + { /*sentinel*/ }
> > > +};
> > > +
> > > +static int __init at91_aic_of_init(void)
> > > +{
> > > + struct device_node *np;
> > > +
> > > + np = of_find_matching_node(NULL, aic_ids);
> > > + if (np == NULL)
> > > + return -ENODEV;
> > > +
> > > + at91_aic_base = of_iomap(np, 0);
> > > + at91_aic_domain.of_node = np;
> >
> > I think this needs to be:
> >
> > at91_aic_domain.of_node = of_node_get(np);
> >
> > to keep the reference count.
> >
> > > + /* Keep refcount of the node */
> > > +
> > > + return 0;
> > > +}
> > > +#else
> > > +static int __init at91_aic_of_init(void)
> > > +{
> > > + return -ENOSYS;
> > > +}
> > > +#endif
> >
> > I think it's preferred if you use of_irq_init() here as it can handle
> > the ordering of IRQ controllers. There are GIC and VIC bindings in
> > -next that use this and provide a way for non-DT platforms to still use
> > the drivers.
> which is the case here as if the of_init fail we failback to the non-dt init
>
> and this IP is AT91 only
Right, but it's not using the of_irq_init() interface which is the
standard way of registering interrupt controllers and will correctly
dependencies for you.
So if you could have something like:
void __init __at91_aic_init(unsigned int priority[NR_AIC_IRQS],
void __iomem *regs,
struct device_node *np)
{
/*
* Do all of the writes to the AIC itself and configure
* the IRQ domain.
*/
}
void __init at91_aic_init(unsigned int priority[NR_AIC_IRQS])
{
void __iomem *base = ioremap(AT91_AIC, 512);
__at91_aic_init(priority, base, NULL);
}
int __init at91_aic_of_init(struct device_node *node,
struct device_node *parent)
{
void __iomem *regs = of_iomap(node, 0);
/*
* Get priorities from the DT. If this was an array of cells
* then that should be okay.
*/
__at91_aic_init(dt_priorities, regs, node);
}
Then the DT based board initialisation can do:
static const struct of_device_id at91_irq_of_match[] __initconst = {
{ .compatible = "atmel,at91-aic", .data = at91_aic_of_init },
{}
};
static void __init at91_of_irq_init(void)
{
of_irq_init(at91_of_irq_init);
}
Which is consistent with other platforms. However this does require
that the priorities are encoded in the device-tree, but I guess that's a
good thing anyway isn't it?
Jamie
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 2/3] ARM: at91/gpio: add irqdomain to gpio interrupts
2011-11-24 21:56 ` [PATCH 2/3] ARM: at91/gpio: add irqdomain to gpio interrupts Nicolas Ferre
@ 2011-11-25 15:36 ` Rob Herring
0 siblings, 0 replies; 12+ messages in thread
From: Rob Herring @ 2011-11-25 15:36 UTC (permalink / raw)
To: Nicolas Ferre
Cc: linux-arm-kernel, grant.likely, linux-kernel, devicetree-discuss,
plagnioj
On Thu, Nov 24, 2011 at 3:56 PM, Nicolas Ferre <nicolas.ferre@atmel.com> wrote:
> Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
> Acked-by: Jean-Christophe PLAGNIOL-VILLARD <plagnioj@jcrosoft.com>
> ---
> arch/arm/mach-at91/gpio.c | 19 +++++++++++++++++++
> 1 files changed, 19 insertions(+), 0 deletions(-)
>
> diff --git a/arch/arm/mach-at91/gpio.c b/arch/arm/mach-at91/gpio.c
> index 74d6783..45a39d0 100644
> --- a/arch/arm/mach-at91/gpio.c
> +++ b/arch/arm/mach-at91/gpio.c
> @@ -20,6 +20,7 @@
> #include <linux/list.h>
> #include <linux/module.h>
> #include <linux/io.h>
> +#include <linux/irqdomain.h>
>
> #include <mach/hardware.h>
> #include <mach/at91_pio.h>
> @@ -32,6 +33,7 @@ struct at91_gpio_chip {
> int id; /* ID of register bank */
> void __iomem *regbase; /* Base of register bank */
> struct clk *clock; /* associated clock */
> + struct irq_domain domain; /* associated irq domain */
> };
>
> #define to_at91_gpio_chip(c) container_of(c, struct at91_gpio_chip, chip)
> @@ -483,6 +485,20 @@ postcore_initcall(at91_gpio_debugfs_init);
> /*--------------------------------------------------------------------------*/
>
> /*
> + * irqdomain initialization: pile up irqdomains on top of AIC range
> + */
> +static void __init at91_gpio_irqdomain(struct at91_gpio_chip *at91_gpio)
> +{
> + struct irq_domain *gpio_irq_d = &at91_gpio->domain;
> +
> + gpio_irq_d->irq_base =
> + gpio_irq_d->hwirq_base = gpio_to_irq(at91_gpio->chip.base);
This is wrong. hwirq_base is the first irq number relative to the
irq_chip and is generally 0.
irq_base should come from the platform if you need it hardcoded.
Otherwise, it should come from irq_alloc_descs.
> + gpio_irq_d->nr_irq = at91_gpio->chip.ngpio;
> + gpio_irq_d->ops = &irq_domain_simple_ops;
> + irq_domain_add(gpio_irq_d);
> +}
> +
> +/*
> * This lock class tells lockdep that GPIO irqs are in a different
> * category than their parents, so it won't report false recursion.
> */
> @@ -517,6 +533,9 @@ void __init at91_gpio_irq_setup(void)
> set_irq_flags(irq, IRQF_VALID);
> }
>
> + /* setup irq domain for this GPIO controller */
> + at91_gpio_irqdomain(this);
I would just inline this code.
Can you use the generic irqchip here? I'm working on a patch to add
irqdomain support to that.
Rob
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/3] ARM: at91/aic: add device tree support for AIC
2011-11-25 15:28 ` Jamie Iles
@ 2011-11-29 13:04 ` Nicolas Ferre
2011-11-29 13:56 ` Nicolas Ferre
0 siblings, 1 reply; 12+ messages in thread
From: Nicolas Ferre @ 2011-11-29 13:04 UTC (permalink / raw)
To: Jamie Iles
Cc: Jean-Christophe PLAGNIOL-VILLARD, devicetree-discuss,
linux-kernel, linux-arm-kernel
On 11/25/2011 04:28 PM, Jamie Iles :
> On Fri, Nov 25, 2011 at 02:51:06PM +0100, Jean-Christophe PLAGNIOL-VILLARD wrote:
>> On 22:26 Thu 24 Nov , Jamie Iles wrote:
>>> Hi Nicolas,
>>> On Thu, Nov 24, 2011 at 10:56:27PM +0100, Nicolas Ferre wrote:
> [...]
>>>> +#if defined(CONFIG_OF)
>>>> +static struct of_device_id aic_ids[] = {
>>>> + { .compatible = "atmel,at91rm9200-aic" },
>>>> + { /*sentinel*/ }
>>>> +};
>>>> +
>>>> +static int __init at91_aic_of_init(void)
>>>> +{
>>>> + struct device_node *np;
>>>> +
>>>> + np = of_find_matching_node(NULL, aic_ids);
>>>> + if (np == NULL)
>>>> + return -ENODEV;
>>>> +
>>>> + at91_aic_base = of_iomap(np, 0);
>>>> + at91_aic_domain.of_node = np;
>>>
>>> I think this needs to be:
>>>
>>> at91_aic_domain.of_node = of_node_get(np);
>>>
>>> to keep the reference count.
Well, in fact the of_find_matching_node() function already indent the
ref. count...
>>>> + /* Keep refcount of the node */
... That is why I added this comment ^^
But maybe for sake of clarity, I may have used what you propose anyway.
What it your opinion?
>>>> +
>>>> + return 0;
>>>> +}
>>>> +#else
>>>> +static int __init at91_aic_of_init(void)
>>>> +{
>>>> + return -ENOSYS;
>>>> +}
>>>> +#endif
>>>
>>> I think it's preferred if you use of_irq_init() here as it can handle
>>> the ordering of IRQ controllers. There are GIC and VIC bindings in
>>> -next that use this and provide a way for non-DT platforms to still use
>>> the drivers.
>> which is the case here as if the of_init fail we failback to the non-dt init
>>
>> and this IP is AT91 only
>
> Right, but it's not using the of_irq_init() interface which is the
> standard way of registering interrupt controllers and will correctly
> dependencies for you.
>
> So if you could have something like:
>
> void __init __at91_aic_init(unsigned int priority[NR_AIC_IRQS],
> void __iomem *regs,
> struct device_node *np)
> {
> /*
> * Do all of the writes to the AIC itself and configure
> * the IRQ domain.
> */
> }
>
> void __init at91_aic_init(unsigned int priority[NR_AIC_IRQS])
> {
> void __iomem *base = ioremap(AT91_AIC, 512);
>
> __at91_aic_init(priority, base, NULL);
> }
>
> int __init at91_aic_of_init(struct device_node *node,
> struct device_node *parent)
> {
> void __iomem *regs = of_iomap(node, 0);
>
> /*
> * Get priorities from the DT. If this was an array of cells
> * then that should be okay.
> */
> __at91_aic_init(dt_priorities, regs, node);
> }
>
> Then the DT based board initialisation can do:
>
> static const struct of_device_id at91_irq_of_match[] __initconst = {
> { .compatible = "atmel,at91-aic", .data = at91_aic_of_init },
> {}
> };
>
> static void __init at91_of_irq_init(void)
> {
> of_irq_init(at91_of_irq_init);
> }
That looks nice. I will try to implement this. I will try to figure out
when of_irq_init() is called compared to the other init_IRQ() function.
> Which is consistent with other platforms. However this does require
> that the priorities are encoded in the device-tree, but I guess that's a
> good thing anyway isn't it?
That is a annoying point: I do not want to add all this "default"
priority stuff in the DT. It is kind of useless until we use the
threaded interrupts everywhere and may bloat the DT...
I will try to find a way to pass the default priority table to the DT
called function.
Thanks for your review,
--
Nicolas Ferre
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH 1/3] ARM: at91/aic: add device tree support for AIC
2011-11-29 13:04 ` Nicolas Ferre
@ 2011-11-29 13:56 ` Nicolas Ferre
0 siblings, 0 replies; 12+ messages in thread
From: Nicolas Ferre @ 2011-11-29 13:56 UTC (permalink / raw)
To: Jamie Iles
Cc: devicetree-discuss, linux-kernel, linux-arm-kernel,
Jean-Christophe PLAGNIOL-VILLARD
On 11/29/2011 02:04 PM, Nicolas Ferre :
> On 11/25/2011 04:28 PM, Jamie Iles :
>> On Fri, Nov 25, 2011 at 02:51:06PM +0100, Jean-Christophe
>> PLAGNIOL-VILLARD wrote:
>>> On 22:26 Thu 24 Nov , Jamie Iles wrote:
>>>> Hi Nicolas,
>>>> On Thu, Nov 24, 2011 at 10:56:27PM +0100, Nicolas Ferre wrote:
>> [...]
>>>>> +#if defined(CONFIG_OF)
>>>>> +static struct of_device_id aic_ids[] = {
>>>>> + { .compatible = "atmel,at91rm9200-aic" },
>>>>> + { /*sentinel*/ }
>>>>> +};
>>>>> +
>>>>> +static int __init at91_aic_of_init(void)
>>>>> +{
>>>>> + struct device_node *np;
>>>>> +
>>>>> + np = of_find_matching_node(NULL, aic_ids);
>>>>> + if (np == NULL)
>>>>> + return -ENODEV;
>>>>> +
>>>>> + at91_aic_base = of_iomap(np, 0);
>>>>> + at91_aic_domain.of_node = np;
>>>>
>>>> I think this needs to be:
>>>>
>>>> at91_aic_domain.of_node = of_node_get(np);
>>>>
>>>> to keep the reference count.
>
> Well, in fact the of_find_matching_node() function already indent the
> ref. count...
>
>>>>> + /* Keep refcount of the node */
>
> ... That is why I added this comment ^^
>
> But maybe for sake of clarity, I may have used what you propose anyway.
> What it your opinion?
>
>>>>> +
>>>>> + return 0;
>>>>> +}
>>>>> +#else
>>>>> +static int __init at91_aic_of_init(void)
>>>>> +{
>>>>> + return -ENOSYS;
>>>>> +}
>>>>> +#endif
>>>>
>>>> I think it's preferred if you use of_irq_init() here as it can handle
>>>> the ordering of IRQ controllers. There are GIC and VIC bindings in
>>>> -next that use this and provide a way for non-DT platforms to still use
>>>> the drivers.
>>> which is the case here as if the of_init fail we failback to the
>>> non-dt init
>>>
>>> and this IP is AT91 only
>>
>> Right, but it's not using the of_irq_init() interface which is the
>> standard way of registering interrupt controllers and will correctly
>> dependencies for you.
>>
>> So if you could have something like:
>>
>> void __init __at91_aic_init(unsigned int priority[NR_AIC_IRQS],
>> void __iomem *regs,
>> struct device_node *np)
>> {
>> /*
>> * Do all of the writes to the AIC itself and configure
>> * the IRQ domain.
>> */
>> }
>>
>> void __init at91_aic_init(unsigned int priority[NR_AIC_IRQS])
>> {
>> void __iomem *base = ioremap(AT91_AIC, 512);
>>
>> __at91_aic_init(priority, base, NULL);
>> }
>>
>> int __init at91_aic_of_init(struct device_node *node,
>> struct device_node *parent)
>> {
>> void __iomem *regs = of_iomap(node, 0);
>>
>> /*
>> * Get priorities from the DT. If this was an array of cells
>> * then that should be okay.
>> */
>> __at91_aic_init(dt_priorities, regs, node);
>> }
>>
>> Then the DT based board initialisation can do:
>>
>> static const struct of_device_id at91_irq_of_match[] __initconst = {
>> { .compatible = "atmel,at91-aic", .data = at91_aic_of_init },
>> {}
>> };
>>
>> static void __init at91_of_irq_init(void)
>> {
>> of_irq_init(at91_of_irq_init);
>> }
>
> That looks nice. I will try to implement this. I will try to figure out
> when of_irq_init() is called compared to the other init_IRQ() function.
>
>> Which is consistent with other platforms. However this does require
>> that the priorities are encoded in the device-tree, but I guess that's a
>> good thing anyway isn't it?
>
> That is a annoying point: I do not want to add all this "default"
> priority stuff in the DT. It is kind of useless until we use the
> threaded interrupts everywhere and may bloat the DT...
>
> I will try to find a way to pass the default priority table to the DT
> called function.
Well, I have better understood the way that all this functions are
called. And I tend to find it not so nice: I prefer to have all this irq
controller related details included in the driver itself.
So, I keep the basic structure of my first attempt but will correct it
using the of_irq_init() API.
Bye,
--
Nicolas Ferre
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH v2 1/3] ARM: at91/aic: add device tree support for AIC
2011-11-24 21:56 [PATCH 1/3] ARM: at91/aic: add device tree support for AIC Nicolas Ferre
` (2 preceding siblings ...)
2011-11-24 22:26 ` [PATCH 1/3] ARM: at91/aic: add device tree support for AIC Jamie Iles
@ 2011-11-29 18:07 ` Nicolas Ferre
2011-12-01 15:42 ` [PATCH v3 1/3] ARM: at91/aic: add irq domain and device tree support Nicolas Ferre
3 siblings, 1 reply; 12+ messages in thread
From: Nicolas Ferre @ 2011-11-29 18:07 UTC (permalink / raw)
To: linux-arm-kernel, robherring2, grant.likely
Cc: linux-kernel, devicetree-discuss, plagnioj, Nicolas Ferre
Ioremap registers from DT specification and adding
of a simple irq domain for AIC interrupts.
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---
v2: - use of_irq_init() function for device tree probing
- add documentation
- use own simple struct irq_domain_ops
.../devicetree/bindings/arm/atmel-aic.txt | 20 +++++++++
arch/arm/Kconfig | 1 +
arch/arm/mach-at91/irq.c | 45 +++++++++++++++++++-
3 files changed, 64 insertions(+), 2 deletions(-)
create mode 100644 Documentation/devicetree/bindings/arm/atmel-aic.txt
diff --git a/Documentation/devicetree/bindings/arm/atmel-aic.txt b/Documentation/devicetree/bindings/arm/atmel-aic.txt
new file mode 100644
index 0000000..e306c63
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/atmel-aic.txt
@@ -0,0 +1,20 @@
+* Advanced Interrupt Controller (AIC)
+
+Required properties:
+- compatible: Should be "atmel,<chip>-dma"
+- interrupt-controller: Identifies the node as an interrupt controller.
+- interrupt-parent: For single AIC system, it is an empty property.
+- #interrupt-cells: The number of cells to define the interrupts. Must be 1 as
+ the AIC has no configuration options for interrupt sources. The cell is an u32
+ and defines the interrupt number.
+- reg: Should contain AIC registers location and length
+
+Example:
+
+ aic: interrupt-controller@fffff000 {
+ compatible = "atmel,at91rm9200-aic";
+ interrupt-controller;
+ interrupt-parent;
+ #interrupt-cells = <1>;
+ reg = <0xfffff000 0x200>;
+ };
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 44789ef..293c152 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -318,6 +318,7 @@ config ARCH_AT91
select ARCH_REQUIRE_GPIOLIB
select HAVE_CLK
select CLKDEV_LOOKUP
+ select IRQ_DOMAIN
help
This enables support for systems based on the Atmel AT91RM9200,
AT91SAM9 and AT91CAP9 processors.
diff --git a/arch/arm/mach-at91/irq.c b/arch/arm/mach-at91/irq.c
index be6b639..46418ef 100644
--- a/arch/arm/mach-at91/irq.c
+++ b/arch/arm/mach-at91/irq.c
@@ -24,6 +24,9 @@
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/types.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/irqdomain.h>
#include <mach/hardware.h>
#include <asm/irq.h>
@@ -34,6 +37,12 @@
#include <asm/mach/map.h>
void __iomem *at91_aic_base;
+static struct irq_domain at91_aic_domain;
+static struct irq_domain_ops at91_aic_domain_ops = {
+#if defined(CONFIG_OF)
+ .dt_translate = irq_domain_simple_dt_translate,
+#endif
+};
static void at91_aic_mask_irq(struct irq_data *d)
{
@@ -127,6 +136,29 @@ static struct irq_chip at91_aic_chip = {
.irq_set_wake = at91_aic_set_wake,
};
+#if defined(CONFIG_OF)
+static int __init __at91_aic_of_init(struct device_node *node,
+ struct device_node *parent)
+{
+ at91_aic_base = of_iomap(node, 0);
+ at91_aic_domain.of_node = of_node_get(node);
+
+ return 0;
+}
+
+static const struct of_device_id aic_ids[] __initconst = {
+ { .compatible = "atmel,at91rm9200-aic", .data = __at91_aic_of_init },
+ { /*sentinel*/ }
+};
+
+static void __init at91_aic_of_init(void)
+{
+ of_irq_init(aic_ids);
+}
+#else
+static void __init at91_aic_of_init(void) {}
+#endif
+
/*
* Initialize the AIC interrupt controller.
*/
@@ -134,10 +166,13 @@ void __init at91_aic_init(unsigned int priority[NR_AIC_IRQS])
{
unsigned int i;
- at91_aic_base = ioremap(AT91_AIC, 512);
+ if(of_have_populated_dt())
+ at91_aic_of_init();
+ else
+ at91_aic_base = ioremap(AT91_AIC, 512);
if (!at91_aic_base)
- panic("Impossible to ioremap AT91_AIC\n");
+ panic("Unable to ioremap AIC registers\n");
/*
* The IVR is used by macro get_irqnr_and_base to read and verify.
@@ -169,4 +204,10 @@ void __init at91_aic_init(unsigned int priority[NR_AIC_IRQS])
/* Disable and clear all interrupts initially */
at91_aic_write(AT91_AIC_IDCR, 0xFFFFFFFF);
at91_aic_write(AT91_AIC_ICCR, 0xFFFFFFFF);
+
+ /* Add irq domain for AIC */
+ at91_aic_domain.irq_base = at91_aic_domain.hwirq_base = 0;
+ at91_aic_domain.nr_irq = NR_AIC_IRQS;
+ at91_aic_domain.ops = &at91_aic_domain_ops;
+ irq_domain_add(&at91_aic_domain);
}
--
1.7.5.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH v3 1/3] ARM: at91/aic: add irq domain and device tree support
2011-11-29 18:07 ` [PATCH v2 " Nicolas Ferre
@ 2011-12-01 15:42 ` Nicolas Ferre
2011-12-06 6:34 ` Jean-Christophe PLAGNIOL-VILLARD
0 siblings, 1 reply; 12+ messages in thread
From: Nicolas Ferre @ 2011-12-01 15:42 UTC (permalink / raw)
To: linux-arm-kernel, robherring2, grant.likely
Cc: linux-kernel, devicetree-discuss, jamie, Nicolas Ferre
Add an irqdomain for the AIC interrupt controller.
The device tree support is mapping the registers and
is using the irq_domain_simple_ops to manage hwirq
translation.
The documentation is describing the meaning of the
two cells required for using this "interrupt-controller"
in a device tree node.
Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
---
This patch should go on top of Jamie's patch:
"irqdomain: export irq_domain_simple_ops for !CONFIG_OF"
https://lkml.org/lkml/2011/12/1/109
v3: - change number of cells to define an AIC interrupt (irq trigger type)
- change current .dtsi files to match specification
- use irq_domain_simple_ops (for DT mapping)
v2: - use of_irq_init() function for device tree probing
- add documentation
- use own simple struct irq_domain_ops
.../devicetree/bindings/arm/atmel-aic.txt | 38 +++++++++++++++++++
arch/arm/Kconfig | 1 +
arch/arm/boot/dts/at91sam9g20.dtsi | 16 ++++----
arch/arm/boot/dts/at91sam9g45.dtsi | 14 +++---
arch/arm/mach-at91/irq.c | 40 +++++++++++++++++++-
5 files changed, 92 insertions(+), 17 deletions(-)
create mode 100644 Documentation/devicetree/bindings/arm/atmel-aic.txt
diff --git a/Documentation/devicetree/bindings/arm/atmel-aic.txt b/Documentation/devicetree/bindings/arm/atmel-aic.txt
new file mode 100644
index 0000000..ade2761
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/atmel-aic.txt
@@ -0,0 +1,38 @@
+* Advanced Interrupt Controller (AIC)
+
+Required properties:
+- compatible: Should be "atmel,<chip>-dma"
+- interrupt-controller: Identifies the node as an interrupt controller.
+- interrupt-parent: For single AIC system, it is an empty property.
+- #interrupt-cells: The number of cells to define the interrupts. It sould be 2.
+ The first cell is the GPIO number.
+ The second cell is used to specify flags:
+ bits[3:0] trigger type and level flags:
+ 1 = low-to-high edge triggered.
+ 2 = high-to-low edge triggered.
+ 4 = active high level-sensitive.
+ 8 = active low level-sensitive.
+ Valid combinations are 1, 2, 3, 4, 8.
+ Default flag for internal sources should be set to 4 (active high).
+- reg: Should contain AIC registers location and length
+
+Examples:
+ /*
+ * AIC
+ */
+ aic: interrupt-controller@fffff000 {
+ compatible = "atmel,at91rm9200-aic";
+ interrupt-controller;
+ interrupt-parent;
+ #interrupt-cells = <2>;
+ reg = <0xfffff000 0x200>;
+ };
+
+ /*
+ * An interrupt generating device that is wired to an AIC.
+ */
+ dma: dma-controller@ffffec00 {
+ compatible = "atmel,at91sam9g45-dma";
+ reg = <0xffffec00 0x200>;
+ interrupts = <21 4>;
+ };
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 57e16d4..b33603a 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -318,6 +318,7 @@ config ARCH_AT91
select ARCH_REQUIRE_GPIOLIB
select HAVE_CLK
select CLKDEV_LOOKUP
+ select IRQ_DOMAIN
help
This enables support for systems based on the Atmel AT91RM9200,
AT91SAM9 and AT91CAP9 processors.
diff --git a/arch/arm/boot/dts/at91sam9g20.dtsi b/arch/arm/boot/dts/at91sam9g20.dtsi
index aeef042..0782f80 100644
--- a/arch/arm/boot/dts/at91sam9g20.dtsi
+++ b/arch/arm/boot/dts/at91sam9g20.dtsi
@@ -47,7 +47,7 @@
ranges;
aic: interrupt-controller@fffff000 {
- #interrupt-cells = <1>;
+ #interrupt-cells = <2>;
compatible = "atmel,at91rm9200-aic";
interrupt-controller;
interrupt-parent;
@@ -57,14 +57,14 @@
dbgu: serial@fffff200 {
compatible = "atmel,at91sam9260-usart";
reg = <0xfffff200 0x200>;
- interrupts = <1>;
+ interrupts = <1 4>;
status = "disabled";
};
usart0: serial@fffb0000 {
compatible = "atmel,at91sam9260-usart";
reg = <0xfffb0000 0x200>;
- interrupts = <6>;
+ interrupts = <6 4>;
atmel,use-dma-rx;
atmel,use-dma-tx;
status = "disabled";
@@ -73,7 +73,7 @@
usart1: serial@fffb4000 {
compatible = "atmel,at91sam9260-usart";
reg = <0xfffb4000 0x200>;
- interrupts = <7>;
+ interrupts = <7 4>;
atmel,use-dma-rx;
atmel,use-dma-tx;
status = "disabled";
@@ -82,7 +82,7 @@
usart2: serial@fffb8000 {
compatible = "atmel,at91sam9260-usart";
reg = <0xfffb8000 0x200>;
- interrupts = <8>;
+ interrupts = <8 4>;
atmel,use-dma-rx;
atmel,use-dma-tx;
status = "disabled";
@@ -91,7 +91,7 @@
usart3: serial@fffd0000 {
compatible = "atmel,at91sam9260-usart";
reg = <0xfffd0000 0x200>;
- interrupts = <23>;
+ interrupts = <23 4>;
atmel,use-dma-rx;
atmel,use-dma-tx;
status = "disabled";
@@ -100,7 +100,7 @@
usart4: serial@fffd4000 {
compatible = "atmel,at91sam9260-usart";
reg = <0xfffd4000 0x200>;
- interrupts = <24>;
+ interrupts = <24 4>;
atmel,use-dma-rx;
atmel,use-dma-tx;
status = "disabled";
@@ -109,7 +109,7 @@
usart5: serial@fffd8000 {
compatible = "atmel,at91sam9260-usart";
reg = <0xfffd8000 0x200>;
- interrupts = <25>;
+ interrupts = <25 4>;
atmel,use-dma-rx;
atmel,use-dma-tx;
status = "disabled";
diff --git a/arch/arm/boot/dts/at91sam9g45.dtsi b/arch/arm/boot/dts/at91sam9g45.dtsi
index db6a452..e89b1d7 100644
--- a/arch/arm/boot/dts/at91sam9g45.dtsi
+++ b/arch/arm/boot/dts/at91sam9g45.dtsi
@@ -46,7 +46,7 @@
ranges;
aic: interrupt-controller@fffff000 {
- #interrupt-cells = <1>;
+ #interrupt-cells = <2>;
compatible = "atmel,at91rm9200-aic";
interrupt-controller;
interrupt-parent;
@@ -56,20 +56,20 @@
dma: dma-controller@ffffec00 {
compatible = "atmel,at91sam9g45-dma";
reg = <0xffffec00 0x200>;
- interrupts = <21>;
+ interrupts = <21 4>;
};
dbgu: serial@ffffee00 {
compatible = "atmel,at91sam9260-usart";
reg = <0xffffee00 0x200>;
- interrupts = <1>;
+ interrupts = <1 4>;
status = "disabled";
};
usart0: serial@fff8c000 {
compatible = "atmel,at91sam9260-usart";
reg = <0xfff8c000 0x200>;
- interrupts = <7>;
+ interrupts = <7 4>;
atmel,use-dma-rx;
atmel,use-dma-tx;
status = "disabled";
@@ -78,7 +78,7 @@
usart1: serial@fff90000 {
compatible = "atmel,at91sam9260-usart";
reg = <0xfff90000 0x200>;
- interrupts = <8>;
+ interrupts = <8 4>;
atmel,use-dma-rx;
atmel,use-dma-tx;
status = "disabled";
@@ -87,7 +87,7 @@
usart2: serial@fff94000 {
compatible = "atmel,at91sam9260-usart";
reg = <0xfff94000 0x200>;
- interrupts = <9>;
+ interrupts = <9 4>;
atmel,use-dma-rx;
atmel,use-dma-tx;
status = "disabled";
@@ -96,7 +96,7 @@
usart3: serial@fff98000 {
compatible = "atmel,at91sam9260-usart";
reg = <0xfff98000 0x200>;
- interrupts = <10>;
+ interrupts = <10 4>;
atmel,use-dma-rx;
atmel,use-dma-tx;
status = "disabled";
diff --git a/arch/arm/mach-at91/irq.c b/arch/arm/mach-at91/irq.c
index be6b639..1c13a2c 100644
--- a/arch/arm/mach-at91/irq.c
+++ b/arch/arm/mach-at91/irq.c
@@ -24,6 +24,9 @@
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/types.h>
+#include <linux/of_address.h>
+#include <linux/of_irq.h>
+#include <linux/irqdomain.h>
#include <mach/hardware.h>
#include <asm/irq.h>
@@ -34,6 +37,7 @@
#include <asm/mach/map.h>
void __iomem *at91_aic_base;
+static struct irq_domain at91_aic_domain;
static void at91_aic_mask_irq(struct irq_data *d)
{
@@ -127,6 +131,29 @@ static struct irq_chip at91_aic_chip = {
.irq_set_wake = at91_aic_set_wake,
};
+#if defined(CONFIG_OF)
+static int __init __at91_aic_of_init(struct device_node *node,
+ struct device_node *parent)
+{
+ at91_aic_base = of_iomap(node, 0);
+ at91_aic_domain.of_node = of_node_get(node);
+
+ return 0;
+}
+
+static const struct of_device_id aic_ids[] __initconst = {
+ { .compatible = "atmel,at91rm9200-aic", .data = __at91_aic_of_init },
+ { /*sentinel*/ }
+};
+
+static void __init at91_aic_of_init(void)
+{
+ of_irq_init(aic_ids);
+}
+#else
+static void __init at91_aic_of_init(void) {}
+#endif
+
/*
* Initialize the AIC interrupt controller.
*/
@@ -134,10 +161,13 @@ void __init at91_aic_init(unsigned int priority[NR_AIC_IRQS])
{
unsigned int i;
- at91_aic_base = ioremap(AT91_AIC, 512);
+ if(of_have_populated_dt())
+ at91_aic_of_init();
+ else
+ at91_aic_base = ioremap(AT91_AIC, 512);
if (!at91_aic_base)
- panic("Impossible to ioremap AT91_AIC\n");
+ panic("Unable to ioremap AIC registers\n");
/*
* The IVR is used by macro get_irqnr_and_base to read and verify.
@@ -169,4 +199,10 @@ void __init at91_aic_init(unsigned int priority[NR_AIC_IRQS])
/* Disable and clear all interrupts initially */
at91_aic_write(AT91_AIC_IDCR, 0xFFFFFFFF);
at91_aic_write(AT91_AIC_ICCR, 0xFFFFFFFF);
+
+ /* Add irq domain for AIC */
+ at91_aic_domain.irq_base = at91_aic_domain.hwirq_base = 0;
+ at91_aic_domain.nr_irq = NR_AIC_IRQS;
+ at91_aic_domain.ops = &irq_domain_simple_ops;
+ irq_domain_add(&at91_aic_domain);
}
--
1.7.5.4
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH v3 1/3] ARM: at91/aic: add irq domain and device tree support
2011-12-01 15:42 ` [PATCH v3 1/3] ARM: at91/aic: add irq domain and device tree support Nicolas Ferre
@ 2011-12-06 6:34 ` Jean-Christophe PLAGNIOL-VILLARD
0 siblings, 0 replies; 12+ messages in thread
From: Jean-Christophe PLAGNIOL-VILLARD @ 2011-12-06 6:34 UTC (permalink / raw)
To: Nicolas Ferre
Cc: linux-arm-kernel, robherring2, grant.likely, devicetree-discuss,
linux-kernel
On 16:42 Thu 01 Dec , Nicolas Ferre wrote:
> Add an irqdomain for the AIC interrupt controller.
> The device tree support is mapping the registers and
> is using the irq_domain_simple_ops to manage hwirq
> translation.
> The documentation is describing the meaning of the
> two cells required for using this "interrupt-controller"
> in a device tree node.
>
> Signed-off-by: Nicolas Ferre <nicolas.ferre@atmel.com>
> ---
> This patch should go on top of Jamie's patch:
> "irqdomain: export irq_domain_simple_ops for !CONFIG_OF"
> https://lkml.org/lkml/2011/12/1/109
>
> v3: - change number of cells to define an AIC interrupt (irq trigger type)
> - change current .dtsi files to match specification
> - use irq_domain_simple_ops (for DT mapping)
>
> v2: - use of_irq_init() function for device tree probing
> - add documentation
> - use own simple struct irq_domain_ops
just one stuff missing the definition of the external irq
Best Regards,
J.
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2011-12-06 6:37 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-11-24 21:56 [PATCH 1/3] ARM: at91/aic: add device tree support for AIC Nicolas Ferre
2011-11-24 21:56 ` [PATCH 2/3] ARM: at91/gpio: add irqdomain to gpio interrupts Nicolas Ferre
2011-11-25 15:36 ` Rob Herring
2011-11-24 21:56 ` [PATCH 3/3] ARM: at91/board-dt: remove AIC irq domain from board file Nicolas Ferre
2011-11-24 22:26 ` [PATCH 1/3] ARM: at91/aic: add device tree support for AIC Jamie Iles
2011-11-25 13:51 ` Jean-Christophe PLAGNIOL-VILLARD
2011-11-25 15:28 ` Jamie Iles
2011-11-29 13:04 ` Nicolas Ferre
2011-11-29 13:56 ` Nicolas Ferre
2011-11-29 18:07 ` [PATCH v2 " Nicolas Ferre
2011-12-01 15:42 ` [PATCH v3 1/3] ARM: at91/aic: add irq domain and device tree support Nicolas Ferre
2011-12-06 6:34 ` Jean-Christophe PLAGNIOL-VILLARD
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).