Commit 0fbf87ca authored by Dmitry Torokhov's avatar Dmitry Torokhov

Input: add semaphore and user count to input_dev structure;

       serialize open and close calls and ensure that device's
       open and close methods are only called when first user
       opens it or last user closes it.
Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
parent 58a00776
......@@ -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.
......
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment