All of lore.kernel.org
 help / color / mirror / Atom feed
From: Grygorii Strashko <grygorii.strashko-l0cyMroinI0@public.gmane.org>
To: "Lad,
	Prabhakar"
	<prabhakar.csengg-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>,
	Sekhar Nori <nsekhar-l0cyMroinI0@public.gmane.org>,
	Linus Walleij
	<linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Cc: Mark Rutland <mark.rutland-5wv7dgnIgG8@public.gmane.org>,
	Alex Elder <alex.elder-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>,
	davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/@public.gmane.org,
	Russell King <linux-lFZ/pmaqli7XmaaqVzeoHQ@public.gmane.org>,
	Pawel Moll <pawel.moll-5wv7dgnIgG8@public.gmane.org>,
	Ian Campbell
	<ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg@public.gmane.org>,
	Stephen Warren <swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org>,
	linux-doc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Rob Herring <rob.herring-bsGFqQB8/DxBDgjK7y7TUQ@public.gmane.org>,
	linux-gpio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Rob Landley <rob-VoJi6FS/r0vR7s880joybQ@public.gmane.org>,
	Grant Likely
	<grant.likely-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>,
	linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org
Subject: Re: [PATCH v4 3/6] gpio: davinci: use irqdomain
Date: Mon, 4 Nov 2013 20:27:46 +0200	[thread overview]
Message-ID: <5277E722.50205@ti.com> (raw)
In-Reply-To: <1383406775-14902-4-git-send-email-prabhakar.csenng-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>

Hi Prabhakar Lad,

On 11/02/2013 05:39 PM, Lad, Prabhakar wrote:
> From: "Lad, Prabhakar" <prabhakar.csengg-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> 
> This patch converts the davinci gpio driver to use irqdomain
> support.

This patch needs to be splitted in two:
1) add IRQ domain support
2) remove intc_irq_num

> 
> Signed-off-by: Lad, Prabhakar <prabhakar.csengg-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
> ---
>   arch/arm/mach-davinci/da830.c              |    1 -
>   arch/arm/mach-davinci/da850.c              |    1 -
>   arch/arm/mach-davinci/dm355.c              |    1 -
>   arch/arm/mach-davinci/dm365.c              |    1 -
>   arch/arm/mach-davinci/dm644x.c             |    1 -
>   arch/arm/mach-davinci/dm646x.c             |    1 -
>   drivers/gpio/gpio-davinci.c                |   49 ++++++++++++++++++----------
>   include/linux/platform_data/gpio-davinci.h |    3 +-
>   8 files changed, 32 insertions(+), 26 deletions(-)
> 

[...]

>   
>   int __init dm646x_gpio_register(void)
> diff --git a/drivers/gpio/gpio-davinci.c b/drivers/gpio/gpio-davinci.c
> index 95c6df1..bcb6d8d 100644
> --- a/drivers/gpio/gpio-davinci.c
> +++ b/drivers/gpio/gpio-davinci.c
> @@ -16,6 +16,7 @@
>   #include <linux/err.h>
>   #include <linux/io.h>
>   #include <linux/irq.h>
> +#include <linux/irqdomain.h>
>   #include <linux/platform_device.h>
>   #include <linux/platform_data/gpio-davinci.h>
>   
> @@ -292,7 +293,7 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
>   		__raw_writel(status, &g->intstat);
>   
>   		/* now demux them to the right lowlevel handler */
> -		n = d->irq_base;
> +		n = irq_find_mapping(d->irq_domain, 0);

Sorry, but I don't understand why have you used <0> as hwirq?

All below logic may not work in case if we switch to use Linear IRQ domain :(
- irq_create_mapping() may return ANY Linux IRQ number. It means, for 
example, for bank0(ngpio=32)[0] it may return Linux_IRQ=200 or 201 or any other.
 Also, for bank3(ngpio=16)[0] it may return Linux_IRQ=150, etc.
- More over, if you call irq_create_mapping() 32 times you may NOT get
 sequential Linux_IRQ numbers.

So, the better sequence here can be smth. as below
(I can't verify it - my HW support only unbanked IRQs):

	if (irq & 1)
		mask <<= 16;

	while (1) {
		u32		status;
		int		bit;

		/* ack any irqs */
		status = __raw_readl(&g->intstat) & mask;
		if (!status)
			break;
		__raw_writel(status, &g->intstat);

		/* now demux them to the right lowlevel handler */
		while (status) {
			bit = __ffs(status);
                        status &= ~(1 << bit);
			generic_handle_irq(irq_find_mapping(d->irq_domain, bit));
		}
	}


>   		if (irq & 1) {
>   			n += 16;
>   			status >>= 16;
> @@ -313,10 +314,7 @@ static int gpio_to_irq_banked(struct gpio_chip *chip, unsigned offset)
>   {
>   	struct davinci_gpio_controller *d = chip2controller(chip);
>   
> -	if (d->irq_base >= 0)
> -		return d->irq_base + offset;
> -	else
> -		return -ENODEV;
> +	return irq_find_mapping(d->irq_domain, offset);

I think you can use irq_create_mapping() here instead of 
irq_find_mapping(), so IRQ will be mapped/allocated on demand.
Also, it seems, above code may crash in case if SoC has >1 GPIO banks and
gpio_unbanked > 0 and someone will call gpio_to_irq(>31).

>   }
>   
>   static int gpio_to_irq_unbanked(struct gpio_chip *chip, unsigned offset)
> @@ -373,6 +371,7 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
>   	struct davinci_gpio_controller *chips = platform_get_drvdata(pdev);
>   	struct davinci_gpio_platform_data *pdata = dev->platform_data;
>   	struct davinci_gpio_regs __iomem *g;
> +	int gpio_irq = 0;
>   
>   	ngpio = pdata->ngpio;
>   	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
> @@ -402,9 +401,15 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
>   	 */
>   	for (gpio = 0, bank = 0; gpio < ngpio; bank++, gpio += 32) {
>   		chips[bank].chip.to_irq = gpio_to_irq_banked;
> -		chips[bank].irq_base = pdata->gpio_unbanked
> -			? -EINVAL
> -			: (pdata->intc_irq_num + gpio);
> +		if (!pdata->gpio_unbanked) {
> +			chips[bank].irq_domain =
> +				irq_domain_add_linear(NULL, 32,

Use chips[i].chip.ngpio here instead of const 32?

> +						      &irq_domain_simple_ops,

Pass &davinci_gpio_irq_ops (see below)

> +						      NULL);

Pass &chips[bank] as host_data and use .map() callback (see below)

> +
> +			if (!chips[bank].irq_domain)
> +				return -ENOMEM;
> +		}
>   	}
>   
>   	/*
> @@ -445,9 +450,7 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
>   	 * Or, AINTC can handle IRQs for banks of 16 GPIO IRQs, which we
>   	 * then chain through our own handler.
>   	 */
> -	for (gpio = 0, irq = gpio_to_irq(0), bank = 0;
> -			gpio < ngpio;
> -			bank++, bank_irq++) {
> +	for (gpio = 0, irq = 0, bank = 0; gpio < ngpio; bank++, bank_irq++) {
>   		unsigned		i;
>   
>   		/* disabled by default, enabled only as needed */
> @@ -465,12 +468,22 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
>   		 */
>   		irq_set_handler_data(bank_irq, &chips[gpio / 32]);
>   
> -		for (i = 0; i < 16 && gpio < ngpio; i++, irq++, gpio++) {
> -			irq_set_chip(irq, &gpio_irqchip);
> -			irq_set_chip_data(irq, (__force void *)g);
> -			irq_set_handler_data(irq, (void *)__gpio_mask(gpio));
> -			irq_set_handler(irq, handle_simple_irq);
> -			set_irq_flags(irq, IRQF_VALID);
> +		if (!(bank % 2))
> +			irq = 0;
> +		else
> +			irq = 16;

As I mentioned above, I think, it is not good to play with IRQ numbers here.
Only chained IRQs and <binten> can be configured in this cycle.

> +
> +		for (i = 0; i < 16 && gpio < ngpio; i++, gpio++) {
> +			int irqno =
> +				irq_create_mapping(chips[gpio / 32].irq_domain,
> +						   i + irq);
> +
> +			irq_set_chip(irqno, &gpio_irqchip);
> +			irq_set_chip_data(irqno, (__force void *)g);
> +			irq_set_handler_data(irqno, (void *)__gpio_mask(gpio));
> +			irq_set_handler(irqno, handle_simple_irq);
> +			set_irq_flags(irqno, IRQF_VALID);

It makes no sense to manually create mapping. Usually it can be done in
.map() callback of IRQ domain. Like:

static int davinci_gpio_irq_map(struct irq_domain *d, unsigned int irq,
			    irq_hw_number_t hw)
{
	struct davinci_gpio_controller *chip = d->host_data;
	unsigned gpio = chip->chip.base + hw;

	irq_set_chip_and_handler_name(irq, &gpio_irqchip, handle_simple_irq,
				      "davinci_gpio");
	irq_set_irq_type(irq, IRQ_TYPE_NONE);
	set_irq_flags(irq, IRQF_VALID);
...
	return 0;
}

static const struct irq_domain_ops davinci_gpio_irq_ops = {
	.map = davinci_gpio_irq_map,
	.xlate = irq_domain_xlate_onetwocell,
};


> +			gpio_irq++;
>   		}
>   
>   		binten |= BIT(bank);
> @@ -483,7 +496,7 @@ done:
>   	 */
>   	__raw_writel(binten, gpio_base + BINTEN);
>   
> -	printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0));
> +	pr_info("DaVinci: %d gpio irqs\n", gpio_irq);
>   
>   	return 0;
>   }
[...]
>   	spinlock_t		lock;
>   	void __iomem		*regs;
> 
start

Regards,
- grygorii

WARNING: multiple messages have this Message-ID (diff)
From: grygorii.strashko@ti.com (Grygorii Strashko)
To: linux-arm-kernel@lists.infradead.org
Subject: [PATCH v4 3/6] gpio: davinci: use irqdomain
Date: Mon, 4 Nov 2013 20:27:46 +0200	[thread overview]
Message-ID: <5277E722.50205@ti.com> (raw)
In-Reply-To: <1383406775-14902-4-git-send-email-prabhakar.csenng@gmail.com>

Hi Prabhakar Lad,

On 11/02/2013 05:39 PM, Lad, Prabhakar wrote:
> From: "Lad, Prabhakar" <prabhakar.csengg@gmail.com>
> 
> This patch converts the davinci gpio driver to use irqdomain
> support.

This patch needs to be splitted in two:
1) add IRQ domain support
2) remove intc_irq_num

> 
> Signed-off-by: Lad, Prabhakar <prabhakar.csengg@gmail.com>
> ---
>   arch/arm/mach-davinci/da830.c              |    1 -
>   arch/arm/mach-davinci/da850.c              |    1 -
>   arch/arm/mach-davinci/dm355.c              |    1 -
>   arch/arm/mach-davinci/dm365.c              |    1 -
>   arch/arm/mach-davinci/dm644x.c             |    1 -
>   arch/arm/mach-davinci/dm646x.c             |    1 -
>   drivers/gpio/gpio-davinci.c                |   49 ++++++++++++++++++----------
>   include/linux/platform_data/gpio-davinci.h |    3 +-
>   8 files changed, 32 insertions(+), 26 deletions(-)
> 

[...]

>   
>   int __init dm646x_gpio_register(void)
> diff --git a/drivers/gpio/gpio-davinci.c b/drivers/gpio/gpio-davinci.c
> index 95c6df1..bcb6d8d 100644
> --- a/drivers/gpio/gpio-davinci.c
> +++ b/drivers/gpio/gpio-davinci.c
> @@ -16,6 +16,7 @@
>   #include <linux/err.h>
>   #include <linux/io.h>
>   #include <linux/irq.h>
> +#include <linux/irqdomain.h>
>   #include <linux/platform_device.h>
>   #include <linux/platform_data/gpio-davinci.h>
>   
> @@ -292,7 +293,7 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
>   		__raw_writel(status, &g->intstat);
>   
>   		/* now demux them to the right lowlevel handler */
> -		n = d->irq_base;
> +		n = irq_find_mapping(d->irq_domain, 0);

Sorry, but I don't understand why have you used <0> as hwirq?

All below logic may not work in case if we switch to use Linear IRQ domain :(
- irq_create_mapping() may return ANY Linux IRQ number. It means, for 
example, for bank0(ngpio=32)[0] it may return Linux_IRQ=200 or 201 or any other.
 Also, for bank3(ngpio=16)[0] it may return Linux_IRQ=150, etc.
- More over, if you call irq_create_mapping() 32 times you may NOT get
 sequential Linux_IRQ numbers.

So, the better sequence here can be smth. as below
(I can't verify it - my HW support only unbanked IRQs):

	if (irq & 1)
		mask <<= 16;

	while (1) {
		u32		status;
		int		bit;

		/* ack any irqs */
		status = __raw_readl(&g->intstat) & mask;
		if (!status)
			break;
		__raw_writel(status, &g->intstat);

		/* now demux them to the right lowlevel handler */
		while (status) {
			bit = __ffs(status);
                        status &= ~(1 << bit);
			generic_handle_irq(irq_find_mapping(d->irq_domain, bit));
		}
	}


>   		if (irq & 1) {
>   			n += 16;
>   			status >>= 16;
> @@ -313,10 +314,7 @@ static int gpio_to_irq_banked(struct gpio_chip *chip, unsigned offset)
>   {
>   	struct davinci_gpio_controller *d = chip2controller(chip);
>   
> -	if (d->irq_base >= 0)
> -		return d->irq_base + offset;
> -	else
> -		return -ENODEV;
> +	return irq_find_mapping(d->irq_domain, offset);

I think you can use irq_create_mapping() here instead of 
irq_find_mapping(), so IRQ will be mapped/allocated on demand.
Also, it seems, above code may crash in case if SoC has >1 GPIO banks and
gpio_unbanked > 0 and someone will call gpio_to_irq(>31).

>   }
>   
>   static int gpio_to_irq_unbanked(struct gpio_chip *chip, unsigned offset)
> @@ -373,6 +371,7 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
>   	struct davinci_gpio_controller *chips = platform_get_drvdata(pdev);
>   	struct davinci_gpio_platform_data *pdata = dev->platform_data;
>   	struct davinci_gpio_regs __iomem *g;
> +	int gpio_irq = 0;
>   
>   	ngpio = pdata->ngpio;
>   	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
> @@ -402,9 +401,15 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
>   	 */
>   	for (gpio = 0, bank = 0; gpio < ngpio; bank++, gpio += 32) {
>   		chips[bank].chip.to_irq = gpio_to_irq_banked;
> -		chips[bank].irq_base = pdata->gpio_unbanked
> -			? -EINVAL
> -			: (pdata->intc_irq_num + gpio);
> +		if (!pdata->gpio_unbanked) {
> +			chips[bank].irq_domain =
> +				irq_domain_add_linear(NULL, 32,

Use chips[i].chip.ngpio here instead of const 32?

> +						      &irq_domain_simple_ops,

Pass &davinci_gpio_irq_ops (see below)

> +						      NULL);

Pass &chips[bank] as host_data and use .map() callback (see below)

> +
> +			if (!chips[bank].irq_domain)
> +				return -ENOMEM;
> +		}
>   	}
>   
>   	/*
> @@ -445,9 +450,7 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
>   	 * Or, AINTC can handle IRQs for banks of 16 GPIO IRQs, which we
>   	 * then chain through our own handler.
>   	 */
> -	for (gpio = 0, irq = gpio_to_irq(0), bank = 0;
> -			gpio < ngpio;
> -			bank++, bank_irq++) {
> +	for (gpio = 0, irq = 0, bank = 0; gpio < ngpio; bank++, bank_irq++) {
>   		unsigned		i;
>   
>   		/* disabled by default, enabled only as needed */
> @@ -465,12 +468,22 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
>   		 */
>   		irq_set_handler_data(bank_irq, &chips[gpio / 32]);
>   
> -		for (i = 0; i < 16 && gpio < ngpio; i++, irq++, gpio++) {
> -			irq_set_chip(irq, &gpio_irqchip);
> -			irq_set_chip_data(irq, (__force void *)g);
> -			irq_set_handler_data(irq, (void *)__gpio_mask(gpio));
> -			irq_set_handler(irq, handle_simple_irq);
> -			set_irq_flags(irq, IRQF_VALID);
> +		if (!(bank % 2))
> +			irq = 0;
> +		else
> +			irq = 16;

As I mentioned above, I think, it is not good to play with IRQ numbers here.
Only chained IRQs and <binten> can be configured in this cycle.

> +
> +		for (i = 0; i < 16 && gpio < ngpio; i++, gpio++) {
> +			int irqno =
> +				irq_create_mapping(chips[gpio / 32].irq_domain,
> +						   i + irq);
> +
> +			irq_set_chip(irqno, &gpio_irqchip);
> +			irq_set_chip_data(irqno, (__force void *)g);
> +			irq_set_handler_data(irqno, (void *)__gpio_mask(gpio));
> +			irq_set_handler(irqno, handle_simple_irq);
> +			set_irq_flags(irqno, IRQF_VALID);

It makes no sense to manually create mapping. Usually it can be done in
.map() callback of IRQ domain. Like:

static int davinci_gpio_irq_map(struct irq_domain *d, unsigned int irq,
			    irq_hw_number_t hw)
{
	struct davinci_gpio_controller *chip = d->host_data;
	unsigned gpio = chip->chip.base + hw;

	irq_set_chip_and_handler_name(irq, &gpio_irqchip, handle_simple_irq,
				      "davinci_gpio");
	irq_set_irq_type(irq, IRQ_TYPE_NONE);
	set_irq_flags(irq, IRQF_VALID);
...
	return 0;
}

static const struct irq_domain_ops davinci_gpio_irq_ops = {
	.map = davinci_gpio_irq_map,
	.xlate = irq_domain_xlate_onetwocell,
};


> +			gpio_irq++;
>   		}
>   
>   		binten |= BIT(bank);
> @@ -483,7 +496,7 @@ done:
>   	 */
>   	__raw_writel(binten, gpio_base + BINTEN);
>   
> -	printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0));
> +	pr_info("DaVinci: %d gpio irqs\n", gpio_irq);
>   
>   	return 0;
>   }
[...]
>   	spinlock_t		lock;
>   	void __iomem		*regs;
> 
start

Regards,
- grygorii

WARNING: multiple messages have this Message-ID (diff)
From: Grygorii Strashko <grygorii.strashko@ti.com>
To: "Lad, Prabhakar" <prabhakar.csengg@gmail.com>,
	Sekhar Nori <nsekhar@ti.com>,
	Linus Walleij <linus.walleij@linaro.org>,
	<devicetree@vger.kernel.org>
Cc: Rob Herring <rob.herring@calxeda.com>,
	Pawel Moll <pawel.moll@arm.com>,
	Mark Rutland <mark.rutland@arm.com>,
	Stephen Warren <swarren@wwwdotorg.org>,
	Ian Campbell <ijc+devicetree@hellion.org.uk>,
	Rob Landley <rob@landley.net>,
	Russell King <linux@arm.linux.org.uk>,
	Grant Likely <grant.likely@linaro.org>,
	Alex Elder <alex.elder@linaro.org>, <linux-doc@vger.kernel.org>,
	<linux-kernel@vger.kernel.org>,
	<linux-arm-kernel@lists.infradead.org>,
	<davinci-linux-open-source@linux.davincidsp.com>,
	<linux-gpio@vger.kernel.org>
Subject: Re: [PATCH v4 3/6] gpio: davinci: use irqdomain
Date: Mon, 4 Nov 2013 20:27:46 +0200	[thread overview]
Message-ID: <5277E722.50205@ti.com> (raw)
In-Reply-To: <1383406775-14902-4-git-send-email-prabhakar.csenng@gmail.com>

Hi Prabhakar Lad,

On 11/02/2013 05:39 PM, Lad, Prabhakar wrote:
> From: "Lad, Prabhakar" <prabhakar.csengg@gmail.com>
> 
> This patch converts the davinci gpio driver to use irqdomain
> support.

This patch needs to be splitted in two:
1) add IRQ domain support
2) remove intc_irq_num

> 
> Signed-off-by: Lad, Prabhakar <prabhakar.csengg@gmail.com>
> ---
>   arch/arm/mach-davinci/da830.c              |    1 -
>   arch/arm/mach-davinci/da850.c              |    1 -
>   arch/arm/mach-davinci/dm355.c              |    1 -
>   arch/arm/mach-davinci/dm365.c              |    1 -
>   arch/arm/mach-davinci/dm644x.c             |    1 -
>   arch/arm/mach-davinci/dm646x.c             |    1 -
>   drivers/gpio/gpio-davinci.c                |   49 ++++++++++++++++++----------
>   include/linux/platform_data/gpio-davinci.h |    3 +-
>   8 files changed, 32 insertions(+), 26 deletions(-)
> 

[...]

>   
>   int __init dm646x_gpio_register(void)
> diff --git a/drivers/gpio/gpio-davinci.c b/drivers/gpio/gpio-davinci.c
> index 95c6df1..bcb6d8d 100644
> --- a/drivers/gpio/gpio-davinci.c
> +++ b/drivers/gpio/gpio-davinci.c
> @@ -16,6 +16,7 @@
>   #include <linux/err.h>
>   #include <linux/io.h>
>   #include <linux/irq.h>
> +#include <linux/irqdomain.h>
>   #include <linux/platform_device.h>
>   #include <linux/platform_data/gpio-davinci.h>
>   
> @@ -292,7 +293,7 @@ gpio_irq_handler(unsigned irq, struct irq_desc *desc)
>   		__raw_writel(status, &g->intstat);
>   
>   		/* now demux them to the right lowlevel handler */
> -		n = d->irq_base;
> +		n = irq_find_mapping(d->irq_domain, 0);

Sorry, but I don't understand why have you used <0> as hwirq?

All below logic may not work in case if we switch to use Linear IRQ domain :(
- irq_create_mapping() may return ANY Linux IRQ number. It means, for 
example, for bank0(ngpio=32)[0] it may return Linux_IRQ=200 or 201 or any other.
 Also, for bank3(ngpio=16)[0] it may return Linux_IRQ=150, etc.
- More over, if you call irq_create_mapping() 32 times you may NOT get
 sequential Linux_IRQ numbers.

So, the better sequence here can be smth. as below
(I can't verify it - my HW support only unbanked IRQs):

	if (irq & 1)
		mask <<= 16;

	while (1) {
		u32		status;
		int		bit;

		/* ack any irqs */
		status = __raw_readl(&g->intstat) & mask;
		if (!status)
			break;
		__raw_writel(status, &g->intstat);

		/* now demux them to the right lowlevel handler */
		while (status) {
			bit = __ffs(status);
                        status &= ~(1 << bit);
			generic_handle_irq(irq_find_mapping(d->irq_domain, bit));
		}
	}


>   		if (irq & 1) {
>   			n += 16;
>   			status >>= 16;
> @@ -313,10 +314,7 @@ static int gpio_to_irq_banked(struct gpio_chip *chip, unsigned offset)
>   {
>   	struct davinci_gpio_controller *d = chip2controller(chip);
>   
> -	if (d->irq_base >= 0)
> -		return d->irq_base + offset;
> -	else
> -		return -ENODEV;
> +	return irq_find_mapping(d->irq_domain, offset);

I think you can use irq_create_mapping() here instead of 
irq_find_mapping(), so IRQ will be mapped/allocated on demand.
Also, it seems, above code may crash in case if SoC has >1 GPIO banks and
gpio_unbanked > 0 and someone will call gpio_to_irq(>31).

>   }
>   
>   static int gpio_to_irq_unbanked(struct gpio_chip *chip, unsigned offset)
> @@ -373,6 +371,7 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
>   	struct davinci_gpio_controller *chips = platform_get_drvdata(pdev);
>   	struct davinci_gpio_platform_data *pdata = dev->platform_data;
>   	struct davinci_gpio_regs __iomem *g;
> +	int gpio_irq = 0;
>   
>   	ngpio = pdata->ngpio;
>   	res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
> @@ -402,9 +401,15 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
>   	 */
>   	for (gpio = 0, bank = 0; gpio < ngpio; bank++, gpio += 32) {
>   		chips[bank].chip.to_irq = gpio_to_irq_banked;
> -		chips[bank].irq_base = pdata->gpio_unbanked
> -			? -EINVAL
> -			: (pdata->intc_irq_num + gpio);
> +		if (!pdata->gpio_unbanked) {
> +			chips[bank].irq_domain =
> +				irq_domain_add_linear(NULL, 32,

Use chips[i].chip.ngpio here instead of const 32?

> +						      &irq_domain_simple_ops,

Pass &davinci_gpio_irq_ops (see below)

> +						      NULL);

Pass &chips[bank] as host_data and use .map() callback (see below)

> +
> +			if (!chips[bank].irq_domain)
> +				return -ENOMEM;
> +		}
>   	}
>   
>   	/*
> @@ -445,9 +450,7 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
>   	 * Or, AINTC can handle IRQs for banks of 16 GPIO IRQs, which we
>   	 * then chain through our own handler.
>   	 */
> -	for (gpio = 0, irq = gpio_to_irq(0), bank = 0;
> -			gpio < ngpio;
> -			bank++, bank_irq++) {
> +	for (gpio = 0, irq = 0, bank = 0; gpio < ngpio; bank++, bank_irq++) {
>   		unsigned		i;
>   
>   		/* disabled by default, enabled only as needed */
> @@ -465,12 +468,22 @@ static int davinci_gpio_irq_setup(struct platform_device *pdev)
>   		 */
>   		irq_set_handler_data(bank_irq, &chips[gpio / 32]);
>   
> -		for (i = 0; i < 16 && gpio < ngpio; i++, irq++, gpio++) {
> -			irq_set_chip(irq, &gpio_irqchip);
> -			irq_set_chip_data(irq, (__force void *)g);
> -			irq_set_handler_data(irq, (void *)__gpio_mask(gpio));
> -			irq_set_handler(irq, handle_simple_irq);
> -			set_irq_flags(irq, IRQF_VALID);
> +		if (!(bank % 2))
> +			irq = 0;
> +		else
> +			irq = 16;

As I mentioned above, I think, it is not good to play with IRQ numbers here.
Only chained IRQs and <binten> can be configured in this cycle.

> +
> +		for (i = 0; i < 16 && gpio < ngpio; i++, gpio++) {
> +			int irqno =
> +				irq_create_mapping(chips[gpio / 32].irq_domain,
> +						   i + irq);
> +
> +			irq_set_chip(irqno, &gpio_irqchip);
> +			irq_set_chip_data(irqno, (__force void *)g);
> +			irq_set_handler_data(irqno, (void *)__gpio_mask(gpio));
> +			irq_set_handler(irqno, handle_simple_irq);
> +			set_irq_flags(irqno, IRQF_VALID);

It makes no sense to manually create mapping. Usually it can be done in
.map() callback of IRQ domain. Like:

static int davinci_gpio_irq_map(struct irq_domain *d, unsigned int irq,
			    irq_hw_number_t hw)
{
	struct davinci_gpio_controller *chip = d->host_data;
	unsigned gpio = chip->chip.base + hw;

	irq_set_chip_and_handler_name(irq, &gpio_irqchip, handle_simple_irq,
				      "davinci_gpio");
	irq_set_irq_type(irq, IRQ_TYPE_NONE);
	set_irq_flags(irq, IRQF_VALID);
...
	return 0;
}

static const struct irq_domain_ops davinci_gpio_irq_ops = {
	.map = davinci_gpio_irq_map,
	.xlate = irq_domain_xlate_onetwocell,
};


> +			gpio_irq++;
>   		}
>   
>   		binten |= BIT(bank);
> @@ -483,7 +496,7 @@ done:
>   	 */
>   	__raw_writel(binten, gpio_base + BINTEN);
>   
> -	printk(KERN_INFO "DaVinci: %d gpio irqs\n", irq - gpio_to_irq(0));
> +	pr_info("DaVinci: %d gpio irqs\n", gpio_irq);
>   
>   	return 0;
>   }
[...]
>   	spinlock_t		lock;
>   	void __iomem		*regs;
> 
start

Regards,
- grygorii

  parent reply	other threads:[~2013-11-04 18:27 UTC|newest]

Thread overview: 54+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2013-11-02 15:39 [PATCH v4 0/6] gpio: daVinci: Fixes and feature enhancement Lad, Prabhakar
2013-11-02 15:39 ` Lad, Prabhakar
2013-11-02 15:39 ` [PATCH v4 1/6] gpio: davinci: Fixed a check for unbanked gpio Lad, Prabhakar
2013-11-02 15:39   ` Lad, Prabhakar
2013-11-05 12:39   ` Linus Walleij
2013-11-05 12:39     ` Linus Walleij
2013-11-06  9:33     ` Prabhakar Lad
2013-11-06  9:33       ` Prabhakar Lad
2013-11-06  9:56       ` Linus Walleij
2013-11-06  9:56         ` Linus Walleij
2013-11-06 10:15         ` Prabhakar Lad
2013-11-06 10:15           ` Prabhakar Lad
     [not found]           ` <CA+V-a8tZTm9bh+arQ+uFyTVHxfdf07bWaM_Sdqo08TO=UCMMUg-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2013-11-06 10:49             ` Sekhar Nori
2013-11-06 10:49               ` Sekhar Nori
2013-11-06 10:49               ` Sekhar Nori
     [not found]               ` <527A1EC7.20400-l0cyMroinI0@public.gmane.org>
2013-11-06 11:33                 ` Grygorii Strashko
2013-11-06 11:33                   ` Grygorii Strashko
2013-11-06 11:33                   ` Grygorii Strashko
     [not found]                   ` <527A28EF.9070601-l0cyMroinI0@public.gmane.org>
2013-11-06 11:42                     ` Sekhar Nori
2013-11-06 11:42                       ` Sekhar Nori
2013-11-06 11:42                       ` Sekhar Nori
2013-11-06 11:36           ` Linus Walleij
2013-11-06 11:36             ` Linus Walleij
2013-11-02 15:39 ` [PATCH v4 2/6] gpio: davinci: remove unnecessary printk Lad, Prabhakar
2013-11-02 15:39   ` Lad, Prabhakar
     [not found] ` <1383406775-14902-1-git-send-email-prabhakar.csenng-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2013-11-02 15:39   ` [PATCH v4 3/6] gpio: davinci: use irqdomain Lad, Prabhakar
2013-11-02 15:39     ` Lad, Prabhakar
2013-11-02 15:39     ` Lad, Prabhakar
     [not found]     ` <1383406775-14902-4-git-send-email-prabhakar.csenng-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2013-11-04 18:27       ` Grygorii Strashko [this message]
2013-11-04 18:27         ` Grygorii Strashko
2013-11-04 18:27         ` Grygorii Strashko
2013-11-05  8:00         ` Prabhakar Lad
2013-11-05  8:00           ` Prabhakar Lad
2013-11-02 15:39   ` [PATCH v4 5/6] ARM: davinci: da850: add GPIO DT node Lad, Prabhakar
2013-11-02 15:39     ` Lad, Prabhakar
2013-11-02 15:39     ` Lad, Prabhakar
2013-11-02 15:39 ` [PATCH v4 4/6] gpio: davinci: add OF support Lad, Prabhakar
2013-11-02 15:39   ` Lad, Prabhakar
     [not found]   ` <1383406775-14902-5-git-send-email-prabhakar.csenng-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2013-11-04 18:28     ` Grygorii Strashko
2013-11-04 18:28       ` Grygorii Strashko
2013-11-04 18:28       ` Grygorii Strashko
2013-11-05  8:53       ` Prabhakar Lad
2013-11-05  8:53         ` Prabhakar Lad
     [not found]         ` <CA+V-a8uV0g36LoQtxFjR56SaMxj7KOE2ztC+pfT_Pn1wGcqEmw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2013-11-05 16:59           ` Grygorii Strashko
2013-11-05 16:59             ` Grygorii Strashko
2013-11-05 16:59             ` Grygorii Strashko
2013-11-06 10:08             ` Prabhakar Lad
2013-11-06 10:08               ` Prabhakar Lad
2013-11-06 10:08               ` Prabhakar Lad
     [not found]               ` <CA+V-a8tJ7yDJOPamoCiaX6Twnnqxp_o_L0rzo2dEeSDS2VoYLw-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2013-11-06 11:55                 ` Grygorii Strashko
2013-11-06 11:55                   ` Grygorii Strashko
2013-11-06 11:55                   ` Grygorii Strashko
2013-11-02 15:39 ` [PATCH v4 6/6] ARM: davinci: da850 evm: add GPIO pinumux entries DT node Lad, Prabhakar
2013-11-02 15:39   ` Lad, Prabhakar

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=5277E722.50205@ti.com \
    --to=grygorii.strashko-l0cymroini0@public.gmane.org \
    --cc=alex.elder-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org \
    --cc=davinci-linux-open-source-VycZQUHpC/PFrsHnngEfi1aTQe2KTcn/@public.gmane.org \
    --cc=devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=grant.likely-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org \
    --cc=ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg@public.gmane.org \
    --cc=linus.walleij-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org \
    --cc=linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r@public.gmane.org \
    --cc=linux-doc-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-gpio-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=linux-lFZ/pmaqli7XmaaqVzeoHQ@public.gmane.org \
    --cc=mark.rutland-5wv7dgnIgG8@public.gmane.org \
    --cc=nsekhar-l0cyMroinI0@public.gmane.org \
    --cc=pawel.moll-5wv7dgnIgG8@public.gmane.org \
    --cc=prabhakar.csengg-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=rob-VoJi6FS/r0vR7s880joybQ@public.gmane.org \
    --cc=rob.herring-bsGFqQB8/DxBDgjK7y7TUQ@public.gmane.org \
    --cc=swarren-3lzwWm7+Weoh9ZMKESR00Q@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.