projects
/
openwrt
/
staging
/
mkresin.git
/ commitdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
| commitdiff |
tree
raw
|
patch
|
inline
| side by side (parent:
c7ac9d3
)
GPIODEV: Fix open-count race condition.
author
Michael Büsch
<mb@bu3sch.de>
Wed, 19 Mar 2008 11:32:08 +0000
(11:32 +0000)
committer
Michael Büsch
<mb@bu3sch.de>
Wed, 19 Mar 2008 11:32:08 +0000
(11:32 +0000)
SVN-Revision: 10625
target/linux/generic-2.6/files/drivers/gpio/gpio_dev.c
patch
|
blob
|
history
diff --git
a/target/linux/generic-2.6/files/drivers/gpio/gpio_dev.c
b/target/linux/generic-2.6/files/drivers/gpio/gpio_dev.c
index 690a3fb8c58c2b28889f45b03dd5831814e42386..48ef76f8a962ac7afef99244960a4a5b6309c5bc 100644
(file)
--- a/
target/linux/generic-2.6/files/drivers/gpio/gpio_dev.c
+++ b/
target/linux/generic-2.6/files/drivers/gpio/gpio_dev.c
@@
-25,6
+25,7
@@
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/gpio.h>
#include <asm/uaccess.h>
#include <asm/io.h>
#include <asm/gpio.h>
+#include <asm/atomic.h>
#include <linux/init.h>
#include <linux/genhd.h>
#include <linux/device.h>
#include <linux/init.h>
#include <linux/genhd.h>
#include <linux/device.h>
@@
-35,10
+36,12
@@
#define DEVNAME "gpio"
static int dev_major;
#define DEVNAME "gpio"
static int dev_major;
-static int gpio_is_open = 0;
-unsigned int gpio_access_mask = 0;
+static unsigned int gpio_access_mask;
static struct class *gpio_class;
static struct class *gpio_class;
+/* Counter is 1, if the device is not opened and zero (or less) if opened. */
+static atomic_t gpio_open_cnt = ATOMIC_INIT(1);
+
static int
gpio_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg)
{
static int
gpio_ioctl(struct inode * inode, struct file * file, unsigned int cmd, unsigned long arg)
{
@@
-94,15
+97,18
@@
gpio_open(struct inode *inode, struct file *file)
goto out;
}
goto out;
}
- if (gpio_is_open)
- {
+ /* FIXME: We should really allow multiple applications to open the device
+ * at the same time, as long as the apps access different IO pins.
+ * The generic gpio-registration functions can be used for that.
+ * Two new IOCTLs have to be introduced for that. Need to check userspace
+ * compatibility first. --mb */
+ if (!atomic_dec_and_test(&gpio_open_cnt)) {
+ atomic_inc(&gpio_open_cnt);
printk(KERN_ERR DRVNAME ": Device with minor ID %d already in use\n", dev_minor);
result = -EBUSY;
goto out;
}
printk(KERN_ERR DRVNAME ": Device with minor ID %d already in use\n", dev_minor);
result = -EBUSY;
goto out;
}
- gpio_is_open = 1;
-
out:
return result;
}
out:
return result;
}
@@
-110,7
+116,8
@@
out:
static int
gpio_close(struct inode * inode, struct file * file)
{
static int
gpio_close(struct inode * inode, struct file * file)
{
- gpio_is_open = 0;
+ smp_mb__before_atomic_inc();
+ atomic_inc(&gpio_open_cnt);
return 0;
}
return 0;
}