diff options
author | JP Abgrall <jpa@google.com> | 2012-02-06 13:07:39 -0800 |
---|---|---|
committer | JP Abgrall <jpa@google.com> | 2012-02-06 13:07:39 -0800 |
commit | 66b1fe9916260621f3decf5b61142f4010e6cd12 (patch) | |
tree | f5ca3444102f737dbdd72d97dc1b94bf62338633 /drivers/input | |
parent | 47771afc77173e4d87f67cd11c792b92e8578e72 (diff) | |
parent | 1f8c5cecfe44994cd617ba2803f41fb56d53e91c (diff) | |
download | kernel_samsung_crespo-66b1fe9916260621f3decf5b61142f4010e6cd12.zip kernel_samsung_crespo-66b1fe9916260621f3decf5b61142f4010e6cd12.tar.gz kernel_samsung_crespo-66b1fe9916260621f3decf5b61142f4010e6cd12.tar.bz2 |
Merge remote-tracking branch 'common/android-3.0' into android-samsung-30-wip-mergedown
* common/android-3.0:
Input: evdev - fix variable initialisation
Input: evdev - Add ioctl to block suspend while event queue is not empty.
Input: evdev - Don't hold wakelock when no data is available to user-space
net: wireless: bcmdhd: Increase pm_notify callback priority
net: wireless: bcmdhd: Fix crash on dhdsdio_probe_attach() failure
net: wireless: bcmdhd: Daemonize wl_event_handler
net: wireless: bcmdhd: Update to Version 5.90.195.23
net: wireless: bcmdhd: Update to Version 5.90.195.22
net: wireless: bcmdhd: Update to Version 5.90.195.19
net: wireless: bcmdhd: Update to Version 5.90.195.15
net: wireless: bcmdhd: Add WIPHY_FLAG_SUPPORTS_FW_ROAM flag
net: wireless: bcmdhd: Fake PNO event to wake up the wpa_supplicant
usb: gadget: android: Honor CONFIG_USB_GADGET_VBUS_DRAW
usb: gadget: Fix usb string id allocation
nl80211/cfg80211: Make addition of new sinfo fields safer
cfg80211/nl80211: Send AssocReq IEs to user space in AP mode
misc: remove android pmem driver, it's obsolete.
Revert "proc: enable writing to /proc/pid/mem"
ram_console: set CON_ANYTIME console flag
Conflicts:
drivers/misc/Kconfig
Change-Id: I7d64300b228a0fc05e700f283a02f830bcadd371
Diffstat (limited to 'drivers/input')
-rw-r--r-- | drivers/input/evdev.c | 54 |
1 files changed, 48 insertions, 6 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index 5c5f9db..6288d7d 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c @@ -45,6 +45,7 @@ struct evdev_client { unsigned int packet_head; /* [future] position of the first element of next packet */ spinlock_t buffer_lock; /* protects access to buffer, head and tail */ struct wake_lock wake_lock; + bool use_wake_lock; char name[28]; struct fasync_struct *fasync; struct evdev *evdev; @@ -62,7 +63,6 @@ static void evdev_pass_event(struct evdev_client *client, /* Interrupts are disabled, just acquire the lock. */ spin_lock(&client->buffer_lock); - wake_lock_timeout(&client->wake_lock, 5 * HZ); client->buffer[client->head++] = *event; client->head &= client->bufsize - 1; @@ -79,10 +79,14 @@ static void evdev_pass_event(struct evdev_client *client, client->buffer[client->tail].value = 0; client->packet_head = client->tail; + if (client->use_wake_lock) + wake_unlock(&client->wake_lock); } if (event->type == EV_SYN && event->code == SYN_REPORT) { client->packet_head = client->head; + if (client->use_wake_lock) + wake_lock(&client->wake_lock); kill_fasync(&client->fasync, SIGIO, POLL_IN); } @@ -262,7 +266,8 @@ static int evdev_release(struct inode *inode, struct file *file) mutex_unlock(&evdev->mutex); evdev_detach_client(evdev, client); - wake_lock_destroy(&client->wake_lock); + if (client->use_wake_lock) + wake_lock_destroy(&client->wake_lock); kfree(client); evdev_close_device(evdev); @@ -316,7 +321,6 @@ static int evdev_open(struct inode *inode, struct file *file) spin_lock_init(&client->buffer_lock); 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); client->evdev = evdev; evdev_attach_client(evdev, client); @@ -331,7 +335,6 @@ static int evdev_open(struct inode *inode, struct file *file) err_free_client: evdev_detach_client(evdev, client); - wake_lock_destroy(&client->wake_lock); kfree(client); err_put_evdev: put_device(&evdev->dev); @@ -385,7 +388,8 @@ static int evdev_fetch_next_event(struct evdev_client *client, if (have_event) { *event = client->buffer[client->tail++]; client->tail &= client->bufsize - 1; - if (client->head == client->tail) + if (client->use_wake_lock && + client->packet_head == client->tail) wake_unlock(&client->wake_lock); } @@ -400,7 +404,7 @@ static ssize_t evdev_read(struct file *file, char __user *buffer, struct evdev_client *client = file->private_data; struct evdev *evdev = client->evdev; struct input_event event; - int retval; + int retval = 0; if (count < input_event_size()) return -EINVAL; @@ -635,6 +639,35 @@ static int evdev_handle_set_keycode_v2(struct input_dev *dev, void __user *p) return input_set_keycode(dev, &ke); } +static int evdev_enable_suspend_block(struct evdev *evdev, + struct evdev_client *client) +{ + if (client->use_wake_lock) + return 0; + + spin_lock_irq(&client->buffer_lock); + wake_lock_init(&client->wake_lock, WAKE_LOCK_SUSPEND, client->name); + client->use_wake_lock = true; + if (client->packet_head != client->tail) + wake_lock(&client->wake_lock); + spin_unlock_irq(&client->buffer_lock); + return 0; +} + +static int evdev_disable_suspend_block(struct evdev *evdev, + struct evdev_client *client) +{ + if (!client->use_wake_lock) + return 0; + + spin_lock_irq(&client->buffer_lock); + client->use_wake_lock = false; + wake_lock_destroy(&client->wake_lock); + spin_unlock_irq(&client->buffer_lock); + + return 0; +} + static long evdev_do_ioctl(struct file *file, unsigned int cmd, void __user *p, int compat_mode) { @@ -708,6 +741,15 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, case EVIOCSKEYCODE_V2: return evdev_handle_set_keycode_v2(dev, p); + + case EVIOCGSUSPENDBLOCK: + return put_user(client->use_wake_lock, ip); + + case EVIOCSSUSPENDBLOCK: + if (p) + return evdev_enable_suspend_block(evdev, client); + else + return evdev_disable_suspend_block(evdev, client); } size = _IOC_SIZE(cmd); |