public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 3/9] New set of input patches - 04-h3600-fixes.patch
       [not found]   ` <200405110104.20283.dtor_core@ameritech.net>
@ 2004-05-11  6:05     ` Dmitry Torokhov
  2004-05-11  6:05       ` [PATCH 4/9] New set of input patches - 05-twidjoy-fixes.patch Dmitry Torokhov
  0 siblings, 1 reply; 9+ messages in thread
From: Dmitry Torokhov @ 2004-05-11  6:05 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: Andrew Morton, linux-kernel


===================================================================


ChangeSet@1.1587.20.5, 2004-05-10 01:29:33-05:00, dtor_core@ameritech.net
  Input: various fixes for H3600 touchscreen driver 
         - h3600ts_interrupt, npower_button_handler and action_button_handler
           should return irqreturn_t
         - fix missing argument in h3600ts_process_packet call
         - add MODULE_AUTHOR, MODULE_DESCRIPTION and MODULE_LICENSE
         - small formatting changes


 h3600_ts_input.c |   32 +++++++++++++++++++++-----------
 1 files changed, 21 insertions(+), 11 deletions(-)


===================================================================



diff -Nru a/drivers/input/touchscreen/h3600_ts_input.c b/drivers/input/touchscreen/h3600_ts_input.c
--- a/drivers/input/touchscreen/h3600_ts_input.c	Tue May 11 00:55:38 2004
+++ b/drivers/input/touchscreen/h3600_ts_input.c	Tue May 11 00:55:38 2004
@@ -45,6 +45,10 @@
 #include <asm/arch/hardware.h>
 #include <asm/arch/irqs.h>
 
+MODULE_AUTHOR("James Simmons <jsimmons@transvirtual.com>");
+MODULE_DESCRIPTION("H3600 touchscreen driver");
+MODULE_LICENSE("GPL");
+
 /*
  * Definitions & global arrays.
  */
@@ -103,7 +107,7 @@
 	char phys[32];
 };
 
-static void action_button_handler(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t action_button_handler(int irq, void *dev_id, struct pt_regs *regs)
 {
         int down = (GPLR & GPIO_BITSY_ACTION_BUTTON) ? 0 : 1;
 	struct input_dev *dev = (struct input_dev *) dev_id;
@@ -111,9 +115,11 @@
 	input_regs(dev, regs);
 	input_report_key(dev, KEY_ENTER, down);
 	input_sync(dev);
+
+	return IRQ_HANDLED;
 }
 
-static void npower_button_handler(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t npower_button_handler(int irq, void *dev_id, struct pt_regs *regs)
 {
         int down = (GPLR & GPIO_BITSY_NPOWER_BUTTON) ? 0 : 1;
 	struct input_dev *dev = (struct input_dev *) dev_id;
@@ -126,6 +132,8 @@
 	input_report_key(dev, KEY_SUSPEND, 1);
 	input_report_key(dev, KEY_SUSPEND, down);
 	input_sync(dev);
+
+	return IRQ_HANDLED;
 }
 
 #ifdef CONFIG_PM
@@ -141,7 +149,7 @@
  * h3600_flite_power: enables or disables power to frontlight, using last bright */
 unsigned int h3600_flite_power(struct input_dev *dev, enum flite_pwr pwr)
 {
-	unsigned char brightness = ((pwr==FLITE_PWR_OFF) ? 0:flite_brightness);
+	unsigned char brightness = (pwr == FLITE_PWR_OFF) ? 0 : flite_brightness;
 	struct h3600_dev *ts = dev->private;
 
 	/* Must be in this order */
@@ -317,8 +325,8 @@
 #define STATE_DATA      2       /* state where we decode data */
 #define STATE_EOF       3       /* state where we decode checksum or EOF */
 
-static void h3600ts_interrupt(struct serio *serio, unsigned char data,
-                              unsigned int flags)
+static irqreturn_t h3600ts_interrupt(struct serio *serio, unsigned char data,
+                                     unsigned int flags, struct pt_regs *regs)
 {
         struct h3600_dev *ts = serio->private;
 
@@ -329,7 +337,7 @@
 		case STATE_SOF:
         		if (data == CHAR_SOF)
                 		state = STATE_ID;
-			return;
+			break;
         	case STATE_ID:
 			ts->event = (data & 0xf0) >> 4;
 			ts->len = (data & 0xf);
@@ -339,7 +347,7 @@
                         	break;
 			}
 			ts->chksum = data;
-                	state=(ts->len > 0 ) ? STATE_DATA : STATE_EOF;
+                	state = (ts->len > 0) ? STATE_DATA : STATE_EOF;
 			break;
 		case STATE_DATA:
 			ts->chksum += data;
@@ -349,13 +357,15 @@
 			break;
 		case STATE_EOF:
                 	state = STATE_SOF;
-                	if (data == CHAR_EOF || data == ts->chksum )
-				h3600ts_process_packet(ts);
+                	if (data == CHAR_EOF || data == ts->chksum)
+				h3600ts_process_packet(ts, regs);
                 	break;
         	default:
                 	printk("Error3\n");
                 	break;
 	}
+
+	return IRQ_HANDLED;
 }
 
 /*
@@ -378,8 +388,8 @@
 	init_input_dev(&ts->dev);
 
 	/* Device specific stuff */
-        set_GPIO_IRQ_edge( GPIO_BITSY_ACTION_BUTTON, GPIO_BOTH_EDGES );
-        set_GPIO_IRQ_edge( GPIO_BITSY_NPOWER_BUTTON, GPIO_RISING_EDGE );
+        set_GPIO_IRQ_edge(GPIO_BITSY_ACTION_BUTTON, GPIO_BOTH_EDGES);
+        set_GPIO_IRQ_edge(GPIO_BITSY_NPOWER_BUTTON, GPIO_RISING_EDGE);
 
         if (request_irq(IRQ_GPIO_BITSY_ACTION_BUTTON, action_button_handler,
 			SA_SHIRQ | SA_INTERRUPT | SA_SAMPLE_RANDOM,

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 4/9] New set of input patches - 05-twidjoy-fixes.patch
  2004-05-11  6:05     ` [PATCH 3/9] New set of input patches - 04-h3600-fixes.patch Dmitry Torokhov
@ 2004-05-11  6:05       ` Dmitry Torokhov
  2004-05-11  6:06         ` [PATCH 5/9] New set of input patches - 07-power-license.patch Dmitry Torokhov
  0 siblings, 1 reply; 9+ messages in thread
From: Dmitry Torokhov @ 2004-05-11  6:05 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: Andrew Morton, linux-kernel


===================================================================


ChangeSet@1.1587.20.6, 2004-05-10 01:30:08-05:00, dtor_core@ameritech.net
  Input: twidjoy module
         - twidjoy_interrupt should return irqreturn_t
         - add MODULE_DESCRIPTION and MODULE_LICENSE


 twidjoy.c |    9 ++++++---
 1 files changed, 6 insertions(+), 3 deletions(-)


===================================================================



diff -Nru a/drivers/input/joystick/twidjoy.c b/drivers/input/joystick/twidjoy.c
--- a/drivers/input/joystick/twidjoy.c	Tue May 11 00:56:27 2004
+++ b/drivers/input/joystick/twidjoy.c	Tue May 11 00:56:27 2004
@@ -58,6 +58,9 @@
 #include <linux/serio.h>
 #include <linux/init.h>
 
+MODULE_DESCRIPTION("Handykey Twiddler keyboard as a joystick driver");
+MODULE_LICENSE("GPL");
+
 /*
  * Constants.
  */
@@ -142,7 +145,7 @@
  * packet processing routine.
  */
 
-static void twidjoy_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struc pt_regs *regs)
+static irqreturn_t twidjoy_interrupt(struct serio *serio, unsigned char data, unsigned int flags, struct pt_regs *regs)
 {
 	struct twidjoy *twidjoy = serio->private;
 
@@ -153,7 +156,7 @@
 	if ((data & 0x80) == 0)
 		twidjoy->idx = 0;	/* this byte starts a new packet */
 	else if (twidjoy->idx == 0)
-		return;			/* wrong MSB -- ignore this byte */
+		return IRQ_HANDLED;	/* wrong MSB -- ignore this byte */
 
 	if (twidjoy->idx < TWIDJOY_MAX_LENGTH)
 		twidjoy->data[twidjoy->idx++] = data;
@@ -163,7 +166,7 @@
 		twidjoy->idx = 0;
 	}
 
-	return;
+	return IRQ_HANDLED;
 }
 
 /*

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 5/9] New set of input patches - 07-power-license.patch
  2004-05-11  6:05       ` [PATCH 4/9] New set of input patches - 05-twidjoy-fixes.patch Dmitry Torokhov
@ 2004-05-11  6:06         ` Dmitry Torokhov
  2004-05-11  6:09           ` [PATCH 6/9] New set of input patches - 11-synaptics-reconnect.patch Dmitry Torokhov
  0 siblings, 1 reply; 9+ messages in thread
From: Dmitry Torokhov @ 2004-05-11  6:06 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: Andrew Morton, linux-kernel


===================================================================


ChangeSet@1.1587.20.8, 2004-05-10 01:32:39-05:00, dtor_core@ameritech.net
  Input: power - add MODULE_LICENSE


 power.c |    1 +
 1 files changed, 1 insertion(+)


===================================================================



diff -Nru a/drivers/input/power.c b/drivers/input/power.c
--- a/drivers/input/power.c	Tue May 11 00:56:54 2004
+++ b/drivers/input/power.c	Tue May 11 00:56:54 2004
@@ -172,3 +172,4 @@
 
 MODULE_AUTHOR("James Simmons <jsimmons@transvirtual.com>");
 MODULE_DESCRIPTION("Input Power Management driver");
+MODULE_LICENSE("GPL");

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 6/9] New set of input patches - 11-synaptics-reconnect.patch
  2004-05-11  6:06         ` [PATCH 5/9] New set of input patches - 07-power-license.patch Dmitry Torokhov
@ 2004-05-11  6:09           ` Dmitry Torokhov
  2004-05-11  6:10             ` [PATCH 7/9] New set of input patches - 12-i8042-interrupt.patch Dmitry Torokhov
  0 siblings, 1 reply; 9+ messages in thread
From: Dmitry Torokhov @ 2004-05-11  6:09 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: Andrew Morton, linux-kernel


===================================================================


ChangeSet@1.1587.20.12, 2004-05-10 01:37:47-05:00, dtor_core@ameritech.net
  Input: do not call synaptics_init unless we are ready to do full
         mouse setup


 psmouse-base.c |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)


===================================================================



diff -Nru a/drivers/input/mouse/psmouse-base.c b/drivers/input/mouse/psmouse-base.c
--- a/drivers/input/mouse/psmouse-base.c	Tue May 11 00:57:50 2004
+++ b/drivers/input/mouse/psmouse-base.c	Tue May 11 00:57:50 2004
@@ -427,7 +427,7 @@
 		}
 
 		if (max_proto > PSMOUSE_IMEX) {
-			if (synaptics_init(psmouse) == 0)
+			if (!set_properties || synaptics_init(psmouse) == 0)
 				return PSMOUSE_SYNAPTICS;
 /*
  * Some Synaptics touchpads can emulate extended protocols (like IMPS/2).

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 7/9] New set of input patches - 12-i8042-interrupt.patch
  2004-05-11  6:09           ` [PATCH 6/9] New set of input patches - 11-synaptics-reconnect.patch Dmitry Torokhov
@ 2004-05-11  6:10             ` Dmitry Torokhov
  2004-05-11  6:10               ` [PATCH 8/9] New set of input patches - 13-i8042-unload.patch Dmitry Torokhov
  0 siblings, 1 reply; 9+ messages in thread
From: Dmitry Torokhov @ 2004-05-11  6:10 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: Andrew Morton, linux-kernel


===================================================================


ChangeSet@1.1587.20.13, 2004-05-10 01:39:35-05:00, dtor_core@ameritech.net
  Input: split i8042 interrupt handling into an IRQ handler and a tasklet


 i8042.c |  141 +++++++++++++++++++++++++++++++++++++++++-----------------------
 1 files changed, 92 insertions(+), 49 deletions(-)


===================================================================



diff -Nru a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
--- a/drivers/input/serio/i8042.c	Tue May 11 00:58:28 2004
+++ b/drivers/input/serio/i8042.c	Tue May 11 00:58:28 2004
@@ -2,6 +2,7 @@
  *  i8042 keyboard and mouse controller driver for Linux
  *
  *  Copyright (c) 1999-2002 Vojtech Pavlik
+ *  Copyright (c) 2004      Dmitry Torokhov
  */
 
 /*
@@ -74,6 +75,14 @@
 	unsigned char *phys;
 };
 
+#define I8042_QUEUE_LEN		64
+struct {
+	unsigned char str[I8042_QUEUE_LEN];
+	unsigned char data[I8042_QUEUE_LEN];
+	unsigned int read_pos;
+	unsigned int write_pos;
+} i8042_buf;
+
 static struct serio i8042_kbd_port;
 static struct serio i8042_aux_port;
 static unsigned char i8042_initial_ctr;
@@ -82,7 +91,7 @@
 static unsigned char i8042_mux_present;
 static unsigned char i8042_sysdev_initialized;
 static struct pm_dev *i8042_pm_dev;
-struct timer_list i8042_timer;
+static struct timer_list i8042_timer;
 
 /*
  * Shared IRQ's require a device pointer, but this driver doesn't support
@@ -374,77 +383,109 @@
 static char i8042_mux_phys[4][32];
 
 /*
- * i8042_interrupt() is the most important function in this driver -
- * it handles the interrupts from the i8042, and sends incoming bytes
- * to the upper layers.
+ * i8042_handle_data() is the most important function in this driver -
+ * it processes data received by i8042_interrupt and sends it to the
+ * upper layers.
  */
 
-static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static void i8042_handle_data(unsigned long notused)
 {
-	unsigned long flags;
 	unsigned char str, data = 0;
 	unsigned int dfl;
-	int ret;
 
-	mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);
+	/*
+	 * No locking it required on i8042_buf as the tasklet is guaranteed
+	 * to be serialized and if write_pos changes while comparing it with
+	 * read_pos another run will be scheduled by i8042_interrupt.
+	 */
+	while (i8042_buf.read_pos != i8042_buf.write_pos) {
 
-	spin_lock_irqsave(&i8042_lock, flags);
-	str = i8042_read_status();
-	if (str & I8042_STR_OBF)
-		data = i8042_read_data();
-	spin_unlock_irqrestore(&i8042_lock, flags);
+		str = i8042_buf.str[i8042_buf.read_pos];
+		data = i8042_buf.data[i8042_buf.read_pos];
 
-	if (~str & I8042_STR_OBF) {
-		if (irq) dbg("Interrupt %d, without any data", irq);
-		ret = 0;
-		goto out;
+		i8042_buf.read_pos++;
+		i8042_buf.read_pos %= I8042_QUEUE_LEN;
+
+		dfl = ((str & I8042_STR_PARITY)  ? SERIO_PARITY  : 0) |
+	      	      ((str & I8042_STR_TIMEOUT) ? SERIO_TIMEOUT : 0);
+
+		if (i8042_mux_values[0].exists && (str & I8042_STR_AUXDATA)) {
+
+			if (str & I8042_STR_MUXERR) {
+				switch (data) {
+					case 0xfd:
+					case 0xfe: dfl = SERIO_TIMEOUT; break;
+					case 0xff: dfl = SERIO_PARITY; break;
+				}
+				data = 0xfe;
+			} else dfl = 0;
+
+			dbg("%02x <- i8042 (interrupt, aux%d, %d%s%s)",
+				data, (str >> 6), irq,
+				dfl & SERIO_PARITY ? ", bad parity" : "",
+				dfl & SERIO_TIMEOUT ? ", timeout" : "");
+
+			serio_interrupt(i8042_mux_port + ((str >> 6) & 3), data, dfl, NULL);
+		} else {
+
+			dbg("%02x <- i8042 (interrupt, %s, %d%s%s)",
+				data, (str & I8042_STR_AUXDATA) ? "aux" : "kbd", irq,
+				dfl & SERIO_PARITY ? ", bad parity" : "",
+				dfl & SERIO_TIMEOUT ? ", timeout" : "");
+
+			if (i8042_aux_values.exists && (str & I8042_STR_AUXDATA))
+				serio_interrupt(&i8042_aux_port, data, dfl, NULL);
+			else if (i8042_kbd_values.exists)
+				serio_interrupt(&i8042_kbd_port, data, dfl, NULL);
+		}
 	}
+}
+
+DECLARE_TASKLET(i8042_tasklet, i8042_handle_data, 0);
+
+/*
+ * i8042_interrupt() handles the interrupts from i8042 and schedules
+ * i8042_handle_data to process and pass received bytes to the upper
+ * layers.
+ */
 
-	dfl = ((str & I8042_STR_PARITY) ? SERIO_PARITY : 0) |
-	      ((str & I8042_STR_TIMEOUT) ? SERIO_TIMEOUT : 0);
+static irqreturn_t i8042_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned long flags;
+	unsigned char str;
+	unsigned int n_bytes = 0;
 
-	if (i8042_mux_values[0].exists && (str & I8042_STR_AUXDATA)) {
+	mod_timer(&i8042_timer, jiffies + I8042_POLL_PERIOD);
 
-		if (str & I8042_STR_MUXERR) {
-			switch (data) {
-				case 0xfd:
-				case 0xfe: dfl = SERIO_TIMEOUT; break;
-				case 0xff: dfl = SERIO_PARITY; break;
-			}
-			data = 0xfe;
-		} else dfl = 0;
+	spin_lock_irqsave(&i8042_lock, flags);
 
-		dbg("%02x <- i8042 (interrupt, aux%d, %d%s%s)",
-			data, (str >> 6), irq,
-			dfl & SERIO_PARITY ? ", bad parity" : "",
-			dfl & SERIO_TIMEOUT ? ", timeout" : "");
+	while ((str = i8042_read_status()) & I8042_STR_OBF) {
 
-		serio_interrupt(i8042_mux_port + ((str >> 6) & 3), data, dfl, regs);
+		n_bytes++;
 
-		goto irq_ret;
-	}
+		i8042_buf.str[i8042_buf.write_pos] = str;
+		i8042_buf.data[i8042_buf.write_pos] = i8042_read_data();
 
-	dbg("%02x <- i8042 (interrupt, %s, %d%s%s)",
-		data, (str & I8042_STR_AUXDATA) ? "aux" : "kbd", irq,
-		dfl & SERIO_PARITY ? ", bad parity" : "",
-		dfl & SERIO_TIMEOUT ? ", timeout" : "");
+		i8042_buf.write_pos++;
+		i8042_buf.write_pos %= I8042_QUEUE_LEN;
 
-	if (i8042_aux_values.exists && (str & I8042_STR_AUXDATA)) {
-		serio_interrupt(&i8042_aux_port, data, dfl, regs);
-		goto irq_ret;
+		if (unlikely(i8042_buf.write_pos == i8042_buf.read_pos))
+			printk(KERN_WARNING "i8042.c: ring buffer full\n");
 	}
 
-	if (!i8042_kbd_values.exists)
-		goto irq_ret;
+	spin_unlock_irqrestore(&i8042_lock, flags);
 
-	serio_interrupt(&i8042_kbd_port, data, dfl, regs);
+	if (unlikely(n_bytes == 0)) {
+		if (irq) dbg("Interrupt %d, without any data", irq);
+		return IRQ_NONE;
+	}
 
-irq_ret:
-	ret = 1;
-out:
-	return IRQ_RETVAL(ret);
+	tasklet_schedule(&i8042_tasklet);
+
+	return IRQ_HANDLED;
 }
 
+
 /*
  * i8042_enable_mux_mode checks whether the controller has an active
  * multiplexor and puts the chip into Multiplexed (as opposed to
@@ -1019,6 +1060,8 @@
 	for (i = 0; i < 4; i++)
 		if (i8042_mux_values[i].exists)
 			serio_unregister_port(i8042_mux_port + i);
+
+	tasklet_kill(&i8042_tasklet);
 
 	i8042_platform_exit();
 }

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 8/9] New set of input patches - 13-i8042-unload.patch
  2004-05-11  6:10             ` [PATCH 7/9] New set of input patches - 12-i8042-interrupt.patch Dmitry Torokhov
@ 2004-05-11  6:10               ` Dmitry Torokhov
  2004-05-11  6:11                 ` [PATCH 9/9] New set of input patches - 14-mousedev-multiplexing.patch Dmitry Torokhov
  0 siblings, 1 reply; 9+ messages in thread
From: Dmitry Torokhov @ 2004-05-11  6:10 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: Andrew Morton, linux-kernel


===================================================================


ChangeSet@1.1587.20.14, 2004-05-10 01:40:59-05:00, dtor_core@ameritech.net
  Patch from Sau Dan Lee
  Input: i8042 - kill the timer only after removing interrupt handler,
         otherwise there is a chance that interrupt handler will install
         the timer again and it will trigger after module is unloaded.


 i8042.c |    3 +--
 1 files changed, 1 insertion(+), 2 deletions(-)


===================================================================



diff -Nru a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c
--- a/drivers/input/serio/i8042.c	Tue May 11 00:58:55 2004
+++ b/drivers/input/serio/i8042.c	Tue May 11 00:58:55 2004
@@ -1047,8 +1047,6 @@
 		sysdev_class_unregister(&kbc_sysclass);
 	}
 
-	del_timer_sync(&i8042_timer);
-
 	i8042_controller_cleanup();
 
 	if (i8042_kbd_values.exists)
@@ -1061,6 +1059,7 @@
 		if (i8042_mux_values[i].exists)
 			serio_unregister_port(i8042_mux_port + i);
 
+	del_timer_sync(&i8042_timer);
 	tasklet_kill(&i8042_tasklet);
 
 	i8042_platform_exit();

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 9/9] New set of input patches - 14-mousedev-multiplexing.patch
  2004-05-11  6:10               ` [PATCH 8/9] New set of input patches - 13-i8042-unload.patch Dmitry Torokhov
@ 2004-05-11  6:11                 ` Dmitry Torokhov
  0 siblings, 0 replies; 9+ messages in thread
From: Dmitry Torokhov @ 2004-05-11  6:11 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: Andrew Morton, linux-kernel


===================================================================


ChangeSet@1.1587.20.15, 2004-05-10 01:44:03-05:00, dtor_core@ameritech.net
  Input: mousedev - better multiplex absolute and relative devices;
         cleanups


 mousedev.c |  260 ++++++++++++++++++++++++++++++++++---------------------------
 1 files changed, 146 insertions(+), 114 deletions(-)


===================================================================



diff -Nru a/drivers/input/mousedev.c b/drivers/input/mousedev.c
--- a/drivers/input/mousedev.c	Tue May 11 00:59:25 2004
+++ b/drivers/input/mousedev.c	Tue May 11 00:59:25 2004
@@ -2,6 +2,7 @@
  * Input driver to ExplorerPS/2 device driver module.
  *
  * Copyright (c) 1999-2002 Vojtech Pavlik
+ * Copyright (c) 2004      Dmitry Torokhov
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as published by
@@ -47,15 +48,24 @@
 module_param(yres, uint, 0);
 MODULE_PARM_DESC(yres, "Vertical screen resolution");
 
+struct mousedev_motion {
+	int dx, dy, dz;
+};
+
 struct mousedev {
 	int exist;
 	int open;
 	int minor;
-	int misc;
 	char name[16];
 	wait_queue_head_t wait;
 	struct list_head list;
 	struct input_handle handle;
+
+	struct mousedev_motion packet;
+	unsigned long buttons;
+	unsigned int pkt_count;
+	int old_x[4], old_y[4];
+	unsigned int touch;
 };
 
 struct mousedev_list {
@@ -63,13 +73,10 @@
 	struct mousedev *mousedev;
 	struct list_head node;
 	int dx, dy, dz;
-	int old_x[4], old_y[4];
 	unsigned long buttons;
 	signed char ps2[6];
 	unsigned char ready, buffer, bufsiz;
 	unsigned char mode, imexseq, impsseq;
-	unsigned int pkt_count;
-	unsigned char touch;
 };
 
 #define MOUSEDEV_SEQ_LEN	6
@@ -82,135 +89,157 @@
 static struct mousedev *mousedev_table[MOUSEDEV_MINORS];
 static struct mousedev mousedev_mix;
 
-#define fx(i)  (list->old_x[(list->pkt_count - (i)) & 03])
-#define fy(i)  (list->old_y[(list->pkt_count - (i)) & 03])
+#define fx(i)  (mousedev->old_x[(mousedev->pkt_count - (i)) & 03])
+#define fy(i)  (mousedev->old_y[(mousedev->pkt_count - (i)) & 03])
 
-static void mousedev_abs_event(struct input_handle *handle, struct mousedev_list *list, unsigned int code, int value)
+static void mousedev_touchpad_event(struct mousedev *mousedev, unsigned int code, int value)
 {
-	int size;
-	int touchpad;
+	if (mousedev->touch) {
+		switch (code) {
+			case ABS_X:
+				fx(0) = value;
+				if (mousedev->pkt_count >= 2)
+					mousedev->packet.dx = ((fx(0) - fx(1)) / 2 + (fx(1) - fx(2)) / 2) / 8;
+				break;
 
-	/* Ignore joysticks */
-	if (test_bit(BTN_TRIGGER, handle->dev->keybit))
-		return;
+			case ABS_Y:
+				fy(0) = value;
+				if (mousedev->pkt_count >= 2)
+					mousedev->packet.dy = -((fy(0) - fy(1)) / 2 + (fy(1) - fy(2)) / 2) / 8;
+				break;
+		}
+	}
+}
 
-	touchpad = test_bit(BTN_TOOL_FINGER, handle->dev->keybit);
+static void mousedev_abs_event(struct input_dev *dev, struct mousedev *mousedev, unsigned int code, int value)
+{
+	int size;
 
 	switch (code) {
 		case ABS_X:
-			if (touchpad) {
-				if (list->touch) {
-					fx(0) = value;
-					if (list->pkt_count >= 2)
-						list->dx = ((fx(0) - fx(1)) / 2 + (fx(1) - fx(2)) / 2) / 8;
-				}
-			} else {
-				size = handle->dev->absmax[ABS_X] - handle->dev->absmin[ABS_X];
-				if (size == 0) size = xres;
-				list->dx += (value * xres - list->old_x[0]) / size;
-				list->old_x[0] += list->dx * size;
-			}
+			size = dev->absmax[ABS_X] - dev->absmin[ABS_X];
+			if (size == 0) size = xres;
+			mousedev->packet.dx = (value * xres - mousedev->old_x[0]) / size;
+			mousedev->old_x[0] = mousedev->packet.dx * size;
 			break;
+
 		case ABS_Y:
-			if (touchpad) {
-				if (list->touch) {
-					fy(0) = value;
-					if (list->pkt_count >= 2)
-						list->dy = -((fy(0) - fy(1)) / 2 + (fy(1) - fy(2)) / 2) / 8;
-				}
-			} else {
-				size = handle->dev->absmax[ABS_Y] - handle->dev->absmin[ABS_Y];
-				if (size == 0) size = yres;
-				list->dy -= (value * yres - list->old_y[0]) / size;
-				list->old_y[0] -= list->dy * size;
-			}
+			size = dev->absmax[ABS_Y] - dev->absmin[ABS_Y];
+			if (size == 0) size = yres;
+			mousedev->packet.dy = (value * yres - mousedev->old_y[0]) / size;
+			mousedev->old_y[0] = mousedev->packet.dy * size;
 			break;
 	}
 }
 
-static void mousedev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
+static void mousedev_rel_event(struct mousedev *mousedev, unsigned int code, int value)
+{
+	switch (code) {
+		case REL_X:	mousedev->packet.dx += value; break;
+		case REL_Y:	mousedev->packet.dy -= value; break;
+		case REL_WHEEL:	mousedev->packet.dz -= value; break;
+	}
+}
+
+static void mousedev_key_event(struct mousedev *mousedev, unsigned int code, int value)
+{
+	int index;
+
+	switch (code) {
+		case BTN_TOUCH:
+		case BTN_0:
+		case BTN_FORWARD:
+		case BTN_LEFT:		index = 0; break;
+		case BTN_STYLUS:
+		case BTN_1:
+		case BTN_RIGHT:		index = 1; break;
+		case BTN_2:
+		case BTN_STYLUS2:
+		case BTN_MIDDLE:	index = 2; break;
+		case BTN_3:
+		case BTN_BACK:
+		case BTN_SIDE:		index = 3; break;
+		case BTN_4:
+		case BTN_EXTRA:		index = 4; break;
+		default: 		return;
+	}
+
+	if (value) {
+		set_bit(index, &mousedev->buttons);
+		set_bit(index, &mousedev_mix.buttons);
+	} else {
+		clear_bit(index, &mousedev->buttons);
+		clear_bit(index, &mousedev_mix.buttons);
+	}
+}
+
+static void mousedev_notify_readers(struct mousedev *mousedev, struct mousedev_motion *packet)
 {
-	struct mousedev *mousedevs[3] = { handle->private, &mousedev_mix, NULL };
-	struct mousedev **mousedev = mousedevs;
 	struct mousedev_list *list;
-	int index, wake;
 
-	while (*mousedev) {
+	list_for_each_entry(list, &mousedev->list, node) {
+		list->dx += packet->dx;
+		list->dy += packet->dy;
+		list->dz += packet->dz;
+		list->buttons = mousedev->buttons;
+		list->ready = 1;
+		kill_fasync(&list->fasync, SIGIO, POLL_IN);
+	}
+
+	wake_up_interruptible(&mousedev->wait);
+}
+
+static void mousedev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value)
+{
+	struct mousedev *mousedev = handle->private;
+
+	switch (type) {
+		case EV_ABS:
+			/* Ignore joysticks */
+			if (test_bit(BTN_TRIGGER, handle->dev->keybit))
+				return;
+
+			if (test_bit(BTN_TOOL_FINGER, handle->dev->keybit))
+				mousedev_touchpad_event(mousedev, code, value);
+			else
+				mousedev_abs_event(handle->dev, mousedev, code, value);
 
-		wake = 0;
+			break;
+
+		case EV_REL:
+			mousedev_rel_event(mousedev, code, value);
+			break;
 
-		list_for_each_entry(list, &(*mousedev)->list, node)
-			switch (type) {
-				case EV_ABS:
-					mousedev_abs_event(handle, list, code, value);
-					break;
-
-				case EV_REL:
-					switch (code) {
-						case REL_X:	list->dx += value; break;
-						case REL_Y:	list->dy -= value; break;
-						case REL_WHEEL:	if (list->mode) list->dz -= value; break;
-					}
-					break;
-
-				case EV_KEY:
-					if (code == BTN_TOUCH && test_bit(BTN_TOOL_FINGER, handle->dev->keybit)) {
-						/* Handle touchpad data */
-						list->touch = value;
-						if (!list->touch)
-							list->pkt_count = 0;
-						break;
-					}
-
-					switch (code) {
-						case BTN_TOUCH:
-						case BTN_0:
-						case BTN_FORWARD:
-						case BTN_LEFT:   index = 0; break;
-						case BTN_4:
-						case BTN_EXTRA:  if (list->mode == 2) { index = 4; break; }
-						case BTN_STYLUS:
-						case BTN_1:
-						case BTN_RIGHT:  index = 1; break;
-						case BTN_3:
-						case BTN_BACK:
-						case BTN_SIDE:   if (list->mode == 2) { index = 3; break; }
-						case BTN_2:
-						case BTN_STYLUS2:
-						case BTN_MIDDLE: index = 2; break;
-						default: return;
-					}
-					switch (value) {
-						case 0: clear_bit(index, &list->buttons); break;
-						case 1: set_bit(index, &list->buttons); break;
-						case 2: return;
-					}
-					break;
-
-				case EV_SYN:
-					switch (code) {
-						case SYN_REPORT:
-							if (list->touch) {
-								list->pkt_count++;
-								/* Input system eats duplicate events,
-								 * but we need all of them to do correct
-								 * averaging so apply present one forward
-								 */
-								fx(0) = fx(1);
-								fy(0) = fy(1);
-							}
-
-							list->ready = 1;
-							kill_fasync(&list->fasync, SIGIO, POLL_IN);
-							wake = 1;
-							break;
-					}
+		case EV_KEY:
+			if (value != 2) {
+				if (code == BTN_TOUCH && test_bit(BTN_TOOL_FINGER, handle->dev->keybit)) {
+					/* Handle touchpad data */
+					mousedev->touch = value;
+					if (!mousedev->touch)
+						mousedev->pkt_count = 0;
+				}
+				else
+					mousedev_key_event(mousedev, code, value);
 			}
+			break;
+
+		case EV_SYN:
+			if (code == SYN_REPORT) {
+				if (mousedev->touch) {
+					mousedev->pkt_count++;
+					/* Input system eats duplicate events, but we need all of them
+					 * to do correct averaging so apply present one forward
+			 		 */
+					fx(0) = fx(1);
+					fy(0) = fy(1);
+				}
 
-		if (wake)
-			wake_up_interruptible(&((*mousedev)->wait));
+				mousedev_notify_readers(mousedev, &mousedev->packet);
+				mousedev_notify_readers(&mousedev_mix, &mousedev->packet);
 
-		mousedev++;
+				memset(&mousedev->packet, 0, sizeof(struct mousedev_motion));
+			}
+			break;
 	}
 }
 
@@ -326,6 +355,8 @@
 		list->dz -= list->ps2[off + 3];
 		list->ps2[off + 3] = (list->ps2[off + 3] & 0x0f) | ((list->buttons & 0x18) << 1);
 		list->bufsiz++;
+	} else {
+		list->ps2[off] |= ((list->buttons & 0x10) >> 3) | ((list->buttons & 0x08) >> 1);
 	}
 
 	if (list->mode == 1) {
@@ -553,6 +584,7 @@
 static struct miscdevice psaux_mouse = {
 	PSMOUSE_MINOR, "psaux", &mousedev_fops
 };
+static int psaux_registered;
 #endif
 
 static int __init mousedev_init(void)
@@ -572,7 +604,7 @@
 				NULL, "mice");
 
 #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
-	if (!(mousedev_mix.misc = !misc_register(&psaux_mouse)))
+	if (!(psaux_registered = !misc_register(&psaux_mouse)))
 		printk(KERN_WARNING "mice: could not misc_register the device\n");
 #endif
 
@@ -584,7 +616,7 @@
 static void __exit mousedev_exit(void)
 {
 #ifdef CONFIG_INPUT_MOUSEDEV_PSAUX
-	if (mousedev_mix.misc)
+	if (psaux_registered)
 		misc_deregister(&psaux_mouse);
 #endif
 	devfs_remove("input/mice");

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/9] New set of input patches - 02-kbd98io-interrupt.patch
       [not found] <200405110101.42805.dtor_core@ameritech.net>
@ 2004-05-11  6:24 ` Dmitry Torokhov
       [not found] ` <200405110103.27973.dtor_core@ameritech.net>
  1 sibling, 0 replies; 9+ messages in thread
From: Dmitry Torokhov @ 2004-05-11  6:24 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: Andrew Morton, linux-kernel


===================================================================


ChangeSet@1.1587.20.3, 2004-05-10 01:25:24-05:00, dtor_core@ameritech.net
  Input: kbd98io_interrupt should return irqreturn_t


 98kbd-io.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)


===================================================================



diff -Nru a/drivers/input/serio/98kbd-io.c b/drivers/input/serio/98kbd-io.c
--- a/drivers/input/serio/98kbd-io.c	Tue May 11 00:54:37 2004
+++ b/drivers/input/serio/98kbd-io.c	Tue May 11 00:54:37 2004
@@ -51,7 +51,7 @@
 static struct serio kbd98_port;
 extern struct pt_regs *kbd_pt_regs;
 
-static void kbd98io_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t kbd98io_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 
 /*
  * kbd98_flush() flushes all data that may be in the keyboard buffers
@@ -143,7 +143,7 @@
  * to the upper layers.
  */
 
-static void kbd98io_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t kbd98io_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	unsigned long flags;
 	unsigned char data;
@@ -154,6 +154,7 @@
 	spin_unlock_irqrestore(&kbd98io_lock, flags);
 	serio_interrupt(&kbd98_port, data, 0, regs);
 
+	return IRQ_HANDLED;
 }
 
 int __init kbd98io_init(void)

^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 2/9] New set of input patches - 03-kbd98-interrupt.patch
       [not found] ` <200405110103.27973.dtor_core@ameritech.net>
       [not found]   ` <200405110104.20283.dtor_core@ameritech.net>
@ 2004-05-11  6:24   ` Dmitry Torokhov
  1 sibling, 0 replies; 9+ messages in thread
From: Dmitry Torokhov @ 2004-05-11  6:24 UTC (permalink / raw)
  To: Vojtech Pavlik; +Cc: Andrew Morton, linux-kernel


===================================================================


ChangeSet@1.1587.20.4, 2004-05-10 01:26:53-05:00, dtor_core@ameritech.net
  Input: kbd98_interrupt should return irqreturn_t


 98kbd.c |   26 +++++++++++++++-----------
 1 files changed, 15 insertions(+), 11 deletions(-)


===================================================================



diff -Nru a/drivers/input/keyboard/98kbd.c b/drivers/input/keyboard/98kbd.c
--- a/drivers/input/keyboard/98kbd.c	Tue May 11 00:55:01 2004
+++ b/drivers/input/keyboard/98kbd.c	Tue May 11 00:55:01 2004
@@ -109,8 +109,8 @@
 	struct jis_kbd_conv jis[16];
 };
 
-void kbd98_interrupt(struct serio *serio, unsigned char data,
-			unsigned int flags, struct pt_regs *regs)
+irqreturn_t kbd98_interrupt(struct serio *serio, unsigned char data,
+			    unsigned int flags, struct pt_regs *regs)
 {
 	struct kbd98 *kbd98 = serio->private;
 	unsigned char scancode, keycode;
@@ -119,15 +119,15 @@
 	switch (data) {
 		case KBD98_RET_ACK:
 			kbd98->ack = 1;
-			return;
+			goto out;
 		case KBD98_RET_NAK:
 			kbd98->ack = -1;
-			return;
+			goto out;
 	}
 
 	if (kbd98->cmdcnt) {
 		kbd98->cmdbuf[--kbd98->cmdcnt] = data;
-		return;
+		goto out;
 	}
 
 	scancode = data & KBD98_KEY;
@@ -164,7 +164,7 @@
 
 			keycode = kbd98->jis[i].emul[kbd98->shift].keycode;
 			if (keycode == KBD98_KEY_NULL)
-				return;
+				break;
 
 			if (press) {
 				kbd98->emul.scancode = scancode;
@@ -187,27 +187,31 @@
 			}
 
 			input_sync(&kbd98->dev);
-			return;
+			break;
 
 		case KEY_CAPSLOCK:
 			input_report_key(&kbd98->dev, keycode, 1);
 			input_sync(&kbd98->dev);
 			input_report_key(&kbd98->dev, keycode, 0);
 			input_sync(&kbd98->dev);
-			return;
+			break;
 
 		case KBD98_KEY_NULL:
-			return;
+			break;
 
 		case 0:
 			printk(KERN_WARNING "kbd98.c: Unknown key (scancode %#x) %s.\n",
 				data & KBD98_KEY, data & KBD98_RELEASE ? "released" : "pressed");
-			return;
+			break;
 
 		default:
 			input_report_key(&kbd98->dev, keycode, press);
 			input_sync(&kbd98->dev);
-		}
+			break;
+	}
+
+out:
+	return IRQ_HANDLED;
 }
 
 /*

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2004-05-11  6:53 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <200405110101.42805.dtor_core@ameritech.net>
2004-05-11  6:24 ` [PATCH 1/9] New set of input patches - 02-kbd98io-interrupt.patch Dmitry Torokhov
     [not found] ` <200405110103.27973.dtor_core@ameritech.net>
     [not found]   ` <200405110104.20283.dtor_core@ameritech.net>
2004-05-11  6:05     ` [PATCH 3/9] New set of input patches - 04-h3600-fixes.patch Dmitry Torokhov
2004-05-11  6:05       ` [PATCH 4/9] New set of input patches - 05-twidjoy-fixes.patch Dmitry Torokhov
2004-05-11  6:06         ` [PATCH 5/9] New set of input patches - 07-power-license.patch Dmitry Torokhov
2004-05-11  6:09           ` [PATCH 6/9] New set of input patches - 11-synaptics-reconnect.patch Dmitry Torokhov
2004-05-11  6:10             ` [PATCH 7/9] New set of input patches - 12-i8042-interrupt.patch Dmitry Torokhov
2004-05-11  6:10               ` [PATCH 8/9] New set of input patches - 13-i8042-unload.patch Dmitry Torokhov
2004-05-11  6:11                 ` [PATCH 9/9] New set of input patches - 14-mousedev-multiplexing.patch Dmitry Torokhov
2004-05-11  6:24   ` [PATCH 2/9] New set of input patches - 03-kbd98-interrupt.patch Dmitry Torokhov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox