diff options
author | SeokYeon Hwang <syeon.hwang@samsung.com> | 2016-06-15 17:35:10 +0900 |
---|---|---|
committer | SeokYeon Hwang <syeon.hwang@samsung.com> | 2016-06-16 14:32:17 +0900 |
commit | 1bff9099294a52cb28ee29298203059ff8b89e5a (patch) | |
tree | 62504390f7411958e28d7e43bf43f7bb7c9b4a29 | |
parent | 46ae71fb93c2993a6243b8e9b8b9e700e6e6828c (diff) | |
download | emulator-kernel-1bff9099294a52cb28ee29298203059ff8b89e5a.tar.gz emulator-kernel-1bff9099294a52cb28ee29298203059ff8b89e5a.tar.bz2 emulator-kernel-1bff9099294a52cb28ee29298203059ff8b89e5a.zip |
input: rewrite virtio touchscreen / keyboard device
Simplified input processing logics.
Used proper virtio APIs.
Change-Id: I24a8564842fbb0d3833c4c2bf21e658c85c00cb0
Signed-off-by: SeokYeon Hwang <syeon.hwang@samsung.com>
-rw-r--r-- | drivers/maru/maru_virtio_keyboard.c | 140 | ||||
-rw-r--r-- | drivers/maru/maru_virtio_touchscreen.c | 39 |
2 files changed, 66 insertions, 113 deletions
diff --git a/drivers/maru/maru_virtio_keyboard.c b/drivers/maru/maru_virtio_keyboard.c index f318ef153a84..a358493b128f 100644 --- a/drivers/maru/maru_virtio_keyboard.c +++ b/drivers/maru/maru_virtio_keyboard.c @@ -4,9 +4,8 @@ * Copyright (c) 2011 Samsung Electronics Co., Ltd. All rights reserved. * * Contact: - * Kitae Kim <kitae.kim@samsung.com> + * GiWoong Kim <giwoong.kim@samsung.com> * SeokYeon Hwang <syeon.hwang@samsung.com> - * YeongKyoon Lee <yeongkyoon.lee@samsung.com> * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -39,16 +38,20 @@ #include <linux/virtio_ids.h> #include <linux/virtio_config.h> + MODULE_LICENSE("GPL2"); -MODULE_AUTHOR("Kitae Kim <kt920.kim@samsung.com>"); -MODULE_DESCRIPTION("Emulator Virtio Keyboard Driver"); +MODULE_AUTHOR("SeokYeon Hwangm <syeon.hwang@samsung.com>"); +MODULE_DESCRIPTION("Emulator virtio keyboard driver"); + #define DRIVER_NAME "virtio-keyboard" + #define VKBD_LOG(log_level, fmt, ...) \ printk(log_level "%s: " fmt, DRIVER_NAME, ##__VA_ARGS__) -#define KBD_BUF_SIZE 100 -static int vqidx = 0; +#define MAX_BUF_COUNT 100 + +//#define DEBUG struct EmulKbdEvent { @@ -62,14 +65,12 @@ struct virtio_keyboard struct virtqueue *vq; struct input_dev *idev; - struct EmulKbdEvent kbdevt[KBD_BUF_SIZE]; - struct scatterlist sg[KBD_BUF_SIZE]; + struct scatterlist sg[1]; + struct EmulKbdEvent evtbuf[MAX_BUF_COUNT]; - struct mutex event_mutex; + spinlock_t lock; }; -struct virtio_keyboard *vkbd; - static struct virtio_device_id id_table[] = { { VIRTIO_ID_KEYBOARD, VIRTIO_DEV_ANY_ID }, { 0 }, @@ -77,42 +78,36 @@ static struct virtio_device_id id_table[] = { static void vq_keyboard_handle(struct virtqueue *vq) { - int err = 0, len = 0; - void *data; - struct EmulKbdEvent kbdevent; - - VKBD_LOG(KERN_DEBUG, "virtqueue callback.\n"); - data = virtqueue_get_buf(vq, &len); - if (!data) { - VKBD_LOG(KERN_ERR, "there is no available buffer.\n"); - return; - } - - VKBD_LOG(KERN_DEBUG, "vqidx: %d\n", vqidx); - while (1) { - memcpy(&kbdevent, &vkbd->kbdevt[vqidx], sizeof(kbdevent)); -#if 1 - if (kbdevent.code == 0) { - break; - } + unsigned int len; /* not used */ + struct virtio_keyboard *vkbd = vq->vdev->priv; + struct EmulKbdEvent *event; + + unsigned long flags; + int err; + + spin_lock_irqsave(&vkbd->lock, flags); + while ((event = virtqueue_get_buf(vkbd->vq, &len)) != NULL) { + spin_unlock_irqrestore(&vkbd->lock, flags); +#ifdef DEBUG + printk(KERN_ERR "keyboard code = %d, value = %d\n", event->code, + event->value); #endif - /* how to get keycode and value. */ - input_event(vkbd->idev, EV_KEY, kbdevent.code, kbdevent.value); + input_event(vkbd->idev, EV_KEY, event->code, event->value); input_sync(vkbd->idev); - printk(KERN_ERR "input_event code = %d, value = %d\n", kbdevent.code, kbdevent.value); - memset(&vkbd->kbdevt[vqidx], 0x00, sizeof(kbdevent)); - vqidx++; - if (vqidx == KBD_BUF_SIZE) { - vqidx = 0; + + // add new buffer + spin_lock_irqsave(&vkbd->lock, flags); + sg_init_one(vkbd->sg, event, sizeof(*event)); + err = virtqueue_add_inbuf(vkbd->vq, vkbd->sg, + 1, event, GFP_ATOMIC); + + if (err < 0) { + printk(KERN_ERR "failed to add buffer!\n"); } } - err = virtqueue_add_inbuf(vq, vkbd->sg, KBD_BUF_SIZE, (void *)vkbd->kbdevt, GFP_ATOMIC); - if (err < 0) { - VKBD_LOG(KERN_ERR, "failed to add buffer to virtqueue.\n"); - return; - } virtqueue_kick(vkbd->vq); + spin_unlock_irqrestore(&vkbd->lock, flags); } static int input_keyboard_open(struct input_dev *dev) @@ -126,42 +121,22 @@ static void input_keyboard_close(struct input_dev *dev) VKBD_LOG(KERN_DEBUG, "input_keyboard_close\n"); } -#if 0 -static int virtio_keyboard_open(struct inode *inode, struct file *file) -{ - VKBD_LOG(KERN_DEBUG, "opened.\n"); - return 0; -} - -static int virtio_keyboard_release(struct inode *inode, struct file *file) -{ - VKBD_LOG(KERN_DEBUG, "closed\n"); - return 0; -} - -struct file_operations virtio_keyboard_fops = { - .owner = THIS_MODULE, - .open = virtio_keyboard_open, - .release = virtio_keyboard_release, -}; -#endif - static int virtio_keyboard_probe(struct virtio_device *vdev) { int ret = 0; int index = 0; + int err = 0; + unsigned long flags; + struct virtio_keyboard *vkbd; VKBD_LOG(KERN_INFO, "driver is probed\n"); - vqidx = 0; - vdev->priv = vkbd = kmalloc(sizeof(struct virtio_keyboard), GFP_KERNEL); + vdev->priv = vkbd = kzalloc(sizeof(struct virtio_keyboard), GFP_KERNEL); if (!vkbd) { return -ENOMEM; } - memset(&vkbd->kbdevt, 0x00, sizeof(vkbd->kbdevt)); vkbd->vdev = vdev; - mutex_init(&vkbd->event_mutex); vkbd->vq = virtio_find_single_vq(vkbd->vdev, vq_keyboard_handle, "virtio-keyboard-vq"); if (IS_ERR(vkbd->vq)) { @@ -171,20 +146,6 @@ static int virtio_keyboard_probe(struct virtio_device *vdev) return ret; } - for (; index < KBD_BUF_SIZE; index++) { - sg_set_buf(&vkbd->sg[index], - &vkbd->kbdevt[index], - sizeof(struct EmulKbdEvent)); - } - - ret = virtqueue_add_inbuf(vkbd->vq, vkbd->sg, KBD_BUF_SIZE, (void *)vkbd->kbdevt, GFP_ATOMIC); - if (ret < 0) { - VKBD_LOG(KERN_ERR, "failed to add buffer to virtqueue.\n"); - kfree(vkbd); - vdev->priv = NULL; - return ret; - } - /* register for input device */ vkbd->idev = input_allocate_device(); if (!vkbd->idev) { @@ -229,11 +190,22 @@ static int virtio_keyboard_probe(struct virtio_device *vdev) return ret; } - for (; index < KBD_BUF_SIZE; index++) { - sg_set_buf(&vkbd->sg[index], - &vkbd->kbdevt[index], - sizeof(struct EmulKbdEvent)); + spin_lock_irqsave(&vkbd->lock, flags); + for (index = 0; index < MAX_BUF_COUNT; index++) { + sg_init_one(vkbd->sg, &vkbd->evtbuf[index], sizeof(&vkbd->evtbuf[index])); + + err = virtqueue_add_inbuf(vkbd->vq, vkbd->sg, + 1, &vkbd->evtbuf[index], GFP_ATOMIC); + + if (err < 0) { + printk(KERN_ERR "failed to add buffer\n"); + + kfree(vkbd); + vdev->priv = NULL; + return err; + } } + spin_unlock_irqrestore(&vkbd->lock, flags); virtqueue_kick(vkbd->vq); @@ -242,6 +214,8 @@ static int virtio_keyboard_probe(struct virtio_device *vdev) static void virtio_keyboard_remove(struct virtio_device *vdev) { + struct virtio_keyboard *vkbd = vdev->priv; + VKBD_LOG(KERN_INFO, "driver is removed.\n"); if (!vkbd) { VKBD_LOG(KERN_ERR, "vkbd is NULL.\n"); diff --git a/drivers/maru/maru_virtio_touchscreen.c b/drivers/maru/maru_virtio_touchscreen.c index ef77bccf111f..5aa04f87e551 100644 --- a/drivers/maru/maru_virtio_touchscreen.c +++ b/drivers/maru/maru_virtio_touchscreen.c @@ -40,9 +40,10 @@ #include <linux/virtio_config.h> #include <linux/kthread.h> + MODULE_LICENSE("GPL2"); -MODULE_AUTHOR("GiWoong Kim <giwoong.kim@samsung.com>"); -MODULE_DESCRIPTION("Emulator Virtio Touchscreen driver"); +MODULE_AUTHOR("SeokYeon Hwangm <syeon.hwang@samsung.com>"); +MODULE_DESCRIPTION("Emulator virtio touchscreen driver"); #define DEVICE_NAME "virtio-touchscreen" @@ -52,7 +53,7 @@ MODULE_DESCRIPTION("Emulator Virtio Touchscreen driver"); #define MAX_BUF_COUNT MAX_TRKID -//#define DEBUG_TS +//#define DEBUG /* This structure must match the qemu definitions */ struct touch_event @@ -92,18 +93,13 @@ static void vq_touchscreen_callback(struct virtqueue *vq) unsigned long flags; int err; -#ifdef DEBUG_TS - printk(KERN_INFO "vq touchscreen callback\n"); -#endif - spin_lock_irqsave(&vt->lock, flags); while ((event = virtqueue_get_buf(vt->vq, &len)) != NULL) { spin_unlock_irqrestore(&vt->lock, flags); -#ifdef DEBUG_TS - printk(KERN_INFO "touch x=%d, y=%d, z=%d, state=%d, len=%d\n", +#ifdef DEBUG + printk(KERN_INFO "touchscreen x=%d, y=%d, z=%d, state=%d, len=%d\n", event->x, event->y, event->z, event->state, len); #endif - finger_id = event->z; if (finger_id < MAX_TRKID) { @@ -137,23 +133,12 @@ static void vq_touchscreen_callback(struct virtqueue *vq) if (err < 0) { printk(KERN_ERR "failed to add buffer!\n"); } - }; + } + virtqueue_kick(vt->vq); spin_unlock_irqrestore(&vt->lock, flags); } -static int virtio_touchscreen_open(struct inode *inode, struct file *file) -{ - printk(KERN_INFO "virtio touchscreen device is opened\n"); - return 0; -} - -static int virtio_touchscreen_release(struct inode *inode, struct file *file) -{ - printk(KERN_INFO "virtio touchscreen device is closed\n"); - return 0; -} - static int input_touchscreen_open(struct input_dev *dev) { printk(KERN_INFO "input touchscreen device is opened\n"); @@ -165,13 +150,8 @@ static void input_touchscreen_close(struct input_dev *dev) printk(KERN_INFO "input touchscreen device is closed\n"); } -struct file_operations virtio_touchscreen_fops = { - .owner = THIS_MODULE, - .open = virtio_touchscreen_open, - .release = virtio_touchscreen_release, -}; - extern char *saved_command_line; + #define VM_RESOLUTION_KEY "vm_resolution=" static int virtio_touchscreen_probe(struct virtio_device *vdev) @@ -309,7 +289,6 @@ static int virtio_touchscreen_probe(struct virtio_device *vdev) spin_unlock_irqrestore(&vt->lock, flags); virtqueue_kick(vt->vq); - index = 0; return 0; } |