diff options
Diffstat (limited to 'drivers/input/serio/i8042.c')
| -rw-r--r-- | drivers/input/serio/i8042.c | 13 |
1 files changed, 11 insertions, 2 deletions
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 09b06e605b50..7e3141f37e32 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
| @@ -106,6 +106,7 @@ static unsigned char i8042_ctr; | |||
| 106 | static unsigned char i8042_mux_present; | 106 | static unsigned char i8042_mux_present; |
| 107 | static unsigned char i8042_kbd_irq_registered; | 107 | static unsigned char i8042_kbd_irq_registered; |
| 108 | static unsigned char i8042_aux_irq_registered; | 108 | static unsigned char i8042_aux_irq_registered; |
| 109 | static unsigned char i8042_suppress_kbd_ack; | ||
| 109 | static struct platform_device *i8042_platform_device; | 110 | static struct platform_device *i8042_platform_device; |
| 110 | 111 | ||
| 111 | static irqreturn_t i8042_interrupt(int irq, void *dev_id); | 112 | static irqreturn_t i8042_interrupt(int irq, void *dev_id); |
| @@ -316,7 +317,7 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id) | |||
| 316 | unsigned char str, data; | 317 | unsigned char str, data; |
| 317 | unsigned int dfl; | 318 | unsigned int dfl; |
| 318 | unsigned int port_no; | 319 | unsigned int port_no; |
| 319 | int ret; | 320 | int ret = 1; |
| 320 | 321 | ||
| 321 | spin_lock_irqsave(&i8042_lock, flags); | 322 | spin_lock_irqsave(&i8042_lock, flags); |
| 322 | str = i8042_read_status(); | 323 | str = i8042_read_status(); |
| @@ -378,10 +379,16 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id) | |||
| 378 | dfl & SERIO_PARITY ? ", bad parity" : "", | 379 | dfl & SERIO_PARITY ? ", bad parity" : "", |
| 379 | dfl & SERIO_TIMEOUT ? ", timeout" : ""); | 380 | dfl & SERIO_TIMEOUT ? ", timeout" : ""); |
| 380 | 381 | ||
| 382 | if (unlikely(i8042_suppress_kbd_ack)) | ||
| 383 | if (port_no == I8042_KBD_PORT_NO && | ||
| 384 | (data == 0xfa || data == 0xfe)) { | ||
| 385 | i8042_suppress_kbd_ack = 0; | ||
| 386 | goto out; | ||
| 387 | } | ||
| 388 | |||
| 381 | if (likely(port->exists)) | 389 | if (likely(port->exists)) |
| 382 | serio_interrupt(port->serio, data, dfl); | 390 | serio_interrupt(port->serio, data, dfl); |
| 383 | 391 | ||
| 384 | ret = 1; | ||
| 385 | out: | 392 | out: |
| 386 | return IRQ_RETVAL(ret); | 393 | return IRQ_RETVAL(ret); |
| 387 | } | 394 | } |
| @@ -842,11 +849,13 @@ static long i8042_panic_blink(long count) | |||
| 842 | led ^= 0x01 | 0x04; | 849 | led ^= 0x01 | 0x04; |
| 843 | while (i8042_read_status() & I8042_STR_IBF) | 850 | while (i8042_read_status() & I8042_STR_IBF) |
| 844 | DELAY; | 851 | DELAY; |
| 852 | i8042_suppress_kbd_ack = 1; | ||
| 845 | i8042_write_data(0xed); /* set leds */ | 853 | i8042_write_data(0xed); /* set leds */ |
| 846 | DELAY; | 854 | DELAY; |
| 847 | while (i8042_read_status() & I8042_STR_IBF) | 855 | while (i8042_read_status() & I8042_STR_IBF) |
| 848 | DELAY; | 856 | DELAY; |
| 849 | DELAY; | 857 | DELAY; |
| 858 | i8042_suppress_kbd_ack = 1; | ||
| 850 | i8042_write_data(led); | 859 | i8042_write_data(led); |
| 851 | DELAY; | 860 | DELAY; |
| 852 | last_blink = count; | 861 | last_blink = count; |
