aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hid
diff options
context:
space:
mode:
authorDavid Herrmann <dh.herrmann@googlemail.com>2012-06-10 15:16:15 +0200
committerColin Cross <ccross@android.com>2012-08-16 12:44:27 -0700
commit191b03260fc0241e355e5cb200d5a9497e67e67c (patch)
tree89feba34ca165fa88cb77d7f8602d775b2e1bc38 /drivers/hid
parentef5006bca12286b1b92d0da4ab0d65973dc1f74d (diff)
downloadkernel_samsung_tuna-191b03260fc0241e355e5cb200d5a9497e67e67c.zip
kernel_samsung_tuna-191b03260fc0241e355e5cb200d5a9497e67e67c.tar.gz
kernel_samsung_tuna-191b03260fc0241e355e5cb200d5a9497e67e67c.tar.bz2
HID: uhid: allow poll()'ing on uhid devices
As long as the internal buffer is not empty, we return POLLIN to user-space. uhid->head and uhid->tail are no atomics so the comparison may return inexact results. However, this doesn't matter here as user-space would need to poll() in two threads simultaneously to trigger this. And in this case it doesn't matter if a cached result is returned or the exact new result as user-space does not know which thread returns first from poll() and the following read(). So it is safe to compare the values without locking. Signed-off-by: David Herrmann <dh.herrmann@googlemail.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
Diffstat (limited to 'drivers/hid')
-rw-r--r--drivers/hid/uhid.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/drivers/hid/uhid.c b/drivers/hid/uhid.c
index 05ef4b0..b1a477f 100644
--- a/drivers/hid/uhid.c
+++ b/drivers/hid/uhid.c
@@ -117,6 +117,13 @@ static ssize_t uhid_char_write(struct file *file, const char __user *buffer,
static unsigned int uhid_char_poll(struct file *file, poll_table *wait)
{
+ struct uhid_device *uhid = file->private_data;
+
+ poll_wait(file, &uhid->waitq, wait);
+
+ if (uhid->head != uhid->tail)
+ return POLLIN | POLLRDNORM;
+
return 0;
}