[PATCH 4/9] Input: Block suspend while event queue is not empty.

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Add an ioctl, EVIOCSSUSPENDBLOCK, to enable a suspend_blocker that will blocksuspend while the event queue is not empty. This allows userspace code toprocess input events while the device appears to be asleep.
Signed-off-by: Arve Hjønnevåg <arve@xxxxxxxxxxx>--- drivers/input/evdev.c |   22 ++++++++++++++++++++++ include/linux/input.h |    3 +++ 2 files changed, 25 insertions(+), 0 deletions(-)
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.cindex 7a7a026..0bb670f 100644--- a/drivers/input/evdev.c+++ b/drivers/input/evdev.c@@ -19,6 +19,7 @@ #include <linux/input.h> #include <linux/major.h> #include <linux/device.h>+#include <linux/suspend_blocker.h> #include "input-compat.h"  struct evdev {@@ -43,6 +44,8 @@ struct evdev_client { 	struct fasync_struct *fasync; 	struct evdev *evdev; 	struct list_head node;+	struct suspend_blocker suspend_blocker;+	bool use_suspend_blocker; };  static struct evdev *evdev_table[EVDEV_MINORS];@@ -55,6 +58,8 @@ static void evdev_pass_event(struct evdev_client *client, 	 * Interrupts are disabled, just acquire the lock 	 */ 	spin_lock(&client->buffer_lock);+	if (client->use_suspend_blocker)+		suspend_block(&client->suspend_blocker); 	client->buffer[client->head++] = *event; 	client->head &= EVDEV_BUFFER_SIZE - 1; 	spin_unlock(&client->buffer_lock);@@ -233,6 +238,8 @@ static int evdev_release(struct inode *inode, struct file *file) 	mutex_unlock(&evdev->mutex);  	evdev_detach_client(evdev, client);+	if (client->use_suspend_blocker)+		suspend_blocker_destroy(&client->suspend_blocker); 	kfree(client);  	evdev_close_device(evdev);@@ -332,6 +339,8 @@ static int evdev_fetch_next_event(struct evdev_client *client, 	if (have_event) { 		*event = client->buffer[client->tail++]; 		client->tail &= EVDEV_BUFFER_SIZE - 1;+		if (client->use_suspend_blocker && client->head == client->tail)+			suspend_unblock(&client->suspend_blocker); 	}  	spin_unlock_irq(&client->buffer_lock);@@ -582,6 +591,19 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, 		else 			return evdev_ungrab(evdev, client); +	case EVIOCGSUSPENDBLOCK:+		return put_user(client->use_suspend_blocker, ip);++	case EVIOCSSUSPENDBLOCK:+		spin_lock_irq(&client->buffer_lock);+		if (!client->use_suspend_blocker && p)+			suspend_blocker_init(&client->suspend_blocker, "evdev");+		else if (client->use_suspend_blocker && !p)+			suspend_blocker_destroy(&client->suspend_blocker);+		client->use_suspend_blocker = !!p;+		spin_unlock_irq(&client->buffer_lock);+		return 0;+ 	default:  		if (_IOC_TYPE(cmd) != 'E')diff --git a/include/linux/input.h b/include/linux/input.hindex 6b28048..e091ea8 100644--- a/include/linux/input.h+++ b/include/linux/input.h@@ -81,6 +81,9 @@ struct input_absinfo {  #define EVIOCGRAB		_IOW('E', 0x90, int)			/* Grab/Release device */ +#define EVIOCGSUSPENDBLOCK	_IOR('E', 0x91, int)			/* get suspend block enable */+#define EVIOCSSUSPENDBLOCK	_IOW('E', 0x91, int)			/* set suspend block enable */+ /*  * Event types  */-- 1.6.1
_______________________________________________linux-pm mailing listlinux-pm@xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx://lists.linux-foundation.org/mailman/listinfo/linux-pm


[Index of Archives]     [Linux ACPI]     [Netdev]     [Ethernet Bridging]     [Linux Wireless]     [CPU Freq]     [Kernel Newbies]     [Fedora Kernel]     [Security]     [Linux for Hams]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux Admin]     [Samba]

  Powered by Linux