Skip to contentSkip to conversation

ARM: at91: move aic driver to drivers/irqchips

RFC PATCH In review Boris BREZILLON 4 participants 19 messages Mar 28, 2014 – Mar 30, 2014

Subsystems (6)
lore
Share & tools
lore
#0 lore raw

v2 cover ARM: at91: move aic driver to drivers/irqchips

Hello,

This series is a proposal to move AIC driver to the irqchip directory.

It also changes the implementation design of the interrupt controller in several ways:
- make use of the generic chip framework whenever possible
- add support for irq muxing definition to prevent spurious interrupts during system startup (see https://lkml.org/lkml/2013/3/8/175)
- only support dt enabled boards

Best Regards,

Boris

Changes since v1:
- rework the irq-mux bindings

Boris BREZILLON (10):
genirq: generic chip: export irq_map_generic_chip function
irqchip: atmel-aic: add new atmel AIC driver
ARM: at91: introduce OLD_IRQ_AT91 Kconfig option
ARM: at91: enclose at91_aic_xx calls in
IS_ENABLED(CONFIG_OLD_IRQ_AT91) blocks
ARM: at91: make use of the new AIC driver for dt enabled boards
irqchip: atmel-aic: move binding doc to interrupt-controller
directory
irqchip: atmel-aic: document new dt properties and children nodes
ARM: at91: remove old irq material
ARM: at91/dt: add new AIC irq mux definitions for sam9x5 SoCs
ARM: at91/dt: add new AIC irq mux definitions for sama5 SoCs

 .../devicetree/bindings/arm/atmel-aic.txt          |   42 -
 .../bindings/interrupt-controller/atmel,aic.txt    |   82 ++
 arch/arm/boot/dts/at91sam9x5.dtsi                  |  108 +++
 arch/arm/boot/dts/sama5d3.dtsi                     |   37 +
 arch/arm/boot/dts/sama5d3_tcb1.dtsi                |   20 +
 arch/arm/mach-at91/Kconfig                         |   11 +
 arch/arm/mach-at91/Kconfig.non_dt                  |    7 +
 arch/arm/mach-at91/Makefile                        |    3 +-
 arch/arm/mach-at91/board-dt-rm9200.c               |   13 -
 arch/arm/mach-at91/board-dt-sam9.c                 |   14 -
 arch/arm/mach-at91/board-dt-sama5.c                |   13 -
 arch/arm/mach-at91/irq.c                           |  270 +------
 arch/arm/mach-at91/pm.c                            |   32 +-
 arch/arm/mach-at91/setup.c                         |    3 +-
 drivers/irqchip/Makefile                           |    1 +
 drivers/irqchip/irq-atmel-aic.c                    |  851 ++++++++++++++++++++
 include/linux/irq.h                                |    2 +
 kernel/irq/generic-chip.c                          |    5 +-
 18 files changed, 1152 insertions(+), 362 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/arm/atmel-aic.txt
 create mode 100644 Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt
 create mode 100644 drivers/irqchip/irq-atmel-aic.c
Signature · 1 line
1.7.9.5
#1 lore raw

RFC PATCH v2 1/10 genirq: generic chip: export irq_map_generic_chip function

Export the generic irq map function in order to provide irq_domain ops with generic mapping and specific of xlate function (needed by the new atmel AIC driver).

---
 include/linux/irq.h       |    2 ++
 kernel/irq/generic-chip.c |    5 +++--
 2 files changed, 5 insertions(+), 2 deletions(-)
include/linux/irq.h +2 -0
index 7dc1003..19b5e3b 100644
@@ -765,6 +765,8 @@ void irq_gc_eoi(struct irq_data *d);
 int irq_gc_set_wake(struct irq_data *d, unsigned int on);
 
 /* Setup functions for irq_chip_generic */
+int irq_map_generic_chip(struct irq_domain *d, unsigned int virq,
+			 irq_hw_number_t hw_irq);
 struct irq_chip_generic *
 irq_alloc_generic_chip(const char *name, int nr_ct, unsigned int irq_base,
 		       void __iomem *reg_base, irq_flow_handler_t handler);
kernel/irq/generic-chip.c +3 -2
index 452d6f2..cf80e7b 100644
@@ -341,8 +341,8 @@ static struct lock_class_key irq_nested_lock_class;
 /*
  * irq_map_generic_chip - Map a generic chip for an irq domain
  */
-static int irq_map_generic_chip(struct irq_domain *d, unsigned int virq,
-				irq_hw_number_t hw_irq)
+int irq_map_generic_chip(struct irq_domain *d, unsigned int virq,
+			 irq_hw_number_t hw_irq)
 {
 	struct irq_data *data = irq_get_irq_data(virq);
 	struct irq_domain_chip_generic *dgc = d->gc;
@@ -394,6 +394,7 @@ static int irq_map_generic_chip(struct irq_domain *d, unsigned int virq,
 	irq_modify_status(virq, dgc->irq_flags_to_clear, dgc->irq_flags_to_set);
 	return 0;
 }
+EXPORT_SYMBOL_GPL(irq_map_generic_chip);
 
 struct irq_domain_ops irq_generic_chip_ops = {
 	.map	= irq_map_generic_chip,
Signature · 1 line
1.7.9.5
#2 lore raw

RFC PATCH v2 2/10 irqchip: atmel-aic: add new atmel AIC driver

In reply to Boris BREZILLON

Add new atmel AIC (Advanced Interrupt Controller) driver based on the generic chip infrastructure.

This driver is only compatible with dt enabled board and replaces the old implementation found in arch/arm/mach-at91/irq.c.

It also provides a new way to handle AIC irq line muxing to avoid spurious interrupts on startup and shutdown:
- disable all muxed interrupts during AIC probe
- disable every muxed interrupt attached to a specific AIC interrupt line when this interrupt is disabled

---
 drivers/irqchip/Makefile        |    1 +
 drivers/irqchip/irq-atmel-aic.c |  851 +++++++++++++++++++++++++++++++++++++++
 2 files changed, 852 insertions(+)
 create mode 100644 drivers/irqchip/irq-atmel-aic.c
drivers/irqchip/Makefile +1 -0
index 5194afb..b2950860 100644
@@ -16,6 +16,7 @@ obj-$(CONFIG_ARCH_SPEAR3XX)		+= spear-shirq.o
 obj-$(CONFIG_ARM_GIC)			+= irq-gic.o
 obj-$(CONFIG_ARM_NVIC)			+= irq-nvic.o
 obj-$(CONFIG_ARM_VIC)			+= irq-vic.o
+obj-$(CONFIG_ATMEL_AIC_IRQ)		+= irq-atmel-aic.o
 obj-$(CONFIG_IMGPDC_IRQ)		+= irq-imgpdc.o
 obj-$(CONFIG_SIRF_IRQ)			+= irq-sirfsoc.o
 obj-$(CONFIG_RENESAS_INTC_IRQPIN)	+= irq-renesas-intc-irqpin.o
drivers/irqchip/irq-atmel-aic.c new file +851 -0

851 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#3 lore raw

RFC PATCH v2 3/10 ARM: at91: introduce OLD_IRQ_AT91 Kconfig option

In reply to Boris BREZILLON

Introduce a new Kconfig option OLD_IRQ_AT91 to prepare migration to the new AIC driver.

Enable this option for all supported at91 SoCs (both dt and non-dt boards).

---
 arch/arm/mach-at91/Kconfig        |    7 +++++++
 arch/arm/mach-at91/Kconfig.non_dt |    7 +++++++
 arch/arm/mach-at91/Makefile       |    3 ++-
 3 files changed, 16 insertions(+), 1 deletion(-)
arch/arm/mach-at91/Kconfig +7 -0
index 4f0e800..4f0b3e0 100644
@@ -28,6 +28,10 @@ config OLD_CLK_AT91
 	bool
 	default AT91_PMC_UNIT && AT91_USE_OLD_CLK
 
+config OLD_IRQ_AT91
+	bool
+	default false
+
 config AT91_SAM9_ALT_RESET
 	bool
 	default !ARCH_AT91X40
@@ -189,6 +193,7 @@ config MACH_AT91RM9200_DT
 	bool "Atmel AT91RM9200 Evaluation Kits with device-tree support"
 	depends on SOC_AT91RM9200
 	select USE_OF
+	select OLD_IRQ_AT91
 	help
 	  Select this if you want to experiment device-tree with
 	  an Atmel RM9200 Evaluation Kit.
@@ -197,6 +202,7 @@ config MACH_AT91SAM9_DT
 	bool "Atmel AT91SAM Evaluation Kits with device-tree support"
 	depends on SOC_AT91SAM9
 	select USE_OF
+	select OLD_IRQ_AT91
 	help
 	  Select this if you want to experiment device-tree with
 	  an Atmel Evaluation Kit.
@@ -205,6 +211,7 @@ config MACH_SAMA5_DT
 	bool "Atmel SAMA5 Evaluation Kits with device-tree support"
 	depends on SOC_SAMA5
 	select USE_OF
+	select OLD_IRQ_AT91
 	select PHYLIB if NETDEVICES
 	help
 	  Select this if you want to experiment device-tree with
arch/arm/mach-at91/Kconfig.non_dt +7 -0
index 1f73e9b..75b582e 100644
@@ -13,31 +13,37 @@ config ARCH_AT91RM9200
 	bool "AT91RM9200"
 	select SOC_AT91RM9200
 	select AT91_USE_OLD_CLK
+	select OLD_IRQ_AT91
 
 config ARCH_AT91SAM9260
 	bool "AT91SAM9260 or AT91SAM9XE or AT91SAM9G20"
 	select SOC_AT91SAM9260
 	select AT91_USE_OLD_CLK
+	select OLD_IRQ_AT91
 
 config ARCH_AT91SAM9261
 	bool "AT91SAM9261 or AT91SAM9G10"
 	select SOC_AT91SAM9261
 	select AT91_USE_OLD_CLK
+	select OLD_IRQ_AT91
 
 config ARCH_AT91SAM9263
 	bool "AT91SAM9263"
 	select SOC_AT91SAM9263
 	select AT91_USE_OLD_CLK
+	select OLD_IRQ_AT91
 
 config ARCH_AT91SAM9RL
 	bool "AT91SAM9RL"
 	select SOC_AT91SAM9RL
 	select AT91_USE_OLD_CLK
+	select OLD_IRQ_AT91
 
 config ARCH_AT91SAM9G45
 	bool "AT91SAM9G45"
 	select SOC_AT91SAM9G45
 	select AT91_USE_OLD_CLK
+	select OLD_IRQ_AT91
 
 config ARCH_AT91X40
 	bool "AT91x40"
@@ -45,6 +51,7 @@ config ARCH_AT91X40
 	select ARCH_USES_GETTIMEOFFSET
 	select MULTI_IRQ_HANDLER
 	select SPARSE_IRQ
+	select OLD_IRQ_AT91
 
 endchoice
 
arch/arm/mach-at91/Makefile +2 -1
index 78e9cec..d972fd6 100644
@@ -2,11 +2,12 @@
 # Makefile for the linux kernel.
 #
 
-obj-y		:= irq.o gpio.o setup.o sysirq_mask.o
+obj-y		:= gpio.o setup.o sysirq_mask.o
 obj-m		:=
 obj-n		:=
 obj-		:=
 
+obj-$(CONFIG_OLD_IRQ_AT91)	+= irq.o
 obj-$(CONFIG_OLD_CLK_AT91)	+= clock.o
 obj-$(CONFIG_AT91_SAM9_ALT_RESET) += at91sam9_alt_reset.o
 obj-$(CONFIG_AT91_SAM9G45_RESET) += at91sam9g45_reset.o
Signature · 1 line
1.7.9.5
#4 lore raw

Re: [RFC PATCH v2 03/10] ARM: at91: introduce OLD_IRQ_AT91 Kconfig option

Dear Boris BREZILLON,

arch/arm/mach-at91/Kconfig config OLD_CLK_AT91 · line 33

Quoted 3 lines · Boris BREZILLON
arch/arm/mach-at91/Kconfig +3 -0
+config OLD_IRQ_AT91
+	bool
+	default false

I don't think "default false" is a valid Kconfig construct. It could be "default n", but that's useless since "default n" is the default behavior. So I believe you can simply get rid of that line.

Thomas

Signature · 3 lines
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
#5 lore raw

Re: [RFC PATCH v2 03/10] ARM: at91: introduce OLD_IRQ_AT91 Kconfig option

Quoted 11 lines · On Saturday 29 March 2014 10:06:39 Thomas Petazzoni wrote:

Dear Boris BREZILLON,

arch/arm/mach-at91/Kconfig config OLD_CLK_AT91 · line 33

Quoted 3 lines · Boris BREZILLON
arch/arm/mach-at91/Kconfig +3 -0
+config OLD_IRQ_AT91
+     bool
+     default false

I don't think "default false" is a valid Kconfig construct. It could be "default n", but that's useless since "default n" is the default behavior. So I believe you can simply get rid of that line.

I think the above is syntactically correct, but it would be highly confusing in anyone ever does

config false
def_bool y

;-)

Aside from that, these three have completely identical meaning:

config OLD_IRQ_AT91
bool

config OLD_IRQ_AT91
def_bool n

config OLD_IRQ_AT91
bool
default n

Arnd

#6 lore raw

Re: [RFC PATCH v2 03/10] ARM: at91: introduce OLD_IRQ_AT91 Kconfig option

Le 29/03/2014 10:12, Arnd Bergmann a ?crit :

Quoted 11 lines · On Saturday 29 March 2014 10:06:39 Thomas Petazzoni wrote:
Quoted 10 lines

Dear Boris BREZILLON,

arch/arm/mach-at91/Kconfig config OLD_CLK_AT91 · line 33

Quoted 3 lines · Boris BREZILLON
arch/arm/mach-at91/Kconfig +3 -0
+config OLD_IRQ_AT91
+     bool
+     default false

I don't think "default false" is a valid Kconfig construct. It could be "default n", but that's useless since "default n" is the default behavior. So I believe you can simply get rid of that line.

I'll fix it for the next version.

Quoted 13 lines

I think the above is syntactically correct, but it would be highly confusing in anyone ever does

config false
def_bool y

;-)

Aside from that, these three have completely identical meaning:

config OLD_IRQ_AT91
bool

Quoted 10 lines

config OLD_IRQ_AT91
def_bool n

config OLD_IRQ_AT91
bool
default n

Arnd

Thanks for the detailled explanation :-).

Best Regards,

Boris

#7 lore raw

RFC PATCH v2 4/10 ARM: at91: enclose at91_aic_xx calls in IS_ENABLED(CONFIG_OLD_IRQ_AT91) blocks

In reply to Boris BREZILLON

Enclose at91_aic_xx calls in IS_ENABLED(CONFIG_OLD_IRQ_AT91) blocks in order to prepare the migration to the new AIC driver.

In the new AIC driver the suspend/resume functions are called by the generic irq framework and are no longer needed in the PM specific code.

Moreover, the new AIC driver no longer exposes the at91_aic_base variable which is used by the at91_aic_read functions.

---
 arch/arm/mach-at91/pm.c    |   32 ++++++++++++++++++++------------
 arch/arm/mach-at91/setup.c |    3 ++-
 2 files changed, 22 insertions(+), 13 deletions(-)
arch/arm/mach-at91/pm.c +20 -12
index 590b52d..b9f4c5c 100644
@@ -204,16 +204,19 @@ static int at91_pm_enter(suspend_state_t state)
 		at91_pinctrl_gpio_suspend();
 	else
 		at91_gpio_suspend();
-	at91_irq_suspend();
 
-	pr_debug("AT91: PM - wake mask %08x, pm state %d\n",
-			/* remember all the always-wake irqs */
-			(at91_pmc_read(AT91_PMC_PCSR)
-					| (1 << AT91_ID_FIQ)
-					| (1 << AT91_ID_SYS)
-					| (at91_get_extern_irq()))
-				& at91_aic_read(AT91_AIC_IMR),
-			state);
+	if (IS_ENABLED(CONFIG_OLD_IRQ_AT91) && at91_aic_base) {
+		at91_irq_suspend();
+
+		pr_debug("AT91: PM - wake mask %08x, pm state %d\n",
+				/* remember all the always-wake irqs */
+				(at91_pmc_read(AT91_PMC_PCSR)
+						| (1 << AT91_ID_FIQ)
+						| (1 << AT91_ID_SYS)
+						| (at91_get_extern_irq()))
+					& at91_aic_read(AT91_AIC_IMR),
+				state);
+	}
 
 	switch (state) {
 		/*
@@ -278,12 +281,17 @@ static int at91_pm_enter(suspend_state_t state)
 			goto error;
 	}
 
-	pr_debug("AT91: PM - wakeup %08x\n",
-			at91_aic_read(AT91_AIC_IPR) & at91_aic_read(AT91_AIC_IMR));
+	if (IS_ENABLED(CONFIG_OLD_IRQ_AT91) && at91_aic_base)
+		pr_debug("AT91: PM - wakeup %08x\n",
+			 at91_aic_read(AT91_AIC_IPR) &
+			 at91_aic_read(AT91_AIC_IMR));
 
 error:
 	target_state = PM_SUSPEND_ON;
-	at91_irq_resume();
+
+	if (IS_ENABLED(CONFIG_OLD_IRQ_AT91) && at91_aic_base)
+		at91_irq_resume();
+
 	if (of_have_populated_dt())
 		at91_pinctrl_gpio_resume();
 	else
arch/arm/mach-at91/setup.c +2 -1
index f7ca97b..1d8a6c8 100644
@@ -49,7 +49,8 @@ void __init at91_init_irq_default(void)
 void __init at91_init_interrupts(unsigned int *priority)
 {
 	/* Initialize the AIC interrupt controller */
-	at91_aic_init(priority, at91_boot_soc.extern_irq);
+	if (IS_ENABLED(CONFIG_OLD_IRQ_AT91))
+		at91_aic_init(priority, at91_boot_soc.extern_irq);
 
 	/* Enable GPIO interrupts */
 	at91_gpio_irq_setup();
Signature · 1 line
1.7.9.5
#8 lore raw

RFC PATCH v2 5/10 ARM: at91: make use of the new AIC driver for dt enabled boards

In reply to Boris BREZILLON

Add a new Kconfig option for the new AIC driver (drivers/irqchip/irq-atmel-aic.c) and remove selection of OLD_IRQ_AT91 when selecting dt boards.

Remove specific irq init code in all dt board files: this init procedure is automatically handled in of_irq_init which is called by the arm irq core code and is in charge of calling the appropriate aic init functions.

---
 arch/arm/mach-at91/Kconfig           |   10 +++++++---
 arch/arm/mach-at91/board-dt-rm9200.c |   13 -------------
 arch/arm/mach-at91/board-dt-sam9.c   |   14 --------------
 arch/arm/mach-at91/board-dt-sama5.c  |   13 -------------
 4 files changed, 7 insertions(+), 43 deletions(-)
arch/arm/mach-at91/Kconfig +7 -3
index 4f0b3e0..7e75c4d 100644
@@ -32,6 +32,13 @@ config OLD_IRQ_AT91
 	bool
 	default false
 
+config ATMEL_AIC_IRQ
+	bool
+	default USE_OF
+	select GENERIC_IRQ_CHIP
+	select IRQ_DOMAIN
+	select MULTI_IRQ_HANDLER
+
 config AT91_SAM9_ALT_RESET
 	bool
 	default !ARCH_AT91X40
@@ -193,7 +200,6 @@ config MACH_AT91RM9200_DT
 	bool "Atmel AT91RM9200 Evaluation Kits with device-tree support"
 	depends on SOC_AT91RM9200
 	select USE_OF
-	select OLD_IRQ_AT91
 	help
 	  Select this if you want to experiment device-tree with
 	  an Atmel RM9200 Evaluation Kit.
@@ -202,7 +208,6 @@ config MACH_AT91SAM9_DT
 	bool "Atmel AT91SAM Evaluation Kits with device-tree support"
 	depends on SOC_AT91SAM9
 	select USE_OF
-	select OLD_IRQ_AT91
 	help
 	  Select this if you want to experiment device-tree with
 	  an Atmel Evaluation Kit.
@@ -211,7 +216,6 @@ config MACH_SAMA5_DT
 	bool "Atmel SAMA5 Evaluation Kits with device-tree support"
 	depends on SOC_SAMA5
 	select USE_OF
-	select OLD_IRQ_AT91
 	select PHYLIB if NETDEVICES
 	help
 	  Select this if you want to experiment device-tree with
arch/arm/mach-at91/board-dt-rm9200.c +0 -13
index 3a185fa..61ea214 100644
@@ -24,17 +24,6 @@
 #include "at91_aic.h"
 #include "generic.h"
 
-
-static const struct of_device_id irq_of_match[] __initconst = {
-	{ .compatible = "atmel,at91rm9200-aic", .data = at91_aic_of_init },
-	{ /*sentinel*/ }
-};
-
-static void __init at91rm9200_dt_init_irq(void)
-{
-	of_irq_init(irq_of_match);
-}
-
 static const char *at91rm9200_dt_board_compat[] __initdata = {
 	"atmel,at91rm9200",
 	NULL
@@ -43,8 +32,6 @@ static const char *at91rm9200_dt_board_compat[] __initdata = {
 DT_MACHINE_START(at91rm9200_dt, "Atmel AT91RM9200 (Device Tree)")
 	.init_time      = at91rm9200_timer_init,
 	.map_io		= at91_map_io,
-	.handle_irq	= at91_aic_handle_irq,
 	.init_early	= at91rm9200_dt_initialize,
-	.init_irq	= at91rm9200_dt_init_irq,
 	.dt_compat	= at91rm9200_dt_board_compat,
 MACHINE_END
arch/arm/mach-at91/board-dt-sam9.c +0 -14
index 3dab868..d4073c0 100644
@@ -20,22 +20,10 @@
 #include <asm/mach/map.h>
 #include <asm/mach/irq.h>
 
-#include "at91_aic.h"
 #include "board.h"
 #include "generic.h"
 
 
-static const struct of_device_id irq_of_match[] __initconst = {
-
-	{ .compatible = "atmel,at91rm9200-aic", .data = at91_aic_of_init },
-	{ /*sentinel*/ }
-};
-
-static void __init at91_dt_init_irq(void)
-{
-	of_irq_init(irq_of_match);
-}
-
 static const char *at91_dt_board_compat[] __initdata = {
 	"atmel,at91sam9",
 	NULL
@@ -45,8 +33,6 @@ DT_MACHINE_START(at91sam_dt, "Atmel AT91SAM (Device Tree)")
 	/* Maintainer: Atmel */
 	.init_time	= at91sam926x_pit_init,
 	.map_io		= at91_map_io,
-	.handle_irq	= at91_aic_handle_irq,
 	.init_early	= at91_dt_initialize,
-	.init_irq	= at91_dt_init_irq,
 	.dt_compat	= at91_dt_board_compat,
 MACHINE_END
arch/arm/mach-at91/board-dt-sama5.c +0 -13
index 075ec05..d6fe04b 100644
@@ -35,17 +35,6 @@ static void __init sama5_dt_timer_init(void)
 	at91sam926x_pit_init();
 }
 
-static const struct of_device_id irq_of_match[] __initconst = {
-
-	{ .compatible = "atmel,sama5d3-aic", .data = at91_aic5_of_init },
-	{ /*sentinel*/ }
-};
-
-static void __init at91_dt_init_irq(void)
-{
-	of_irq_init(irq_of_match);
-}
-
 static int ksz9021rn_phy_fixup(struct phy_device *phy)
 {
 	int value;
@@ -82,9 +71,7 @@ DT_MACHINE_START(sama5_dt, "Atmel SAMA5 (Device Tree)")
 	/* Maintainer: Atmel */
 	.init_time	= sama5_dt_timer_init,
 	.map_io		= at91_map_io,
-	.handle_irq	= at91_aic5_handle_irq,
 	.init_early	= at91_dt_initialize,
-	.init_irq	= at91_dt_init_irq,
 	.init_machine	= sama5_dt_device_init,
 	.dt_compat	= sama5_dt_board_compat,
 MACHINE_END
Signature · 1 line
1.7.9.5
#9 lore raw

Re: [RFC PATCH v2 05/10] ARM: at91: make use of the new AIC driver for dt enabled boards

Dear Boris BREZILLON,

arch/arm/mach-at91/Kconfig config OLD_IRQ_AT91 · line 40

Quoted 6 lines · Boris BREZILLON
arch/arm/mach-at91/Kconfig +6 -0
+config ATMEL_AIC_IRQ
+	bool
+	default USE_OF
+	select GENERIC_IRQ_CHIP
+	select IRQ_DOMAIN
+	select MULTI_IRQ_HANDLER

This option should probably go in drivers/irqchip/Kconfig, no?

Thomas

Signature · 3 lines
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
#10 lore raw

Re: [RFC PATCH v2 05/10] ARM: at91: make use of the new AIC driver for dt enabled boards

Hello Thomas,

Le 29/03/2014 10:07, Thomas Petazzoni a ?crit :

Quoted 11 lines

Dear Boris BREZILLON,

arch/arm/mach-at91/Kconfig config OLD_IRQ_AT91 · line 40

Quoted 6 lines · Boris BREZILLON
arch/arm/mach-at91/Kconfig +6 -0
+config ATMEL_AIC_IRQ
+	bool
+	default USE_OF
+	select GENERIC_IRQ_CHIP
+	select IRQ_DOMAIN
+	select MULTI_IRQ_HANDLER

This option should probably go in drivers/irqchip/Kconfig, no?

Absolutely, I'll move this section into drivers/irqchip/Kconfig.

Best Regards,

Boris

Quoted 2 lines

Thomas

#11 lore raw

RFC PATCH v2 6/10 irqchip: atmel-aic: move binding doc to interrupt-controller directory

In reply to Boris BREZILLON

Move atmel aic driver doc to the interrupt-controller directory as the new driver now lays in drivers/irqchip/atmel-aic.c.

---
 .../atmel,aic.txt}                                 |    0
 1 file changed, 0 insertions(+), 0 deletions(-)
 rename Documentation/devicetree/bindings/{arm/atmel-aic.txt => interrupt-controller/atmel,aic.txt} (100%)
Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt renamed from Documentation/devicetree/bindings/arm/atmel-aic.txt +0 -0
similarity index 100%
rename from Documentation/devicetree/bindings/arm/atmel-aic.txt
rename to Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt
Signature · 1 line
1.7.9.5
#12 lore raw

RFC PATCH v2 7/10 irqchip: atmel-aic: document new dt properties and children nodes

In reply to Boris BREZILLON

Add irq muxing and irq-mapping dt bindings documentation.

---
 .../bindings/interrupt-controller/atmel,aic.txt    |   42 +++++++++++++++++++-
 1 file changed, 41 insertions(+), 1 deletion(-)
Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt +41 -1
index 2742e9c..d46ec8e 100644
@@ -18,8 +18,33 @@ Required properties:
   The third cell is used to specify the irq priority from 0 (lowest) to 7
   (highest).
 - reg: Should contain AIC registers location and length
+- #address-cells: Shall be 2. The first cell encodes the irq line (or irq id).
+  The second cell encodes the register offset within the iomem range.
+- #size-cells: Shall be 1.
+- ranges: Defines the iomem ranges attached to a given irq line (e.i. irq
+  line 1 <=> SYSC range).
 - atmel,external-irqs: u32 array of external irqs.
 
+Optional properties:
+- atmel,irq-mapping: u32 mask array representing the available irqs:
+    e.i. : atmel,irq-mapping = <0xffff1fff> => irqs 13 to 15 are unavailables
+
+Optional children nodes:
+- muxed irq entries:
+  Required properties:
+   * compatible: Shall be
+     "atmel,aic-mux-1reg-irq": irq enable/disable/retrieve-status is done by
+     setting/clearing/reading flags in a specific register
+     or
+     "atmel,aic-mux-3reg-irq": irq enable/disable/retrieve-status is done
+     by writing/reading flags in specific enable/disable/mask registers
+   * reg: encode the interrupt control register.
+     The first cell encode the irq line.
+     The second cell encode the offset register within its iomem range
+     The last cell encode the iomem region size (should always be set to 0x4).
+   * atmel,aic-mux-reg-mask: define the mask used to disable the interrupts
+     generated by the muxed entry.
+
 Examples:
 	/*
 	 * AIC
@@ -29,11 +54,26 @@ Examples:
 		interrupt-controller;
 		interrupt-parent;
 		#interrupt-cells = <3>;
+		#address-cells = <2>;
+		#size-cells = <1>;
 		reg = <0xfffff000 0x200>;
+		ranges = <0x1 0x0 0xffffc000 0x4000>;
+
+		dbgu_irq: irq at 1,320c {
+			compatible = "atmel,aic-mux-3reg-irq";
+			reg = <1 0x320c 0x4>;
+			atmel,aic-mux-reg-mask = <0xc0001afb>;
+		};
+
+		pmc_irq: irq at 1,3c64 {
+			compatible = "atmel,aic-mux-3reg-irq";
+			reg = <1 0x3c64 0x4>;
+			atmel,aic-mux-reg-mask = <0xf0f>;
+		};
 	};
 
 	/*
-	 * An interrupt generating device that is wired to an AIC.
+	 * A device generating interrupts wired to the AIC.
 	 */
 	dma: dma-controller at ffffec00 {
 		compatible = "atmel,at91sam9g45-dma";
Signature · 1 line
1.7.9.5
#13 lore raw

Re: [RFC PATCH v2 07/10] irqchip: atmel-aic: document new dt properties and children nodes

Dear Boris BREZILLON,

Quoted 5 lines · Boris BREZILLON
Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt +5 -0
+Optional children nodes:
+- muxed irq entries:
+  Required properties:
+   * compatible: Shall be
+     "atmel,aic-mux-1reg-irq": irq enable/disable/retrieve-status is done by

Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt Required properties: · line 46

Quoted 10 lines
Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt +10 -0
+     setting/clearing/reading flags in a specific register
+     or
+     "atmel,aic-mux-3reg-irq": irq enable/disable/retrieve-status is done
+     by writing/reading flags in specific enable/disable/mask registers
+   * reg: encode the interrupt control register.
+     The first cell encode the irq line.
+     The second cell encode the offset register within its iomem range
+     The last cell encode the iomem region size (should always be set to 0x4).
+   * atmel,aic-mux-reg-mask: define the mask used to disable the interrupts
+     generated by the muxed entry.

Can you describe in more details what are these muxed irqs? Are they interrupts raised to the AIC that may actually be related to several devices, like a shared interrupt?

If that's the case, then what you want is to implement separate interrupt controller drivers to handle those shared interrupts, and demux them into multiple separate interrupts.

Note that the way you use the "ranges" property seems wrong to me:
you're using it as a "hack" to define the base address of some peripherals that are outside the AIC, while the ranges property is normally used to describe the address translations between a child bus and a parent bus. Which is not what you have here, as far as I can understand.

So could you give more details about the design of the AIC and these muxed interrupts, to see if the DT binding you're proposing is actually the right way of representing the hardware?

Thomas

Signature · 3 lines
Thomas Petazzoni, CTO, Free Electrons
Embedded Linux, Kernel and Android engineering
http://free-electrons.com
#14 lore raw

Re: [RFC PATCH v2 07/10] irqchip: atmel-aic: document new dt properties and children nodes

Hello Thomas,

Le 29/03/2014 10:19, Thomas Petazzoni a ?crit :

Quoted 19 lines

Dear Boris BREZILLON,

Quoted 5 lines · Boris BREZILLON
Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt +5 -0
+Optional children nodes:
+- muxed irq entries:
+  Required properties:
+   * compatible: Shall be
+     "atmel,aic-mux-1reg-irq": irq enable/disable/retrieve-status is done by

Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt Required properties: · line 46

Quoted 10 lines
Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt +10 -0
+     setting/clearing/reading flags in a specific register
+     or
+     "atmel,aic-mux-3reg-irq": irq enable/disable/retrieve-status is done
+     by writing/reading flags in specific enable/disable/mask registers
+   * reg: encode the interrupt control register.
+     The first cell encode the irq line.
+     The second cell encode the offset register within its iomem range
+     The last cell encode the iomem region size (should always be set to 0x4).
+   * atmel,aic-mux-reg-mask: define the mask used to disable the interrupts
+     generated by the muxed entry.
Quoted 3 lines

Can you describe in more details what are these muxed irqs? Are they interrupts raised to the AIC that may actually be related to several devices, like a shared interrupt?

Exactly, muxed irqs are shared irqs.

Quoted 3 lines

If that's the case, then what you want is to implement separate interrupt controller drivers to handle those shared interrupts, and demux them into multiple separate interrupts.

It may work (I'll take a look), but we may have to modify several drivers (and
it may break the DT ABI).

Quoted 7 lines

Note that the way you use the "ranges" property seems wrong to me:
you're using it as a "hack" to define the base address of some peripherals that are outside the AIC, while the ranges property is normally used to describe the address translations between a child bus and a parent bus. Which is not what you have here, as far as I can understand.

This is clearly not a real bus, but more a virtual/conceptual bus where each irq source is a bus device.

Quoted 3 lines

So could you give more details about the design of the AIC and these muxed interrupts, to see if the DT binding you're proposing is actually the right way of representing the hardware?

The AIC controller muxes several peripheral irqs to one irq line. If a given peripheral has a pending irq, and the driver requesting this irq is
not loaded (either because it was not enabled or because it is not loaded yet)
it may generate spurious interrupts (or even hang forever), waiting for someone
clearing/reading the interrupt flag(s).

See this thread for an example of what can happen if we don't disable all muxed
interrupts before enabling an IRQ line:

https://lkml.org/lkml/2013/3/8/176

In this series' implementation, I define all the muxed (or shared) interrupt entries (using the DT) and let the AIC driver disable all the interrupt sources
when shutting down an interrupt line or before starting the AIC controller.

This provides a generic solution to avoid these spurious interrupt issues instead of adding several hooks in the machine specific code (one for each impacted peripheral).

Please tell me if you see a better solution (but keep in mind, this should be
done during early init, because the at91 init timer is using a muxed irq line
on almost all at91 SoCs).

Best Regards,

Boris

Quoted 2 lines

Thomas

#15 lore raw

Re: [RFC PATCH v2 07/10] irqchip: atmel-aic: document new dt properties and children nodes

In reply to Thomas Petazzoni

Hello Thomas,

Quoted 19 lines · Thomas Petazzoni

Dear Boris BREZILLON,

Quoted 5 lines · Boris BREZILLON
Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt +5 -0
+Optional children nodes:
+- muxed irq entries:
+  Required properties:
+   * compatible: Shall be
+     "atmel,aic-mux-1reg-irq": irq enable/disable/retrieve-status is done by

Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt Required properties: · line 46

Quoted 10 lines
Documentation/devicetree/bindings/interrupt-controller/atmel,aic.txt +10 -0
+     setting/clearing/reading flags in a specific register
+     or
+     "atmel,aic-mux-3reg-irq": irq enable/disable/retrieve-status is done
+     by writing/reading flags in specific enable/disable/mask registers
+   * reg: encode the interrupt control register.
+     The first cell encode the irq line.
+     The second cell encode the offset register within its iomem range
+     The last cell encode the iomem region size (should always be set to 0x4).
+   * atmel,aic-mux-reg-mask: define the mask used to disable the interrupts
+     generated by the muxed entry.
Quoted 3 lines

Can you describe in more details what are these muxed irqs? Are they interrupts raised to the AIC that may actually be related to several devices, like a shared interrupt?

Exactly, muxed irqs are shared irqs.

Quoted 3 lines

If that's the case, then what you want is to implement separate interrupt controller drivers to handle those shared interrupts, and demux them into multiple separate interrupts.

It may work (I'll take a look), but we may have to modify several drivers (and it may break the DT ABI).

Quoted 7 lines

Note that the way you use the "ranges" property seems wrong to me:
you're using it as a "hack" to define the base address of some peripherals that are outside the AIC, while the ranges property is normally used to describe the address translations between a child bus and a parent bus. Which is not what you have here, as far as I can understand.

This is clearly not a real bus, but more a virtual/conceptual bus where each irq source is a bus device.

Quoted 3 lines

So could you give more details about the design of the AIC and these muxed interrupts, to see if the DT binding you're proposing is actually the right way of representing the hardware?

The AIC controller muxes several peripheral irqs to one irq line.
If a given peripheral has a pending irq, and the driver requesting this irq is not loaded (either because it was not enabled or because it is not loaded yet) it may generate spurious interrupts (or even hang forever), waiting for someone clearing/reading the interrupt flag(s).

See this thread for an example of what can happen if we don't disable all muxed interrupts before enabling an IRQ line:

https://lkml.org/lkml/2013/3/8/176

In this series' implementation, I define all the muxed (or shared) interrupt entries (using the DT) and let the AIC driver disable all the interrupt sources when shutting down an interrupt line or before starting the AIC controller.

This provides a generic solution to avoid these spurious interrupt issues instead of adding several hooks in the machine specific code (one for each impacted peripheral).

Please tell me if you see a better solution (but keep in mind, this should be done during early init, because the at91 init timer is using a muxed irq line on almost all at91 SoCs).

Best Regards,

Boris

Quoted 2 lines

Thomas

--
To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html

#16 lore raw

RFC PATCH v2 8/10 ARM: at91: remove old irq material

In reply to Boris BREZILLON

Remove all the material related to AIC support on dt enabled SoCs.

This is now implemented within the new AIC driver
(drivers/irqchip/atmel-aic.c).

---
 arch/arm/mach-at91/irq.c |  270 ++--------------------------------------------
 1 file changed, 6 insertions(+), 264 deletions(-)
arch/arm/mach-at91/irq.c +6 -264
index 3d192c5..cdb3ec9 100644
@@ -48,11 +48,6 @@ void __iomem *at91_aic_base;
 static struct irq_domain *at91_aic_domain;
 static struct device_node *at91_aic_np;
 static unsigned int n_irqs = NR_AIC_IRQS;
-static unsigned long at91_aic_caps = 0;
-
-/* AIC5 introduces a Source Select Register */
-#define AT91_AIC_CAP_AIC5	(1 << 0)
-#define has_aic5()		(at91_aic_caps & AT91_AIC_CAP_AIC5)
 
 #ifdef CONFIG_PM
 
@@ -92,50 +87,14 @@ static int at91_aic_set_wake(struct irq_data *d, unsigned value)
 
 void at91_irq_suspend(void)
 {
-	int bit = -1;
-
-	if (has_aic5()) {
-		/* disable enabled irqs */
-		while ((bit = find_next_bit(backups, n_irqs, bit + 1)) < n_irqs) {
-			at91_aic_write(AT91_AIC5_SSR,
-				       bit & AT91_AIC5_INTSEL_MSK);
-			at91_aic_write(AT91_AIC5_IDCR, 1);
-		}
-		/* enable wakeup irqs */
-		bit = -1;
-		while ((bit = find_next_bit(wakeups, n_irqs, bit + 1)) < n_irqs) {
-			at91_aic_write(AT91_AIC5_SSR,
-				       bit & AT91_AIC5_INTSEL_MSK);
-			at91_aic_write(AT91_AIC5_IECR, 1);
-		}
-	} else {
-		at91_aic_write(AT91_AIC_IDCR, *backups);
-		at91_aic_write(AT91_AIC_IECR, *wakeups);
-	}
+	at91_aic_write(AT91_AIC_IDCR, *backups);
+	at91_aic_write(AT91_AIC_IECR, *wakeups);
 }
 
 void at91_irq_resume(void)
 {
-	int bit = -1;
-
-	if (has_aic5()) {
-		/* disable wakeup irqs */
-		while ((bit = find_next_bit(wakeups, n_irqs, bit + 1)) < n_irqs) {
-			at91_aic_write(AT91_AIC5_SSR,
-				       bit & AT91_AIC5_INTSEL_MSK);
-			at91_aic_write(AT91_AIC5_IDCR, 1);
-		}
-		/* enable irqs disabled for suspend */
-		bit = -1;
-		while ((bit = find_next_bit(backups, n_irqs, bit + 1)) < n_irqs) {
-			at91_aic_write(AT91_AIC5_SSR,
-				       bit & AT91_AIC5_INTSEL_MSK);
-			at91_aic_write(AT91_AIC5_IECR, 1);
-		}
-	} else {
-		at91_aic_write(AT91_AIC_IDCR, *wakeups);
-		at91_aic_write(AT91_AIC_IECR, *backups);
-	}
+	at91_aic_write(AT91_AIC_IDCR, *wakeups);
+	at91_aic_write(AT91_AIC_IECR, *backups);
 }
 
 #else
@@ -169,21 +128,6 @@ at91_aic_handle_irq(struct pt_regs *regs)
 		handle_IRQ(irqnr, regs);
 }
 
-asmlinkage void __exception_irq_entry
-at91_aic5_handle_irq(struct pt_regs *regs)
-{
-	u32 irqnr;
-	u32 irqstat;
-
-	irqnr = at91_aic_read(AT91_AIC5_IVR);
-	irqstat = at91_aic_read(AT91_AIC5_ISR);
-
-	if (!irqstat)
-		at91_aic_write(AT91_AIC5_EOICR, 0);
-	else
-		handle_IRQ(irqnr, regs);
-}
-
 static void at91_aic_mask_irq(struct irq_data *d)
 {
 	/* Disable interrupt on AIC */
@@ -192,15 +136,6 @@ static void at91_aic_mask_irq(struct irq_data *d)
 	clear_backup(d->hwirq);
 }
 
-static void __maybe_unused at91_aic5_mask_irq(struct irq_data *d)
-{
-	/* Disable interrupt on AIC5 */
-	at91_aic_write(AT91_AIC5_SSR, d->hwirq & AT91_AIC5_INTSEL_MSK);
-	at91_aic_write(AT91_AIC5_IDCR, 1);
-	/* Update ISR cache */
-	clear_backup(d->hwirq);
-}
-
 static void at91_aic_unmask_irq(struct irq_data *d)
 {
 	/* Enable interrupt on AIC */
@@ -209,15 +144,6 @@ static void at91_aic_unmask_irq(struct irq_data *d)
 	set_backup(d->hwirq);
 }
 
-static void __maybe_unused at91_aic5_unmask_irq(struct irq_data *d)
-{
-	/* Enable interrupt on AIC5 */
-	at91_aic_write(AT91_AIC5_SSR, d->hwirq & AT91_AIC5_INTSEL_MSK);
-	at91_aic_write(AT91_AIC5_IECR, 1);
-	/* Update ISR cache */
-	set_backup(d->hwirq);
-}
-
 static void at91_aic_eoi(struct irq_data *d)
 {
 	/*
@@ -227,11 +153,6 @@ static void at91_aic_eoi(struct irq_data *d)
 	at91_aic_write(AT91_AIC_EOICR, 0);
 }
 
-static void __maybe_unused at91_aic5_eoi(struct irq_data *d)
-{
-	at91_aic_write(AT91_AIC5_EOICR, 0);
-}
-
 static unsigned long *at91_extern_irq;
 
 u32 at91_get_extern_irq(void)
@@ -282,16 +203,8 @@ static int at91_aic_set_type(struct irq_data *d, unsigned type)
 	if (srctype < 0)
 		return srctype;
 
-	if (has_aic5()) {
-		at91_aic_write(AT91_AIC5_SSR,
-			       d->hwirq & AT91_AIC5_INTSEL_MSK);
-		smr = at91_aic_read(AT91_AIC5_SMR) & ~AT91_AIC_SRCTYPE;
-		at91_aic_write(AT91_AIC5_SMR, smr | srctype);
-	} else {
-		smr = at91_aic_read(AT91_AIC_SMR(d->hwirq))
-		      & ~AT91_AIC_SRCTYPE;
-		at91_aic_write(AT91_AIC_SMR(d->hwirq), smr | srctype);
-	}
+	smr = at91_aic_read(AT91_AIC_SMR(d->hwirq)) & ~AT91_AIC_SRCTYPE;
+	at91_aic_write(AT91_AIC_SMR(d->hwirq), smr | srctype);
 
 	return 0;
 }
@@ -331,177 +244,6 @@ static void __init at91_aic_hw_init(unsigned int spu_vector)
 	at91_aic_write(AT91_AIC_ICCR, 0xFFFFFFFF);
 }
 
-static void __init __maybe_unused at91_aic5_hw_init(unsigned int spu_vector)
-{
-	int i;
-
-	/*
-	 * Perform 8 End Of Interrupt Command to make sure AIC
-	 * will not Lock out nIRQ
-	 */
-	for (i = 0; i < 8; i++)
-		at91_aic_write(AT91_AIC5_EOICR, 0);
-
-	/*
-	 * Spurious Interrupt ID in Spurious Vector Register.
-	 * When there is no current interrupt, the IRQ Vector Register
-	 * reads the value stored in AIC_SPU
-	 */
-	at91_aic_write(AT91_AIC5_SPU, spu_vector);
-
-	/* No debugging in AIC: Debug (Protect) Control Register */
-	at91_aic_write(AT91_AIC5_DCR, 0);
-
-	/* Disable and clear all interrupts initially */
-	for (i = 0; i < n_irqs; i++) {
-		at91_aic_write(AT91_AIC5_SSR, i & AT91_AIC5_INTSEL_MSK);
-		at91_aic_write(AT91_AIC5_IDCR, 1);
-		at91_aic_write(AT91_AIC5_ICCR, 1);
-	}
-}
-
-#if defined(CONFIG_OF)
-static unsigned int *at91_aic_irq_priorities;
-
-static int at91_aic_irq_map(struct irq_domain *h, unsigned int virq,
-							irq_hw_number_t hw)
-{
-	/* Put virq number in Source Vector Register */
-	at91_aic_write(AT91_AIC_SVR(hw), virq);
-
-	/* Active Low interrupt, with priority */
-	at91_aic_write(AT91_AIC_SMR(hw),
-		       AT91_AIC_SRCTYPE_LOW | at91_aic_irq_priorities[hw]);
-
-	irq_set_chip_and_handler(virq, &at91_aic_chip, handle_fasteoi_irq);
-	set_irq_flags(virq, IRQF_VALID | IRQF_PROBE);
-
-	return 0;
-}
-
-static int at91_aic5_irq_map(struct irq_domain *h, unsigned int virq,
-		irq_hw_number_t hw)
-{
-	at91_aic_write(AT91_AIC5_SSR, hw & AT91_AIC5_INTSEL_MSK);
-
-	/* Put virq number in Source Vector Register */
-	at91_aic_write(AT91_AIC5_SVR, virq);
-
-	/* Active Low interrupt, with priority */
-	at91_aic_write(AT91_AIC5_SMR,
-		       AT91_AIC_SRCTYPE_LOW | at91_aic_irq_priorities[hw]);
-
-	irq_set_chip_and_handler(virq, &at91_aic_chip, handle_fasteoi_irq);
-	set_irq_flags(virq, IRQF_VALID | IRQF_PROBE);
-
-	return 0;
-}
-
-static int at91_aic_irq_domain_xlate(struct irq_domain *d, struct device_node *ctrlr,
-				const u32 *intspec, unsigned int intsize,
-				irq_hw_number_t *out_hwirq, unsigned int *out_type)
-{
-	if (WARN_ON(intsize < 3))
-		return -EINVAL;
-	if (WARN_ON(intspec[0] >= n_irqs))
-		return -EINVAL;
-	if (WARN_ON((intspec[2] < AT91_AIC_IRQ_MIN_PRIORITY)
-		    || (intspec[2] > AT91_AIC_IRQ_MAX_PRIORITY)))
-		return -EINVAL;
-
-	*out_hwirq = intspec[0];
-	*out_type = intspec[1] & IRQ_TYPE_SENSE_MASK;
-	at91_aic_irq_priorities[*out_hwirq] = intspec[2];
-
-	return 0;
-}
-
-static struct irq_domain_ops at91_aic_irq_ops = {
-	.map	= at91_aic_irq_map,
-	.xlate	= at91_aic_irq_domain_xlate,
-};
-
-int __init at91_aic_of_common_init(struct device_node *node,
-				    struct device_node *parent)
-{
-	struct property *prop;
-	const __be32 *p;
-	u32 val;
-
-	at91_extern_irq = kzalloc(BITS_TO_LONGS(n_irqs)
-				  * sizeof(*at91_extern_irq), GFP_KERNEL);
-	if (!at91_extern_irq)
-		return -ENOMEM;
-
-	if (at91_aic_pm_init()) {
-		kfree(at91_extern_irq);
-		return -ENOMEM;
-	}
-
-	at91_aic_irq_priorities = kzalloc(n_irqs
-					  * sizeof(*at91_aic_irq_priorities),
-					  GFP_KERNEL);
-	if (!at91_aic_irq_priorities)
-		return -ENOMEM;
-
-	at91_aic_base = of_iomap(node, 0);
-	at91_aic_np = node;
-
-	at91_aic_domain = irq_domain_add_linear(at91_aic_np, n_irqs,
-						&at91_aic_irq_ops, NULL);
-	if (!at91_aic_domain)
-		panic("Unable to add AIC irq domain (DT)\n");
-
-	of_property_for_each_u32(node, "atmel,external-irqs", prop, p, val) {
-		if (val >= n_irqs)
-			pr_warn("AIC: external irq %d >= %d skip it\n",
-				val, n_irqs);
-		else
-			set_bit(val, at91_extern_irq);
-	}
-
-	irq_set_default_host(at91_aic_domain);
-
-	return 0;
-}
-
-int __init at91_aic_of_init(struct device_node *node,
-				     struct device_node *parent)
-{
-	int err;
-
-	err = at91_aic_of_common_init(node, parent);
-	if (err)
-		return err;
-
-	at91_aic_hw_init(n_irqs);
-
-	return 0;
-}
-
-int __init at91_aic5_of_init(struct device_node *node,
-				     struct device_node *parent)
-{
-	int err;
-
-	at91_aic_caps |= AT91_AIC_CAP_AIC5;
-	n_irqs = NR_AIC5_IRQS;
-	at91_aic_chip.irq_ack           = at91_aic5_mask_irq;
-	at91_aic_chip.irq_mask		= at91_aic5_mask_irq;
-	at91_aic_chip.irq_unmask	= at91_aic5_unmask_irq;
-	at91_aic_chip.irq_eoi		= at91_aic5_eoi;
-	at91_aic_irq_ops.map		= at91_aic5_irq_map;
-
-	err = at91_aic_of_common_init(node, parent);
-	if (err)
-		return err;
-
-	at91_aic5_hw_init(n_irqs);
-
-	return 0;
-}
-#endif
-
 /*
  * Initialize the AIC interrupt controller.
  */
Signature · 1 line
1.7.9.5
#17 lore raw

RFC PATCH v2 9/10 ARM: at91/dt: add new AIC irq mux definitions for sam9x5 SoCs

In reply to Boris BREZILLON

Add irq line muxing definition for sam9x5 SoCs.

---
 arch/arm/boot/dts/at91sam9x5.dtsi |  108 +++++++++++++++++++++++++++++++++++++
 1 file changed, 108 insertions(+)
arch/arm/boot/dts/at91sam9x5.dtsi +108 -0
index 174219d..ccdfdf3 100644
@@ -69,6 +69,114 @@
 				interrupt-controller;
 				reg = <0xfffff000 0x200>;
 				atmel,external-irqs = <31>;
+				#address-cells = <2>;
+				#size-cells = <1>;
+				ranges = <1 0x0 0xffffc000 0x4000>,
+					 <2 0x0 0xfffff400 0x400>,
+					 <3 0x0 0xfffff800 0x400>,
+					 <17 0x0 0xf8008000 0x8000>;
+
+				dbgu_irq: irq-mux at 1,2e0c {
+					compatible = "atmel,aic-mux-3reg-irq";
+					reg = <1 0x2e0c 0x4>;
+					atmel,aic-mux-reg-mask = <0xc00002e3>;
+				};
+
+				pmc_irq: irq-mux at 1,3c64 {
+					compatible = "atmel,aic-mux-3reg-irq";
+					reg = <1 0x3c64 0x4>;
+					atmel,aic-mux-reg-mask = <0x7034b>;
+				};
+
+				pmecc_irq: irq-mux at 1,2020 {
+					compatible = "atmel,aic-mux-3reg-irq";
+					reg = <1 0x2020 0x4>;
+					atmel,aic-mux-reg-mask = <0x1>;
+				};
+
+				pmerrloc_irq: irq-mux at 1,2618 {
+					compatible = "atmel,aic-mux-3reg-irq";
+					reg = <1 0x2618 0x4>;
+					atmel,aic-mux-reg-mask = <0x1>;
+				};
+
+				pit_irq: irq-mux at 1,3e30 {
+					compatible = "atmel,aic-mux-1reg-irq";
+					reg = <1 0x3e30 0x4>;
+					atmel,aic-mux-reg-mask = <0x2000000>;
+				};
+
+				wdt_irq: irq-mux at 1,3e40 {
+					compatible = "atmel,aic-mux-1reg-irq";
+					reg = <1 0x3e40 0x4>;
+					atmel,aic-mux-reg-mask = <0x1000>;
+				};
+
+				rtc_irq: irq-mux at 1,3ed4 {
+					compatible = "atmel,aic-mux-3reg-irq";
+					reg = <1 0x3ed4 0x4>;
+					atmel,aic-mux-reg-mask = <0x1f>;
+				};
+
+				pioA_irq: irq-mux at 2,44 {
+					compatible = "atmel,aic-mux-3reg-irq";
+					reg = <2 0x44 0x4>;
+					atmel,aic-mux-reg-mask = <0xffffffff>;
+				};
+
+				pioB_irq: irq-mux at 2,244 {
+					compatible = "atmel,aic-mux-3reg-irq";
+					reg = <2 0x244 0x4>;
+					atmel,aic-mux-reg-mask = <0xffffffff>;
+				};
+
+				pioC_irq: irq-mux at 3,44 {
+					compatible = "atmel,aic-mux-3reg-irq";
+					reg = <3 0x44 0x4>;
+					atmel,aic-mux-reg-mask = <0xffffffff>;
+				};
+
+				pioD_irq: irq-mux at 3,244 {
+					compatible = "atmel,aic-mux-3reg-irq";
+					reg = <3 0x244 0x4>;
+					atmel,aic-mux-reg-mask = <0xffffffff>;
+				};
+
+				tc0_irq: irq-mux at 17,28 {
+					compatible = "atmel,aic-mux-3reg-irq";
+					reg = <17 0x28 0x4>;
+					atmel,aic-mux-reg-mask = <0xff>;
+				};
+
+				tc1_irq: irq-mux at 17,68 {
+					compatible = "atmel,aic-mux-3reg-irq";
+					reg = <17 0x68 0x4>;
+					atmel,aic-mux-reg-mask = <0xff>;
+				};
+
+				tc2_irq: irq-mux at 17,a8 {
+					compatible = "atmel,aic-mux-3reg-irq";
+					reg = <17 0xa8 0x4>;
+					atmel,aic-mux-reg-mask = <0xff>;
+				};
+
+				tc3_irq: irq-mux at 17,4028 {
+					compatible = "atmel,aic-mux-3reg-irq";
+					reg = <17 0x4028 0x4>;
+					atmel,aic-mux-reg-mask = <0xff>;
+				};
+
+				tc4_irq: irq-mux at 17,4068 {
+					compatible = "atmel,aic-mux-3reg-irq";
+					reg = <17 0x4068 0x4>;
+					atmel,aic-mux-reg-mask = <0xff>;
+				};
+
+				tc5_irq: irq-mux at 17,40a8 {
+					compatible = "atmel,aic-mux-3reg-irq";
+					reg = <17 0x40a8 0x4>;
+					atmel,aic-mux-reg-mask = <0xff>;
+				};
 			};
 
 			ramc0: ramc at ffffe800 {
Signature · 1 line
1.7.9.5
#18 lore raw

RFC PATCH v2 10/10 ARM: at91/dt: add new AIC irq mux definitions for sama5 SoCs

In reply to Boris BREZILLON

Add irq line muxing definition for sama5 SoCs.

---
 arch/arm/boot/dts/sama5d3.dtsi      |   37 +++++++++++++++++++++++++++++++++++
 arch/arm/boot/dts/sama5d3_tcb1.dtsi |   20 +++++++++++++++++++
 2 files changed, 57 insertions(+)
arch/arm/boot/dts/sama5d3.dtsi +37 -0
index 3d5faf8..ece1f7b 100644
@@ -416,6 +416,43 @@
 				interrupt-controller;
 				reg = <0xfffff000 0x200>;
 				atmel,external-irqs = <47>;
+				#address-cells = <2>;
+				#size-cells = <1>;
+				ranges = <1 0x0 0xffffc000 0x4000>,
+					 <26 0x0 0xf0010000 0x4000>,
+					 <27 0x0 0xf8014000 0x4000>;
+
+				atmel,aic-irq-mapping = <0xffffffff 0x7ffff>;
+
+				pmc_irq: irq-mux at 1,3c64 {
+					compatible = "atmel,aic-mux-3reg-irq";
+					reg = <1 0x3c64 0x4>;
+					atmel,aic-mux-reg-mask = <0x5074b>;
+				};
+
+				rtc_irq: irq-mux at 1,3ed4 {
+					compatible = "atmel,aic-mux-3reg-irq";
+					reg = <1 0x3ed4 0x4>;
+					atmel,aic-mux-reg-mask = <0x1f>;
+				};
+
+				tc0_irq: irq-mux at 26,28 {
+					compatible = "atmel,aic-mux-3reg-irq";
+					reg = <26 0x28 0x4>;
+					atmel,aic-mux-reg-mask = <0xff>;
+				};
+
+				tc1_irq: irq-mux at 26,68 {
+					compatible = "atmel,aic-mux-3reg-irq";
+					reg = <26 0x68 0x4>;
+					atmel,aic-mux-reg-mask = <0xff>;
+				};
+
+				tc2_irq: irq-mux at 26,a8 {
+					compatible = "atmel,aic-mux-3reg-irq";
+					reg = <26 0xa8 0x4>;
+					atmel,aic-mux-reg-mask = <0xff>;
+				};
 			};
 
 			pinctrl at fffff200 {
arch/arm/boot/dts/sama5d3_tcb1.dtsi +20 -0
index 382b044..6060bfd 100644
@@ -18,6 +18,26 @@
 
 	ahb {
 		apb {
+			aic: interrupt-controller at fffff000 {
+				tc3_irq: irq-mux at 27,28 {
+					compatible = "atmel,aic-mux-3reg-irq";
+					reg = <27 0x28 0x4>;
+					atmel,aic-mux-reg-mask = <0xff>;
+				};
+
+				tc4_irq: irq-mux at 27,68 {
+					compatible = "atmel,aic-mux-3reg-irq";
+					reg = <27 0x68 0x4>;
+					atmel,aic-mux-reg-mask = <0xff>;
+				};
+
+				tc5_irq: irq-mux at 27,a8 {
+					compatible = "atmel,aic-mux-3reg-irq";
+					reg = <27 0xa8 0x4>;
+					atmel,aic-mux-reg-mask = <0xff>;
+				};
+			};
+
 			pmc: pmc at fffffc00 {
 				periphck {
 					tcb1_clk: tcb1_clk {
Signature · 1 line
1.7.9.5