diff options
author | Roel Kluin <12o3l@tiscali.nl> | 2007-11-14 20:00:06 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-11-14 21:45:42 -0500 |
commit | 5c6ff79d0908df0d281c05b5b693eaba55b06e0f (patch) | |
tree | 81d276887ab70d83d88d5fc953cae816912381a2 /arch/cris | |
parent | 5d0360ee96a5ef953dbea45873c2a8c87e77d59b (diff) |
cris gpio: undo locks before returning
Signed-off-by: Roel Kluin <12o3l@tiscali.nl>
Cc: Mikael Starvik <starvik@axis.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'arch/cris')
-rw-r--r-- | arch/cris/arch-v10/drivers/gpio.c | 15 |
1 files changed, 11 insertions, 4 deletions
diff --git a/arch/cris/arch-v10/drivers/gpio.c b/arch/cris/arch-v10/drivers/gpio.c index f389ed6998fe..0d347a705835 100644 --- a/arch/cris/arch-v10/drivers/gpio.c +++ b/arch/cris/arch-v10/drivers/gpio.c | |||
@@ -297,8 +297,10 @@ gpio_poll(struct file *file, | |||
297 | data = *R_PORT_PB_DATA; | 297 | data = *R_PORT_PB_DATA; |
298 | else if (priv->minor == GPIO_MINOR_G) | 298 | else if (priv->minor == GPIO_MINOR_G) |
299 | data = *R_PORT_G_DATA; | 299 | data = *R_PORT_G_DATA; |
300 | else | 300 | else { |
301 | spin_unlock(&gpio_lock); | ||
301 | return 0; | 302 | return 0; |
303 | } | ||
302 | 304 | ||
303 | if ((data & priv->highalarm) || | 305 | if ((data & priv->highalarm) || |
304 | (~data & priv->lowalarm)) { | 306 | (~data & priv->lowalarm)) { |
@@ -381,18 +383,21 @@ static ssize_t gpio_write(struct file * file, const char * buf, size_t count, | |||
381 | 383 | ||
382 | ssize_t retval = count; | 384 | ssize_t retval = count; |
383 | if (priv->minor !=GPIO_MINOR_A && priv->minor != GPIO_MINOR_B) { | 385 | if (priv->minor !=GPIO_MINOR_A && priv->minor != GPIO_MINOR_B) { |
384 | return -EFAULT; | 386 | retval = -EFAULT; |
387 | goto out; | ||
385 | } | 388 | } |
386 | 389 | ||
387 | if (!access_ok(VERIFY_READ, buf, count)) { | 390 | if (!access_ok(VERIFY_READ, buf, count)) { |
388 | return -EFAULT; | 391 | retval = -EFAULT; |
392 | goto out; | ||
389 | } | 393 | } |
390 | clk_mask = priv->clk_mask; | 394 | clk_mask = priv->clk_mask; |
391 | data_mask = priv->data_mask; | 395 | data_mask = priv->data_mask; |
392 | /* It must have been configured using the IO_CFG_WRITE_MODE */ | 396 | /* It must have been configured using the IO_CFG_WRITE_MODE */ |
393 | /* Perhaps a better error code? */ | 397 | /* Perhaps a better error code? */ |
394 | if (clk_mask == 0 || data_mask == 0) { | 398 | if (clk_mask == 0 || data_mask == 0) { |
395 | return -EPERM; | 399 | retval = -EPERM; |
400 | goto out; | ||
396 | } | 401 | } |
397 | write_msb = priv->write_msb; | 402 | write_msb = priv->write_msb; |
398 | D(printk("gpio_write: %lu to data 0x%02X clk 0x%02X msb: %i\n",count, data_mask, clk_mask, write_msb)); | 403 | D(printk("gpio_write: %lu to data 0x%02X clk 0x%02X msb: %i\n",count, data_mask, clk_mask, write_msb)); |
@@ -425,6 +430,7 @@ static ssize_t gpio_write(struct file * file, const char * buf, size_t count, | |||
425 | } | 430 | } |
426 | } | 431 | } |
427 | } | 432 | } |
433 | out: | ||
428 | spin_unlock(&gpio_lock); | 434 | spin_unlock(&gpio_lock); |
429 | return retval; | 435 | return retval; |
430 | } | 436 | } |
@@ -506,6 +512,7 @@ gpio_release(struct inode *inode, struct file *filp) | |||
506 | while (p) { | 512 | while (p) { |
507 | if (p->highalarm | p->lowalarm) { | 513 | if (p->highalarm | p->lowalarm) { |
508 | gpio_some_alarms = 1; | 514 | gpio_some_alarms = 1; |
515 | spin_unlock(&gpio_lock); | ||
509 | return 0; | 516 | return 0; |
510 | } | 517 | } |
511 | p = p->next; | 518 | p = p->next; |