summaryrefslogtreecommitdiff
path: root/drivers/input/evdev.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/evdev.c')
-rw-r--r--drivers/input/evdev.c19
1 files changed, 9 insertions, 10 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index e494295d1c7b..95f90699d2b1 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -28,7 +28,6 @@
struct evdev {
int open;
struct input_handle handle;
- wait_queue_head_t wait;
struct evdev_client __rcu *grab;
struct list_head client_list;
spinlock_t client_lock; /* protects client_list */
@@ -43,6 +42,7 @@ struct evdev_client {
unsigned int tail;
unsigned int packet_head; /* [future] position of the first element of next packet */
spinlock_t buffer_lock; /* protects access to buffer, head and tail */
+ wait_queue_head_t wait;
struct fasync_struct *fasync;
struct evdev *evdev;
struct list_head node;
@@ -245,7 +245,6 @@ static void evdev_pass_values(struct evdev_client *client,
const struct input_value *vals, unsigned int count,
ktime_t *ev_time)
{
- struct evdev *evdev = client->evdev;
const struct input_value *v;
struct input_event event;
struct timespec64 ts;
@@ -282,7 +281,7 @@ static void evdev_pass_values(struct evdev_client *client,
spin_unlock(&client->buffer_lock);
if (wakeup)
- wake_up_interruptible_poll(&evdev->wait,
+ wake_up_interruptible_poll(&client->wait,
EPOLLIN | EPOLLOUT | EPOLLRDNORM | EPOLLWRNORM);
}
@@ -426,11 +425,11 @@ static void evdev_hangup(struct evdev *evdev)
struct evdev_client *client;
spin_lock(&evdev->client_lock);
- list_for_each_entry(client, &evdev->client_list, node)
+ list_for_each_entry(client, &evdev->client_list, node) {
kill_fasync(&client->fasync, SIGIO, POLL_HUP);
+ wake_up_interruptible_poll(&client->wait, EPOLLHUP | EPOLLERR);
+ }
spin_unlock(&evdev->client_lock);
-
- wake_up_interruptible_poll(&evdev->wait, EPOLLHUP | EPOLLERR);
}
static int evdev_release(struct inode *inode, struct file *file)
@@ -479,6 +478,7 @@ static int evdev_open(struct inode *inode, struct file *file)
if (!client)
return -ENOMEM;
+ init_waitqueue_head(&client->wait);
client->bufsize = bufsize;
spin_lock_init(&client->buffer_lock);
client->evdev = evdev;
@@ -595,7 +595,7 @@ static ssize_t evdev_read(struct file *file, char __user *buffer,
break;
if (!(file->f_flags & O_NONBLOCK)) {
- error = wait_event_interruptible(evdev->wait,
+ error = wait_event_interruptible(client->wait,
client->packet_head != client->tail ||
!evdev->exist || client->revoked);
if (error)
@@ -613,7 +613,7 @@ static __poll_t evdev_poll(struct file *file, poll_table *wait)
struct evdev *evdev = client->evdev;
__poll_t mask;
- poll_wait(file, &evdev->wait, wait);
+ poll_wait(file, &client->wait, wait);
if (evdev->exist && !client->revoked)
mask = EPOLLOUT | EPOLLWRNORM;
@@ -946,7 +946,7 @@ static int evdev_revoke(struct evdev *evdev, struct evdev_client *client,
client->revoked = true;
evdev_ungrab(evdev, client);
input_flush_device(&evdev->handle, file);
- wake_up_interruptible_poll(&evdev->wait, EPOLLHUP | EPOLLERR);
+ wake_up_interruptible_poll(&client->wait, EPOLLHUP | EPOLLERR);
return 0;
}
@@ -1358,7 +1358,6 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev,
INIT_LIST_HEAD(&evdev->client_list);
spin_lock_init(&evdev->client_lock);
mutex_init(&evdev->mutex);
- init_waitqueue_head(&evdev->wait);
evdev->exist = true;
dev_no = minor;