Skip to contentSkip to conversation

i.MX: switch to sparse irqs

PATCH New Sascha Hauer 4 participants 32 messages May 20, 2011 – May 25, 2011

Subsystems (6)
lore
Share & tools
lore

Sascha Hauer

author maintainer
#0 lore raw

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(-)
author maintainer
#1 lore raw

PATCH 1/9 ARM i.MX tzic: do not depend on MXC_INTERNAL_IRQS

This becomes meaningless in subsequent patches.

---
 arch/arm/plat-mxc/tzic.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)
arch/arm/plat-mxc/tzic.c +3 -1
index 57f9395..710f2e7 100644
@@ -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);
Signature · 1 line
1.7.4.1
author maintainer
#2 lore raw

PATCH 1/1 mfd wm8350: allocate irq descs dynamically

In reply to Sascha Hauer

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

---
 drivers/mfd/wm8350-irq.c |   16 +++++++++++++---
 1 files changed, 13 insertions(+), 3 deletions(-)
drivers/mfd/wm8350-irq.c +13 -3
index ed4b22a..04408a5 100644
@@ -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;
Signature · 1 line
1.7.4.1
#3 lore raw

PATCH 1/1 mfd wm8350: allocate irq descs dynamically

drivers/mfd/wm8350-irq.c int wm8350_irq_init(struct wm8350 *wm8350, int irq, · line 503

Quoted 5 lines · Sascha Hauer
drivers/mfd/wm8350-irq.c +0 -1
@@ -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 :)

drivers/mfd/wm8350-irq.c int wm8350_irq_init(struct wm8350 *wm8350, int irq, · line 509

Quoted 7 lines
drivers/mfd/wm8350-irq.c +7 -0
+
+	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 ?

Quoted 11 lines
drivers/mfd/wm8350-irq.c +4 -0
+		}
+	} else {
+		wm8350->irq_base = pdata->irq_base;
+	}
 
 	if (pdata->irq_high) {
 		flags |= IRQF_TRIGGER_HIGH;
Signature · 1 line
1.7.4.1
author maintainer
#4 lore raw

PATCH 1/1 mfd wm8350: allocate irq descs dynamically

Quoted 8 lines · Thomas Gleixner

drivers/mfd/wm8350-irq.c int wm8350_irq_init(struct wm8350 *wm8350, int irq, · line 503

Quoted 5 lines · Sascha Hauer
drivers/mfd/wm8350-irq.c +0 -1
@@ -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.

Quoted 10 lines

drivers/mfd/wm8350-irq.c int wm8350_irq_init(struct wm8350 *wm8350, int irq, · line 509

Quoted 8 lines
drivers/mfd/wm8350-irq.c +7 -0
+
+	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

Signature · 4 lines
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 |
#5 lore raw

PATCH 1/1 mfd wm8350: allocate irq descs dynamically

Quoted 23 lines · Sascha Hauer
Quoted 8 lines · Thomas Gleixner

drivers/mfd/wm8350-irq.c int wm8350_irq_init(struct wm8350 *wm8350, int irq, · line 503

Quoted 5 lines · Sascha Hauer
drivers/mfd/wm8350-irq.c +0 -1
@@ -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.

Quoted 10 lines

drivers/mfd/wm8350-irq.c int wm8350_irq_init(struct wm8350 *wm8350, int irq, · line 509

Quoted 8 lines
drivers/mfd/wm8350-irq.c +7 -0
+
+	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 ?

Quoted 2 lines

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

Fair enough.

Quoted 3 lines

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

#6 lore raw

PATCH 1/1 mfd wm8350: allocate irq descs dynamically

Quoted 5 lines · Thomas Gleixner
Quoted 3 lines · Sascha Hauer
Quoted 2 lines · Thomas Gleixner

Review int wm8350_irq_init(struct wm8350 *wm8350, int irq,

Quoted 1 line · Sascha Hauer
(quoted diff) +0 -0
@@ -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.

author maintainer
#7 lore raw

PATCH 1/1 mfd wm8350: allocate irq descs dynamically

Mark,

Quoted 10 lines · Mark Brown
Quoted 5 lines · Thomas Gleixner
Quoted 3 lines · Sascha Hauer
Quoted 2 lines · Thomas Gleixner

Review int wm8350_irq_init(struct wm8350 *wm8350, int irq,

Quoted 1 line · Sascha Hauer
(quoted diff) +0 -0
@@ -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

Signature · 4 lines
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 |
#8 lore raw

PATCH 1/1 mfd wm8350: allocate irq descs dynamically

Quoted 2 lines · Sascha Hauer

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 <[email protected]>
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 <[email protected]>
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>

author maintainer
#9 lore raw

PATCH 1/1 mfd wm8350: allocate irq descs dynamically

Quoted 8 lines

Review

Quoted 5 lines
(quoted diff) +2 -2
-	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.

Quoted 12 lines

Review

Quoted 4 lines
(quoted diff) +3 -0
+	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

Signature · 4 lines
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 |
#10 lore raw

PATCH 1/1 mfd wm8350: allocate irq descs dynamically

Quoted 5 lines · Sascha Hauer
Quoted 2 lines

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.

Quoted 2 lines

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.

Quoted 10 lines
Quoted 7 lines

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.

Quoted 1 line

from the wm8350 driver?

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

author maintainer
#11 lore raw

PATCH 1/1 mfd wm8350: allocate irq descs dynamically

Quoted 8 lines · Mark Brown
Quoted 5 lines · Sascha Hauer
Quoted 2 lines

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?

Quoted 7 lines

Yes, exactly.

Quoted 2 lines

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?

Quoted 9 lines
Quoted 8 lines
Quoted 8 lines

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.

Quoted 8 lines
Quoted 2 lines

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.

Quoted 5 lines
Quoted 2 lines

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

Signature · 4 lines
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 |
#12 lore raw

PATCH 1/1 mfd wm8350: allocate irq descs dynamically

Quoted 7 lines · Sascha Hauer
Quoted 2 lines · Mark Brown

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.

Quoted 10 lines
Quoted 5 lines

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.

Quoted 7 lines
Quoted 2 lines

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.

author maintainer
#13 lore raw

PATCH 1/1 mfd wm8350: allocate irq descs dynamically

Quoted 10 lines · Mark Brown
Quoted 7 lines · Sascha Hauer
Quoted 2 lines · Mark Brown

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.

Quoted 7 lines
Quoted 6 lines
Quoted 6 lines

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.

Quoted 7 lines
Quoted 4 lines

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.

Quoted 2 lines

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.

Quoted 9 lines
Quoted 8 lines
Quoted 3 lines

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.

Quoted 4 lines

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

Signature · 4 lines
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 |
#14 lore raw

PATCH 1/1 mfd wm8350: allocate irq descs dynamically

Quoted 7 lines · Sascha Hauer
Quoted 2 lines · Mark Brown

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.

author maintainer
#15 lore raw

PATCH 1/1 mfd wm8350: allocate irq descs dynamically

Quoted 6 lines · Mark Brown
Quoted 4 lines · Sascha Hauer
Quoted 2 lines · Mark Brown

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

Quoted 6 lines
Quoted 2 lines

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

Signature · 4 lines
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 |
#16 lore raw

PATCH 1/1 mfd wm8350: allocate irq descs dynamically

Quoted 8 lines · Sascha Hauer
Quoted 3 lines · Mark Brown

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.

author maintainer
#17 lore raw

PATCH 1/1 mfd wm8350: allocate irq descs dynamically

Quoted 7 lines · Mark Brown
Quoted 5 lines · Sascha Hauer
Quoted 3 lines · Mark Brown

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.

Quoted 7 lines
Quoted 2 lines

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

Signature · 4 lines
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 |
#18 lore raw

PATCH 1/1 mfd wm8350: allocate irq descs dynamically

Quoted 10 lines · Sascha Hauer

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

Quoted 2 lines

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.

author maintainer
#19 lore raw

PATCH 1/1 mfd wm8350: allocate irq descs dynamically

Quoted 12 lines · Mark Brown
Quoted 9 lines · Sascha Hauer

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

Quoted 6 lines
Quoted 2 lines

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

Signature · 4 lines
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 |
author maintainer
#20 lore raw

PATCH 2/9 ARM i.MX avic: do not depend on MXC_INTERNAL_IRQS

In reply to Sascha Hauer

This becomes meaningless in subsequent patches.

---
 arch/arm/plat-mxc/avic.c |   12 +++++++-----
 1 files changed, 7 insertions(+), 5 deletions(-)
arch/arm/plat-mxc/avic.c +7 -5
index 09e2bd0..55d2534 100644
@@ -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);
Signature · 1 line
1.7.4.1
author maintainer
#21 lore raw

PATCH 3/9 ARM i.MX: get rid of wrong MXC_INTERNAL_IRQ usage

In reply to Sascha Hauer

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.

---
 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(-)
arch/arm/mach-imx/mach-mx27_3ds.c +1 -1
index 6e1accf..fcbac6e 100644
@@ -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 */
arch/arm/mach-imx/mach-mx35_3ds.c +1 -1
index 882880a..c10221d 100644
@@ -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,
arch/arm/mach-mx5/board-cpuimx51.c +4 -8
index 4efa02e..7fbfd06 100644
@@ -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,
arch/arm/mach-mx5/board-mx51_3ds.c +1 -1
index 63dfbea..288965d 100644
@@ -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[] = {
arch/arm/mach-mx5/eukrea_mbimx51-baseboard.c +1 -2
index 97292d2..66d24ea 100644
@@ -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),
arch/arm/plat-mxc/include/mach/iomux-v1.h +0 -3
index c07d302..a7fc51e 100644
@@ -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)
Signature · 1 line
1.7.4.1
author maintainer
#22 lore raw

PATCH 4/9 mfd wm8350: allocate irq descs dynamically

In reply to Sascha Hauer

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

---
 drivers/mfd/wm8350-irq.c |   16 +++++++++++++---
 1 files changed, 13 insertions(+), 3 deletions(-)
drivers/mfd/wm8350-irq.c +13 -3
index ed4b22a..04408a5 100644
@@ -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;
Signature · 1 line
1.7.4.1
author maintainer
#23 lore raw

PATCH 5/9 ARM i.MX mx31ads: allocate irqs for expio dynamically

In reply to Sascha Hauer
---
 arch/arm/mach-imx/mach-mx31ads.c |   45 +++++++++++++++++++------------------
 1 files changed, 23 insertions(+), 22 deletions(-)
arch/arm/mach-imx/mach-mx31ads.c +23 -22
index f4dee02..d183592 100644
@@ -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();
Signature · 1 line
1.7.4.1
author maintainer
#24 lore raw

PATCH 6/9 ARM i.MX 3ds debugboard: allocate irqs dynamically

In reply to Sascha Hauer
---
 arch/arm/plat-mxc/3ds_debugboard.c |   53 ++++++++++++++++++++---------------
 1 files changed, 30 insertions(+), 23 deletions(-)
arch/arm/plat-mxc/3ds_debugboard.c +30 -23
index f0ba072..e644cd9 100644
@@ -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;
 }
Signature · 1 line
1.7.4.1
author maintainer
#25 lore raw

PATCH 7/9 ARM i.MX: use sparse irqs

In reply to Sascha Hauer

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.

---
 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(-)
arch/arm/Kconfig +1 -0
index 377a7a5..cebed1e 100644
@@ -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
 
arch/arm/mach-imx/mm-imx31.c +7 -1
index 86b9b45..e055ef0 100644
@@ -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);
 }
arch/arm/mach-imx/mm-imx35.c +7 -0
index c880e6d..abe908b 100644
@@ -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);
 }
arch/arm/plat-mxc/avic.c +5 -1
index 55d2534..1a4f00c 100644
@@ -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);
arch/arm/plat-mxc/gpio.c +5 -1
index 6cd6d7f..8352264 100644
@@ -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);
arch/arm/plat-mxc/include/mach/irqs.h +9 -45

67 lines not on this page · raw message

Signature · 1 line
1.7.4.1
author maintainer
#26 lore raw

PATCH 8/9 dma IPU: rework irq handling

In reply to Sascha Hauer

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.

---
 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(-)
drivers/dma/Kconfig +0 -10
index a572600..4119188 100644
@@ -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
drivers/dma/ipu/ipu_idmac.c +13 -28

118 lines not on this page · raw message

drivers/dma/ipu/ipu_intern.h +3 -11
index 545cf11..4eb7d0b 100644
@@ -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);
 
drivers/dma/ipu/ipu_irq.c +38 -262

400 lines not on this page · raw message

Signature · 1 line
1.7.4.1
#27 lore raw

PATCH 8/9 dma IPU: rework irq handling

drivers/dma/ipu/ipu_irq.c static struct irq_chip ipu_irq_chip = { · line 144

Quoted 10 lines · Sascha Hauer
drivers/dma/ipu/ipu_irq.c +2 -3
@@ -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 ?

drivers/dma/ipu/ipu_irq.c static struct irq_chip ipu_irq_chip = { · line 146

Quoted 2 lines
drivers/dma/ipu/ipu_irq.c +2 -0
+	if (irq_base < 0)
+		return irq_base;

So this allocates 160 interrupts. How many of them are actually going to be used ?

Thanks,

tglx

author maintainer
#28 lore raw

PATCH 8/9 dma IPU: rework irq handling

Quoted 14 lines · Thomas Gleixner

drivers/dma/ipu/ipu_irq.c static struct irq_chip ipu_irq_chip = { · line 144

Quoted 10 lines · Sascha Hauer
drivers/dma/ipu/ipu_irq.c +2 -3
@@ -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 ?

Quoted 5 lines

drivers/dma/ipu/ipu_irq.c static struct irq_chip ipu_irq_chip = { · line 146

Quoted 2 lines
drivers/dma/ipu/ipu_irq.c +2 -0
+	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

Signature · 4 lines
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 |
#29 lore raw

PATCH 8/9 dma IPU: rework irq handling

Quoted 21 lines · Sascha Hauer
Quoted 14 lines · Thomas Gleixner

drivers/dma/ipu/ipu_irq.c static struct irq_chip ipu_irq_chip = { · line 144

Quoted 10 lines · Sascha Hauer
drivers/dma/ipu/ipu_irq.c +2 -3
@@ -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 ?

Quoted 5 lines

drivers/dma/ipu/ipu_irq.c static struct irq_chip ipu_irq_chip = { · line 146

Quoted 2 lines
drivers/dma/ipu/ipu_irq.c +2 -0
+	if (irq_base < 0)
+		return irq_base;

So this allocates 160 interrupts. How many of them are actually going to be used ?

Quoted 5 lines

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

#30 lore raw

PATCH 8/9 dma IPU: rework irq handling

Quoted 18 lines
Quoted 6 lines

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.

Quoted 3 lines

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.

author maintainer
#31 lore raw

PATCH 9/9 ARM i.MX3: remove now useless ipu platform data from boards

In reply to Sascha Hauer

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.

---
 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(-)
arch/arm/mach-imx/eukrea_mbimxsd35-baseboard.c +1 -5
index 4909ea0..260a8bc 100644
@@ -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);
arch/arm/mach-imx/mach-armadillo5x0.c +1 -5
index ffb40ff..00eebeb 100644
@@ -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 */
arch/arm/mach-imx/mach-mx31_3ds.c +1 -5
index 9b98244..3b1b374 100644
@@ -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 */
arch/arm/mach-imx/mach-mx31moboard.c +1 -5
index eaa51e4..18e97d7 100644
@@ -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))
arch/arm/mach-imx/mach-pcm037.c +1 -5
index 89c213b..2789fd1 100644
@@ -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 */
arch/arm/mach-imx/mach-pcm043.c +1 -5
index 0264416..1820a95b 100644
@@ -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) {
arch/arm/mach-imx/mach-vpr200.c +1 -5
index d74e347..190a19e 100644
@@ -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);
arch/arm/mach-imx/mm-imx31.c +0 -6
index e055ef0..af0a982 100644
@@ -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);
 }
arch/arm/mach-imx/mm-imx35.c +0 -6
index abe908b..d10bff5 100644
@@ -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);
 }
arch/arm/mach-imx/mx31lilly-db.c +1 -5
index 7d26f76..dc0fc9b 100644
@@ -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);
 }
arch/arm/plat-mxc/include/mach/ipu.h +0 -1
index a9221f1..0b38d13 100644
@@ -111,7 +111,6 @@ enum ipu_rotate_mode {
 };
 
 struct ipu_platform_data {
-	unsigned int	irq_base;
 };
 
 /*
arch/arm/plat-mxc/include/mach/irqs.h +0 -3
index 8253463..c281cf0 100644
@@ -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
 
Signature · 1 line
1.7.4.1