From 9d900ba96f89193c4a6d7e9d3ebeed1cf434e91e Mon Sep 17 00:00:00 2001 From: Dmitry Torokhov Date: Sun, 29 May 2005 02:29:25 -0500 Subject: [PATCH] --- yaml --- r: 3522 b: refs/heads/master c: 0fbf87caf70acec0c435233fbc39c7bd0aca3ca6 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/drivers/input/input.c | 33 ++++++++++++++++++++++++++++----- trunk/include/linux/input.h | 4 ++++ 3 files changed, 33 insertions(+), 6 deletions(-) diff --git a/[refs] b/[refs] index d678c9c792c7..fcfef880b91c 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 58a007765bb5f16020e6000ecbdc5bcc6e54a147 +refs/heads/master: 0fbf87caf70acec0c435233fbc39c7bd0aca3ca6 diff --git a/trunk/drivers/input/input.c b/trunk/drivers/input/input.c index 3385dd03abfc..1885f369e3e2 100644 --- a/trunk/drivers/input/input.c +++ b/trunk/drivers/input/input.c @@ -219,10 +219,24 @@ void input_release_device(struct input_handle *handle) int input_open_device(struct input_handle *handle) { + struct input_dev *dev = handle->dev; + int err; + + err = down_interruptible(&dev->sem); + if (err) + return err; + handle->open++; - if (handle->dev->open) - return handle->dev->open(handle->dev); - return 0; + + if (!dev->users++ && dev->open) + err = dev->open(dev); + + if (err) + handle->open--; + + up(&dev->sem); + + return err; } int input_flush_device(struct input_handle* handle, struct file* file) @@ -235,10 +249,17 @@ int input_flush_device(struct input_handle* handle, struct file* file) void input_close_device(struct input_handle *handle) { + struct input_dev *dev = handle->dev; + input_release_device(handle); - if (handle->dev->close) - handle->dev->close(handle->dev); + + down(&dev->sem); + + if (!--dev->users && dev->close) + dev->close(dev); handle->open--; + + up(&dev->sem); } static void input_link_handle(struct input_handle *handle) @@ -415,6 +436,8 @@ void input_register_device(struct input_dev *dev) set_bit(EV_SYN, dev->evbit); + init_MUTEX(&dev->sem); + /* * If delay and period are pre-set by the driver, then autorepeating * is handled by the driver itself and we don't do it in input.c. diff --git a/trunk/include/linux/input.h b/trunk/include/linux/input.h index 72731d7d189e..43e8ecec602b 100644 --- a/trunk/include/linux/input.h +++ b/trunk/include/linux/input.h @@ -859,6 +859,10 @@ struct input_dev { int (*erase_effect)(struct input_dev *dev, int effect_id); struct input_handle *grab; + + struct semaphore sem; /* serializes open and close operations */ + unsigned int users; + struct device *dev; struct list_head h_list;