aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/serio
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@g5.osdl.org>2006-10-17 11:56:43 -0400
committerLinus Torvalds <torvalds@g5.osdl.org>2006-10-17 11:56:43 -0400
commit43f82216f0bd114599f4a221ae6924f3658a0c9a (patch)
tree89dbd85a0a1882ae38e6b61e360b365c018195fd /drivers/input/serio
parent20f85957667ccc53183b5ffac22213d75e317408 (diff)
parentb435fdcda126db42343b8055d04a0a27c229717b (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
* git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: Input: fm801-gp - handle errors from pci_enable_device() Input: gameport core - handle errors returned by device_bind_driver() Input: serio core - handle errors returned by device_bind_driver() Lockdep: fix compile error in drivers/input/serio/serio.c Input: serio - add lockdep annotations Lockdep: add lockdep_set_class_and_subclass() and lockdep_set_subclass() Input: atkbd - supress "too many keys" error message Input: i8042 - supress ACK/NAKs when blinking during panic Input: add missing exports to fix modular build
Diffstat (limited to 'drivers/input/serio')
-rw-r--r--drivers/input/serio/i8042.c13
-rw-r--r--drivers/input/serio/libps2.c3
-rw-r--r--drivers/input/serio/serio.c22
3 files changed, 32 insertions, 6 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;
106static unsigned char i8042_mux_present; 106static unsigned char i8042_mux_present;
107static unsigned char i8042_kbd_irq_registered; 107static unsigned char i8042_kbd_irq_registered;
108static unsigned char i8042_aux_irq_registered; 108static unsigned char i8042_aux_irq_registered;
109static unsigned char i8042_suppress_kbd_ack;
109static struct platform_device *i8042_platform_device; 110static struct platform_device *i8042_platform_device;
110 111
111static irqreturn_t i8042_interrupt(int irq, void *dev_id); 112static 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;
diff --git a/drivers/input/serio/libps2.c b/drivers/input/serio/libps2.c
index dcb16b5cbec0..e5b1b60757bb 100644
--- a/drivers/input/serio/libps2.c
+++ b/drivers/input/serio/libps2.c
@@ -189,7 +189,7 @@ int ps2_command(struct ps2dev *ps2dev, unsigned char *param, int command)
189 return -1; 189 return -1;
190 } 190 }
191 191
192 mutex_lock_nested(&ps2dev->cmd_mutex, SINGLE_DEPTH_NESTING); 192 mutex_lock(&ps2dev->cmd_mutex);
193 193
194 serio_pause_rx(ps2dev->serio); 194 serio_pause_rx(ps2dev->serio);
195 ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0; 195 ps2dev->flags = command == PS2_CMD_GETID ? PS2_FLAG_WAITID : 0;
@@ -296,6 +296,7 @@ EXPORT_SYMBOL(ps2_schedule_command);
296void ps2_init(struct ps2dev *ps2dev, struct serio *serio) 296void ps2_init(struct ps2dev *ps2dev, struct serio *serio)
297{ 297{
298 mutex_init(&ps2dev->cmd_mutex); 298 mutex_init(&ps2dev->cmd_mutex);
299 lockdep_set_subclass(&ps2dev->cmd_mutex, serio->depth);
299 init_waitqueue_head(&ps2dev->wait); 300 init_waitqueue_head(&ps2dev->wait);
300 ps2dev->serio = serio; 301 ps2dev->serio = serio;
301} 302}
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c
index 960fae3c3cea..211943f85cb6 100644
--- a/drivers/input/serio/serio.c
+++ b/drivers/input/serio/serio.c
@@ -118,6 +118,8 @@ static int serio_match_port(const struct serio_device_id *ids, struct serio *ser
118 118
119static void serio_bind_driver(struct serio *serio, struct serio_driver *drv) 119static void serio_bind_driver(struct serio *serio, struct serio_driver *drv)
120{ 120{
121 int error;
122
121 down_write(&serio_bus.subsys.rwsem); 123 down_write(&serio_bus.subsys.rwsem);
122 124
123 if (serio_match_port(drv->id_table, serio)) { 125 if (serio_match_port(drv->id_table, serio)) {
@@ -126,9 +128,19 @@ static void serio_bind_driver(struct serio *serio, struct serio_driver *drv)
126 serio->dev.driver = NULL; 128 serio->dev.driver = NULL;
127 goto out; 129 goto out;
128 } 130 }
129 device_bind_driver(&serio->dev); 131 error = device_bind_driver(&serio->dev);
132 if (error) {
133 printk(KERN_WARNING
134 "serio: device_bind_driver() failed "
135 "for %s (%s) and %s, error: %d\n",
136 serio->phys, serio->name,
137 drv->description, error);
138 serio_disconnect_driver(serio);
139 serio->dev.driver = NULL;
140 goto out;
141 }
130 } 142 }
131out: 143 out:
132 up_write(&serio_bus.subsys.rwsem); 144 up_write(&serio_bus.subsys.rwsem);
133} 145}
134 146
@@ -538,8 +550,12 @@ static void serio_init_port(struct serio *serio)
538 "serio%ld", (long)atomic_inc_return(&serio_no) - 1); 550 "serio%ld", (long)atomic_inc_return(&serio_no) - 1);
539 serio->dev.bus = &serio_bus; 551 serio->dev.bus = &serio_bus;
540 serio->dev.release = serio_release_port; 552 serio->dev.release = serio_release_port;
541 if (serio->parent) 553 if (serio->parent) {
542 serio->dev.parent = &serio->parent->dev; 554 serio->dev.parent = &serio->parent->dev;
555 serio->depth = serio->parent->depth + 1;
556 } else
557 serio->depth = 0;
558 lockdep_set_subclass(&serio->lock, serio->depth);
543} 559}
544 560
545/* 561/*