* [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
[parent not found: <200405110103.27973.dtor_core@ameritech.net>]
[parent not found: <200405110104.20283.dtor_core@ameritech.net>]
* [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 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