* [PATCH 1/9] dt: add empty of_get_node/of_put_node functions
2011-12-14 15:28 [PATCH 0/9] irq domain for gen irq chip and pl061 DT irq support Rob Herring
@ 2011-12-14 15:28 ` Rob Herring
2011-12-14 16:02 ` Grant Likely
2011-12-14 15:28 ` [PATCH 2/9] irq: check domain hwirq range for DT translate Rob Herring
` (8 subsequent siblings)
9 siblings, 1 reply; 43+ messages in thread
From: Rob Herring @ 2011-12-14 15:28 UTC (permalink / raw)
To: linux-arm-kernel
From: Rob Herring <rob.herring@calxeda.com>
Add empty of_get_node/of_put_node functions for !CONFIG_OF builds.
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
---
include/linux/of.h | 29 ++++++++++++++---------------
1 files changed, 14 insertions(+), 15 deletions(-)
diff --git a/include/linux/of.h b/include/linux/of.h
index 4948552..e291381 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -65,6 +65,20 @@ struct device_node {
#endif
};
+#if defined(CONFIG_SPARC) || !defined(CONFIG_OF)
+/* Dummy ref counting routines - to be implemented later */
+static inline struct device_node *of_node_get(struct device_node *node)
+{
+ return node;
+}
+static inline void of_node_put(struct device_node *node)
+{
+}
+#else
+extern struct device_node *of_node_get(struct device_node *node);
+extern void of_node_put(struct device_node *node);
+#endif
+
#ifdef CONFIG_OF
/* Pointer for first entry in chain of all nodes. */
@@ -95,21 +109,6 @@ static inline void of_node_set_flag(struct device_node *n, unsigned long flag)
extern struct device_node *of_find_all_nodes(struct device_node *prev);
-#if defined(CONFIG_SPARC)
-/* Dummy ref counting routines - to be implemented later */
-static inline struct device_node *of_node_get(struct device_node *node)
-{
- return node;
-}
-static inline void of_node_put(struct device_node *node)
-{
-}
-
-#else
-extern struct device_node *of_node_get(struct device_node *node);
-extern void of_node_put(struct device_node *node);
-#endif
-
/*
* OF address retrieval & translation
*/
--
1.7.5.4
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [PATCH 1/9] dt: add empty of_get_node/of_put_node functions
2011-12-14 15:28 ` [PATCH 1/9] dt: add empty of_get_node/of_put_node functions Rob Herring
@ 2011-12-14 16:02 ` Grant Likely
0 siblings, 0 replies; 43+ messages in thread
From: Grant Likely @ 2011-12-14 16:02 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Dec 14, 2011 at 8:28 AM, Rob Herring <robherring2@gmail.com> wrote:
> From: Rob Herring <rob.herring@calxeda.com>
>
> Add empty of_get_node/of_put_node functions for !CONFIG_OF builds.
>
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> Cc: Grant Likely <grant.likely@secretlab.ca>
Looks good.
> ---
> ?include/linux/of.h | ? 29 ++++++++++++++---------------
> ?1 files changed, 14 insertions(+), 15 deletions(-)
>
> diff --git a/include/linux/of.h b/include/linux/of.h
> index 4948552..e291381 100644
> --- a/include/linux/of.h
> +++ b/include/linux/of.h
> @@ -65,6 +65,20 @@ struct device_node {
> ?#endif
> ?};
>
> +#if defined(CONFIG_SPARC) || !defined(CONFIG_OF)
> +/* Dummy ref counting routines - to be implemented later */
> +static inline struct device_node *of_node_get(struct device_node *node)
> +{
> + ? ? ? return node;
> +}
> +static inline void of_node_put(struct device_node *node)
> +{
> +}
> +#else
> +extern struct device_node *of_node_get(struct device_node *node);
> +extern void of_node_put(struct device_node *node);
> +#endif
> +
> ?#ifdef CONFIG_OF
>
> ?/* Pointer for first entry in chain of all nodes. */
> @@ -95,21 +109,6 @@ static inline void of_node_set_flag(struct device_node *n, unsigned long flag)
>
> ?extern struct device_node *of_find_all_nodes(struct device_node *prev);
>
> -#if defined(CONFIG_SPARC)
> -/* Dummy ref counting routines - to be implemented later */
> -static inline struct device_node *of_node_get(struct device_node *node)
> -{
> - ? ? ? return node;
> -}
> -static inline void of_node_put(struct device_node *node)
> -{
> -}
> -
> -#else
> -extern struct device_node *of_node_get(struct device_node *node);
> -extern void of_node_put(struct device_node *node);
> -#endif
> -
> ?/*
> ?* OF address retrieval & translation
> ?*/
> --
> 1.7.5.4
>
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply [flat|nested] 43+ messages in thread
* [PATCH 2/9] irq: check domain hwirq range for DT translate
2011-12-14 15:28 [PATCH 0/9] irq domain for gen irq chip and pl061 DT irq support Rob Herring
2011-12-14 15:28 ` [PATCH 1/9] dt: add empty of_get_node/of_put_node functions Rob Herring
@ 2011-12-14 15:28 ` Rob Herring
2011-12-14 16:08 ` Grant Likely
` (2 more replies)
2011-12-14 15:28 ` [PATCH 3/9] irq: convert generic-chip to use irq_domain Rob Herring
` (7 subsequent siblings)
9 siblings, 3 replies; 43+ messages in thread
From: Rob Herring @ 2011-12-14 15:28 UTC (permalink / raw)
To: linux-arm-kernel
From: Rob Herring <rob.herring@calxeda.com>
A DT node may have more than 1 domain associated with it, so make sure
the hwirq number is within range when doing DT translation.
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
---
kernel/irq/irqdomain.c | 3 +++
1 files changed, 3 insertions(+), 0 deletions(-)
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index 200ce83..ae6441e 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -135,6 +135,9 @@ int irq_domain_simple_dt_translate(struct irq_domain *d,
return -EINVAL;
if (intsize < 1)
return -EINVAL;
+ if ((intspec[0] < d->hwirq_base) ||
+ (intspec[0] >= d->hwirq_base + d->nr_irq))
+ return -EINVAL;
*out_hwirq = intspec[0];
*out_type = IRQ_TYPE_NONE;
--
1.7.5.4
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [PATCH 2/9] irq: check domain hwirq range for DT translate
2011-12-14 15:28 ` [PATCH 2/9] irq: check domain hwirq range for DT translate Rob Herring
@ 2011-12-14 16:08 ` Grant Likely
2011-12-15 5:23 ` Shawn Guo
2011-12-19 12:41 ` Cousson, Benoit
2 siblings, 0 replies; 43+ messages in thread
From: Grant Likely @ 2011-12-14 16:08 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Dec 14, 2011 at 8:28 AM, Rob Herring <robherring2@gmail.com> wrote:
> From: Rob Herring <rob.herring@calxeda.com>
>
> A DT node may have more than 1 domain associated with it, so make sure
> the hwirq number is within range when doing DT translation.
>
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
> ---
> ?kernel/irq/irqdomain.c | ? ?3 +++
> ?1 files changed, 3 insertions(+), 0 deletions(-)
>
> diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
> index 200ce83..ae6441e 100644
> --- a/kernel/irq/irqdomain.c
> +++ b/kernel/irq/irqdomain.c
> @@ -135,6 +135,9 @@ int irq_domain_simple_dt_translate(struct irq_domain *d,
> ? ? ? ? ? ? ? ?return -EINVAL;
> ? ? ? ?if (intsize < 1)
> ? ? ? ? ? ? ? ?return -EINVAL;
> + ? ? ? if ((intspec[0] < d->hwirq_base) ||
> + ? ? ? ? ? (intspec[0] >= d->hwirq_base + d->nr_irq))
> + ? ? ? ? ? ? ? return -EINVAL;
>
> ? ? ? ?*out_hwirq = intspec[0];
> ? ? ? ?*out_type = IRQ_TYPE_NONE;
> --
> 1.7.5.4
>
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply [flat|nested] 43+ messages in thread
* [PATCH 2/9] irq: check domain hwirq range for DT translate
2011-12-14 15:28 ` [PATCH 2/9] irq: check domain hwirq range for DT translate Rob Herring
2011-12-14 16:08 ` Grant Likely
@ 2011-12-15 5:23 ` Shawn Guo
2011-12-19 12:41 ` Cousson, Benoit
2 siblings, 0 replies; 43+ messages in thread
From: Shawn Guo @ 2011-12-15 5:23 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Dec 14, 2011 at 09:28:51AM -0600, Rob Herring wrote:
> From: Rob Herring <rob.herring@calxeda.com>
>
> A DT node may have more than 1 domain associated with it, so make sure
> the hwirq number is within range when doing DT translation.
>
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> ---
Acked-by: Shawn Guo <shawn.guo@linaro.org>
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 43+ messages in thread
* [PATCH 2/9] irq: check domain hwirq range for DT translate
2011-12-14 15:28 ` [PATCH 2/9] irq: check domain hwirq range for DT translate Rob Herring
2011-12-14 16:08 ` Grant Likely
2011-12-15 5:23 ` Shawn Guo
@ 2011-12-19 12:41 ` Cousson, Benoit
2011-12-19 14:23 ` Rob Herring
2 siblings, 1 reply; 43+ messages in thread
From: Cousson, Benoit @ 2011-12-19 12:41 UTC (permalink / raw)
To: linux-arm-kernel
Hi Rob,
While trying your series to take advantage of the generic-irq domain
support for OMAP3 INTC, I realized that the following patch is breaking
drivers that are using irq_domain_add_simple.
The point is that irq_domain_add_simple does not populate hwirq_base or
nr_irq, so that test will always fail if the domain is created by the
irq_domain_add_simple API.
Adding an extra parameter to provide the nr_irq should fix that.
The long term fix should be to use the generic-irq for such driver, but
this is not the same effort, so it might worth fixing that API for the
moment.
Regards,
Benoit
On 12/14/2011 4:28 PM, Rob Herring wrote:
> From: Rob Herring<rob.herring@calxeda.com>
>
> A DT node may have more than 1 domain associated with it, so make sure
> the hwirq number is within range when doing DT translation.
>
> Signed-off-by: Rob Herring<rob.herring@calxeda.com>
> Cc: Thomas Gleixner<tglx@linutronix.de>
> ---
> kernel/irq/irqdomain.c | 3 +++
> 1 files changed, 3 insertions(+), 0 deletions(-)
>
> diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
> index 200ce83..ae6441e 100644
> --- a/kernel/irq/irqdomain.c
> +++ b/kernel/irq/irqdomain.c
> @@ -135,6 +135,9 @@ int irq_domain_simple_dt_translate(struct irq_domain *d,
> return -EINVAL;
> if (intsize< 1)
> return -EINVAL;
> + if ((intspec[0]< d->hwirq_base) ||
> + (intspec[0]>= d->hwirq_base + d->nr_irq))
> + return -EINVAL;
>
> *out_hwirq = intspec[0];
> *out_type = IRQ_TYPE_NONE;
^ permalink raw reply [flat|nested] 43+ messages in thread
* [PATCH 2/9] irq: check domain hwirq range for DT translate
2011-12-19 12:41 ` Cousson, Benoit
@ 2011-12-19 14:23 ` Rob Herring
2011-12-19 15:21 ` Cousson, Benoit
0 siblings, 1 reply; 43+ messages in thread
From: Rob Herring @ 2011-12-19 14:23 UTC (permalink / raw)
To: linux-arm-kernel
Benoit,
On 12/19/2011 06:41 AM, Cousson, Benoit wrote:
> Hi Rob,
>
> While trying your series to take advantage of the generic-irq domain
> support for OMAP3 INTC, I realized that the following patch is breaking
> drivers that are using irq_domain_add_simple.
>
> The point is that irq_domain_add_simple does not populate hwirq_base or
> nr_irq, so that test will always fail if the domain is created by the
> irq_domain_add_simple API.
>
> Adding an extra parameter to provide the nr_irq should fix that.
>
> The long term fix should be to use the generic-irq for such driver, but
> this is not the same effort, so it might worth fixing that API for the
> moment.
>
> Regards,
> Benoit
>
> On 12/14/2011 4:28 PM, Rob Herring wrote:
>> From: Rob Herring<rob.herring@calxeda.com>
>>
>> A DT node may have more than 1 domain associated with it, so make sure
>> the hwirq number is within range when doing DT translation.
>>
>> Signed-off-by: Rob Herring<rob.herring@calxeda.com>
>> Cc: Thomas Gleixner<tglx@linutronix.de>
>> ---
>> kernel/irq/irqdomain.c | 3 +++
>> 1 files changed, 3 insertions(+), 0 deletions(-)
>>
>> diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
>> index 200ce83..ae6441e 100644
>> --- a/kernel/irq/irqdomain.c
>> +++ b/kernel/irq/irqdomain.c
>> @@ -135,6 +135,9 @@ int irq_domain_simple_dt_translate(struct
>> irq_domain *d,
>> return -EINVAL;
>> if (intsize< 1)
>> return -EINVAL;
>> + if ((intspec[0]< d->hwirq_base) ||
>> + (intspec[0]>= d->hwirq_base + d->nr_irq))
I think this should work:
if (d->nr_irq && ((intspec[0] < d->hwirq_base) ||
(intspec[0] >= d->hwirq_base + d->nr_irq)))
Rob
>> + return -EINVAL;
>>
>> *out_hwirq = intspec[0];
>> *out_type = IRQ_TYPE_NONE;
>
^ permalink raw reply [flat|nested] 43+ messages in thread
* [PATCH 2/9] irq: check domain hwirq range for DT translate
2011-12-19 14:23 ` Rob Herring
@ 2011-12-19 15:21 ` Cousson, Benoit
0 siblings, 0 replies; 43+ messages in thread
From: Cousson, Benoit @ 2011-12-19 15:21 UTC (permalink / raw)
To: linux-arm-kernel
On 12/19/2011 3:23 PM, Rob Herring wrote:
> Benoit,
>
> On 12/19/2011 06:41 AM, Cousson, Benoit wrote:
>> Hi Rob,
>>
>> While trying your series to take advantage of the generic-irq domain
>> support for OMAP3 INTC, I realized that the following patch is breaking
>> drivers that are using irq_domain_add_simple.
>>
>> The point is that irq_domain_add_simple does not populate hwirq_base or
>> nr_irq, so that test will always fail if the domain is created by the
>> irq_domain_add_simple API.
>>
>> Adding an extra parameter to provide the nr_irq should fix that.
>>
>> The long term fix should be to use the generic-irq for such driver, but
>> this is not the same effort, so it might worth fixing that API for the
>> moment.
>>
>> Regards,
>> Benoit
>>
>> On 12/14/2011 4:28 PM, Rob Herring wrote:
>>> From: Rob Herring<rob.herring@calxeda.com>
>>>
>>> A DT node may have more than 1 domain associated with it, so make sure
>>> the hwirq number is within range when doing DT translation.
>>>
>>> Signed-off-by: Rob Herring<rob.herring@calxeda.com>
>>> Cc: Thomas Gleixner<tglx@linutronix.de>
>>> ---
>>> kernel/irq/irqdomain.c | 3 +++
>>> 1 files changed, 3 insertions(+), 0 deletions(-)
>>>
>>> diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
>>> index 200ce83..ae6441e 100644
>>> --- a/kernel/irq/irqdomain.c
>>> +++ b/kernel/irq/irqdomain.c
>>> @@ -135,6 +135,9 @@ int irq_domain_simple_dt_translate(struct
>>> irq_domain *d,
>>> return -EINVAL;
>>> if (intsize< 1)
>>> return -EINVAL;
>>> + if ((intspec[0]< d->hwirq_base) ||
>>> + (intspec[0]>= d->hwirq_base + d->nr_irq))
>
> I think this should work:
>
> if (d->nr_irq&& ((intspec[0]< d->hwirq_base) ||
> (intspec[0]>= d->hwirq_base + d->nr_irq)))
Yes, indeed. It is even simpler that fixing the API.
I can now repost the OMAP3/4 series based on this series.
Thanks,
Benoit
^ permalink raw reply [flat|nested] 43+ messages in thread
* [PATCH 3/9] irq: convert generic-chip to use irq_domain
2011-12-14 15:28 [PATCH 0/9] irq domain for gen irq chip and pl061 DT irq support Rob Herring
2011-12-14 15:28 ` [PATCH 1/9] dt: add empty of_get_node/of_put_node functions Rob Herring
2011-12-14 15:28 ` [PATCH 2/9] irq: check domain hwirq range for DT translate Rob Herring
@ 2011-12-14 15:28 ` Rob Herring
2011-12-14 21:14 ` Grant Likely
2011-12-15 5:25 ` Shawn Guo
2011-12-14 15:28 ` [PATCH 4/9] gpio: pl061: use chained_irq_* functions in irq handler Rob Herring
` (6 subsequent siblings)
9 siblings, 2 replies; 43+ messages in thread
From: Rob Herring @ 2011-12-14 15:28 UTC (permalink / raw)
To: linux-arm-kernel
From: Rob Herring <rob.herring@calxeda.com>
Add irq domain support to irq generic-chip. This enables users of
generic-chip to support dynamic irq assignment needed for DT interrupt
binding. Users must be converted to use irq_data.hwirq for determining
local interrupt numbers rather than using the Linux irq number.
irq_base is kept for now as there are a few users of it. Once they
are converted to use the irq domain, it can be removed.
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
---
include/linux/irq.h | 2 +-
kernel/irq/Kconfig | 1 +
kernel/irq/generic-chip.c | 57 ++++++++++++++++++++++++++++----------------
3 files changed, 38 insertions(+), 22 deletions(-)
diff --git a/include/linux/irq.h b/include/linux/irq.h
index bff29c5..9ba8a30 100644
--- a/include/linux/irq.h
+++ b/include/linux/irq.h
@@ -664,7 +664,7 @@ struct irq_chip_generic {
raw_spinlock_t lock;
void __iomem *reg_base;
unsigned int irq_base;
- unsigned int irq_cnt;
+ struct irq_domain *domain;
u32 mask_cache;
u32 type_cache;
u32 polarity_cache;
diff --git a/kernel/irq/Kconfig b/kernel/irq/Kconfig
index 5a38bf4..861f2fe 100644
--- a/kernel/irq/Kconfig
+++ b/kernel/irq/Kconfig
@@ -51,6 +51,7 @@ config IRQ_EDGE_EOI_HANDLER
# Generic configurable interrupt chip implementation
config GENERIC_IRQ_CHIP
bool
+ select IRQ_DOMAIN
# Generic irq_domain hw <--> linux irq number translation
config IRQ_DOMAIN
diff --git a/kernel/irq/generic-chip.c b/kernel/irq/generic-chip.c
index c89295a..e32fac7 100644
--- a/kernel/irq/generic-chip.c
+++ b/kernel/irq/generic-chip.c
@@ -5,6 +5,7 @@
*/
#include <linux/io.h>
#include <linux/irq.h>
+#include <linux/irqdomain.h>
#include <linux/slab.h>
#include <linux/export.h>
#include <linux/interrupt.h>
@@ -39,7 +40,7 @@ void irq_gc_noop(struct irq_data *d)
void irq_gc_mask_disable_reg(struct irq_data *d)
{
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
- u32 mask = 1 << (d->irq - gc->irq_base);
+ u32 mask = 1 << d->hwirq;
irq_gc_lock(gc);
irq_reg_writel(mask, gc->reg_base + cur_regs(d)->disable);
@@ -57,7 +58,7 @@ void irq_gc_mask_disable_reg(struct irq_data *d)
void irq_gc_mask_set_bit(struct irq_data *d)
{
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
- u32 mask = 1 << (d->irq - gc->irq_base);
+ u32 mask = 1 << d->hwirq;
irq_gc_lock(gc);
gc->mask_cache |= mask;
@@ -75,7 +76,7 @@ void irq_gc_mask_set_bit(struct irq_data *d)
void irq_gc_mask_clr_bit(struct irq_data *d)
{
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
- u32 mask = 1 << (d->irq - gc->irq_base);
+ u32 mask = 1 << d->hwirq;
irq_gc_lock(gc);
gc->mask_cache &= ~mask;
@@ -93,7 +94,7 @@ void irq_gc_mask_clr_bit(struct irq_data *d)
void irq_gc_unmask_enable_reg(struct irq_data *d)
{
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
- u32 mask = 1 << (d->irq - gc->irq_base);
+ u32 mask = 1 << d->hwirq;
irq_gc_lock(gc);
irq_reg_writel(mask, gc->reg_base + cur_regs(d)->enable);
@@ -108,7 +109,7 @@ void irq_gc_unmask_enable_reg(struct irq_data *d)
void irq_gc_ack_set_bit(struct irq_data *d)
{
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
- u32 mask = 1 << (d->irq - gc->irq_base);
+ u32 mask = 1 << d->hwirq;
irq_gc_lock(gc);
irq_reg_writel(mask, gc->reg_base + cur_regs(d)->ack);
@@ -122,7 +123,7 @@ void irq_gc_ack_set_bit(struct irq_data *d)
void irq_gc_ack_clr_bit(struct irq_data *d)
{
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
- u32 mask = ~(1 << (d->irq - gc->irq_base));
+ u32 mask = ~(1 << d->hwirq);
irq_gc_lock(gc);
irq_reg_writel(mask, gc->reg_base + cur_regs(d)->ack);
@@ -136,7 +137,7 @@ void irq_gc_ack_clr_bit(struct irq_data *d)
void irq_gc_mask_disable_reg_and_ack(struct irq_data *d)
{
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
- u32 mask = 1 << (d->irq - gc->irq_base);
+ u32 mask = 1 << d->hwirq;
irq_gc_lock(gc);
irq_reg_writel(mask, gc->reg_base + cur_regs(d)->mask);
@@ -151,7 +152,7 @@ void irq_gc_mask_disable_reg_and_ack(struct irq_data *d)
void irq_gc_eoi(struct irq_data *d)
{
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
- u32 mask = 1 << (d->irq - gc->irq_base);
+ u32 mask = 1 << d->hwirq;
irq_gc_lock(gc);
irq_reg_writel(mask, gc->reg_base + cur_regs(d)->eoi);
@@ -169,7 +170,7 @@ void irq_gc_eoi(struct irq_data *d)
int irq_gc_set_wake(struct irq_data *d, unsigned int on)
{
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
- u32 mask = 1 << (d->irq - gc->irq_base);
+ u32 mask = 1 << d->hwirq;
if (!(mask & gc->wake_enabled))
return -EINVAL;
@@ -201,10 +202,13 @@ irq_alloc_generic_chip(const char *name, int num_ct, unsigned int irq_base,
struct irq_chip_generic *gc;
unsigned long sz = sizeof(*gc) + num_ct * sizeof(struct irq_chip_type);
- gc = kzalloc(sz, GFP_KERNEL);
+ gc = kzalloc(sz + sizeof(struct irq_domain), GFP_KERNEL);
if (gc) {
raw_spin_lock_init(&gc->lock);
gc->num_ct = num_ct;
+ gc->domain = (void *)gc + sz;
+ gc->domain->irq_base = irq_base;
+ gc->domain->ops = &irq_domain_simple_ops;
gc->irq_base = irq_base;
gc->reg_base = reg_base;
gc->chip_types->chip.name = name;
@@ -237,7 +241,7 @@ void irq_setup_generic_chip(struct irq_chip_generic *gc, u32 msk,
unsigned int set)
{
struct irq_chip_type *ct = gc->chip_types;
- unsigned int i;
+ unsigned int i, irq;
raw_spin_lock(&gc_lock);
list_add_tail(&gc->list, &gc_list);
@@ -247,18 +251,26 @@ void irq_setup_generic_chip(struct irq_chip_generic *gc, u32 msk,
if (flags & IRQ_GC_INIT_MASK_CACHE)
gc->mask_cache = irq_reg_readl(gc->reg_base + ct->regs.mask);
- for (i = gc->irq_base; msk; msk >>= 1, i++) {
+ gc->domain->nr_irq = fls(msk);
+ if ((int)gc->domain->irq_base == -1)
+ gc->domain->irq_base = irq_alloc_descs(-1, 1,
+ gc->domain->nr_irq,
+ numa_node_id());
+
+ irq_domain_add(gc->domain);
+
+ for (i = gc->domain->hwirq_base; msk; msk >>= 1, i++) {
if (!(msk & 0x01))
continue;
+ irq = irq_domain_to_irq(gc->domain, i);
if (flags & IRQ_GC_INIT_NESTED_LOCK)
- irq_set_lockdep_class(i, &irq_nested_lock_class);
+ irq_set_lockdep_class(irq, &irq_nested_lock_class);
- irq_set_chip_and_handler(i, &ct->chip, ct->handler);
- irq_set_chip_data(i, gc);
- irq_modify_status(i, clr, set);
+ irq_set_chip_and_handler(irq, &ct->chip, ct->handler);
+ irq_set_chip_data(irq, gc);
+ irq_modify_status(irq, clr, set);
}
- gc->irq_cnt = i - gc->irq_base;
}
EXPORT_SYMBOL_GPL(irq_setup_generic_chip);
@@ -298,7 +310,7 @@ EXPORT_SYMBOL_GPL(irq_setup_alt_chip);
void irq_remove_generic_chip(struct irq_chip_generic *gc, u32 msk,
unsigned int clr, unsigned int set)
{
- unsigned int i = gc->irq_base;
+ unsigned int i = gc->domain->irq_base;
raw_spin_lock(&gc_lock);
list_del(&gc->list);
@@ -324,9 +336,10 @@ static int irq_gc_suspend(void)
list_for_each_entry(gc, &gc_list, list) {
struct irq_chip_type *ct = gc->chip_types;
+ struct irq_domain *d = gc->domain;
if (ct->chip.irq_suspend)
- ct->chip.irq_suspend(irq_get_irq_data(gc->irq_base));
+ ct->chip.irq_suspend(irq_get_irq_data(d->irq_base));
}
return 0;
}
@@ -337,9 +350,10 @@ static void irq_gc_resume(void)
list_for_each_entry(gc, &gc_list, list) {
struct irq_chip_type *ct = gc->chip_types;
+ struct irq_domain *d = gc->domain;
if (ct->chip.irq_resume)
- ct->chip.irq_resume(irq_get_irq_data(gc->irq_base));
+ ct->chip.irq_resume(irq_get_irq_data(d->irq_base));
}
}
#else
@@ -353,9 +367,10 @@ static void irq_gc_shutdown(void)
list_for_each_entry(gc, &gc_list, list) {
struct irq_chip_type *ct = gc->chip_types;
+ struct irq_domain *d = gc->domain;
if (ct->chip.irq_pm_shutdown)
- ct->chip.irq_pm_shutdown(irq_get_irq_data(gc->irq_base));
+ ct->chip.irq_pm_shutdown(irq_get_irq_data(d->irq_base));
}
}
--
1.7.5.4
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [PATCH 3/9] irq: convert generic-chip to use irq_domain
2011-12-14 15:28 ` [PATCH 3/9] irq: convert generic-chip to use irq_domain Rob Herring
@ 2011-12-14 21:14 ` Grant Likely
2011-12-14 21:23 ` Rob Herring
2011-12-15 5:25 ` Shawn Guo
1 sibling, 1 reply; 43+ messages in thread
From: Grant Likely @ 2011-12-14 21:14 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Dec 14, 2011 at 8:28 AM, Rob Herring <robherring2@gmail.com> wrote:
> From: Rob Herring <rob.herring@calxeda.com>
>
> Add irq domain support to irq generic-chip. This enables users of
> generic-chip to support dynamic irq assignment needed for DT interrupt
> binding. Users must be converted to use irq_data.hwirq for determining
> local interrupt numbers rather than using the Linux irq number.
>
> irq_base is kept for now as there are a few users of it. Once they
> are converted to use the irq domain, it can be removed.
>
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> ---
> ?include/linux/irq.h ? ? ? | ? ?2 +-
> ?kernel/irq/Kconfig ? ? ? ?| ? ?1 +
> ?kernel/irq/generic-chip.c | ? 57 ++++++++++++++++++++++++++++----------------
> ?3 files changed, 38 insertions(+), 22 deletions(-)
>
> diff --git a/include/linux/irq.h b/include/linux/irq.h
> index bff29c5..9ba8a30 100644
> --- a/include/linux/irq.h
> +++ b/include/linux/irq.h
> @@ -664,7 +664,7 @@ struct irq_chip_generic {
> ? ? ? ?raw_spinlock_t ? ? ? ? ?lock;
> ? ? ? ?void __iomem ? ? ? ? ? ?*reg_base;
> ? ? ? ?unsigned int ? ? ? ? ? ?irq_base;
> - ? ? ? unsigned int ? ? ? ? ? ?irq_cnt;
> + ? ? ? struct irq_domain ? ? ? *domain;
Instead of making domain a pointer, why not embed the structure inside
irq_chip_generic? I don't see a reason for keeping it separate.
After changing that you can add my Acked-by for this patch.
g.
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply [flat|nested] 43+ messages in thread
* [PATCH 3/9] irq: convert generic-chip to use irq_domain
2011-12-14 21:14 ` Grant Likely
@ 2011-12-14 21:23 ` Rob Herring
2011-12-14 21:26 ` Grant Likely
0 siblings, 1 reply; 43+ messages in thread
From: Rob Herring @ 2011-12-14 21:23 UTC (permalink / raw)
To: linux-arm-kernel
On 12/14/2011 03:14 PM, Grant Likely wrote:
> On Wed, Dec 14, 2011 at 8:28 AM, Rob Herring <robherring2@gmail.com> wrote:
>> From: Rob Herring <rob.herring@calxeda.com>
>>
>> Add irq domain support to irq generic-chip. This enables users of
>> generic-chip to support dynamic irq assignment needed for DT interrupt
>> binding. Users must be converted to use irq_data.hwirq for determining
>> local interrupt numbers rather than using the Linux irq number.
>>
>> irq_base is kept for now as there are a few users of it. Once they
>> are converted to use the irq domain, it can be removed.
>>
>> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
>> Cc: Thomas Gleixner <tglx@linutronix.de>
>> ---
>> include/linux/irq.h | 2 +-
>> kernel/irq/Kconfig | 1 +
>> kernel/irq/generic-chip.c | 57 ++++++++++++++++++++++++++++----------------
>> 3 files changed, 38 insertions(+), 22 deletions(-)
>>
>> diff --git a/include/linux/irq.h b/include/linux/irq.h
>> index bff29c5..9ba8a30 100644
>> --- a/include/linux/irq.h
>> +++ b/include/linux/irq.h
>> @@ -664,7 +664,7 @@ struct irq_chip_generic {
>> raw_spinlock_t lock;
>> void __iomem *reg_base;
>> unsigned int irq_base;
>> - unsigned int irq_cnt;
>> + struct irq_domain *domain;
>
> Instead of making domain a pointer, why not embed the structure inside
> irq_chip_generic? I don't see a reason for keeping it separate.
>
There is a circular header dependency between irq.h and irq_domain.h.
Maybe I just need to put the include of irq_domain.h just above here
rather than the top of the file.
Rob
> After changing that you can add my Acked-by for this patch.
>
> g.
>
>
^ permalink raw reply [flat|nested] 43+ messages in thread
* [PATCH 3/9] irq: convert generic-chip to use irq_domain
2011-12-14 21:23 ` Rob Herring
@ 2011-12-14 21:26 ` Grant Likely
2011-12-14 23:29 ` Rob Herring
0 siblings, 1 reply; 43+ messages in thread
From: Grant Likely @ 2011-12-14 21:26 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Dec 14, 2011 at 2:23 PM, Rob Herring <robherring2@gmail.com> wrote:
>
>
> On 12/14/2011 03:14 PM, Grant Likely wrote:
>> On Wed, Dec 14, 2011 at 8:28 AM, Rob Herring <robherring2@gmail.com> wrote:
>>> From: Rob Herring <rob.herring@calxeda.com>
>>>
>>> Add irq domain support to irq generic-chip. This enables users of
>>> generic-chip to support dynamic irq assignment needed for DT interrupt
>>> binding. Users must be converted to use irq_data.hwirq for determining
>>> local interrupt numbers rather than using the Linux irq number.
>>>
>>> irq_base is kept for now as there are a few users of it. Once they
>>> are converted to use the irq domain, it can be removed.
>>>
>>> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
>>> Cc: Thomas Gleixner <tglx@linutronix.de>
>>> ---
>>> ?include/linux/irq.h ? ? ? | ? ?2 +-
>>> ?kernel/irq/Kconfig ? ? ? ?| ? ?1 +
>>> ?kernel/irq/generic-chip.c | ? 57 ++++++++++++++++++++++++++++----------------
>>> ?3 files changed, 38 insertions(+), 22 deletions(-)
>>>
>>> diff --git a/include/linux/irq.h b/include/linux/irq.h
>>> index bff29c5..9ba8a30 100644
>>> --- a/include/linux/irq.h
>>> +++ b/include/linux/irq.h
>>> @@ -664,7 +664,7 @@ struct irq_chip_generic {
>>> ? ? ? ?raw_spinlock_t ? ? ? ? ?lock;
>>> ? ? ? ?void __iomem ? ? ? ? ? ?*reg_base;
>>> ? ? ? ?unsigned int ? ? ? ? ? ?irq_base;
>>> - ? ? ? unsigned int ? ? ? ? ? ?irq_cnt;
>>> + ? ? ? struct irq_domain ? ? ? *domain;
>>
>> Instead of making domain a pointer, why not embed the structure inside
>> irq_chip_generic? ?I don't see a reason for keeping it separate.
>>
>
> There is a circular header dependency between irq.h and irq_domain.h.
> Maybe I just need to put the include of irq_domain.h just above here
> rather than the top of the file.
Yes, try that. I'd rather get the dependency problem sorted out.
Alternately, problematic bit of irq_domain.h can be moved to another
header.
g.
^ permalink raw reply [flat|nested] 43+ messages in thread
* [PATCH 3/9] irq: convert generic-chip to use irq_domain
2011-12-14 21:26 ` Grant Likely
@ 2011-12-14 23:29 ` Rob Herring
0 siblings, 0 replies; 43+ messages in thread
From: Rob Herring @ 2011-12-14 23:29 UTC (permalink / raw)
To: linux-arm-kernel
On 12/14/2011 03:26 PM, Grant Likely wrote:
> On Wed, Dec 14, 2011 at 2:23 PM, Rob Herring <robherring2@gmail.com> wrote:
>>
>>
>> On 12/14/2011 03:14 PM, Grant Likely wrote:
>>> On Wed, Dec 14, 2011 at 8:28 AM, Rob Herring <robherring2@gmail.com> wrote:
>>>> From: Rob Herring <rob.herring@calxeda.com>
>>>>
>>>> Add irq domain support to irq generic-chip. This enables users of
>>>> generic-chip to support dynamic irq assignment needed for DT interrupt
>>>> binding. Users must be converted to use irq_data.hwirq for determining
>>>> local interrupt numbers rather than using the Linux irq number.
>>>>
>>>> irq_base is kept for now as there are a few users of it. Once they
>>>> are converted to use the irq domain, it can be removed.
>>>>
>>>> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
>>>> Cc: Thomas Gleixner <tglx@linutronix.de>
>>>> ---
>>>> include/linux/irq.h | 2 +-
>>>> kernel/irq/Kconfig | 1 +
>>>> kernel/irq/generic-chip.c | 57 ++++++++++++++++++++++++++++----------------
>>>> 3 files changed, 38 insertions(+), 22 deletions(-)
>>>>
>>>> diff --git a/include/linux/irq.h b/include/linux/irq.h
>>>> index bff29c5..9ba8a30 100644
>>>> --- a/include/linux/irq.h
>>>> +++ b/include/linux/irq.h
>>>> @@ -664,7 +664,7 @@ struct irq_chip_generic {
>>>> raw_spinlock_t lock;
>>>> void __iomem *reg_base;
>>>> unsigned int irq_base;
>>>> - unsigned int irq_cnt;
>>>> + struct irq_domain *domain;
>>>
>>> Instead of making domain a pointer, why not embed the structure inside
>>> irq_chip_generic? I don't see a reason for keeping it separate.
>>>
>>
>> There is a circular header dependency between irq.h and irq_domain.h.
>> Maybe I just need to put the include of irq_domain.h just above here
>> rather than the top of the file.
>
> Yes, try that. I'd rather get the dependency problem sorted out.
> Alternately, problematic bit of irq_domain.h can be moved to another
> header.
>
Things always start out so simple...
Removing irq.h from irqdomain.h fixes my original problem. However, that
breaks on x86 since x86 has it's own struct irq_domain. Some ifdef'ing
could fix it since x86 doesn't use irq_chip_generic. Didn't you have
converting x86 in your original irq domain patches?
Rob
^ permalink raw reply [flat|nested] 43+ messages in thread
* [PATCH 3/9] irq: convert generic-chip to use irq_domain
2011-12-14 15:28 ` [PATCH 3/9] irq: convert generic-chip to use irq_domain Rob Herring
2011-12-14 21:14 ` Grant Likely
@ 2011-12-15 5:25 ` Shawn Guo
2011-12-15 5:55 ` Shawn Guo
1 sibling, 1 reply; 43+ messages in thread
From: Shawn Guo @ 2011-12-15 5:25 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Dec 14, 2011 at 09:28:52AM -0600, Rob Herring wrote:
> From: Rob Herring <rob.herring@calxeda.com>
>
> Add irq domain support to irq generic-chip. This enables users of
> generic-chip to support dynamic irq assignment needed for DT interrupt
> binding. Users must be converted to use irq_data.hwirq for determining
> local interrupt numbers rather than using the Linux irq number.
>
> irq_base is kept for now as there are a few users of it. Once they
> are converted to use the irq domain, it can be removed.
>
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> Cc: Thomas Gleixner <tglx@linutronix.de>
> ---
Tested-by: Shawn Guo <shawn.guo@linaro.org>
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 43+ messages in thread
* [PATCH 3/9] irq: convert generic-chip to use irq_domain
2011-12-15 5:25 ` Shawn Guo
@ 2011-12-15 5:55 ` Shawn Guo
2011-12-15 13:39 ` Rob Herring
0 siblings, 1 reply; 43+ messages in thread
From: Shawn Guo @ 2011-12-15 5:55 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, Dec 15, 2011 at 01:25:20PM +0800, Shawn Guo wrote:
> On Wed, Dec 14, 2011 at 09:28:52AM -0600, Rob Herring wrote:
> > From: Rob Herring <rob.herring@calxeda.com>
> >
> > Add irq domain support to irq generic-chip. This enables users of
> > generic-chip to support dynamic irq assignment needed for DT interrupt
> > binding. Users must be converted to use irq_data.hwirq for determining
> > local interrupt numbers rather than using the Linux irq number.
> >
> > irq_base is kept for now as there are a few users of it. Once they
> > are converted to use the irq domain, it can be removed.
> >
> > Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> > Cc: Thomas Gleixner <tglx@linutronix.de>
> > ---
>
> Tested-by: Shawn Guo <shawn.guo@linaro.org>
>
Sorry, I have to take that tag back after I correct my test setup.
It does not work for imx5 TZIC case, because the following change
I suggested before is missed.
diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
index eb763f7..2a2aac1 100644
--- a/kernel/irq/irqdomain.c
+++ b/kernel/irq/irqdomain.c
@@ -39,7 +39,7 @@ void irq_domain_add(struct irq_domain *domain)
return;
}
d->domain = domain;
- d->hwirq = hwirq;
+ d->hwirq = hwirq - domain->hwirq_base;
}
mutex_lock(&irq_domain_mutex);
--
Regards,
Shawn
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [PATCH 3/9] irq: convert generic-chip to use irq_domain
2011-12-15 5:55 ` Shawn Guo
@ 2011-12-15 13:39 ` Rob Herring
2011-12-15 13:56 ` Rob Herring
2011-12-15 14:08 ` Shawn Guo
0 siblings, 2 replies; 43+ messages in thread
From: Rob Herring @ 2011-12-15 13:39 UTC (permalink / raw)
To: linux-arm-kernel
On 12/14/2011 11:55 PM, Shawn Guo wrote:
> On Thu, Dec 15, 2011 at 01:25:20PM +0800, Shawn Guo wrote:
>> On Wed, Dec 14, 2011 at 09:28:52AM -0600, Rob Herring wrote:
>>> From: Rob Herring <rob.herring@calxeda.com>
>>>
>>> Add irq domain support to irq generic-chip. This enables users of
>>> generic-chip to support dynamic irq assignment needed for DT interrupt
>>> binding. Users must be converted to use irq_data.hwirq for determining
>>> local interrupt numbers rather than using the Linux irq number.
>>>
>>> irq_base is kept for now as there are a few users of it. Once they
>>> are converted to use the irq domain, it can be removed.
>>>
>>> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
>>> Cc: Thomas Gleixner <tglx@linutronix.de>
>>> ---
>>
>> Tested-by: Shawn Guo <shawn.guo@linaro.org>
>>
> Sorry, I have to take that tag back after I correct my test setup.
> It does not work for imx5 TZIC case, because the following change
> I suggested before is missed.
>
> diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
> index eb763f7..2a2aac1 100644
> --- a/kernel/irq/irqdomain.c
> +++ b/kernel/irq/irqdomain.c
> @@ -39,7 +39,7 @@ void irq_domain_add(struct irq_domain *domain)
> return;
> }
> d->domain = domain;
> - d->hwirq = hwirq;
> + d->hwirq = hwirq - domain->hwirq_base;
This is a problem. It entirely defeats the point of hwirq_base and it
would break the GIC. We need to fix this in the generic irq chip.
Rob
> }
>
> mutex_lock(&irq_domain_mutex);
>
^ permalink raw reply [flat|nested] 43+ messages in thread
* [PATCH 3/9] irq: convert generic-chip to use irq_domain
2011-12-15 13:39 ` Rob Herring
@ 2011-12-15 13:56 ` Rob Herring
2011-12-15 14:15 ` Shawn Guo
` (2 more replies)
2011-12-15 14:08 ` Shawn Guo
1 sibling, 3 replies; 43+ messages in thread
From: Rob Herring @ 2011-12-15 13:56 UTC (permalink / raw)
To: linux-arm-kernel
Shawn,
On 12/15/2011 07:39 AM, Rob Herring wrote:
> On 12/14/2011 11:55 PM, Shawn Guo wrote:
>> On Thu, Dec 15, 2011 at 01:25:20PM +0800, Shawn Guo wrote:
>>> On Wed, Dec 14, 2011 at 09:28:52AM -0600, Rob Herring wrote:
>>>> From: Rob Herring <rob.herring@calxeda.com>
>>>>
>>>> Add irq domain support to irq generic-chip. This enables users of
>>>> generic-chip to support dynamic irq assignment needed for DT interrupt
>>>> binding. Users must be converted to use irq_data.hwirq for determining
>>>> local interrupt numbers rather than using the Linux irq number.
>>>>
>>>> irq_base is kept for now as there are a few users of it. Once they
>>>> are converted to use the irq domain, it can be removed.
>>>>
>>>> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
>>>> Cc: Thomas Gleixner <tglx@linutronix.de>
>>>> ---
>>>
>>> Tested-by: Shawn Guo <shawn.guo@linaro.org>
>>>
>> Sorry, I have to take that tag back after I correct my test setup.
>> It does not work for imx5 TZIC case, because the following change
>> I suggested before is missed.
>>
>> diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
>> index eb763f7..2a2aac1 100644
>> --- a/kernel/irq/irqdomain.c
>> +++ b/kernel/irq/irqdomain.c
>> @@ -39,7 +39,7 @@ void irq_domain_add(struct irq_domain *domain)
>> return;
>> }
>> d->domain = domain;
>> - d->hwirq = hwirq;
>> + d->hwirq = hwirq - domain->hwirq_base;
>
> This is a problem. It entirely defeats the point of hwirq_base and it
> would break the GIC. We need to fix this in the generic irq chip.
>
I think I found a fix. Can you try 's/d->hwirq/(d->hwirq % 32)/' in
generic-chip.c.
Rob
^ permalink raw reply [flat|nested] 43+ messages in thread
* [PATCH 3/9] irq: convert generic-chip to use irq_domain
2011-12-15 13:56 ` Rob Herring
@ 2011-12-15 14:15 ` Shawn Guo
2011-12-15 14:46 ` Shawn Guo
2011-12-15 15:55 ` Grant Likely
2 siblings, 0 replies; 43+ messages in thread
From: Shawn Guo @ 2011-12-15 14:15 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, Dec 15, 2011 at 07:56:41AM -0600, Rob Herring wrote:
[...]
> >> diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
> >> index eb763f7..2a2aac1 100644
> >> --- a/kernel/irq/irqdomain.c
> >> +++ b/kernel/irq/irqdomain.c
> >> @@ -39,7 +39,7 @@ void irq_domain_add(struct irq_domain *domain)
> >> return;
> >> }
> >> d->domain = domain;
> >> - d->hwirq = hwirq;
> >> + d->hwirq = hwirq - domain->hwirq_base;
> >
> > This is a problem. It entirely defeats the point of hwirq_base and it
> > would break the GIC. We need to fix this in the generic irq chip.
> >
>
> I think I found a fix. Can you try 's/d->hwirq/(d->hwirq % 32)/' in
> generic-chip.c.
>
Needless to try (will try later), this will work. But again, what do
we need to change 'd->irq - d->irq_base' at all?
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 43+ messages in thread
* [PATCH 3/9] irq: convert generic-chip to use irq_domain
2011-12-15 13:56 ` Rob Herring
2011-12-15 14:15 ` Shawn Guo
@ 2011-12-15 14:46 ` Shawn Guo
2011-12-15 15:55 ` Grant Likely
2 siblings, 0 replies; 43+ messages in thread
From: Shawn Guo @ 2011-12-15 14:46 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, Dec 15, 2011 at 07:56:41AM -0600, Rob Herring wrote:
[...]
> I think I found a fix. Can you try 's/d->hwirq/(d->hwirq % 32)/' in
> generic-chip.c.
>
Tried, it works.
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 43+ messages in thread
* [PATCH 3/9] irq: convert generic-chip to use irq_domain
2011-12-15 13:56 ` Rob Herring
2011-12-15 14:15 ` Shawn Guo
2011-12-15 14:46 ` Shawn Guo
@ 2011-12-15 15:55 ` Grant Likely
2011-12-15 16:17 ` Rob Herring
2 siblings, 1 reply; 43+ messages in thread
From: Grant Likely @ 2011-12-15 15:55 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, Dec 15, 2011 at 6:56 AM, Rob Herring <robherring2@gmail.com> wrote:
> Shawn,
>
> On 12/15/2011 07:39 AM, Rob Herring wrote:
>> On 12/14/2011 11:55 PM, Shawn Guo wrote:
>>> On Thu, Dec 15, 2011 at 01:25:20PM +0800, Shawn Guo wrote:
>>>> On Wed, Dec 14, 2011 at 09:28:52AM -0600, Rob Herring wrote:
>>>>> From: Rob Herring <rob.herring@calxeda.com>
>>>>>
>>>>> Add irq domain support to irq generic-chip. This enables users of
>>>>> generic-chip to support dynamic irq assignment needed for DT interrupt
>>>>> binding. Users must be converted to use irq_data.hwirq for determining
>>>>> local interrupt numbers rather than using the Linux irq number.
>>>>>
>>>>> irq_base is kept for now as there are a few users of it. Once they
>>>>> are converted to use the irq domain, it can be removed.
>>>>>
>>>>> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
>>>>> Cc: Thomas Gleixner <tglx@linutronix.de>
>>>>> ---
>>>>
>>>> Tested-by: Shawn Guo <shawn.guo@linaro.org>
>>>>
>>> Sorry, I have to take that tag back after I correct my test setup.
>>> It does not work for imx5 TZIC case, because the following change
>>> I suggested before is missed.
>>>
>>> diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
>>> index eb763f7..2a2aac1 100644
>>> --- a/kernel/irq/irqdomain.c
>>> +++ b/kernel/irq/irqdomain.c
>>> @@ -39,7 +39,7 @@ void irq_domain_add(struct irq_domain *domain)
>>> ? ? ? ? ? ? ? ? ? ? ? ? return;
>>> ? ? ? ? ? ? ? ? }
>>> ? ? ? ? ? ? ? ? d->domain = domain;
>>> - ? ? ? ? ? ? ? d->hwirq = hwirq;
>>> + ? ? ? ? ? ? ? d->hwirq = hwirq - domain->hwirq_base;
>>
>> This is a problem. It entirely defeats the point of hwirq_base and it
>> would break the GIC. We need to fix this in the generic irq chip.
>>
>
> I think I found a fix. Can you try 's/d->hwirq/(d->hwirq % 32)/' in
> generic-chip.c.
Ugh, but that hard codes an assumption that a domain cannot have more
that 32 irqs.
/me goes to dig into irq_domain code...
g.
^ permalink raw reply [flat|nested] 43+ messages in thread
* [PATCH 3/9] irq: convert generic-chip to use irq_domain
2011-12-15 15:55 ` Grant Likely
@ 2011-12-15 16:17 ` Rob Herring
2011-12-15 16:39 ` Grant Likely
0 siblings, 1 reply; 43+ messages in thread
From: Rob Herring @ 2011-12-15 16:17 UTC (permalink / raw)
To: linux-arm-kernel
On 12/15/2011 09:55 AM, Grant Likely wrote:
> On Thu, Dec 15, 2011 at 6:56 AM, Rob Herring <robherring2@gmail.com> wrote:
>> Shawn,
>>
>> On 12/15/2011 07:39 AM, Rob Herring wrote:
>>> On 12/14/2011 11:55 PM, Shawn Guo wrote:
>>>> On Thu, Dec 15, 2011 at 01:25:20PM +0800, Shawn Guo wrote:
>>>>> On Wed, Dec 14, 2011 at 09:28:52AM -0600, Rob Herring wrote:
>>>>>> From: Rob Herring <rob.herring@calxeda.com>
>>>>>>
>>>>>> Add irq domain support to irq generic-chip. This enables users of
>>>>>> generic-chip to support dynamic irq assignment needed for DT interrupt
>>>>>> binding. Users must be converted to use irq_data.hwirq for determining
>>>>>> local interrupt numbers rather than using the Linux irq number.
>>>>>>
>>>>>> irq_base is kept for now as there are a few users of it. Once they
>>>>>> are converted to use the irq domain, it can be removed.
>>>>>>
>>>>>> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
>>>>>> Cc: Thomas Gleixner <tglx@linutronix.de>
>>>>>> ---
>>>>>
>>>>> Tested-by: Shawn Guo <shawn.guo@linaro.org>
>>>>>
>>>> Sorry, I have to take that tag back after I correct my test setup.
>>>> It does not work for imx5 TZIC case, because the following change
>>>> I suggested before is missed.
>>>>
>>>> diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
>>>> index eb763f7..2a2aac1 100644
>>>> --- a/kernel/irq/irqdomain.c
>>>> +++ b/kernel/irq/irqdomain.c
>>>> @@ -39,7 +39,7 @@ void irq_domain_add(struct irq_domain *domain)
>>>> return;
>>>> }
>>>> d->domain = domain;
>>>> - d->hwirq = hwirq;
>>>> + d->hwirq = hwirq - domain->hwirq_base;
>>>
>>> This is a problem. It entirely defeats the point of hwirq_base and it
>>> would break the GIC. We need to fix this in the generic irq chip.
>>>
>>
>> I think I found a fix. Can you try 's/d->hwirq/(d->hwirq % 32)/' in
>> generic-chip.c.
>
> Ugh, but that hard codes an assumption that a domain cannot have more
> that 32 irqs.
>
> /me goes to dig into irq_domain code...
No, it hard codes that generic irq chip is 32 interrupts at most which
is already the case. That's why the TZIC uses 5 generic irq chip instances.
Rob
^ permalink raw reply [flat|nested] 43+ messages in thread
* [PATCH 3/9] irq: convert generic-chip to use irq_domain
2011-12-15 16:17 ` Rob Herring
@ 2011-12-15 16:39 ` Grant Likely
0 siblings, 0 replies; 43+ messages in thread
From: Grant Likely @ 2011-12-15 16:39 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, Dec 15, 2011 at 9:17 AM, Rob Herring <robherring2@gmail.com> wrote:
> On 12/15/2011 09:55 AM, Grant Likely wrote:
>> On Thu, Dec 15, 2011 at 6:56 AM, Rob Herring <robherring2@gmail.com> wrote:
>>> Shawn,
>>>
>>> On 12/15/2011 07:39 AM, Rob Herring wrote:
>>>> On 12/14/2011 11:55 PM, Shawn Guo wrote:
>>>>> On Thu, Dec 15, 2011 at 01:25:20PM +0800, Shawn Guo wrote:
>>>>>> On Wed, Dec 14, 2011 at 09:28:52AM -0600, Rob Herring wrote:
>>>>>>> From: Rob Herring <rob.herring@calxeda.com>
>>>>>>>
>>>>>>> Add irq domain support to irq generic-chip. This enables users of
>>>>>>> generic-chip to support dynamic irq assignment needed for DT interrupt
>>>>>>> binding. Users must be converted to use irq_data.hwirq for determining
>>>>>>> local interrupt numbers rather than using the Linux irq number.
>>>>>>>
>>>>>>> irq_base is kept for now as there are a few users of it. Once they
>>>>>>> are converted to use the irq domain, it can be removed.
>>>>>>>
>>>>>>> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
>>>>>>> Cc: Thomas Gleixner <tglx@linutronix.de>
>>>>>>> ---
>>>>>>
>>>>>> Tested-by: Shawn Guo <shawn.guo@linaro.org>
>>>>>>
>>>>> Sorry, I have to take that tag back after I correct my test setup.
>>>>> It does not work for imx5 TZIC case, because the following change
>>>>> I suggested before is missed.
>>>>>
>>>>> diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
>>>>> index eb763f7..2a2aac1 100644
>>>>> --- a/kernel/irq/irqdomain.c
>>>>> +++ b/kernel/irq/irqdomain.c
>>>>> @@ -39,7 +39,7 @@ void irq_domain_add(struct irq_domain *domain)
>>>>> ? ? ? ? ? ? ? ? ? ? ? ? return;
>>>>> ? ? ? ? ? ? ? ? }
>>>>> ? ? ? ? ? ? ? ? d->domain = domain;
>>>>> - ? ? ? ? ? ? ? d->hwirq = hwirq;
>>>>> + ? ? ? ? ? ? ? d->hwirq = hwirq - domain->hwirq_base;
>>>>
>>>> This is a problem. It entirely defeats the point of hwirq_base and it
>>>> would break the GIC. We need to fix this in the generic irq chip.
>>>>
>>>
>>> I think I found a fix. Can you try 's/d->hwirq/(d->hwirq % 32)/' in
>>> generic-chip.c.
>>
>> Ugh, but that hard codes an assumption that a domain cannot have more
>> that 32 irqs.
>>
>> /me goes to dig into irq_domain code...
>
> No, it hard codes that generic irq chip is 32 interrupts at most which
> is already the case. That's why the TZIC uses 5 generic irq chip instances.
Oops, you're right. I wasn't paying close enough attention. Sorry for
the noise.
g.
^ permalink raw reply [flat|nested] 43+ messages in thread
* [PATCH 3/9] irq: convert generic-chip to use irq_domain
2011-12-15 13:39 ` Rob Herring
2011-12-15 13:56 ` Rob Herring
@ 2011-12-15 14:08 ` Shawn Guo
2011-12-15 14:01 ` Rob Herring
1 sibling, 1 reply; 43+ messages in thread
From: Shawn Guo @ 2011-12-15 14:08 UTC (permalink / raw)
To: linux-arm-kernel
On Thu, Dec 15, 2011 at 07:39:37AM -0600, Rob Herring wrote:
> On 12/14/2011 11:55 PM, Shawn Guo wrote:
> > On Thu, Dec 15, 2011 at 01:25:20PM +0800, Shawn Guo wrote:
> >> On Wed, Dec 14, 2011 at 09:28:52AM -0600, Rob Herring wrote:
> >>> From: Rob Herring <rob.herring@calxeda.com>
> >>>
> >>> Add irq domain support to irq generic-chip. This enables users of
> >>> generic-chip to support dynamic irq assignment needed for DT interrupt
> >>> binding. Users must be converted to use irq_data.hwirq for determining
> >>> local interrupt numbers rather than using the Linux irq number.
> >>>
> >>> irq_base is kept for now as there are a few users of it. Once they
> >>> are converted to use the irq domain, it can be removed.
> >>>
> >>> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> >>> Cc: Thomas Gleixner <tglx@linutronix.de>
> >>> ---
> >>
> >> Tested-by: Shawn Guo <shawn.guo@linaro.org>
> >>
> > Sorry, I have to take that tag back after I correct my test setup.
> > It does not work for imx5 TZIC case, because the following change
> > I suggested before is missed.
> >
> > diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
> > index eb763f7..2a2aac1 100644
> > --- a/kernel/irq/irqdomain.c
> > +++ b/kernel/irq/irqdomain.c
> > @@ -39,7 +39,7 @@ void irq_domain_add(struct irq_domain *domain)
> > return;
> > }
> > d->domain = domain;
> > - d->hwirq = hwirq;
> > + d->hwirq = hwirq - domain->hwirq_base;
>
> This is a problem. It entirely defeats the point of hwirq_base and it
> would break the GIC. We need to fix this in the generic irq chip.
>
Actually I do not quite understand why we need to make the following
change all over generic-chip.c.
- u32 mask = 1 << (d->irq - gc->irq_base);
+ u32 mask = 1 << d->hwirq;
Though d->irq is the Linux irq number, "d->irq - gc->irq_base" is
really just what we need here.
--
Regards,
Shawn
^ permalink raw reply [flat|nested] 43+ messages in thread
* [PATCH 3/9] irq: convert generic-chip to use irq_domain
2011-12-15 14:08 ` Shawn Guo
@ 2011-12-15 14:01 ` Rob Herring
0 siblings, 0 replies; 43+ messages in thread
From: Rob Herring @ 2011-12-15 14:01 UTC (permalink / raw)
To: linux-arm-kernel
On 12/15/2011 08:08 AM, Shawn Guo wrote:
> On Thu, Dec 15, 2011 at 07:39:37AM -0600, Rob Herring wrote:
>> On 12/14/2011 11:55 PM, Shawn Guo wrote:
>>> On Thu, Dec 15, 2011 at 01:25:20PM +0800, Shawn Guo wrote:
>>>> On Wed, Dec 14, 2011 at 09:28:52AM -0600, Rob Herring wrote:
>>>>> From: Rob Herring <rob.herring@calxeda.com>
>>>>>
>>>>> Add irq domain support to irq generic-chip. This enables users of
>>>>> generic-chip to support dynamic irq assignment needed for DT interrupt
>>>>> binding. Users must be converted to use irq_data.hwirq for determining
>>>>> local interrupt numbers rather than using the Linux irq number.
>>>>>
>>>>> irq_base is kept for now as there are a few users of it. Once they
>>>>> are converted to use the irq domain, it can be removed.
>>>>>
>>>>> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
>>>>> Cc: Thomas Gleixner <tglx@linutronix.de>
>>>>> ---
>>>>
>>>> Tested-by: Shawn Guo <shawn.guo@linaro.org>
>>>>
>>> Sorry, I have to take that tag back after I correct my test setup.
>>> It does not work for imx5 TZIC case, because the following change
>>> I suggested before is missed.
>>>
>>> diff --git a/kernel/irq/irqdomain.c b/kernel/irq/irqdomain.c
>>> index eb763f7..2a2aac1 100644
>>> --- a/kernel/irq/irqdomain.c
>>> +++ b/kernel/irq/irqdomain.c
>>> @@ -39,7 +39,7 @@ void irq_domain_add(struct irq_domain *domain)
>>> return;
>>> }
>>> d->domain = domain;
>>> - d->hwirq = hwirq;
>>> + d->hwirq = hwirq - domain->hwirq_base;
>>
>> This is a problem. It entirely defeats the point of hwirq_base and it
>> would break the GIC. We need to fix this in the generic irq chip.
>>
> Actually I do not quite understand why we need to make the following
> change all over generic-chip.c.
>
> - u32 mask = 1 << (d->irq - gc->irq_base);
> + u32 mask = 1 << d->hwirq;
>
> Though d->irq is the Linux irq number, "d->irq - gc->irq_base" is
> really just what we need here.
That's assuming a linear mapping between the irq and hwirq. What if we
start allocating irq_descs on demand within a domain? Then there would
be no way to convert.
Rob
^ permalink raw reply [flat|nested] 43+ messages in thread
* [PATCH 4/9] gpio: pl061: use chained_irq_* functions in irq handler
2011-12-14 15:28 [PATCH 0/9] irq domain for gen irq chip and pl061 DT irq support Rob Herring
` (2 preceding siblings ...)
2011-12-14 15:28 ` [PATCH 3/9] irq: convert generic-chip to use irq_domain Rob Herring
@ 2011-12-14 15:28 ` Rob Herring
2011-12-14 21:15 ` Grant Likely
2011-12-14 15:28 ` [PATCH 5/9] gpio: pl061: convert to use 0 for no irq Rob Herring
` (5 subsequent siblings)
9 siblings, 1 reply; 43+ messages in thread
From: Rob Herring @ 2011-12-14 15:28 UTC (permalink / raw)
To: linux-arm-kernel
From: Rob Herring <rob.herring@calxeda.com>
Use chained_irq_enter/exit helper functions instead of direct pointer
accesses. This is needed for generic irq chip conversion.
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Linus Walleij <linus.ml.walleij@gmail.com>
---
drivers/gpio/gpio-pl061.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c
index 4102f63..0f718f9 100644
--- a/drivers/gpio/gpio-pl061.c
+++ b/drivers/gpio/gpio-pl061.c
@@ -23,6 +23,7 @@
#include <linux/amba/bus.h>
#include <linux/amba/pl061.h>
#include <linux/slab.h>
+#include <asm/mach/irq.h>
#define GPIODIR 0x400
#define GPIOIS 0x404
@@ -211,8 +212,9 @@ static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
struct list_head *chip_list = irq_get_handler_data(irq);
struct list_head *ptr;
struct pl061_gpio *chip;
+ struct irq_chip *irqchip = irq_desc_get_chip(desc);
- desc->irq_data.chip->irq_ack(&desc->irq_data);
+ chained_irq_enter(irqchip, desc);
list_for_each(ptr, chip_list) {
unsigned long pending;
int offset;
@@ -227,7 +229,7 @@ static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
for_each_set_bit(offset, &pending, PL061_GPIO_NR)
generic_handle_irq(pl061_to_irq(&chip->gc, offset));
}
- desc->irq_data.chip->irq_unmask(&desc->irq_data);
+ chained_irq_exit(irqchip, desc);
}
static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
--
1.7.5.4
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [PATCH 4/9] gpio: pl061: use chained_irq_* functions in irq handler
2011-12-14 15:28 ` [PATCH 4/9] gpio: pl061: use chained_irq_* functions in irq handler Rob Herring
@ 2011-12-14 21:15 ` Grant Likely
0 siblings, 0 replies; 43+ messages in thread
From: Grant Likely @ 2011-12-14 21:15 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Dec 14, 2011 at 8:28 AM, Rob Herring <robherring2@gmail.com> wrote:
> From: Rob Herring <rob.herring@calxeda.com>
>
> Use chained_irq_enter/exit helper functions instead of direct pointer
> accesses. This is needed for generic irq chip conversion.
>
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> Cc: Grant Likely <grant.likely@secretlab.ca>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
> Cc: Linus Walleij <linus.ml.walleij@gmail.com>
> ---
> ?drivers/gpio/gpio-pl061.c | ? ?6 ++++--
> ?1 files changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c
> index 4102f63..0f718f9 100644
> --- a/drivers/gpio/gpio-pl061.c
> +++ b/drivers/gpio/gpio-pl061.c
> @@ -23,6 +23,7 @@
> ?#include <linux/amba/bus.h>
> ?#include <linux/amba/pl061.h>
> ?#include <linux/slab.h>
> +#include <asm/mach/irq.h>
>
> ?#define GPIODIR 0x400
> ?#define GPIOIS ?0x404
> @@ -211,8 +212,9 @@ static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
> ? ? ? ?struct list_head *chip_list = irq_get_handler_data(irq);
> ? ? ? ?struct list_head *ptr;
> ? ? ? ?struct pl061_gpio *chip;
> + ? ? ? struct irq_chip *irqchip = irq_desc_get_chip(desc);
>
> - ? ? ? desc->irq_data.chip->irq_ack(&desc->irq_data);
> + ? ? ? chained_irq_enter(irqchip, desc);
> ? ? ? ?list_for_each(ptr, chip_list) {
> ? ? ? ? ? ? ? ?unsigned long pending;
> ? ? ? ? ? ? ? ?int offset;
> @@ -227,7 +229,7 @@ static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
> ? ? ? ? ? ? ? ?for_each_set_bit(offset, &pending, PL061_GPIO_NR)
> ? ? ? ? ? ? ? ? ? ? ? ?generic_handle_irq(pl061_to_irq(&chip->gc, offset));
> ? ? ? ?}
> - ? ? ? desc->irq_data.chip->irq_unmask(&desc->irq_data);
> + ? ? ? chained_irq_exit(irqchip, desc);
> ?}
>
> ?static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
> --
> 1.7.5.4
>
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply [flat|nested] 43+ messages in thread
* [PATCH 5/9] gpio: pl061: convert to use 0 for no irq
2011-12-14 15:28 [PATCH 0/9] irq domain for gen irq chip and pl061 DT irq support Rob Herring
` (3 preceding siblings ...)
2011-12-14 15:28 ` [PATCH 4/9] gpio: pl061: use chained_irq_* functions in irq handler Rob Herring
@ 2011-12-14 15:28 ` Rob Herring
2011-12-14 21:16 ` Grant Likely
2011-12-14 15:28 ` [PATCH 6/9] ARM: realview: convert pl061 no irq to 0 instead of -1 Rob Herring
` (4 subsequent siblings)
9 siblings, 1 reply; 43+ messages in thread
From: Rob Herring @ 2011-12-14 15:28 UTC (permalink / raw)
To: linux-arm-kernel
From: Rob Herring <rob.herring@calxeda.com>
We don't want drivers using NO_IRQ, so remove its use. For now, 0 or
-1 means no irq until platforms are converted to use 0.
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Linus Walleij <linus.ml.walleij@gmail.com>
---
drivers/gpio/gpio-pl061.c | 8 ++++----
include/linux/amba/pl061.h | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c
index 0f718f9..fe19dec 100644
--- a/drivers/gpio/gpio-pl061.c
+++ b/drivers/gpio/gpio-pl061.c
@@ -53,7 +53,7 @@ struct pl061_gpio {
spinlock_t irq_lock; /* IRQ registers */
void __iomem *base;
- unsigned irq_base;
+ int irq_base;
struct gpio_chip gc;
};
@@ -119,7 +119,7 @@ static int pl061_to_irq(struct gpio_chip *gc, unsigned offset)
{
struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
- if (chip->irq_base == NO_IRQ)
+ if (chip->irq_base <= 0)
return -EINVAL;
return chip->irq_base + offset;
@@ -250,7 +250,7 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
chip->irq_base = pdata->irq_base;
} else if (dev->dev.of_node) {
chip->gc.base = -1;
- chip->irq_base = NO_IRQ;
+ chip->irq_base = 0;
} else {
ret = -ENODEV;
goto free_mem;
@@ -290,7 +290,7 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
* irq_chip support
*/
- if (chip->irq_base == NO_IRQ)
+ if (chip->irq_base <= 0)
return 0;
writeb(0, chip->base + GPIOIE); /* disable irqs */
diff --git a/include/linux/amba/pl061.h b/include/linux/amba/pl061.h
index 2412af9..fb83c04 100644
--- a/include/linux/amba/pl061.h
+++ b/include/linux/amba/pl061.h
@@ -7,7 +7,7 @@ struct pl061_platform_data {
unsigned gpio_base;
/* number of the first IRQ.
- * If the IRQ functionality in not desired this must be set to NO_IRQ.
+ * If the IRQ functionality in not desired this must be set to 0.
*/
unsigned irq_base;
--
1.7.5.4
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [PATCH 5/9] gpio: pl061: convert to use 0 for no irq
2011-12-14 15:28 ` [PATCH 5/9] gpio: pl061: convert to use 0 for no irq Rob Herring
@ 2011-12-14 21:16 ` Grant Likely
0 siblings, 0 replies; 43+ messages in thread
From: Grant Likely @ 2011-12-14 21:16 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Dec 14, 2011 at 8:28 AM, Rob Herring <robherring2@gmail.com> wrote:
> From: Rob Herring <rob.herring@calxeda.com>
>
> We don't want drivers using NO_IRQ, so remove its use. For now, 0 or
> -1 means no irq until platforms are converted to use 0.
>
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> Cc: Grant Likely <grant.likely@secretlab.ca>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
> Cc: Linus Walleij <linus.ml.walleij@gmail.com>
> ---
> ?drivers/gpio/gpio-pl061.c ?| ? ?8 ++++----
> ?include/linux/amba/pl061.h | ? ?2 +-
> ?2 files changed, 5 insertions(+), 5 deletions(-)
>
> diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c
> index 0f718f9..fe19dec 100644
> --- a/drivers/gpio/gpio-pl061.c
> +++ b/drivers/gpio/gpio-pl061.c
> @@ -53,7 +53,7 @@ struct pl061_gpio {
> ? ? ? ?spinlock_t ? ? ? ? ? ? ?irq_lock; ? ? ? /* IRQ registers */
>
> ? ? ? ?void __iomem ? ? ? ? ? ?*base;
> - ? ? ? unsigned ? ? ? ? ? ? ? ?irq_base;
> + ? ? ? int ? ? ? ? ? ? ? ? ? ? irq_base;
> ? ? ? ?struct gpio_chip ? ? ? ?gc;
> ?};
>
> @@ -119,7 +119,7 @@ static int pl061_to_irq(struct gpio_chip *gc, unsigned offset)
> ?{
> ? ? ? ?struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
>
> - ? ? ? if (chip->irq_base == NO_IRQ)
> + ? ? ? if (chip->irq_base <= 0)
> ? ? ? ? ? ? ? ?return -EINVAL;
>
> ? ? ? ?return chip->irq_base + offset;
> @@ -250,7 +250,7 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
> ? ? ? ? ? ? ? ?chip->irq_base = pdata->irq_base;
> ? ? ? ?} else if (dev->dev.of_node) {
> ? ? ? ? ? ? ? ?chip->gc.base = -1;
> - ? ? ? ? ? ? ? chip->irq_base = NO_IRQ;
> + ? ? ? ? ? ? ? chip->irq_base = 0;
> ? ? ? ?} else {
> ? ? ? ? ? ? ? ?ret = -ENODEV;
> ? ? ? ? ? ? ? ?goto free_mem;
> @@ -290,7 +290,7 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
> ? ? ? ? * irq_chip support
> ? ? ? ? */
>
> - ? ? ? if (chip->irq_base == NO_IRQ)
> + ? ? ? if (chip->irq_base <= 0)
> ? ? ? ? ? ? ? ?return 0;
>
> ? ? ? ?writeb(0, chip->base + GPIOIE); /* disable irqs */
> diff --git a/include/linux/amba/pl061.h b/include/linux/amba/pl061.h
> index 2412af9..fb83c04 100644
> --- a/include/linux/amba/pl061.h
> +++ b/include/linux/amba/pl061.h
> @@ -7,7 +7,7 @@ struct pl061_platform_data {
> ? ? ? ?unsigned ? ? ? ?gpio_base;
>
> ? ? ? ?/* number of the first IRQ.
> - ? ? ? ?* If the IRQ functionality in not desired this must be set to NO_IRQ.
> + ? ? ? ?* If the IRQ functionality in not desired this must be set to 0.
> ? ? ? ? */
> ? ? ? ?unsigned ? ? ? ?irq_base;
>
> --
> 1.7.5.4
>
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply [flat|nested] 43+ messages in thread
* [PATCH 6/9] ARM: realview: convert pl061 no irq to 0 instead of -1
2011-12-14 15:28 [PATCH 0/9] irq domain for gen irq chip and pl061 DT irq support Rob Herring
` (4 preceding siblings ...)
2011-12-14 15:28 ` [PATCH 5/9] gpio: pl061: convert to use 0 for no irq Rob Herring
@ 2011-12-14 15:28 ` Rob Herring
2011-12-14 21:16 ` Grant Likely
2011-12-14 15:28 ` [PATCH 7/9] gpio: pl061: convert to use generic irq chip Rob Herring
` (3 subsequent siblings)
9 siblings, 1 reply; 43+ messages in thread
From: Rob Herring @ 2011-12-14 15:28 UTC (permalink / raw)
To: linux-arm-kernel
From: Rob Herring <rob.herring@calxeda.com>
Drivers should use 0 for no irq, so convert realview platforms pl061
platform_data over to use 0.
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Cc: Russell King <linux@arm.linux.org.uk>
---
arch/arm/mach-realview/realview_eb.c | 3 ---
arch/arm/mach-realview/realview_pb1176.c | 3 ---
arch/arm/mach-realview/realview_pb11mp.c | 3 ---
arch/arm/mach-realview/realview_pba8.c | 3 ---
arch/arm/mach-realview/realview_pbx.c | 3 ---
5 files changed, 0 insertions(+), 15 deletions(-)
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
index 026c66a..57f5bac 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -117,17 +117,14 @@ static void __init realview_eb_map_io(void)
static struct pl061_platform_data gpio0_plat_data = {
.gpio_base = 0,
- .irq_base = -1,
};
static struct pl061_platform_data gpio1_plat_data = {
.gpio_base = 8,
- .irq_base = -1,
};
static struct pl061_platform_data gpio2_plat_data = {
.gpio_base = 16,
- .irq_base = -1,
};
static struct pl022_ssp_controller ssp0_plat_data = {
diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c
index c057540..2267696 100644
--- a/arch/arm/mach-realview/realview_pb1176.c
+++ b/arch/arm/mach-realview/realview_pb1176.c
@@ -113,17 +113,14 @@ static void __init realview_pb1176_map_io(void)
static struct pl061_platform_data gpio0_plat_data = {
.gpio_base = 0,
- .irq_base = -1,
};
static struct pl061_platform_data gpio1_plat_data = {
.gpio_base = 8,
- .irq_base = -1,
};
static struct pl061_platform_data gpio2_plat_data = {
.gpio_base = 16,
- .irq_base = -1,
};
static struct pl022_ssp_controller ssp0_plat_data = {
diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c
index 671ad6d..8622dbb 100644
--- a/arch/arm/mach-realview/realview_pb11mp.c
+++ b/arch/arm/mach-realview/realview_pb11mp.c
@@ -112,17 +112,14 @@ static void __init realview_pb11mp_map_io(void)
static struct pl061_platform_data gpio0_plat_data = {
.gpio_base = 0,
- .irq_base = -1,
};
static struct pl061_platform_data gpio1_plat_data = {
.gpio_base = 8,
- .irq_base = -1,
};
static struct pl061_platform_data gpio2_plat_data = {
.gpio_base = 16,
- .irq_base = -1,
};
static struct pl022_ssp_controller ssp0_plat_data = {
diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c
index cbf22df..6f9511d 100644
--- a/arch/arm/mach-realview/realview_pba8.c
+++ b/arch/arm/mach-realview/realview_pba8.c
@@ -102,17 +102,14 @@ static void __init realview_pba8_map_io(void)
static struct pl061_platform_data gpio0_plat_data = {
.gpio_base = 0,
- .irq_base = -1,
};
static struct pl061_platform_data gpio1_plat_data = {
.gpio_base = 8,
- .irq_base = -1,
};
static struct pl061_platform_data gpio2_plat_data = {
.gpio_base = 16,
- .irq_base = -1,
};
static struct pl022_ssp_controller ssp0_plat_data = {
diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c
index 63c4114..be3a01f 100644
--- a/arch/arm/mach-realview/realview_pbx.c
+++ b/arch/arm/mach-realview/realview_pbx.c
@@ -124,17 +124,14 @@ static void __init realview_pbx_map_io(void)
static struct pl061_platform_data gpio0_plat_data = {
.gpio_base = 0,
- .irq_base = -1,
};
static struct pl061_platform_data gpio1_plat_data = {
.gpio_base = 8,
- .irq_base = -1,
};
static struct pl061_platform_data gpio2_plat_data = {
.gpio_base = 16,
- .irq_base = -1,
};
static struct pl022_ssp_controller ssp0_plat_data = {
--
1.7.5.4
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [PATCH 6/9] ARM: realview: convert pl061 no irq to 0 instead of -1
2011-12-14 15:28 ` [PATCH 6/9] ARM: realview: convert pl061 no irq to 0 instead of -1 Rob Herring
@ 2011-12-14 21:16 ` Grant Likely
0 siblings, 0 replies; 43+ messages in thread
From: Grant Likely @ 2011-12-14 21:16 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Dec 14, 2011 at 8:28 AM, Rob Herring <robherring2@gmail.com> wrote:
> From: Rob Herring <rob.herring@calxeda.com>
>
> Drivers should use 0 for no irq, so convert realview platforms pl061
> platform_data over to use 0.
>
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> Cc: Russell King <linux@arm.linux.org.uk>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
> ---
> ?arch/arm/mach-realview/realview_eb.c ? ? | ? ?3 ---
> ?arch/arm/mach-realview/realview_pb1176.c | ? ?3 ---
> ?arch/arm/mach-realview/realview_pb11mp.c | ? ?3 ---
> ?arch/arm/mach-realview/realview_pba8.c ? | ? ?3 ---
> ?arch/arm/mach-realview/realview_pbx.c ? ?| ? ?3 ---
> ?5 files changed, 0 insertions(+), 15 deletions(-)
>
> diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
> index 026c66a..57f5bac 100644
> --- a/arch/arm/mach-realview/realview_eb.c
> +++ b/arch/arm/mach-realview/realview_eb.c
> @@ -117,17 +117,14 @@ static void __init realview_eb_map_io(void)
>
> ?static struct pl061_platform_data gpio0_plat_data = {
> ? ? ? ?.gpio_base ? ? ?= 0,
> - ? ? ? .irq_base ? ? ? = -1,
> ?};
>
> ?static struct pl061_platform_data gpio1_plat_data = {
> ? ? ? ?.gpio_base ? ? ?= 8,
> - ? ? ? .irq_base ? ? ? = -1,
> ?};
>
> ?static struct pl061_platform_data gpio2_plat_data = {
> ? ? ? ?.gpio_base ? ? ?= 16,
> - ? ? ? .irq_base ? ? ? = -1,
> ?};
>
> ?static struct pl022_ssp_controller ssp0_plat_data = {
> diff --git a/arch/arm/mach-realview/realview_pb1176.c b/arch/arm/mach-realview/realview_pb1176.c
> index c057540..2267696 100644
> --- a/arch/arm/mach-realview/realview_pb1176.c
> +++ b/arch/arm/mach-realview/realview_pb1176.c
> @@ -113,17 +113,14 @@ static void __init realview_pb1176_map_io(void)
>
> ?static struct pl061_platform_data gpio0_plat_data = {
> ? ? ? ?.gpio_base ? ? ?= 0,
> - ? ? ? .irq_base ? ? ? = -1,
> ?};
>
> ?static struct pl061_platform_data gpio1_plat_data = {
> ? ? ? ?.gpio_base ? ? ?= 8,
> - ? ? ? .irq_base ? ? ? = -1,
> ?};
>
> ?static struct pl061_platform_data gpio2_plat_data = {
> ? ? ? ?.gpio_base ? ? ?= 16,
> - ? ? ? .irq_base ? ? ? = -1,
> ?};
>
> ?static struct pl022_ssp_controller ssp0_plat_data = {
> diff --git a/arch/arm/mach-realview/realview_pb11mp.c b/arch/arm/mach-realview/realview_pb11mp.c
> index 671ad6d..8622dbb 100644
> --- a/arch/arm/mach-realview/realview_pb11mp.c
> +++ b/arch/arm/mach-realview/realview_pb11mp.c
> @@ -112,17 +112,14 @@ static void __init realview_pb11mp_map_io(void)
>
> ?static struct pl061_platform_data gpio0_plat_data = {
> ? ? ? ?.gpio_base ? ? ?= 0,
> - ? ? ? .irq_base ? ? ? = -1,
> ?};
>
> ?static struct pl061_platform_data gpio1_plat_data = {
> ? ? ? ?.gpio_base ? ? ?= 8,
> - ? ? ? .irq_base ? ? ? = -1,
> ?};
>
> ?static struct pl061_platform_data gpio2_plat_data = {
> ? ? ? ?.gpio_base ? ? ?= 16,
> - ? ? ? .irq_base ? ? ? = -1,
> ?};
>
> ?static struct pl022_ssp_controller ssp0_plat_data = {
> diff --git a/arch/arm/mach-realview/realview_pba8.c b/arch/arm/mach-realview/realview_pba8.c
> index cbf22df..6f9511d 100644
> --- a/arch/arm/mach-realview/realview_pba8.c
> +++ b/arch/arm/mach-realview/realview_pba8.c
> @@ -102,17 +102,14 @@ static void __init realview_pba8_map_io(void)
>
> ?static struct pl061_platform_data gpio0_plat_data = {
> ? ? ? ?.gpio_base ? ? ?= 0,
> - ? ? ? .irq_base ? ? ? = -1,
> ?};
>
> ?static struct pl061_platform_data gpio1_plat_data = {
> ? ? ? ?.gpio_base ? ? ?= 8,
> - ? ? ? .irq_base ? ? ? = -1,
> ?};
>
> ?static struct pl061_platform_data gpio2_plat_data = {
> ? ? ? ?.gpio_base ? ? ?= 16,
> - ? ? ? .irq_base ? ? ? = -1,
> ?};
>
> ?static struct pl022_ssp_controller ssp0_plat_data = {
> diff --git a/arch/arm/mach-realview/realview_pbx.c b/arch/arm/mach-realview/realview_pbx.c
> index 63c4114..be3a01f 100644
> --- a/arch/arm/mach-realview/realview_pbx.c
> +++ b/arch/arm/mach-realview/realview_pbx.c
> @@ -124,17 +124,14 @@ static void __init realview_pbx_map_io(void)
>
> ?static struct pl061_platform_data gpio0_plat_data = {
> ? ? ? ?.gpio_base ? ? ?= 0,
> - ? ? ? .irq_base ? ? ? = -1,
> ?};
>
> ?static struct pl061_platform_data gpio1_plat_data = {
> ? ? ? ?.gpio_base ? ? ?= 8,
> - ? ? ? .irq_base ? ? ? = -1,
> ?};
>
> ?static struct pl061_platform_data gpio2_plat_data = {
> ? ? ? ?.gpio_base ? ? ?= 16,
> - ? ? ? .irq_base ? ? ? = -1,
> ?};
>
> ?static struct pl022_ssp_controller ssp0_plat_data = {
> --
> 1.7.5.4
>
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply [flat|nested] 43+ messages in thread
* [PATCH 7/9] gpio: pl061: convert to use generic irq chip
2011-12-14 15:28 [PATCH 0/9] irq domain for gen irq chip and pl061 DT irq support Rob Herring
` (5 preceding siblings ...)
2011-12-14 15:28 ` [PATCH 6/9] ARM: realview: convert pl061 no irq to 0 instead of -1 Rob Herring
@ 2011-12-14 15:28 ` Rob Herring
2011-12-14 21:17 ` Grant Likely
2011-12-19 20:52 ` [PATCH v2] " Rob Herring
2011-12-14 15:28 ` [PATCH 8/9] gpio: pl061: enable interrupts with DT style binding Rob Herring
` (2 subsequent siblings)
9 siblings, 2 replies; 43+ messages in thread
From: Rob Herring @ 2011-12-14 15:28 UTC (permalink / raw)
To: linux-arm-kernel
From: Rob Herring <rob.herring@calxeda.com>
Convert the pl061 irq_chip code to use the generic irq chip code.
This has the side effect of using 32-bit accesses rather than 8-bit
accesses to interrupt registers. The h/w TRM and testing seem to indicate
this is fine.
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Linus Walleij <linus.ml.walleij@gmail.com>
---
drivers/gpio/Kconfig | 1 +
drivers/gpio/gpio-pl061.c | 74 ++++++++++++++++-----------------------------
2 files changed, 27 insertions(+), 48 deletions(-)
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 8482a23..4d433e2 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -138,6 +138,7 @@ config GPIO_MXS
config GPIO_PL061
bool "PrimeCell PL061 GPIO support"
depends on ARM_AMBA
+ select GENERIC_IRQ_CHIP
help
Say yes here to support the PrimeCell PL061 GPIO device
diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c
index fe19dec..4a1874f 100644
--- a/drivers/gpio/gpio-pl061.c
+++ b/drivers/gpio/gpio-pl061.c
@@ -50,7 +50,6 @@ struct pl061_gpio {
* the IRQ code simpler.
*/
spinlock_t lock; /* GPIO registers */
- spinlock_t irq_lock; /* IRQ registers */
void __iomem *base;
int irq_base;
@@ -125,40 +124,10 @@ static int pl061_to_irq(struct gpio_chip *gc, unsigned offset)
return chip->irq_base + offset;
}
-/*
- * PL061 GPIO IRQ
- */
-static void pl061_irq_disable(struct irq_data *d)
-{
- struct pl061_gpio *chip = irq_data_get_irq_chip_data(d);
- int offset = d->irq - chip->irq_base;
- unsigned long flags;
- u8 gpioie;
-
- spin_lock_irqsave(&chip->irq_lock, flags);
- gpioie = readb(chip->base + GPIOIE);
- gpioie &= ~(1 << offset);
- writeb(gpioie, chip->base + GPIOIE);
- spin_unlock_irqrestore(&chip->irq_lock, flags);
-}
-
-static void pl061_irq_enable(struct irq_data *d)
-{
- struct pl061_gpio *chip = irq_data_get_irq_chip_data(d);
- int offset = d->irq - chip->irq_base;
- unsigned long flags;
- u8 gpioie;
-
- spin_lock_irqsave(&chip->irq_lock, flags);
- gpioie = readb(chip->base + GPIOIE);
- gpioie |= 1 << offset;
- writeb(gpioie, chip->base + GPIOIE);
- spin_unlock_irqrestore(&chip->irq_lock, flags);
-}
-
static int pl061_irq_type(struct irq_data *d, unsigned trigger)
{
- struct pl061_gpio *chip = irq_data_get_irq_chip_data(d);
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ struct pl061_gpio *chip = gc->private;
int offset = d->irq - chip->irq_base;
unsigned long flags;
u8 gpiois, gpioibe, gpioiev;
@@ -166,7 +135,7 @@ static int pl061_irq_type(struct irq_data *d, unsigned trigger)
if (offset < 0 || offset >= PL061_GPIO_NR)
return -EINVAL;
- spin_lock_irqsave(&chip->irq_lock, flags);
+ raw_spin_lock_irqsave(&gc->lock, flags);
gpioiev = readb(chip->base + GPIOIEV);
@@ -195,18 +164,11 @@ static int pl061_irq_type(struct irq_data *d, unsigned trigger)
writeb(gpioiev, chip->base + GPIOIEV);
- spin_unlock_irqrestore(&chip->irq_lock, flags);
+ raw_spin_unlock_irqrestore(&gc->lock, flags);
return 0;
}
-static struct irq_chip pl061_irqchip = {
- .name = "GPIO",
- .irq_enable = pl061_irq_enable,
- .irq_disable = pl061_irq_disable,
- .irq_set_type = pl061_irq_type,
-};
-
static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
{
struct list_head *chip_list = irq_get_handler_data(irq);
@@ -232,6 +194,26 @@ static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
chained_irq_exit(irqchip, desc);
}
+static void __init pl061_init_gc(struct pl061_gpio *chip, int irq_base)
+{
+ struct irq_chip_generic *gc;
+ struct irq_chip_type *ct;
+
+ gc = irq_alloc_generic_chip("gpio-pl061", 1, irq_base,
+ chip->base, handle_simple_irq);
+ gc->private = chip;
+
+ ct = gc->chip_types;
+ ct->chip.irq_mask = irq_gc_mask_clr_bit;
+ ct->chip.irq_unmask = irq_gc_mask_set_bit;
+ ct->chip.irq_set_type = pl061_irq_type;
+ ct->chip.irq_set_wake = irq_gc_set_wake;
+ ct->regs.mask = GPIOIE;
+
+ irq_setup_generic_chip(gc, IRQ_MSK(PL061_GPIO_NR),
+ IRQ_GC_INIT_NESTED_LOCK, IRQ_NOREQUEST, 0);
+}
+
static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
{
struct pl061_platform_data *pdata;
@@ -269,7 +251,6 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
}
spin_lock_init(&chip->lock);
- spin_lock_init(&chip->irq_lock);
INIT_LIST_HEAD(&chip->list);
chip->gc.direction_input = pl061_direction_input;
@@ -293,6 +274,8 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
if (chip->irq_base <= 0)
return 0;
+ pl061_init_gc(chip, chip->irq_base);
+
writeb(0, chip->base + GPIOIE); /* disable irqs */
irq = dev->irq[0];
if (irq < 0) {
@@ -321,11 +304,6 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
else
pl061_direction_input(&chip->gc, i);
}
-
- irq_set_chip_and_handler(i + chip->irq_base, &pl061_irqchip,
- handle_simple_irq);
- set_irq_flags(i+chip->irq_base, IRQF_VALID);
- irq_set_chip_data(i + chip->irq_base, chip);
}
return 0;
--
1.7.5.4
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [PATCH 7/9] gpio: pl061: convert to use generic irq chip
2011-12-14 15:28 ` [PATCH 7/9] gpio: pl061: convert to use generic irq chip Rob Herring
@ 2011-12-14 21:17 ` Grant Likely
2011-12-19 20:52 ` [PATCH v2] " Rob Herring
1 sibling, 0 replies; 43+ messages in thread
From: Grant Likely @ 2011-12-14 21:17 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Dec 14, 2011 at 8:28 AM, Rob Herring <robherring2@gmail.com> wrote:
> From: Rob Herring <rob.herring@calxeda.com>
>
> Convert the pl061 irq_chip code to use the generic irq chip code.
>
> This has the side effect of using 32-bit accesses rather than 8-bit
> accesses to interrupt registers. The h/w TRM and testing seem to indicate
> this is fine.
>
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> Cc: Grant Likely <grant.likely@secretlab.ca>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
> Cc: Linus Walleij <linus.ml.walleij@gmail.com>
> ---
> ?drivers/gpio/Kconfig ? ? ?| ? ?1 +
> ?drivers/gpio/gpio-pl061.c | ? 74 ++++++++++++++++-----------------------------
> ?2 files changed, 27 insertions(+), 48 deletions(-)
>
> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index 8482a23..4d433e2 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -138,6 +138,7 @@ config GPIO_MXS
> ?config GPIO_PL061
> ? ? ? ?bool "PrimeCell PL061 GPIO support"
> ? ? ? ?depends on ARM_AMBA
> + ? ? ? select GENERIC_IRQ_CHIP
> ? ? ? ?help
> ? ? ? ? ?Say yes here to support the PrimeCell PL061 GPIO device
>
> diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c
> index fe19dec..4a1874f 100644
> --- a/drivers/gpio/gpio-pl061.c
> +++ b/drivers/gpio/gpio-pl061.c
> @@ -50,7 +50,6 @@ struct pl061_gpio {
> ? ? ? ? * the IRQ code simpler.
> ? ? ? ? */
> ? ? ? ?spinlock_t ? ? ? ? ? ? ?lock; ? ? ? ? ? /* GPIO registers */
> - ? ? ? spinlock_t ? ? ? ? ? ? ?irq_lock; ? ? ? /* IRQ registers */
>
> ? ? ? ?void __iomem ? ? ? ? ? ?*base;
> ? ? ? ?int ? ? ? ? ? ? ? ? ? ? irq_base;
> @@ -125,40 +124,10 @@ static int pl061_to_irq(struct gpio_chip *gc, unsigned offset)
> ? ? ? ?return chip->irq_base + offset;
> ?}
>
> -/*
> - * PL061 GPIO IRQ
> - */
> -static void pl061_irq_disable(struct irq_data *d)
> -{
> - ? ? ? struct pl061_gpio *chip = irq_data_get_irq_chip_data(d);
> - ? ? ? int offset = d->irq - chip->irq_base;
> - ? ? ? unsigned long flags;
> - ? ? ? u8 gpioie;
> -
> - ? ? ? spin_lock_irqsave(&chip->irq_lock, flags);
> - ? ? ? gpioie = readb(chip->base + GPIOIE);
> - ? ? ? gpioie &= ~(1 << offset);
> - ? ? ? writeb(gpioie, chip->base + GPIOIE);
> - ? ? ? spin_unlock_irqrestore(&chip->irq_lock, flags);
> -}
> -
> -static void pl061_irq_enable(struct irq_data *d)
> -{
> - ? ? ? struct pl061_gpio *chip = irq_data_get_irq_chip_data(d);
> - ? ? ? int offset = d->irq - chip->irq_base;
> - ? ? ? unsigned long flags;
> - ? ? ? u8 gpioie;
> -
> - ? ? ? spin_lock_irqsave(&chip->irq_lock, flags);
> - ? ? ? gpioie = readb(chip->base + GPIOIE);
> - ? ? ? gpioie |= 1 << offset;
> - ? ? ? writeb(gpioie, chip->base + GPIOIE);
> - ? ? ? spin_unlock_irqrestore(&chip->irq_lock, flags);
> -}
> -
> ?static int pl061_irq_type(struct irq_data *d, unsigned trigger)
> ?{
> - ? ? ? struct pl061_gpio *chip = irq_data_get_irq_chip_data(d);
> + ? ? ? struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
> + ? ? ? struct pl061_gpio *chip = gc->private;
> ? ? ? ?int offset = d->irq - chip->irq_base;
> ? ? ? ?unsigned long flags;
> ? ? ? ?u8 gpiois, gpioibe, gpioiev;
> @@ -166,7 +135,7 @@ static int pl061_irq_type(struct irq_data *d, unsigned trigger)
> ? ? ? ?if (offset < 0 || offset >= PL061_GPIO_NR)
> ? ? ? ? ? ? ? ?return -EINVAL;
>
> - ? ? ? spin_lock_irqsave(&chip->irq_lock, flags);
> + ? ? ? raw_spin_lock_irqsave(&gc->lock, flags);
>
> ? ? ? ?gpioiev = readb(chip->base + GPIOIEV);
>
> @@ -195,18 +164,11 @@ static int pl061_irq_type(struct irq_data *d, unsigned trigger)
>
> ? ? ? ?writeb(gpioiev, chip->base + GPIOIEV);
>
> - ? ? ? spin_unlock_irqrestore(&chip->irq_lock, flags);
> + ? ? ? raw_spin_unlock_irqrestore(&gc->lock, flags);
>
> ? ? ? ?return 0;
> ?}
>
> -static struct irq_chip pl061_irqchip = {
> - ? ? ? .name ? ? ? ? ? = "GPIO",
> - ? ? ? .irq_enable ? ? = pl061_irq_enable,
> - ? ? ? .irq_disable ? ?= pl061_irq_disable,
> - ? ? ? .irq_set_type ? = pl061_irq_type,
> -};
> -
> ?static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
> ?{
> ? ? ? ?struct list_head *chip_list = irq_get_handler_data(irq);
> @@ -232,6 +194,26 @@ static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
> ? ? ? ?chained_irq_exit(irqchip, desc);
> ?}
>
> +static void __init pl061_init_gc(struct pl061_gpio *chip, int irq_base)
> +{
> + ? ? ? struct irq_chip_generic *gc;
> + ? ? ? struct irq_chip_type *ct;
> +
> + ? ? ? gc = irq_alloc_generic_chip("gpio-pl061", 1, irq_base,
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? chip->base, handle_simple_irq);
> + ? ? ? gc->private = chip;
> +
> + ? ? ? ct = gc->chip_types;
> + ? ? ? ct->chip.irq_mask = irq_gc_mask_clr_bit;
> + ? ? ? ct->chip.irq_unmask = irq_gc_mask_set_bit;
> + ? ? ? ct->chip.irq_set_type = pl061_irq_type;
> + ? ? ? ct->chip.irq_set_wake = irq_gc_set_wake;
> + ? ? ? ct->regs.mask = GPIOIE;
> +
> + ? ? ? irq_setup_generic_chip(gc, IRQ_MSK(PL061_GPIO_NR),
> + ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?IRQ_GC_INIT_NESTED_LOCK, IRQ_NOREQUEST, 0);
> +}
> +
> ?static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
> ?{
> ? ? ? ?struct pl061_platform_data *pdata;
> @@ -269,7 +251,6 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
> ? ? ? ?}
>
> ? ? ? ?spin_lock_init(&chip->lock);
> - ? ? ? spin_lock_init(&chip->irq_lock);
> ? ? ? ?INIT_LIST_HEAD(&chip->list);
>
> ? ? ? ?chip->gc.direction_input = pl061_direction_input;
> @@ -293,6 +274,8 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
> ? ? ? ?if (chip->irq_base <= 0)
> ? ? ? ? ? ? ? ?return 0;
>
> + ? ? ? pl061_init_gc(chip, chip->irq_base);
> +
> ? ? ? ?writeb(0, chip->base + GPIOIE); /* disable irqs */
> ? ? ? ?irq = dev->irq[0];
> ? ? ? ?if (irq < 0) {
> @@ -321,11 +304,6 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
> ? ? ? ? ? ? ? ? ? ? ? ?else
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?pl061_direction_input(&chip->gc, i);
> ? ? ? ? ? ? ? ?}
> -
> - ? ? ? ? ? ? ? irq_set_chip_and_handler(i + chip->irq_base, &pl061_irqchip,
> - ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?handle_simple_irq);
> - ? ? ? ? ? ? ? set_irq_flags(i+chip->irq_base, IRQF_VALID);
> - ? ? ? ? ? ? ? irq_set_chip_data(i + chip->irq_base, chip);
> ? ? ? ?}
>
> ? ? ? ?return 0;
> --
> 1.7.5.4
>
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply [flat|nested] 43+ messages in thread
* [PATCH v2] gpio: pl061: convert to use generic irq chip
2011-12-14 15:28 ` [PATCH 7/9] gpio: pl061: convert to use generic irq chip Rob Herring
2011-12-14 21:17 ` Grant Likely
@ 2011-12-19 20:52 ` Rob Herring
2011-12-24 23:26 ` Linus Walleij
2012-01-02 8:54 ` Grant Likely
1 sibling, 2 replies; 43+ messages in thread
From: Rob Herring @ 2011-12-19 20:52 UTC (permalink / raw)
To: linux-arm-kernel
From: Rob Herring <rob.herring@calxeda.com>
Convert the pl061 irq_chip code to use the generic irq chip code.
This has the side effect of using 32-bit accesses rather than 8-bit
accesses to interrupt registers. The h/w TRM and testing seem to indicate
this is fine.
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
Cc: Linus Walleij <linus.ml.walleij@gmail.com>
---
v2:
- put struct irq_chip_generic pointer into struct pl061_gpio instead of domain
ptr.
drivers/gpio/Kconfig | 1 +
drivers/gpio/gpio-pl061.c | 74 ++++++++++++++++-----------------------------
2 files changed, 27 insertions(+), 48 deletions(-)
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 8482a23..4d433e2 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -138,6 +138,7 @@ config GPIO_MXS
config GPIO_PL061
bool "PrimeCell PL061 GPIO support"
depends on ARM_AMBA
+ select GENERIC_IRQ_CHIP
help
Say yes here to support the PrimeCell PL061 GPIO device
diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c
index fe19dec..96ff6b2 100644
--- a/drivers/gpio/gpio-pl061.c
+++ b/drivers/gpio/gpio-pl061.c
@@ -50,10 +50,10 @@ struct pl061_gpio {
* the IRQ code simpler.
*/
spinlock_t lock; /* GPIO registers */
- spinlock_t irq_lock; /* IRQ registers */
void __iomem *base;
int irq_base;
+ struct irq_chip_generic *irq_gc;
struct gpio_chip gc;
};
@@ -125,40 +125,10 @@ static int pl061_to_irq(struct gpio_chip *gc, unsigned offset)
return chip->irq_base + offset;
}
-/*
- * PL061 GPIO IRQ
- */
-static void pl061_irq_disable(struct irq_data *d)
-{
- struct pl061_gpio *chip = irq_data_get_irq_chip_data(d);
- int offset = d->irq - chip->irq_base;
- unsigned long flags;
- u8 gpioie;
-
- spin_lock_irqsave(&chip->irq_lock, flags);
- gpioie = readb(chip->base + GPIOIE);
- gpioie &= ~(1 << offset);
- writeb(gpioie, chip->base + GPIOIE);
- spin_unlock_irqrestore(&chip->irq_lock, flags);
-}
-
-static void pl061_irq_enable(struct irq_data *d)
-{
- struct pl061_gpio *chip = irq_data_get_irq_chip_data(d);
- int offset = d->irq - chip->irq_base;
- unsigned long flags;
- u8 gpioie;
-
- spin_lock_irqsave(&chip->irq_lock, flags);
- gpioie = readb(chip->base + GPIOIE);
- gpioie |= 1 << offset;
- writeb(gpioie, chip->base + GPIOIE);
- spin_unlock_irqrestore(&chip->irq_lock, flags);
-}
-
static int pl061_irq_type(struct irq_data *d, unsigned trigger)
{
- struct pl061_gpio *chip = irq_data_get_irq_chip_data(d);
+ struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
+ struct pl061_gpio *chip = gc->private;
int offset = d->irq - chip->irq_base;
unsigned long flags;
u8 gpiois, gpioibe, gpioiev;
@@ -166,7 +136,7 @@ static int pl061_irq_type(struct irq_data *d, unsigned trigger)
if (offset < 0 || offset >= PL061_GPIO_NR)
return -EINVAL;
- spin_lock_irqsave(&chip->irq_lock, flags);
+ raw_spin_lock_irqsave(&gc->lock, flags);
gpioiev = readb(chip->base + GPIOIEV);
@@ -195,18 +165,11 @@ static int pl061_irq_type(struct irq_data *d, unsigned trigger)
writeb(gpioiev, chip->base + GPIOIEV);
- spin_unlock_irqrestore(&chip->irq_lock, flags);
+ raw_spin_unlock_irqrestore(&gc->lock, flags);
return 0;
}
-static struct irq_chip pl061_irqchip = {
- .name = "GPIO",
- .irq_enable = pl061_irq_enable,
- .irq_disable = pl061_irq_disable,
- .irq_set_type = pl061_irq_type,
-};
-
static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
{
struct list_head *chip_list = irq_get_handler_data(irq);
@@ -232,6 +195,25 @@ static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
chained_irq_exit(irqchip, desc);
}
+static void __init pl061_init_gc(struct pl061_gpio *chip, int irq_base)
+{
+ struct irq_chip_type *ct;
+
+ chip->irq_gc = irq_alloc_generic_chip("gpio-pl061", 1, irq_base,
+ chip->base, handle_simple_irq);
+ chip->irq_gc->private = chip;
+
+ ct = chip->irq_gc->chip_types;
+ ct->chip.irq_mask = irq_gc_mask_clr_bit;
+ ct->chip.irq_unmask = irq_gc_mask_set_bit;
+ ct->chip.irq_set_type = pl061_irq_type;
+ ct->chip.irq_set_wake = irq_gc_set_wake;
+ ct->regs.mask = GPIOIE;
+
+ irq_setup_generic_chip(chip->irq_gc, IRQ_MSK(PL061_GPIO_NR),
+ IRQ_GC_INIT_NESTED_LOCK, IRQ_NOREQUEST, 0);
+}
+
static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
{
struct pl061_platform_data *pdata;
@@ -269,7 +251,6 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
}
spin_lock_init(&chip->lock);
- spin_lock_init(&chip->irq_lock);
INIT_LIST_HEAD(&chip->list);
chip->gc.direction_input = pl061_direction_input;
@@ -293,6 +274,8 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
if (chip->irq_base <= 0)
return 0;
+ pl061_init_gc(chip, chip->irq_base);
+
writeb(0, chip->base + GPIOIE); /* disable irqs */
irq = dev->irq[0];
if (irq < 0) {
@@ -321,11 +304,6 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
else
pl061_direction_input(&chip->gc, i);
}
-
- irq_set_chip_and_handler(i + chip->irq_base, &pl061_irqchip,
- handle_simple_irq);
- set_irq_flags(i+chip->irq_base, IRQF_VALID);
- irq_set_chip_data(i + chip->irq_base, chip);
}
return 0;
--
1.7.5.4
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [PATCH v2] gpio: pl061: convert to use generic irq chip
2011-12-19 20:52 ` [PATCH v2] " Rob Herring
@ 2011-12-24 23:26 ` Linus Walleij
2012-01-02 8:54 ` Grant Likely
1 sibling, 0 replies; 43+ messages in thread
From: Linus Walleij @ 2011-12-24 23:26 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Dec 19, 2011 at 9:52 PM, Rob Herring <robherring2@gmail.com> wrote:
> From: Rob Herring <rob.herring@calxeda.com>
>
> Convert the pl061 irq_chip code to use the generic irq chip code.
>
> This has the side effect of using 32-bit accesses rather than 8-bit
> accesses to interrupt registers. The h/w TRM and testing seem to indicate
> this is fine.
>
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> Acked-by: Grant Likely <grant.likely@secretlab.ca>
> Cc: Linus Walleij <linus.ml.walleij@gmail.com>
> ---
> v2:
> - put struct irq_chip_generic pointer into struct pl061_gpio instead of domain
> ptr.
Looks good to me.
Acked-by: Linus Walleij <linus.walleij@linaro.org>
Thanks,
Linus Walleij
^ permalink raw reply [flat|nested] 43+ messages in thread
* [PATCH v2] gpio: pl061: convert to use generic irq chip
2011-12-19 20:52 ` [PATCH v2] " Rob Herring
2011-12-24 23:26 ` Linus Walleij
@ 2012-01-02 8:54 ` Grant Likely
2012-01-02 16:54 ` Rob Herring
1 sibling, 1 reply; 43+ messages in thread
From: Grant Likely @ 2012-01-02 8:54 UTC (permalink / raw)
To: linux-arm-kernel
On Mon, Dec 19, 2011 at 02:52:07PM -0600, Rob Herring wrote:
> From: Rob Herring <rob.herring@calxeda.com>
>
> Convert the pl061 irq_chip code to use the generic irq chip code.
>
> This has the side effect of using 32-bit accesses rather than 8-bit
> accesses to interrupt registers. The h/w TRM and testing seem to indicate
> this is fine.
>
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> Acked-by: Grant Likely <grant.likely@secretlab.ca>
> Cc: Linus Walleij <linus.ml.walleij@gmail.com>
What does this apply against? It doesn't apply cleanly.
g.
> ---
> v2:
> - put struct irq_chip_generic pointer into struct pl061_gpio instead of domain
> ptr.
>
> drivers/gpio/Kconfig | 1 +
> drivers/gpio/gpio-pl061.c | 74 ++++++++++++++++-----------------------------
> 2 files changed, 27 insertions(+), 48 deletions(-)
>
> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
> index 8482a23..4d433e2 100644
> --- a/drivers/gpio/Kconfig
> +++ b/drivers/gpio/Kconfig
> @@ -138,6 +138,7 @@ config GPIO_MXS
> config GPIO_PL061
> bool "PrimeCell PL061 GPIO support"
> depends on ARM_AMBA
> + select GENERIC_IRQ_CHIP
> help
> Say yes here to support the PrimeCell PL061 GPIO device
>
> diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c
> index fe19dec..96ff6b2 100644
> --- a/drivers/gpio/gpio-pl061.c
> +++ b/drivers/gpio/gpio-pl061.c
> @@ -50,10 +50,10 @@ struct pl061_gpio {
> * the IRQ code simpler.
> */
> spinlock_t lock; /* GPIO registers */
> - spinlock_t irq_lock; /* IRQ registers */
>
> void __iomem *base;
> int irq_base;
> + struct irq_chip_generic *irq_gc;
> struct gpio_chip gc;
> };
>
> @@ -125,40 +125,10 @@ static int pl061_to_irq(struct gpio_chip *gc, unsigned offset)
> return chip->irq_base + offset;
> }
>
> -/*
> - * PL061 GPIO IRQ
> - */
> -static void pl061_irq_disable(struct irq_data *d)
> -{
> - struct pl061_gpio *chip = irq_data_get_irq_chip_data(d);
> - int offset = d->irq - chip->irq_base;
> - unsigned long flags;
> - u8 gpioie;
> -
> - spin_lock_irqsave(&chip->irq_lock, flags);
> - gpioie = readb(chip->base + GPIOIE);
> - gpioie &= ~(1 << offset);
> - writeb(gpioie, chip->base + GPIOIE);
> - spin_unlock_irqrestore(&chip->irq_lock, flags);
> -}
> -
> -static void pl061_irq_enable(struct irq_data *d)
> -{
> - struct pl061_gpio *chip = irq_data_get_irq_chip_data(d);
> - int offset = d->irq - chip->irq_base;
> - unsigned long flags;
> - u8 gpioie;
> -
> - spin_lock_irqsave(&chip->irq_lock, flags);
> - gpioie = readb(chip->base + GPIOIE);
> - gpioie |= 1 << offset;
> - writeb(gpioie, chip->base + GPIOIE);
> - spin_unlock_irqrestore(&chip->irq_lock, flags);
> -}
> -
> static int pl061_irq_type(struct irq_data *d, unsigned trigger)
> {
> - struct pl061_gpio *chip = irq_data_get_irq_chip_data(d);
> + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
> + struct pl061_gpio *chip = gc->private;
> int offset = d->irq - chip->irq_base;
> unsigned long flags;
> u8 gpiois, gpioibe, gpioiev;
> @@ -166,7 +136,7 @@ static int pl061_irq_type(struct irq_data *d, unsigned trigger)
> if (offset < 0 || offset >= PL061_GPIO_NR)
> return -EINVAL;
>
> - spin_lock_irqsave(&chip->irq_lock, flags);
> + raw_spin_lock_irqsave(&gc->lock, flags);
>
> gpioiev = readb(chip->base + GPIOIEV);
>
> @@ -195,18 +165,11 @@ static int pl061_irq_type(struct irq_data *d, unsigned trigger)
>
> writeb(gpioiev, chip->base + GPIOIEV);
>
> - spin_unlock_irqrestore(&chip->irq_lock, flags);
> + raw_spin_unlock_irqrestore(&gc->lock, flags);
>
> return 0;
> }
>
> -static struct irq_chip pl061_irqchip = {
> - .name = "GPIO",
> - .irq_enable = pl061_irq_enable,
> - .irq_disable = pl061_irq_disable,
> - .irq_set_type = pl061_irq_type,
> -};
> -
> static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
> {
> struct list_head *chip_list = irq_get_handler_data(irq);
> @@ -232,6 +195,25 @@ static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
> chained_irq_exit(irqchip, desc);
> }
>
> +static void __init pl061_init_gc(struct pl061_gpio *chip, int irq_base)
> +{
> + struct irq_chip_type *ct;
> +
> + chip->irq_gc = irq_alloc_generic_chip("gpio-pl061", 1, irq_base,
> + chip->base, handle_simple_irq);
> + chip->irq_gc->private = chip;
> +
> + ct = chip->irq_gc->chip_types;
> + ct->chip.irq_mask = irq_gc_mask_clr_bit;
> + ct->chip.irq_unmask = irq_gc_mask_set_bit;
> + ct->chip.irq_set_type = pl061_irq_type;
> + ct->chip.irq_set_wake = irq_gc_set_wake;
> + ct->regs.mask = GPIOIE;
> +
> + irq_setup_generic_chip(chip->irq_gc, IRQ_MSK(PL061_GPIO_NR),
> + IRQ_GC_INIT_NESTED_LOCK, IRQ_NOREQUEST, 0);
> +}
> +
> static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
> {
> struct pl061_platform_data *pdata;
> @@ -269,7 +251,6 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
> }
>
> spin_lock_init(&chip->lock);
> - spin_lock_init(&chip->irq_lock);
> INIT_LIST_HEAD(&chip->list);
>
> chip->gc.direction_input = pl061_direction_input;
> @@ -293,6 +274,8 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
> if (chip->irq_base <= 0)
> return 0;
>
> + pl061_init_gc(chip, chip->irq_base);
> +
> writeb(0, chip->base + GPIOIE); /* disable irqs */
> irq = dev->irq[0];
> if (irq < 0) {
> @@ -321,11 +304,6 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
> else
> pl061_direction_input(&chip->gc, i);
> }
> -
> - irq_set_chip_and_handler(i + chip->irq_base, &pl061_irqchip,
> - handle_simple_irq);
> - set_irq_flags(i+chip->irq_base, IRQF_VALID);
> - irq_set_chip_data(i + chip->irq_base, chip);
> }
>
> return 0;
> --
> 1.7.5.4
>
^ permalink raw reply [flat|nested] 43+ messages in thread
* [PATCH v2] gpio: pl061: convert to use generic irq chip
2012-01-02 8:54 ` Grant Likely
@ 2012-01-02 16:54 ` Rob Herring
0 siblings, 0 replies; 43+ messages in thread
From: Rob Herring @ 2012-01-02 16:54 UTC (permalink / raw)
To: linux-arm-kernel
Grant,
On 01/02/2012 02:54 AM, Grant Likely wrote:
> On Mon, Dec 19, 2011 at 02:52:07PM -0600, Rob Herring wrote:
>> From: Rob Herring <rob.herring@calxeda.com>
>>
>> Convert the pl061 irq_chip code to use the generic irq chip code.
>>
>> This has the side effect of using 32-bit accesses rather than 8-bit
>> accesses to interrupt registers. The h/w TRM and testing seem to indicate
>> this is fine.
>>
>> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
>> Acked-by: Grant Likely <grant.likely@secretlab.ca>
>> Cc: Linus Walleij <linus.ml.walleij@gmail.com>
>
> What does this apply against? It doesn't apply cleanly.
>
You need the whole series which is available here:
git://sources.calxeda.com/kernel/linux.git pl061-domain-v2
Rob
> g.
>
>> ---
>> v2:
>> - put struct irq_chip_generic pointer into struct pl061_gpio instead of domain
>> ptr.
>>
>> drivers/gpio/Kconfig | 1 +
>> drivers/gpio/gpio-pl061.c | 74 ++++++++++++++++-----------------------------
>> 2 files changed, 27 insertions(+), 48 deletions(-)
>>
>> diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
>> index 8482a23..4d433e2 100644
>> --- a/drivers/gpio/Kconfig
>> +++ b/drivers/gpio/Kconfig
>> @@ -138,6 +138,7 @@ config GPIO_MXS
>> config GPIO_PL061
>> bool "PrimeCell PL061 GPIO support"
>> depends on ARM_AMBA
>> + select GENERIC_IRQ_CHIP
>> help
>> Say yes here to support the PrimeCell PL061 GPIO device
>>
>> diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c
>> index fe19dec..96ff6b2 100644
>> --- a/drivers/gpio/gpio-pl061.c
>> +++ b/drivers/gpio/gpio-pl061.c
>> @@ -50,10 +50,10 @@ struct pl061_gpio {
>> * the IRQ code simpler.
>> */
>> spinlock_t lock; /* GPIO registers */
>> - spinlock_t irq_lock; /* IRQ registers */
>>
>> void __iomem *base;
>> int irq_base;
>> + struct irq_chip_generic *irq_gc;
>> struct gpio_chip gc;
>> };
>>
>> @@ -125,40 +125,10 @@ static int pl061_to_irq(struct gpio_chip *gc, unsigned offset)
>> return chip->irq_base + offset;
>> }
>>
>> -/*
>> - * PL061 GPIO IRQ
>> - */
>> -static void pl061_irq_disable(struct irq_data *d)
>> -{
>> - struct pl061_gpio *chip = irq_data_get_irq_chip_data(d);
>> - int offset = d->irq - chip->irq_base;
>> - unsigned long flags;
>> - u8 gpioie;
>> -
>> - spin_lock_irqsave(&chip->irq_lock, flags);
>> - gpioie = readb(chip->base + GPIOIE);
>> - gpioie &= ~(1 << offset);
>> - writeb(gpioie, chip->base + GPIOIE);
>> - spin_unlock_irqrestore(&chip->irq_lock, flags);
>> -}
>> -
>> -static void pl061_irq_enable(struct irq_data *d)
>> -{
>> - struct pl061_gpio *chip = irq_data_get_irq_chip_data(d);
>> - int offset = d->irq - chip->irq_base;
>> - unsigned long flags;
>> - u8 gpioie;
>> -
>> - spin_lock_irqsave(&chip->irq_lock, flags);
>> - gpioie = readb(chip->base + GPIOIE);
>> - gpioie |= 1 << offset;
>> - writeb(gpioie, chip->base + GPIOIE);
>> - spin_unlock_irqrestore(&chip->irq_lock, flags);
>> -}
>> -
>> static int pl061_irq_type(struct irq_data *d, unsigned trigger)
>> {
>> - struct pl061_gpio *chip = irq_data_get_irq_chip_data(d);
>> + struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
>> + struct pl061_gpio *chip = gc->private;
>> int offset = d->irq - chip->irq_base;
>> unsigned long flags;
>> u8 gpiois, gpioibe, gpioiev;
>> @@ -166,7 +136,7 @@ static int pl061_irq_type(struct irq_data *d, unsigned trigger)
>> if (offset < 0 || offset >= PL061_GPIO_NR)
>> return -EINVAL;
>>
>> - spin_lock_irqsave(&chip->irq_lock, flags);
>> + raw_spin_lock_irqsave(&gc->lock, flags);
>>
>> gpioiev = readb(chip->base + GPIOIEV);
>>
>> @@ -195,18 +165,11 @@ static int pl061_irq_type(struct irq_data *d, unsigned trigger)
>>
>> writeb(gpioiev, chip->base + GPIOIEV);
>>
>> - spin_unlock_irqrestore(&chip->irq_lock, flags);
>> + raw_spin_unlock_irqrestore(&gc->lock, flags);
>>
>> return 0;
>> }
>>
>> -static struct irq_chip pl061_irqchip = {
>> - .name = "GPIO",
>> - .irq_enable = pl061_irq_enable,
>> - .irq_disable = pl061_irq_disable,
>> - .irq_set_type = pl061_irq_type,
>> -};
>> -
>> static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
>> {
>> struct list_head *chip_list = irq_get_handler_data(irq);
>> @@ -232,6 +195,25 @@ static void pl061_irq_handler(unsigned irq, struct irq_desc *desc)
>> chained_irq_exit(irqchip, desc);
>> }
>>
>> +static void __init pl061_init_gc(struct pl061_gpio *chip, int irq_base)
>> +{
>> + struct irq_chip_type *ct;
>> +
>> + chip->irq_gc = irq_alloc_generic_chip("gpio-pl061", 1, irq_base,
>> + chip->base, handle_simple_irq);
>> + chip->irq_gc->private = chip;
>> +
>> + ct = chip->irq_gc->chip_types;
>> + ct->chip.irq_mask = irq_gc_mask_clr_bit;
>> + ct->chip.irq_unmask = irq_gc_mask_set_bit;
>> + ct->chip.irq_set_type = pl061_irq_type;
>> + ct->chip.irq_set_wake = irq_gc_set_wake;
>> + ct->regs.mask = GPIOIE;
>> +
>> + irq_setup_generic_chip(chip->irq_gc, IRQ_MSK(PL061_GPIO_NR),
>> + IRQ_GC_INIT_NESTED_LOCK, IRQ_NOREQUEST, 0);
>> +}
>> +
>> static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
>> {
>> struct pl061_platform_data *pdata;
>> @@ -269,7 +251,6 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
>> }
>>
>> spin_lock_init(&chip->lock);
>> - spin_lock_init(&chip->irq_lock);
>> INIT_LIST_HEAD(&chip->list);
>>
>> chip->gc.direction_input = pl061_direction_input;
>> @@ -293,6 +274,8 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
>> if (chip->irq_base <= 0)
>> return 0;
>>
>> + pl061_init_gc(chip, chip->irq_base);
>> +
>> writeb(0, chip->base + GPIOIE); /* disable irqs */
>> irq = dev->irq[0];
>> if (irq < 0) {
>> @@ -321,11 +304,6 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
>> else
>> pl061_direction_input(&chip->gc, i);
>> }
>> -
>> - irq_set_chip_and_handler(i + chip->irq_base, &pl061_irqchip,
>> - handle_simple_irq);
>> - set_irq_flags(i+chip->irq_base, IRQF_VALID);
>> - irq_set_chip_data(i + chip->irq_base, chip);
>> }
>>
>> return 0;
>> --
>> 1.7.5.4
>>
^ permalink raw reply [flat|nested] 43+ messages in thread
* [PATCH 8/9] gpio: pl061: enable interrupts with DT style binding
2011-12-14 15:28 [PATCH 0/9] irq domain for gen irq chip and pl061 DT irq support Rob Herring
` (6 preceding siblings ...)
2011-12-14 15:28 ` [PATCH 7/9] gpio: pl061: convert to use generic irq chip Rob Herring
@ 2011-12-14 15:28 ` Rob Herring
2011-12-14 21:39 ` Grant Likely
2011-12-19 20:54 ` [PATCH v2] " Rob Herring
2011-12-14 15:28 ` [PATCH 9/9] ARM: highbank: add interrupt properties to gpio nodes Rob Herring
2011-12-14 15:41 ` [PATCH 0/9] irq domain for gen irq chip and pl061 DT irq support Rob Herring
9 siblings, 2 replies; 43+ messages in thread
From: Rob Herring @ 2011-12-14 15:28 UTC (permalink / raw)
To: linux-arm-kernel
From: Rob Herring <rob.herring@calxeda.com>
Enable DT interrupt binding support for pl061 gpio lines. If the gpio
node has an interrupt-controller property, then it will be setup to
handle interrupts on gpio lines.
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Linus Walleij <linus.ml.walleij@gmail.com>
---
.../devicetree/bindings/gpio/pl061-gpio.txt | 15 ++++++++++
drivers/gpio/gpio-pl061.c | 29 +++++++++++--------
2 files changed, 32 insertions(+), 12 deletions(-)
diff --git a/Documentation/devicetree/bindings/gpio/pl061-gpio.txt b/Documentation/devicetree/bindings/gpio/pl061-gpio.txt
index a2c416b..9671d4e 100644
--- a/Documentation/devicetree/bindings/gpio/pl061-gpio.txt
+++ b/Documentation/devicetree/bindings/gpio/pl061-gpio.txt
@@ -8,3 +8,18 @@ Required properties:
- gpio-controller : Marks the device node as a GPIO controller.
- interrupts : Interrupt mapping for GPIO IRQ.
+Optional properties:
+- interrupt-controller : Identifies the node as an interrupt controller. Must
+ be present if using gpios lines for interrupts.
+- #interrupt-cells : Specifies the number of cells needed to encode an
+ interrupt source. The type shall be a <u32> and the value shall be 2.
+
+ The 1st cell contains the interrupt number 0-7 corresponding to the gpio
+ line.
+
+ The 2nd cell is the flags, encoding trigger type and level flags.
+ 1 = low-to-high edge triggered
+ 2 = high-to-low edge triggered
+ 4 = active high level-sensitive
+ 8 = active low level-sensitive
+
diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c
index 4a1874f..0151798 100644
--- a/drivers/gpio/gpio-pl061.c
+++ b/drivers/gpio/gpio-pl061.c
@@ -16,6 +16,8 @@
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of.h>
#include <linux/bitops.h>
#include <linux/workqueue.h>
#include <linux/gpio.h>
@@ -52,7 +54,7 @@ struct pl061_gpio {
spinlock_t lock; /* GPIO registers */
void __iomem *base;
- int irq_base;
+ struct irq_domain *irq_domain;
struct gpio_chip gc;
};
@@ -117,18 +119,16 @@ static void pl061_set_value(struct gpio_chip *gc, unsigned offset, int value)
static int pl061_to_irq(struct gpio_chip *gc, unsigned offset)
{
struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
-
- if (chip->irq_base <= 0)
- return -EINVAL;
-
- return chip->irq_base + offset;
+ if (!chip->irq_domain)
+ return -ENXIO;
+ return irq_domain_to_irq(chip->irq_domain, offset);
}
static int pl061_irq_type(struct irq_data *d, unsigned trigger)
{
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
struct pl061_gpio *chip = gc->private;
- int offset = d->irq - chip->irq_base;
+ int offset = d->hwirq;
unsigned long flags;
u8 gpiois, gpioibe, gpioiev;
@@ -212,6 +212,7 @@ static void __init pl061_init_gc(struct pl061_gpio *chip, int irq_base)
irq_setup_generic_chip(gc, IRQ_MSK(PL061_GPIO_NR),
IRQ_GC_INIT_NESTED_LOCK, IRQ_NOREQUEST, 0);
+ chip->irq_domain = gc->domain;
}
static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
@@ -219,7 +220,7 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
struct pl061_platform_data *pdata;
struct pl061_gpio *chip;
struct list_head *chip_list;
- int ret, irq, i;
+ int ret, irq, i, irq_base;
static DECLARE_BITMAP(init_irq, NR_IRQS);
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
@@ -229,10 +230,13 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
pdata = dev->dev.platform_data;
if (pdata) {
chip->gc.base = pdata->gpio_base;
- chip->irq_base = pdata->irq_base;
+ irq_base = pdata->irq_base;
} else if (dev->dev.of_node) {
chip->gc.base = -1;
- chip->irq_base = 0;
+ if (of_get_property(dev->dev.of_node, "interrupt-controller", NULL))
+ irq_base = -1;
+ else
+ irq_base = 0;
} else {
ret = -ENODEV;
goto free_mem;
@@ -271,10 +275,11 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
* irq_chip support
*/
- if (chip->irq_base <= 0)
+ if (!irq_base)
return 0;
- pl061_init_gc(chip, chip->irq_base);
+ pl061_init_gc(chip, irq_base);
+ chip->irq_domain->of_node = of_node_get(dev->dev.of_node);
writeb(0, chip->base + GPIOIE); /* disable irqs */
irq = dev->irq[0];
--
1.7.5.4
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [PATCH 8/9] gpio: pl061: enable interrupts with DT style binding
2011-12-14 15:28 ` [PATCH 8/9] gpio: pl061: enable interrupts with DT style binding Rob Herring
@ 2011-12-14 21:39 ` Grant Likely
2011-12-19 20:54 ` [PATCH v2] " Rob Herring
1 sibling, 0 replies; 43+ messages in thread
From: Grant Likely @ 2011-12-14 21:39 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Dec 14, 2011 at 8:28 AM, Rob Herring <robherring2@gmail.com> wrote:
> From: Rob Herring <rob.herring@calxeda.com>
>
> Enable DT interrupt binding support for pl061 gpio lines. If the gpio
> node has an interrupt-controller property, then it will be setup to
> handle interrupts on gpio lines.
>
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
> Cc: Grant Likely <grant.likely@secretlab.ca>
> Cc: Linus Walleij <linus.ml.walleij@gmail.com>
> ---
> ?.../devicetree/bindings/gpio/pl061-gpio.txt ? ? ? ?| ? 15 ++++++++++
> ?drivers/gpio/gpio-pl061.c ? ? ? ? ? ? ? ? ? ? ? ? ?| ? 29 +++++++++++--------
> ?2 files changed, 32 insertions(+), 12 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/gpio/pl061-gpio.txt b/Documentation/devicetree/bindings/gpio/pl061-gpio.txt
> index a2c416b..9671d4e 100644
> --- a/Documentation/devicetree/bindings/gpio/pl061-gpio.txt
> +++ b/Documentation/devicetree/bindings/gpio/pl061-gpio.txt
> @@ -8,3 +8,18 @@ Required properties:
> ?- gpio-controller : Marks the device node as a GPIO controller.
> ?- interrupts : Interrupt mapping for GPIO IRQ.
>
> +Optional properties:
> +- interrupt-controller : Identifies the node as an interrupt controller. Must
> + ?be present if using gpios lines for interrupts.
> +- #interrupt-cells : Specifies the number of cells needed to encode an
> + ?interrupt source. ?The type shall be a <u32> and the value shall be 2.
> +
> + ?The 1st cell contains the interrupt number 0-7 corresponding to the gpio
> + ?line.
> +
> + ?The 2nd cell is the flags, encoding trigger type and level flags.
> + ? ? ? 1 = low-to-high edge triggered
> + ? ? ? 2 = high-to-low edge triggered
> + ? ? ? 4 = active high level-sensitive
> + ? ? ? 8 = active low level-sensitive
> +
> diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c
> index 4a1874f..0151798 100644
> --- a/drivers/gpio/gpio-pl061.c
> +++ b/drivers/gpio/gpio-pl061.c
> @@ -16,6 +16,8 @@
> ?#include <linux/io.h>
> ?#include <linux/ioport.h>
> ?#include <linux/irq.h>
> +#include <linux/irqdomain.h>
> +#include <linux/of.h>
> ?#include <linux/bitops.h>
> ?#include <linux/workqueue.h>
> ?#include <linux/gpio.h>
> @@ -52,7 +54,7 @@ struct pl061_gpio {
> ? ? ? ?spinlock_t ? ? ? ? ? ? ?lock; ? ? ? ? ? /* GPIO registers */
>
> ? ? ? ?void __iomem ? ? ? ? ? ?*base;
> - ? ? ? int ? ? ? ? ? ? ? ? ? ? irq_base;
> + ? ? ? struct irq_domain ? ? ? *irq_domain;
> ? ? ? ?struct gpio_chip ? ? ? ?gc;
> ?};
>
> @@ -117,18 +119,16 @@ static void pl061_set_value(struct gpio_chip *gc, unsigned offset, int value)
> ?static int pl061_to_irq(struct gpio_chip *gc, unsigned offset)
> ?{
> ? ? ? ?struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
> -
> - ? ? ? if (chip->irq_base <= 0)
> - ? ? ? ? ? ? ? return -EINVAL;
> -
> - ? ? ? return chip->irq_base + offset;
> + ? ? ? if (!chip->irq_domain)
> + ? ? ? ? ? ? ? return -ENXIO;
> + ? ? ? return irq_domain_to_irq(chip->irq_domain, offset);
> ?}
>
> ?static int pl061_irq_type(struct irq_data *d, unsigned trigger)
> ?{
> ? ? ? ?struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
> ? ? ? ?struct pl061_gpio *chip = gc->private;
> - ? ? ? int offset = d->irq - chip->irq_base;
> + ? ? ? int offset = d->hwirq;
> ? ? ? ?unsigned long flags;
> ? ? ? ?u8 gpiois, gpioibe, gpioiev;
>
> @@ -212,6 +212,7 @@ static void __init pl061_init_gc(struct pl061_gpio *chip, int irq_base)
>
> ? ? ? ?irq_setup_generic_chip(gc, IRQ_MSK(PL061_GPIO_NR),
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? IRQ_GC_INIT_NESTED_LOCK, IRQ_NOREQUEST, 0);
> + ? ? ? chip->irq_domain = gc->domain;
I would expect the driver to store chip->gc = gc instead. Then the
driver has access to both structures, and if ever needed, the gc could
be freed on driver release.
> ?}
>
> ?static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
> @@ -219,7 +220,7 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
> ? ? ? ?struct pl061_platform_data *pdata;
> ? ? ? ?struct pl061_gpio *chip;
> ? ? ? ?struct list_head *chip_list;
> - ? ? ? int ret, irq, i;
> + ? ? ? int ret, irq, i, irq_base;
> ? ? ? ?static DECLARE_BITMAP(init_irq, NR_IRQS);
>
> ? ? ? ?chip = kzalloc(sizeof(*chip), GFP_KERNEL);
> @@ -229,10 +230,13 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
> ? ? ? ?pdata = dev->dev.platform_data;
> ? ? ? ?if (pdata) {
> ? ? ? ? ? ? ? ?chip->gc.base = pdata->gpio_base;
> - ? ? ? ? ? ? ? chip->irq_base = pdata->irq_base;
> + ? ? ? ? ? ? ? irq_base = pdata->irq_base;
> ? ? ? ?} else if (dev->dev.of_node) {
> ? ? ? ? ? ? ? ?chip->gc.base = -1;
> - ? ? ? ? ? ? ? chip->irq_base = 0;
> + ? ? ? ? ? ? ? if (of_get_property(dev->dev.of_node, "interrupt-controller", NULL))
> + ? ? ? ? ? ? ? ? ? ? ? irq_base = -1;
> + ? ? ? ? ? ? ? else
> + ? ? ? ? ? ? ? ? ? ? ? irq_base = 0;
> ? ? ? ?} else {
> ? ? ? ? ? ? ? ?ret = -ENODEV;
> ? ? ? ? ? ? ? ?goto free_mem;
> @@ -271,10 +275,11 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
> ? ? ? ? * irq_chip support
> ? ? ? ? */
>
> - ? ? ? if (chip->irq_base <= 0)
> + ? ? ? if (!irq_base)
> ? ? ? ? ? ? ? ?return 0;
A comment would be useful here as it took a bit for me to work out
what the options are here. What are the possible values of irq_base
at this point, and what do they mean?
Otherwise looks pretty good.
g.
^ permalink raw reply [flat|nested] 43+ messages in thread
* [PATCH v2] gpio: pl061: enable interrupts with DT style binding
2011-12-14 15:28 ` [PATCH 8/9] gpio: pl061: enable interrupts with DT style binding Rob Herring
2011-12-14 21:39 ` Grant Likely
@ 2011-12-19 20:54 ` Rob Herring
1 sibling, 0 replies; 43+ messages in thread
From: Rob Herring @ 2011-12-19 20:54 UTC (permalink / raw)
To: linux-arm-kernel
From: Rob Herring <rob.herring@calxeda.com>
Enable DT interrupt binding support for pl061 gpio lines. If the gpio
node has an interrupt-controller property, then it will be setup to
handle interrupts on gpio lines.
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Cc: Grant Likely <grant.likely@secretlab.ca>
Cc: Linus Walleij <linus.ml.walleij@gmail.com>
---
v2:
- use domain ptr from struct irq_chip_generic
- Add comment on irq_base values.
.../devicetree/bindings/gpio/pl061-gpio.txt | 15 +++++++++
drivers/gpio/gpio-pl061.c | 31 +++++++++++---------
2 files changed, 32 insertions(+), 14 deletions(-)
diff --git a/Documentation/devicetree/bindings/gpio/pl061-gpio.txt b/Documentation/devicetree/bindings/gpio/pl061-gpio.txt
index a2c416b..9671d4e 100644
--- a/Documentation/devicetree/bindings/gpio/pl061-gpio.txt
+++ b/Documentation/devicetree/bindings/gpio/pl061-gpio.txt
@@ -8,3 +8,18 @@ Required properties:
- gpio-controller : Marks the device node as a GPIO controller.
- interrupts : Interrupt mapping for GPIO IRQ.
+Optional properties:
+- interrupt-controller : Identifies the node as an interrupt controller. Must
+ be present if using gpios lines for interrupts.
+- #interrupt-cells : Specifies the number of cells needed to encode an
+ interrupt source. The type shall be a <u32> and the value shall be 2.
+
+ The 1st cell contains the interrupt number 0-7 corresponding to the gpio
+ line.
+
+ The 2nd cell is the flags, encoding trigger type and level flags.
+ 1 = low-to-high edge triggered
+ 2 = high-to-low edge triggered
+ 4 = active high level-sensitive
+ 8 = active low level-sensitive
+
diff --git a/drivers/gpio/gpio-pl061.c b/drivers/gpio/gpio-pl061.c
index 96ff6b2..ea799c7 100644
--- a/drivers/gpio/gpio-pl061.c
+++ b/drivers/gpio/gpio-pl061.c
@@ -16,6 +16,8 @@
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/of.h>
#include <linux/bitops.h>
#include <linux/workqueue.h>
#include <linux/gpio.h>
@@ -52,7 +54,6 @@ struct pl061_gpio {
spinlock_t lock; /* GPIO registers */
void __iomem *base;
- int irq_base;
struct irq_chip_generic *irq_gc;
struct gpio_chip gc;
};
@@ -118,18 +119,16 @@ static void pl061_set_value(struct gpio_chip *gc, unsigned offset, int value)
static int pl061_to_irq(struct gpio_chip *gc, unsigned offset)
{
struct pl061_gpio *chip = container_of(gc, struct pl061_gpio, gc);
-
- if (chip->irq_base <= 0)
- return -EINVAL;
-
- return chip->irq_base + offset;
+ if (!chip->irq_gc)
+ return -ENXIO;
+ return irq_domain_to_irq(&chip->irq_gc->domain, offset);
}
static int pl061_irq_type(struct irq_data *d, unsigned trigger)
{
struct irq_chip_generic *gc = irq_data_get_irq_chip_data(d);
struct pl061_gpio *chip = gc->private;
- int offset = d->irq - chip->irq_base;
+ int offset = d->hwirq;
unsigned long flags;
u8 gpiois, gpioibe, gpioiev;
@@ -219,7 +218,7 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
struct pl061_platform_data *pdata;
struct pl061_gpio *chip;
struct list_head *chip_list;
- int ret, irq, i;
+ int ret, irq, i, irq_base;
static DECLARE_BITMAP(init_irq, NR_IRQS);
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
@@ -229,10 +228,13 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
pdata = dev->dev.platform_data;
if (pdata) {
chip->gc.base = pdata->gpio_base;
- chip->irq_base = pdata->irq_base;
+ irq_base = pdata->irq_base;
} else if (dev->dev.of_node) {
chip->gc.base = -1;
- chip->irq_base = 0;
+ if (of_get_property(dev->dev.of_node, "interrupt-controller", NULL))
+ irq_base = -1;
+ else
+ irq_base = 0;
} else {
ret = -ENODEV;
goto free_mem;
@@ -268,13 +270,14 @@ static int pl061_probe(struct amba_device *dev, const struct amba_id *id)
goto iounmap;
/*
- * irq_chip support
+ * irq_chip support. If irq_base is 0, then we don't support interrupts
+ * on gpio lines and just return now. Otherwise setup the interrupts.
*/
-
- if (chip->irq_base <= 0)
+ if (!irq_base)
return 0;
- pl061_init_gc(chip, chip->irq_base);
+ pl061_init_gc(chip, irq_base);
+ chip->irq_gc->domain.of_node = of_node_get(dev->dev.of_node);
writeb(0, chip->base + GPIOIE); /* disable irqs */
irq = dev->irq[0];
--
1.7.5.4
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [PATCH 9/9] ARM: highbank: add interrupt properties to gpio nodes
2011-12-14 15:28 [PATCH 0/9] irq domain for gen irq chip and pl061 DT irq support Rob Herring
` (7 preceding siblings ...)
2011-12-14 15:28 ` [PATCH 8/9] gpio: pl061: enable interrupts with DT style binding Rob Herring
@ 2011-12-14 15:28 ` Rob Herring
2011-12-14 21:39 ` Grant Likely
2011-12-14 15:41 ` [PATCH 0/9] irq domain for gen irq chip and pl061 DT irq support Rob Herring
9 siblings, 1 reply; 43+ messages in thread
From: Rob Herring @ 2011-12-14 15:28 UTC (permalink / raw)
To: linux-arm-kernel
From: Rob Herring <rob.herring@calxeda.com>
Add interrupt-controller properties to pl061 gpio nodes so gpio lines can
function as interrupts.
Signed-off-by: Rob Herring <rob.herring@calxeda.com>
---
arch/arm/boot/dts/highbank.dts | 9 ++++++++-
1 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/arch/arm/boot/dts/highbank.dts b/arch/arm/boot/dts/highbank.dts
index aeb1a75..dfe2b49 100644
--- a/arch/arm/boot/dts/highbank.dts
+++ b/arch/arm/boot/dts/highbank.dts
@@ -89,7 +89,6 @@
#size-cells = <0>;
#address-cells = <1>;
interrupt-controller;
- interrupt-parent;
reg = <0xfff11000 0x1000>,
<0xfff10100 0x100>;
};
@@ -129,6 +128,8 @@
#gpio-cells = <2>;
compatible = "arm,pl061", "arm,primecell";
gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
reg = <0xfff30000 0x1000>;
interrupts = <0 14 4>;
};
@@ -137,6 +138,8 @@
#gpio-cells = <2>;
compatible = "arm,pl061", "arm,primecell";
gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
reg = <0xfff31000 0x1000>;
interrupts = <0 15 4>;
};
@@ -145,6 +148,8 @@
#gpio-cells = <2>;
compatible = "arm,pl061", "arm,primecell";
gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
reg = <0xfff32000 0x1000>;
interrupts = <0 16 4>;
};
@@ -153,6 +158,8 @@
#gpio-cells = <2>;
compatible = "arm,pl061", "arm,primecell";
gpio-controller;
+ interrupt-controller;
+ #interrupt-cells = <2>;
reg = <0xfff33000 0x1000>;
interrupts = <0 17 4>;
};
--
1.7.5.4
^ permalink raw reply related [flat|nested] 43+ messages in thread
* [PATCH 9/9] ARM: highbank: add interrupt properties to gpio nodes
2011-12-14 15:28 ` [PATCH 9/9] ARM: highbank: add interrupt properties to gpio nodes Rob Herring
@ 2011-12-14 21:39 ` Grant Likely
0 siblings, 0 replies; 43+ messages in thread
From: Grant Likely @ 2011-12-14 21:39 UTC (permalink / raw)
To: linux-arm-kernel
On Wed, Dec 14, 2011 at 8:28 AM, Rob Herring <robherring2@gmail.com> wrote:
> From: Rob Herring <rob.herring@calxeda.com>
>
> Add interrupt-controller properties to pl061 gpio nodes so gpio lines can
> function as interrupts.
>
> Signed-off-by: Rob Herring <rob.herring@calxeda.com>
Acked-by: Grant Likely <grant.likely@secretlab.ca>
> ---
> ?arch/arm/boot/dts/highbank.dts | ? ?9 ++++++++-
> ?1 files changed, 8 insertions(+), 1 deletions(-)
>
> diff --git a/arch/arm/boot/dts/highbank.dts b/arch/arm/boot/dts/highbank.dts
> index aeb1a75..dfe2b49 100644
> --- a/arch/arm/boot/dts/highbank.dts
> +++ b/arch/arm/boot/dts/highbank.dts
> @@ -89,7 +89,6 @@
> ? ? ? ? ? ? ? ? ? ? ? ?#size-cells = <0>;
> ? ? ? ? ? ? ? ? ? ? ? ?#address-cells = <1>;
> ? ? ? ? ? ? ? ? ? ? ? ?interrupt-controller;
> - ? ? ? ? ? ? ? ? ? ? ? interrupt-parent;
> ? ? ? ? ? ? ? ? ? ? ? ?reg = <0xfff11000 0x1000>,
> ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?<0xfff10100 0x100>;
> ? ? ? ? ? ? ? ?};
> @@ -129,6 +128,8 @@
> ? ? ? ? ? ? ? ? ? ? ? ?#gpio-cells = <2>;
> ? ? ? ? ? ? ? ? ? ? ? ?compatible = "arm,pl061", "arm,primecell";
> ? ? ? ? ? ? ? ? ? ? ? ?gpio-controller;
> + ? ? ? ? ? ? ? ? ? ? ? interrupt-controller;
> + ? ? ? ? ? ? ? ? ? ? ? #interrupt-cells = <2>;
> ? ? ? ? ? ? ? ? ? ? ? ?reg = <0xfff30000 0x1000>;
> ? ? ? ? ? ? ? ? ? ? ? ?interrupts = <0 14 4>;
> ? ? ? ? ? ? ? ?};
> @@ -137,6 +138,8 @@
> ? ? ? ? ? ? ? ? ? ? ? ?#gpio-cells = <2>;
> ? ? ? ? ? ? ? ? ? ? ? ?compatible = "arm,pl061", "arm,primecell";
> ? ? ? ? ? ? ? ? ? ? ? ?gpio-controller;
> + ? ? ? ? ? ? ? ? ? ? ? interrupt-controller;
> + ? ? ? ? ? ? ? ? ? ? ? #interrupt-cells = <2>;
> ? ? ? ? ? ? ? ? ? ? ? ?reg = <0xfff31000 0x1000>;
> ? ? ? ? ? ? ? ? ? ? ? ?interrupts = <0 15 4>;
> ? ? ? ? ? ? ? ?};
> @@ -145,6 +148,8 @@
> ? ? ? ? ? ? ? ? ? ? ? ?#gpio-cells = <2>;
> ? ? ? ? ? ? ? ? ? ? ? ?compatible = "arm,pl061", "arm,primecell";
> ? ? ? ? ? ? ? ? ? ? ? ?gpio-controller;
> + ? ? ? ? ? ? ? ? ? ? ? interrupt-controller;
> + ? ? ? ? ? ? ? ? ? ? ? #interrupt-cells = <2>;
> ? ? ? ? ? ? ? ? ? ? ? ?reg = <0xfff32000 0x1000>;
> ? ? ? ? ? ? ? ? ? ? ? ?interrupts = <0 16 4>;
> ? ? ? ? ? ? ? ?};
> @@ -153,6 +158,8 @@
> ? ? ? ? ? ? ? ? ? ? ? ?#gpio-cells = <2>;
> ? ? ? ? ? ? ? ? ? ? ? ?compatible = "arm,pl061", "arm,primecell";
> ? ? ? ? ? ? ? ? ? ? ? ?gpio-controller;
> + ? ? ? ? ? ? ? ? ? ? ? interrupt-controller;
> + ? ? ? ? ? ? ? ? ? ? ? #interrupt-cells = <2>;
> ? ? ? ? ? ? ? ? ? ? ? ?reg = <0xfff33000 0x1000>;
> ? ? ? ? ? ? ? ? ? ? ? ?interrupts = <0 17 4>;
> ? ? ? ? ? ? ? ?};
> --
> 1.7.5.4
>
--
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.
^ permalink raw reply [flat|nested] 43+ messages in thread
* [PATCH 0/9] irq domain for gen irq chip and pl061 DT irq support
2011-12-14 15:28 [PATCH 0/9] irq domain for gen irq chip and pl061 DT irq support Rob Herring
` (8 preceding siblings ...)
2011-12-14 15:28 ` [PATCH 9/9] ARM: highbank: add interrupt properties to gpio nodes Rob Herring
@ 2011-12-14 15:41 ` Rob Herring
9 siblings, 0 replies; 43+ messages in thread
From: Rob Herring @ 2011-12-14 15:41 UTC (permalink / raw)
To: linux-arm-kernel
On 12/14/2011 09:28 AM, Rob Herring wrote:
> From: Rob Herring <rob.herring@calxeda.com>
>
> This series adds irq_domain support to generic irq chip, converts the
> pl061 gpio driver to use generic irq chip, and finally adds DT irq binding
> support for pl061. The pl061 driver is also fixed to use 0 for no irq
> instead of -1 or NO_IRQ.
>
> The irq_domain support should be transparent to users of generic irq
> chip. Shawn Guo has tested previous version with i.MX AVIC and his fixes
> have been incorporated. Any testing by other users of generic irq chip
> is appreciated.
>
> This series is also dependent on:
>
> irqdomain: export irq_domain_simple_ops for !CONFIG_OF
> http://www.spinics.net/lists/arm-kernel/msg150290.html
>
> gpio: pl061: drop extra check for NULL platform_data
> http://www.spinics.net/lists/arm-kernel/msg151701.html
>
> Tested on highbank and built all defconfigs.
>
> Rob
Forgot to mention this series is also available here:
git://sources.calxeda.com/kernel/linux.git pl061-domain
Rob
^ permalink raw reply [flat|nested] 43+ messages in thread