lkml.org 
[lkml]   [2020]   [Aug]   [20]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.8 053/232] pinctrl: ingenic: Enhance support for IRQ_TYPE_EDGE_BOTH
    Date
    From: Paul Cercueil <paul@crapouillou.net>

    commit 1c95348ba327fe8621d3680890c2341523d3524a upstream.

    Ingenic SoCs don't natively support registering an interrupt for both
    rising and falling edges. This has to be emulated in software.

    Until now, this was emulated by switching back and forth between
    IRQ_TYPE_EDGE_RISING and IRQ_TYPE_EDGE_FALLING according to the level of
    the GPIO. While this worked most of the time, when used with GPIOs that
    need debouncing, some events would be lost. For instance, between the
    time a falling-edge interrupt happens and the interrupt handler
    configures the hardware for rising-edge, the level of the pin may have
    already risen, and the rising-edge event is lost.

    To address that issue, instead of switching back and forth between
    IRQ_TYPE_EDGE_RISING and IRQ_TYPE_EDGE_FALLING, we now switch back and
    forth between IRQ_TYPE_LEVEL_LOW and IRQ_TYPE_LEVEL_HIGH. Since we
    always switch in the interrupt handler, they actually permit to detect
    level changes. In the example above, if the pin level rises before
    switching the IRQ type from IRQ_TYPE_LEVEL_LOW to IRQ_TYPE_LEVEL_HIGH,
    a new interrupt will raise as soon as the handler exits, and the
    rising-edge event will be properly detected.

    Fixes: e72394e2ea19 ("pinctrl: ingenic: Merge GPIO functionality")
    Reported-by: João Henrique <johnnyonflame@hotmail.com>
    Signed-off-by: Paul Cercueil <paul@crapouillou.net>
    Tested-by: João Henrique <johnnyonflame@hotmail.com>
    Cc: stable@vger.kernel.org
    Link: https://lore.kernel.org/r/20200622214548.265417-1-paul@crapouillou.net
    Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
    Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

    ---
    drivers/pinctrl/pinctrl-ingenic.c | 6 +++---
    1 file changed, 3 insertions(+), 3 deletions(-)

    --- a/drivers/pinctrl/pinctrl-ingenic.c
    +++ b/drivers/pinctrl/pinctrl-ingenic.c
    @@ -1810,9 +1810,9 @@ static void ingenic_gpio_irq_ack(struct
    */
    high = ingenic_gpio_get_value(jzgc, irq);
    if (high)
    - irq_set_type(jzgc, irq, IRQ_TYPE_EDGE_FALLING);
    + irq_set_type(jzgc, irq, IRQ_TYPE_LEVEL_LOW);
    else
    - irq_set_type(jzgc, irq, IRQ_TYPE_EDGE_RISING);
    + irq_set_type(jzgc, irq, IRQ_TYPE_LEVEL_HIGH);
    }

    if (jzgc->jzpc->info->version >= ID_JZ4760)
    @@ -1848,7 +1848,7 @@ static int ingenic_gpio_irq_set_type(str
    */
    bool high = ingenic_gpio_get_value(jzgc, irqd->hwirq);

    - type = high ? IRQ_TYPE_EDGE_FALLING : IRQ_TYPE_EDGE_RISING;
    + type = high ? IRQ_TYPE_LEVEL_LOW : IRQ_TYPE_LEVEL_HIGH;
    }

    irq_set_type(jzgc, irqd->hwirq, type);

    \
     
     \ /
      Last update: 2020-08-20 11:27    [W:4.103 / U:0.384 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site