input: make gpio-keys use IRQF_SHARED
diff mbox

Message ID 1253113398-22751-1-git-send-email-dbaryshkov@gmail.com
State Accepted
Commit 558a5e296a02266ef43d6e933ee35df9976de987
Headers show

Commit Message

Dmitry Eremin-Solenikov Sept. 16, 2009, 3:03 p.m. UTC
There is nothing that disallows gpio-keys to share it's IRQ line
w/ other drivers. Make it use IRQF_SHARED in request_irq().

An example of other driver with which I'd like to share IRQ line
for GPIO buttons is ledtrig-gpio.

Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
 drivers/input/keyboard/gpio_keys.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

Comments

Dmitry Torokhov Sept. 16, 2009, 4:28 p.m. UTC | #1
On Wed, Sep 16, 2009 at 07:03:18PM +0400, Dmitry Eremin-Solenikov wrote:
> There is nothing that disallows gpio-keys to share it's IRQ line
> w/ other drivers. Make it use IRQF_SHARED in request_irq().
> 
> An example of other driver with which I'd like to share IRQ line
> for GPIO buttons is ledtrig-gpio.
> 
> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> ---
>  drivers/input/keyboard/gpio_keys.c |    1 +
>  1 files changed, 1 insertions(+), 0 deletions(-)
> 
> diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
> index efed0c9..9fc2fab 100644
> --- a/drivers/input/keyboard/gpio_keys.c
> +++ b/drivers/input/keyboard/gpio_keys.c
> @@ -147,6 +147,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
>  		}
>  
>  		error = request_irq(irq, gpio_keys_isr,
> +				    IRQF_SHARED |
>  				    IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
>  				    button->desc ? button->desc : "gpio_keys",
>  				    bdata);

How will you determine which device generated the interrupt? Because you
can't return IRQ_HANDLED unconditionally and expect both devices work
reliably.
Dmitry Eremin-Solenikov Sept. 16, 2009, 6:41 p.m. UTC | #2
On Wed, Sep 16, 2009 at 8:28 PM, Dmitry Torokhov
<dmitry.torokhov@gmail.com> wrote:
> On Wed, Sep 16, 2009 at 07:03:18PM +0400, Dmitry Eremin-Solenikov wrote:
>> There is nothing that disallows gpio-keys to share it's IRQ line
>> w/ other drivers. Make it use IRQF_SHARED in request_irq().
>>
>> An example of other driver with which I'd like to share IRQ line
>> for GPIO buttons is ledtrig-gpio.
>>
>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>> ---
>>  drivers/input/keyboard/gpio_keys.c |    1 +
>>  1 files changed, 1 insertions(+), 0 deletions(-)
>>
>> diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
>> index efed0c9..9fc2fab 100644
>> --- a/drivers/input/keyboard/gpio_keys.c
>> +++ b/drivers/input/keyboard/gpio_keys.c
>> @@ -147,6 +147,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
>>               }
>>
>>               error = request_irq(irq, gpio_keys_isr,
>> +                                 IRQF_SHARED |
>>                                   IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
>>                                   button->desc ? button->desc : "gpio_keys",
>>                                   bdata);
>
> How will you determine which device generated the interrupt? Because you
> can't return IRQ_HANDLED unconditionally and expect both devices work
> reliably.

It's a single device (gpio pin). However I'd like to be able to attach
several handlers to it.
E.g. one isr is gpio-keys (for reporting event to userspace), another
isr will be from
ledtrig-gpio (controlling the LED). Another can be some kind of
battery driver, etc.

All these drivers will provide different kinds of response for single GPIO pin.
Dmitry Eremin-Solenikov Sept. 18, 2009, 11:44 a.m. UTC | #3
On Wed, Sep 16, 2009 at 10:41 PM, Dmitry Eremin-Solenikov
<dbaryshkov@gmail.com> wrote:
> On Wed, Sep 16, 2009 at 8:28 PM, Dmitry Torokhov
> <dmitry.torokhov@gmail.com> wrote:
>> On Wed, Sep 16, 2009 at 07:03:18PM +0400, Dmitry Eremin-Solenikov wrote:
>>> There is nothing that disallows gpio-keys to share it's IRQ line
>>> w/ other drivers. Make it use IRQF_SHARED in request_irq().
>>>
>>> An example of other driver with which I'd like to share IRQ line
>>> for GPIO buttons is ledtrig-gpio.
>>>
>>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>>> ---
>>>  drivers/input/keyboard/gpio_keys.c |    1 +
>>>  1 files changed, 1 insertions(+), 0 deletions(-)
>>>
>>> diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
>>> index efed0c9..9fc2fab 100644
>>> --- a/drivers/input/keyboard/gpio_keys.c
>>> +++ b/drivers/input/keyboard/gpio_keys.c
>>> @@ -147,6 +147,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
>>>               }
>>>
>>>               error = request_irq(irq, gpio_keys_isr,
>>> +                                 IRQF_SHARED |
>>>                                   IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
>>>                                   button->desc ? button->desc : "gpio_keys",
>>>                                   bdata);
>>
>> How will you determine which device generated the interrupt? Because you
>> can't return IRQ_HANDLED unconditionally and expect both devices work
>> reliably.
>
> It's a single device (gpio pin). However I'd like to be able to attach
> several handlers to it.
> E.g. one isr is gpio-keys (for reporting event to userspace), another
> isr will be from
> ledtrig-gpio (controlling the LED). Another can be some kind of
> battery driver, etc.
>
> All these drivers will provide different kinds of response for single GPIO pin.

So, what about this patch?
Ferenc Wagner Sept. 22, 2009, 3:14 p.m. UTC | #4
Dmitry Torokhov <dmitry.torokhov@gmail.com> writes:

> On Wed, Sep 16, 2009 at 07:03:18PM +0400, Dmitry Eremin-Solenikov wrote:
>> There is nothing that disallows gpio-keys to share it's IRQ line
>> w/ other drivers. Make it use IRQF_SHARED in request_irq().
>> 
>> An example of other driver with which I'd like to share IRQ line
>> for GPIO buttons is ledtrig-gpio.
>> 
>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>> ---
>>  drivers/input/keyboard/gpio_keys.c |    1 +
>>  1 files changed, 1 insertions(+), 0 deletions(-)
>> 
>> diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
>> index efed0c9..9fc2fab 100644
>> --- a/drivers/input/keyboard/gpio_keys.c
>> +++ b/drivers/input/keyboard/gpio_keys.c
>> @@ -147,6 +147,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
>>  		}
>>  
>>  		error = request_irq(irq, gpio_keys_isr,
>> +				    IRQF_SHARED |
>>  				    IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
>>  				    button->desc ? button->desc : "gpio_keys",
>>  				    bdata);
>
> How will you determine which device generated the interrupt? Because you
> can't return IRQ_HANDLED unconditionally and expect both devices work
> reliably.

It would be possible, but commit
da0d03fe6cecde837f113a8a587f5a872d0fade0 states that:

    The gpio_get_value function may sleep, so it should not be called in a
    timer function.

But I don't see why it could sleep, is that really the case?  Because
that makes acknowledging the interrupt very hard.  Actually, I need
and tested interrupt sharing.  What are the "cansleep wrappers" in
asm-generic/gpio.h if these function can sleep as well?  I'd be
grateful for some explanation.  Also, commit
57ffe9d539e0eb741bb9ca8f2834d210e70ee2e3 removed the possibility of
telling apart different keys, so that should be reverted during the
process.  I already asked Uwe Kleine-König about the whys, but didn't
get a reply.
Dmitry Torokhov Sept. 22, 2009, 4:41 p.m. UTC | #5
On Tue, Sep 22, 2009 at 05:14:22PM +0200, Ferenc Wagner wrote:
> Dmitry Torokhov <dmitry.torokhov@gmail.com> writes:
> 
> > On Wed, Sep 16, 2009 at 07:03:18PM +0400, Dmitry Eremin-Solenikov wrote:
> >> There is nothing that disallows gpio-keys to share it's IRQ line
> >> w/ other drivers. Make it use IRQF_SHARED in request_irq().
> >> 
> >> An example of other driver with which I'd like to share IRQ line
> >> for GPIO buttons is ledtrig-gpio.
> >> 
> >> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> >> ---
> >>  drivers/input/keyboard/gpio_keys.c |    1 +
> >>  1 files changed, 1 insertions(+), 0 deletions(-)
> >> 
> >> diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
> >> index efed0c9..9fc2fab 100644
> >> --- a/drivers/input/keyboard/gpio_keys.c
> >> +++ b/drivers/input/keyboard/gpio_keys.c
> >> @@ -147,6 +147,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
> >>  		}
> >>  
> >>  		error = request_irq(irq, gpio_keys_isr,
> >> +				    IRQF_SHARED |
> >>  				    IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
> >>  				    button->desc ? button->desc : "gpio_keys",
> >>  				    bdata);
> >
> > How will you determine which device generated the interrupt? Because you
> > can't return IRQ_HANDLED unconditionally and expect both devices work
> > reliably.
> 
> It would be possible, but commit
> da0d03fe6cecde837f113a8a587f5a872d0fade0 states that:
> 
>     The gpio_get_value function may sleep, so it should not be called in a
>     timer function.
> 
> But I don't see why it could sleep, is that really the case?

There are things like i2c gpio extenders that require access to slow
buses and can't sleep.

>  Because
> that makes acknowledging the interrupt very hard.  Actually, I need
> and tested interrupt sharing.  What are the "cansleep wrappers" in
> asm-generic/gpio.h if these function can sleep as well?  I'd be
> grateful for some explanation.  Also, commit
> 57ffe9d539e0eb741bb9ca8f2834d210e70ee2e3 removed the possibility of
> telling apart different keys, so that should be reverted during the
> process.  I already asked Uwe Kleine-König about the whys, but didn't
> get a reply.

I don't see why you say that... You request IRQ per button and you get
that button structure as argument in the interrupt handler.
Dmitry Torokhov Sept. 22, 2009, 4:42 p.m. UTC | #6
On Fri, Sep 18, 2009 at 03:44:41PM +0400, Dmitry Eremin-Solenikov wrote:
> On Wed, Sep 16, 2009 at 10:41 PM, Dmitry Eremin-Solenikov
> <dbaryshkov@gmail.com> wrote:
> > On Wed, Sep 16, 2009 at 8:28 PM, Dmitry Torokhov
> > <dmitry.torokhov@gmail.com> wrote:
> >> On Wed, Sep 16, 2009 at 07:03:18PM +0400, Dmitry Eremin-Solenikov wrote:
> >>> There is nothing that disallows gpio-keys to share it's IRQ line
> >>> w/ other drivers. Make it use IRQF_SHARED in request_irq().
> >>>
> >>> An example of other driver with which I'd like to share IRQ line
> >>> for GPIO buttons is ledtrig-gpio.
> >>>
> >>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> >>> ---
> >>>  drivers/input/keyboard/gpio_keys.c |    1 +
> >>>  1 files changed, 1 insertions(+), 0 deletions(-)
> >>>
> >>> diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
> >>> index efed0c9..9fc2fab 100644
> >>> --- a/drivers/input/keyboard/gpio_keys.c
> >>> +++ b/drivers/input/keyboard/gpio_keys.c
> >>> @@ -147,6 +147,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
> >>>               }
> >>>
> >>>               error = request_irq(irq, gpio_keys_isr,
> >>> +                                 IRQF_SHARED |
> >>>                                   IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
> >>>                                   button->desc ? button->desc : "gpio_keys",
> >>>                                   bdata);
> >>
> >> How will you determine which device generated the interrupt? Because you
> >> can't return IRQ_HANDLED unconditionally and expect both devices work
> >> reliably.
> >
> > It's a single device (gpio pin). However I'd like to be able to attach
> > several handlers to it.
> > E.g. one isr is gpio-keys (for reporting event to userspace), another
> > isr will be from
> > ledtrig-gpio (controlling the LED). Another can be some kind of
> > battery driver, etc.
> >
> > All these drivers will provide different kinds of response for single GPIO pin.
> 
> So, what about this patch?
> 

OK, will apply.
Ferenc Wagner Sept. 22, 2009, 6:50 p.m. UTC | #7
Dmitry Torokhov <dmitry.torokhov@gmail.com> writes:

> On Fri, Sep 18, 2009 at 03:44:41PM +0400, Dmitry Eremin-Solenikov wrote:
>> On Wed, Sep 16, 2009 at 10:41 PM, Dmitry Eremin-Solenikov
>> <dbaryshkov@gmail.com> wrote:
>>> On Wed, Sep 16, 2009 at 8:28 PM, Dmitry Torokhov
>>> <dmitry.torokhov@gmail.com> wrote:
>>>> On Wed, Sep 16, 2009 at 07:03:18PM +0400, Dmitry Eremin-Solenikov wrote:
>>>>> There is nothing that disallows gpio-keys to share it's IRQ line
>>>>> w/ other drivers. Make it use IRQF_SHARED in request_irq().
>>>>>
>>>>> An example of other driver with which I'd like to share IRQ line
>>>>> for GPIO buttons is ledtrig-gpio.
>>>>>
>>>>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>>>>> ---
>>>>>  drivers/input/keyboard/gpio_keys.c |    1 +
>>>>>  1 files changed, 1 insertions(+), 0 deletions(-)
>>>>>
>>>>> diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
>>>>> index efed0c9..9fc2fab 100644
>>>>> --- a/drivers/input/keyboard/gpio_keys.c
>>>>> +++ b/drivers/input/keyboard/gpio_keys.c
>>>>> @@ -147,6 +147,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
>>>>>               }
>>>>>
>>>>>               error = request_irq(irq, gpio_keys_isr,
>>>>> +                                 IRQF_SHARED |
>>>>>                                   IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
>>>>>                                   button->desc ? button->desc : "gpio_keys",
>>>>>                                   bdata);
>>>>
>>>> How will you determine which device generated the interrupt? Because you
>>>> can't return IRQ_HANDLED unconditionally and expect both devices work
>>>> reliably.
>>>
>>> It's a single device (gpio pin). However I'd like to be able to attach
>>> several handlers to it.
>>> E.g. one isr is gpio-keys (for reporting event to userspace), another
>>> isr will be from
>>> ledtrig-gpio (controlling the LED). Another can be some kind of
>>> battery driver, etc.
>>>
>>> All these drivers will provide different kinds of response for single GPIO pin.
>> 
>> So, what about this patch?
>
> OK, will apply.

I still think it's dangerous.  But I am not a kernel hacker and a very
beginner on this whole field, so please let me explain why, and please
correct my conclusions as needed.

I met this problem playing with an embedded platform (brcm47xx), where
I wanted to employ the gpio_keys driver.  Registering the gpio_keys
platform device wasn't enough, because the gpio_keys module still
couldn't be loaded as the serial console already used the same
interrupt line of the Sonics Silicon Backplane.  (Also, it used
shared, but level triggered interrupts, so simply adding in
IRQF_SHARED wouldn't have helped either, besides breaking both
devices).  Anyway, such platforms may have several GPIO buttons,
typically using the same interrupt line, so there must be a way to
tell them apart, which looks impossible without some GPIO access to
acknowledge (change polarity of) the correct button.  So I plan to put
forward some changes in this area, like switching to level triggered
interrupts to facilitate sharing.  I've got some proof of concept
code, but still have to learn the ropes.

Apart from this, adding in IRQF_SHARED like above for being able to
attach several handlers looks fishy big time.  Would the rest be
invoked at all once you returned IRQ_HANDLED from the first (it's a
question of fact in Linux interrupt handling, I just down't know, but
would guess yes, for level triggered interrupts at least)?  Is this
common practice?
Ferenc Wagner Sept. 22, 2009, 7:06 p.m. UTC | #8
Dmitry Torokhov <dmitry.torokhov@gmail.com> writes:

> On Tue, Sep 22, 2009 at 05:14:22PM +0200, Ferenc Wagner wrote:
>> Dmitry Torokhov <dmitry.torokhov@gmail.com> writes:
>> 
>>> On Wed, Sep 16, 2009 at 07:03:18PM +0400, Dmitry Eremin-Solenikov wrote:
>>>> There is nothing that disallows gpio-keys to share it's IRQ line
>>>> w/ other drivers. Make it use IRQF_SHARED in request_irq().
>>>> 
>>>> An example of other driver with which I'd like to share IRQ line
>>>> for GPIO buttons is ledtrig-gpio.
>>>> 
>>>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
>>>> ---
>>>>  drivers/input/keyboard/gpio_keys.c |    1 +
>>>>  1 files changed, 1 insertions(+), 0 deletions(-)
>>>> 
>>>> diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
>>>> index efed0c9..9fc2fab 100644
>>>> --- a/drivers/input/keyboard/gpio_keys.c
>>>> +++ b/drivers/input/keyboard/gpio_keys.c
>>>> @@ -147,6 +147,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
>>>>  		}
>>>>  
>>>>  		error = request_irq(irq, gpio_keys_isr,
>>>> +				    IRQF_SHARED |
>>>>  				    IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
>>>>  				    button->desc ? button->desc : "gpio_keys",
>>>>  				    bdata);
>>>
>>> How will you determine which device generated the interrupt? Because you
>>> can't return IRQ_HANDLED unconditionally and expect both devices work
>>> reliably.
>> 
>> It would be possible, but commit
>> da0d03fe6cecde837f113a8a587f5a872d0fade0 states that:
>> 
>>     The gpio_get_value function may sleep, so it should not be called in a
>>     timer function.
>> 
>> But I don't see why it could sleep, is that really the case?
>
> There are things like i2c gpio extenders that require access to slow
> buses and can't sleep.

I assume you mean "can sleep".  Please read my other reply in this
thread before the following.  All this seems to mean that using level
triggered interrupts on such devices is impossible, unless we find a
way to acknowledge the interrupt without GPIO access.  But level
triggering is needed for sharing.  Maybe we could make this
configurable on a per-button basis?  Or by a module parameter?
Anyway, a gpio_cansleep test should go into the module initialisation
routine.

>> Also, commit 57ffe9d539e0eb741bb9ca8f2834d210e70ee2e3 removed the
>> possibility of telling apart different keys, so that should be
>> reverted during the process.  I already asked Uwe Kleine-König
>> about the whys, but didn't get a reply.
>
> I don't see why you say that... You request IRQ per button and you get
> that button structure as argument in the interrupt handler.

In practice, several buttons often share a single IRQ line, possibly
even with other hardware, like the serial port in my case (as
described in my other reply).  So generally you need the full platform
data for all GPIO buttons in the handler, to find out which generated
the interrupt.
Dmitry Torokhov Sept. 28, 2009, 5:03 p.m. UTC | #9
On Tue, Sep 22, 2009 at 09:06:05PM +0200, Ferenc Wagner wrote:
> Dmitry Torokhov <dmitry.torokhov@gmail.com> writes:
> 
> > On Tue, Sep 22, 2009 at 05:14:22PM +0200, Ferenc Wagner wrote:
> >> Dmitry Torokhov <dmitry.torokhov@gmail.com> writes:
> >> 
> >>> On Wed, Sep 16, 2009 at 07:03:18PM +0400, Dmitry Eremin-Solenikov wrote:
> >>>> There is nothing that disallows gpio-keys to share it's IRQ line
> >>>> w/ other drivers. Make it use IRQF_SHARED in request_irq().
> >>>> 
> >>>> An example of other driver with which I'd like to share IRQ line
> >>>> for GPIO buttons is ledtrig-gpio.
> >>>> 
> >>>> Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
> >>>> ---
> >>>>  drivers/input/keyboard/gpio_keys.c |    1 +
> >>>>  1 files changed, 1 insertions(+), 0 deletions(-)
> >>>> 
> >>>> diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
> >>>> index efed0c9..9fc2fab 100644
> >>>> --- a/drivers/input/keyboard/gpio_keys.c
> >>>> +++ b/drivers/input/keyboard/gpio_keys.c
> >>>> @@ -147,6 +147,7 @@ static int __devinit gpio_keys_probe(struct platform_device *pdev)
> >>>>  		}
> >>>>  
> >>>>  		error = request_irq(irq, gpio_keys_isr,
> >>>> +				    IRQF_SHARED |
> >>>>  				    IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
> >>>>  				    button->desc ? button->desc : "gpio_keys",
> >>>>  				    bdata);
> >>>
> >>> How will you determine which device generated the interrupt? Because you
> >>> can't return IRQ_HANDLED unconditionally and expect both devices work
> >>> reliably.
> >> 
> >> It would be possible, but commit
> >> da0d03fe6cecde837f113a8a587f5a872d0fade0 states that:
> >> 
> >>     The gpio_get_value function may sleep, so it should not be called in a
> >>     timer function.
> >> 
> >> But I don't see why it could sleep, is that really the case?
> >
> > There are things like i2c gpio extenders that require access to slow
> > buses and can't sleep.
> 
> I assume you mean "can sleep".

Yes.

> Please read my other reply in this
> thread before the following.  All this seems to mean that using level
> triggered interrupts on such devices is impossible, unless we find a
> way to acknowledge the interrupt without GPIO access.

You probably want to look into threaded interrupt handlers and
IRQF_ONESHOT. These can't be shared though, so it looks like you need
nested IRQ handlers ifrastructure.

> But level
> triggering is needed for sharing.

I believe that both level and edge-triggered interrupts can be shared.

>  Maybe we could make this
> configurable on a per-button basis?  Or by a module parameter?
> Anyway, a gpio_cansleep test should go into the module initialisation
> routine.
> 
> >> Also, commit 57ffe9d539e0eb741bb9ca8f2834d210e70ee2e3 removed the
> >> possibility of telling apart different keys, so that should be
> >> reverted during the process.  I already asked Uwe Kleine-König
> >> about the whys, but didn't get a reply.
> >
> > I don't see why you say that... You request IRQ per button and you get
> > that button structure as argument in the interrupt handler.
> 
> In practice, several buttons often share a single IRQ line, possibly
> even with other hardware, like the serial port in my case (as
> described in my other reply).  So generally you need the full platform
> data for all GPIO buttons in the handler, to find out which generated
> the interrupt.

Your interrupt handler will get called for every button on that IRQ line
and you can query button state I think.

Patch
diff mbox

diff --git a/drivers/input/keyboard/gpio_keys.c b/drivers/input/keyboard/gpio_keys.c
index efed0c9..9fc2fab 100644
--- a/drivers/input/keyboard/gpio_keys.c
+++ b/drivers/input/keyboard/gpio_keys.c
@@ -147,6 +147,7 @@  static int __devinit gpio_keys_probe(struct platform_device *pdev)
 		}
 
 		error = request_irq(irq, gpio_keys_isr,
+				    IRQF_SHARED |
 				    IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
 				    button->desc ? button->desc : "gpio_keys",
 				    bdata);