Skip to content

Commit c374a0c

Browse files
committed
Input: i8042 - tease apart interrupt handler
In preparation to using guard notation when acquiring mutexes and spinlocks factor out handling of active multiplexing mode from i8042_interrupt(). Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Dmitry Torokhov <[email protected]>
1 parent 79d0197 commit c374a0c

File tree

1 file changed

+83
-56
lines changed

1 file changed

+83
-56
lines changed

drivers/input/serio/i8042.c

Lines changed: 83 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -178,7 +178,7 @@ static unsigned char i8042_suppress_kbd_ack;
178178
static struct platform_device *i8042_platform_device;
179179
static struct notifier_block i8042_kbd_bind_notifier_block;
180180

181-
static irqreturn_t i8042_interrupt(int irq, void *dev_id);
181+
static bool i8042_handle_data(int irq);
182182
static bool (*i8042_platform_filter)(unsigned char data, unsigned char str,
183183
struct serio *serio);
184184

@@ -434,7 +434,7 @@ static void i8042_port_close(struct serio *serio)
434434
* See if there is any data appeared while we were messing with
435435
* port state.
436436
*/
437-
i8042_interrupt(0, NULL);
437+
i8042_handle_data(0);
438438
}
439439

440440
/*
@@ -518,12 +518,68 @@ static bool i8042_filter(unsigned char data, unsigned char str,
518518
}
519519

520520
/*
521-
* i8042_interrupt() is the most important function in this driver -
522-
* it handles the interrupts from the i8042, and sends incoming bytes
523-
* to the upper layers.
521+
* i8042_handle_mux() handles case when data is coming from one of
522+
* the multiplexed ports. It would be simple if not for quirks with
523+
* handling errors:
524+
*
525+
* When MUXERR condition is signalled the data register can only contain
526+
* 0xfd, 0xfe or 0xff if implementation follows the spec. Unfortunately
527+
* it is not always the case. Some KBCs also report 0xfc when there is
528+
* nothing connected to the port while others sometimes get confused which
529+
* port the data came from and signal error leaving the data intact. They
530+
* _do not_ revert to legacy mode (actually I've never seen KBC reverting
531+
* to legacy mode yet, when we see one we'll add proper handling).
532+
* Anyway, we process 0xfc, 0xfd, 0xfe and 0xff as timeouts, and for the
533+
* rest assume that the data came from the same serio last byte
534+
* was transmitted (if transmission happened not too long ago).
524535
*/
536+
static int i8042_handle_mux(u8 str, u8 *data, unsigned int *dfl)
537+
{
538+
static unsigned long last_transmit;
539+
static unsigned long last_port;
540+
unsigned int mux_port;
541+
542+
mux_port = (str >> 6) & 3;
543+
*dfl = 0;
544+
545+
if (str & I8042_STR_MUXERR) {
546+
dbg("MUX error, status is %02x, data is %02x\n",
547+
str, *data);
548+
549+
switch (*data) {
550+
default:
551+
if (time_before(jiffies, last_transmit + HZ/10)) {
552+
mux_port = last_port;
553+
break;
554+
}
555+
fallthrough; /* report timeout */
556+
case 0xfc:
557+
case 0xfd:
558+
case 0xfe:
559+
*dfl = SERIO_TIMEOUT;
560+
*data = 0xfe;
561+
break;
562+
case 0xff:
563+
*dfl = SERIO_PARITY;
564+
*data = 0xfe;
565+
break;
566+
}
567+
}
525568

526-
static irqreturn_t i8042_interrupt(int irq, void *dev_id)
569+
last_port = mux_port;
570+
last_transmit = jiffies;
571+
572+
return I8042_MUX_PORT_NO + mux_port;
573+
}
574+
575+
/*
576+
* i8042_handle_data() is the most important function in this driver -
577+
* it reads the data from the i8042, determines its destination serio
578+
* port, and sends received byte to the upper layers.
579+
*
580+
* Returns true if there was data waiting, false otherwise.
581+
*/
582+
static bool i8042_handle_data(int irq)
527583
{
528584
struct i8042_port *port;
529585
struct serio *serio;
@@ -532,63 +588,24 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id)
532588
unsigned int dfl;
533589
unsigned int port_no;
534590
bool filtered;
535-
int ret = 1;
536591

537592
spin_lock_irqsave(&i8042_lock, flags);
538593

539594
str = i8042_read_status();
540595
if (unlikely(~str & I8042_STR_OBF)) {
541596
spin_unlock_irqrestore(&i8042_lock, flags);
542-
if (irq)
543-
dbg("Interrupt %d, without any data\n", irq);
544-
ret = 0;
545-
goto out;
597+
return false;
546598
}
547599

548600
data = i8042_read_data();
549601

550602
if (i8042_mux_present && (str & I8042_STR_AUXDATA)) {
551-
static unsigned long last_transmit;
552-
static unsigned char last_str;
553-
554-
dfl = 0;
555-
if (str & I8042_STR_MUXERR) {
556-
dbg("MUX error, status is %02x, data is %02x\n",
557-
str, data);
558-
/*
559-
* When MUXERR condition is signalled the data register can only contain
560-
* 0xfd, 0xfe or 0xff if implementation follows the spec. Unfortunately
561-
* it is not always the case. Some KBCs also report 0xfc when there is
562-
* nothing connected to the port while others sometimes get confused which
563-
* port the data came from and signal error leaving the data intact. They
564-
* _do not_ revert to legacy mode (actually I've never seen KBC reverting
565-
* to legacy mode yet, when we see one we'll add proper handling).
566-
* Anyway, we process 0xfc, 0xfd, 0xfe and 0xff as timeouts, and for the
567-
* rest assume that the data came from the same serio last byte
568-
* was transmitted (if transmission happened not too long ago).
569-
*/
570-
571-
switch (data) {
572-
default:
573-
if (time_before(jiffies, last_transmit + HZ/10)) {
574-
str = last_str;
575-
break;
576-
}
577-
fallthrough; /* report timeout */
578-
case 0xfc:
579-
case 0xfd:
580-
case 0xfe: dfl = SERIO_TIMEOUT; data = 0xfe; break;
581-
case 0xff: dfl = SERIO_PARITY; data = 0xfe; break;
582-
}
583-
}
584-
585-
port_no = I8042_MUX_PORT_NO + ((str >> 6) & 3);
586-
last_str = str;
587-
last_transmit = jiffies;
603+
port_no = i8042_handle_mux(str, &data, &dfl);
588604
} else {
589605

590-
dfl = ((str & I8042_STR_PARITY) ? SERIO_PARITY : 0) |
591-
((str & I8042_STR_TIMEOUT && !i8042_notimeout) ? SERIO_TIMEOUT : 0);
606+
dfl = (str & I8042_STR_PARITY) ? SERIO_PARITY : 0;
607+
if ((str & I8042_STR_TIMEOUT) && !i8042_notimeout)
608+
dfl |= SERIO_TIMEOUT;
592609

593610
port_no = (str & I8042_STR_AUXDATA) ?
594611
I8042_AUX_PORT_NO : I8042_KBD_PORT_NO;
@@ -609,8 +626,17 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id)
609626
if (likely(serio && !filtered))
610627
serio_interrupt(serio, data, dfl);
611628

612-
out:
613-
return IRQ_RETVAL(ret);
629+
return true;
630+
}
631+
632+
static irqreturn_t i8042_interrupt(int irq, void *dev_id)
633+
{
634+
if (unlikely(!i8042_handle_data(irq))) {
635+
dbg("Interrupt %d, without any data\n", irq);
636+
return IRQ_NONE;
637+
}
638+
639+
return IRQ_HANDLED;
614640
}
615641

616642
/*
@@ -1216,13 +1242,14 @@ static int i8042_controller_resume(bool s2r_wants_reset)
12161242
if (i8042_mux_present) {
12171243
if (i8042_set_mux_mode(true, NULL) || i8042_enable_mux_ports())
12181244
pr_warn("failed to resume active multiplexor, mouse won't work\n");
1219-
} else if (i8042_ports[I8042_AUX_PORT_NO].serio)
1245+
} else if (i8042_ports[I8042_AUX_PORT_NO].serio) {
12201246
i8042_enable_aux_port();
1247+
}
12211248

12221249
if (i8042_ports[I8042_KBD_PORT_NO].serio)
12231250
i8042_enable_kbd_port();
12241251

1225-
i8042_interrupt(0, NULL);
1252+
i8042_handle_data(0);
12261253

12271254
return 0;
12281255
}
@@ -1253,7 +1280,7 @@ static int i8042_pm_suspend(struct device *dev)
12531280
static int i8042_pm_resume_noirq(struct device *dev)
12541281
{
12551282
if (i8042_forcenorestore || !pm_resume_via_firmware())
1256-
i8042_interrupt(0, NULL);
1283+
i8042_handle_data(0);
12571284

12581285
return 0;
12591286
}
@@ -1290,7 +1317,7 @@ static int i8042_pm_resume(struct device *dev)
12901317

12911318
static int i8042_pm_thaw(struct device *dev)
12921319
{
1293-
i8042_interrupt(0, NULL);
1320+
i8042_handle_data(0);
12941321

12951322
return 0;
12961323
}

0 commit comments

Comments
 (0)