Subject: Re: [PATCH 6/7] gpio: dwapb: use a second irq chip

On 03/25/2014 10:36 PM, Sebastian Hesselbarth wrote:
>> @@ -242,17 +244,28 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio,
>> irq_gc->reg_base = gpio->regs;
>> irq_gc->private = gpio;
>>
>> - ct = irq_gc->chip_types;
>> - ct->chip.irq_ack = irq_gc_ack_set_bit;
>> - ct->chip.irq_mask = irq_gc_mask_set_bit;
>> - ct->chip.irq_unmask = irq_gc_mask_clr_bit;
>> - ct->chip.irq_set_type = dwapb_irq_set_type;
>> - ct->chip.irq_enable = dwapb_irq_enable;
>> - ct->chip.irq_disable = dwapb_irq_disable;
>> - ct->chip.irq_request_resources = dwapb_irq_reqres;
>> - ct->chip.irq_release_resources = dwapb_irq_relres;
>> - ct->regs.ack = GPIO_PORTA_EOI;
>> - ct->regs.mask = GPIO_INTMASK;
>> + for (i = 0; i < 2; i++) {
>> +
>> + ct = &irq_gc->chip_types[i];
>> + ct->chip.irq_ack = irq_gc_ack_set_bit;
>> + ct->chip.irq_mask = irq_gc_mask_set_bit;
>> + ct->chip.irq_unmask = irq_gc_mask_clr_bit;
>> + ct->chip.irq_set_type = dwapb_irq_set_type;
>> + ct->chip.irq_enable = dwapb_irq_enable;
>> + ct->chip.irq_disable = dwapb_irq_disable;
>> + ct->chip.irq_request_resources = dwapb_irq_reqres;
>> + ct->chip.irq_release_resources = dwapb_irq_relres;
>> + ct->regs.ack = GPIO_PORTA_EOI;
>> + ct->regs.mask = GPIO_INTMASK;
>> +
>> + if (i == 0) {
>> + ct->type = IRQ_TYPE_LEVEL_MASK;
>> + ct->handler = handle_level_irq;
>> + } else {
>> + ct->type = IRQ_TYPE_EDGE_BOTH;
>> + ct->handler = handle_edge_irq;
>> + }
>
> Sebastian,
>
> IMHO the loop looks strange, especially with the (i == 0) check.

how so?

> How about unrolling it again and assign both chip_types independently?

If more code makes you happy so be it. I will post the series soon with
the loop unrolled.

> Sebastian

Sebastian


2014-04-08 15:11:25

by Alan Tull

[permalink] [raw]
Subject: Re: [PATCH 6/7] gpio: dwapb: use a second irq chip

On Mon, Apr 7, 2014 at 4:59 AM, Sebastian Andrzej Siewior
<[email protected]> wrote:
> On 03/25/2014 10:36 PM, Sebastian Hesselbarth wrote:
>>> @@ -242,17 +244,28 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio,
>>> irq_gc->reg_base = gpio->regs;
>>> irq_gc->private = gpio;
>>>
>>> - ct = irq_gc->chip_types;
>>> - ct->chip.irq_ack = irq_gc_ack_set_bit;
>>> - ct->chip.irq_mask = irq_gc_mask_set_bit;
>>> - ct->chip.irq_unmask = irq_gc_mask_clr_bit;
>>> - ct->chip.irq_set_type = dwapb_irq_set_type;
>>> - ct->chip.irq_enable = dwapb_irq_enable;
>>> - ct->chip.irq_disable = dwapb_irq_disable;
>>> - ct->chip.irq_request_resources = dwapb_irq_reqres;
>>> - ct->chip.irq_release_resources = dwapb_irq_relres;
>>> - ct->regs.ack = GPIO_PORTA_EOI;
>>> - ct->regs.mask = GPIO_INTMASK;
>>> + for (i = 0; i < 2; i++) {
>>> +
>>> + ct = &irq_gc->chip_types[i];
>>> + ct->chip.irq_ack = irq_gc_ack_set_bit;
>>> + ct->chip.irq_mask = irq_gc_mask_set_bit;
>>> + ct->chip.irq_unmask = irq_gc_mask_clr_bit;
>>> + ct->chip.irq_set_type = dwapb_irq_set_type;
>>> + ct->chip.irq_enable = dwapb_irq_enable;
>>> + ct->chip.irq_disable = dwapb_irq_disable;
>>> + ct->chip.irq_request_resources = dwapb_irq_reqres;
>>> + ct->chip.irq_release_resources = dwapb_irq_relres;
>>> + ct->regs.ack = GPIO_PORTA_EOI;
>>> + ct->regs.mask = GPIO_INTMASK;
>>> +
>>> + if (i == 0) {
>>> + ct->type = IRQ_TYPE_LEVEL_MASK;
>>> + ct->handler = handle_level_irq;
>>> + } else {
>>> + ct->type = IRQ_TYPE_EDGE_BOTH;
>>> + ct->handler = handle_edge_irq;
>>> + }
>>
>> Sebastian,
>>
>> IMHO the loop looks strange, especially with the (i == 0) check.
>
> how so?
>
>> How about unrolling it again and assign both chip_types independently?
>
> If more code makes you happy so be it. I will post the series soon with
> the loop unrolled.
>
>> Sebastian
>
> Sebastian

You could keep the loop but take out the if (i==0). Set the type and
handler after the loop:

irq_gc->chip_types[0]->type = IRQ_TYPE_LEVEL_MASK;
irq_gc->chip_types[0]->handler = handle_level_irq;
irq_gc->chip_types[1]->type = IRQ_TYPE_EDGE_BOTH;
irq_gc->chip_types[1]->handler = handle_edge_irq;

Alan Tull
aka
delicious quinoa

Subject: [PATCH 6/7 v2] gpio: dwapb: use a second irq chip

Right new have one irq chip running always in level mode. It would nicer
to have two irq chips where one is handling level type interrupts and
the other one is doing edge interrupts. So we can have at runtime two users
where one is using edge and the other level.

Signed-off-by: Sebastian Andrzej Siewior <[email protected]>
---
I am very sorry for the delay. I assumed that I've already fixed the
patch sent it out. Just realized that it was not the case.

v1…v2:
- using the lopp again but breaking the assignment of type and
handler out of the loop as suggested by delicious quinoa.

drivers/gpio/gpio-dwapb.c | 35 ++++++++++++++++++++++-------------
1 file changed, 22 insertions(+), 13 deletions(-)

diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c
index 752ccb1..ca36f11 100644
--- a/drivers/gpio/gpio-dwapb.c
+++ b/drivers/gpio/gpio-dwapb.c
@@ -192,6 +192,8 @@ static int dwapb_irq_set_type(struct irq_data *d, u32 type)
break;
}

+ irq_setup_alt_chip(d, type);
+
writel(level, gpio->regs + GPIO_INTTYPE_LEVEL);
writel(polarity, gpio->regs + GPIO_INT_POLARITY);
irq_gc_unlock(igc);
@@ -207,7 +209,7 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio,
struct irq_chip_generic *irq_gc;
unsigned int hwirq, ngpio = gc->ngpio;
struct irq_chip_type *ct;
- int err, irq;
+ int err, irq, i;

irq = irq_of_parse_and_map(node, 0);
if (!irq) {
@@ -221,7 +223,7 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio,
if (!gpio->domain)
return;

- err = irq_alloc_domain_generic_chips(gpio->domain, ngpio, 1,
+ err = irq_alloc_domain_generic_chips(gpio->domain, ngpio, 2,
"gpio-dwapb", handle_level_irq,
IRQ_NOREQUEST, 0,
IRQ_GC_INIT_NESTED_LOCK);
@@ -242,17 +244,24 @@ static void dwapb_configure_irqs(struct dwapb_gpio *gpio,
irq_gc->reg_base = gpio->regs;
irq_gc->private = gpio;

- ct = irq_gc->chip_types;
- ct->chip.irq_ack = irq_gc_ack_set_bit;
- ct->chip.irq_mask = irq_gc_mask_set_bit;
- ct->chip.irq_unmask = irq_gc_mask_clr_bit;
- ct->chip.irq_set_type = dwapb_irq_set_type;
- ct->chip.irq_enable = dwapb_irq_enable;
- ct->chip.irq_disable = dwapb_irq_disable;
- ct->chip.irq_request_resources = dwapb_irq_reqres;
- ct->chip.irq_release_resources = dwapb_irq_relres;
- ct->regs.ack = GPIO_PORTA_EOI;
- ct->regs.mask = GPIO_INTMASK;
+ for (i = 0; i < 2; i++) {
+ ct = &irq_gc->chip_types[i];
+ ct->chip.irq_ack = irq_gc_ack_set_bit;
+ ct->chip.irq_mask = irq_gc_mask_set_bit;
+ ct->chip.irq_unmask = irq_gc_mask_clr_bit;
+ ct->chip.irq_set_type = dwapb_irq_set_type;
+ ct->chip.irq_enable = dwapb_irq_enable;
+ ct->chip.irq_disable = dwapb_irq_disable;
+ ct->chip.irq_request_resources = dwapb_irq_reqres;
+ ct->chip.irq_release_resources = dwapb_irq_relres;
+ ct->regs.ack = GPIO_PORTA_EOI;
+ ct->regs.mask = GPIO_INTMASK;
+ ct->type = IRQ_TYPE_LEVEL_MASK;
+ }
+
+ irq_gc->chip_types[0].type = IRQ_TYPE_LEVEL_MASK;
+ irq_gc->chip_types[1].type = IRQ_TYPE_EDGE_BOTH;
+ irq_gc->chip_types[1].handler = handle_edge_irq;

irq_set_chained_handler(irq, dwapb_irq_handler);
irq_set_handler_data(irq, gpio);
--
1.9.2