From: Vojtech Pavlik <vojtech@suse.cz>
To: torvalds@osdl.org, akpm@osdl.org, vojtech@ucw.cz,
linux-kernel@vger.kernel.org
Subject: [PATCH 33/39] input: Split i8042 interrupt handling into an IRQ handler and a tasklet [excluded later]
Date: Mon, 7 Jun 2004 13:55:54 +0200 [thread overview]
Message-ID: <10866093543861@twilight.ucw.cz> (raw)
In-Reply-To: <10866093543712@twilight.ucw.cz>
You can pull this changeset from:
bk://kernel.bkbits.net/vojtech/input-for-linus
===================================================================
ChangeSet@1.1587.27.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 2004-06-07 13:10:49 +02:00
+++ b/drivers/input/serio/i8042.c 2004-06-07 13:10:49 +02:00
@@ -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();
}
next prev parent reply other threads:[~2004-06-07 12:10 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-06-07 11:50 [patches] Input update Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 1/39] input: Fix a workaround for USB Legacy detected as MUX in i8042.c Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 2/39] input: Profusion/ServerWorks chipset workaround in i8042.c for Ingo Molnar Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 3/39] input: Fix emulation of mouse reset (0xff) command Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 4/39] input: Synaptics driver cleanup Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 5/39] input: Support Synaptics touchpads that have separate middle button Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 6/39] input: Pass psmouse_extensions as a parameter Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 7/39] input: Soften ACK warning in atkbd Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 8/39] input: Fix trailing whitespace " Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 9/39] input: Remove unneeded fields in atkbd structure, convert to bitfields Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 10/39] input: Do not process scancodes in atkbd until fully initialized Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 11/39] input: Use reconnect instead of rescan in psmouse if possible Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 12/39] input: Move reconnect after errors to generic code in psmouse Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 13/39] input: Add protocol_handler to psmouse structure Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 14/39] input: Add psmouse_sliced_command Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 15/39] input: Do not modify device's properties when probing for protocol extensions Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 16/39] input: Allow disabling legacy psaux device Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 17/39] input: Serio trailing whitespace fixes Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 18/39] input: Make serio open and close methods optional Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 19/39] input: Trailing whitespace fixes Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 20/39] input: Create input_set_abs_params() Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 21/39] input: Microtouch USB driver update Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 22/39] input: Trailing whitespace fixes in drivers/input/serio Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 23/39] input: kbd98io_interrupt should return irqreturn_t Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 24/39] input: kbd98_interrupt " Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 25/39] input: Various fixes for H3600 touchscreen driver Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 26/39] input: Twidjoy module fixes Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 27/39] input: Trailing whitespace fixes in drivers/input/keyboard Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 28/39] input: Power - add MODULE_LICENSE Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 29/39] input: Trailing whitespace fixes in drivers/input/joystick Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 30/39] input: Trailing whitespace fixes in drivers/input/gameport Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 31/39] input: Trailing whitespace fixes in drivers/input Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 32/39] input: Do not call synaptics_init unless we are ready to do full mouse setup Vojtech Pavlik
2004-06-07 11:55 ` Vojtech Pavlik [this message]
2004-06-07 11:55 ` [PATCH 34/39] input: i8042 - kill the timer only after removing interrupt handler Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 35/39] input: Mousedev - better multiplex absolute and relative devices Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 36/39] input: Fix an oops at opentime of /dev/input/event devices Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 37/39] input: Check for IM Explorer mice even if IMPS check failed Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 38/39] input: Fix oops in hiddev Vojtech Pavlik
2004-06-07 11:55 ` [PATCH 39/39] input: Exclude tasklet changes to i8042.c Vojtech Pavlik
2004-06-07 13:07 ` [PATCH 20/39] input: Create input_set_abs_params() Jan-Benedict Glaw
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=10866093543861@twilight.ucw.cz \
--to=vojtech@suse.cz \
--cc=akpm@osdl.org \
--cc=linux-kernel@vger.kernel.org \
--cc=torvalds@osdl.org \
--cc=vojtech@ucw.cz \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox