Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+28 −5
Original line number Diff line number Diff line
@@ -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.
+4 −0
Original line number Diff line number Diff line
@@ -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;