lkml.org 
[lkml]   [2011]   [Mar]   [17]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    /
    From
    Date
    SubjectRE: [patch 5/5] [RFC] gpio: langwell: Clear edge bit before handling
    On Fri, 18 Mar 2011 03:32:58 +0800
    Thomas Gleixner <tglx@linutronix.de> wrote:

    > I don't have the specs for this beast, but it looks a lot like the PXA
    > GPIO block. Though I bet it's the same IP and the driver should have
    > reused the PXA code.
    >

    I think so.

    > Acknowleding the edge detect status after handling one or more gpio
    > interrupts looks wrong. We might lose an edge which came in while we
    > handled the previous one.
    >

    Thanks for it. Although losing interrupt can always happen if the pending
    IRQs are more than 1, but your patch will reduce the possibility.

    Thanks,
    Alek

    > Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
    > Cc: Feng Tang <feng.tang@intel.com>
    > Cc: Alek Du <alek.du@intel.com>
    > Cc: Alan Cox <alan@lxorguk.ukuu.org.uk>
    >
    > ---
    > drivers/gpio/langwell_gpio.c | 13 ++++++-------
    > 1 file changed, 6 insertions(+), 7 deletions(-)
    >
    > Index: linux-2.6-tip/drivers/gpio/langwell_gpio.c
    > ===================================================================
    > --- linux-2.6-tip.orig/drivers/gpio/langwell_gpio.c
    > +++ linux-2.6-tip/drivers/gpio/langwell_gpio.c
    > @@ -190,23 +190,22 @@ static void lnw_irq_handler(unsigned irq
    > struct irq_data *data = irq_desc_get_irq_data(desc);
    > struct lnw_gpio *lnw = irq_data_get_irq_handler_data(data);
    > struct irq_chip *chip = irq_data_get_irq_chip(data);
    > - u32 base, gpio, gedr_v;
    > + u32 base, gpio, mask;
    > unsigned long pending;
    > void __iomem *gedr;
    >
    > /* check GPIO controller to check which pin triggered the interrupt */
    > for (base = 0; base < lnw->chip.ngpio; base += 32) {
    > gedr = gpio_reg(&lnw->chip, base, GEDR);
    > - gedr_v = pending = readl(gedr);
    > - if (!gedr_v)
    > - continue;
    > + pending = readl(gedr);
    > while (pending) {
    > gpio = __ffs(pending) - 1;
    > - pending &= ~BIT(gpio);
    > + mask = BIT(gpio);
    > + pending &= ~mask;
    > + /* Clear before handling so we can't lose an edge */
    > + writel(mask, gedr);
    > generic_handle_irq(lnw->irq_base + base + gpio);
    > }
    > - /* clear the edge detect status bit */
    > - writel(gedr_v, gedr);
    > }
    >
    > chip->irq_eoi(data);
    >
    >



    \
     
     \ /
      Last update: 2011-03-18 03:37    [W:0.048 / U:0.316 seconds]
    ©2003-2016 Jasper Spaans. hosted at Digital OceanAdvertise on this site