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.c29
1 files changed, 29 insertions, 0 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
index 1148140d08a1..5598ecb48c5b 100644
--- a/drivers/input/evdev.c
+++ b/drivers/input/evdev.c
@@ -19,6 +19,9 @@
#include <linux/input.h>
#include <linux/major.h>
#include <linux/device.h>
+#ifdef CONFIG_WAKELOCK
+#include <linux/wakelock.h>
+#endif
#include "input-compat.h"
struct evdev {
@@ -42,6 +45,10 @@ struct evdev_client {
struct fasync_struct *fasync;
struct evdev *evdev;
struct list_head node;
+#ifdef CONFIG_WAKELOCK
+ struct wake_lock wake_lock;
+ char name[28];
+#endif
};
static struct evdev *evdev_table[EVDEV_MINORS];
@@ -54,6 +61,9 @@ static void evdev_pass_event(struct evdev_client *client,
* Interrupts are disabled, just acquire the lock
*/
spin_lock(&client->buffer_lock);
+#ifdef CONFIG_WAKELOCK
+ wake_lock_timeout(&client->wake_lock, 5 * HZ);
+#endif
client->buffer[client->head++] = *event;
client->head &= EVDEV_BUFFER_SIZE - 1;
spin_unlock(&client->buffer_lock);
@@ -70,8 +80,15 @@ static void evdev_event(struct input_handle *handle,
struct evdev *evdev = handle->private;
struct evdev_client *client;
struct input_event event;
+#ifdef CONFIG_WAKELOCK
+ struct timespec ts;
+ ktime_get_ts(&ts);
+ event.time.tv_sec = ts.tv_sec;
+ event.time.tv_usec = ts.tv_nsec / NSEC_PER_USEC;
+#else
do_gettimeofday(&event.time);
+#endif
event.type = type;
event.code = code;
event.value = value;
@@ -232,6 +249,9 @@ static int evdev_release(struct inode *inode, struct file *file)
mutex_unlock(&evdev->mutex);
evdev_detach_client(evdev, client);
+#ifdef CONFIG_WAKELOCK
+ wake_lock_destroy(&client->wake_lock);
+#endif
kfree(client);
evdev_close_device(evdev);
@@ -268,6 +288,11 @@ static int evdev_open(struct inode *inode, struct file *file)
}
spin_lock_init(&client->buffer_lock);
+#ifdef CONFIG_WAKELOCK
+ snprintf(client->name, sizeof(client->name), "%s-%d", dev_name(&evdev->dev),
+ task_tgid_vnr(current));
+ wake_lock_init(&client->wake_lock, WAKE_LOCK_SUSPEND, client->name);
+#endif
client->evdev = evdev;
evdev_attach_client(evdev, client);
@@ -331,6 +356,10 @@ static int evdev_fetch_next_event(struct evdev_client *client,
if (have_event) {
*event = client->buffer[client->tail++];
client->tail &= EVDEV_BUFFER_SIZE - 1;
+#ifdef CONFIG_WAKELOCK
+ if (client->head == client->tail)
+ wake_unlock(&client->wake_lock);
+#endif
}
spin_unlock_irq(&client->buffer_lock);