lkml.org 
[lkml]   [2010]   [Apr]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 7/8] Input: Block suspend while event queue is not empty.
    Date
    Add an ioctl, EVIOCSSUSPENDBLOCK, to enable a suspend_blocker that will block
    suspend while the event queue is not empty. This allows userspace code to
    process input events while the device appears to be asleep.

    Signed-off-by: Arve Hjønnevåg <arve@android.com>
    ---
    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.c
    index 2ee6c7a..66e0d16 100644
    --- a/drivers/input/evdev.c
    +++ b/drivers/input/evdev.c
    @@ -20,6 +20,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);
    @@ -234,6 +239,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);
    @@ -335,6 +342,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);
    @@ -585,6 +594,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.h
    index 7ed2251..b2d93b4 100644
    --- a/include/linux/input.h
    +++ b/include/linux/input.h
    @@ -82,6 +82,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.5.1
    --
    To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
    the body of a message to majordomo@vger.kernel.org
    More majordomo info at http://vger.kernel.org/majordomo-info.html
    Please read the FAQ at http://www.tux.org/lkml/

    \
     
     \ /
      Last update: 2010-04-28 06:37    [W:4.123 / U:0.088 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site