linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] gpio/mxc: use the edge_sel feature if available
@ 2012-06-18 19:57 Benoît Thébaudeau
  2012-06-19  1:24 ` Shawn Guo
  2012-06-20  9:19 ` Sascha Hauer
  0 siblings, 2 replies; 15+ messages in thread
From: Benoît Thébaudeau @ 2012-06-18 19:57 UTC (permalink / raw)
  To: linux-arm-kernel

Some mxc processors have an edge_sel feature, which allows the IRQ to be
triggered by any edge.

This patch makes use of this feature if available, which skips mxc_flip_edge().

Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Linus Walleij <linus.walleij@stericsson.com>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: <linux-arm-kernel@lists.infradead.org>
Signed-off-by: Beno?t Th?baudeau <benoit.thebaudeau@advansee.com>
---
 .../drivers/gpio/gpio-mxc.c                        |   44 ++++++++++++++------
 1 file changed, 32 insertions(+), 12 deletions(-)

diff --git linux-next-HEAD-6c86b58.orig/drivers/gpio/gpio-mxc.c linux-next-HEAD-6c86b58/drivers/gpio/gpio-mxc.c
index c337143..4c74482 100644
--- linux-next-HEAD-6c86b58.orig/drivers/gpio/gpio-mxc.c
+++ linux-next-HEAD-6c86b58/drivers/gpio/gpio-mxc.c
@@ -30,6 +30,7 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/module.h>
+#include <mach/hardware.h>
 #include <asm-generic/bug.h>
 #include <asm/mach/irq.h>
 
@@ -104,12 +105,13 @@ static struct mxc_gpio_hwdata *mxc_gpio_hwdata;
 #define GPIO_ICR2		(mxc_gpio_hwdata->icr2_reg)
 #define GPIO_IMR		(mxc_gpio_hwdata->imr_reg)
 #define GPIO_ISR		(mxc_gpio_hwdata->isr_reg)
+#define GPIO_EDGE_SEL		0x1c
 
 #define GPIO_INT_LOW_LEV	(mxc_gpio_hwdata->low_level)
 #define GPIO_INT_HIGH_LEV	(mxc_gpio_hwdata->high_level)
 #define GPIO_INT_RISE_EDGE	(mxc_gpio_hwdata->rise_edge)
 #define GPIO_INT_FALL_EDGE	(mxc_gpio_hwdata->fall_edge)
-#define GPIO_INT_NONE		0x4
+#define GPIO_INT_BOTH_EDGES	0x4
 
 static struct platform_device_id mxc_gpio_devtype[] = {
 	{
@@ -150,6 +152,7 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type)
 	u32 bit, val;
 	int edge;
 	void __iomem *reg = port->base;
+	bool edge_sel = cpu_is_mx25() || cpu_is_mx35() || cpu_is_mx51() || cpu_is_mx53();
 
 	port->both_edges &= ~(1 << (gpio & 31));
 	switch (type) {
@@ -160,15 +163,19 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type)
 		edge = GPIO_INT_FALL_EDGE;
 		break;
 	case IRQ_TYPE_EDGE_BOTH:
-		val = gpio_get_value(gpio);
-		if (val) {
-			edge = GPIO_INT_LOW_LEV;
-			pr_debug("mxc: set GPIO %d to low trigger\n", gpio);
+		if (edge_sel) {
+			edge = GPIO_INT_BOTH_EDGES;
 		} else {
-			edge = GPIO_INT_HIGH_LEV;
-			pr_debug("mxc: set GPIO %d to high trigger\n", gpio);
+			val = gpio_get_value(gpio);
+			if (val) {
+				edge = GPIO_INT_LOW_LEV;
+				pr_debug("mxc: set GPIO %d to low trigger\n", gpio);
+			} else {
+				edge = GPIO_INT_HIGH_LEV;
+				pr_debug("mxc: set GPIO %d to high trigger\n", gpio);
+			}
+			port->both_edges |= 1 << (gpio & 31);
 		}
-		port->both_edges |= 1 << (gpio & 31);
 		break;
 	case IRQ_TYPE_LEVEL_LOW:
 		edge = GPIO_INT_LOW_LEV;
@@ -180,10 +187,23 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type)
 		return -EINVAL;
 	}
 
-	reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
-	bit = gpio & 0xf;
-	val = readl(reg) & ~(0x3 << (bit << 1));
-	writel(val | (edge << (bit << 1)), reg);
+	if (edge_sel) {
+		val = readl(port->base + GPIO_EDGE_SEL);
+		if (edge == GPIO_INT_BOTH_EDGES)
+			writel(val | (1 << (gpio & 0x1f)),
+				port->base + GPIO_EDGE_SEL);
+		else
+			writel(val & ~(1 << (gpio & 0x1f)),
+				port->base + GPIO_EDGE_SEL);
+	}
+
+	if (edge != GPIO_INT_BOTH_EDGES) {
+		reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
+		bit = gpio & 0xf;
+		val = readl(reg) & ~(0x3 << (bit << 1));
+		writel(val | (edge << (bit << 1)), reg);
+	}
+
 	writel(1 << (gpio & 0x1f), port->base + GPIO_ISR);
 
 	return 0;

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

* [PATCH] gpio/mxc: use the edge_sel feature if available
  2012-06-18 19:57 [PATCH] gpio/mxc: use the edge_sel feature if available Benoît Thébaudeau
@ 2012-06-19  1:24 ` Shawn Guo
  2012-06-19 12:00   ` Benoît Thébaudeau
  2012-06-20  9:19 ` Sascha Hauer
  1 sibling, 1 reply; 15+ messages in thread
From: Shawn Guo @ 2012-06-19  1:24 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jun 18, 2012 at 09:57:12PM +0200, Beno?t Th?baudeau wrote:
> Some mxc processors have an edge_sel feature, which allows the IRQ to be
> triggered by any edge.
> 
> This patch makes use of this feature if available, which skips mxc_flip_edge().
> 
> Cc: Grant Likely <grant.likely@secretlab.ca>
> Cc: Linus Walleij <linus.walleij@stericsson.com>
> Cc: Sascha Hauer <kernel@pengutronix.de>
> Cc: <linux-arm-kernel@lists.infradead.org>
> Signed-off-by: Beno?t Th?baudeau <benoit.thebaudeau@advansee.com>

NAK.

We have just gone through the pain to clean up those cpu_is_xxx() from
the driver.  Please do not bring them back.

Regards,
Shawn

> ---
>  .../drivers/gpio/gpio-mxc.c                        |   44 ++++++++++++++------
>  1 file changed, 32 insertions(+), 12 deletions(-)
> 
> diff --git linux-next-HEAD-6c86b58.orig/drivers/gpio/gpio-mxc.c linux-next-HEAD-6c86b58/drivers/gpio/gpio-mxc.c
> index c337143..4c74482 100644
> --- linux-next-HEAD-6c86b58.orig/drivers/gpio/gpio-mxc.c
> +++ linux-next-HEAD-6c86b58/drivers/gpio/gpio-mxc.c
> @@ -30,6 +30,7 @@
>  #include <linux/of.h>
>  #include <linux/of_device.h>
>  #include <linux/module.h>
> +#include <mach/hardware.h>
>  #include <asm-generic/bug.h>
>  #include <asm/mach/irq.h>
>  
> @@ -104,12 +105,13 @@ static struct mxc_gpio_hwdata *mxc_gpio_hwdata;
>  #define GPIO_ICR2		(mxc_gpio_hwdata->icr2_reg)
>  #define GPIO_IMR		(mxc_gpio_hwdata->imr_reg)
>  #define GPIO_ISR		(mxc_gpio_hwdata->isr_reg)
> +#define GPIO_EDGE_SEL		0x1c
>  
>  #define GPIO_INT_LOW_LEV	(mxc_gpio_hwdata->low_level)
>  #define GPIO_INT_HIGH_LEV	(mxc_gpio_hwdata->high_level)
>  #define GPIO_INT_RISE_EDGE	(mxc_gpio_hwdata->rise_edge)
>  #define GPIO_INT_FALL_EDGE	(mxc_gpio_hwdata->fall_edge)
> -#define GPIO_INT_NONE		0x4
> +#define GPIO_INT_BOTH_EDGES	0x4
>  
>  static struct platform_device_id mxc_gpio_devtype[] = {
>  	{
> @@ -150,6 +152,7 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type)
>  	u32 bit, val;
>  	int edge;
>  	void __iomem *reg = port->base;
> +	bool edge_sel = cpu_is_mx25() || cpu_is_mx35() || cpu_is_mx51() || cpu_is_mx53();
>  
>  	port->both_edges &= ~(1 << (gpio & 31));
>  	switch (type) {
> @@ -160,15 +163,19 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type)
>  		edge = GPIO_INT_FALL_EDGE;
>  		break;
>  	case IRQ_TYPE_EDGE_BOTH:
> -		val = gpio_get_value(gpio);
> -		if (val) {
> -			edge = GPIO_INT_LOW_LEV;
> -			pr_debug("mxc: set GPIO %d to low trigger\n", gpio);
> +		if (edge_sel) {
> +			edge = GPIO_INT_BOTH_EDGES;
>  		} else {
> -			edge = GPIO_INT_HIGH_LEV;
> -			pr_debug("mxc: set GPIO %d to high trigger\n", gpio);
> +			val = gpio_get_value(gpio);
> +			if (val) {
> +				edge = GPIO_INT_LOW_LEV;
> +				pr_debug("mxc: set GPIO %d to low trigger\n", gpio);
> +			} else {
> +				edge = GPIO_INT_HIGH_LEV;
> +				pr_debug("mxc: set GPIO %d to high trigger\n", gpio);
> +			}
> +			port->both_edges |= 1 << (gpio & 31);
>  		}
> -		port->both_edges |= 1 << (gpio & 31);
>  		break;
>  	case IRQ_TYPE_LEVEL_LOW:
>  		edge = GPIO_INT_LOW_LEV;
> @@ -180,10 +187,23 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type)
>  		return -EINVAL;
>  	}
>  
> -	reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
> -	bit = gpio & 0xf;
> -	val = readl(reg) & ~(0x3 << (bit << 1));
> -	writel(val | (edge << (bit << 1)), reg);
> +	if (edge_sel) {
> +		val = readl(port->base + GPIO_EDGE_SEL);
> +		if (edge == GPIO_INT_BOTH_EDGES)
> +			writel(val | (1 << (gpio & 0x1f)),
> +				port->base + GPIO_EDGE_SEL);
> +		else
> +			writel(val & ~(1 << (gpio & 0x1f)),
> +				port->base + GPIO_EDGE_SEL);
> +	}
> +
> +	if (edge != GPIO_INT_BOTH_EDGES) {
> +		reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
> +		bit = gpio & 0xf;
> +		val = readl(reg) & ~(0x3 << (bit << 1));
> +		writel(val | (edge << (bit << 1)), reg);
> +	}
> +
>  	writel(1 << (gpio & 0x1f), port->base + GPIO_ISR);
>  
>  	return 0;
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel at lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel

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

* [PATCH] gpio/mxc: use the edge_sel feature if available
  2012-06-19  1:24 ` Shawn Guo
@ 2012-06-19 12:00   ` Benoît Thébaudeau
  2012-06-19 13:18     ` Benoît Thébaudeau
  2012-06-20  8:35     ` Linus Walleij
  0 siblings, 2 replies; 15+ messages in thread
From: Benoît Thébaudeau @ 2012-06-19 12:00 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jun 19, 2012 at 03:24:22AM +0200, Shawn Guo wrote:
> NAK.
> 
> We have just gone through the pain to clean up those cpu_is_xxx()
> from
> the driver.  Please do not bring them back.

OK. I don't find the changeset you are referring to. Can you give me an example
that tells me by what you replaced those cpu_is_xxx()? By some feature test
macros? E.g., there are still many of those cpu_is_xxx() in
drivers/mtd/nand/mxc_nand.c in linux-next.

Regards,
Beno?t

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

* [PATCH] gpio/mxc: use the edge_sel feature if available
  2012-06-19 12:00   ` Benoît Thébaudeau
@ 2012-06-19 13:18     ` Benoît Thébaudeau
  2012-06-20  8:35     ` Linus Walleij
  1 sibling, 0 replies; 15+ messages in thread
From: Benoît Thébaudeau @ 2012-06-19 13:18 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jun 19, 2012 at 02:00:38PM +0200, Beno?t Th?baudeau wrote:
> On Tue, Jun 19, 2012 at 03:24:22AM +0200, Shawn Guo wrote:
> > NAK.
> > 
> > We have just gone through the pain to clean up those cpu_is_xxx()
> > from
> > the driver.  Please do not bring them back.
> 
> OK. I don't find the changeset you are referring to. Can you give me
> an example
> that tells me by what you replaced those cpu_is_xxx()? By some
> feature test
> macros? E.g., there are still many of those cpu_is_xxx() in
> drivers/mtd/nand/mxc_nand.c in linux-next.

I think you were talking about commit e7fc6ae0. I'll see what I can do with
that.

Regards,
Beno?t

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

* [PATCH] gpio/mxc: use the edge_sel feature if available
  2012-06-19 12:00   ` Benoît Thébaudeau
  2012-06-19 13:18     ` Benoît Thébaudeau
@ 2012-06-20  8:35     ` Linus Walleij
  2012-06-20  9:21       ` Sascha Hauer
  1 sibling, 1 reply; 15+ messages in thread
From: Linus Walleij @ 2012-06-20  8:35 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Jun 19, 2012 at 2:00 PM, Beno?t Th?baudeau
<benoit.thebaudeau@advansee.com> wrote:

> Can you give me an example
> that tells me by what you replaced those cpu_is_xxx()? By some feature test
> macros?

Since this is a DT-enabled driver, add a boolean attribute for
the DT node like "has-edge-select" and add that attribute to
the SoC .dtsi files for the SoCs that has this feature.

Another (better) option is if there are magic numbers in the
silicon register range that you can check for revision of that
hardware in itself. Such auto-detect plug-n-play is always best.

> E.g., there are still many of those cpu_is_xxx() in
> drivers/mtd/nand/mxc_nand.c in linux-next.

Two wrongs does not make one right or how you put it ;-)

Yours,
Linus Walleij

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

* [PATCH] gpio/mxc: use the edge_sel feature if available
  2012-06-18 19:57 [PATCH] gpio/mxc: use the edge_sel feature if available Benoît Thébaudeau
  2012-06-19  1:24 ` Shawn Guo
@ 2012-06-20  9:19 ` Sascha Hauer
  2012-06-20 18:27   ` Benoît Thébaudeau
  1 sibling, 1 reply; 15+ messages in thread
From: Sascha Hauer @ 2012-06-20  9:19 UTC (permalink / raw)
  To: linux-arm-kernel

On Mon, Jun 18, 2012 at 09:57:12PM +0200, Beno?t Th?baudeau wrote:
> Some mxc processors have an edge_sel feature, which allows the IRQ to be
> triggered by any edge.
> 
> This patch makes use of this feature if available, which skips mxc_flip_edge().
> 
> Cc: Grant Likely <grant.likely@secretlab.ca>
> Cc: Linus Walleij <linus.walleij@stericsson.com>
> Cc: Sascha Hauer <kernel@pengutronix.de>
> Cc: <linux-arm-kernel@lists.infradead.org>
> Signed-off-by: Beno?t Th?baudeau <benoit.thebaudeau@advansee.com>
> ---
>  .../drivers/gpio/gpio-mxc.c                        |   44 ++++++++++++++------
>  1 file changed, 32 insertions(+), 12 deletions(-)
> 
> diff --git linux-next-HEAD-6c86b58.orig/drivers/gpio/gpio-mxc.c linux-next-HEAD-6c86b58/drivers/gpio/gpio-mxc.c
> index c337143..4c74482 100644
> --- linux-next-HEAD-6c86b58.orig/drivers/gpio/gpio-mxc.c
> +++ linux-next-HEAD-6c86b58/drivers/gpio/gpio-mxc.c
> @@ -30,6 +30,7 @@
>  #include <linux/of.h>
>  #include <linux/of_device.h>
>  #include <linux/module.h>
> +#include <mach/hardware.h>
>  #include <asm-generic/bug.h>
>  #include <asm/mach/irq.h>
>  
> @@ -104,12 +105,13 @@ static struct mxc_gpio_hwdata *mxc_gpio_hwdata;
>  #define GPIO_ICR2		(mxc_gpio_hwdata->icr2_reg)
>  #define GPIO_IMR		(mxc_gpio_hwdata->imr_reg)
>  #define GPIO_ISR		(mxc_gpio_hwdata->isr_reg)
> +#define GPIO_EDGE_SEL		0x1c
>  
>  #define GPIO_INT_LOW_LEV	(mxc_gpio_hwdata->low_level)
>  #define GPIO_INT_HIGH_LEV	(mxc_gpio_hwdata->high_level)
>  #define GPIO_INT_RISE_EDGE	(mxc_gpio_hwdata->rise_edge)
>  #define GPIO_INT_FALL_EDGE	(mxc_gpio_hwdata->fall_edge)
> -#define GPIO_INT_NONE		0x4
> +#define GPIO_INT_BOTH_EDGES	0x4
>  
>  static struct platform_device_id mxc_gpio_devtype[] = {
>  	{
> @@ -150,6 +152,7 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type)
>  	u32 bit, val;
>  	int edge;
>  	void __iomem *reg = port->base;
> +	bool edge_sel = cpu_is_mx25() || cpu_is_mx35() || cpu_is_mx51() || cpu_is_mx53();

To make Shawns suggestion a bit more clear:

What you should do here is to add flags describing differences between
SoCs in mxc_gpio_hwdata.

This means that you have to:

- add IMX35_GPIO to enum mxc_gpio_hwtype
- add imx35-gpio to mxc_gpio_devtype[]
- add "fsl,imx35-gpio" to the compatible list.
- fix all devicetree bindings and platform device bindings for
  i.MX25,35,51,53 and probably i.MX6

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] 15+ messages in thread

* [PATCH] gpio/mxc: use the edge_sel feature if available
  2012-06-20  8:35     ` Linus Walleij
@ 2012-06-20  9:21       ` Sascha Hauer
  0 siblings, 0 replies; 15+ messages in thread
From: Sascha Hauer @ 2012-06-20  9:21 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jun 20, 2012 at 10:35:21AM +0200, Linus Walleij wrote:
> On Tue, Jun 19, 2012 at 2:00 PM, Beno?t Th?baudeau
> <benoit.thebaudeau@advansee.com> wrote:
> 
> > Can you give me an example
> > that tells me by what you replaced those cpu_is_xxx()? By some feature test
> > macros?
> 
> Since this is a DT-enabled driver, add a boolean attribute for
> the DT node like "has-edge-select" and add that attribute to
> the SoC .dtsi files for the SoCs that has this feature.
> 
> Another (better) option is if there are magic numbers in the
> silicon register range that you can check for revision of that
> hardware in itself. Such auto-detect plug-n-play is always best.

If there would be such a register it would almost certainly be on different
register offsets on different SoCs...

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] 15+ messages in thread

* [PATCH] gpio/mxc: use the edge_sel feature if available
  2012-06-20  9:19 ` Sascha Hauer
@ 2012-06-20 18:27   ` Benoît Thébaudeau
  2012-06-20 18:36     ` Benoît Thébaudeau
                       ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: Benoît Thébaudeau @ 2012-06-20 18:27 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jun 20, 2012 at 11:19:59AM +0200, Sascha Hauer wrote:
> To make Shawns suggestion a bit more clear:
> 
> What you should do here is to add flags describing differences
> between
> SoCs in mxc_gpio_hwdata.
> 
> This means that you have to:
> 
> - add IMX35_GPIO to enum mxc_gpio_hwtype
> - add imx35-gpio to mxc_gpio_devtype[]
> - add "fsl,imx35-gpio" to the compatible list.
> - fix all devicetree bindings and platform device bindings for
>   i.MX25,35,51,53 and probably i.MX6

Thanks for your suggestion. I have implemented it in the reworked patch below.

I have checked the reference manuals for i.MX25/35/5x and tested it on
i.MX25/35. The reference manual of the i.MX6Q is not public (yet?), so I need
someone who has it to check that this change is valid for the i.MX6Q too. I
assumed in this patch that the i.MX6Q has this EDGE_SEL register at offset 0x1c.

I have a question regarding the fallback mechanism in the i.MX31 case: it has
been created in commit 910862e using levels instead of edges, and this has not
been changed since. Why? Is it a bug or on purpose?

Regards,
Beno?t


[PATCH] gpio/mxc: use the edge_sel feature if available

Some mxc processors have an edge_sel feature, which allows the IRQ to be
triggered by any edge.

This patch makes use of this feature if available, which skips mxc_flip_edge().

Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Linus Walleij <linus.walleij@stericsson.com>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: <linux-arm-kernel@lists.infradead.org>
Signed-off-by: Beno?t Th?baudeau <benoit.thebaudeau@advansee.com>
---
 .../devicetree/bindings/gpio/fsl-imx-gpio.txt      |    2 +-
 .../arch/arm/boot/dts/imx51.dtsi                   |    8 +--
 .../arch/arm/boot/dts/imx53.dtsi                   |   14 ++---
 .../arch/arm/boot/dts/imx6q.dtsi                   |   14 ++---
 .../arch/arm/mach-imx/mm-imx25.c                   |   10 +--
 .../arch/arm/mach-imx/mm-imx3.c                    |    7 +--
 .../arch/arm/mach-imx/mm-imx5.c                    |   40 ++++++------
 .../drivers/gpio/gpio-mxc.c                        |   66 +++++++++++++++-----
 8 files changed, 96 insertions(+), 65 deletions(-)

diff --git linux-next-HEAD-a99225f.orig/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt linux-next-HEAD-a99225f/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt
index 4363ae4..33a0345 100644
--- linux-next-HEAD-a99225f.orig/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt
+++ linux-next-HEAD-a99225f/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt
@@ -14,7 +14,7 @@ Required properties:
 Example:
 
 gpio0: gpio at 73f84000 {
-	compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
+	compatible = "fsl,imx51-gpio", "fsl,imx35-gpio";
 	reg = <0x73f84000 0x4000>;
 	interrupts = <50 51>;
 	gpio-controller;
diff --git linux-next-HEAD-a99225f.orig/arch/arm/boot/dts/imx51.dtsi linux-next-HEAD-a99225f/arch/arm/boot/dts/imx51.dtsi
index 39eb88e..5236e42 100644
--- linux-next-HEAD-a99225f.orig/arch/arm/boot/dts/imx51.dtsi
+++ linux-next-HEAD-a99225f/arch/arm/boot/dts/imx51.dtsi
@@ -127,7 +127,7 @@
 			};
 
 			gpio1: gpio at 73f84000 {
-				compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx51-gpio", "fsl,imx35-gpio";
 				reg = <0x73f84000 0x4000>;
 				interrupts = <50 51>;
 				gpio-controller;
@@ -137,7 +137,7 @@
 			};
 
 			gpio2: gpio at 73f88000 {
-				compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx51-gpio", "fsl,imx35-gpio";
 				reg = <0x73f88000 0x4000>;
 				interrupts = <52 53>;
 				gpio-controller;
@@ -147,7 +147,7 @@
 			};
 
 			gpio3: gpio at 73f8c000 {
-				compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx51-gpio", "fsl,imx35-gpio";
 				reg = <0x73f8c000 0x4000>;
 				interrupts = <54 55>;
 				gpio-controller;
@@ -157,7 +157,7 @@
 			};
 
 			gpio4: gpio at 73f90000 {
-				compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx51-gpio", "fsl,imx35-gpio";
 				reg = <0x73f90000 0x4000>;
 				interrupts = <56 57>;
 				gpio-controller;
diff --git linux-next-HEAD-a99225f.orig/arch/arm/boot/dts/imx53.dtsi linux-next-HEAD-a99225f/arch/arm/boot/dts/imx53.dtsi
index 2b5caf9..39ea1a5 100644
--- linux-next-HEAD-a99225f.orig/arch/arm/boot/dts/imx53.dtsi
+++ linux-next-HEAD-a99225f/arch/arm/boot/dts/imx53.dtsi
@@ -129,7 +129,7 @@
 			};
 
 			gpio1: gpio at 53f84000 {
-				compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
 				reg = <0x53f84000 0x4000>;
 				interrupts = <50 51>;
 				gpio-controller;
@@ -139,7 +139,7 @@
 			};
 
 			gpio2: gpio at 53f88000 {
-				compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
 				reg = <0x53f88000 0x4000>;
 				interrupts = <52 53>;
 				gpio-controller;
@@ -149,7 +149,7 @@
 			};
 
 			gpio3: gpio at 53f8c000 {
-				compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
 				reg = <0x53f8c000 0x4000>;
 				interrupts = <54 55>;
 				gpio-controller;
@@ -159,7 +159,7 @@
 			};
 
 			gpio4: gpio at 53f90000 {
-				compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
 				reg = <0x53f90000 0x4000>;
 				interrupts = <56 57>;
 				gpio-controller;
@@ -197,7 +197,7 @@
 			};
 
 			gpio5: gpio at 53fdc000 {
-				compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
 				reg = <0x53fdc000 0x4000>;
 				interrupts = <103 104>;
 				gpio-controller;
@@ -207,7 +207,7 @@
 			};
 
 			gpio6: gpio at 53fe0000 {
-				compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
 				reg = <0x53fe0000 0x4000>;
 				interrupts = <105 106>;
 				gpio-controller;
@@ -217,7 +217,7 @@
 			};
 
 			gpio7: gpio at 53fe4000 {
-				compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
 				reg = <0x53fe4000 0x4000>;
 				interrupts = <107 108>;
 				gpio-controller;
diff --git linux-next-HEAD-a99225f.orig/arch/arm/boot/dts/imx6q.dtsi linux-next-HEAD-a99225f/arch/arm/boot/dts/imx6q.dtsi
index 8c90cba..da78fd8 100644
--- linux-next-HEAD-a99225f.orig/arch/arm/boot/dts/imx6q.dtsi
+++ linux-next-HEAD-a99225f/arch/arm/boot/dts/imx6q.dtsi
@@ -260,7 +260,7 @@
 			};
 
 			gpio1: gpio at 0209c000 {
-				compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
 				reg = <0x0209c000 0x4000>;
 				interrupts = <0 66 0x04 0 67 0x04>;
 				gpio-controller;
@@ -270,7 +270,7 @@
 			};
 
 			gpio2: gpio at 020a0000 {
-				compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
 				reg = <0x020a0000 0x4000>;
 				interrupts = <0 68 0x04 0 69 0x04>;
 				gpio-controller;
@@ -280,7 +280,7 @@
 			};
 
 			gpio3: gpio at 020a4000 {
-				compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
 				reg = <0x020a4000 0x4000>;
 				interrupts = <0 70 0x04 0 71 0x04>;
 				gpio-controller;
@@ -290,7 +290,7 @@
 			};
 
 			gpio4: gpio at 020a8000 {
-				compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
 				reg = <0x020a8000 0x4000>;
 				interrupts = <0 72 0x04 0 73 0x04>;
 				gpio-controller;
@@ -300,7 +300,7 @@
 			};
 
 			gpio5: gpio at 020ac000 {
-				compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
 				reg = <0x020ac000 0x4000>;
 				interrupts = <0 74 0x04 0 75 0x04>;
 				gpio-controller;
@@ -310,7 +310,7 @@
 			};
 
 			gpio6: gpio at 020b0000 {
-				compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
 				reg = <0x020b0000 0x4000>;
 				interrupts = <0 76 0x04 0 77 0x04>;
 				gpio-controller;
@@ -320,7 +320,7 @@
 			};
 
 			gpio7: gpio at 020b4000 {
-				compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
 				reg = <0x020b4000 0x4000>;
 				interrupts = <0 78 0x04 0 79 0x04>;
 				gpio-controller;
diff --git linux-next-HEAD-a99225f.orig/arch/arm/mach-imx/mm-imx25.c linux-next-HEAD-a99225f/arch/arm/mach-imx/mm-imx25.c
index 6ff3714..8e8ddb8 100644
--- linux-next-HEAD-a99225f.orig/arch/arm/mach-imx/mm-imx25.c
+++ linux-next-HEAD-a99225f/arch/arm/mach-imx/mm-imx25.c
@@ -90,11 +90,11 @@ static const struct resource imx25_audmux_res[] __initconst = {
 
 void __init imx25_soc_init(void)
 {
-	/* i.mx25 has the i.mx31 type gpio */
-	mxc_register_gpio("imx31-gpio", 0, MX25_GPIO1_BASE_ADDR, SZ_16K, MX25_INT_GPIO1, 0);
-	mxc_register_gpio("imx31-gpio", 1, MX25_GPIO2_BASE_ADDR, SZ_16K, MX25_INT_GPIO2, 0);
-	mxc_register_gpio("imx31-gpio", 2, MX25_GPIO3_BASE_ADDR, SZ_16K, MX25_INT_GPIO3, 0);
-	mxc_register_gpio("imx31-gpio", 3, MX25_GPIO4_BASE_ADDR, SZ_16K, MX25_INT_GPIO4, 0);
+	/* i.mx25 has the i.mx35 type gpio */
+	mxc_register_gpio("imx35-gpio", 0, MX25_GPIO1_BASE_ADDR, SZ_16K, MX25_INT_GPIO1, 0);
+	mxc_register_gpio("imx35-gpio", 1, MX25_GPIO2_BASE_ADDR, SZ_16K, MX25_INT_GPIO2, 0);
+	mxc_register_gpio("imx35-gpio", 2, MX25_GPIO3_BASE_ADDR, SZ_16K, MX25_INT_GPIO3, 0);
+	mxc_register_gpio("imx35-gpio", 3, MX25_GPIO4_BASE_ADDR, SZ_16K, MX25_INT_GPIO4, 0);
 
 	pinctrl_provide_dummies();
 	/* i.mx25 has the i.mx35 type sdma */
diff --git linux-next-HEAD-a99225f.orig/arch/arm/mach-imx/mm-imx3.c linux-next-HEAD-a99225f/arch/arm/mach-imx/mm-imx3.c
index a8983b9..8e51e77 100644
--- linux-next-HEAD-a99225f.orig/arch/arm/mach-imx/mm-imx3.c
+++ linux-next-HEAD-a99225f/arch/arm/mach-imx/mm-imx3.c
@@ -273,10 +273,9 @@ void __init imx35_soc_init(void)
 
 	imx3_init_l2x0();
 
-	/* i.mx35 has the i.mx31 type gpio */
-	mxc_register_gpio("imx31-gpio", 0, MX35_GPIO1_BASE_ADDR, SZ_16K, MX35_INT_GPIO1, 0);
-	mxc_register_gpio("imx31-gpio", 1, MX35_GPIO2_BASE_ADDR, SZ_16K, MX35_INT_GPIO2, 0);
-	mxc_register_gpio("imx31-gpio", 2, MX35_GPIO3_BASE_ADDR, SZ_16K, MX35_INT_GPIO3, 0);
+	mxc_register_gpio("imx35-gpio", 0, MX35_GPIO1_BASE_ADDR, SZ_16K, MX35_INT_GPIO1, 0);
+	mxc_register_gpio("imx35-gpio", 1, MX35_GPIO2_BASE_ADDR, SZ_16K, MX35_INT_GPIO2, 0);
+	mxc_register_gpio("imx35-gpio", 2, MX35_GPIO3_BASE_ADDR, SZ_16K, MX35_INT_GPIO3, 0);
 
 	pinctrl_provide_dummies();
 	if (to_version == 1) {
diff --git linux-next-HEAD-a99225f.orig/arch/arm/mach-imx/mm-imx5.c linux-next-HEAD-a99225f/arch/arm/mach-imx/mm-imx5.c
index 1d00305..d70d16c 100644
--- linux-next-HEAD-a99225f.orig/arch/arm/mach-imx/mm-imx5.c
+++ linux-next-HEAD-a99225f/arch/arm/mach-imx/mm-imx5.c
@@ -181,13 +181,13 @@ static const struct resource imx53_audmux_res[] __initconst = {
 
 void __init imx50_soc_init(void)
 {
-	/* i.mx50 has the i.mx31 type gpio */
-	mxc_register_gpio("imx31-gpio", 0, MX50_GPIO1_BASE_ADDR, SZ_16K, MX50_INT_GPIO1_LOW, MX50_INT_GPIO1_HIGH);
-	mxc_register_gpio("imx31-gpio", 1, MX50_GPIO2_BASE_ADDR, SZ_16K, MX50_INT_GPIO2_LOW, MX50_INT_GPIO2_HIGH);
-	mxc_register_gpio("imx31-gpio", 2, MX50_GPIO3_BASE_ADDR, SZ_16K, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH);
-	mxc_register_gpio("imx31-gpio", 3, MX50_GPIO4_BASE_ADDR, SZ_16K, MX50_INT_GPIO4_LOW, MX50_INT_GPIO4_HIGH);
-	mxc_register_gpio("imx31-gpio", 4, MX50_GPIO5_BASE_ADDR, SZ_16K, MX50_INT_GPIO5_LOW, MX50_INT_GPIO5_HIGH);
-	mxc_register_gpio("imx31-gpio", 5, MX50_GPIO6_BASE_ADDR, SZ_16K, MX50_INT_GPIO6_LOW, MX50_INT_GPIO6_HIGH);
+	/* i.mx50 has the i.mx35 type gpio */
+	mxc_register_gpio("imx35-gpio", 0, MX50_GPIO1_BASE_ADDR, SZ_16K, MX50_INT_GPIO1_LOW, MX50_INT_GPIO1_HIGH);
+	mxc_register_gpio("imx35-gpio", 1, MX50_GPIO2_BASE_ADDR, SZ_16K, MX50_INT_GPIO2_LOW, MX50_INT_GPIO2_HIGH);
+	mxc_register_gpio("imx35-gpio", 2, MX50_GPIO3_BASE_ADDR, SZ_16K, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH);
+	mxc_register_gpio("imx35-gpio", 3, MX50_GPIO4_BASE_ADDR, SZ_16K, MX50_INT_GPIO4_LOW, MX50_INT_GPIO4_HIGH);
+	mxc_register_gpio("imx35-gpio", 4, MX50_GPIO5_BASE_ADDR, SZ_16K, MX50_INT_GPIO5_LOW, MX50_INT_GPIO5_HIGH);
+	mxc_register_gpio("imx35-gpio", 5, MX50_GPIO6_BASE_ADDR, SZ_16K, MX50_INT_GPIO6_LOW, MX50_INT_GPIO6_HIGH);
 
 	/* i.mx50 has the i.mx31 type audmux */
 	platform_device_register_simple("imx31-audmux", 0, imx50_audmux_res,
@@ -196,11 +196,11 @@ void __init imx50_soc_init(void)
 
 void __init imx51_soc_init(void)
 {
-	/* i.mx51 has the i.mx31 type gpio */
-	mxc_register_gpio("imx31-gpio", 0, MX51_GPIO1_BASE_ADDR, SZ_16K, MX51_INT_GPIO1_LOW, MX51_INT_GPIO1_HIGH);
-	mxc_register_gpio("imx31-gpio", 1, MX51_GPIO2_BASE_ADDR, SZ_16K, MX51_INT_GPIO2_LOW, MX51_INT_GPIO2_HIGH);
-	mxc_register_gpio("imx31-gpio", 2, MX51_GPIO3_BASE_ADDR, SZ_16K, MX51_INT_GPIO3_LOW, MX51_INT_GPIO3_HIGH);
-	mxc_register_gpio("imx31-gpio", 3, MX51_GPIO4_BASE_ADDR, SZ_16K, MX51_INT_GPIO4_LOW, MX51_INT_GPIO4_HIGH);
+	/* i.mx51 has the i.mx35 type gpio */
+	mxc_register_gpio("imx35-gpio", 0, MX51_GPIO1_BASE_ADDR, SZ_16K, MX51_INT_GPIO1_LOW, MX51_INT_GPIO1_HIGH);
+	mxc_register_gpio("imx35-gpio", 1, MX51_GPIO2_BASE_ADDR, SZ_16K, MX51_INT_GPIO2_LOW, MX51_INT_GPIO2_HIGH);
+	mxc_register_gpio("imx35-gpio", 2, MX51_GPIO3_BASE_ADDR, SZ_16K, MX51_INT_GPIO3_LOW, MX51_INT_GPIO3_HIGH);
+	mxc_register_gpio("imx35-gpio", 3, MX51_GPIO4_BASE_ADDR, SZ_16K, MX51_INT_GPIO4_LOW, MX51_INT_GPIO4_HIGH);
 
 	pinctrl_provide_dummies();
 
@@ -218,14 +218,14 @@ void __init imx51_soc_init(void)
 
 void __init imx53_soc_init(void)
 {
-	/* i.mx53 has the i.mx31 type gpio */
-	mxc_register_gpio("imx31-gpio", 0, MX53_GPIO1_BASE_ADDR, SZ_16K, MX53_INT_GPIO1_LOW, MX53_INT_GPIO1_HIGH);
-	mxc_register_gpio("imx31-gpio", 1, MX53_GPIO2_BASE_ADDR, SZ_16K, MX53_INT_GPIO2_LOW, MX53_INT_GPIO2_HIGH);
-	mxc_register_gpio("imx31-gpio", 2, MX53_GPIO3_BASE_ADDR, SZ_16K, MX53_INT_GPIO3_LOW, MX53_INT_GPIO3_HIGH);
-	mxc_register_gpio("imx31-gpio", 3, MX53_GPIO4_BASE_ADDR, SZ_16K, MX53_INT_GPIO4_LOW, MX53_INT_GPIO4_HIGH);
-	mxc_register_gpio("imx31-gpio", 4, MX53_GPIO5_BASE_ADDR, SZ_16K, MX53_INT_GPIO5_LOW, MX53_INT_GPIO5_HIGH);
-	mxc_register_gpio("imx31-gpio", 5, MX53_GPIO6_BASE_ADDR, SZ_16K, MX53_INT_GPIO6_LOW, MX53_INT_GPIO6_HIGH);
-	mxc_register_gpio("imx31-gpio", 6, MX53_GPIO7_BASE_ADDR, SZ_16K, MX53_INT_GPIO7_LOW, MX53_INT_GPIO7_HIGH);
+	/* i.mx53 has the i.mx35 type gpio */
+	mxc_register_gpio("imx35-gpio", 0, MX53_GPIO1_BASE_ADDR, SZ_16K, MX53_INT_GPIO1_LOW, MX53_INT_GPIO1_HIGH);
+	mxc_register_gpio("imx35-gpio", 1, MX53_GPIO2_BASE_ADDR, SZ_16K, MX53_INT_GPIO2_LOW, MX53_INT_GPIO2_HIGH);
+	mxc_register_gpio("imx35-gpio", 2, MX53_GPIO3_BASE_ADDR, SZ_16K, MX53_INT_GPIO3_LOW, MX53_INT_GPIO3_HIGH);
+	mxc_register_gpio("imx35-gpio", 3, MX53_GPIO4_BASE_ADDR, SZ_16K, MX53_INT_GPIO4_LOW, MX53_INT_GPIO4_HIGH);
+	mxc_register_gpio("imx35-gpio", 4, MX53_GPIO5_BASE_ADDR, SZ_16K, MX53_INT_GPIO5_LOW, MX53_INT_GPIO5_HIGH);
+	mxc_register_gpio("imx35-gpio", 5, MX53_GPIO6_BASE_ADDR, SZ_16K, MX53_INT_GPIO6_LOW, MX53_INT_GPIO6_HIGH);
+	mxc_register_gpio("imx35-gpio", 6, MX53_GPIO7_BASE_ADDR, SZ_16K, MX53_INT_GPIO7_LOW, MX53_INT_GPIO7_HIGH);
 
 	pinctrl_provide_dummies();
 	/* i.mx53 has the i.mx35 type sdma */
diff --git linux-next-HEAD-a99225f.orig/drivers/gpio/gpio-mxc.c linux-next-HEAD-a99225f/drivers/gpio/gpio-mxc.c
index c337143..bd6f5ec 100644
--- linux-next-HEAD-a99225f.orig/drivers/gpio/gpio-mxc.c
+++ linux-next-HEAD-a99225f/drivers/gpio/gpio-mxc.c
@@ -30,6 +30,7 @@
 #include <linux/of.h>
 #include <linux/of_device.h>
 #include <linux/module.h>
+#include <mach/hardware.h>
 #include <asm-generic/bug.h>
 #include <asm/mach/irq.h>
 
@@ -38,7 +39,8 @@
 enum mxc_gpio_hwtype {
 	IMX1_GPIO,	/* runs on i.mx1 */
 	IMX21_GPIO,	/* runs on i.mx21 and i.mx27 */
-	IMX31_GPIO,	/* runs on all other i.mx */
+	IMX31_GPIO,	/* runs on i.mx31 */
+	IMX35_GPIO,	/* runs on all other i.mx */
 };
 
 /* device type dependent stuff */
@@ -50,6 +52,7 @@ struct mxc_gpio_hwdata {
 	unsigned icr2_reg;
 	unsigned imr_reg;
 	unsigned isr_reg;
+	int edge_sel_reg;
 	unsigned low_level;
 	unsigned high_level;
 	unsigned rise_edge;
@@ -74,13 +77,14 @@ static struct mxc_gpio_hwdata imx1_imx21_gpio_hwdata = {
 	.icr2_reg	= 0x2c,
 	.imr_reg	= 0x30,
 	.isr_reg	= 0x34,
+	.edge_sel_reg	= -1,
 	.low_level	= 0x03,
 	.high_level	= 0x02,
 	.rise_edge	= 0x00,
 	.fall_edge	= 0x01,
 };
 
-static struct mxc_gpio_hwdata imx31_gpio_hwdata = {
+static struct mxc_gpio_hwdata imx31_imx35_gpio_hwdata = {
 	.dr_reg		= 0x00,
 	.gdir_reg	= 0x04,
 	.psr_reg	= 0x08,
@@ -88,6 +92,7 @@ static struct mxc_gpio_hwdata imx31_gpio_hwdata = {
 	.icr2_reg	= 0x10,
 	.imr_reg	= 0x14,
 	.isr_reg	= 0x18,
+	.edge_sel_reg	= 0x1c,
 	.low_level	= 0x00,
 	.high_level	= 0x01,
 	.rise_edge	= 0x02,
@@ -104,12 +109,13 @@ static struct mxc_gpio_hwdata *mxc_gpio_hwdata;
 #define GPIO_ICR2		(mxc_gpio_hwdata->icr2_reg)
 #define GPIO_IMR		(mxc_gpio_hwdata->imr_reg)
 #define GPIO_ISR		(mxc_gpio_hwdata->isr_reg)
+#define GPIO_EDGE_SEL		(mxc_gpio_hwdata->edge_sel_reg)
 
 #define GPIO_INT_LOW_LEV	(mxc_gpio_hwdata->low_level)
 #define GPIO_INT_HIGH_LEV	(mxc_gpio_hwdata->high_level)
 #define GPIO_INT_RISE_EDGE	(mxc_gpio_hwdata->rise_edge)
 #define GPIO_INT_FALL_EDGE	(mxc_gpio_hwdata->fall_edge)
-#define GPIO_INT_NONE		0x4
+#define GPIO_INT_BOTH_EDGES	0x4
 
 static struct platform_device_id mxc_gpio_devtype[] = {
 	{
@@ -122,6 +128,9 @@ static struct platform_device_id mxc_gpio_devtype[] = {
 		.name = "imx31-gpio",
 		.driver_data = IMX31_GPIO,
 	}, {
+		.name = "imx35-gpio",
+		.driver_data = IMX35_GPIO,
+	}, {
 		/* sentinel */
 	}
 };
@@ -130,6 +139,7 @@ static const struct of_device_id mxc_gpio_dt_ids[] = {
 	{ .compatible = "fsl,imx1-gpio", .data = &mxc_gpio_devtype[IMX1_GPIO], },
 	{ .compatible = "fsl,imx21-gpio", .data = &mxc_gpio_devtype[IMX21_GPIO], },
 	{ .compatible = "fsl,imx31-gpio", .data = &mxc_gpio_devtype[IMX31_GPIO], },
+	{ .compatible = "fsl,imx35-gpio", .data = &mxc_gpio_devtype[IMX35_GPIO], },
 	{ /* sentinel */ }
 };
 
@@ -160,15 +170,19 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type)
 		edge = GPIO_INT_FALL_EDGE;
 		break;
 	case IRQ_TYPE_EDGE_BOTH:
-		val = gpio_get_value(gpio);
-		if (val) {
-			edge = GPIO_INT_LOW_LEV;
-			pr_debug("mxc: set GPIO %d to low trigger\n", gpio);
+		if (GPIO_EDGE_SEL >= 0) {
+			edge = GPIO_INT_BOTH_EDGES;
 		} else {
-			edge = GPIO_INT_HIGH_LEV;
-			pr_debug("mxc: set GPIO %d to high trigger\n", gpio);
+			val = gpio_get_value(gpio);
+			if (val) {
+				edge = GPIO_INT_LOW_LEV;
+				pr_debug("mxc: set GPIO %d to low trigger\n", gpio);
+			} else {
+				edge = GPIO_INT_HIGH_LEV;
+				pr_debug("mxc: set GPIO %d to high trigger\n", gpio);
+			}
+			port->both_edges |= 1 << (gpio & 31);
 		}
-		port->both_edges |= 1 << (gpio & 31);
 		break;
 	case IRQ_TYPE_LEVEL_LOW:
 		edge = GPIO_INT_LOW_LEV;
@@ -180,10 +194,23 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type)
 		return -EINVAL;
 	}
 
-	reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
-	bit = gpio & 0xf;
-	val = readl(reg) & ~(0x3 << (bit << 1));
-	writel(val | (edge << (bit << 1)), reg);
+	if (GPIO_EDGE_SEL >= 0) {
+		val = readl(port->base + GPIO_EDGE_SEL);
+		if (edge == GPIO_INT_BOTH_EDGES)
+			writel(val | (1 << (gpio & 0x1f)),
+				port->base + GPIO_EDGE_SEL);
+		else
+			writel(val & ~(1 << (gpio & 0x1f)),
+				port->base + GPIO_EDGE_SEL);
+	}
+
+	if (edge != GPIO_INT_BOTH_EDGES) {
+		reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
+		bit = gpio & 0xf;
+		val = readl(reg) & ~(0x3 << (bit << 1));
+		writel(val | (edge << (bit << 1)), reg);
+	}
+
 	writel(1 << (gpio & 0x1f), port->base + GPIO_ISR);
 
 	return 0;
@@ -338,10 +365,15 @@ static void __devinit mxc_gpio_get_hw(struct platform_device *pdev)
 		return;
 	}
 
-	if (hwtype == IMX31_GPIO)
-		mxc_gpio_hwdata = &imx31_gpio_hwdata;
-	else
+	switch (hwtype) {
+	case IMX31_GPIO:
+		imx31_imx35_gpio_hwdata.edge_sel_reg = -1;
+	case IMX35_GPIO:
+		mxc_gpio_hwdata = &imx31_imx35_gpio_hwdata;
+		break;
+	default:
 		mxc_gpio_hwdata = &imx1_imx21_gpio_hwdata;
+	}
 
 	mxc_gpio_hwtype = hwtype;
 }

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

* [PATCH] gpio/mxc: use the edge_sel feature if available
  2012-06-20 18:27   ` Benoît Thébaudeau
@ 2012-06-20 18:36     ` Benoît Thébaudeau
  2012-06-21  6:43     ` Sascha Hauer
  2012-06-22 13:46     ` Guennadi Liakhovetski
  2 siblings, 0 replies; 15+ messages in thread
From: Benoît Thébaudeau @ 2012-06-20 18:36 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jun 20, 2012 at 08:27:22PM +0200, Beno?t Th?baudeau wrote:
> --- linux-next-HEAD-a99225f.orig/drivers/gpio/gpio-mxc.c
> +++ linux-next-HEAD-a99225f/drivers/gpio/gpio-mxc.c
> @@ -30,6 +30,7 @@
>  #include <linux/of.h>
>  #include <linux/of_device.h>
>  #include <linux/module.h>
> +#include <mach/hardware.h>
>  #include <asm-generic/bug.h>
>  #include <asm/mach/irq.h>
>  

This hunk can be dropped.

Beno?t

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

* [PATCH] gpio/mxc: use the edge_sel feature if available
  2012-06-20 18:27   ` Benoît Thébaudeau
  2012-06-20 18:36     ` Benoît Thébaudeau
@ 2012-06-21  6:43     ` Sascha Hauer
  2012-06-21 11:23       ` Benoît Thébaudeau
  2012-06-22 13:46     ` Guennadi Liakhovetski
  2 siblings, 1 reply; 15+ messages in thread
From: Sascha Hauer @ 2012-06-21  6:43 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jun 20, 2012 at 08:27:22PM +0200, Beno?t Th?baudeau wrote:
> On Wed, Jun 20, 2012 at 11:19:59AM +0200, Sascha Hauer wrote:
> > To make Shawns suggestion a bit more clear:
> > 
> > What you should do here is to add flags describing differences
> > between
> > SoCs in mxc_gpio_hwdata.
> > 
> > This means that you have to:
> > 
> > - add IMX35_GPIO to enum mxc_gpio_hwtype
> > - add imx35-gpio to mxc_gpio_devtype[]
> > - add "fsl,imx35-gpio" to the compatible list.
> > - fix all devicetree bindings and platform device bindings for
> >   i.MX25,35,51,53 and probably i.MX6
> 
> Thanks for your suggestion. I have implemented it in the reworked patch below.
> 
> I have checked the reference manuals for i.MX25/35/5x and tested it on
> i.MX25/35. The reference manual of the i.MX6Q is not public (yet?), so I need
> someone who has it to check that this change is valid for the i.MX6Q too. I
> assumed in this patch that the i.MX6Q has this EDGE_SEL register at offset 0x1c.

Just checked, that's correct.

> 
> I have a question regarding the fallback mechanism in the i.MX31 case: it has
> been created in commit 910862e using levels instead of edges, and this has not
> been changed since. Why? Is it a bug or on purpose?

I assume that implementing this using level irqs is less racy. If you
implement it using edge irqs the edge could come during the time you
reconfigure the edge in the controller in which case the interrupt would
get lost.


> @@ -338,10 +365,15 @@ static void __devinit mxc_gpio_get_hw(struct platform_device *pdev)
>  		return;
>  	}
>  
> -	if (hwtype == IMX31_GPIO)
> -		mxc_gpio_hwdata = &imx31_gpio_hwdata;
> -	else
> +	switch (hwtype) {
> +	case IMX31_GPIO:
> +		imx31_imx35_gpio_hwdata.edge_sel_reg = -1;

missing 'break'

Also I think we should not modify imx31_gpio_hwdata but instead add an
additional imx35_gpio_hwdata. It will waste a few bytes but make the
code more straightforward.

Sascha

> +	case IMX35_GPIO:
> +		mxc_gpio_hwdata = &imx31_imx35_gpio_hwdata;
> +		break;
> +	default:
>  		mxc_gpio_hwdata = &imx1_imx21_gpio_hwdata;
> +	}
>  
>  	mxc_gpio_hwtype = hwtype;
>  }
> 

-- 
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] 15+ messages in thread

* [PATCH] gpio/mxc: use the edge_sel feature if available
  2012-06-21  6:43     ` Sascha Hauer
@ 2012-06-21 11:23       ` Benoît Thébaudeau
  0 siblings, 0 replies; 15+ messages in thread
From: Benoît Thébaudeau @ 2012-06-21 11:23 UTC (permalink / raw)
  To: linux-arm-kernel

On Thu, Jun 21, 2012 at 08:43:47AM +0200, Sascha Hauer wrote:
> > I have checked the reference manuals for i.MX25/35/5x and tested it
> > on
> > i.MX25/35. The reference manual of the i.MX6Q is not public (yet?),
> > so I need
> > someone who has it to check that this change is valid for the
> > i.MX6Q too. I
> > assumed in this patch that the i.MX6Q has this EDGE_SEL register at
> > offset 0x1c.
> 
> Just checked, that's correct.

Thanks.

> > I have a question regarding the fallback mechanism in the i.MX31
> > case: it has
> > been created in commit 910862e using levels instead of edges, and
> > this has not
> > been changed since. Why? Is it a bug or on purpose?
> 
> I assume that implementing this using level irqs is less racy. If you
> implement it using edge irqs the edge could come during the time you
> reconfigure the edge in the controller in which case the interrupt
> would
> get lost.

I think so.

> > @@ -338,10 +365,15 @@ static void __devinit mxc_gpio_get_hw(struct
> > platform_device *pdev)
> >  		return;
> >  	}
> >  
> > -	if (hwtype == IMX31_GPIO)
> > -		mxc_gpio_hwdata = &imx31_gpio_hwdata;
> > -	else
> > +	switch (hwtype) {
> > +	case IMX31_GPIO:
> > +		imx31_imx35_gpio_hwdata.edge_sel_reg = -1;
> 
> missing 'break'

It was not missing: the end of this case was shared with the next case.

> Also I think we should not modify imx31_gpio_hwdata but instead add
> an
> additional imx35_gpio_hwdata. It will waste a few bytes but make the
> code more straightforward.

Done below.

Regards,
Beno?t


[PATCH] gpio/mxc: use the edge_sel feature if available

Some mxc processors have an edge_sel feature, which allows the IRQ to be
triggered by any edge.

This patch makes use of this feature if available, which skips mxc_flip_edge().

Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Linus Walleij <linus.walleij@stericsson.com>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: <linux-arm-kernel@lists.infradead.org>
Signed-off-by: Beno?t Th?baudeau <benoit.thebaudeau@advansee.com>
---
 .../devicetree/bindings/gpio/fsl-imx-gpio.txt      |    2 +-
 .../arch/arm/boot/dts/imx51.dtsi                   |    8 +--
 .../arch/arm/boot/dts/imx53.dtsi                   |   14 ++--
 .../arch/arm/boot/dts/imx6q.dtsi                   |   14 ++--
 .../arch/arm/mach-imx/mm-imx25.c                   |   10 +--
 .../arch/arm/mach-imx/mm-imx3.c                    |    7 +-
 .../arch/arm/mach-imx/mm-imx5.c                    |   40 +++++------
 .../drivers/gpio/gpio-mxc.c                        |   71 ++++++++++++++++----
 8 files changed, 104 insertions(+), 62 deletions(-)

diff --git linux-next-HEAD-a99225f.orig/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt linux-next-HEAD-a99225f/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt
index 4363ae4..33a0345 100644
--- linux-next-HEAD-a99225f.orig/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt
+++ linux-next-HEAD-a99225f/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt
@@ -14,7 +14,7 @@ Required properties:
 Example:
 
 gpio0: gpio at 73f84000 {
-	compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
+	compatible = "fsl,imx51-gpio", "fsl,imx35-gpio";
 	reg = <0x73f84000 0x4000>;
 	interrupts = <50 51>;
 	gpio-controller;
diff --git linux-next-HEAD-a99225f.orig/arch/arm/boot/dts/imx51.dtsi linux-next-HEAD-a99225f/arch/arm/boot/dts/imx51.dtsi
index 39eb88e..5236e42 100644
--- linux-next-HEAD-a99225f.orig/arch/arm/boot/dts/imx51.dtsi
+++ linux-next-HEAD-a99225f/arch/arm/boot/dts/imx51.dtsi
@@ -127,7 +127,7 @@
 			};
 
 			gpio1: gpio at 73f84000 {
-				compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx51-gpio", "fsl,imx35-gpio";
 				reg = <0x73f84000 0x4000>;
 				interrupts = <50 51>;
 				gpio-controller;
@@ -137,7 +137,7 @@
 			};
 
 			gpio2: gpio at 73f88000 {
-				compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx51-gpio", "fsl,imx35-gpio";
 				reg = <0x73f88000 0x4000>;
 				interrupts = <52 53>;
 				gpio-controller;
@@ -147,7 +147,7 @@
 			};
 
 			gpio3: gpio at 73f8c000 {
-				compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx51-gpio", "fsl,imx35-gpio";
 				reg = <0x73f8c000 0x4000>;
 				interrupts = <54 55>;
 				gpio-controller;
@@ -157,7 +157,7 @@
 			};
 
 			gpio4: gpio at 73f90000 {
-				compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx51-gpio", "fsl,imx35-gpio";
 				reg = <0x73f90000 0x4000>;
 				interrupts = <56 57>;
 				gpio-controller;
diff --git linux-next-HEAD-a99225f.orig/arch/arm/boot/dts/imx53.dtsi linux-next-HEAD-a99225f/arch/arm/boot/dts/imx53.dtsi
index 2b5caf9..39ea1a5 100644
--- linux-next-HEAD-a99225f.orig/arch/arm/boot/dts/imx53.dtsi
+++ linux-next-HEAD-a99225f/arch/arm/boot/dts/imx53.dtsi
@@ -129,7 +129,7 @@
 			};
 
 			gpio1: gpio at 53f84000 {
-				compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
 				reg = <0x53f84000 0x4000>;
 				interrupts = <50 51>;
 				gpio-controller;
@@ -139,7 +139,7 @@
 			};
 
 			gpio2: gpio at 53f88000 {
-				compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
 				reg = <0x53f88000 0x4000>;
 				interrupts = <52 53>;
 				gpio-controller;
@@ -149,7 +149,7 @@
 			};
 
 			gpio3: gpio at 53f8c000 {
-				compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
 				reg = <0x53f8c000 0x4000>;
 				interrupts = <54 55>;
 				gpio-controller;
@@ -159,7 +159,7 @@
 			};
 
 			gpio4: gpio at 53f90000 {
-				compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
 				reg = <0x53f90000 0x4000>;
 				interrupts = <56 57>;
 				gpio-controller;
@@ -197,7 +197,7 @@
 			};
 
 			gpio5: gpio at 53fdc000 {
-				compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
 				reg = <0x53fdc000 0x4000>;
 				interrupts = <103 104>;
 				gpio-controller;
@@ -207,7 +207,7 @@
 			};
 
 			gpio6: gpio at 53fe0000 {
-				compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
 				reg = <0x53fe0000 0x4000>;
 				interrupts = <105 106>;
 				gpio-controller;
@@ -217,7 +217,7 @@
 			};
 
 			gpio7: gpio at 53fe4000 {
-				compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
 				reg = <0x53fe4000 0x4000>;
 				interrupts = <107 108>;
 				gpio-controller;
diff --git linux-next-HEAD-a99225f.orig/arch/arm/boot/dts/imx6q.dtsi linux-next-HEAD-a99225f/arch/arm/boot/dts/imx6q.dtsi
index 8c90cba..da78fd8 100644
--- linux-next-HEAD-a99225f.orig/arch/arm/boot/dts/imx6q.dtsi
+++ linux-next-HEAD-a99225f/arch/arm/boot/dts/imx6q.dtsi
@@ -260,7 +260,7 @@
 			};
 
 			gpio1: gpio at 0209c000 {
-				compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
 				reg = <0x0209c000 0x4000>;
 				interrupts = <0 66 0x04 0 67 0x04>;
 				gpio-controller;
@@ -270,7 +270,7 @@
 			};
 
 			gpio2: gpio at 020a0000 {
-				compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
 				reg = <0x020a0000 0x4000>;
 				interrupts = <0 68 0x04 0 69 0x04>;
 				gpio-controller;
@@ -280,7 +280,7 @@
 			};
 
 			gpio3: gpio at 020a4000 {
-				compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
 				reg = <0x020a4000 0x4000>;
 				interrupts = <0 70 0x04 0 71 0x04>;
 				gpio-controller;
@@ -290,7 +290,7 @@
 			};
 
 			gpio4: gpio at 020a8000 {
-				compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
 				reg = <0x020a8000 0x4000>;
 				interrupts = <0 72 0x04 0 73 0x04>;
 				gpio-controller;
@@ -300,7 +300,7 @@
 			};
 
 			gpio5: gpio at 020ac000 {
-				compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
 				reg = <0x020ac000 0x4000>;
 				interrupts = <0 74 0x04 0 75 0x04>;
 				gpio-controller;
@@ -310,7 +310,7 @@
 			};
 
 			gpio6: gpio at 020b0000 {
-				compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
 				reg = <0x020b0000 0x4000>;
 				interrupts = <0 76 0x04 0 77 0x04>;
 				gpio-controller;
@@ -320,7 +320,7 @@
 			};
 
 			gpio7: gpio at 020b4000 {
-				compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
 				reg = <0x020b4000 0x4000>;
 				interrupts = <0 78 0x04 0 79 0x04>;
 				gpio-controller;
diff --git linux-next-HEAD-a99225f.orig/arch/arm/mach-imx/mm-imx25.c linux-next-HEAD-a99225f/arch/arm/mach-imx/mm-imx25.c
index 6ff3714..8e8ddb8 100644
--- linux-next-HEAD-a99225f.orig/arch/arm/mach-imx/mm-imx25.c
+++ linux-next-HEAD-a99225f/arch/arm/mach-imx/mm-imx25.c
@@ -90,11 +90,11 @@ static const struct resource imx25_audmux_res[] __initconst = {
 
 void __init imx25_soc_init(void)
 {
-	/* i.mx25 has the i.mx31 type gpio */
-	mxc_register_gpio("imx31-gpio", 0, MX25_GPIO1_BASE_ADDR, SZ_16K, MX25_INT_GPIO1, 0);
-	mxc_register_gpio("imx31-gpio", 1, MX25_GPIO2_BASE_ADDR, SZ_16K, MX25_INT_GPIO2, 0);
-	mxc_register_gpio("imx31-gpio", 2, MX25_GPIO3_BASE_ADDR, SZ_16K, MX25_INT_GPIO3, 0);
-	mxc_register_gpio("imx31-gpio", 3, MX25_GPIO4_BASE_ADDR, SZ_16K, MX25_INT_GPIO4, 0);
+	/* i.mx25 has the i.mx35 type gpio */
+	mxc_register_gpio("imx35-gpio", 0, MX25_GPIO1_BASE_ADDR, SZ_16K, MX25_INT_GPIO1, 0);
+	mxc_register_gpio("imx35-gpio", 1, MX25_GPIO2_BASE_ADDR, SZ_16K, MX25_INT_GPIO2, 0);
+	mxc_register_gpio("imx35-gpio", 2, MX25_GPIO3_BASE_ADDR, SZ_16K, MX25_INT_GPIO3, 0);
+	mxc_register_gpio("imx35-gpio", 3, MX25_GPIO4_BASE_ADDR, SZ_16K, MX25_INT_GPIO4, 0);
 
 	pinctrl_provide_dummies();
 	/* i.mx25 has the i.mx35 type sdma */
diff --git linux-next-HEAD-a99225f.orig/arch/arm/mach-imx/mm-imx3.c linux-next-HEAD-a99225f/arch/arm/mach-imx/mm-imx3.c
index a8983b9..8e51e77 100644
--- linux-next-HEAD-a99225f.orig/arch/arm/mach-imx/mm-imx3.c
+++ linux-next-HEAD-a99225f/arch/arm/mach-imx/mm-imx3.c
@@ -273,10 +273,9 @@ void __init imx35_soc_init(void)
 
 	imx3_init_l2x0();
 
-	/* i.mx35 has the i.mx31 type gpio */
-	mxc_register_gpio("imx31-gpio", 0, MX35_GPIO1_BASE_ADDR, SZ_16K, MX35_INT_GPIO1, 0);
-	mxc_register_gpio("imx31-gpio", 1, MX35_GPIO2_BASE_ADDR, SZ_16K, MX35_INT_GPIO2, 0);
-	mxc_register_gpio("imx31-gpio", 2, MX35_GPIO3_BASE_ADDR, SZ_16K, MX35_INT_GPIO3, 0);
+	mxc_register_gpio("imx35-gpio", 0, MX35_GPIO1_BASE_ADDR, SZ_16K, MX35_INT_GPIO1, 0);
+	mxc_register_gpio("imx35-gpio", 1, MX35_GPIO2_BASE_ADDR, SZ_16K, MX35_INT_GPIO2, 0);
+	mxc_register_gpio("imx35-gpio", 2, MX35_GPIO3_BASE_ADDR, SZ_16K, MX35_INT_GPIO3, 0);
 
 	pinctrl_provide_dummies();
 	if (to_version == 1) {
diff --git linux-next-HEAD-a99225f.orig/arch/arm/mach-imx/mm-imx5.c linux-next-HEAD-a99225f/arch/arm/mach-imx/mm-imx5.c
index 1d00305..d70d16c 100644
--- linux-next-HEAD-a99225f.orig/arch/arm/mach-imx/mm-imx5.c
+++ linux-next-HEAD-a99225f/arch/arm/mach-imx/mm-imx5.c
@@ -181,13 +181,13 @@ static const struct resource imx53_audmux_res[] __initconst = {
 
 void __init imx50_soc_init(void)
 {
-	/* i.mx50 has the i.mx31 type gpio */
-	mxc_register_gpio("imx31-gpio", 0, MX50_GPIO1_BASE_ADDR, SZ_16K, MX50_INT_GPIO1_LOW, MX50_INT_GPIO1_HIGH);
-	mxc_register_gpio("imx31-gpio", 1, MX50_GPIO2_BASE_ADDR, SZ_16K, MX50_INT_GPIO2_LOW, MX50_INT_GPIO2_HIGH);
-	mxc_register_gpio("imx31-gpio", 2, MX50_GPIO3_BASE_ADDR, SZ_16K, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH);
-	mxc_register_gpio("imx31-gpio", 3, MX50_GPIO4_BASE_ADDR, SZ_16K, MX50_INT_GPIO4_LOW, MX50_INT_GPIO4_HIGH);
-	mxc_register_gpio("imx31-gpio", 4, MX50_GPIO5_BASE_ADDR, SZ_16K, MX50_INT_GPIO5_LOW, MX50_INT_GPIO5_HIGH);
-	mxc_register_gpio("imx31-gpio", 5, MX50_GPIO6_BASE_ADDR, SZ_16K, MX50_INT_GPIO6_LOW, MX50_INT_GPIO6_HIGH);
+	/* i.mx50 has the i.mx35 type gpio */
+	mxc_register_gpio("imx35-gpio", 0, MX50_GPIO1_BASE_ADDR, SZ_16K, MX50_INT_GPIO1_LOW, MX50_INT_GPIO1_HIGH);
+	mxc_register_gpio("imx35-gpio", 1, MX50_GPIO2_BASE_ADDR, SZ_16K, MX50_INT_GPIO2_LOW, MX50_INT_GPIO2_HIGH);
+	mxc_register_gpio("imx35-gpio", 2, MX50_GPIO3_BASE_ADDR, SZ_16K, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH);
+	mxc_register_gpio("imx35-gpio", 3, MX50_GPIO4_BASE_ADDR, SZ_16K, MX50_INT_GPIO4_LOW, MX50_INT_GPIO4_HIGH);
+	mxc_register_gpio("imx35-gpio", 4, MX50_GPIO5_BASE_ADDR, SZ_16K, MX50_INT_GPIO5_LOW, MX50_INT_GPIO5_HIGH);
+	mxc_register_gpio("imx35-gpio", 5, MX50_GPIO6_BASE_ADDR, SZ_16K, MX50_INT_GPIO6_LOW, MX50_INT_GPIO6_HIGH);
 
 	/* i.mx50 has the i.mx31 type audmux */
 	platform_device_register_simple("imx31-audmux", 0, imx50_audmux_res,
@@ -196,11 +196,11 @@ void __init imx50_soc_init(void)
 
 void __init imx51_soc_init(void)
 {
-	/* i.mx51 has the i.mx31 type gpio */
-	mxc_register_gpio("imx31-gpio", 0, MX51_GPIO1_BASE_ADDR, SZ_16K, MX51_INT_GPIO1_LOW, MX51_INT_GPIO1_HIGH);
-	mxc_register_gpio("imx31-gpio", 1, MX51_GPIO2_BASE_ADDR, SZ_16K, MX51_INT_GPIO2_LOW, MX51_INT_GPIO2_HIGH);
-	mxc_register_gpio("imx31-gpio", 2, MX51_GPIO3_BASE_ADDR, SZ_16K, MX51_INT_GPIO3_LOW, MX51_INT_GPIO3_HIGH);
-	mxc_register_gpio("imx31-gpio", 3, MX51_GPIO4_BASE_ADDR, SZ_16K, MX51_INT_GPIO4_LOW, MX51_INT_GPIO4_HIGH);
+	/* i.mx51 has the i.mx35 type gpio */
+	mxc_register_gpio("imx35-gpio", 0, MX51_GPIO1_BASE_ADDR, SZ_16K, MX51_INT_GPIO1_LOW, MX51_INT_GPIO1_HIGH);
+	mxc_register_gpio("imx35-gpio", 1, MX51_GPIO2_BASE_ADDR, SZ_16K, MX51_INT_GPIO2_LOW, MX51_INT_GPIO2_HIGH);
+	mxc_register_gpio("imx35-gpio", 2, MX51_GPIO3_BASE_ADDR, SZ_16K, MX51_INT_GPIO3_LOW, MX51_INT_GPIO3_HIGH);
+	mxc_register_gpio("imx35-gpio", 3, MX51_GPIO4_BASE_ADDR, SZ_16K, MX51_INT_GPIO4_LOW, MX51_INT_GPIO4_HIGH);
 
 	pinctrl_provide_dummies();
 
@@ -218,14 +218,14 @@ void __init imx51_soc_init(void)
 
 void __init imx53_soc_init(void)
 {
-	/* i.mx53 has the i.mx31 type gpio */
-	mxc_register_gpio("imx31-gpio", 0, MX53_GPIO1_BASE_ADDR, SZ_16K, MX53_INT_GPIO1_LOW, MX53_INT_GPIO1_HIGH);
-	mxc_register_gpio("imx31-gpio", 1, MX53_GPIO2_BASE_ADDR, SZ_16K, MX53_INT_GPIO2_LOW, MX53_INT_GPIO2_HIGH);
-	mxc_register_gpio("imx31-gpio", 2, MX53_GPIO3_BASE_ADDR, SZ_16K, MX53_INT_GPIO3_LOW, MX53_INT_GPIO3_HIGH);
-	mxc_register_gpio("imx31-gpio", 3, MX53_GPIO4_BASE_ADDR, SZ_16K, MX53_INT_GPIO4_LOW, MX53_INT_GPIO4_HIGH);
-	mxc_register_gpio("imx31-gpio", 4, MX53_GPIO5_BASE_ADDR, SZ_16K, MX53_INT_GPIO5_LOW, MX53_INT_GPIO5_HIGH);
-	mxc_register_gpio("imx31-gpio", 5, MX53_GPIO6_BASE_ADDR, SZ_16K, MX53_INT_GPIO6_LOW, MX53_INT_GPIO6_HIGH);
-	mxc_register_gpio("imx31-gpio", 6, MX53_GPIO7_BASE_ADDR, SZ_16K, MX53_INT_GPIO7_LOW, MX53_INT_GPIO7_HIGH);
+	/* i.mx53 has the i.mx35 type gpio */
+	mxc_register_gpio("imx35-gpio", 0, MX53_GPIO1_BASE_ADDR, SZ_16K, MX53_INT_GPIO1_LOW, MX53_INT_GPIO1_HIGH);
+	mxc_register_gpio("imx35-gpio", 1, MX53_GPIO2_BASE_ADDR, SZ_16K, MX53_INT_GPIO2_LOW, MX53_INT_GPIO2_HIGH);
+	mxc_register_gpio("imx35-gpio", 2, MX53_GPIO3_BASE_ADDR, SZ_16K, MX53_INT_GPIO3_LOW, MX53_INT_GPIO3_HIGH);
+	mxc_register_gpio("imx35-gpio", 3, MX53_GPIO4_BASE_ADDR, SZ_16K, MX53_INT_GPIO4_LOW, MX53_INT_GPIO4_HIGH);
+	mxc_register_gpio("imx35-gpio", 4, MX53_GPIO5_BASE_ADDR, SZ_16K, MX53_INT_GPIO5_LOW, MX53_INT_GPIO5_HIGH);
+	mxc_register_gpio("imx35-gpio", 5, MX53_GPIO6_BASE_ADDR, SZ_16K, MX53_INT_GPIO6_LOW, MX53_INT_GPIO6_HIGH);
+	mxc_register_gpio("imx35-gpio", 6, MX53_GPIO7_BASE_ADDR, SZ_16K, MX53_INT_GPIO7_LOW, MX53_INT_GPIO7_HIGH);
 
 	pinctrl_provide_dummies();
 	/* i.mx53 has the i.mx35 type sdma */
diff --git linux-next-HEAD-a99225f.orig/drivers/gpio/gpio-mxc.c linux-next-HEAD-a99225f/drivers/gpio/gpio-mxc.c
index c337143..c014fb4 100644
--- linux-next-HEAD-a99225f.orig/drivers/gpio/gpio-mxc.c
+++ linux-next-HEAD-a99225f/drivers/gpio/gpio-mxc.c
@@ -38,7 +38,8 @@
 enum mxc_gpio_hwtype {
 	IMX1_GPIO,	/* runs on i.mx1 */
 	IMX21_GPIO,	/* runs on i.mx21 and i.mx27 */
-	IMX31_GPIO,	/* runs on all other i.mx */
+	IMX31_GPIO,	/* runs on i.mx31 */
+	IMX35_GPIO,	/* runs on all other i.mx */
 };
 
 /* device type dependent stuff */
@@ -50,6 +51,7 @@ struct mxc_gpio_hwdata {
 	unsigned icr2_reg;
 	unsigned imr_reg;
 	unsigned isr_reg;
+	int edge_sel_reg;
 	unsigned low_level;
 	unsigned high_level;
 	unsigned rise_edge;
@@ -74,6 +76,7 @@ static struct mxc_gpio_hwdata imx1_imx21_gpio_hwdata = {
 	.icr2_reg	= 0x2c,
 	.imr_reg	= 0x30,
 	.isr_reg	= 0x34,
+	.edge_sel_reg	= -1,
 	.low_level	= 0x03,
 	.high_level	= 0x02,
 	.rise_edge	= 0x00,
@@ -88,6 +91,22 @@ static struct mxc_gpio_hwdata imx31_gpio_hwdata = {
 	.icr2_reg	= 0x10,
 	.imr_reg	= 0x14,
 	.isr_reg	= 0x18,
+	.edge_sel_reg	= -1,
+	.low_level	= 0x00,
+	.high_level	= 0x01,
+	.rise_edge	= 0x02,
+	.fall_edge	= 0x03,
+};
+
+static struct mxc_gpio_hwdata imx35_gpio_hwdata = {
+	.dr_reg		= 0x00,
+	.gdir_reg	= 0x04,
+	.psr_reg	= 0x08,
+	.icr1_reg	= 0x0c,
+	.icr2_reg	= 0x10,
+	.imr_reg	= 0x14,
+	.isr_reg	= 0x18,
+	.edge_sel_reg	= 0x1c,
 	.low_level	= 0x00,
 	.high_level	= 0x01,
 	.rise_edge	= 0x02,
@@ -104,12 +123,13 @@ static struct mxc_gpio_hwdata *mxc_gpio_hwdata;
 #define GPIO_ICR2		(mxc_gpio_hwdata->icr2_reg)
 #define GPIO_IMR		(mxc_gpio_hwdata->imr_reg)
 #define GPIO_ISR		(mxc_gpio_hwdata->isr_reg)
+#define GPIO_EDGE_SEL		(mxc_gpio_hwdata->edge_sel_reg)
 
 #define GPIO_INT_LOW_LEV	(mxc_gpio_hwdata->low_level)
 #define GPIO_INT_HIGH_LEV	(mxc_gpio_hwdata->high_level)
 #define GPIO_INT_RISE_EDGE	(mxc_gpio_hwdata->rise_edge)
 #define GPIO_INT_FALL_EDGE	(mxc_gpio_hwdata->fall_edge)
-#define GPIO_INT_NONE		0x4
+#define GPIO_INT_BOTH_EDGES	0x4
 
 static struct platform_device_id mxc_gpio_devtype[] = {
 	{
@@ -122,6 +142,9 @@ static struct platform_device_id mxc_gpio_devtype[] = {
 		.name = "imx31-gpio",
 		.driver_data = IMX31_GPIO,
 	}, {
+		.name = "imx35-gpio",
+		.driver_data = IMX35_GPIO,
+	}, {
 		/* sentinel */
 	}
 };
@@ -130,6 +153,7 @@ static const struct of_device_id mxc_gpio_dt_ids[] = {
 	{ .compatible = "fsl,imx1-gpio", .data = &mxc_gpio_devtype[IMX1_GPIO], },
 	{ .compatible = "fsl,imx21-gpio", .data = &mxc_gpio_devtype[IMX21_GPIO], },
 	{ .compatible = "fsl,imx31-gpio", .data = &mxc_gpio_devtype[IMX31_GPIO], },
+	{ .compatible = "fsl,imx35-gpio", .data = &mxc_gpio_devtype[IMX35_GPIO], },
 	{ /* sentinel */ }
 };
 
@@ -160,15 +184,19 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type)
 		edge = GPIO_INT_FALL_EDGE;
 		break;
 	case IRQ_TYPE_EDGE_BOTH:
-		val = gpio_get_value(gpio);
-		if (val) {
-			edge = GPIO_INT_LOW_LEV;
-			pr_debug("mxc: set GPIO %d to low trigger\n", gpio);
+		if (GPIO_EDGE_SEL >= 0) {
+			edge = GPIO_INT_BOTH_EDGES;
 		} else {
-			edge = GPIO_INT_HIGH_LEV;
-			pr_debug("mxc: set GPIO %d to high trigger\n", gpio);
+			val = gpio_get_value(gpio);
+			if (val) {
+				edge = GPIO_INT_LOW_LEV;
+				pr_debug("mxc: set GPIO %d to low trigger\n", gpio);
+			} else {
+				edge = GPIO_INT_HIGH_LEV;
+				pr_debug("mxc: set GPIO %d to high trigger\n", gpio);
+			}
+			port->both_edges |= 1 << (gpio & 31);
 		}
-		port->both_edges |= 1 << (gpio & 31);
 		break;
 	case IRQ_TYPE_LEVEL_LOW:
 		edge = GPIO_INT_LOW_LEV;
@@ -180,10 +208,23 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type)
 		return -EINVAL;
 	}
 
-	reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
-	bit = gpio & 0xf;
-	val = readl(reg) & ~(0x3 << (bit << 1));
-	writel(val | (edge << (bit << 1)), reg);
+	if (GPIO_EDGE_SEL >= 0) {
+		val = readl(port->base + GPIO_EDGE_SEL);
+		if (edge == GPIO_INT_BOTH_EDGES)
+			writel(val | (1 << (gpio & 0x1f)),
+				port->base + GPIO_EDGE_SEL);
+		else
+			writel(val & ~(1 << (gpio & 0x1f)),
+				port->base + GPIO_EDGE_SEL);
+	}
+
+	if (edge != GPIO_INT_BOTH_EDGES) {
+		reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
+		bit = gpio & 0xf;
+		val = readl(reg) & ~(0x3 << (bit << 1));
+		writel(val | (edge << (bit << 1)), reg);
+	}
+
 	writel(1 << (gpio & 0x1f), port->base + GPIO_ISR);
 
 	return 0;
@@ -338,7 +379,9 @@ static void __devinit mxc_gpio_get_hw(struct platform_device *pdev)
 		return;
 	}
 
-	if (hwtype == IMX31_GPIO)
+	if (hwtype == IMX35_GPIO)
+		mxc_gpio_hwdata = &imx35_gpio_hwdata;
+	else if (hwtype == IMX31_GPIO)
 		mxc_gpio_hwdata = &imx31_gpio_hwdata;
 	else
 		mxc_gpio_hwdata = &imx1_imx21_gpio_hwdata;

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

* [PATCH] gpio/mxc: use the edge_sel feature if available
  2012-06-20 18:27   ` Benoît Thébaudeau
  2012-06-20 18:36     ` Benoît Thébaudeau
  2012-06-21  6:43     ` Sascha Hauer
@ 2012-06-22 13:46     ` Guennadi Liakhovetski
  2012-06-22 19:04       ` Benoît Thébaudeau
  2 siblings, 1 reply; 15+ messages in thread
From: Guennadi Liakhovetski @ 2012-06-22 13:46 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Beno??t

Sorry for a delay, just a minor nit-pick below:

On Wed, 20 Jun 2012, Beno??t Th??baudeau wrote:

> On Wed, Jun 20, 2012 at 11:19:59AM +0200, Sascha Hauer wrote:
> > To make Shawns suggestion a bit more clear:
> > 
> > What you should do here is to add flags describing differences
> > between
> > SoCs in mxc_gpio_hwdata.
> > 
> > This means that you have to:
> > 
> > - add IMX35_GPIO to enum mxc_gpio_hwtype
> > - add imx35-gpio to mxc_gpio_devtype[]
> > - add "fsl,imx35-gpio" to the compatible list.
> > - fix all devicetree bindings and platform device bindings for
> >   i.MX25,35,51,53 and probably i.MX6
> 
> Thanks for your suggestion. I have implemented it in the reworked patch below.
> 
> I have checked the reference manuals for i.MX25/35/5x and tested it on
> i.MX25/35. The reference manual of the i.MX6Q is not public (yet?), so I need
> someone who has it to check that this change is valid for the i.MX6Q too. I
> assumed in this patch that the i.MX6Q has this EDGE_SEL register at offset 0x1c.
> 
> I have a question regarding the fallback mechanism in the i.MX31 case: it has
> been created in commit 910862e using levels instead of edges, and this has not
> been changed since. Why? Is it a bug or on purpose?
> 
> Regards,
> Beno??t
> 
> 
> [PATCH] gpio/mxc: use the edge_sel feature if available
> 
> Some mxc processors have an edge_sel feature, which allows the IRQ to be
> triggered by any edge.
> 
> This patch makes use of this feature if available, which skips mxc_flip_edge().
> 
> Cc: Grant Likely <grant.likely@secretlab.ca>
> Cc: Linus Walleij <linus.walleij@stericsson.com>
> Cc: Sascha Hauer <kernel@pengutronix.de>
> Cc: <linux-arm-kernel@lists.infradead.org>
> Signed-off-by: Beno??t Th??baudeau <benoit.thebaudeau@advansee.com>
> ---
>  .../devicetree/bindings/gpio/fsl-imx-gpio.txt      |    2 +-
>  .../arch/arm/boot/dts/imx51.dtsi                   |    8 +--
>  .../arch/arm/boot/dts/imx53.dtsi                   |   14 ++---
>  .../arch/arm/boot/dts/imx6q.dtsi                   |   14 ++---
>  .../arch/arm/mach-imx/mm-imx25.c                   |   10 +--
>  .../arch/arm/mach-imx/mm-imx3.c                    |    7 +--
>  .../arch/arm/mach-imx/mm-imx5.c                    |   40 ++++++------
>  .../drivers/gpio/gpio-mxc.c                        |   66 +++++++++++++++-----
>  8 files changed, 96 insertions(+), 65 deletions(-)

[snip]

> @@ -74,13 +77,14 @@ static struct mxc_gpio_hwdata imx1_imx21_gpio_hwdata = {
>  	.icr2_reg	= 0x2c,
>  	.imr_reg	= 0x30,
>  	.isr_reg	= 0x34,
> +	.edge_sel_reg	= -1,

Maybe better use a meaningful error code like -EINVAL?

[snip]

> @@ -338,10 +365,15 @@ static void __devinit mxc_gpio_get_hw(struct platform_device *pdev)
>  		return;
>  	}
>  
> -	if (hwtype == IMX31_GPIO)
> -		mxc_gpio_hwdata = &imx31_gpio_hwdata;
> -	else
> +	switch (hwtype) {
> +	case IMX31_GPIO:
> +		imx31_imx35_gpio_hwdata.edge_sel_reg = -1;

ditto

> +	case IMX35_GPIO:
> +		mxc_gpio_hwdata = &imx31_imx35_gpio_hwdata;
> +		break;
> +	default:
>  		mxc_gpio_hwdata = &imx1_imx21_gpio_hwdata;
> +	}
>  
>  	mxc_gpio_hwtype = hwtype;
>  }

Thanks
Guennadi
---
Guennadi Liakhovetski, Ph.D.
Freelance Open-Source Software Developer
http://www.open-technology.de/

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

* [PATCH] gpio/mxc: use the edge_sel feature if available
  2012-06-22 13:46     ` Guennadi Liakhovetski
@ 2012-06-22 19:04       ` Benoît Thébaudeau
  2012-06-27  6:59         ` Sascha Hauer
  0 siblings, 1 reply; 15+ messages in thread
From: Benoît Thébaudeau @ 2012-06-22 19:04 UTC (permalink / raw)
  To: linux-arm-kernel

Hi Guennadi,

On Fri, Jun 22, 2012 at 03:46:25PM +0200, Guennadi Liakhovetski wrote:
> Sorry for a delay,

No problem. Since you're talking about that, I'm wondering what the usual answer
delays are on Linux mailing lists. I've posted my first official Linux patches
last week. Some have been almost instantly applied. Others had answers that I
took into account, then nothing. Others had no answer at all (especially on
linux-media and rtc-linux). I'm not sure what to expect, if I should post to
other mailing lists, do something or simply wait.

> just a minor nit-pick below:
> On Wed, 20 Jun 2012, Beno?t Th?baudeau wrote:
> > @@ -74,13 +77,14 @@ static struct mxc_gpio_hwdata
> > imx1_imx21_gpio_hwdata = {
> >  	.icr2_reg	= 0x2c,
> >  	.imr_reg	= 0x30,
> >  	.isr_reg	= 0x34,
> > +	.edge_sel_reg	= -1,
> 
> Maybe better use a meaningful error code like -EINVAL?
> 
> [snip]
> 
> > @@ -338,10 +365,15 @@ static void __devinit mxc_gpio_get_hw(struct
> > platform_device *pdev)
> >  		return;
> >  	}
> >  
> > -	if (hwtype == IMX31_GPIO)
> > -		mxc_gpio_hwdata = &imx31_gpio_hwdata;
> > -	else
> > +	switch (hwtype) {
> > +	case IMX31_GPIO:
> > +		imx31_imx35_gpio_hwdata.edge_sel_reg = -1;
> 
> ditto

Here you are.

Regards,
Beno?t


[PATCH] gpio/mxc: use the edge_sel feature if available

Some mxc processors have an edge_sel feature, which allows the IRQ to be
triggered by any edge.

This patch makes use of this feature if available, which skips mxc_flip_edge().

Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Linus Walleij <linus.walleij@stericsson.com>
Cc: Sascha Hauer <kernel@pengutronix.de>
Cc: <linux-arm-kernel@lists.infradead.org>
Signed-off-by: Beno?t Th?baudeau <benoit.thebaudeau@advansee.com>
---
 .../devicetree/bindings/gpio/fsl-imx-gpio.txt      |    2 +-
 .../arch/arm/boot/dts/imx51.dtsi                   |    8 +--
 .../arch/arm/boot/dts/imx53.dtsi                   |   14 ++--
 .../arch/arm/boot/dts/imx6q.dtsi                   |   14 ++--
 .../arch/arm/mach-imx/mm-imx25.c                   |   10 +--
 .../arch/arm/mach-imx/mm-imx3.c                    |    7 +-
 .../arch/arm/mach-imx/mm-imx5.c                    |   40 +++++------
 .../drivers/gpio/gpio-mxc.c                        |   71 ++++++++++++++++----
 8 files changed, 104 insertions(+), 62 deletions(-)

diff --git linux-next-HEAD-072e7c8.orig/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt linux-next-HEAD-072e7c8/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt
index 4363ae4..33a0345 100644
--- linux-next-HEAD-072e7c8.orig/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt
+++ linux-next-HEAD-072e7c8/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt
@@ -14,7 +14,7 @@ Required properties:
 Example:
 
 gpio0: gpio at 73f84000 {
-	compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
+	compatible = "fsl,imx51-gpio", "fsl,imx35-gpio";
 	reg = <0x73f84000 0x4000>;
 	interrupts = <50 51>;
 	gpio-controller;
diff --git linux-next-HEAD-072e7c8.orig/arch/arm/boot/dts/imx51.dtsi linux-next-HEAD-072e7c8/arch/arm/boot/dts/imx51.dtsi
index 39eb88e..5236e42 100644
--- linux-next-HEAD-072e7c8.orig/arch/arm/boot/dts/imx51.dtsi
+++ linux-next-HEAD-072e7c8/arch/arm/boot/dts/imx51.dtsi
@@ -127,7 +127,7 @@
 			};
 
 			gpio1: gpio at 73f84000 {
-				compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx51-gpio", "fsl,imx35-gpio";
 				reg = <0x73f84000 0x4000>;
 				interrupts = <50 51>;
 				gpio-controller;
@@ -137,7 +137,7 @@
 			};
 
 			gpio2: gpio at 73f88000 {
-				compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx51-gpio", "fsl,imx35-gpio";
 				reg = <0x73f88000 0x4000>;
 				interrupts = <52 53>;
 				gpio-controller;
@@ -147,7 +147,7 @@
 			};
 
 			gpio3: gpio at 73f8c000 {
-				compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx51-gpio", "fsl,imx35-gpio";
 				reg = <0x73f8c000 0x4000>;
 				interrupts = <54 55>;
 				gpio-controller;
@@ -157,7 +157,7 @@
 			};
 
 			gpio4: gpio at 73f90000 {
-				compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx51-gpio", "fsl,imx35-gpio";
 				reg = <0x73f90000 0x4000>;
 				interrupts = <56 57>;
 				gpio-controller;
diff --git linux-next-HEAD-072e7c8.orig/arch/arm/boot/dts/imx53.dtsi linux-next-HEAD-072e7c8/arch/arm/boot/dts/imx53.dtsi
index 2b5caf9..39ea1a5 100644
--- linux-next-HEAD-072e7c8.orig/arch/arm/boot/dts/imx53.dtsi
+++ linux-next-HEAD-072e7c8/arch/arm/boot/dts/imx53.dtsi
@@ -129,7 +129,7 @@
 			};
 
 			gpio1: gpio at 53f84000 {
-				compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
 				reg = <0x53f84000 0x4000>;
 				interrupts = <50 51>;
 				gpio-controller;
@@ -139,7 +139,7 @@
 			};
 
 			gpio2: gpio at 53f88000 {
-				compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
 				reg = <0x53f88000 0x4000>;
 				interrupts = <52 53>;
 				gpio-controller;
@@ -149,7 +149,7 @@
 			};
 
 			gpio3: gpio at 53f8c000 {
-				compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
 				reg = <0x53f8c000 0x4000>;
 				interrupts = <54 55>;
 				gpio-controller;
@@ -159,7 +159,7 @@
 			};
 
 			gpio4: gpio at 53f90000 {
-				compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
 				reg = <0x53f90000 0x4000>;
 				interrupts = <56 57>;
 				gpio-controller;
@@ -197,7 +197,7 @@
 			};
 
 			gpio5: gpio at 53fdc000 {
-				compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
 				reg = <0x53fdc000 0x4000>;
 				interrupts = <103 104>;
 				gpio-controller;
@@ -207,7 +207,7 @@
 			};
 
 			gpio6: gpio at 53fe0000 {
-				compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
 				reg = <0x53fe0000 0x4000>;
 				interrupts = <105 106>;
 				gpio-controller;
@@ -217,7 +217,7 @@
 			};
 
 			gpio7: gpio at 53fe4000 {
-				compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
 				reg = <0x53fe4000 0x4000>;
 				interrupts = <107 108>;
 				gpio-controller;
diff --git linux-next-HEAD-072e7c8.orig/arch/arm/boot/dts/imx6q.dtsi linux-next-HEAD-072e7c8/arch/arm/boot/dts/imx6q.dtsi
index 8c90cba..da78fd8 100644
--- linux-next-HEAD-072e7c8.orig/arch/arm/boot/dts/imx6q.dtsi
+++ linux-next-HEAD-072e7c8/arch/arm/boot/dts/imx6q.dtsi
@@ -260,7 +260,7 @@
 			};
 
 			gpio1: gpio at 0209c000 {
-				compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
 				reg = <0x0209c000 0x4000>;
 				interrupts = <0 66 0x04 0 67 0x04>;
 				gpio-controller;
@@ -270,7 +270,7 @@
 			};
 
 			gpio2: gpio at 020a0000 {
-				compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
 				reg = <0x020a0000 0x4000>;
 				interrupts = <0 68 0x04 0 69 0x04>;
 				gpio-controller;
@@ -280,7 +280,7 @@
 			};
 
 			gpio3: gpio at 020a4000 {
-				compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
 				reg = <0x020a4000 0x4000>;
 				interrupts = <0 70 0x04 0 71 0x04>;
 				gpio-controller;
@@ -290,7 +290,7 @@
 			};
 
 			gpio4: gpio at 020a8000 {
-				compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
 				reg = <0x020a8000 0x4000>;
 				interrupts = <0 72 0x04 0 73 0x04>;
 				gpio-controller;
@@ -300,7 +300,7 @@
 			};
 
 			gpio5: gpio at 020ac000 {
-				compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
 				reg = <0x020ac000 0x4000>;
 				interrupts = <0 74 0x04 0 75 0x04>;
 				gpio-controller;
@@ -310,7 +310,7 @@
 			};
 
 			gpio6: gpio at 020b0000 {
-				compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
 				reg = <0x020b0000 0x4000>;
 				interrupts = <0 76 0x04 0 77 0x04>;
 				gpio-controller;
@@ -320,7 +320,7 @@
 			};
 
 			gpio7: gpio at 020b4000 {
-				compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
+				compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
 				reg = <0x020b4000 0x4000>;
 				interrupts = <0 78 0x04 0 79 0x04>;
 				gpio-controller;
diff --git linux-next-HEAD-072e7c8.orig/arch/arm/mach-imx/mm-imx25.c linux-next-HEAD-072e7c8/arch/arm/mach-imx/mm-imx25.c
index 6ff3714..8e8ddb8 100644
--- linux-next-HEAD-072e7c8.orig/arch/arm/mach-imx/mm-imx25.c
+++ linux-next-HEAD-072e7c8/arch/arm/mach-imx/mm-imx25.c
@@ -90,11 +90,11 @@ static const struct resource imx25_audmux_res[] __initconst = {
 
 void __init imx25_soc_init(void)
 {
-	/* i.mx25 has the i.mx31 type gpio */
-	mxc_register_gpio("imx31-gpio", 0, MX25_GPIO1_BASE_ADDR, SZ_16K, MX25_INT_GPIO1, 0);
-	mxc_register_gpio("imx31-gpio", 1, MX25_GPIO2_BASE_ADDR, SZ_16K, MX25_INT_GPIO2, 0);
-	mxc_register_gpio("imx31-gpio", 2, MX25_GPIO3_BASE_ADDR, SZ_16K, MX25_INT_GPIO3, 0);
-	mxc_register_gpio("imx31-gpio", 3, MX25_GPIO4_BASE_ADDR, SZ_16K, MX25_INT_GPIO4, 0);
+	/* i.mx25 has the i.mx35 type gpio */
+	mxc_register_gpio("imx35-gpio", 0, MX25_GPIO1_BASE_ADDR, SZ_16K, MX25_INT_GPIO1, 0);
+	mxc_register_gpio("imx35-gpio", 1, MX25_GPIO2_BASE_ADDR, SZ_16K, MX25_INT_GPIO2, 0);
+	mxc_register_gpio("imx35-gpio", 2, MX25_GPIO3_BASE_ADDR, SZ_16K, MX25_INT_GPIO3, 0);
+	mxc_register_gpio("imx35-gpio", 3, MX25_GPIO4_BASE_ADDR, SZ_16K, MX25_INT_GPIO4, 0);
 
 	pinctrl_provide_dummies();
 	/* i.mx25 has the i.mx35 type sdma */
diff --git linux-next-HEAD-072e7c8.orig/arch/arm/mach-imx/mm-imx3.c linux-next-HEAD-072e7c8/arch/arm/mach-imx/mm-imx3.c
index a8983b9..8e51e77 100644
--- linux-next-HEAD-072e7c8.orig/arch/arm/mach-imx/mm-imx3.c
+++ linux-next-HEAD-072e7c8/arch/arm/mach-imx/mm-imx3.c
@@ -273,10 +273,9 @@ void __init imx35_soc_init(void)
 
 	imx3_init_l2x0();
 
-	/* i.mx35 has the i.mx31 type gpio */
-	mxc_register_gpio("imx31-gpio", 0, MX35_GPIO1_BASE_ADDR, SZ_16K, MX35_INT_GPIO1, 0);
-	mxc_register_gpio("imx31-gpio", 1, MX35_GPIO2_BASE_ADDR, SZ_16K, MX35_INT_GPIO2, 0);
-	mxc_register_gpio("imx31-gpio", 2, MX35_GPIO3_BASE_ADDR, SZ_16K, MX35_INT_GPIO3, 0);
+	mxc_register_gpio("imx35-gpio", 0, MX35_GPIO1_BASE_ADDR, SZ_16K, MX35_INT_GPIO1, 0);
+	mxc_register_gpio("imx35-gpio", 1, MX35_GPIO2_BASE_ADDR, SZ_16K, MX35_INT_GPIO2, 0);
+	mxc_register_gpio("imx35-gpio", 2, MX35_GPIO3_BASE_ADDR, SZ_16K, MX35_INT_GPIO3, 0);
 
 	pinctrl_provide_dummies();
 	if (to_version == 1) {
diff --git linux-next-HEAD-072e7c8.orig/arch/arm/mach-imx/mm-imx5.c linux-next-HEAD-072e7c8/arch/arm/mach-imx/mm-imx5.c
index 1d00305..d70d16c 100644
--- linux-next-HEAD-072e7c8.orig/arch/arm/mach-imx/mm-imx5.c
+++ linux-next-HEAD-072e7c8/arch/arm/mach-imx/mm-imx5.c
@@ -181,13 +181,13 @@ static const struct resource imx53_audmux_res[] __initconst = {
 
 void __init imx50_soc_init(void)
 {
-	/* i.mx50 has the i.mx31 type gpio */
-	mxc_register_gpio("imx31-gpio", 0, MX50_GPIO1_BASE_ADDR, SZ_16K, MX50_INT_GPIO1_LOW, MX50_INT_GPIO1_HIGH);
-	mxc_register_gpio("imx31-gpio", 1, MX50_GPIO2_BASE_ADDR, SZ_16K, MX50_INT_GPIO2_LOW, MX50_INT_GPIO2_HIGH);
-	mxc_register_gpio("imx31-gpio", 2, MX50_GPIO3_BASE_ADDR, SZ_16K, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH);
-	mxc_register_gpio("imx31-gpio", 3, MX50_GPIO4_BASE_ADDR, SZ_16K, MX50_INT_GPIO4_LOW, MX50_INT_GPIO4_HIGH);
-	mxc_register_gpio("imx31-gpio", 4, MX50_GPIO5_BASE_ADDR, SZ_16K, MX50_INT_GPIO5_LOW, MX50_INT_GPIO5_HIGH);
-	mxc_register_gpio("imx31-gpio", 5, MX50_GPIO6_BASE_ADDR, SZ_16K, MX50_INT_GPIO6_LOW, MX50_INT_GPIO6_HIGH);
+	/* i.mx50 has the i.mx35 type gpio */
+	mxc_register_gpio("imx35-gpio", 0, MX50_GPIO1_BASE_ADDR, SZ_16K, MX50_INT_GPIO1_LOW, MX50_INT_GPIO1_HIGH);
+	mxc_register_gpio("imx35-gpio", 1, MX50_GPIO2_BASE_ADDR, SZ_16K, MX50_INT_GPIO2_LOW, MX50_INT_GPIO2_HIGH);
+	mxc_register_gpio("imx35-gpio", 2, MX50_GPIO3_BASE_ADDR, SZ_16K, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH);
+	mxc_register_gpio("imx35-gpio", 3, MX50_GPIO4_BASE_ADDR, SZ_16K, MX50_INT_GPIO4_LOW, MX50_INT_GPIO4_HIGH);
+	mxc_register_gpio("imx35-gpio", 4, MX50_GPIO5_BASE_ADDR, SZ_16K, MX50_INT_GPIO5_LOW, MX50_INT_GPIO5_HIGH);
+	mxc_register_gpio("imx35-gpio", 5, MX50_GPIO6_BASE_ADDR, SZ_16K, MX50_INT_GPIO6_LOW, MX50_INT_GPIO6_HIGH);
 
 	/* i.mx50 has the i.mx31 type audmux */
 	platform_device_register_simple("imx31-audmux", 0, imx50_audmux_res,
@@ -196,11 +196,11 @@ void __init imx50_soc_init(void)
 
 void __init imx51_soc_init(void)
 {
-	/* i.mx51 has the i.mx31 type gpio */
-	mxc_register_gpio("imx31-gpio", 0, MX51_GPIO1_BASE_ADDR, SZ_16K, MX51_INT_GPIO1_LOW, MX51_INT_GPIO1_HIGH);
-	mxc_register_gpio("imx31-gpio", 1, MX51_GPIO2_BASE_ADDR, SZ_16K, MX51_INT_GPIO2_LOW, MX51_INT_GPIO2_HIGH);
-	mxc_register_gpio("imx31-gpio", 2, MX51_GPIO3_BASE_ADDR, SZ_16K, MX51_INT_GPIO3_LOW, MX51_INT_GPIO3_HIGH);
-	mxc_register_gpio("imx31-gpio", 3, MX51_GPIO4_BASE_ADDR, SZ_16K, MX51_INT_GPIO4_LOW, MX51_INT_GPIO4_HIGH);
+	/* i.mx51 has the i.mx35 type gpio */
+	mxc_register_gpio("imx35-gpio", 0, MX51_GPIO1_BASE_ADDR, SZ_16K, MX51_INT_GPIO1_LOW, MX51_INT_GPIO1_HIGH);
+	mxc_register_gpio("imx35-gpio", 1, MX51_GPIO2_BASE_ADDR, SZ_16K, MX51_INT_GPIO2_LOW, MX51_INT_GPIO2_HIGH);
+	mxc_register_gpio("imx35-gpio", 2, MX51_GPIO3_BASE_ADDR, SZ_16K, MX51_INT_GPIO3_LOW, MX51_INT_GPIO3_HIGH);
+	mxc_register_gpio("imx35-gpio", 3, MX51_GPIO4_BASE_ADDR, SZ_16K, MX51_INT_GPIO4_LOW, MX51_INT_GPIO4_HIGH);
 
 	pinctrl_provide_dummies();
 
@@ -218,14 +218,14 @@ void __init imx51_soc_init(void)
 
 void __init imx53_soc_init(void)
 {
-	/* i.mx53 has the i.mx31 type gpio */
-	mxc_register_gpio("imx31-gpio", 0, MX53_GPIO1_BASE_ADDR, SZ_16K, MX53_INT_GPIO1_LOW, MX53_INT_GPIO1_HIGH);
-	mxc_register_gpio("imx31-gpio", 1, MX53_GPIO2_BASE_ADDR, SZ_16K, MX53_INT_GPIO2_LOW, MX53_INT_GPIO2_HIGH);
-	mxc_register_gpio("imx31-gpio", 2, MX53_GPIO3_BASE_ADDR, SZ_16K, MX53_INT_GPIO3_LOW, MX53_INT_GPIO3_HIGH);
-	mxc_register_gpio("imx31-gpio", 3, MX53_GPIO4_BASE_ADDR, SZ_16K, MX53_INT_GPIO4_LOW, MX53_INT_GPIO4_HIGH);
-	mxc_register_gpio("imx31-gpio", 4, MX53_GPIO5_BASE_ADDR, SZ_16K, MX53_INT_GPIO5_LOW, MX53_INT_GPIO5_HIGH);
-	mxc_register_gpio("imx31-gpio", 5, MX53_GPIO6_BASE_ADDR, SZ_16K, MX53_INT_GPIO6_LOW, MX53_INT_GPIO6_HIGH);
-	mxc_register_gpio("imx31-gpio", 6, MX53_GPIO7_BASE_ADDR, SZ_16K, MX53_INT_GPIO7_LOW, MX53_INT_GPIO7_HIGH);
+	/* i.mx53 has the i.mx35 type gpio */
+	mxc_register_gpio("imx35-gpio", 0, MX53_GPIO1_BASE_ADDR, SZ_16K, MX53_INT_GPIO1_LOW, MX53_INT_GPIO1_HIGH);
+	mxc_register_gpio("imx35-gpio", 1, MX53_GPIO2_BASE_ADDR, SZ_16K, MX53_INT_GPIO2_LOW, MX53_INT_GPIO2_HIGH);
+	mxc_register_gpio("imx35-gpio", 2, MX53_GPIO3_BASE_ADDR, SZ_16K, MX53_INT_GPIO3_LOW, MX53_INT_GPIO3_HIGH);
+	mxc_register_gpio("imx35-gpio", 3, MX53_GPIO4_BASE_ADDR, SZ_16K, MX53_INT_GPIO4_LOW, MX53_INT_GPIO4_HIGH);
+	mxc_register_gpio("imx35-gpio", 4, MX53_GPIO5_BASE_ADDR, SZ_16K, MX53_INT_GPIO5_LOW, MX53_INT_GPIO5_HIGH);
+	mxc_register_gpio("imx35-gpio", 5, MX53_GPIO6_BASE_ADDR, SZ_16K, MX53_INT_GPIO6_LOW, MX53_INT_GPIO6_HIGH);
+	mxc_register_gpio("imx35-gpio", 6, MX53_GPIO7_BASE_ADDR, SZ_16K, MX53_INT_GPIO7_LOW, MX53_INT_GPIO7_HIGH);
 
 	pinctrl_provide_dummies();
 	/* i.mx53 has the i.mx35 type sdma */
diff --git linux-next-HEAD-072e7c8.orig/drivers/gpio/gpio-mxc.c linux-next-HEAD-072e7c8/drivers/gpio/gpio-mxc.c
index c337143..bb985e8 100644
--- linux-next-HEAD-072e7c8.orig/drivers/gpio/gpio-mxc.c
+++ linux-next-HEAD-072e7c8/drivers/gpio/gpio-mxc.c
@@ -38,7 +38,8 @@
 enum mxc_gpio_hwtype {
 	IMX1_GPIO,	/* runs on i.mx1 */
 	IMX21_GPIO,	/* runs on i.mx21 and i.mx27 */
-	IMX31_GPIO,	/* runs on all other i.mx */
+	IMX31_GPIO,	/* runs on i.mx31 */
+	IMX35_GPIO,	/* runs on all other i.mx */
 };
 
 /* device type dependent stuff */
@@ -50,6 +51,7 @@ struct mxc_gpio_hwdata {
 	unsigned icr2_reg;
 	unsigned imr_reg;
 	unsigned isr_reg;
+	int edge_sel_reg;
 	unsigned low_level;
 	unsigned high_level;
 	unsigned rise_edge;
@@ -74,6 +76,7 @@ static struct mxc_gpio_hwdata imx1_imx21_gpio_hwdata = {
 	.icr2_reg	= 0x2c,
 	.imr_reg	= 0x30,
 	.isr_reg	= 0x34,
+	.edge_sel_reg	= -EINVAL,
 	.low_level	= 0x03,
 	.high_level	= 0x02,
 	.rise_edge	= 0x00,
@@ -88,6 +91,22 @@ static struct mxc_gpio_hwdata imx31_gpio_hwdata = {
 	.icr2_reg	= 0x10,
 	.imr_reg	= 0x14,
 	.isr_reg	= 0x18,
+	.edge_sel_reg	= -EINVAL,
+	.low_level	= 0x00,
+	.high_level	= 0x01,
+	.rise_edge	= 0x02,
+	.fall_edge	= 0x03,
+};
+
+static struct mxc_gpio_hwdata imx35_gpio_hwdata = {
+	.dr_reg		= 0x00,
+	.gdir_reg	= 0x04,
+	.psr_reg	= 0x08,
+	.icr1_reg	= 0x0c,
+	.icr2_reg	= 0x10,
+	.imr_reg	= 0x14,
+	.isr_reg	= 0x18,
+	.edge_sel_reg	= 0x1c,
 	.low_level	= 0x00,
 	.high_level	= 0x01,
 	.rise_edge	= 0x02,
@@ -104,12 +123,13 @@ static struct mxc_gpio_hwdata *mxc_gpio_hwdata;
 #define GPIO_ICR2		(mxc_gpio_hwdata->icr2_reg)
 #define GPIO_IMR		(mxc_gpio_hwdata->imr_reg)
 #define GPIO_ISR		(mxc_gpio_hwdata->isr_reg)
+#define GPIO_EDGE_SEL		(mxc_gpio_hwdata->edge_sel_reg)
 
 #define GPIO_INT_LOW_LEV	(mxc_gpio_hwdata->low_level)
 #define GPIO_INT_HIGH_LEV	(mxc_gpio_hwdata->high_level)
 #define GPIO_INT_RISE_EDGE	(mxc_gpio_hwdata->rise_edge)
 #define GPIO_INT_FALL_EDGE	(mxc_gpio_hwdata->fall_edge)
-#define GPIO_INT_NONE		0x4
+#define GPIO_INT_BOTH_EDGES	0x4
 
 static struct platform_device_id mxc_gpio_devtype[] = {
 	{
@@ -122,6 +142,9 @@ static struct platform_device_id mxc_gpio_devtype[] = {
 		.name = "imx31-gpio",
 		.driver_data = IMX31_GPIO,
 	}, {
+		.name = "imx35-gpio",
+		.driver_data = IMX35_GPIO,
+	}, {
 		/* sentinel */
 	}
 };
@@ -130,6 +153,7 @@ static const struct of_device_id mxc_gpio_dt_ids[] = {
 	{ .compatible = "fsl,imx1-gpio", .data = &mxc_gpio_devtype[IMX1_GPIO], },
 	{ .compatible = "fsl,imx21-gpio", .data = &mxc_gpio_devtype[IMX21_GPIO], },
 	{ .compatible = "fsl,imx31-gpio", .data = &mxc_gpio_devtype[IMX31_GPIO], },
+	{ .compatible = "fsl,imx35-gpio", .data = &mxc_gpio_devtype[IMX35_GPIO], },
 	{ /* sentinel */ }
 };
 
@@ -160,15 +184,19 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type)
 		edge = GPIO_INT_FALL_EDGE;
 		break;
 	case IRQ_TYPE_EDGE_BOTH:
-		val = gpio_get_value(gpio);
-		if (val) {
-			edge = GPIO_INT_LOW_LEV;
-			pr_debug("mxc: set GPIO %d to low trigger\n", gpio);
+		if (GPIO_EDGE_SEL >= 0) {
+			edge = GPIO_INT_BOTH_EDGES;
 		} else {
-			edge = GPIO_INT_HIGH_LEV;
-			pr_debug("mxc: set GPIO %d to high trigger\n", gpio);
+			val = gpio_get_value(gpio);
+			if (val) {
+				edge = GPIO_INT_LOW_LEV;
+				pr_debug("mxc: set GPIO %d to low trigger\n", gpio);
+			} else {
+				edge = GPIO_INT_HIGH_LEV;
+				pr_debug("mxc: set GPIO %d to high trigger\n", gpio);
+			}
+			port->both_edges |= 1 << (gpio & 31);
 		}
-		port->both_edges |= 1 << (gpio & 31);
 		break;
 	case IRQ_TYPE_LEVEL_LOW:
 		edge = GPIO_INT_LOW_LEV;
@@ -180,10 +208,23 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type)
 		return -EINVAL;
 	}
 
-	reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
-	bit = gpio & 0xf;
-	val = readl(reg) & ~(0x3 << (bit << 1));
-	writel(val | (edge << (bit << 1)), reg);
+	if (GPIO_EDGE_SEL >= 0) {
+		val = readl(port->base + GPIO_EDGE_SEL);
+		if (edge == GPIO_INT_BOTH_EDGES)
+			writel(val | (1 << (gpio & 0x1f)),
+				port->base + GPIO_EDGE_SEL);
+		else
+			writel(val & ~(1 << (gpio & 0x1f)),
+				port->base + GPIO_EDGE_SEL);
+	}
+
+	if (edge != GPIO_INT_BOTH_EDGES) {
+		reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
+		bit = gpio & 0xf;
+		val = readl(reg) & ~(0x3 << (bit << 1));
+		writel(val | (edge << (bit << 1)), reg);
+	}
+
 	writel(1 << (gpio & 0x1f), port->base + GPIO_ISR);
 
 	return 0;
@@ -338,7 +379,9 @@ static void __devinit mxc_gpio_get_hw(struct platform_device *pdev)
 		return;
 	}
 
-	if (hwtype == IMX31_GPIO)
+	if (hwtype == IMX35_GPIO)
+		mxc_gpio_hwdata = &imx35_gpio_hwdata;
+	else if (hwtype == IMX31_GPIO)
 		mxc_gpio_hwdata = &imx31_gpio_hwdata;
 	else
 		mxc_gpio_hwdata = &imx1_imx21_gpio_hwdata;

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

* [PATCH] gpio/mxc: use the edge_sel feature if available
  2012-06-22 19:04       ` Benoît Thébaudeau
@ 2012-06-27  6:59         ` Sascha Hauer
  2012-07-05 13:51           ` Linus Walleij
  0 siblings, 1 reply; 15+ messages in thread
From: Sascha Hauer @ 2012-06-27  6:59 UTC (permalink / raw)
  To: linux-arm-kernel

On Fri, Jun 22, 2012 at 09:04:06PM +0200, Beno?t Th?baudeau wrote:
> 
> [PATCH] gpio/mxc: use the edge_sel feature if available
> 
> Some mxc processors have an edge_sel feature, which allows the IRQ to be
> triggered by any edge.
> 
> This patch makes use of this feature if available, which skips mxc_flip_edge().
> 
> Cc: Grant Likely <grant.likely@secretlab.ca>
> Cc: Linus Walleij <linus.walleij@stericsson.com>
> Cc: Sascha Hauer <kernel@pengutronix.de>
> Cc: <linux-arm-kernel@lists.infradead.org>
> Signed-off-by: Beno?t Th?baudeau <benoit.thebaudeau@advansee.com>

Acked-by: Sascha Hauer <s.hauer@pengutronix.de>

Grant, Linus, this should probably go through your gpio tree.

Sascha

> ---
>  .../devicetree/bindings/gpio/fsl-imx-gpio.txt      |    2 +-
>  .../arch/arm/boot/dts/imx51.dtsi                   |    8 +--
>  .../arch/arm/boot/dts/imx53.dtsi                   |   14 ++--
>  .../arch/arm/boot/dts/imx6q.dtsi                   |   14 ++--
>  .../arch/arm/mach-imx/mm-imx25.c                   |   10 +--
>  .../arch/arm/mach-imx/mm-imx3.c                    |    7 +-
>  .../arch/arm/mach-imx/mm-imx5.c                    |   40 +++++------
>  .../drivers/gpio/gpio-mxc.c                        |   71 ++++++++++++++++----
>  8 files changed, 104 insertions(+), 62 deletions(-)
> 
> diff --git linux-next-HEAD-072e7c8.orig/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt linux-next-HEAD-072e7c8/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt
> index 4363ae4..33a0345 100644
> --- linux-next-HEAD-072e7c8.orig/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt
> +++ linux-next-HEAD-072e7c8/Documentation/devicetree/bindings/gpio/fsl-imx-gpio.txt
> @@ -14,7 +14,7 @@ Required properties:
>  Example:
>  
>  gpio0: gpio at 73f84000 {
> -	compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
> +	compatible = "fsl,imx51-gpio", "fsl,imx35-gpio";
>  	reg = <0x73f84000 0x4000>;
>  	interrupts = <50 51>;
>  	gpio-controller;
> diff --git linux-next-HEAD-072e7c8.orig/arch/arm/boot/dts/imx51.dtsi linux-next-HEAD-072e7c8/arch/arm/boot/dts/imx51.dtsi
> index 39eb88e..5236e42 100644
> --- linux-next-HEAD-072e7c8.orig/arch/arm/boot/dts/imx51.dtsi
> +++ linux-next-HEAD-072e7c8/arch/arm/boot/dts/imx51.dtsi
> @@ -127,7 +127,7 @@
>  			};
>  
>  			gpio1: gpio at 73f84000 {
> -				compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
> +				compatible = "fsl,imx51-gpio", "fsl,imx35-gpio";
>  				reg = <0x73f84000 0x4000>;
>  				interrupts = <50 51>;
>  				gpio-controller;
> @@ -137,7 +137,7 @@
>  			};
>  
>  			gpio2: gpio at 73f88000 {
> -				compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
> +				compatible = "fsl,imx51-gpio", "fsl,imx35-gpio";
>  				reg = <0x73f88000 0x4000>;
>  				interrupts = <52 53>;
>  				gpio-controller;
> @@ -147,7 +147,7 @@
>  			};
>  
>  			gpio3: gpio at 73f8c000 {
> -				compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
> +				compatible = "fsl,imx51-gpio", "fsl,imx35-gpio";
>  				reg = <0x73f8c000 0x4000>;
>  				interrupts = <54 55>;
>  				gpio-controller;
> @@ -157,7 +157,7 @@
>  			};
>  
>  			gpio4: gpio at 73f90000 {
> -				compatible = "fsl,imx51-gpio", "fsl,imx31-gpio";
> +				compatible = "fsl,imx51-gpio", "fsl,imx35-gpio";
>  				reg = <0x73f90000 0x4000>;
>  				interrupts = <56 57>;
>  				gpio-controller;
> diff --git linux-next-HEAD-072e7c8.orig/arch/arm/boot/dts/imx53.dtsi linux-next-HEAD-072e7c8/arch/arm/boot/dts/imx53.dtsi
> index 2b5caf9..39ea1a5 100644
> --- linux-next-HEAD-072e7c8.orig/arch/arm/boot/dts/imx53.dtsi
> +++ linux-next-HEAD-072e7c8/arch/arm/boot/dts/imx53.dtsi
> @@ -129,7 +129,7 @@
>  			};
>  
>  			gpio1: gpio at 53f84000 {
> -				compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
> +				compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
>  				reg = <0x53f84000 0x4000>;
>  				interrupts = <50 51>;
>  				gpio-controller;
> @@ -139,7 +139,7 @@
>  			};
>  
>  			gpio2: gpio at 53f88000 {
> -				compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
> +				compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
>  				reg = <0x53f88000 0x4000>;
>  				interrupts = <52 53>;
>  				gpio-controller;
> @@ -149,7 +149,7 @@
>  			};
>  
>  			gpio3: gpio at 53f8c000 {
> -				compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
> +				compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
>  				reg = <0x53f8c000 0x4000>;
>  				interrupts = <54 55>;
>  				gpio-controller;
> @@ -159,7 +159,7 @@
>  			};
>  
>  			gpio4: gpio at 53f90000 {
> -				compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
> +				compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
>  				reg = <0x53f90000 0x4000>;
>  				interrupts = <56 57>;
>  				gpio-controller;
> @@ -197,7 +197,7 @@
>  			};
>  
>  			gpio5: gpio at 53fdc000 {
> -				compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
> +				compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
>  				reg = <0x53fdc000 0x4000>;
>  				interrupts = <103 104>;
>  				gpio-controller;
> @@ -207,7 +207,7 @@
>  			};
>  
>  			gpio6: gpio at 53fe0000 {
> -				compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
> +				compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
>  				reg = <0x53fe0000 0x4000>;
>  				interrupts = <105 106>;
>  				gpio-controller;
> @@ -217,7 +217,7 @@
>  			};
>  
>  			gpio7: gpio at 53fe4000 {
> -				compatible = "fsl,imx53-gpio", "fsl,imx31-gpio";
> +				compatible = "fsl,imx53-gpio", "fsl,imx35-gpio";
>  				reg = <0x53fe4000 0x4000>;
>  				interrupts = <107 108>;
>  				gpio-controller;
> diff --git linux-next-HEAD-072e7c8.orig/arch/arm/boot/dts/imx6q.dtsi linux-next-HEAD-072e7c8/arch/arm/boot/dts/imx6q.dtsi
> index 8c90cba..da78fd8 100644
> --- linux-next-HEAD-072e7c8.orig/arch/arm/boot/dts/imx6q.dtsi
> +++ linux-next-HEAD-072e7c8/arch/arm/boot/dts/imx6q.dtsi
> @@ -260,7 +260,7 @@
>  			};
>  
>  			gpio1: gpio at 0209c000 {
> -				compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
> +				compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
>  				reg = <0x0209c000 0x4000>;
>  				interrupts = <0 66 0x04 0 67 0x04>;
>  				gpio-controller;
> @@ -270,7 +270,7 @@
>  			};
>  
>  			gpio2: gpio at 020a0000 {
> -				compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
> +				compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
>  				reg = <0x020a0000 0x4000>;
>  				interrupts = <0 68 0x04 0 69 0x04>;
>  				gpio-controller;
> @@ -280,7 +280,7 @@
>  			};
>  
>  			gpio3: gpio at 020a4000 {
> -				compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
> +				compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
>  				reg = <0x020a4000 0x4000>;
>  				interrupts = <0 70 0x04 0 71 0x04>;
>  				gpio-controller;
> @@ -290,7 +290,7 @@
>  			};
>  
>  			gpio4: gpio at 020a8000 {
> -				compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
> +				compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
>  				reg = <0x020a8000 0x4000>;
>  				interrupts = <0 72 0x04 0 73 0x04>;
>  				gpio-controller;
> @@ -300,7 +300,7 @@
>  			};
>  
>  			gpio5: gpio at 020ac000 {
> -				compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
> +				compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
>  				reg = <0x020ac000 0x4000>;
>  				interrupts = <0 74 0x04 0 75 0x04>;
>  				gpio-controller;
> @@ -310,7 +310,7 @@
>  			};
>  
>  			gpio6: gpio at 020b0000 {
> -				compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
> +				compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
>  				reg = <0x020b0000 0x4000>;
>  				interrupts = <0 76 0x04 0 77 0x04>;
>  				gpio-controller;
> @@ -320,7 +320,7 @@
>  			};
>  
>  			gpio7: gpio at 020b4000 {
> -				compatible = "fsl,imx6q-gpio", "fsl,imx31-gpio";
> +				compatible = "fsl,imx6q-gpio", "fsl,imx35-gpio";
>  				reg = <0x020b4000 0x4000>;
>  				interrupts = <0 78 0x04 0 79 0x04>;
>  				gpio-controller;
> diff --git linux-next-HEAD-072e7c8.orig/arch/arm/mach-imx/mm-imx25.c linux-next-HEAD-072e7c8/arch/arm/mach-imx/mm-imx25.c
> index 6ff3714..8e8ddb8 100644
> --- linux-next-HEAD-072e7c8.orig/arch/arm/mach-imx/mm-imx25.c
> +++ linux-next-HEAD-072e7c8/arch/arm/mach-imx/mm-imx25.c
> @@ -90,11 +90,11 @@ static const struct resource imx25_audmux_res[] __initconst = {
>  
>  void __init imx25_soc_init(void)
>  {
> -	/* i.mx25 has the i.mx31 type gpio */
> -	mxc_register_gpio("imx31-gpio", 0, MX25_GPIO1_BASE_ADDR, SZ_16K, MX25_INT_GPIO1, 0);
> -	mxc_register_gpio("imx31-gpio", 1, MX25_GPIO2_BASE_ADDR, SZ_16K, MX25_INT_GPIO2, 0);
> -	mxc_register_gpio("imx31-gpio", 2, MX25_GPIO3_BASE_ADDR, SZ_16K, MX25_INT_GPIO3, 0);
> -	mxc_register_gpio("imx31-gpio", 3, MX25_GPIO4_BASE_ADDR, SZ_16K, MX25_INT_GPIO4, 0);
> +	/* i.mx25 has the i.mx35 type gpio */
> +	mxc_register_gpio("imx35-gpio", 0, MX25_GPIO1_BASE_ADDR, SZ_16K, MX25_INT_GPIO1, 0);
> +	mxc_register_gpio("imx35-gpio", 1, MX25_GPIO2_BASE_ADDR, SZ_16K, MX25_INT_GPIO2, 0);
> +	mxc_register_gpio("imx35-gpio", 2, MX25_GPIO3_BASE_ADDR, SZ_16K, MX25_INT_GPIO3, 0);
> +	mxc_register_gpio("imx35-gpio", 3, MX25_GPIO4_BASE_ADDR, SZ_16K, MX25_INT_GPIO4, 0);
>  
>  	pinctrl_provide_dummies();
>  	/* i.mx25 has the i.mx35 type sdma */
> diff --git linux-next-HEAD-072e7c8.orig/arch/arm/mach-imx/mm-imx3.c linux-next-HEAD-072e7c8/arch/arm/mach-imx/mm-imx3.c
> index a8983b9..8e51e77 100644
> --- linux-next-HEAD-072e7c8.orig/arch/arm/mach-imx/mm-imx3.c
> +++ linux-next-HEAD-072e7c8/arch/arm/mach-imx/mm-imx3.c
> @@ -273,10 +273,9 @@ void __init imx35_soc_init(void)
>  
>  	imx3_init_l2x0();
>  
> -	/* i.mx35 has the i.mx31 type gpio */
> -	mxc_register_gpio("imx31-gpio", 0, MX35_GPIO1_BASE_ADDR, SZ_16K, MX35_INT_GPIO1, 0);
> -	mxc_register_gpio("imx31-gpio", 1, MX35_GPIO2_BASE_ADDR, SZ_16K, MX35_INT_GPIO2, 0);
> -	mxc_register_gpio("imx31-gpio", 2, MX35_GPIO3_BASE_ADDR, SZ_16K, MX35_INT_GPIO3, 0);
> +	mxc_register_gpio("imx35-gpio", 0, MX35_GPIO1_BASE_ADDR, SZ_16K, MX35_INT_GPIO1, 0);
> +	mxc_register_gpio("imx35-gpio", 1, MX35_GPIO2_BASE_ADDR, SZ_16K, MX35_INT_GPIO2, 0);
> +	mxc_register_gpio("imx35-gpio", 2, MX35_GPIO3_BASE_ADDR, SZ_16K, MX35_INT_GPIO3, 0);
>  
>  	pinctrl_provide_dummies();
>  	if (to_version == 1) {
> diff --git linux-next-HEAD-072e7c8.orig/arch/arm/mach-imx/mm-imx5.c linux-next-HEAD-072e7c8/arch/arm/mach-imx/mm-imx5.c
> index 1d00305..d70d16c 100644
> --- linux-next-HEAD-072e7c8.orig/arch/arm/mach-imx/mm-imx5.c
> +++ linux-next-HEAD-072e7c8/arch/arm/mach-imx/mm-imx5.c
> @@ -181,13 +181,13 @@ static const struct resource imx53_audmux_res[] __initconst = {
>  
>  void __init imx50_soc_init(void)
>  {
> -	/* i.mx50 has the i.mx31 type gpio */
> -	mxc_register_gpio("imx31-gpio", 0, MX50_GPIO1_BASE_ADDR, SZ_16K, MX50_INT_GPIO1_LOW, MX50_INT_GPIO1_HIGH);
> -	mxc_register_gpio("imx31-gpio", 1, MX50_GPIO2_BASE_ADDR, SZ_16K, MX50_INT_GPIO2_LOW, MX50_INT_GPIO2_HIGH);
> -	mxc_register_gpio("imx31-gpio", 2, MX50_GPIO3_BASE_ADDR, SZ_16K, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH);
> -	mxc_register_gpio("imx31-gpio", 3, MX50_GPIO4_BASE_ADDR, SZ_16K, MX50_INT_GPIO4_LOW, MX50_INT_GPIO4_HIGH);
> -	mxc_register_gpio("imx31-gpio", 4, MX50_GPIO5_BASE_ADDR, SZ_16K, MX50_INT_GPIO5_LOW, MX50_INT_GPIO5_HIGH);
> -	mxc_register_gpio("imx31-gpio", 5, MX50_GPIO6_BASE_ADDR, SZ_16K, MX50_INT_GPIO6_LOW, MX50_INT_GPIO6_HIGH);
> +	/* i.mx50 has the i.mx35 type gpio */
> +	mxc_register_gpio("imx35-gpio", 0, MX50_GPIO1_BASE_ADDR, SZ_16K, MX50_INT_GPIO1_LOW, MX50_INT_GPIO1_HIGH);
> +	mxc_register_gpio("imx35-gpio", 1, MX50_GPIO2_BASE_ADDR, SZ_16K, MX50_INT_GPIO2_LOW, MX50_INT_GPIO2_HIGH);
> +	mxc_register_gpio("imx35-gpio", 2, MX50_GPIO3_BASE_ADDR, SZ_16K, MX50_INT_GPIO3_LOW, MX50_INT_GPIO3_HIGH);
> +	mxc_register_gpio("imx35-gpio", 3, MX50_GPIO4_BASE_ADDR, SZ_16K, MX50_INT_GPIO4_LOW, MX50_INT_GPIO4_HIGH);
> +	mxc_register_gpio("imx35-gpio", 4, MX50_GPIO5_BASE_ADDR, SZ_16K, MX50_INT_GPIO5_LOW, MX50_INT_GPIO5_HIGH);
> +	mxc_register_gpio("imx35-gpio", 5, MX50_GPIO6_BASE_ADDR, SZ_16K, MX50_INT_GPIO6_LOW, MX50_INT_GPIO6_HIGH);
>  
>  	/* i.mx50 has the i.mx31 type audmux */
>  	platform_device_register_simple("imx31-audmux", 0, imx50_audmux_res,
> @@ -196,11 +196,11 @@ void __init imx50_soc_init(void)
>  
>  void __init imx51_soc_init(void)
>  {
> -	/* i.mx51 has the i.mx31 type gpio */
> -	mxc_register_gpio("imx31-gpio", 0, MX51_GPIO1_BASE_ADDR, SZ_16K, MX51_INT_GPIO1_LOW, MX51_INT_GPIO1_HIGH);
> -	mxc_register_gpio("imx31-gpio", 1, MX51_GPIO2_BASE_ADDR, SZ_16K, MX51_INT_GPIO2_LOW, MX51_INT_GPIO2_HIGH);
> -	mxc_register_gpio("imx31-gpio", 2, MX51_GPIO3_BASE_ADDR, SZ_16K, MX51_INT_GPIO3_LOW, MX51_INT_GPIO3_HIGH);
> -	mxc_register_gpio("imx31-gpio", 3, MX51_GPIO4_BASE_ADDR, SZ_16K, MX51_INT_GPIO4_LOW, MX51_INT_GPIO4_HIGH);
> +	/* i.mx51 has the i.mx35 type gpio */
> +	mxc_register_gpio("imx35-gpio", 0, MX51_GPIO1_BASE_ADDR, SZ_16K, MX51_INT_GPIO1_LOW, MX51_INT_GPIO1_HIGH);
> +	mxc_register_gpio("imx35-gpio", 1, MX51_GPIO2_BASE_ADDR, SZ_16K, MX51_INT_GPIO2_LOW, MX51_INT_GPIO2_HIGH);
> +	mxc_register_gpio("imx35-gpio", 2, MX51_GPIO3_BASE_ADDR, SZ_16K, MX51_INT_GPIO3_LOW, MX51_INT_GPIO3_HIGH);
> +	mxc_register_gpio("imx35-gpio", 3, MX51_GPIO4_BASE_ADDR, SZ_16K, MX51_INT_GPIO4_LOW, MX51_INT_GPIO4_HIGH);
>  
>  	pinctrl_provide_dummies();
>  
> @@ -218,14 +218,14 @@ void __init imx51_soc_init(void)
>  
>  void __init imx53_soc_init(void)
>  {
> -	/* i.mx53 has the i.mx31 type gpio */
> -	mxc_register_gpio("imx31-gpio", 0, MX53_GPIO1_BASE_ADDR, SZ_16K, MX53_INT_GPIO1_LOW, MX53_INT_GPIO1_HIGH);
> -	mxc_register_gpio("imx31-gpio", 1, MX53_GPIO2_BASE_ADDR, SZ_16K, MX53_INT_GPIO2_LOW, MX53_INT_GPIO2_HIGH);
> -	mxc_register_gpio("imx31-gpio", 2, MX53_GPIO3_BASE_ADDR, SZ_16K, MX53_INT_GPIO3_LOW, MX53_INT_GPIO3_HIGH);
> -	mxc_register_gpio("imx31-gpio", 3, MX53_GPIO4_BASE_ADDR, SZ_16K, MX53_INT_GPIO4_LOW, MX53_INT_GPIO4_HIGH);
> -	mxc_register_gpio("imx31-gpio", 4, MX53_GPIO5_BASE_ADDR, SZ_16K, MX53_INT_GPIO5_LOW, MX53_INT_GPIO5_HIGH);
> -	mxc_register_gpio("imx31-gpio", 5, MX53_GPIO6_BASE_ADDR, SZ_16K, MX53_INT_GPIO6_LOW, MX53_INT_GPIO6_HIGH);
> -	mxc_register_gpio("imx31-gpio", 6, MX53_GPIO7_BASE_ADDR, SZ_16K, MX53_INT_GPIO7_LOW, MX53_INT_GPIO7_HIGH);
> +	/* i.mx53 has the i.mx35 type gpio */
> +	mxc_register_gpio("imx35-gpio", 0, MX53_GPIO1_BASE_ADDR, SZ_16K, MX53_INT_GPIO1_LOW, MX53_INT_GPIO1_HIGH);
> +	mxc_register_gpio("imx35-gpio", 1, MX53_GPIO2_BASE_ADDR, SZ_16K, MX53_INT_GPIO2_LOW, MX53_INT_GPIO2_HIGH);
> +	mxc_register_gpio("imx35-gpio", 2, MX53_GPIO3_BASE_ADDR, SZ_16K, MX53_INT_GPIO3_LOW, MX53_INT_GPIO3_HIGH);
> +	mxc_register_gpio("imx35-gpio", 3, MX53_GPIO4_BASE_ADDR, SZ_16K, MX53_INT_GPIO4_LOW, MX53_INT_GPIO4_HIGH);
> +	mxc_register_gpio("imx35-gpio", 4, MX53_GPIO5_BASE_ADDR, SZ_16K, MX53_INT_GPIO5_LOW, MX53_INT_GPIO5_HIGH);
> +	mxc_register_gpio("imx35-gpio", 5, MX53_GPIO6_BASE_ADDR, SZ_16K, MX53_INT_GPIO6_LOW, MX53_INT_GPIO6_HIGH);
> +	mxc_register_gpio("imx35-gpio", 6, MX53_GPIO7_BASE_ADDR, SZ_16K, MX53_INT_GPIO7_LOW, MX53_INT_GPIO7_HIGH);
>  
>  	pinctrl_provide_dummies();
>  	/* i.mx53 has the i.mx35 type sdma */
> diff --git linux-next-HEAD-072e7c8.orig/drivers/gpio/gpio-mxc.c linux-next-HEAD-072e7c8/drivers/gpio/gpio-mxc.c
> index c337143..bb985e8 100644
> --- linux-next-HEAD-072e7c8.orig/drivers/gpio/gpio-mxc.c
> +++ linux-next-HEAD-072e7c8/drivers/gpio/gpio-mxc.c
> @@ -38,7 +38,8 @@
>  enum mxc_gpio_hwtype {
>  	IMX1_GPIO,	/* runs on i.mx1 */
>  	IMX21_GPIO,	/* runs on i.mx21 and i.mx27 */
> -	IMX31_GPIO,	/* runs on all other i.mx */
> +	IMX31_GPIO,	/* runs on i.mx31 */
> +	IMX35_GPIO,	/* runs on all other i.mx */
>  };
>  
>  /* device type dependent stuff */
> @@ -50,6 +51,7 @@ struct mxc_gpio_hwdata {
>  	unsigned icr2_reg;
>  	unsigned imr_reg;
>  	unsigned isr_reg;
> +	int edge_sel_reg;
>  	unsigned low_level;
>  	unsigned high_level;
>  	unsigned rise_edge;
> @@ -74,6 +76,7 @@ static struct mxc_gpio_hwdata imx1_imx21_gpio_hwdata = {
>  	.icr2_reg	= 0x2c,
>  	.imr_reg	= 0x30,
>  	.isr_reg	= 0x34,
> +	.edge_sel_reg	= -EINVAL,
>  	.low_level	= 0x03,
>  	.high_level	= 0x02,
>  	.rise_edge	= 0x00,
> @@ -88,6 +91,22 @@ static struct mxc_gpio_hwdata imx31_gpio_hwdata = {
>  	.icr2_reg	= 0x10,
>  	.imr_reg	= 0x14,
>  	.isr_reg	= 0x18,
> +	.edge_sel_reg	= -EINVAL,
> +	.low_level	= 0x00,
> +	.high_level	= 0x01,
> +	.rise_edge	= 0x02,
> +	.fall_edge	= 0x03,
> +};
> +
> +static struct mxc_gpio_hwdata imx35_gpio_hwdata = {
> +	.dr_reg		= 0x00,
> +	.gdir_reg	= 0x04,
> +	.psr_reg	= 0x08,
> +	.icr1_reg	= 0x0c,
> +	.icr2_reg	= 0x10,
> +	.imr_reg	= 0x14,
> +	.isr_reg	= 0x18,
> +	.edge_sel_reg	= 0x1c,
>  	.low_level	= 0x00,
>  	.high_level	= 0x01,
>  	.rise_edge	= 0x02,
> @@ -104,12 +123,13 @@ static struct mxc_gpio_hwdata *mxc_gpio_hwdata;
>  #define GPIO_ICR2		(mxc_gpio_hwdata->icr2_reg)
>  #define GPIO_IMR		(mxc_gpio_hwdata->imr_reg)
>  #define GPIO_ISR		(mxc_gpio_hwdata->isr_reg)
> +#define GPIO_EDGE_SEL		(mxc_gpio_hwdata->edge_sel_reg)
>  
>  #define GPIO_INT_LOW_LEV	(mxc_gpio_hwdata->low_level)
>  #define GPIO_INT_HIGH_LEV	(mxc_gpio_hwdata->high_level)
>  #define GPIO_INT_RISE_EDGE	(mxc_gpio_hwdata->rise_edge)
>  #define GPIO_INT_FALL_EDGE	(mxc_gpio_hwdata->fall_edge)
> -#define GPIO_INT_NONE		0x4
> +#define GPIO_INT_BOTH_EDGES	0x4
>  
>  static struct platform_device_id mxc_gpio_devtype[] = {
>  	{
> @@ -122,6 +142,9 @@ static struct platform_device_id mxc_gpio_devtype[] = {
>  		.name = "imx31-gpio",
>  		.driver_data = IMX31_GPIO,
>  	}, {
> +		.name = "imx35-gpio",
> +		.driver_data = IMX35_GPIO,
> +	}, {
>  		/* sentinel */
>  	}
>  };
> @@ -130,6 +153,7 @@ static const struct of_device_id mxc_gpio_dt_ids[] = {
>  	{ .compatible = "fsl,imx1-gpio", .data = &mxc_gpio_devtype[IMX1_GPIO], },
>  	{ .compatible = "fsl,imx21-gpio", .data = &mxc_gpio_devtype[IMX21_GPIO], },
>  	{ .compatible = "fsl,imx31-gpio", .data = &mxc_gpio_devtype[IMX31_GPIO], },
> +	{ .compatible = "fsl,imx35-gpio", .data = &mxc_gpio_devtype[IMX35_GPIO], },
>  	{ /* sentinel */ }
>  };
>  
> @@ -160,15 +184,19 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type)
>  		edge = GPIO_INT_FALL_EDGE;
>  		break;
>  	case IRQ_TYPE_EDGE_BOTH:
> -		val = gpio_get_value(gpio);
> -		if (val) {
> -			edge = GPIO_INT_LOW_LEV;
> -			pr_debug("mxc: set GPIO %d to low trigger\n", gpio);
> +		if (GPIO_EDGE_SEL >= 0) {
> +			edge = GPIO_INT_BOTH_EDGES;
>  		} else {
> -			edge = GPIO_INT_HIGH_LEV;
> -			pr_debug("mxc: set GPIO %d to high trigger\n", gpio);
> +			val = gpio_get_value(gpio);
> +			if (val) {
> +				edge = GPIO_INT_LOW_LEV;
> +				pr_debug("mxc: set GPIO %d to low trigger\n", gpio);
> +			} else {
> +				edge = GPIO_INT_HIGH_LEV;
> +				pr_debug("mxc: set GPIO %d to high trigger\n", gpio);
> +			}
> +			port->both_edges |= 1 << (gpio & 31);
>  		}
> -		port->both_edges |= 1 << (gpio & 31);
>  		break;
>  	case IRQ_TYPE_LEVEL_LOW:
>  		edge = GPIO_INT_LOW_LEV;
> @@ -180,10 +208,23 @@ static int gpio_set_irq_type(struct irq_data *d, u32 type)
>  		return -EINVAL;
>  	}
>  
> -	reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
> -	bit = gpio & 0xf;
> -	val = readl(reg) & ~(0x3 << (bit << 1));
> -	writel(val | (edge << (bit << 1)), reg);
> +	if (GPIO_EDGE_SEL >= 0) {
> +		val = readl(port->base + GPIO_EDGE_SEL);
> +		if (edge == GPIO_INT_BOTH_EDGES)
> +			writel(val | (1 << (gpio & 0x1f)),
> +				port->base + GPIO_EDGE_SEL);
> +		else
> +			writel(val & ~(1 << (gpio & 0x1f)),
> +				port->base + GPIO_EDGE_SEL);
> +	}
> +
> +	if (edge != GPIO_INT_BOTH_EDGES) {
> +		reg += GPIO_ICR1 + ((gpio & 0x10) >> 2); /* lower or upper register */
> +		bit = gpio & 0xf;
> +		val = readl(reg) & ~(0x3 << (bit << 1));
> +		writel(val | (edge << (bit << 1)), reg);
> +	}
> +
>  	writel(1 << (gpio & 0x1f), port->base + GPIO_ISR);
>  
>  	return 0;
> @@ -338,7 +379,9 @@ static void __devinit mxc_gpio_get_hw(struct platform_device *pdev)
>  		return;
>  	}
>  
> -	if (hwtype == IMX31_GPIO)
> +	if (hwtype == IMX35_GPIO)
> +		mxc_gpio_hwdata = &imx35_gpio_hwdata;
> +	else if (hwtype == IMX31_GPIO)
>  		mxc_gpio_hwdata = &imx31_gpio_hwdata;
>  	else
>  		mxc_gpio_hwdata = &imx1_imx21_gpio_hwdata;
> 

-- 
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] 15+ messages in thread

* [PATCH] gpio/mxc: use the edge_sel feature if available
  2012-06-27  6:59         ` Sascha Hauer
@ 2012-07-05 13:51           ` Linus Walleij
  0 siblings, 0 replies; 15+ messages in thread
From: Linus Walleij @ 2012-07-05 13:51 UTC (permalink / raw)
  To: linux-arm-kernel

On Wed, Jun 27, 2012 at 8:59 AM, Sascha Hauer <s.hauer@pengutronix.de> wrote:
> On Fri, Jun 22, 2012 at 09:04:06PM +0200, Beno?t Th?baudeau wrote:

>> [PATCH] gpio/mxc: use the edge_sel feature if available
>>
>> Some mxc processors have an edge_sel feature, which allows the IRQ to be
>> triggered by any edge.
>>
>> This patch makes use of this feature if available, which skips mxc_flip_edge().
>>
>> Cc: Grant Likely <grant.likely@secretlab.ca>
>> Cc: Linus Walleij <linus.walleij@stericsson.com>
>> Cc: Sascha Hauer <kernel@pengutronix.de>
>> Cc: <linux-arm-kernel@lists.infradead.org>
>> Signed-off-by: Beno?t Th?baudeau <benoit.thebaudeau@advansee.com>
>
> Acked-by: Sascha Hauer <s.hauer@pengutronix.de>
>
> Grant, Linus, this should probably go through your gpio tree.

OK applied.

Make sure to check in linux-next that I got it right.

Yours,
Linus Walleij

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

end of thread, other threads:[~2012-07-05 13:51 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-06-18 19:57 [PATCH] gpio/mxc: use the edge_sel feature if available Benoît Thébaudeau
2012-06-19  1:24 ` Shawn Guo
2012-06-19 12:00   ` Benoît Thébaudeau
2012-06-19 13:18     ` Benoît Thébaudeau
2012-06-20  8:35     ` Linus Walleij
2012-06-20  9:21       ` Sascha Hauer
2012-06-20  9:19 ` Sascha Hauer
2012-06-20 18:27   ` Benoît Thébaudeau
2012-06-20 18:36     ` Benoît Thébaudeau
2012-06-21  6:43     ` Sascha Hauer
2012-06-21 11:23       ` Benoît Thébaudeau
2012-06-22 13:46     ` Guennadi Liakhovetski
2012-06-22 19:04       ` Benoît Thébaudeau
2012-06-27  6:59         ` Sascha Hauer
2012-07-05 13:51           ` Linus Walleij

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).