drivers/gpio/timbgpio.c: add missing unlock
authorJulia Lawall <julia@diku.dk>
Tue, 6 Apr 2010 21:34:48 +0000 (14:34 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 7 Apr 2010 15:38:02 +0000 (08:38 -0700)
In an error handling case the lock is not unlocked.  The return is
converted to a goto, to share the unlock at the end of the function.

A simplified version of the semantic patch that finds this problem is as
follows: (http://coccinelle.lip6.fr/)

// <smpl>
@r exists@
expression E1;
identifier f;
@@

f (...) { <+...
* spin_lock_irqsave (E1,...);
... when != E1
* return ...;
...+> }
// </smpl>

Signed-off-by: Julia Lawall <julia@diku.dk>
Cc: <richard.rojfors@pelagicore.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
drivers/gpio/timbgpio.c

index ac4d0f0ea02bb362ef6d210884d3c25f7c33c01f..ddd053108a136ce2a41dd346a438622609c7f480 100644 (file)
@@ -131,6 +131,7 @@ static int timbgpio_irq_type(unsigned irq, unsigned trigger)
        unsigned long flags;
        u32 lvr, flr, bflr = 0;
        u32 ver;
+       int ret = 0;
 
        if (offset < 0 || offset > tgpio->gpio.ngpio)
                return -EINVAL;
@@ -154,8 +155,10 @@ static int timbgpio_irq_type(unsigned irq, unsigned trigger)
        }
 
        if ((trigger & IRQ_TYPE_EDGE_BOTH) == IRQ_TYPE_EDGE_BOTH) {
-               if (ver < 3)
-                       return -EINVAL;
+               if (ver < 3) {
+                       ret = -EINVAL;
+                       goto out;
+               }
                else {
                        flr |= 1 << offset;
                        bflr |= 1 << offset;
@@ -175,9 +178,10 @@ static int timbgpio_irq_type(unsigned irq, unsigned trigger)
                iowrite32(bflr, tgpio->membase + TGPIO_BFLR);
 
        iowrite32(1 << offset, tgpio->membase + TGPIO_ICR);
-       spin_unlock_irqrestore(&tgpio->lock, flags);
 
-       return 0;
+out:
+       spin_unlock_irqrestore(&tgpio->lock, flags);
+       return ret;
 }
 
 static void timbgpio_irq(unsigned int irq, struct irq_desc *desc)