Patchwork [1/6] gpio/mxs: adopt irq_domain support for mxs gpio driver

login
register
mail settings
Submitter Shawn Guo
Date Aug. 20, 2012, 2:19 p.m.
Message ID <1345472400-31262-2-git-send-email-shawn.guo@linaro.org>
Download mbox | patch
Permalink /patch/178836/
State New
Headers show

Comments

Shawn Guo - Aug. 20, 2012, 2:19 p.m.
Remove irq_domain_add_legacy call from mach-mxs.c and have the gpio
driver adopt irqdomain support, so that we can have the mapping
between gpio and irq number available without using virtual_irq_start
and MXS_GPIO_IRQ_START.

Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
Cc: Linus Walleij <linus.walleij@linaro.org>
---
 arch/arm/mach-mxs/mach-mxs.c |   12 ----------
 drivers/gpio/gpio-mxs.c      |   48 ++++++++++++++++++++++++++---------------
 2 files changed, 30 insertions(+), 30 deletions(-)
Linus Walleij - Aug. 21, 2012, 1:01 p.m.
On Mon, Aug 20, 2012 at 4:19 PM, Shawn Guo <shawn.guo@linaro.org> wrote:

> Remove irq_domain_add_legacy call from mach-mxs.c and have the gpio
> driver adopt irqdomain support, so that we can have the mapping
> between gpio and irq number available without using virtual_irq_start
> and MXS_GPIO_IRQ_START.

Seems like a good thing to do, but with Grant and Rob being better at
irqdomain than me I'd prefer one of them to have a look at this too.

> +       irq_base = irq_alloc_descs(-1, 0, 32, numa_node_id());
> +       if (irq_base < 0)
> +               return irq_base;
> +
> +       port->domain = irq_domain_add_legacy(np, 32, irq_base, 0,
> +                                            &irq_domain_simple_ops, NULL);

For example I want to understand if it'd be possible to use a
linear domain here.

Yours,
Linus Walleij
Rob Herring - Aug. 21, 2012, 1:16 p.m.
On 08/21/2012 08:01 AM, Linus Walleij wrote:
> On Mon, Aug 20, 2012 at 4:19 PM, Shawn Guo <shawn.guo@linaro.org> wrote:
> 
>> Remove irq_domain_add_legacy call from mach-mxs.c and have the gpio
>> driver adopt irqdomain support, so that we can have the mapping
>> between gpio and irq number available without using virtual_irq_start
>> and MXS_GPIO_IRQ_START.
> 
> Seems like a good thing to do, but with Grant and Rob being better at
> irqdomain than me I'd prefer one of them to have a look at this too.
> 
>> +       irq_base = irq_alloc_descs(-1, 0, 32, numa_node_id());
>> +       if (irq_base < 0)
>> +               return irq_base;
>> +
>> +       port->domain = irq_domain_add_legacy(np, 32, irq_base, 0,
>> +                                            &irq_domain_simple_ops, NULL);
> 
> For example I want to understand if it'd be possible to use a
> linear domain here.

Unfortunately, not if you care about your irq base and need sequential
irq numbers which is the case for non-DT.

Rob

> 
> Yours,
> Linus Walleij
> 
> _______________________________________________
> linux-arm-kernel mailing list
> linux-arm-kernel@lists.infradead.org
> http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
>
Shawn Guo - Aug. 22, 2012, 2:14 a.m.
On Tue, Aug 21, 2012 at 08:16:37AM -0500, Rob Herring wrote:
> On 08/21/2012 08:01 AM, Linus Walleij wrote:
> > On Mon, Aug 20, 2012 at 4:19 PM, Shawn Guo <shawn.guo@linaro.org> wrote:
> > 
> >> Remove irq_domain_add_legacy call from mach-mxs.c and have the gpio
> >> driver adopt irqdomain support, so that we can have the mapping
> >> between gpio and irq number available without using virtual_irq_start
> >> and MXS_GPIO_IRQ_START.
> > 
> > Seems like a good thing to do, but with Grant and Rob being better at
> > irqdomain than me I'd prefer one of them to have a look at this too.
> > 
> >> +       irq_base = irq_alloc_descs(-1, 0, 32, numa_node_id());
> >> +       if (irq_base < 0)
> >> +               return irq_base;
> >> +
> >> +       port->domain = irq_domain_add_legacy(np, 32, irq_base, 0,
> >> +                                            &irq_domain_simple_ops, NULL);
> > 
> > For example I want to understand if it'd be possible to use a
> > linear domain here.
> 
> Unfortunately, not if you care about your irq base and need sequential
> irq numbers which is the case for non-DT.
> 
Right.  For for this particular case, it's more because generic-chip
currently does not cope with the driver using linear domain.
Linus Walleij - Aug. 23, 2012, 9:49 p.m.
On Mon, Aug 20, 2012 at 4:19 PM, Shawn Guo <shawn.guo@linaro.org> wrote:

> Remove irq_domain_add_legacy call from mach-mxs.c and have the gpio
> driver adopt irqdomain support, so that we can have the mapping
> between gpio and irq number available without using virtual_irq_start
> and MXS_GPIO_IRQ_START.
>
> Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
> Cc: Linus Walleij <linus.walleij@linaro.org>

OK patch applied, thanks!

Yours,
Linus Walleij
Shawn Guo - Aug. 24, 2012, 1:09 a.m.
On Thu, Aug 23, 2012 at 11:49:50PM +0200, Linus Walleij wrote:
> On Mon, Aug 20, 2012 at 4:19 PM, Shawn Guo <shawn.guo@linaro.org> wrote:
> 
> > Remove irq_domain_add_legacy call from mach-mxs.c and have the gpio
> > driver adopt irqdomain support, so that we can have the mapping
> > between gpio and irq number available without using virtual_irq_start
> > and MXS_GPIO_IRQ_START.
> >
> > Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
> > Cc: Linus Walleij <linus.walleij@linaro.org>
> 
> OK patch applied, thanks!
> 
I was planning to have the patch to go via arm-soc tree with your ACK.
But it also works to have it on gpio tree and I ask arm-soc people to
pull gpio tree into arm-soc, but you need to ensure the branch is
stable (no rebase).
Linus Walleij - Aug. 31, 2012, 10:28 p.m.
On Fri, Aug 24, 2012 at 3:09 AM, Shawn Guo <shawn.guo@linaro.org> wrote:
> On Thu, Aug 23, 2012 at 11:49:50PM +0200, Linus Walleij wrote:
>> On Mon, Aug 20, 2012 at 4:19 PM, Shawn Guo <shawn.guo@linaro.org> wrote:
>>
>> > Remove irq_domain_add_legacy call from mach-mxs.c and have the gpio
>> > driver adopt irqdomain support, so that we can have the mapping
>> > between gpio and irq number available without using virtual_irq_start
>> > and MXS_GPIO_IRQ_START.
>> >
>> > Signed-off-by: Shawn Guo <shawn.guo@linaro.org>
>> > Cc: Linus Walleij <linus.walleij@linaro.org>
>>
>> OK patch applied, thanks!
>>
> I was planning to have the patch to go via arm-soc tree with your ACK.
> But it also works to have it on gpio tree and I ask arm-soc people to
> pull gpio tree into arm-soc, but you need to ensure the branch is
> stable (no rebase).

OK sorry (and sorry for the delay) I took the patch out again, please take
this through your tree as needed.

Acked-by: Linus Walleij <linus.walleij@linaro.org>

Yours.
Linus Walleij
Shawn Guo - Sept. 3, 2012, 12:28 a.m.
On Sat, Sep 01, 2012 at 12:28:29AM +0200, Linus Walleij wrote:
> OK sorry (and sorry for the delay) I took the patch out again, please take
> this through your tree as needed.
> 
Will do.

> Acked-by: Linus Walleij <linus.walleij@linaro.org>
> 
Thanks, Linus.

Patch

diff --git a/arch/arm/mach-mxs/mach-mxs.c b/arch/arm/mach-mxs/mach-mxs.c
index 3b0d9c6..9f8406e 100644
--- a/arch/arm/mach-mxs/mach-mxs.c
+++ b/arch/arm/mach-mxs/mach-mxs.c
@@ -149,20 +149,8 @@  static int __init mxs_icoll_add_irq_domain(struct device_node *np,
 	return 0;
 }
 
-static int __init mxs_gpio_add_irq_domain(struct device_node *np,
-				struct device_node *interrupt_parent)
-{
-	static int gpio_irq_base = MXS_GPIO_IRQ_START;
-
-	irq_domain_add_legacy(np, 32, gpio_irq_base, 0, &irq_domain_simple_ops, NULL);
-	gpio_irq_base += 32;
-
-	return 0;
-}
-
 static const struct of_device_id mxs_irq_match[] __initconst = {
 	{ .compatible = "fsl,mxs-icoll", .data = mxs_icoll_add_irq_domain, },
-	{ .compatible = "fsl,mxs-gpio", .data = mxs_gpio_add_irq_domain, },
 	{ /* sentinel */ }
 };
 
diff --git a/drivers/gpio/gpio-mxs.c b/drivers/gpio/gpio-mxs.c
index 39e4956..796fb13 100644
--- a/drivers/gpio/gpio-mxs.c
+++ b/drivers/gpio/gpio-mxs.c
@@ -24,6 +24,7 @@ 
 #include <linux/interrupt.h>
 #include <linux/io.h>
 #include <linux/irq.h>
+#include <linux/irqdomain.h>
 #include <linux/gpio.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
@@ -52,8 +53,6 @@ 
 #define GPIO_INT_LEV_MASK	(1 << 0)
 #define GPIO_INT_POL_MASK	(1 << 1)
 
-#define irq_to_gpio(irq)	((irq) - MXS_GPIO_IRQ_START)
-
 enum mxs_gpio_id {
 	IMX23_GPIO,
 	IMX28_GPIO,
@@ -63,7 +62,7 @@  struct mxs_gpio_port {
 	void __iomem *base;
 	int id;
 	int irq;
-	int virtual_irq_start;
+	struct irq_domain *domain;
 	struct bgpio_chip bgc;
 	enum mxs_gpio_id devid;
 };
@@ -82,8 +81,7 @@  static inline int is_imx28_gpio(struct mxs_gpio_port *port)
 
 static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type)
 {
-	u32 gpio = irq_to_gpio(d->irq);
-	u32 pin_mask = 1 << (gpio & 31);
+	u32 pin_mask = 1 << d->hwirq;
 	struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
 	struct mxs_gpio_port *port = gc->private;
 	void __iomem *pin_addr;
@@ -120,7 +118,7 @@  static int mxs_gpio_set_irq_type(struct irq_data *d, unsigned int type)
 	else
 		writel(pin_mask, pin_addr + MXS_CLR);
 
-	writel(1 << (gpio & 0x1f),
+	writel(pin_mask,
 	       port->base + PINCTRL_IRQSTAT(port) + MXS_CLR);
 
 	return 0;
@@ -131,7 +129,6 @@  static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc)
 {
 	u32 irq_stat;
 	struct mxs_gpio_port *port = irq_get_handler_data(irq);
-	u32 gpio_irq_no_base = port->virtual_irq_start;
 
 	desc->irq_data.chip->irq_ack(&desc->irq_data);
 
@@ -140,7 +137,7 @@  static void mxs_gpio_irq_handler(u32 irq, struct irq_desc *desc)
 
 	while (irq_stat != 0) {
 		int irqoffset = fls(irq_stat) - 1;
-		generic_handle_irq(gpio_irq_no_base + irqoffset);
+		generic_handle_irq(irq_find_mapping(port->domain, irqoffset));
 		irq_stat &= ~(1 << irqoffset);
 	}
 }
@@ -167,12 +164,12 @@  static int mxs_gpio_set_wake_irq(struct irq_data *d, unsigned int enable)
 	return 0;
 }
 
-static void __init mxs_gpio_init_gc(struct mxs_gpio_port *port)
+static void __init mxs_gpio_init_gc(struct mxs_gpio_port *port, int irq_base)
 {
 	struct irq_chip_generic *gc;
 	struct irq_chip_type *ct;
 
-	gc = irq_alloc_generic_chip("gpio-mxs", 1, port->virtual_irq_start,
+	gc = irq_alloc_generic_chip("gpio-mxs", 1, irq_base,
 				    port->base, handle_level_irq);
 	gc->private = port;
 
@@ -194,7 +191,7 @@  static int mxs_gpio_to_irq(struct gpio_chip *gc, unsigned offset)
 	struct mxs_gpio_port *port =
 		container_of(bgc, struct mxs_gpio_port, bgc);
 
-	return port->virtual_irq_start + offset;
+	return irq_find_mapping(port->domain, offset);
 }
 
 static struct platform_device_id mxs_gpio_ids[] = {
@@ -226,6 +223,7 @@  static int __devinit mxs_gpio_probe(struct platform_device *pdev)
 	static void __iomem *base;
 	struct mxs_gpio_port *port;
 	struct resource *iores = NULL;
+	int irq_base;
 	int err;
 
 	port = devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL);
@@ -241,7 +239,6 @@  static int __devinit mxs_gpio_probe(struct platform_device *pdev)
 		port->id = pdev->id;
 		port->devid = pdev->id_entry->driver_data;
 	}
-	port->virtual_irq_start = MXS_GPIO_IRQ_START + port->id * 32;
 
 	port->irq = platform_get_irq(pdev, 0);
 	if (port->irq < 0)
@@ -275,8 +272,19 @@  static int __devinit mxs_gpio_probe(struct platform_device *pdev)
 	/* clear address has to be used to clear IRQSTAT bits */
 	writel(~0U, port->base + PINCTRL_IRQSTAT(port) + MXS_CLR);
 
+	irq_base = irq_alloc_descs(-1, 0, 32, numa_node_id());
+	if (irq_base < 0)
+		return irq_base;
+
+	port->domain = irq_domain_add_legacy(np, 32, irq_base, 0,
+					     &irq_domain_simple_ops, NULL);
+	if (!port->domain) {
+		err = -ENODEV;
+		goto out_irqdesc_free;
+	}
+
 	/* gpio-mxs can be a generic irq chip */
-	mxs_gpio_init_gc(port);
+	mxs_gpio_init_gc(port, irq_base);
 
 	/* setup one handler for each entry */
 	irq_set_chained_handler(port->irq, mxs_gpio_irq_handler);
@@ -287,18 +295,22 @@  static int __devinit mxs_gpio_probe(struct platform_device *pdev)
 			 port->base + PINCTRL_DOUT(port), NULL,
 			 port->base + PINCTRL_DOE(port), NULL, 0);
 	if (err)
-		return err;
+		goto out_irqdesc_free;
 
 	port->bgc.gc.to_irq = mxs_gpio_to_irq;
 	port->bgc.gc.base = port->id * 32;
 
 	err = gpiochip_add(&port->bgc.gc);
-	if (err) {
-		bgpio_remove(&port->bgc);
-		return err;
-	}
+	if (err)
+		goto out_bgpio_remove;
 
 	return 0;
+
+out_bgpio_remove:
+	bgpio_remove(&port->bgc);
+out_irqdesc_free:
+	irq_free_descs(irq_base, 32);
+	return err;
 }
 
 static struct platform_driver mxs_gpio_driver = {