aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
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
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')
-rw-r--r--drivers/char/random.c1
-rw-r--r--drivers/input/gameport/fm801-gp.c22
-rw-r--r--drivers/input/gameport/gameport.c18
-rw-r--r--drivers/input/keyboard/atkbd.c54
-rw-r--r--drivers/input/serio/i8042.c13
-rw-r--r--drivers/input/serio/libps2.c3
-rw-r--r--drivers/input/serio/serio.c22
7 files changed, 105 insertions, 28 deletions
diff --git a/drivers/char/random.c b/drivers/char/random.c
index 07f47a0208a7..eb6b13f4211a 100644
--- a/drivers/char/random.c
+++ b/drivers/char/random.c
@@ -645,6 +645,7 @@ void add_input_randomness(unsigned int type, unsigned int code,
645 add_timer_randomness(&input_timer_state, 645 add_timer_randomness(&input_timer_state,
646 (type << 4) ^ code ^ (code >> 4) ^ value); 646 (type << 4) ^ code ^ (code >> 4) ^ value);
647} 647}
648EXPORT_SYMBOL_GPL(add_input_randomness);
648 649
649void add_interrupt_randomness(int irq) 650void add_interrupt_randomness(int irq)
650{ 651{
diff --git a/drivers/input/gameport/fm801-gp.c b/drivers/input/gameport/fm801-gp.c
index 90de5afe03c2..1dec00e20dbc 100644
--- a/drivers/input/gameport/fm801-gp.c
+++ b/drivers/input/gameport/fm801-gp.c
@@ -82,17 +82,19 @@ static int __devinit fm801_gp_probe(struct pci_dev *pci, const struct pci_device
82{ 82{
83 struct fm801_gp *gp; 83 struct fm801_gp *gp;
84 struct gameport *port; 84 struct gameport *port;
85 int error;
85 86
86 gp = kzalloc(sizeof(struct fm801_gp), GFP_KERNEL); 87 gp = kzalloc(sizeof(struct fm801_gp), GFP_KERNEL);
87 port = gameport_allocate_port(); 88 port = gameport_allocate_port();
88 if (!gp || !port) { 89 if (!gp || !port) {
89 printk(KERN_ERR "fm801-gp: Memory allocation failed\n"); 90 printk(KERN_ERR "fm801-gp: Memory allocation failed\n");
90 kfree(gp); 91 error = -ENOMEM;
91 gameport_free_port(port); 92 goto err_out_free;
92 return -ENOMEM;
93 } 93 }
94 94
95 pci_enable_device(pci); 95 error = pci_enable_device(pci);
96 if (error)
97 goto err_out_free;
96 98
97 port->open = fm801_gp_open; 99 port->open = fm801_gp_open;
98#ifdef HAVE_COOKED 100#ifdef HAVE_COOKED
@@ -108,9 +110,8 @@ static int __devinit fm801_gp_probe(struct pci_dev *pci, const struct pci_device
108 if (!gp->res_port) { 110 if (!gp->res_port) {
109 printk(KERN_DEBUG "fm801-gp: unable to grab region 0x%x-0x%x\n", 111 printk(KERN_DEBUG "fm801-gp: unable to grab region 0x%x-0x%x\n",
110 port->io, port->io + 0x0f); 112 port->io, port->io + 0x0f);
111 gameport_free_port(port); 113 error = -EBUSY;
112 kfree(gp); 114 goto err_out_disable_dev;
113 return -EBUSY;
114 } 115 }
115 116
116 pci_set_drvdata(pci, gp); 117 pci_set_drvdata(pci, gp);
@@ -119,6 +120,13 @@ static int __devinit fm801_gp_probe(struct pci_dev *pci, const struct pci_device
119 gameport_register_port(port); 120 gameport_register_port(port);
120 121
121 return 0; 122 return 0;
123
124 err_out_disable_dev:
125 pci_disable_device(pci);
126 err_out_free:
127 gameport_free_port(port);
128 kfree(gp);
129 return error;
122} 130}
123 131
124static void __devexit fm801_gp_remove(struct pci_dev *pci) 132static void __devexit fm801_gp_remove(struct pci_dev *pci)
diff --git a/drivers/input/gameport/gameport.c b/drivers/input/gameport/gameport.c
index 3f47ae55c6f3..a0af97efe6ac 100644
--- a/drivers/input/gameport/gameport.c
+++ b/drivers/input/gameport/gameport.c
@@ -191,6 +191,8 @@ static void gameport_run_poll_handler(unsigned long d)
191 191
192static void gameport_bind_driver(struct gameport *gameport, struct gameport_driver *drv) 192static void gameport_bind_driver(struct gameport *gameport, struct gameport_driver *drv)
193{ 193{
194 int error;
195
194 down_write(&gameport_bus.subsys.rwsem); 196 down_write(&gameport_bus.subsys.rwsem);
195 197
196 gameport->dev.driver = &drv->driver; 198 gameport->dev.driver = &drv->driver;
@@ -198,8 +200,20 @@ static void gameport_bind_driver(struct gameport *gameport, struct gameport_driv
198 gameport->dev.driver = NULL; 200 gameport->dev.driver = NULL;
199 goto out; 201 goto out;
200 } 202 }
201 device_bind_driver(&gameport->dev); 203
202out: 204 error = device_bind_driver(&gameport->dev);
205 if (error) {
206 printk(KERN_WARNING
207 "gameport: device_bind_driver() failed "
208 "for %s (%s) and %s, error: %d\n",
209 gameport->phys, gameport->name,
210 drv->description, error);
211 drv->disconnect(gameport);
212 gameport->dev.driver = NULL;
213 goto out;
214 }
215
216 out:
203 up_write(&gameport_bus.subsys.rwsem); 217 up_write(&gameport_bus.subsys.rwsem);
204} 218}
205 219
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index b6ef9eaad1dc..cbb93669d1ce 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -221,6 +221,7 @@ struct atkbd {
221 unsigned long xl_bit; 221 unsigned long xl_bit;
222 unsigned int last; 222 unsigned int last;
223 unsigned long time; 223 unsigned long time;
224 unsigned long err_count;
224 225
225 struct work_struct event_work; 226 struct work_struct event_work;
226 struct mutex event_mutex; 227 struct mutex event_mutex;
@@ -234,11 +235,13 @@ static ssize_t atkbd_attr_set_helper(struct device *dev, const char *buf, size_t
234#define ATKBD_DEFINE_ATTR(_name) \ 235#define ATKBD_DEFINE_ATTR(_name) \
235static ssize_t atkbd_show_##_name(struct atkbd *, char *); \ 236static ssize_t atkbd_show_##_name(struct atkbd *, char *); \
236static ssize_t atkbd_set_##_name(struct atkbd *, const char *, size_t); \ 237static ssize_t atkbd_set_##_name(struct atkbd *, const char *, size_t); \
237static ssize_t atkbd_do_show_##_name(struct device *d, struct device_attribute *attr, char *b) \ 238static ssize_t atkbd_do_show_##_name(struct device *d, \
239 struct device_attribute *attr, char *b) \
238{ \ 240{ \
239 return atkbd_attr_show_helper(d, b, atkbd_show_##_name); \ 241 return atkbd_attr_show_helper(d, b, atkbd_show_##_name); \
240} \ 242} \
241static ssize_t atkbd_do_set_##_name(struct device *d, struct device_attribute *attr, const char *b, size_t s) \ 243static ssize_t atkbd_do_set_##_name(struct device *d, \
244 struct device_attribute *attr, const char *b, size_t s) \
242{ \ 245{ \
243 return atkbd_attr_set_helper(d, b, s, atkbd_set_##_name); \ 246 return atkbd_attr_set_helper(d, b, s, atkbd_set_##_name); \
244} \ 247} \
@@ -251,6 +254,32 @@ ATKBD_DEFINE_ATTR(set);
251ATKBD_DEFINE_ATTR(softrepeat); 254ATKBD_DEFINE_ATTR(softrepeat);
252ATKBD_DEFINE_ATTR(softraw); 255ATKBD_DEFINE_ATTR(softraw);
253 256
257#define ATKBD_DEFINE_RO_ATTR(_name) \
258static ssize_t atkbd_show_##_name(struct atkbd *, char *); \
259static ssize_t atkbd_do_show_##_name(struct device *d, \
260 struct device_attribute *attr, char *b) \
261{ \
262 return atkbd_attr_show_helper(d, b, atkbd_show_##_name); \
263} \
264static struct device_attribute atkbd_attr_##_name = \
265 __ATTR(_name, S_IRUGO, atkbd_do_show_##_name, NULL);
266
267ATKBD_DEFINE_RO_ATTR(err_count);
268
269static struct attribute *atkbd_attributes[] = {
270 &atkbd_attr_extra.attr,
271 &atkbd_attr_scroll.attr,
272 &atkbd_attr_set.attr,
273 &atkbd_attr_softrepeat.attr,
274 &atkbd_attr_softraw.attr,
275 &atkbd_attr_err_count.attr,
276 NULL
277};
278
279static struct attribute_group atkbd_attribute_group = {
280 .attrs = atkbd_attributes,
281};
282
254static const unsigned int xl_table[] = { 283static const unsigned int xl_table[] = {
255 ATKBD_RET_BAT, ATKBD_RET_ERR, ATKBD_RET_ACK, 284 ATKBD_RET_BAT, ATKBD_RET_ERR, ATKBD_RET_ACK,
256 ATKBD_RET_NAK, ATKBD_RET_HANJA, ATKBD_RET_HANGEUL, 285 ATKBD_RET_NAK, ATKBD_RET_HANJA, ATKBD_RET_HANGEUL,
@@ -396,7 +425,10 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
396 add_release_event = 1; 425 add_release_event = 1;
397 break; 426 break;
398 case ATKBD_RET_ERR: 427 case ATKBD_RET_ERR:
428 atkbd->err_count++;
429#ifdef ATKBD_DEBUG
399 printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys); 430 printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys);
431#endif
400 goto out; 432 goto out;
401 } 433 }
402 434
@@ -786,12 +818,7 @@ static void atkbd_disconnect(struct serio *serio)
786 synchronize_sched(); /* Allow atkbd_interrupt()s to complete. */ 818 synchronize_sched(); /* Allow atkbd_interrupt()s to complete. */
787 flush_scheduled_work(); 819 flush_scheduled_work();
788 820
789 device_remove_file(&serio->dev, &atkbd_attr_extra); 821 sysfs_remove_group(&serio->dev.kobj, &atkbd_attribute_group);
790 device_remove_file(&serio->dev, &atkbd_attr_scroll);
791 device_remove_file(&serio->dev, &atkbd_attr_set);
792 device_remove_file(&serio->dev, &atkbd_attr_softrepeat);
793 device_remove_file(&serio->dev, &atkbd_attr_softraw);
794
795 input_unregister_device(atkbd->dev); 822 input_unregister_device(atkbd->dev);
796 serio_close(serio); 823 serio_close(serio);
797 serio_set_drvdata(serio, NULL); 824 serio_set_drvdata(serio, NULL);
@@ -961,11 +988,7 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
961 atkbd_set_keycode_table(atkbd); 988 atkbd_set_keycode_table(atkbd);
962 atkbd_set_device_attrs(atkbd); 989 atkbd_set_device_attrs(atkbd);
963 990
964 device_create_file(&serio->dev, &atkbd_attr_extra); 991 sysfs_create_group(&serio->dev.kobj, &atkbd_attribute_group);
965 device_create_file(&serio->dev, &atkbd_attr_scroll);
966 device_create_file(&serio->dev, &atkbd_attr_set);
967 device_create_file(&serio->dev, &atkbd_attr_softrepeat);
968 device_create_file(&serio->dev, &atkbd_attr_softraw);
969 992
970 atkbd_enable(atkbd); 993 atkbd_enable(atkbd);
971 994
@@ -1259,6 +1282,11 @@ static ssize_t atkbd_set_softraw(struct atkbd *atkbd, const char *buf, size_t co
1259 return count; 1282 return count;
1260} 1283}
1261 1284
1285static ssize_t atkbd_show_err_count(struct atkbd *atkbd, char *buf)
1286{
1287 return sprintf(buf, "%lu\n", atkbd->err_count);
1288}
1289
1262 1290
1263static int __init atkbd_init(void) 1291static int __init atkbd_init(void)
1264{ 1292{
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/*