All of lore.kernel.org
 help / color / mirror / Atom feed
* i.MX: switch to sparse irqs
@ 2011-05-20  7:59 Sascha Hauer
  2011-05-20  7:59 ` [PATCH 1/9] ARM i.MX tzic: do not depend on MXC_INTERNAL_IRQS Sascha Hauer
                   ` (9 more replies)
  0 siblings, 10 replies; 32+ messages in thread
From: Sascha Hauer @ 2011-05-20  7:59 UTC (permalink / raw)
  To: linux-arm-kernel

The following series switches the i.MX architecture to sparse
irqs. It allows us to remove some ugly dependencies on irq
number defines in both the boards and the architecture.

Sascha Hauer (9):
      ARM i.MX tzic: do not depend on MXC_INTERNAL_IRQS
      ARM i.MX avic: do not depend on MXC_INTERNAL_IRQS
      ARM i.MX: get rid of wrong MXC_INTERNAL_IRQ usage
      mfd wm8350: allocate irq descs dynamically
      ARM i.MX mx31ads: allocate irqs for expio dynamically
      ARM i.MX 3ds debugboard: allocate irqs dynamically
      ARM i.MX: use sparse irqs
      dma IPU: rework irq handling
      ARM i.MX3: remove now useless ipu platform data from boards

 arch/arm/Kconfig                               |    1 +
 arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c |    6 +-
 arch/arm/mach-imx/mach-armadillo5x0.c          |    6 +-
 arch/arm/mach-imx/mach-mx27_3ds.c              |    2 +-
 arch/arm/mach-imx/mach-mx31_3ds.c              |    6 +-
 arch/arm/mach-imx/mach-mx31ads.c               |   45 ++--
 arch/arm/mach-imx/mach-mx31moboard.c           |    6 +-
 arch/arm/mach-imx/mach-mx35_3ds.c              |    2 +-
 arch/arm/mach-imx/mach-pcm037.c                |    6 +-
 arch/arm/mach-imx/mach-pcm043.c                |    6 +-
 arch/arm/mach-imx/mach-vpr200.c                |    6 +-
 arch/arm/mach-imx/mm-imx31.c                   |    2 +-
 arch/arm/mach-imx/mm-imx35.c                   |    1 +
 arch/arm/mach-imx/mx31lilly-db.c               |    6 +-
 arch/arm/mach-mx5/board-cpuimx51.c             |   12 +-
 arch/arm/mach-mx5/board-mx51_3ds.c             |    2 +-
 arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c   |    3 +-
 arch/arm/plat-mxc/3ds_debugboard.c             |   53 +++--
 arch/arm/plat-mxc/avic.c                       |   18 +-
 arch/arm/plat-mxc/gpio.c                       |    6 +-
 arch/arm/plat-mxc/include/mach/iomux-v1.h      |    3 -
 arch/arm/plat-mxc/include/mach/ipu.h           |    1 -
 arch/arm/plat-mxc/include/mach/irqs.h          |   53 +----
 arch/arm/plat-mxc/tzic.c                       |    4 +-
 drivers/dma/Kconfig                            |   10 -
 drivers/dma/ipu/ipu_idmac.c                    |   41 +---
 drivers/dma/ipu/ipu_intern.h                   |   14 +-
 drivers/dma/ipu/ipu_irq.c                      |  300 +++---------------------
 drivers/mfd/wm8350-irq.c                       |   16 +-
 29 files changed, 166 insertions(+), 471 deletions(-)

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 1/9] ARM i.MX tzic: do not depend on MXC_INTERNAL_IRQS
  2011-05-20  7:59 i.MX: switch to sparse irqs Sascha Hauer
@ 2011-05-20  7:59 ` Sascha Hauer
  2011-05-20  7:59 ` [PATCH] mfd wm8350: allocate irq descs dynamically Sascha Hauer
                   ` (8 subsequent siblings)
  9 siblings, 0 replies; 32+ messages in thread
From: Sascha Hauer @ 2011-05-20  7:59 UTC (permalink / raw)
  To: linux-arm-kernel

This becomes meaningless in subsequent patches.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/plat-mxc/tzic.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

diff --git a/arch/arm/plat-mxc/tzic.c b/arch/arm/plat-mxc/tzic.c
index 57f9395..710f2e7 100644
--- a/arch/arm/plat-mxc/tzic.c
+++ b/arch/arm/plat-mxc/tzic.c
@@ -49,6 +49,8 @@
 
 void __iomem *tzic_base; /* Used as irq controller base in entry-macro.S */
 
+#define TZIC_NUM_IRQS 128
+
 #ifdef CONFIG_FIQ
 static int tzic_set_irq_fiq(unsigned int irq, unsigned int type)
 {
@@ -166,7 +168,7 @@ void __init tzic_init_irq(void __iomem *irqbase)
 
 	/* all IRQ no FIQ Warning :: No selection */
 
-	for (i = 0; i < MXC_INTERNAL_IRQS; i++) {
+	for (i = 0; i < TZIC_NUM_IRQS; i++) {
 		irq_set_chip_and_handler(i, &mxc_tzic_chip.base,
 					 handle_level_irq);
 		set_irq_flags(i, IRQF_VALID);
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH] mfd wm8350: allocate irq descs dynamically
  2011-05-20  7:59 i.MX: switch to sparse irqs Sascha Hauer
  2011-05-20  7:59 ` [PATCH 1/9] ARM i.MX tzic: do not depend on MXC_INTERNAL_IRQS Sascha Hauer
@ 2011-05-20  7:59 ` Sascha Hauer
  2011-05-20 12:52   ` Thomas Gleixner
  2011-05-20  7:59 ` [PATCH 2/9] ARM i.MX avic: do not depend on MXC_INTERNAL_IRQS Sascha Hauer
                   ` (7 subsequent siblings)
  9 siblings, 1 reply; 32+ messages in thread
From: Sascha Hauer @ 2011-05-20  7:59 UTC (permalink / raw)
  To: linux-arm-kernel

This allows boards to leave the irq_base field unitialized and
prevents them having to reserve irqs in the platform.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mfd/wm8350-irq.c |   16 +++++++++++++---
 1 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/mfd/wm8350-irq.c b/drivers/mfd/wm8350-irq.c
index ed4b22a..04408a5 100644
--- a/drivers/mfd/wm8350-irq.c
+++ b/drivers/mfd/wm8350-irq.c
@@ -479,8 +479,8 @@ int wm8350_irq_init(struct wm8350 *wm8350, int irq,
 		return 0;
 	}
 
-	if (!pdata || !pdata->irq_base) {
-		dev_warn(wm8350->dev, "No interrupt support, no IRQ base\n");
+	if (!pdata) {
+		dev_warn(wm8350->dev, "No interrupt support, no platform data\n");
 		return 0;
 	}
 
@@ -500,7 +500,17 @@ int wm8350_irq_init(struct wm8350 *wm8350, int irq,
 
 	mutex_init(&wm8350->irq_lock);
 	wm8350->chip_irq = irq;
-	wm8350->irq_base = pdata->irq_base;
+
+	if (!pdata->irq_base) {
+		wm8350->irq_base = irq_alloc_descs(-1, 0, ARRAY_SIZE(wm8350_irqs), 0);
+		if (wm8350->irq_base < 0) {
+			dev_warn(wm8350->dev, "Allocating irqs failed with %d\n",
+				wm8350->irq_base);
+			return 0;
+		}
+	} else {
+		wm8350->irq_base = pdata->irq_base;
+	}
 
 	if (pdata->irq_high) {
 		flags |= IRQF_TRIGGER_HIGH;
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 2/9] ARM i.MX avic: do not depend on MXC_INTERNAL_IRQS
  2011-05-20  7:59 i.MX: switch to sparse irqs Sascha Hauer
  2011-05-20  7:59 ` [PATCH 1/9] ARM i.MX tzic: do not depend on MXC_INTERNAL_IRQS Sascha Hauer
  2011-05-20  7:59 ` [PATCH] mfd wm8350: allocate irq descs dynamically Sascha Hauer
@ 2011-05-20  7:59 ` Sascha Hauer
  2011-05-20  7:59 ` [PATCH 3/9] ARM i.MX: get rid of wrong MXC_INTERNAL_IRQ usage Sascha Hauer
                   ` (6 subsequent siblings)
  9 siblings, 0 replies; 32+ messages in thread
From: Sascha Hauer @ 2011-05-20  7:59 UTC (permalink / raw)
  To: linux-arm-kernel

This becomes meaningless in subsequent patches.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/plat-mxc/avic.c |   12 +++++++-----
 1 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/arch/arm/plat-mxc/avic.c b/arch/arm/plat-mxc/avic.c
index 09e2bd0..55d2534 100644
--- a/arch/arm/plat-mxc/avic.c
+++ b/arch/arm/plat-mxc/avic.c
@@ -46,6 +46,8 @@
 #define AVIC_FIPNDH		0x60	/* fast int pending high */
 #define AVIC_FIPNDL		0x64	/* fast int pending low */
 
+#define AVIC_NUM_IRQS 64
+
 void __iomem *avic_base;
 
 #ifdef CONFIG_MXC_IRQ_PRIOR
@@ -54,7 +56,7 @@ static int avic_irq_set_priority(unsigned char irq, unsigned char prio)
 	unsigned int temp;
 	unsigned int mask = 0x0F << irq % 8 * 4;
 
-	if (irq >= MXC_INTERNAL_IRQS)
+	if (irq >= AVIC_NUM_IRQS)
 		return -EINVAL;;
 
 	temp = __raw_readl(avic_base + AVIC_NIPRIORITY(irq / 8));
@@ -72,14 +74,14 @@ static int avic_set_irq_fiq(unsigned int irq, unsigned int type)
 {
 	unsigned int irqt;
 
-	if (irq >= MXC_INTERNAL_IRQS)
+	if (irq >= AVIC_NUM_IRQS)
 		return -EINVAL;
 
-	if (irq < MXC_INTERNAL_IRQS / 2) {
+	if (irq < AVIC_NUM_IRQS / 2) {
 		irqt = __raw_readl(avic_base + AVIC_INTTYPEL) & ~(1 << irq);
 		__raw_writel(irqt | (!!type << irq), avic_base + AVIC_INTTYPEL);
 	} else {
-		irq -= MXC_INTERNAL_IRQS / 2;
+		irq -= AVIC_NUM_IRQS / 2;
 		irqt = __raw_readl(avic_base + AVIC_INTTYPEH) & ~(1 << irq);
 		__raw_writel(irqt | (!!type << irq), avic_base + AVIC_INTTYPEH);
 	}
@@ -138,7 +140,7 @@ void __init mxc_init_irq(void __iomem *irqbase)
 	/* all IRQ no FIQ */
 	__raw_writel(0, avic_base + AVIC_INTTYPEH);
 	__raw_writel(0, avic_base + AVIC_INTTYPEL);
-	for (i = 0; i < MXC_INTERNAL_IRQS; i++) {
+	for (i = 0; i < AVIC_NUM_IRQS; i++) {
 		irq_set_chip_and_handler(i, &mxc_avic_chip.base,
 					 handle_level_irq);
 		set_irq_flags(i, IRQF_VALID);
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 3/9] ARM i.MX: get rid of wrong MXC_INTERNAL_IRQ usage
  2011-05-20  7:59 i.MX: switch to sparse irqs Sascha Hauer
                   ` (2 preceding siblings ...)
  2011-05-20  7:59 ` [PATCH 2/9] ARM i.MX avic: do not depend on MXC_INTERNAL_IRQS Sascha Hauer
@ 2011-05-20  7:59 ` Sascha Hauer
  2011-05-20  7:59 ` [PATCH 4/9] mfd wm8350: allocate irq descs dynamically Sascha Hauer
                   ` (5 subsequent siblings)
  9 siblings, 0 replies; 32+ messages in thread
From: Sascha Hauer @ 2011-05-20  7:59 UTC (permalink / raw)
  To: linux-arm-kernel

There are several occurences where MXC_INTERNAL_IRQ is
assumed to be the start of the gpio interrupts. It was never
meant this way. Replace these with gpio_to_irq.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/mach-mx27_3ds.c            |    2 +-
 arch/arm/mach-imx/mach-mx35_3ds.c            |    2 +-
 arch/arm/mach-mx5/board-cpuimx51.c           |   12 ++++--------
 arch/arm/mach-mx5/board-mx51_3ds.c           |    2 +-
 arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c |    3 +--
 arch/arm/plat-mxc/include/mach/iomux-v1.h    |    3 ---
 6 files changed, 8 insertions(+), 16 deletions(-)

diff --git a/arch/arm/mach-imx/mach-mx27_3ds.c b/arch/arm/mach-imx/mach-mx27_3ds.c
index 6e1accf..fcbac6e 100644
--- a/arch/arm/mach-imx/mach-mx27_3ds.c
+++ b/arch/arm/mach-imx/mach-mx27_3ds.c
@@ -45,7 +45,7 @@
 #define SD1_EN_GPIO (GPIO_PORTB + 25)
 #define OTG_PHY_RESET_GPIO (GPIO_PORTB + 23)
 #define SPI2_SS0 (GPIO_PORTD + 21)
-#define EXPIO_PARENT_INT	(MXC_INTERNAL_IRQS + GPIO_PORTC + 28)
+#define EXPIO_PARENT_INT	gpio_to_irq(IMX_GPIO_NR(3, 28))
 
 static const int mx27pdk_pins[] __initconst = {
 	/* UART1 */
diff --git a/arch/arm/mach-imx/mach-mx35_3ds.c b/arch/arm/mach-imx/mach-mx35_3ds.c
index 882880a..c10221d 100644
--- a/arch/arm/mach-imx/mach-mx35_3ds.c
+++ b/arch/arm/mach-imx/mach-mx35_3ds.c
@@ -43,7 +43,7 @@
 
 #include "devices-imx35.h"
 
-#define EXPIO_PARENT_INT	(MXC_INTERNAL_IRQS + GPIO_PORTA + 1)
+#define EXPIO_PARENT_INT	gpio_to_irq(IMX_GPIO_NR(1, 1))
 
 static const struct imxuart_platform_data uart_pdata __initconst = {
 	.flags = IMXUART_HAVE_RTSCTS,
diff --git a/arch/arm/mach-mx5/board-cpuimx51.c b/arch/arm/mach-mx5/board-cpuimx51.c
index 4efa02e..7fbfd06 100644
--- a/arch/arm/mach-mx5/board-cpuimx51.c
+++ b/arch/arm/mach-mx5/board-cpuimx51.c
@@ -43,10 +43,6 @@
 #define CPUIMX51_QUARTB_GPIO	IMX_GPIO_NR(3, 25)
 #define CPUIMX51_QUARTC_GPIO	IMX_GPIO_NR(3, 26)
 #define CPUIMX51_QUARTD_GPIO	IMX_GPIO_NR(3, 27)
-#define CPUIMX51_QUARTA_IRQ	(MXC_INTERNAL_IRQS + CPUIMX51_QUARTA_GPIO)
-#define CPUIMX51_QUARTB_IRQ	(MXC_INTERNAL_IRQS + CPUIMX51_QUARTB_GPIO)
-#define CPUIMX51_QUARTC_IRQ	(MXC_INTERNAL_IRQS + CPUIMX51_QUARTC_GPIO)
-#define CPUIMX51_QUARTD_IRQ	(MXC_INTERNAL_IRQS + CPUIMX51_QUARTD_GPIO)
 #define CPUIMX51_QUART_XTAL	14745600
 #define CPUIMX51_QUART_REGSHIFT	17
 
@@ -61,7 +57,7 @@
 static struct plat_serial8250_port serial_platform_data[] = {
 	{
 		.mapbase = (unsigned long)(MX51_CS1_BASE_ADDR + 0x400000),
-		.irq = CPUIMX51_QUARTA_IRQ,
+		.irq = gpio_to_irq(CPUIMX51_QUARTA_GPIO),
 		.irqflags = IRQF_TRIGGER_HIGH,
 		.uartclk = CPUIMX51_QUART_XTAL,
 		.regshift = CPUIMX51_QUART_REGSHIFT,
@@ -69,7 +65,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
 		.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
 	}, {
 		.mapbase = (unsigned long)(MX51_CS1_BASE_ADDR + 0x800000),
-		.irq = CPUIMX51_QUARTB_IRQ,
+		.irq = gpio_to_irq(CPUIMX51_QUARTB_GPIO),
 		.irqflags = IRQF_TRIGGER_HIGH,
 		.uartclk = CPUIMX51_QUART_XTAL,
 		.regshift = CPUIMX51_QUART_REGSHIFT,
@@ -77,7 +73,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
 		.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
 	}, {
 		.mapbase = (unsigned long)(MX51_CS1_BASE_ADDR + 0x1000000),
-		.irq = CPUIMX51_QUARTC_IRQ,
+		.irq = gpio_to_irq(CPUIMX51_QUARTC_GPIO),
 		.irqflags = IRQF_TRIGGER_HIGH,
 		.uartclk = CPUIMX51_QUART_XTAL,
 		.regshift = CPUIMX51_QUART_REGSHIFT,
@@ -85,7 +81,7 @@ static struct plat_serial8250_port serial_platform_data[] = {
 		.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_IOREMAP,
 	}, {
 		.mapbase = (unsigned long)(MX51_CS1_BASE_ADDR + 0x2000000),
-		.irq = CPUIMX51_QUARTD_IRQ,
+		.irq = irq_to_gpio(CPUIMX51_QUARTD_GPIO),
 		.irqflags = IRQF_TRIGGER_HIGH,
 		.uartclk = CPUIMX51_QUART_XTAL,
 		.regshift = CPUIMX51_QUART_REGSHIFT,
diff --git a/arch/arm/mach-mx5/board-mx51_3ds.c b/arch/arm/mach-mx5/board-mx51_3ds.c
index 63dfbea..288965d 100644
--- a/arch/arm/mach-mx5/board-mx51_3ds.c
+++ b/arch/arm/mach-mx5/board-mx51_3ds.c
@@ -26,7 +26,7 @@
 #include "devices-imx51.h"
 #include "devices.h"
 
-#define EXPIO_PARENT_INT	(MXC_INTERNAL_IRQS + GPIO_PORTA + 6)
+#define EXPIO_PARENT_INT	gpio_to_irq((IMX_GPIO_NR(1, 6))
 #define MX51_3DS_ECSPI2_CS	(GPIO_PORTC + 28)
 
 static iomux_v3_cfg_t mx51_3ds_pads[] = {
diff --git a/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c b/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c
index 97292d2..66d24ea 100644
--- a/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c
+++ b/arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c
@@ -31,7 +31,6 @@
 #include "devices.h"
 
 #define MBIMX51_TSC2007_GPIO	IMX_GPIO_NR(3, 30)
-#define MBIMX51_TSC2007_IRQ	(MXC_INTERNAL_IRQS + MBIMX51_TSC2007_GPIO)
 #define MBIMX51_LED0		IMX_GPIO_NR(3, 5)
 #define MBIMX51_LED1		IMX_GPIO_NR(3, 6)
 #define MBIMX51_LED2		IMX_GPIO_NR(3, 7)
@@ -173,7 +172,7 @@ struct tsc2007_platform_data tsc2007_data = {
 static struct i2c_board_info mbimx51_i2c_devices[] = {
 	{
 		I2C_BOARD_INFO("tsc2007", 0x49),
-		.irq  = MBIMX51_TSC2007_IRQ,
+		.irq  = gpio_to_irq(MBIMX51_TSC2007_GPIO),
 		.platform_data = &tsc2007_data,
 	}, {
 		I2C_BOARD_INFO("tlv320aic23", 0x1a),
diff --git a/arch/arm/plat-mxc/include/mach/iomux-v1.h b/arch/arm/plat-mxc/include/mach/iomux-v1.h
index c07d302..a7fc51e 100644
--- a/arch/arm/plat-mxc/include/mach/iomux-v1.h
+++ b/arch/arm/plat-mxc/include/mach/iomux-v1.h
@@ -85,9 +85,6 @@
 #define GPIO_BOUT_0	(2 << GPIO_BOUT_SHIFT)
 #define GPIO_BOUT_1	(3 << GPIO_BOUT_SHIFT)
 
-/* decode irq number to use with IMR(x), ISR(x) and friends */
-#define IRQ_TO_REG(irq) ((irq - MXC_INTERNAL_IRQS) >> 5)
-
 #define IRQ_GPIOA(x)  (MXC_GPIO_IRQ_START + x)
 #define IRQ_GPIOB(x)  (IRQ_GPIOA(32) + x)
 #define IRQ_GPIOC(x)  (IRQ_GPIOB(32) + x)
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 4/9] mfd wm8350: allocate irq descs dynamically
  2011-05-20  7:59 i.MX: switch to sparse irqs Sascha Hauer
                   ` (3 preceding siblings ...)
  2011-05-20  7:59 ` [PATCH 3/9] ARM i.MX: get rid of wrong MXC_INTERNAL_IRQ usage Sascha Hauer
@ 2011-05-20  7:59 ` Sascha Hauer
  2011-05-20  7:59 ` [PATCH 5/9] ARM i.MX mx31ads: allocate irqs for expio dynamically Sascha Hauer
                   ` (4 subsequent siblings)
  9 siblings, 0 replies; 32+ messages in thread
From: Sascha Hauer @ 2011-05-20  7:59 UTC (permalink / raw)
  To: linux-arm-kernel

This allows boards to leave the irq_base field unitialized and
prevents them having to reserve irqs in the platform.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/mfd/wm8350-irq.c |   16 +++++++++++++---
 1 files changed, 13 insertions(+), 3 deletions(-)

diff --git a/drivers/mfd/wm8350-irq.c b/drivers/mfd/wm8350-irq.c
index ed4b22a..04408a5 100644
--- a/drivers/mfd/wm8350-irq.c
+++ b/drivers/mfd/wm8350-irq.c
@@ -479,8 +479,8 @@ int wm8350_irq_init(struct wm8350 *wm8350, int irq,
 		return 0;
 	}
 
-	if (!pdata || !pdata->irq_base) {
-		dev_warn(wm8350->dev, "No interrupt support, no IRQ base\n");
+	if (!pdata) {
+		dev_warn(wm8350->dev, "No interrupt support, no platform data\n");
 		return 0;
 	}
 
@@ -500,7 +500,17 @@ int wm8350_irq_init(struct wm8350 *wm8350, int irq,
 
 	mutex_init(&wm8350->irq_lock);
 	wm8350->chip_irq = irq;
-	wm8350->irq_base = pdata->irq_base;
+
+	if (!pdata->irq_base) {
+		wm8350->irq_base = irq_alloc_descs(-1, 0, ARRAY_SIZE(wm8350_irqs), 0);
+		if (wm8350->irq_base < 0) {
+			dev_warn(wm8350->dev, "Allocating irqs failed with %d\n",
+				wm8350->irq_base);
+			return 0;
+		}
+	} else {
+		wm8350->irq_base = pdata->irq_base;
+	}
 
 	if (pdata->irq_high) {
 		flags |= IRQF_TRIGGER_HIGH;
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 5/9] ARM i.MX mx31ads: allocate irqs for expio dynamically
  2011-05-20  7:59 i.MX: switch to sparse irqs Sascha Hauer
                   ` (4 preceding siblings ...)
  2011-05-20  7:59 ` [PATCH 4/9] mfd wm8350: allocate irq descs dynamically Sascha Hauer
@ 2011-05-20  7:59 ` Sascha Hauer
  2011-05-20  7:59 ` [PATCH 6/9] ARM i.MX 3ds debugboard: allocate irqs dynamically Sascha Hauer
                   ` (3 subsequent siblings)
  9 siblings, 0 replies; 32+ messages in thread
From: Sascha Hauer @ 2011-05-20  7:59 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/mach-mx31ads.c |   45 +++++++++++++++++++------------------
 1 files changed, 23 insertions(+), 22 deletions(-)

diff --git a/arch/arm/mach-imx/mach-mx31ads.c b/arch/arm/mach-imx/mach-mx31ads.c
index f4dee02..d183592 100644
--- a/arch/arm/mach-imx/mach-mx31ads.c
+++ b/arch/arm/mach-imx/mach-mx31ads.c
@@ -62,11 +62,6 @@
 #define PBC_INTMASK_CLEAR_REG	(PBC_INTMASK_CLEAR + PBC_BASE_ADDRESS)
 #define EXPIO_PARENT_INT	IOMUX_TO_IRQ(MX31_PIN_GPIO1_4)
 
-#define MXC_IRQ_TO_EXPIO(irq)	((irq) - MXC_EXP_IO_BASE)
-
-#define EXPIO_INT_XUART_INTA	(MXC_EXP_IO_BASE + 10)
-#define EXPIO_INT_XUART_INTB	(MXC_EXP_IO_BASE + 11)
-
 #define MXC_MAX_EXP_IO_LINES	16
 
 /*
@@ -76,7 +71,6 @@ static struct plat_serial8250_port serial_platform_data[] = {
 	{
 		.membase  = (void *)(PBC_BASE_ADDRESS + PBC_SC16C652_UARTA),
 		.mapbase  = (unsigned long)(MX31_CS4_BASE_ADDR + PBC_SC16C652_UARTA),
-		.irq      = EXPIO_INT_XUART_INTA,
 		.uartclk  = 14745600,
 		.regshift = 0,
 		.iotype   = UPIO_MEM,
@@ -84,7 +78,6 @@ static struct plat_serial8250_port serial_platform_data[] = {
 	}, {
 		.membase  = (void *)(PBC_BASE_ADDRESS + PBC_SC16C652_UARTB),
 		.mapbase  = (unsigned long)(MX31_CS4_BASE_ADDR + PBC_SC16C652_UARTB),
-		.irq      = EXPIO_INT_XUART_INTB,
 		.uartclk  = 14745600,
 		.regshift = 0,
 		.iotype   = UPIO_MEM,
@@ -101,11 +94,6 @@ static struct platform_device serial_device = {
 	},
 };
 
-static int __init mxc_init_extuart(void)
-{
-	return platform_device_register(&serial_device);
-}
-
 static const struct imxuart_platform_data uart_pdata __initconst = {
 	.flags = IMXUART_HAVE_RTSCTS,
 };
@@ -123,6 +111,8 @@ static inline void mxc_init_imx_uart(void)
 	imx31_add_imx_uart0(&uart_pdata);
 }
 
+static int expio_base_irq;
+
 static void mx31ads_expio_irq_handler(u32 irq, struct irq_desc *desc)
 {
 	u32 imr_val;
@@ -132,7 +122,7 @@ static void mx31ads_expio_irq_handler(u32 irq, struct irq_desc *desc)
 	imr_val = __raw_readw(PBC_INTMASK_SET_REG);
 	int_valid = __raw_readw(PBC_INTSTATUS_REG) & imr_val;
 
-	expio_irq = MXC_EXP_IO_BASE;
+	expio_irq = expio_base_irq;
 	for (; int_valid != 0; int_valid >>= 1, expio_irq++) {
 		if ((int_valid & 1) == 0)
 			continue;
@@ -147,8 +137,8 @@ static void mx31ads_expio_irq_handler(u32 irq, struct irq_desc *desc)
  */
 static void expio_mask_irq(struct irq_data *d)
 {
-	u32 expio = MXC_IRQ_TO_EXPIO(d->irq);
-	/* mask the interrupt */
+	u32 expio = d->irq - expio_base_irq;
+
 	__raw_writew(1 << expio, PBC_INTMASK_CLEAR_REG);
 	__raw_readw(PBC_INTMASK_CLEAR_REG);
 }
@@ -159,8 +149,8 @@ static void expio_mask_irq(struct irq_data *d)
  */
 static void expio_ack_irq(struct irq_data *d)
 {
-	u32 expio = MXC_IRQ_TO_EXPIO(d->irq);
-	/* clear the interrupt status */
+	u32 expio = d->irq - expio_base_irq;
+
 	__raw_writew(1 << expio, PBC_INTSTATUS_REG);
 }
 
@@ -170,8 +160,8 @@ static void expio_ack_irq(struct irq_data *d)
  */
 static void expio_unmask_irq(struct irq_data *d)
 {
-	u32 expio = MXC_IRQ_TO_EXPIO(d->irq);
-	/* unmask the interrupt */
+	u32 expio = d->irq - expio_base_irq;
+
 	__raw_writew(1 << expio, PBC_INTMASK_SET_REG);
 }
 
@@ -188,6 +178,13 @@ static void __init mx31ads_init_expio(void)
 
 	printk(KERN_INFO "MX31ADS EXPIO(CPLD) hardware\n");
 
+	/* Currently we rely on the exact irq number as this must be hardcoded
+	 * into the cs89x0 driver
+	 */
+	expio_base_irq = irq_alloc_descs(-1, MXC_EXP_IO_BASE, MXC_MAX_EXP_IO_LINES, 0);
+	if (expio_base_irq != MXC_EXP_IO_BASE)
+		return;
+
 	/*
 	 * Configure INT line as GPIO input
 	 */
@@ -196,13 +193,18 @@ static void __init mx31ads_init_expio(void)
 	/* disable the interrupt and clear the status */
 	__raw_writew(0xFFFF, PBC_INTMASK_CLEAR_REG);
 	__raw_writew(0xFFFF, PBC_INTSTATUS_REG);
-	for (i = MXC_EXP_IO_BASE; i < (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES);
+	for (i = expio_base_irq; i < (expio_base_irq + MXC_MAX_EXP_IO_LINES);
 	     i++) {
 		irq_set_chip_and_handler(i, &expio_irq_chip, handle_level_irq);
 		set_irq_flags(i, IRQF_VALID);
 	}
 	irq_set_irq_type(EXPIO_PARENT_INT, IRQ_TYPE_LEVEL_HIGH);
 	irq_set_chained_handler(EXPIO_PARENT_INT, mx31ads_expio_irq_handler);
+
+	serial_platform_data[0].irq = expio_base_irq + 10;
+	serial_platform_data[1].irq = expio_base_irq + 11;
+
+	platform_device_register(&serial_device);
 }
 
 #ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
@@ -511,12 +513,11 @@ static void __init mx31ads_map_io(void)
 static void __init mx31ads_init_irq(void)
 {
 	mx31_init_irq();
-	mx31ads_init_expio();
 }
 
 static void __init mx31ads_init(void)
 {
-	mxc_init_extuart();
+	mx31ads_init_expio();
 	mxc_init_imx_uart();
 	mxc_init_i2c();
 	mxc_init_audio();
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 6/9] ARM i.MX 3ds debugboard: allocate irqs dynamically
  2011-05-20  7:59 i.MX: switch to sparse irqs Sascha Hauer
                   ` (5 preceding siblings ...)
  2011-05-20  7:59 ` [PATCH 5/9] ARM i.MX mx31ads: allocate irqs for expio dynamically Sascha Hauer
@ 2011-05-20  7:59 ` Sascha Hauer
  2011-05-20  7:59 ` [PATCH 7/9] ARM i.MX: use sparse irqs Sascha Hauer
                   ` (2 subsequent siblings)
  9 siblings, 0 replies; 32+ messages in thread
From: Sascha Hauer @ 2011-05-20  7:59 UTC (permalink / raw)
  To: linux-arm-kernel

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/plat-mxc/3ds_debugboard.c |   53 ++++++++++++++++++++---------------
 1 files changed, 30 insertions(+), 23 deletions(-)

diff --git a/arch/arm/plat-mxc/3ds_debugboard.c b/arch/arm/plat-mxc/3ds_debugboard.c
index f0ba072..e644cd9 100644
--- a/arch/arm/plat-mxc/3ds_debugboard.c
+++ b/arch/arm/plat-mxc/3ds_debugboard.c
@@ -46,18 +46,14 @@
 /* CPU ID and Personality ID */
 #define MCU_BOARD_ID_REG	0x68
 
-#define MXC_IRQ_TO_EXPIO(irq)   ((irq) - MXC_BOARD_IRQ_START)
-#define MXC_IRQ_TO_GPIO(irq)	((irq) - MXC_INTERNAL_IRQS)
-
-#define MXC_EXP_IO_BASE		(MXC_BOARD_IRQ_START)
 #define MXC_MAX_EXP_IO_LINES	16
 
 /* interrupts like external uart , external ethernet etc*/
-#define EXPIO_INT_ENET		(MXC_BOARD_IRQ_START + 0)
-#define EXPIO_INT_XUART_A	(MXC_BOARD_IRQ_START + 1)
-#define EXPIO_INT_XUART_B	(MXC_BOARD_IRQ_START + 2)
-#define EXPIO_INT_BUTTON_A	(MXC_BOARD_IRQ_START + 3)
-#define EXPIO_INT_BUTTON_B	(MXC_BOARD_IRQ_START + 4)
+#define EXPIO_INT_ENET		0
+#define EXPIO_INT_XUART_A	1
+#define EXPIO_INT_XUART_B	2
+#define EXPIO_INT_BUTTON_A	3
+#define EXPIO_INT_BUTTON_B	4
 
 static void __iomem *brd_io;
 
@@ -65,8 +61,6 @@ static struct resource smsc911x_resources[] = {
 	{
 		.flags = IORESOURCE_MEM,
 	} , {
-		.start = EXPIO_INT_ENET,
-		.end = EXPIO_INT_ENET,
 		.flags = IORESOURCE_IRQ,
 	},
 };
@@ -86,6 +80,8 @@ static struct platform_device smsc_lan9217_device = {
 	.resource = smsc911x_resources,
 };
 
+static int mxc_expio_base_irq;
+
 static void mxc_expio_irq_handler(u32 irq, struct irq_desc *desc)
 {
 	u32 imr_val;
@@ -98,7 +94,7 @@ static void mxc_expio_irq_handler(u32 irq, struct irq_desc *desc)
 	imr_val = __raw_readw(brd_io + INTR_MASK_REG);
 	int_valid = __raw_readw(brd_io + INTR_STATUS_REG) & ~imr_val;
 
-	expio_irq = MXC_BOARD_IRQ_START;
+	expio_irq = mxc_expio_base_irq;
 	for (; int_valid != 0; int_valid >>= 1, expio_irq++) {
 		if ((int_valid & 1) == 0)
 			continue;
@@ -116,7 +112,7 @@ static void mxc_expio_irq_handler(u32 irq, struct irq_desc *desc)
 static void expio_mask_irq(struct irq_data *d)
 {
 	u16 reg;
-	u32 expio = MXC_IRQ_TO_EXPIO(d->irq);
+	u32 expio = d->irq - mxc_expio_base_irq;
 
 	reg = __raw_readw(brd_io + INTR_MASK_REG);
 	reg |= (1 << expio);
@@ -125,7 +121,7 @@ static void expio_mask_irq(struct irq_data *d)
 
 static void expio_ack_irq(struct irq_data *d)
 {
-	u32 expio = MXC_IRQ_TO_EXPIO(d->irq);
+	u32 expio = d->irq - mxc_expio_base_irq;
 
 	__raw_writew(1 << expio, brd_io + INTR_RESET_REG);
 	__raw_writew(0, brd_io + INTR_RESET_REG);
@@ -135,7 +131,7 @@ static void expio_ack_irq(struct irq_data *d)
 static void expio_unmask_irq(struct irq_data *d)
 {
 	u16 reg;
-	u32 expio = MXC_IRQ_TO_EXPIO(d->irq);
+	u32 expio = d->irq - mxc_expio_base_irq;
 
 	reg = __raw_readw(brd_io + INTR_MASK_REG);
 	reg &= ~(1 << expio);
@@ -150,7 +146,7 @@ static struct irq_chip expio_irq_chip = {
 
 int __init mxc_expio_init(u32 base, u32 p_irq)
 {
-	int i;
+	int ret, i;
 
 	brd_io = ioremap(BOARD_IO_ADDR(base), SZ_4K);
 	if (brd_io == NULL)
@@ -160,9 +156,8 @@ int __init mxc_expio_init(u32 base, u32 p_irq)
 	    (__raw_readw(brd_io + MAGIC_NUMBER2_REG) != 0x5555) ||
 	    (__raw_readw(brd_io + MAGIC_NUMBER3_REG) != 0xCAFE)) {
 		pr_info("3-Stack Debug board not detected\n");
-		iounmap(brd_io);
-		brd_io = NULL;
-		return -ENODEV;
+		ret = -ENODEV;
+		goto out;
 	}
 
 	pr_info("3-Stack Debug board detected, rev = 0x%04X\n",
@@ -171,16 +166,23 @@ int __init mxc_expio_init(u32 base, u32 p_irq)
 	/*
 	 * Configure INT line as GPIO input
 	 */
-	gpio_request(MXC_IRQ_TO_GPIO(p_irq), "expio_pirq");
-	gpio_direction_input(MXC_IRQ_TO_GPIO(p_irq));
+	gpio_request(irq_to_gpio(p_irq), "expio_pirq");
+	gpio_direction_input(irq_to_gpio(p_irq));
 
 	/* disable the interrupt and clear the status */
 	__raw_writew(0, brd_io + INTR_MASK_REG);
 	__raw_writew(0xFFFF, brd_io + INTR_RESET_REG);
 	__raw_writew(0, brd_io + INTR_RESET_REG);
 	__raw_writew(0x1F, brd_io + INTR_MASK_REG);
-	for (i = MXC_EXP_IO_BASE;
-	     i < (MXC_EXP_IO_BASE + MXC_MAX_EXP_IO_LINES); i++) {
+
+	mxc_expio_base_irq = irq_alloc_descs(-1, 0, MXC_MAX_EXP_IO_LINES, 0);
+	if (mxc_expio_base_irq < 0) {
+		ret = mxc_expio_base_irq;
+		goto out;
+	}
+
+	for (i = mxc_expio_base_irq;
+	     i < mxc_expio_base_irq + MXC_MAX_EXP_IO_LINES; i++) {
 		irq_set_chip_and_handler(i, &expio_irq_chip, handle_level_irq);
 		set_irq_flags(i, IRQF_VALID);
 	}
@@ -190,7 +192,12 @@ int __init mxc_expio_init(u32 base, u32 p_irq)
 	/* Register Lan device on the debugboard */
 	smsc911x_resources[0].start = LAN9217_BASE_ADDR(base);
 	smsc911x_resources[0].end = LAN9217_BASE_ADDR(base) + 0x100 - 1;
+	smsc911x_resources[1].start = mxc_expio_base_irq + EXPIO_INT_ENET;
+	smsc911x_resources[1].end = mxc_expio_base_irq + EXPIO_INT_ENET;
 	platform_device_register(&smsc_lan9217_device);
 
 	return 0;
+out:
+	iounmap(brd_io);
+	return ret;
 }
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 7/9] ARM i.MX: use sparse irqs
  2011-05-20  7:59 i.MX: switch to sparse irqs Sascha Hauer
                   ` (6 preceding siblings ...)
  2011-05-20  7:59 ` [PATCH 6/9] ARM i.MX 3ds debugboard: allocate irqs dynamically Sascha Hauer
@ 2011-05-20  7:59 ` Sascha Hauer
  2011-05-20  7:59 ` [PATCH 8/9] dma IPU: rework irq handling Sascha Hauer
  2011-05-20  7:59 ` [PATCH 9/9] ARM i.MX3: remove now useless ipu platform data from boards Sascha Hauer
  9 siblings, 0 replies; 32+ messages in thread
From: Sascha Hauer @ 2011-05-20  7:59 UTC (permalink / raw)
  To: linux-arm-kernel

This switches the whole i.MX architecture to use sparse irqs.
It helps us getting rid of some ifdeffery in irqs.h and allows
us to be more flexible with chained interrupt handlers.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/Kconfig                      |    1 +
 arch/arm/mach-imx/mm-imx31.c          |    8 ++++-
 arch/arm/mach-imx/mm-imx35.c          |    7 ++++
 arch/arm/plat-mxc/avic.c              |    6 +++-
 arch/arm/plat-mxc/gpio.c              |    6 +++-
 arch/arm/plat-mxc/include/mach/irqs.h |   54 +++++---------------------------
 6 files changed, 34 insertions(+), 48 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 377a7a5..cebed1e 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -367,6 +367,7 @@ config ARCH_MXC
 	select ARCH_REQUIRE_GPIOLIB
 	select CLKDEV_LOOKUP
 	select HAVE_SCHED_CLOCK
+	select SPARSE_IRQ
 	help
 	  Support for Freescale MXC/iMX-based family of processors
 
diff --git a/arch/arm/mach-imx/mm-imx31.c b/arch/arm/mach-imx/mm-imx31.c
index 86b9b45..e055ef0 100644
--- a/arch/arm/mach-imx/mm-imx31.c
+++ b/arch/arm/mach-imx/mm-imx31.c
@@ -19,7 +19,7 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/err.h>
-
+#include <linux/irq.h>
 #include <asm/pgtable.h>
 #include <asm/mach/map.h>
 
@@ -61,6 +61,12 @@ static struct mxc_gpio_port imx31_gpio_ports[] = {
 
 void __init mx31_init_irq(void)
 {
+	int ret;
+
 	mxc_init_irq(MX31_IO_ADDRESS(MX31_AVIC_BASE_ADDR));
 	mxc_gpio_init(imx31_gpio_ports,	ARRAY_SIZE(imx31_gpio_ports));
+
+	/* The ipu driver should handle this */
+	ret = irq_alloc_descs(MXC_IPU_IRQ_START, MXC_IPU_IRQ_START, 160, 0);
+	BUG_ON(ret != MXC_IPU_IRQ_START);
 }
diff --git a/arch/arm/mach-imx/mm-imx35.c b/arch/arm/mach-imx/mm-imx35.c
index c880e6d..abe908b 100644
--- a/arch/arm/mach-imx/mm-imx35.c
+++ b/arch/arm/mach-imx/mm-imx35.c
@@ -19,6 +19,7 @@
 #include <linux/mm.h>
 #include <linux/init.h>
 #include <linux/err.h>
+#include <linux/irq.h>
 
 #include <asm/pgtable.h>
 #include <asm/mach/map.h>
@@ -58,6 +59,12 @@ static struct mxc_gpio_port imx35_gpio_ports[] = {
 
 void __init mx35_init_irq(void)
 {
+	int ret;
+
 	mxc_init_irq(MX35_IO_ADDRESS(MX35_AVIC_BASE_ADDR));
 	mxc_gpio_init(imx35_gpio_ports,	ARRAY_SIZE(imx35_gpio_ports));
+
+	/* The ipu driver should handle this */
+	ret = irq_alloc_descs(MXC_IPU_IRQ_START, MXC_IPU_IRQ_START, 160, 0);
+	BUG_ON(ret != MXC_IPU_IRQ_START);
 }
diff --git a/arch/arm/plat-mxc/avic.c b/arch/arm/plat-mxc/avic.c
index 55d2534..1a4f00c 100644
--- a/arch/arm/plat-mxc/avic.c
+++ b/arch/arm/plat-mxc/avic.c
@@ -123,7 +123,7 @@ static struct mxc_irq_chip mxc_avic_chip = {
  */
 void __init mxc_init_irq(void __iomem *irqbase)
 {
-	int i;
+	int ret, i;
 
 	avic_base = irqbase;
 
@@ -140,6 +140,10 @@ void __init mxc_init_irq(void __iomem *irqbase)
 	/* all IRQ no FIQ */
 	__raw_writel(0, avic_base + AVIC_INTTYPEH);
 	__raw_writel(0, avic_base + AVIC_INTTYPEL);
+
+	ret = irq_alloc_descs(0, 0, AVIC_NUM_IRQS, 0);
+	BUG_ON(ret);
+
 	for (i = 0; i < AVIC_NUM_IRQS; i++) {
 		irq_set_chip_and_handler(i, &mxc_avic_chip.base,
 					 handle_level_irq);
diff --git a/arch/arm/plat-mxc/gpio.c b/arch/arm/plat-mxc/gpio.c
index 6cd6d7f..8352264 100644
--- a/arch/arm/plat-mxc/gpio.c
+++ b/arch/arm/plat-mxc/gpio.c
@@ -303,7 +303,7 @@ static struct lock_class_key gpio_lock_class;
 
 int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt)
 {
-	int i, j;
+	int i, j, ret;
 
 	/* save for local usage */
 	mxc_gpio_ports = port;
@@ -311,6 +311,10 @@ int __init mxc_gpio_init(struct mxc_gpio_port *port, int cnt)
 
 	printk(KERN_INFO "MXC GPIO hardware\n");
 
+	ret = irq_alloc_descs(MXC_GPIO_IRQ_START, MXC_GPIO_IRQ_START,
+		cnt * 32, 0);
+	BUG_ON(ret != MXC_GPIO_IRQ_START);
+
 	for (i = 0; i < cnt; i++) {
 		/* disable the interrupt and clear the status */
 		__raw_writel(0, port[i].base + GPIO_IMR);
diff --git a/arch/arm/plat-mxc/include/mach/irqs.h b/arch/arm/plat-mxc/include/mach/irqs.h
index 35c89bc..8253463 100644
--- a/arch/arm/plat-mxc/include/mach/irqs.h
+++ b/arch/arm/plat-mxc/include/mach/irqs.h
@@ -11,58 +11,22 @@
 #ifndef __ASM_ARCH_MXC_IRQS_H__
 #define __ASM_ARCH_MXC_IRQS_H__
 
-/*
- * SoCs with TZIC interrupt controller have 128 IRQs, those with AVIC have 64
+/* This should go away. Currently the serial driver uses this
+ * (and it shouldn't)
  */
-#ifdef CONFIG_MXC_TZIC
 #define MXC_INTERNAL_IRQS	128
-#else
-#define MXC_INTERNAL_IRQS	64
-#endif
 
+/* Right after maximum number of internal irqs */
 #define MXC_GPIO_IRQ_START	MXC_INTERNAL_IRQS
 
-/* these are ordered by size to support multi-SoC kernels */
-#if defined CONFIG_SOC_IMX53
-#define MXC_GPIO_IRQS		(32 * 7)
-#elif defined CONFIG_ARCH_MX2
-#define MXC_GPIO_IRQS		(32 * 6)
-#elif defined CONFIG_SOC_IMX50
-#define MXC_GPIO_IRQS		(32 * 6)
-#elif defined CONFIG_ARCH_MX1
-#define MXC_GPIO_IRQS		(32 * 4)
-#elif defined CONFIG_ARCH_MX25
-#define MXC_GPIO_IRQS		(32 * 4)
-#elif defined CONFIG_SOC_IMX51
-#define MXC_GPIO_IRQS		(32 * 4)
-#elif defined CONFIG_ARCH_MX3
-#define MXC_GPIO_IRQS		(32 * 3)
-#endif
-
-/*
- * The next 16 interrupts are for board specific purposes.  Since
- * the kernel can only run on one machine@a time, we can re-use
- * these.  If you need more, increase MXC_BOARD_IRQS, but keep it
- * within sensible limits.
- */
-#define MXC_BOARD_IRQ_START	(MXC_INTERNAL_IRQS + MXC_GPIO_IRQS)
-
-#ifdef CONFIG_MACH_MX31ADS_WM1133_EV1
-#define MXC_BOARD_IRQS  80
-#else
-#define MXC_BOARD_IRQS	16
-#endif
-
-#define MXC_IPU_IRQ_START	(MXC_BOARD_IRQ_START + MXC_BOARD_IRQS)
+/* one board (mx31ads) still depends on this. Do not add new dependencies */
+#define MXC_BOARD_IRQ_START	512
 
-#ifdef CONFIG_MX3_IPU_IRQS
-#define MX3_IPU_IRQS CONFIG_MX3_IPU_IRQS
-#else
-#define MX3_IPU_IRQS 0
-#endif
-/* REVISIT: Add IPU irqs on IMX51 */
+/* should go away once the ipu uses dynamically allocated irqs */
+#define MXC_IPU_IRQ_START	1024
 
-#define NR_IRQS			(MXC_IPU_IRQ_START + MX3_IPU_IRQS)
+/* All irqs dynamically allocated */
+#define NR_IRQS			0
 
 extern int imx_irq_set_priority(unsigned char irq, unsigned char prio);
 
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 8/9] dma IPU: rework irq handling
  2011-05-20  7:59 i.MX: switch to sparse irqs Sascha Hauer
                   ` (7 preceding siblings ...)
  2011-05-20  7:59 ` [PATCH 7/9] ARM i.MX: use sparse irqs Sascha Hauer
@ 2011-05-20  7:59 ` Sascha Hauer
  2011-05-20 13:16   ` Thomas Gleixner
  2011-05-20  7:59 ` [PATCH 9/9] ARM i.MX3: remove now useless ipu platform data from boards Sascha Hauer
  9 siblings, 1 reply; 32+ messages in thread
From: Sascha Hauer @ 2011-05-20  7:59 UTC (permalink / raw)
  To: linux-arm-kernel

By the time interrupt descriptors were a precious resource the ipu
driver had a mechanism to map all ipu interrupts to a configurable
number of hardware interrupts. Now with sparse irqs we can simplify
it significantly and switch to standard chained handlers.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 drivers/dma/Kconfig          |   10 --
 drivers/dma/ipu/ipu_idmac.c  |   41 ++----
 drivers/dma/ipu/ipu_intern.h |   14 +--
 drivers/dma/ipu/ipu_irq.c    |  300 ++++++------------------------------------
 4 files changed, 54 insertions(+), 311 deletions(-)

diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index a572600..4119188 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -131,16 +131,6 @@ config MX3_IPU
 	  If you plan to use the Image Processing unit in the i.MX3x, say
 	  Y here. If unsure, select Y.
 
-config MX3_IPU_IRQS
-	int "Number of dynamically mapped interrupts for IPU"
-	depends on MX3_IPU
-	range 2 137
-	default 4
-	help
-	  Out of 137 interrupt sources on i.MX31 IPU only very few are used.
-	  To avoid bloating the irq_desc[] array we allocate a sufficient
-	  number of IRQ slots and map them dynamically to specific sources.
-
 config TXX9_DMAC
 	tristate "Toshiba TXx9 SoC DMA support"
 	depends on MACH_TX49XX || MACH_TX39XX
diff --git a/drivers/dma/ipu/ipu_idmac.c b/drivers/dma/ipu/ipu_idmac.c
index c1a125e..3c17c5a 100644
--- a/drivers/dma/ipu/ipu_idmac.c
+++ b/drivers/dma/ipu/ipu_idmac.c
@@ -1132,7 +1132,7 @@ static int ipu_disable_channel(struct idmac *idmac, struct idmac_channel *ichan,
 	if (wait_for_stop && (channel == IDMAC_SDC_0 ||
 			      channel == IDMAC_SDC_1)) {
 		for (timeout = 5;
-		     timeout && !ipu_irq_status(ichan->eof_irq); timeout--)
+		     timeout && !ipu_irq_status(ipu, ichan->eof_irq); timeout--)
 			msleep(5);
 	}
 
@@ -1203,10 +1203,10 @@ static irqreturn_t idmac_interrupt(int irq, void *dev_id)
 	ready0	= idmac_read_ipureg(&ipu_data, IPU_CHA_BUF0_RDY);
 	ready1	= idmac_read_ipureg(&ipu_data, IPU_CHA_BUF1_RDY);
 	curbuf	= idmac_read_ipureg(&ipu_data, IPU_CHA_CUR_BUF);
-	err	= idmac_read_ipureg(&ipu_data, IPU_INT_STAT_4);
+	err	= idmac_read_ipureg(&ipu_data, IPU_INT_STAT(3));
 
 	if (err & (1 << chan_id)) {
-		idmac_write_ipureg(&ipu_data, 1 << chan_id, IPU_INT_STAT_4);
+		idmac_write_ipureg(&ipu_data, 1 << chan_id, IPU_INT_STAT(3));
 		spin_unlock_irqrestore(&ipu_data.lock, flags);
 		/*
 		 * Doing this
@@ -1505,6 +1505,7 @@ static int idmac_alloc_chan_resources(struct dma_chan *chan)
 {
 	struct idmac_channel *ichan = to_idmac_chan(chan);
 	struct idmac *idmac = to_idmac(chan->device);
+	struct ipu *ipu = to_ipu(idmac);
 	int ret;
 
 	/* dmaengine.c now guarantees to only offer free channels */
@@ -1514,11 +1515,7 @@ static int idmac_alloc_chan_resources(struct dma_chan *chan)
 	chan->cookie		= 1;
 	ichan->completed	= -ENXIO;
 
-	ret = ipu_irq_map(chan->chan_id);
-	if (ret < 0)
-		goto eimap;
-
-	ichan->eof_irq = ret;
+	ichan->eof_irq = ipu->irq_base + chan->chan_id;
 
 	/*
 	 * Important to first disable the channel, because maybe someone
@@ -1537,12 +1534,10 @@ static int idmac_alloc_chan_resources(struct dma_chan *chan)
 
 #ifdef DEBUG
 	if (chan->chan_id == IDMAC_IC_7) {
-		ic_sof = ipu_irq_map(69);
-		if (ic_sof > 0)
-			request_irq(ic_sof, ic_sof_irq, 0, "IC SOF", ichan);
-		ic_eof = ipu_irq_map(70);
-		if (ic_eof > 0)
-			request_irq(ic_eof, ic_eof_irq, 0, "IC EOF", ichan);
+		ic_sof = ipu->irq_base + 69;
+		request_irq(ic_sof, ic_sof_irq, 0, "IC SOF", ichan);
+		ic_eof = ipu->irq_base + 70;
+		request_irq(ic_eof, ic_eof_irq, 0, "IC EOF", ichan);
 	}
 #endif
 
@@ -1556,8 +1551,6 @@ static int idmac_alloc_chan_resources(struct dma_chan *chan)
 erirq:
 	ipu_uninit_channel(idmac, ichan);
 eichan:
-	ipu_irq_unmap(chan->chan_id);
-eimap:
 	return ret;
 }
 
@@ -1575,18 +1568,15 @@ static void idmac_free_chan_resources(struct dma_chan *chan)
 		if (chan->chan_id == IDMAC_IC_7) {
 			if (ic_sof > 0) {
 				free_irq(ic_sof, ichan);
-				ipu_irq_unmap(69);
 				ic_sof = -EINVAL;
 			}
 			if (ic_eof > 0) {
 				free_irq(ic_eof, ichan);
-				ipu_irq_unmap(70);
 				ic_eof = -EINVAL;
 			}
 		}
 #endif
 		free_irq(ichan->eof_irq, ichan);
-		ipu_irq_unmap(chan->chan_id);
 	}
 
 	ichan->status = IPU_CHANNEL_FREE;
@@ -1674,15 +1664,14 @@ static void __exit ipu_idmac_exit(struct ipu *ipu)
 
 static int __init ipu_probe(struct platform_device *pdev)
 {
-	struct ipu_platform_data *pdata = pdev->dev.platform_data;
 	struct resource *mem_ipu, *mem_ic;
-	int ret;
+	int i, ret;
 
 	spin_lock_init(&ipu_data.lock);
 
 	mem_ipu	= platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	mem_ic	= platform_get_resource(pdev, IORESOURCE_MEM, 1);
-	if (!pdata || !mem_ipu || !mem_ic)
+	if (!mem_ipu || !mem_ic)
 		return -EINVAL;
 
 	ipu_data.dev = &pdev->dev;
@@ -1699,7 +1688,6 @@ static int __init ipu_probe(struct platform_device *pdev)
 		goto err_noirq;
 
 	ipu_data.irq_err = ret;
-	ipu_data.irq_base = pdata->irq_base;
 
 	dev_dbg(&pdev->dev, "fn irq %u, err irq %u, irq-base %u\n",
 		ipu_data.irq_fn, ipu_data.irq_err, ipu_data.irq_base);
@@ -1731,11 +1719,8 @@ static int __init ipu_probe(struct platform_device *pdev)
 	clk_enable(ipu_data.ipu_clk);
 
 	/* Disable all interrupts */
-	idmac_write_ipureg(&ipu_data, 0, IPU_INT_CTRL_1);
-	idmac_write_ipureg(&ipu_data, 0, IPU_INT_CTRL_2);
-	idmac_write_ipureg(&ipu_data, 0, IPU_INT_CTRL_3);
-	idmac_write_ipureg(&ipu_data, 0, IPU_INT_CTRL_4);
-	idmac_write_ipureg(&ipu_data, 0, IPU_INT_CTRL_5);
+	for (i = 0; i < 5; i++)
+		idmac_write_ipureg(&ipu_data, 0, IPU_INT_CTRL(i));
 
 	dev_dbg(&pdev->dev, "%s @ 0x%08lx, fn irq %u, err irq %u\n", pdev->name,
 		(unsigned long)mem_ipu->start, ipu_data.irq_fn, ipu_data.irq_err);
diff --git a/drivers/dma/ipu/ipu_intern.h b/drivers/dma/ipu/ipu_intern.h
index 545cf11..4eb7d0b 100644
--- a/drivers/dma/ipu/ipu_intern.h
+++ b/drivers/dma/ipu/ipu_intern.h
@@ -27,16 +27,8 @@
 #define IPU_TASKS_STAT		0x1C
 #define IPU_IMA_ADDR		0x20
 #define IPU_IMA_DATA		0x24
-#define IPU_INT_CTRL_1		0x28
-#define IPU_INT_CTRL_2		0x2C
-#define IPU_INT_CTRL_3		0x30
-#define IPU_INT_CTRL_4		0x34
-#define IPU_INT_CTRL_5		0x38
-#define IPU_INT_STAT_1		0x3C
-#define IPU_INT_STAT_2		0x40
-#define IPU_INT_STAT_3		0x44
-#define IPU_INT_STAT_4		0x48
-#define IPU_INT_STAT_5		0x4C
+#define IPU_INT_CTRL(n)		(0x28 + (n) * 4)
+#define IPU_INT_STAT(n)		(0x3c + (n) * 4)
 #define IPU_BRK_CTRL_1		0x50
 #define IPU_BRK_CTRL_2		0x54
 #define IPU_BRK_STAT		0x58
@@ -169,7 +161,7 @@ struct ipu {
 extern int ipu_irq_attach_irq(struct ipu *ipu, struct platform_device *dev);
 extern void ipu_irq_detach_irq(struct ipu *ipu, struct platform_device *dev);
 
-extern bool ipu_irq_status(uint32_t irq);
+extern bool ipu_irq_status(struct ipu *ipu, uint32_t irq);
 extern int ipu_irq_map(unsigned int source);
 extern int ipu_irq_unmap(unsigned int source);
 
diff --git a/drivers/dma/ipu/ipu_irq.c b/drivers/dma/ipu/ipu_irq.c
index ab8a4ef..bf28df9 100644
--- a/drivers/dma/ipu/ipu_irq.c
+++ b/drivers/dma/ipu/ipu_irq.c
@@ -40,122 +40,51 @@ static void ipu_write_reg(struct ipu *ipu, u32 value, unsigned long reg)
 #define IPU_IRQ_NR_FN_BANKS 3
 #define IPU_IRQ_NR_ERR_BANKS 2
 #define IPU_IRQ_NR_BANKS (IPU_IRQ_NR_FN_BANKS + IPU_IRQ_NR_ERR_BANKS)
+#define IPU_NUM_IRQS	(IPU_IRQ_NR_BANKS * 32)
 
-struct ipu_irq_bank {
-	unsigned int	control;
-	unsigned int	status;
-	spinlock_t	lock;
-	struct ipu	*ipu;
-};
-
-static struct ipu_irq_bank irq_bank[IPU_IRQ_NR_BANKS] = {
-	/* 3 groups of functional interrupts */
-	{
-		.control	= IPU_INT_CTRL_1,
-		.status		= IPU_INT_STAT_1,
-	}, {
-		.control	= IPU_INT_CTRL_2,
-		.status		= IPU_INT_STAT_2,
-	}, {
-		.control	= IPU_INT_CTRL_3,
-		.status		= IPU_INT_STAT_3,
-	},
-	/* 2 groups of error interrupts */
-	{
-		.control	= IPU_INT_CTRL_4,
-		.status		= IPU_INT_STAT_4,
-	}, {
-		.control	= IPU_INT_CTRL_5,
-		.status		= IPU_INT_STAT_5,
-	},
-};
-
-struct ipu_irq_map {
-	unsigned int		irq;
-	int			source;
-	struct ipu_irq_bank	*bank;
-	struct ipu		*ipu;
-};
-
-static struct ipu_irq_map irq_map[CONFIG_MX3_IPU_IRQS];
-/* Protects allocations from the above array of maps */
-static DEFINE_MUTEX(map_lock);
 /* Protects register accesses and individual mappings */
 static DEFINE_SPINLOCK(bank_lock);
 
-static struct ipu_irq_map *src2map(unsigned int src)
-{
-	int i;
-
-	for (i = 0; i < CONFIG_MX3_IPU_IRQS; i++)
-		if (irq_map[i].source == src)
-			return irq_map + i;
-
-	return NULL;
-}
-
 static void ipu_irq_unmask(struct irq_data *d)
 {
-	struct ipu_irq_map *map = irq_data_get_irq_chip_data(d);
-	struct ipu_irq_bank *bank;
+	struct ipu *ipu = irq_data_get_irq_chip_data(d);
+	int ipu_irq = d->irq - ipu->irq_base;
 	uint32_t reg;
 	unsigned long lock_flags;
 
 	spin_lock_irqsave(&bank_lock, lock_flags);
 
-	bank = map->bank;
-	if (!bank) {
-		spin_unlock_irqrestore(&bank_lock, lock_flags);
-		pr_err("IPU: %s(%u) - unmapped!\n", __func__, d->irq);
-		return;
-	}
-
-	reg = ipu_read_reg(bank->ipu, bank->control);
-	reg |= (1UL << (map->source & 31));
-	ipu_write_reg(bank->ipu, reg, bank->control);
+	reg = ipu_read_reg(ipu, IPU_INT_CTRL(ipu_irq / 32));
+	reg |= 1UL << (ipu_irq & 31);
+	ipu_write_reg(ipu, reg, IPU_INT_CTRL(ipu_irq / 32));
 
 	spin_unlock_irqrestore(&bank_lock, lock_flags);
 }
 
 static void ipu_irq_mask(struct irq_data *d)
 {
-	struct ipu_irq_map *map = irq_data_get_irq_chip_data(d);
-	struct ipu_irq_bank *bank;
+	struct ipu *ipu = irq_data_get_irq_chip_data(d);
+	int ipu_irq = d->irq - ipu->irq_base;
 	uint32_t reg;
 	unsigned long lock_flags;
 
 	spin_lock_irqsave(&bank_lock, lock_flags);
 
-	bank = map->bank;
-	if (!bank) {
-		spin_unlock_irqrestore(&bank_lock, lock_flags);
-		pr_err("IPU: %s(%u) - unmapped!\n", __func__, d->irq);
-		return;
-	}
-
-	reg = ipu_read_reg(bank->ipu, bank->control);
-	reg &= ~(1UL << (map->source & 31));
-	ipu_write_reg(bank->ipu, reg, bank->control);
+	reg = ipu_read_reg(ipu, IPU_INT_CTRL(ipu_irq / 32));
+	reg &= ~(1UL << (ipu_irq & 31));
+	ipu_write_reg(ipu, reg, IPU_INT_CTRL(ipu_irq / 32));
 
 	spin_unlock_irqrestore(&bank_lock, lock_flags);
 }
 
 static void ipu_irq_ack(struct irq_data *d)
 {
-	struct ipu_irq_map *map = irq_data_get_irq_chip_data(d);
-	struct ipu_irq_bank *bank;
+	struct ipu *ipu = irq_data_get_irq_chip_data(d);
+	int ipu_irq = d->irq - ipu->irq_base;
 	unsigned long lock_flags;
 
 	spin_lock_irqsave(&bank_lock, lock_flags);
-
-	bank = map->bank;
-	if (!bank) {
-		spin_unlock_irqrestore(&bank_lock, lock_flags);
-		pr_err("IPU: %s(%u) - unmapped!\n", __func__, d->irq);
-		return;
-	}
-
-	ipu_write_reg(bank->ipu, 1UL << (map->source & 31), bank->status);
+	ipu_write_reg(ipu, 1UL << (ipu_irq & 31), IPU_INT_STAT(ipu_irq / 32));
 	spin_unlock_irqrestore(&bank_lock, lock_flags);
 }
 
@@ -165,182 +94,38 @@ static void ipu_irq_ack(struct irq_data *d)
  * @return:	true if the interrupt is pending/asserted or false if the
  *		interrupt is not pending.
  */
-bool ipu_irq_status(unsigned int irq)
+bool ipu_irq_status(struct ipu *ipu, unsigned int irq)
 {
-	struct ipu_irq_map *map = irq_get_chip_data(irq);
-	struct ipu_irq_bank *bank;
-	unsigned long lock_flags;
+	int ipu_irq = irq - ipu->irq_base;
 	bool ret;
 
-	spin_lock_irqsave(&bank_lock, lock_flags);
-	bank = map->bank;
-	ret = bank && ipu_read_reg(bank->ipu, bank->status) &
-		(1UL << (map->source & 31));
-	spin_unlock_irqrestore(&bank_lock, lock_flags);
-
-	return ret;
-}
-
-/**
- * ipu_irq_map() - map an IPU interrupt source to an IRQ number
- * @source:	interrupt source bit position (see below)
- * @return:	mapped IRQ number or negative error code
- *
- * The source parameter has to be explained further. On i.MX31 IPU has 137 IRQ
- * sources, they are broken down in 5 32-bit registers, like 32, 32, 24, 32, 17.
- * However, the source argument of this function is not the sequence number of
- * the possible IRQ, but rather its bit position. So, first interrupt in fourth
- * register has source number 96, and not 88. This makes calculations easier,
- * and also provides forward compatibility with any future IPU implementations
- * with any interrupt bit assignments.
- */
-int ipu_irq_map(unsigned int source)
-{
-	int i, ret = -ENOMEM;
-	struct ipu_irq_map *map;
-
-	might_sleep();
-
-	mutex_lock(&map_lock);
-	map = src2map(source);
-	if (map) {
-		pr_err("IPU: Source %u already mapped to IRQ %u\n", source, map->irq);
-		ret = -EBUSY;
-		goto out;
-	}
-
-	for (i = 0; i < CONFIG_MX3_IPU_IRQS; i++) {
-		if (irq_map[i].source < 0) {
-			unsigned long lock_flags;
-
-			spin_lock_irqsave(&bank_lock, lock_flags);
-			irq_map[i].source = source;
-			irq_map[i].bank = irq_bank + source / 32;
-			spin_unlock_irqrestore(&bank_lock, lock_flags);
-
-			ret = irq_map[i].irq;
-			pr_debug("IPU: mapped source %u to IRQ %u\n",
-				 source, ret);
-			break;
-		}
-	}
-out:
-	mutex_unlock(&map_lock);
-
-	if (ret < 0)
-		pr_err("IPU: couldn't map source %u: %d\n", source, ret);
-
-	return ret;
-}
-
-/**
- * ipu_irq_map() - map an IPU interrupt source to an IRQ number
- * @source:	interrupt source bit position (see ipu_irq_map())
- * @return:	0 or negative error code
- */
-int ipu_irq_unmap(unsigned int source)
-{
-	int i, ret = -EINVAL;
-
-	might_sleep();
-
-	mutex_lock(&map_lock);
-	for (i = 0; i < CONFIG_MX3_IPU_IRQS; i++) {
-		if (irq_map[i].source == source) {
-			unsigned long lock_flags;
-
-			pr_debug("IPU: unmapped source %u from IRQ %u\n",
-				 source, irq_map[i].irq);
-
-			spin_lock_irqsave(&bank_lock, lock_flags);
-			irq_map[i].source = -EINVAL;
-			irq_map[i].bank = NULL;
-			spin_unlock_irqrestore(&bank_lock, lock_flags);
-
-			ret = 0;
-			break;
-		}
-	}
-	mutex_unlock(&map_lock);
+	ret = ipu_read_reg(ipu, IPU_INT_STAT(ipu_irq / 32)) &
+		(1UL << (ipu_irq & 31));
 
 	return ret;
 }
 
 /* Chained IRQ handler for IPU error interrupt */
-static void ipu_irq_err(unsigned int irq, struct irq_desc *desc)
+static void ipu_irq(unsigned int irq, struct irq_desc *desc)
 {
 	struct ipu *ipu = irq_get_handler_data(irq);
-	u32 status;
-	int i, line;
+	unsigned long status;
+	unsigned long bit;
+	int i;
 
-	for (i = IPU_IRQ_NR_FN_BANKS; i < IPU_IRQ_NR_BANKS; i++) {
-		struct ipu_irq_bank *bank = irq_bank + i;
+	for (i = 0; i < IPU_IRQ_NR_BANKS; i++) {
 
 		spin_lock(&bank_lock);
-		status = ipu_read_reg(ipu, bank->status);
+		status = ipu_read_reg(ipu, IPU_INT_STAT(i));
 		/*
 		 * Don't think we have to clear all interrupts here, they will
 		 * be acked by ->handle_irq() (handle_level_irq). However, we
 		 * might want to clear unhandled interrupts after the loop...
 		 */
-		status &= ipu_read_reg(ipu, bank->control);
+		status &= ipu_read_reg(ipu, IPU_INT_CTRL(i));
 		spin_unlock(&bank_lock);
-		while ((line = ffs(status))) {
-			struct ipu_irq_map *map;
-
-			line--;
-			status &= ~(1UL << line);
-
-			spin_lock(&bank_lock);
-			map = src2map(32 * i + line);
-			if (map)
-				irq = map->irq;
-			spin_unlock(&bank_lock);
-
-			if (!map) {
-				pr_err("IPU: Interrupt on unmapped source %u bank %d\n",
-				       line, i);
-				continue;
-			}
-			generic_handle_irq(irq);
-		}
-	}
-}
-
-/* Chained IRQ handler for IPU function interrupt */
-static void ipu_irq_fn(unsigned int irq, struct irq_desc *desc)
-{
-	struct ipu *ipu = irq_desc_get_handler_data(desc);
-	u32 status;
-	int i, line;
-
-	for (i = 0; i < IPU_IRQ_NR_FN_BANKS; i++) {
-		struct ipu_irq_bank *bank = irq_bank + i;
-
-		spin_lock(&bank_lock);
-		status = ipu_read_reg(ipu, bank->status);
-		/* Not clearing all interrupts, see above */
-		status &= ipu_read_reg(ipu, bank->control);
-		spin_unlock(&bank_lock);
-		while ((line = ffs(status))) {
-			struct ipu_irq_map *map;
-
-			line--;
-			status &= ~(1UL << line);
-
-			spin_lock(&bank_lock);
-			map = src2map(32 * i + line);
-			if (map)
-				irq = map->irq;
-			spin_unlock(&bank_lock);
-
-			if (!map) {
-				pr_err("IPU: Interrupt on unmapped source %u bank %d\n",
-				       line, i);
-				continue;
-			}
-			generic_handle_irq(irq);
-		}
+		for_each_set_bit(bit, &status, 32)
+			generic_handle_irq(ipu->irq_base + i * 32 + bit);
 	}
 }
 
@@ -354,48 +139,41 @@ static struct irq_chip ipu_irq_chip = {
 /* Install the IRQ handler */
 int __init ipu_irq_attach_irq(struct ipu *ipu, struct platform_device *dev)
 {
-	struct ipu_platform_data *pdata = dev->dev.platform_data;
-	unsigned int irq, irq_base, i;
+	unsigned int irq, irq_base;
 
-	irq_base = pdata->irq_base;
+	irq_base = irq_alloc_descs(-1, 0, IPU_IRQ_NR_BANKS * 32, 0);
+	if (irq_base < 0)
+		return irq_base;
 
-	for (i = 0; i < IPU_IRQ_NR_BANKS; i++)
-		irq_bank[i].ipu = ipu;
+	ipu->irq_base = irq_base;
 
-	for (i = 0; i < CONFIG_MX3_IPU_IRQS; i++) {
+	for (irq = irq_base; irq < irq_base + IPU_NUM_IRQS; irq++) {
 		int ret;
 
-		irq = irq_base + i;
 		ret = irq_set_chip(irq, &ipu_irq_chip);
 		if (ret < 0)
 			return ret;
-		ret = irq_set_chip_data(irq, irq_map + i);
+		ret = irq_set_chip_data(irq, ipu);
 		if (ret < 0)
 			return ret;
-		irq_map[i].ipu = ipu;
-		irq_map[i].irq = irq;
-		irq_map[i].source = -EINVAL;
 		irq_set_handler(irq, handle_level_irq);
-#ifdef CONFIG_ARM
 		set_irq_flags(irq, IRQF_VALID | IRQF_PROBE);
-#endif
 	}
 
 	irq_set_handler_data(ipu->irq_fn, ipu);
-	irq_set_chained_handler(ipu->irq_fn, ipu_irq_fn);
+	irq_set_chained_handler(ipu->irq_fn, ipu_irq);
 
 	irq_set_handler_data(ipu->irq_err, ipu);
-	irq_set_chained_handler(ipu->irq_err, ipu_irq_err);
+	irq_set_chained_handler(ipu->irq_err, ipu_irq);
 
 	return 0;
 }
 
 void ipu_irq_detach_irq(struct ipu *ipu, struct platform_device *dev)
 {
-	struct ipu_platform_data *pdata = dev->dev.platform_data;
 	unsigned int irq, irq_base;
 
-	irq_base = pdata->irq_base;
+	irq_base = ipu->irq_base;
 
 	irq_set_chained_handler(ipu->irq_fn, NULL);
 	irq_set_handler_data(ipu->irq_fn, NULL);
@@ -403,10 +181,8 @@ void ipu_irq_detach_irq(struct ipu *ipu, struct platform_device *dev)
 	irq_set_chained_handler(ipu->irq_err, NULL);
 	irq_set_handler_data(ipu->irq_err, NULL);
 
-	for (irq = irq_base; irq < irq_base + CONFIG_MX3_IPU_IRQS; irq++) {
-#ifdef CONFIG_ARM
+	for (irq = irq_base; irq < irq_base + IPU_IRQ_NR_BANKS * 32; irq++) {
 		set_irq_flags(irq, 0);
-#endif
 		irq_set_chip(irq, NULL);
 		irq_set_chip_data(irq, NULL);
 	}
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH 9/9] ARM i.MX3: remove now useless ipu platform data from boards
  2011-05-20  7:59 i.MX: switch to sparse irqs Sascha Hauer
                   ` (8 preceding siblings ...)
  2011-05-20  7:59 ` [PATCH 8/9] dma IPU: rework irq handling Sascha Hauer
@ 2011-05-20  7:59 ` Sascha Hauer
  9 siblings, 0 replies; 32+ messages in thread
From: Sascha Hauer @ 2011-05-20  7:59 UTC (permalink / raw)
  To: linux-arm-kernel

The ipu now uses dynamically allocated irqs, thus we do not need
the platform data anymore. Also, remove the temporary irq_alloc_descs
in the i.MX platform code.

Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
---
 arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c |    6 +-----
 arch/arm/mach-imx/mach-armadillo5x0.c          |    6 +-----
 arch/arm/mach-imx/mach-mx31_3ds.c              |    6 +-----
 arch/arm/mach-imx/mach-mx31moboard.c           |    6 +-----
 arch/arm/mach-imx/mach-pcm037.c                |    6 +-----
 arch/arm/mach-imx/mach-pcm043.c                |    6 +-----
 arch/arm/mach-imx/mach-vpr200.c                |    6 +-----
 arch/arm/mach-imx/mm-imx31.c                   |    6 ------
 arch/arm/mach-imx/mm-imx35.c                   |    6 ------
 arch/arm/mach-imx/mx31lilly-db.c               |    6 +-----
 arch/arm/plat-mxc/include/mach/ipu.h           |    1 -
 arch/arm/plat-mxc/include/mach/irqs.h          |    3 ---
 12 files changed, 8 insertions(+), 56 deletions(-)

diff --git a/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c b/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c
index 4909ea0..260a8bc 100644
--- a/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c
+++ b/arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c
@@ -95,10 +95,6 @@ static const struct fb_videomode fb_modedb[] = {
 	},
 };
 
-static const struct ipu_platform_data mx3_ipu_data __initconst = {
-	.irq_base = MXC_IPU_IRQ_START,
-};
-
 static struct mx3fb_platform_data mx3fb_pdata __initdata = {
 	.name		= "CMO-QVGA",
 	.mode		= fb_modedb,
@@ -276,7 +272,7 @@ void __init eukrea_mbimxsd35_baseboard_init(void)
 #endif
 
 	imx35_add_imx_uart1(&uart_pdata);
-	imx35_add_ipu_core(&mx3_ipu_data);
+	imx35_add_ipu_core(NULL);
 	imx35_add_mx3_sdc_fb(&mx3fb_pdata);
 
 	imx35_add_imx_ssi(0, &eukrea_mbimxsd_ssi_pdata);
diff --git a/arch/arm/mach-imx/mach-armadillo5x0.c b/arch/arm/mach-imx/mach-armadillo5x0.c
index ffb40ff..00eebeb 100644
--- a/arch/arm/mach-imx/mach-armadillo5x0.c
+++ b/arch/arm/mach-imx/mach-armadillo5x0.c
@@ -371,10 +371,6 @@ static const struct fb_videomode fb_modedb[] = {
 	},
 };
 
-static const struct ipu_platform_data mx3_ipu_data __initconst = {
-	.irq_base = MXC_IPU_IRQ_START,
-};
-
 static struct mx3fb_platform_data mx3fb_pdata __initdata = {
 	.name		= "CRT-VGA",
 	.mode		= fb_modedb,
@@ -508,7 +504,7 @@ static void __init armadillo5x0_init(void)
 	imx31_add_mxc_mmc(0, &sdhc_pdata);
 
 	/* Register FB */
-	imx31_add_ipu_core(&mx3_ipu_data);
+	imx31_add_ipu_core(NULL);
 	imx31_add_mx3_sdc_fb(&mx3fb_pdata);
 
 	/* Register NOR Flash */
diff --git a/arch/arm/mach-imx/mach-mx31_3ds.c b/arch/arm/mach-imx/mach-mx31_3ds.c
index 9b98244..3b1b374 100644
--- a/arch/arm/mach-imx/mach-mx31_3ds.c
+++ b/arch/arm/mach-imx/mach-mx31_3ds.c
@@ -273,10 +273,6 @@ static const struct fb_videomode fb_modedb[] = {
 	},
 };
 
-static struct ipu_platform_data mx3_ipu_data = {
-	.irq_base = MXC_IPU_IRQ_START,
-};
-
 static struct mx3fb_platform_data mx3fb_pdata __initdata = {
 	.name		= "Epson-VGA",
 	.mode		= fb_modedb,
@@ -726,7 +722,7 @@ static void __init mx31_3ds_init(void)
 	imx31_add_mxc_mmc(0, &sdhc1_pdata);
 
 	imx31_add_spi_imx0(&spi0_pdata);
-	imx31_add_ipu_core(&mx3_ipu_data);
+	imx31_add_ipu_core(NULL);
 	imx31_add_mx3_sdc_fb(&mx3fb_pdata);
 
 	/* CSI */
diff --git a/arch/arm/mach-imx/mach-mx31moboard.c b/arch/arm/mach-imx/mach-mx31moboard.c
index eaa51e4..18e97d7 100644
--- a/arch/arm/mach-imx/mach-mx31moboard.c
+++ b/arch/arm/mach-imx/mach-mx31moboard.c
@@ -455,10 +455,6 @@ static struct platform_device mx31moboard_leds_device = {
 	},
 };
 
-static const struct ipu_platform_data mx3_ipu_data __initconst = {
-	.irq_base = MXC_IPU_IRQ_START,
-};
-
 static struct platform_device *devices[] __initdata = {
 	&mx31moboard_flash,
 	&mx31moboard_leds_device,
@@ -477,7 +473,7 @@ static int __init mx31moboard_init_cam(void)
 	int dma, ret = -ENOMEM;
 	struct platform_device *pdev;
 
-	imx31_add_ipu_core(&mx3_ipu_data);
+	imx31_add_ipu_core(NULL);
 
 	pdev = imx31_alloc_mx3_camera(&camera_pdata);
 	if (IS_ERR(pdev))
diff --git a/arch/arm/mach-imx/mach-pcm037.c b/arch/arm/mach-imx/mach-pcm037.c
index 89c213b..2789fd1 100644
--- a/arch/arm/mach-imx/mach-pcm037.c
+++ b/arch/arm/mach-imx/mach-pcm037.c
@@ -439,10 +439,6 @@ static struct platform_device *devices[] __initdata = {
 	&pcm037_mt9v022,
 };
 
-static const struct ipu_platform_data mx3_ipu_data __initconst = {
-	.irq_base = MXC_IPU_IRQ_START,
-};
-
 static const struct fb_videomode fb_modedb[] = {
 	{
 		/* 240x320 @ 60 Hz Sharp */
@@ -634,7 +630,7 @@ static void __init pcm037_init(void)
 
 	imx31_add_mxc_nand(&pcm037_nand_board_info);
 	imx31_add_mxc_mmc(0, &sdhc_pdata);
-	imx31_add_ipu_core(&mx3_ipu_data);
+	imx31_add_ipu_core(NULL);
 	imx31_add_mx3_sdc_fb(&mx3fb_pdata);
 
 	/* CSI */
diff --git a/arch/arm/mach-imx/mach-pcm043.c b/arch/arm/mach-imx/mach-pcm043.c
index 0264416..1820a95b 100644
--- a/arch/arm/mach-imx/mach-pcm043.c
+++ b/arch/arm/mach-imx/mach-pcm043.c
@@ -77,10 +77,6 @@ static const struct fb_videomode fb_modedb[] = {
 	},
 };
 
-static const struct ipu_platform_data mx3_ipu_data __initconst = {
-	.irq_base = MXC_IPU_IRQ_START,
-};
-
 static struct mx3fb_platform_data mx3fb_pdata __initdata = {
 	.name		= "Sharp-LQ035Q7",
 	.mode		= fb_modedb,
@@ -385,7 +381,7 @@ static void __init pcm043_init(void)
 
 	imx35_add_imx_i2c0(&pcm043_i2c0_data);
 
-	imx35_add_ipu_core(&mx3_ipu_data);
+	imx35_add_ipu_core(NULL);
 	imx35_add_mx3_sdc_fb(&mx3fb_pdata);
 
 	if (otg_mode_host) {
diff --git a/arch/arm/mach-imx/mach-vpr200.c b/arch/arm/mach-imx/mach-vpr200.c
index d74e347..190a19e 100644
--- a/arch/arm/mach-imx/mach-vpr200.c
+++ b/arch/arm/mach-imx/mach-vpr200.c
@@ -87,10 +87,6 @@ static const struct fb_videomode fb_modedb[] = {
 	}
 };
 
-static const struct ipu_platform_data mx3_ipu_data __initconst = {
-	.irq_base = MXC_IPU_IRQ_START,
-};
-
 static struct mx3fb_platform_data mx3fb_pdata __initdata = {
 	.name		= "PT0708048",
 	.mode		= fb_modedb,
@@ -288,7 +284,7 @@ static void __init vpr200_board_init(void)
 	imx35_add_imx_uart0(NULL);
 	imx35_add_imx_uart2(NULL);
 
-	imx35_add_ipu_core(&mx3_ipu_data);
+	imx35_add_ipu_core(NULL);
 	imx35_add_mx3_sdc_fb(&mx3fb_pdata);
 
 	imx35_add_fsl_usb2_udc(&otg_device_pdata);
diff --git a/arch/arm/mach-imx/mm-imx31.c b/arch/arm/mach-imx/mm-imx31.c
index e055ef0..af0a982 100644
--- a/arch/arm/mach-imx/mm-imx31.c
+++ b/arch/arm/mach-imx/mm-imx31.c
@@ -61,12 +61,6 @@ static struct mxc_gpio_port imx31_gpio_ports[] = {
 
 void __init mx31_init_irq(void)
 {
-	int ret;
-
 	mxc_init_irq(MX31_IO_ADDRESS(MX31_AVIC_BASE_ADDR));
 	mxc_gpio_init(imx31_gpio_ports,	ARRAY_SIZE(imx31_gpio_ports));
-
-	/* The ipu driver should handle this */
-	ret = irq_alloc_descs(MXC_IPU_IRQ_START, MXC_IPU_IRQ_START, 160, 0);
-	BUG_ON(ret != MXC_IPU_IRQ_START);
 }
diff --git a/arch/arm/mach-imx/mm-imx35.c b/arch/arm/mach-imx/mm-imx35.c
index abe908b..d10bff5 100644
--- a/arch/arm/mach-imx/mm-imx35.c
+++ b/arch/arm/mach-imx/mm-imx35.c
@@ -59,12 +59,6 @@ static struct mxc_gpio_port imx35_gpio_ports[] = {
 
 void __init mx35_init_irq(void)
 {
-	int ret;
-
 	mxc_init_irq(MX35_IO_ADDRESS(MX35_AVIC_BASE_ADDR));
 	mxc_gpio_init(imx35_gpio_ports,	ARRAY_SIZE(imx35_gpio_ports));
-
-	/* The ipu driver should handle this */
-	ret = irq_alloc_descs(MXC_IPU_IRQ_START, MXC_IPU_IRQ_START, 160, 0);
-	BUG_ON(ret != MXC_IPU_IRQ_START);
 }
diff --git a/arch/arm/mach-imx/mx31lilly-db.c b/arch/arm/mach-imx/mx31lilly-db.c
index 7d26f76..dc0fc9b 100644
--- a/arch/arm/mach-imx/mx31lilly-db.c
+++ b/arch/arm/mach-imx/mx31lilly-db.c
@@ -161,10 +161,6 @@ static const struct imxmmc_platform_data mmc_pdata __initconst = {
 };
 
 /* Framebuffer support */
-static const struct ipu_platform_data ipu_data __initconst = {
-	.irq_base = MXC_IPU_IRQ_START,
-};
-
 static const struct fb_videomode fb_modedb = {
 	/* 640x480 TFT panel (IPS-056T) */
 	.name		= "CRT-VGA",
@@ -198,7 +194,7 @@ static void __init mx31lilly_init_fb(void)
 		return;
 	}
 
-	imx31_add_ipu_core(&ipu_data);
+	imx31_add_ipu_core(NULL);
 	imx31_add_mx3_sdc_fb(&fb_pdata);
 	gpio_direction_output(LCD_VCC_EN_GPIO, 1);
 }
diff --git a/arch/arm/plat-mxc/include/mach/ipu.h b/arch/arm/plat-mxc/include/mach/ipu.h
index a9221f1..0b38d13 100644
--- a/arch/arm/plat-mxc/include/mach/ipu.h
+++ b/arch/arm/plat-mxc/include/mach/ipu.h
@@ -111,7 +111,6 @@ enum ipu_rotate_mode {
 };
 
 struct ipu_platform_data {
-	unsigned int	irq_base;
 };
 
 /*
diff --git a/arch/arm/plat-mxc/include/mach/irqs.h b/arch/arm/plat-mxc/include/mach/irqs.h
index 8253463..c281cf0 100644
--- a/arch/arm/plat-mxc/include/mach/irqs.h
+++ b/arch/arm/plat-mxc/include/mach/irqs.h
@@ -22,9 +22,6 @@
 /* one board (mx31ads) still depends on this. Do not add new dependencies */
 #define MXC_BOARD_IRQ_START	512
 
-/* should go away once the ipu uses dynamically allocated irqs */
-#define MXC_IPU_IRQ_START	1024
-
 /* All irqs dynamically allocated */
 #define NR_IRQS			0
 
-- 
1.7.4.1

^ permalink raw reply related	[flat|nested] 32+ messages in thread

* [PATCH] mfd wm8350: allocate irq descs dynamically
  2011-05-20  7:59 ` [PATCH] mfd wm8350: allocate irq descs dynamically Sascha Hauer
@ 2011-05-20 12:52   ` Thomas Gleixner
  2011-05-20 13:07     ` Sascha Hauer
  0 siblings, 1 reply; 32+ messages in thread
From: Thomas Gleixner @ 2011-05-20 12:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 20 May 2011, Sascha Hauer wrote:
> @@ -500,7 +500,17 @@ int wm8350_irq_init(struct wm8350 *wm8350, int irq,
>  
>  	mutex_init(&wm8350->irq_lock);
>  	wm8350->chip_irq = irq;
> -	wm8350->irq_base = pdata->irq_base;

Keeping this line would save you the else path :)

> +
> +	if (!pdata->irq_base) {
> +		wm8350->irq_base = irq_alloc_descs(-1, 0, ARRAY_SIZE(wm8350_irqs), 0);
> +		if (wm8350->irq_base < 0) {
> +			dev_warn(wm8350->dev, "Allocating irqs failed with %d\n",
> +				wm8350->irq_base);
> +			return 0;

  Hmm, return 0 on failure ?

> +		}
> +	} else {
> +		wm8350->irq_base = pdata->irq_base;
> +	}
>  
>  	if (pdata->irq_high) {
>  		flags |= IRQF_TRIGGER_HIGH;
> -- 
> 1.7.4.1
> 
> 

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH] mfd wm8350: allocate irq descs dynamically
  2011-05-20 12:52   ` Thomas Gleixner
@ 2011-05-20 13:07     ` Sascha Hauer
  2011-05-20 13:19       ` Thomas Gleixner
  0 siblings, 1 reply; 32+ messages in thread
From: Sascha Hauer @ 2011-05-20 13:07 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, May 20, 2011 at 02:52:28PM +0200, Thomas Gleixner wrote:
> On Fri, 20 May 2011, Sascha Hauer wrote:
> > @@ -500,7 +500,17 @@ int wm8350_irq_init(struct wm8350 *wm8350, int irq,
> >  
> >  	mutex_init(&wm8350->irq_lock);
> >  	wm8350->chip_irq = irq;
> > -	wm8350->irq_base = pdata->irq_base;
> 
> Keeping this line would save you the else path :)

Right.

> 
> > +
> > +	if (!pdata->irq_base) {
> > +		wm8350->irq_base = irq_alloc_descs(-1, 0, ARRAY_SIZE(wm8350_irqs), 0);
> > +		if (wm8350->irq_base < 0) {
> > +			dev_warn(wm8350->dev, "Allocating irqs failed with %d\n",
> > +				wm8350->irq_base);
> > +			return 0;
> 
>   Hmm, return 0 on failure ?

This function does this elsewhere aswell. The driver continues without
interrupt support in this case.

Looking at the driver again I wonder that it does not call
irq_set_chained_handler but request_threaded_irq for its chained
handler. Is it ok to do so or even prefered?

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 8/9] dma IPU: rework irq handling
  2011-05-20  7:59 ` [PATCH 8/9] dma IPU: rework irq handling Sascha Hauer
@ 2011-05-20 13:16   ` Thomas Gleixner
  2011-05-20 13:30     ` Sascha Hauer
  0 siblings, 1 reply; 32+ messages in thread
From: Thomas Gleixner @ 2011-05-20 13:16 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 20 May 2011, Sascha Hauer wrote:
> @@ -354,48 +139,41 @@ static struct irq_chip ipu_irq_chip = {
>  /* Install the IRQ handler */
>  int __init ipu_irq_attach_irq(struct ipu *ipu, struct platform_device *dev)
>  {
> -	struct ipu_platform_data *pdata = dev->dev.platform_data;
> -	unsigned int irq, irq_base, i;
> +	unsigned int irq, irq_base;
>  
> -	irq_base = pdata->irq_base;
> +	irq_base = irq_alloc_descs(-1, 0, IPU_IRQ_NR_BANKS * 32, 0);

  	IPU_NUM_IRQS perhaps ?

> +	if (irq_base < 0)
> +		return irq_base;
  
So this allocates 160 interrupts. How many of them are actually going
to be used ?

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH] mfd wm8350: allocate irq descs dynamically
  2011-05-20 13:07     ` Sascha Hauer
@ 2011-05-20 13:19       ` Thomas Gleixner
  2011-05-21 11:29         ` Mark Brown
  0 siblings, 1 reply; 32+ messages in thread
From: Thomas Gleixner @ 2011-05-20 13:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 20 May 2011, Sascha Hauer wrote:

> On Fri, May 20, 2011 at 02:52:28PM +0200, Thomas Gleixner wrote:
> > On Fri, 20 May 2011, Sascha Hauer wrote:
> > > @@ -500,7 +500,17 @@ int wm8350_irq_init(struct wm8350 *wm8350, int irq,
> > >  
> > >  	mutex_init(&wm8350->irq_lock);
> > >  	wm8350->chip_irq = irq;
> > > -	wm8350->irq_base = pdata->irq_base;
> > 
> > Keeping this line would save you the else path :)
> 
> Right.
> 
> > 
> > > +
> > > +	if (!pdata->irq_base) {
> > > +		wm8350->irq_base = irq_alloc_descs(-1, 0, ARRAY_SIZE(wm8350_irqs), 0);
> > > +		if (wm8350->irq_base < 0) {
> > > +			dev_warn(wm8350->dev, "Allocating irqs failed with %d\n",
> > > +				wm8350->irq_base);
> > > +			return 0;
> > 
> >   Hmm, return 0 on failure ?
> 
> This function does this elsewhere aswell. The driver continues without
> interrupt support in this case.

Fair enough.
 
> Looking at the driver again I wonder that it does not call
> irq_set_chained_handler but request_threaded_irq for its chained
> handler. Is it ok to do so or even prefered?

It's ok and done on purpose. See the comment above the interrupt
handler function:

* This is a threaded IRQ handler so can access I2C/SPI. ...

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 8/9] dma IPU: rework irq handling
  2011-05-20 13:16   ` Thomas Gleixner
@ 2011-05-20 13:30     ` Sascha Hauer
  2011-05-20 16:46       ` Thomas Gleixner
  0 siblings, 1 reply; 32+ messages in thread
From: Sascha Hauer @ 2011-05-20 13:30 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, May 20, 2011 at 03:16:42PM +0200, Thomas Gleixner wrote:
> On Fri, 20 May 2011, Sascha Hauer wrote:
> > @@ -354,48 +139,41 @@ static struct irq_chip ipu_irq_chip = {
> >  /* Install the IRQ handler */
> >  int __init ipu_irq_attach_irq(struct ipu *ipu, struct platform_device *dev)
> >  {
> > -	struct ipu_platform_data *pdata = dev->dev.platform_data;
> > -	unsigned int irq, irq_base, i;
> > +	unsigned int irq, irq_base;
> >  
> > -	irq_base = pdata->irq_base;
> > +	irq_base = irq_alloc_descs(-1, 0, IPU_IRQ_NR_BANKS * 32, 0);
> 
>   	IPU_NUM_IRQS perhaps ?
> 
> > +	if (irq_base < 0)
> > +		return irq_base;
>   
> So this allocates 160 interrupts. How many of them are actually going
> to be used ?

One for the framebuffer and another one for the camera...

BTW often enough it's the same for the gpio interrupts. I have plenty of
boards ending up with a single gpio interrupt out of 160 used for a
external network controller.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 8/9] dma IPU: rework irq handling
  2011-05-20 13:30     ` Sascha Hauer
@ 2011-05-20 16:46       ` Thomas Gleixner
  2011-05-20 22:11         ` Benjamin Herrenschmidt
  0 siblings, 1 reply; 32+ messages in thread
From: Thomas Gleixner @ 2011-05-20 16:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, 20 May 2011, Sascha Hauer wrote:

> On Fri, May 20, 2011 at 03:16:42PM +0200, Thomas Gleixner wrote:
> > On Fri, 20 May 2011, Sascha Hauer wrote:
> > > @@ -354,48 +139,41 @@ static struct irq_chip ipu_irq_chip = {
> > >  /* Install the IRQ handler */
> > >  int __init ipu_irq_attach_irq(struct ipu *ipu, struct platform_device *dev)
> > >  {
> > > -	struct ipu_platform_data *pdata = dev->dev.platform_data;
> > > -	unsigned int irq, irq_base, i;
> > > +	unsigned int irq, irq_base;
> > >  
> > > -	irq_base = pdata->irq_base;
> > > +	irq_base = irq_alloc_descs(-1, 0, IPU_IRQ_NR_BANKS * 32, 0);
> > 
> >   	IPU_NUM_IRQS perhaps ?
> > 
> > > +	if (irq_base < 0)
> > > +		return irq_base;
> >   
> > So this allocates 160 interrupts. How many of them are actually going
> > to be used ?
> 
> One for the framebuffer and another one for the camera...
> 
> BTW often enough it's the same for the gpio interrupts. I have plenty of
> boards ending up with a single gpio interrupt out of 160 used for a
> external network controller.

We could actually be more clever about that by doing:

   irq_prealloc_irqs(from, cnt, setup_callback);

Which would return you the base nr of a linear range and at
request_irq() time we would detect the missing irq descriptor,
allocate it and call the setup_callback, which would fill in chip,
handler, data etc. That would make the few lines of init code for the
descriptor non __init, but we could avoid allocating 159 irq
descriptors for nothing.

The demux interrupt could still call generic_handle_irq() as we have a
sanity in place there now and a return value to let the demux irq know
that shite happened.

Thanks,

	tglx

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH 8/9] dma IPU: rework irq handling
  2011-05-20 16:46       ` Thomas Gleixner
@ 2011-05-20 22:11         ` Benjamin Herrenschmidt
  0 siblings, 0 replies; 32+ messages in thread
From: Benjamin Herrenschmidt @ 2011-05-20 22:11 UTC (permalink / raw)
  To: linux-arm-kernel


> > One for the framebuffer and another one for the camera...
> > 
> > BTW often enough it's the same for the gpio interrupts. I have plenty of
> > boards ending up with a single gpio interrupt out of 160 used for a
> > external network controller.
> 
> We could actually be more clever about that by doing:
> 
>    irq_prealloc_irqs(from, cnt, setup_callback);
> 
> Which would return you the base nr of a linear range and at
> request_irq() time we would detect the missing irq descriptor,
> allocate it and call the setup_callback, which would fill in chip,
> handler, data etc. That would make the few lines of init code for the
> descriptor non __init, but we could avoid allocating 159 irq
> descriptors for nothing.
> 
> The demux interrupt could still call generic_handle_irq() as we have a
> sanity in place there now and a return value to let the demux irq know
> that shite happened.

Well, if you use the remapper we use on power, then you can allocate
descriptors and interrupt numbers even on demand :-) But I see some
interest I suppose in keeping a linear range of irq numbers, makes
diagnosing easier for example...

Cheers,
Ben.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH] mfd wm8350: allocate irq descs dynamically
  2011-05-20 13:19       ` Thomas Gleixner
@ 2011-05-21 11:29         ` Mark Brown
  2011-05-23  6:25           ` Sascha Hauer
  0 siblings, 1 reply; 32+ messages in thread
From: Mark Brown @ 2011-05-21 11:29 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, May 20, 2011 at 03:19:44PM +0200, Thomas Gleixner wrote:
> On Fri, 20 May 2011, Sascha Hauer wrote:
> 
> > On Fri, May 20, 2011 at 02:52:28PM +0200, Thomas Gleixner wrote:
> > > On Fri, 20 May 2011, Sascha Hauer wrote:
> > > > @@ -500,7 +500,17 @@ int wm8350_irq_init(struct wm8350 *wm8350, int irq,

Sascha, you should know to *always* CC maintainers on patches.  Don't
apply this patch, and please engage with the feedback I posted when you
sent an earlier version of this patch.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH] mfd wm8350: allocate irq descs dynamically
  2011-05-21 11:29         ` Mark Brown
@ 2011-05-23  6:25           ` Sascha Hauer
  2011-05-23 10:44             ` Mark Brown
  0 siblings, 1 reply; 32+ messages in thread
From: Sascha Hauer @ 2011-05-23  6:25 UTC (permalink / raw)
  To: linux-arm-kernel

Mark,

On Sat, May 21, 2011 at 12:29:47PM +0100, Mark Brown wrote:
> On Fri, May 20, 2011 at 03:19:44PM +0200, Thomas Gleixner wrote:
> > On Fri, 20 May 2011, Sascha Hauer wrote:
> > 
> > > On Fri, May 20, 2011 at 02:52:28PM +0200, Thomas Gleixner wrote:
> > > > On Fri, 20 May 2011, Sascha Hauer wrote:
> > > > > @@ -500,7 +500,17 @@ int wm8350_irq_init(struct wm8350 *wm8350, int irq,
> 
> Sascha, you should know to *always* CC maintainers on patches.  Don't
> apply this patch, and please engage with the feedback I posted when you
> sent an earlier version of this patch.

Sorry for this, should have added you to the cc list of that indivual
patch. I can't find your reply in my mail, could you send it again?

Sascha


-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH] mfd wm8350: allocate irq descs dynamically
  2011-05-23  6:25           ` Sascha Hauer
@ 2011-05-23 10:44             ` Mark Brown
  2011-05-23 14:41               ` Sascha Hauer
  0 siblings, 1 reply; 32+ messages in thread
From: Mark Brown @ 2011-05-23 10:44 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, May 23, 2011 at 08:25:01AM +0200, Sascha Hauer wrote:

> Sorry for this, should have added you to the cc list of that indivual
> patch. I can't find your reply in my mail, could you send it again?

Attached.
-------------- next part --------------
An embedded message was scrubbed...
From: Mark Brown <broonie@opensource.wolfsonmicro.com>
Subject: Re: [PATCH] mfd wm8350: allocate irq descs dynamically
Date: Thu, 19 May 2011 14:04:41 -0700
Size: 3293
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20110523/ba098eff/attachment-0002.mht>
-------------- next part --------------
An embedded message was scrubbed...
From: Mark Brown <broonie@opensource.wolfsonmicro.com>
Subject: Re: [PATCH] mfd wm8350: allocate irq descs dynamically
Date: Thu, 19 May 2011 23:04:03 +0100
Size: 3470
URL: <http://lists.infradead.org/pipermail/linux-arm-kernel/attachments/20110523/ba098eff/attachment-0003.mht>

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH] mfd wm8350: allocate irq descs dynamically
  2011-05-23 10:44             ` Mark Brown
@ 2011-05-23 14:41               ` Sascha Hauer
  2011-05-23 15:22                 ` Mark Brown
  0 siblings, 1 reply; 32+ messages in thread
From: Sascha Hauer @ 2011-05-23 14:41 UTC (permalink / raw)
  To: linux-arm-kernel

> 
> > -	if (!pdata || !pdata->irq_base) {
> > -		dev_warn(wm8350->dev, "No interrupt support, no IRQ base\n");
> > +	if (!pdata) {
> > +		dev_warn(wm8350->dev, "No interrupt support, no platform data\n");
> 
> This isn't terribly good, the only reason we're checking pdata here is
> because we can't dereference it to look up irq_base if it's not there.

I'm not sure what you mean here. Are you suggesting that we should
default to dynamically requested irqs without platform data?
I did it this way because without platform data pdata->irq_high is
unknown.

> 
> > +	if (!pdata->irq_base) {
> > +		wm8350->irq_base = irq_alloc_descs(-1, 0, ARRAY_SIZE(wm8350_irqs), 0);
> > +		if (wm8350->irq_base < 0) {
> 
> One other thing - it doesn't seem to be 100% desirable to making the
> allocation of the IRQ descriptors depend on not specifying a base - for
> many situations we're likely to want to know what the numbers we end up
> with are (eg, for passing to another device) but if we don't call
> irq_alloc_decs() the platform still has to arrange for the descriptors
> to be there in advance.  It feels like the code should always use
> irq_alloc_descs(), though obviously that's not going to work right now.

If that's the case the platform still can provide irq_base and then it
does know in advance. Also, shouldn't this other device be instantiated
from the wm8350 driver?

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH] mfd wm8350: allocate irq descs dynamically
  2011-05-23 14:41               ` Sascha Hauer
@ 2011-05-23 15:22                 ` Mark Brown
  2011-05-23 16:46                   ` Sascha Hauer
  0 siblings, 1 reply; 32+ messages in thread
From: Mark Brown @ 2011-05-23 15:22 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, May 23, 2011 at 04:41:26PM +0200, Sascha Hauer wrote:

> > This isn't terribly good, the only reason we're checking pdata here is
> > because we can't dereference it to look up irq_base if it's not there.

> I'm not sure what you mean here. Are you suggesting that we should
> default to dynamically requested irqs without platform data?

Yes, exactly.

> I did it this way because without platform data pdata->irq_high is
> unknown.

With platform data it has a default value, and indeed when the chip
powers on it has a default.

> > One other thing - it doesn't seem to be 100% desirable to making the
> > allocation of the IRQ descriptors depend on not specifying a base - for
> > many situations we're likely to want to know what the numbers we end up
> > with are (eg, for passing to another device) but if we don't call
> > irq_alloc_decs() the platform still has to arrange for the descriptors
> > to be there in advance.  It feels like the code should always use
> > irq_alloc_descs(), though obviously that's not going to work right now.

> If that's the case the platform still can provide irq_base and then it
> does know in advance. Also, shouldn't this other device be instantiated

You're missing my point here.  The platform not only has to allocate the
base number, it also has to do the allocation of the descriptors.  That
seems less than ideal as it means that any platform using the driver
has to replicate the code for allocating the IRQ range that was
assigned.

> from the wm8350 driver?

We normally instantiate drivers following the control bus heirachy, not
the interrupt controller heirachy...

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH] mfd wm8350: allocate irq descs dynamically
  2011-05-23 15:22                 ` Mark Brown
@ 2011-05-23 16:46                   ` Sascha Hauer
  2011-05-23 22:41                     ` Mark Brown
  0 siblings, 1 reply; 32+ messages in thread
From: Sascha Hauer @ 2011-05-23 16:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, May 23, 2011 at 04:22:48PM +0100, Mark Brown wrote:
> On Mon, May 23, 2011 at 04:41:26PM +0200, Sascha Hauer wrote:
> 
> > > This isn't terribly good, the only reason we're checking pdata here is
> > > because we can't dereference it to look up irq_base if it's not there.
> 
> > I'm not sure what you mean here. Are you suggesting that we should
> > default to dynamically requested irqs without platform data?
> 
> Yes, exactly.
> 
> > I did it this way because without platform data pdata->irq_high is
> > unknown.
> 
> With platform data it has a default value, and indeed when the chip
> powers on it has a default.

Ok, what should be the default for irq_high then if we do not have
platform data?

> 
> > > One other thing - it doesn't seem to be 100% desirable to making the
> > > allocation of the IRQ descriptors depend on not specifying a base - for
> > > many situations we're likely to want to know what the numbers we end up
> > > with are (eg, for passing to another device) but if we don't call
> > > irq_alloc_decs() the platform still has to arrange for the descriptors
> > > to be there in advance.  It feels like the code should always use
> > > irq_alloc_descs(), though obviously that's not going to work right now.
> 
> > If that's the case the platform still can provide irq_base and then it
> > does know in advance. Also, shouldn't this other device be instantiated
> 
> You're missing my point here.  The platform not only has to allocate the
> base number, it also has to do the allocation of the descriptors.  That
> seems less than ideal as it means that any platform using the driver
> has to replicate the code for allocating the IRQ range that was
> assigned.

We can do the irq_alloc_descs unconditionally then. If irq_base is
not given, we are happy with any irq irq_alloc_descs returns. If
irq_base is given, we check the return value of irq_alloc_descs for
exactly irq_base.

> 
> > from the wm8350 driver?
> 
> We normally instantiate drivers following the control bus heirachy, not
> the interrupt controller heirachy...

I assumed that drivers using the irqs from the wm8350 are usually
children of the wm8350, like the watchdog, rtc, regulator drivers already are.
This may not be true for the gpio interrupts, but you can calculate the
irq from the gpio number.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH] mfd wm8350: allocate irq descs dynamically
  2011-05-23 16:46                   ` Sascha Hauer
@ 2011-05-23 22:41                     ` Mark Brown
  2011-05-24  7:28                       ` Sascha Hauer
  0 siblings, 1 reply; 32+ messages in thread
From: Mark Brown @ 2011-05-23 22:41 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, May 23, 2011 at 06:46:01PM +0200, Sascha Hauer wrote:
> On Mon, May 23, 2011 at 04:22:48PM +0100, Mark Brown wrote:

> > With platform data it has a default value, and indeed when the chip
> > powers on it has a default.

> Ok, what should be the default for irq_high then if we do not have
> platform data?

Off - the default value for platform data is all zeros.

> > You're missing my point here.  The platform not only has to allocate the
> > base number, it also has to do the allocation of the descriptors.  That
> > seems less than ideal as it means that any platform using the driver
> > has to replicate the code for allocating the IRQ range that was
> > assigned.

> We can do the irq_alloc_descs unconditionally then. If irq_base is
> not given, we are happy with any irq irq_alloc_descs returns. If
> irq_base is given, we check the return value of irq_alloc_descs for
> exactly irq_base.

That's what I'm suggesting, but like I say I'm not convinced that's
actually going to do the right thing currently on non-sparse systems or
on systems that do actually have the IRQ range allocated for some other
reason.

> > We normally instantiate drivers following the control bus heirachy, not
> > the interrupt controller heirachy...

> I assumed that drivers using the irqs from the wm8350 are usually
> children of the wm8350, like the watchdog, rtc, regulator drivers already are.
> This may not be true for the gpio interrupts, but you can calculate the
> irq from the gpio number.

You can only do that if the device is using the GPIO as a GPIO as well
as using it as an interrupt.  If the device is just using the GPIO on
the PMIC as an interrupt then it doesn't help as the driver isn't using
the GPIO API at all.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH] mfd wm8350: allocate irq descs dynamically
  2011-05-23 22:41                     ` Mark Brown
@ 2011-05-24  7:28                       ` Sascha Hauer
  2011-05-24  9:46                         ` Mark Brown
  0 siblings, 1 reply; 32+ messages in thread
From: Sascha Hauer @ 2011-05-24  7:28 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, May 24, 2011 at 06:41:00AM +0800, Mark Brown wrote:
> On Mon, May 23, 2011 at 06:46:01PM +0200, Sascha Hauer wrote:
> > On Mon, May 23, 2011 at 04:22:48PM +0100, Mark Brown wrote:
> 
> > > With platform data it has a default value, and indeed when the chip
> > > powers on it has a default.
> 
> > Ok, what should be the default for irq_high then if we do not have
> > platform data?
> 
> Off - the default value for platform data is all zeros.

Ok.

> 
> > > You're missing my point here.  The platform not only has to allocate the
> > > base number, it also has to do the allocation of the descriptors.  That
> > > seems less than ideal as it means that any platform using the driver
> > > has to replicate the code for allocating the IRQ range that was
> > > assigned.
> 
> > We can do the irq_alloc_descs unconditionally then. If irq_base is
> > not given, we are happy with any irq irq_alloc_descs returns. If
> > irq_base is given, we check the return value of irq_alloc_descs for
> > exactly irq_base.
> 
> That's what I'm suggesting, but like I say I'm not convinced that's
> actually going to do the right thing currently on non-sparse systems or

non-sparse systems handle this correctly.

> on systems that do actually have the IRQ range allocated for some other
> reason.

By 'some other reason' you mean an implementation bug? If the range is
already allocated the wm8350 driver should better not use it.

> 
> > > We normally instantiate drivers following the control bus heirachy, not
> > > the interrupt controller heirachy...
> 
> > I assumed that drivers using the irqs from the wm8350 are usually
> > children of the wm8350, like the watchdog, rtc, regulator drivers already are.
> > This may not be true for the gpio interrupts, but you can calculate the
> > irq from the gpio number.
> 
> You can only do that if the device is using the GPIO as a GPIO as well
> as using it as an interrupt.  If the device is just using the GPIO on
> the PMIC as an interrupt then it doesn't help as the driver isn't using
> the GPIO API at all.

You are right. As we agreed on allocating the irq descs unconditionally
and preserve the possibility for a fixed range passed in from platform
data this shouldn't be a problem. A platform can still use fixed irq
numbers if it wishes to.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH] mfd wm8350: allocate irq descs dynamically
  2011-05-24  7:28                       ` Sascha Hauer
@ 2011-05-24  9:46                         ` Mark Brown
  2011-05-24 11:52                           ` Sascha Hauer
  0 siblings, 1 reply; 32+ messages in thread
From: Mark Brown @ 2011-05-24  9:46 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, May 24, 2011 at 09:28:14AM +0200, Sascha Hauer wrote:
> On Tue, May 24, 2011 at 06:41:00AM +0800, Mark Brown wrote:

> > on systems that do actually have the IRQ range allocated for some other
> > reason.

> By 'some other reason' you mean an implementation bug? If the range is
> already allocated the wm8350 driver should better not use it.

Well, one obvious example is if someone's using the device with a sparse
system already - they'll have had to arrange to allocate the IRQ range
already.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH] mfd wm8350: allocate irq descs dynamically
  2011-05-24  9:46                         ` Mark Brown
@ 2011-05-24 11:52                           ` Sascha Hauer
  2011-05-24 15:35                             ` Mark Brown
  0 siblings, 1 reply; 32+ messages in thread
From: Sascha Hauer @ 2011-05-24 11:52 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, May 24, 2011 at 05:46:59PM +0800, Mark Brown wrote:
> On Tue, May 24, 2011 at 09:28:14AM +0200, Sascha Hauer wrote:
> > On Tue, May 24, 2011 at 06:41:00AM +0800, Mark Brown wrote:
> 
> > > on systems that do actually have the IRQ range allocated for some other
> > > reason.
> 
> > By 'some other reason' you mean an implementation bug? If the range is
> > already allocated the wm8350 driver should better not use it.
> 
> Well, one obvious example is if someone's using the device with a sparse
> system already - they'll have had to arrange to allocate the IRQ range
> already.

There seems to be no user in the kernel. Anyway, sooner or later we'll
have the same problem with other mfd drivers. So what do yuo suggest?

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH] mfd wm8350: allocate irq descs dynamically
  2011-05-24 11:52                           ` Sascha Hauer
@ 2011-05-24 15:35                             ` Mark Brown
  2011-05-25  8:13                               ` Sascha Hauer
  0 siblings, 1 reply; 32+ messages in thread
From: Mark Brown @ 2011-05-24 15:35 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, May 24, 2011 at 01:52:15PM +0200, Sascha Hauer wrote:
> On Tue, May 24, 2011 at 05:46:59PM +0800, Mark Brown wrote:

> > Well, one obvious example is if someone's using the device with a sparse
> > system already - they'll have had to arrange to allocate the IRQ range
> > already.

> There seems to be no user in the kernel. Anyway, sooner or later we'll
> have the same problem with other mfd drivers. So what do yuo suggest?

The other MFD drivers are exactly my issue here, obviously all these
devices have pretty much the same code and we should be doing the same
thing with all of them.  I've got a good idea about users for drivers I
maintain but less so for others.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH] mfd wm8350: allocate irq descs dynamically
  2011-05-24 15:35                             ` Mark Brown
@ 2011-05-25  8:13                               ` Sascha Hauer
  2011-05-25  9:23                                 ` Mark Brown
  0 siblings, 1 reply; 32+ messages in thread
From: Sascha Hauer @ 2011-05-25  8:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, May 24, 2011 at 11:35:46PM +0800, Mark Brown wrote:
> On Tue, May 24, 2011 at 01:52:15PM +0200, Sascha Hauer wrote:
> > On Tue, May 24, 2011 at 05:46:59PM +0800, Mark Brown wrote:
> 
> > > Well, one obvious example is if someone's using the device with a sparse
> > > system already - they'll have had to arrange to allocate the IRQ range
> > > already.
> 
> > There seems to be no user in the kernel. Anyway, sooner or later we'll
> > have the same problem with other mfd drivers. So what do yuo suggest?
> 
> The other MFD drivers are exactly my issue here, obviously all these
> devices have pretty much the same code and we should be doing the same
> thing with all of them.  I've got a good idea about users for drivers I
> maintain but less so for others.

Ok, how about this?

- Add a ALLOC_DESCS flag to platform data
- Without platform data are descs are dynamically allocated
- With platform data and ALLOC_DESCS not set: no dynamically
  allocated descs, no change at all
- With ALLOC_DESCS set descs are dynamically allocated with:
  - if irq_base is 0, the some range is allocated
  - with irq_base != 0, exactly irq_base + num is allocated

I also wonder if we should spill out a warning when ALLOC_DESCS is not
set. It basically means that we may use some otherwise used resources.

Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH] mfd wm8350: allocate irq descs dynamically
  2011-05-25  8:13                               ` Sascha Hauer
@ 2011-05-25  9:23                                 ` Mark Brown
  2011-05-25 19:10                                   ` Sascha Hauer
  0 siblings, 1 reply; 32+ messages in thread
From: Mark Brown @ 2011-05-25  9:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, May 25, 2011 at 10:13:26AM +0200, Sascha Hauer wrote:

> Ok, how about this?

> - Add a ALLOC_DESCS flag to platform data
> - Without platform data are descs are dynamically allocated
> - With platform data and ALLOC_DESCS not set: no dynamically
>   allocated descs, no change at all
> - With ALLOC_DESCS set descs are dynamically allocated with:
>   - if irq_base is 0, the some range is allocated
>   - with irq_base != 0, exactly irq_base + num is allocated

> I also wonder if we should spill out a warning when ALLOC_DESCS is not
> set. It basically means that we may use some otherwise used resources.

I dunno, that seems painful.  Perhaps we just accept that some boards
will be broken if things go wrong - the whole ALLOC_DESCS thing seems
more pain than it's worth.

^ permalink raw reply	[flat|nested] 32+ messages in thread

* [PATCH] mfd wm8350: allocate irq descs dynamically
  2011-05-25  9:23                                 ` Mark Brown
@ 2011-05-25 19:10                                   ` Sascha Hauer
  0 siblings, 0 replies; 32+ messages in thread
From: Sascha Hauer @ 2011-05-25 19:10 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, May 25, 2011 at 05:23:17PM +0800, Mark Brown wrote:
> On Wed, May 25, 2011 at 10:13:26AM +0200, Sascha Hauer wrote:
> 
> > Ok, how about this?
> 
> > - Add a ALLOC_DESCS flag to platform data
> > - Without platform data are descs are dynamically allocated
> > - With platform data and ALLOC_DESCS not set: no dynamically
> >   allocated descs, no change at all
> > - With ALLOC_DESCS set descs are dynamically allocated with:
> >   - if irq_base is 0, the some range is allocated
> >   - with irq_base != 0, exactly irq_base + num is allocated
> 
> > I also wonder if we should spill out a warning when ALLOC_DESCS is not
> > set. It basically means that we may use some otherwise used resources.
> 
> I dunno, that seems painful.  Perhaps we just accept that some boards
> will be broken if things go wrong - the whole ALLOC_DESCS thing seems
> more pain than it's worth.

Great :)

I'll send an updated patch soon.

Thanks
 Sascha

-- 
Pengutronix e.K.                           |                             |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |
Peiner Str. 6-8, 31137 Hildesheim, Germany | Phone: +49-5121-206917-0    |
Amtsgericht Hildesheim, HRA 2686           | Fax:   +49-5121-206917-5555 |

^ permalink raw reply	[flat|nested] 32+ messages in thread

end of thread, other threads:[~2011-05-25 19:10 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-05-20  7:59 i.MX: switch to sparse irqs Sascha Hauer
2011-05-20  7:59 ` [PATCH 1/9] ARM i.MX tzic: do not depend on MXC_INTERNAL_IRQS Sascha Hauer
2011-05-20  7:59 ` [PATCH] mfd wm8350: allocate irq descs dynamically Sascha Hauer
2011-05-20 12:52   ` Thomas Gleixner
2011-05-20 13:07     ` Sascha Hauer
2011-05-20 13:19       ` Thomas Gleixner
2011-05-21 11:29         ` Mark Brown
2011-05-23  6:25           ` Sascha Hauer
2011-05-23 10:44             ` Mark Brown
2011-05-23 14:41               ` Sascha Hauer
2011-05-23 15:22                 ` Mark Brown
2011-05-23 16:46                   ` Sascha Hauer
2011-05-23 22:41                     ` Mark Brown
2011-05-24  7:28                       ` Sascha Hauer
2011-05-24  9:46                         ` Mark Brown
2011-05-24 11:52                           ` Sascha Hauer
2011-05-24 15:35                             ` Mark Brown
2011-05-25  8:13                               ` Sascha Hauer
2011-05-25  9:23                                 ` Mark Brown
2011-05-25 19:10                                   ` Sascha Hauer
2011-05-20  7:59 ` [PATCH 2/9] ARM i.MX avic: do not depend on MXC_INTERNAL_IRQS Sascha Hauer
2011-05-20  7:59 ` [PATCH 3/9] ARM i.MX: get rid of wrong MXC_INTERNAL_IRQ usage Sascha Hauer
2011-05-20  7:59 ` [PATCH 4/9] mfd wm8350: allocate irq descs dynamically Sascha Hauer
2011-05-20  7:59 ` [PATCH 5/9] ARM i.MX mx31ads: allocate irqs for expio dynamically Sascha Hauer
2011-05-20  7:59 ` [PATCH 6/9] ARM i.MX 3ds debugboard: allocate irqs dynamically Sascha Hauer
2011-05-20  7:59 ` [PATCH 7/9] ARM i.MX: use sparse irqs Sascha Hauer
2011-05-20  7:59 ` [PATCH 8/9] dma IPU: rework irq handling Sascha Hauer
2011-05-20 13:16   ` Thomas Gleixner
2011-05-20 13:30     ` Sascha Hauer
2011-05-20 16:46       ` Thomas Gleixner
2011-05-20 22:11         ` Benjamin Herrenschmidt
2011-05-20  7:59 ` [PATCH 9/9] ARM i.MX3: remove now useless ipu platform data from boards Sascha Hauer

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.