diff options
Diffstat (limited to 'drivers/input/serio')
-rw-r--r-- | drivers/input/serio/i8042.c | 39 | ||||
-rw-r--r-- | drivers/input/serio/serio.c | 147 | ||||
-rw-r--r-- | drivers/input/serio/serio_raw.c | 3 |
3 files changed, 100 insertions, 89 deletions
diff --git a/drivers/input/serio/i8042.c b/drivers/input/serio/i8042.c index 7e3141f37e32..debe9445488c 100644 --- a/drivers/input/serio/i8042.c +++ b/drivers/input/serio/i8042.c | |||
@@ -255,25 +255,10 @@ static int i8042_kbd_write(struct serio *port, unsigned char c) | |||
255 | static int i8042_aux_write(struct serio *serio, unsigned char c) | 255 | static int i8042_aux_write(struct serio *serio, unsigned char c) |
256 | { | 256 | { |
257 | struct i8042_port *port = serio->port_data; | 257 | struct i8042_port *port = serio->port_data; |
258 | int retval; | ||
259 | |||
260 | /* | ||
261 | * Send the byte out. | ||
262 | */ | ||
263 | |||
264 | if (port->mux == -1) | ||
265 | retval = i8042_command(&c, I8042_CMD_AUX_SEND); | ||
266 | else | ||
267 | retval = i8042_command(&c, I8042_CMD_MUX_SEND + port->mux); | ||
268 | |||
269 | /* | ||
270 | * Make sure the interrupt happens and the character is received even | ||
271 | * in the case the IRQ isn't wired, so that we can receive further | ||
272 | * characters later. | ||
273 | */ | ||
274 | 258 | ||
275 | i8042_interrupt(0, NULL); | 259 | return i8042_command(&c, port->mux == -1 ? |
276 | return retval; | 260 | I8042_CMD_AUX_SEND : |
261 | I8042_CMD_MUX_SEND + port->mux); | ||
277 | } | 262 | } |
278 | 263 | ||
279 | /* | 264 | /* |
@@ -337,23 +322,27 @@ static irqreturn_t i8042_interrupt(int irq, void *dev_id) | |||
337 | dfl = 0; | 322 | dfl = 0; |
338 | if (str & I8042_STR_MUXERR) { | 323 | if (str & I8042_STR_MUXERR) { |
339 | dbg("MUX error, status is %02x, data is %02x", str, data); | 324 | dbg("MUX error, status is %02x, data is %02x", str, data); |
340 | switch (data) { | ||
341 | default: | ||
342 | /* | 325 | /* |
343 | * When MUXERR condition is signalled the data register can only contain | 326 | * When MUXERR condition is signalled the data register can only contain |
344 | * 0xfd, 0xfe or 0xff if implementation follows the spec. Unfortunately | 327 | * 0xfd, 0xfe or 0xff if implementation follows the spec. Unfortunately |
345 | * it is not always the case. Some KBC just get confused which port the | 328 | * it is not always the case. Some KBCs also report 0xfc when there is |
346 | * data came from and signal error leaving the data intact. They _do not_ | 329 | * nothing connected to the port while others sometimes get confused which |
347 | * revert to legacy mode (actually I've never seen KBC reverting to legacy | 330 | * port the data came from and signal error leaving the data intact. They |
348 | * mode yet, when we see one we'll add proper handling). | 331 | * _do not_ revert to legacy mode (actually I've never seen KBC reverting |
349 | * Anyway, we will assume that the data came from the same serio last byte | 332 | * to legacy mode yet, when we see one we'll add proper handling). |
333 | * Anyway, we process 0xfc, 0xfd, 0xfe and 0xff as timeouts, and for the | ||
334 | * rest assume that the data came from the same serio last byte | ||
350 | * was transmitted (if transmission happened not too long ago). | 335 | * was transmitted (if transmission happened not too long ago). |
351 | */ | 336 | */ |
337 | |||
338 | switch (data) { | ||
339 | default: | ||
352 | if (time_before(jiffies, last_transmit + HZ/10)) { | 340 | if (time_before(jiffies, last_transmit + HZ/10)) { |
353 | str = last_str; | 341 | str = last_str; |
354 | break; | 342 | break; |
355 | } | 343 | } |
356 | /* fall through - report timeout */ | 344 | /* fall through - report timeout */ |
345 | case 0xfc: | ||
357 | case 0xfd: | 346 | case 0xfd: |
358 | case 0xfe: dfl = SERIO_TIMEOUT; data = 0xfe; break; | 347 | case 0xfe: dfl = SERIO_TIMEOUT; data = 0xfe; break; |
359 | case 0xff: dfl = SERIO_PARITY; data = 0xfe; break; | 348 | case 0xff: dfl = SERIO_PARITY; data = 0xfe; break; |
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 5f1d4032fd57..f0ce822c1028 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c | |||
@@ -45,8 +45,7 @@ EXPORT_SYMBOL(serio_interrupt); | |||
45 | EXPORT_SYMBOL(__serio_register_port); | 45 | EXPORT_SYMBOL(__serio_register_port); |
46 | EXPORT_SYMBOL(serio_unregister_port); | 46 | EXPORT_SYMBOL(serio_unregister_port); |
47 | EXPORT_SYMBOL(serio_unregister_child_port); | 47 | EXPORT_SYMBOL(serio_unregister_child_port); |
48 | EXPORT_SYMBOL(__serio_unregister_port_delayed); | 48 | EXPORT_SYMBOL(serio_register_driver); |
49 | EXPORT_SYMBOL(__serio_register_driver); | ||
50 | EXPORT_SYMBOL(serio_unregister_driver); | 49 | EXPORT_SYMBOL(serio_unregister_driver); |
51 | EXPORT_SYMBOL(serio_open); | 50 | EXPORT_SYMBOL(serio_open); |
52 | EXPORT_SYMBOL(serio_close); | 51 | EXPORT_SYMBOL(serio_close); |
@@ -63,11 +62,10 @@ static LIST_HEAD(serio_list); | |||
63 | 62 | ||
64 | static struct bus_type serio_bus; | 63 | static struct bus_type serio_bus; |
65 | 64 | ||
66 | static void serio_add_driver(struct serio_driver *drv); | ||
67 | static void serio_add_port(struct serio *serio); | 65 | static void serio_add_port(struct serio *serio); |
68 | static void serio_destroy_port(struct serio *serio); | ||
69 | static void serio_reconnect_port(struct serio *serio); | 66 | static void serio_reconnect_port(struct serio *serio); |
70 | static void serio_disconnect_port(struct serio *serio); | 67 | static void serio_disconnect_port(struct serio *serio); |
68 | static void serio_attach_driver(struct serio_driver *drv); | ||
71 | 69 | ||
72 | static int serio_connect_driver(struct serio *serio, struct serio_driver *drv) | 70 | static int serio_connect_driver(struct serio *serio, struct serio_driver *drv) |
73 | { | 71 | { |
@@ -171,11 +169,10 @@ static void serio_find_driver(struct serio *serio) | |||
171 | */ | 169 | */ |
172 | 170 | ||
173 | enum serio_event_type { | 171 | enum serio_event_type { |
174 | SERIO_RESCAN, | 172 | SERIO_RESCAN_PORT, |
175 | SERIO_RECONNECT, | 173 | SERIO_RECONNECT_PORT, |
176 | SERIO_REGISTER_PORT, | 174 | SERIO_REGISTER_PORT, |
177 | SERIO_UNREGISTER_PORT, | 175 | SERIO_ATTACH_DRIVER, |
178 | SERIO_REGISTER_DRIVER, | ||
179 | }; | 176 | }; |
180 | 177 | ||
181 | struct serio_event { | 178 | struct serio_event { |
@@ -190,11 +187,12 @@ static LIST_HEAD(serio_event_list); | |||
190 | static DECLARE_WAIT_QUEUE_HEAD(serio_wait); | 187 | static DECLARE_WAIT_QUEUE_HEAD(serio_wait); |
191 | static struct task_struct *serio_task; | 188 | static struct task_struct *serio_task; |
192 | 189 | ||
193 | static void serio_queue_event(void *object, struct module *owner, | 190 | static int serio_queue_event(void *object, struct module *owner, |
194 | enum serio_event_type event_type) | 191 | enum serio_event_type event_type) |
195 | { | 192 | { |
196 | unsigned long flags; | 193 | unsigned long flags; |
197 | struct serio_event *event; | 194 | struct serio_event *event; |
195 | int retval = 0; | ||
198 | 196 | ||
199 | spin_lock_irqsave(&serio_event_lock, flags); | 197 | spin_lock_irqsave(&serio_event_lock, flags); |
200 | 198 | ||
@@ -213,24 +211,34 @@ static void serio_queue_event(void *object, struct module *owner, | |||
213 | } | 211 | } |
214 | } | 212 | } |
215 | 213 | ||
216 | if ((event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC))) { | 214 | event = kmalloc(sizeof(struct serio_event), GFP_ATOMIC); |
217 | if (!try_module_get(owner)) { | 215 | if (!event) { |
218 | printk(KERN_WARNING "serio: Can't get module reference, dropping event %d\n", event_type); | 216 | printk(KERN_ERR |
219 | kfree(event); | 217 | "serio: Not enough memory to queue event %d\n", |
220 | goto out; | 218 | event_type); |
221 | } | 219 | retval = -ENOMEM; |
222 | 220 | goto out; | |
223 | event->type = event_type; | 221 | } |
224 | event->object = object; | ||
225 | event->owner = owner; | ||
226 | 222 | ||
227 | list_add_tail(&event->node, &serio_event_list); | 223 | if (!try_module_get(owner)) { |
228 | wake_up(&serio_wait); | 224 | printk(KERN_WARNING |
229 | } else { | 225 | "serio: Can't get module reference, dropping event %d\n", |
230 | printk(KERN_ERR "serio: Not enough memory to queue event %d\n", event_type); | 226 | event_type); |
227 | kfree(event); | ||
228 | retval = -EINVAL; | ||
229 | goto out; | ||
231 | } | 230 | } |
231 | |||
232 | event->type = event_type; | ||
233 | event->object = object; | ||
234 | event->owner = owner; | ||
235 | |||
236 | list_add_tail(&event->node, &serio_event_list); | ||
237 | wake_up(&serio_wait); | ||
238 | |||
232 | out: | 239 | out: |
233 | spin_unlock_irqrestore(&serio_event_lock, flags); | 240 | spin_unlock_irqrestore(&serio_event_lock, flags); |
241 | return retval; | ||
234 | } | 242 | } |
235 | 243 | ||
236 | static void serio_free_event(struct serio_event *event) | 244 | static void serio_free_event(struct serio_event *event) |
@@ -308,22 +316,17 @@ static void serio_handle_event(void) | |||
308 | serio_add_port(event->object); | 316 | serio_add_port(event->object); |
309 | break; | 317 | break; |
310 | 318 | ||
311 | case SERIO_UNREGISTER_PORT: | 319 | case SERIO_RECONNECT_PORT: |
312 | serio_disconnect_port(event->object); | ||
313 | serio_destroy_port(event->object); | ||
314 | break; | ||
315 | |||
316 | case SERIO_RECONNECT: | ||
317 | serio_reconnect_port(event->object); | 320 | serio_reconnect_port(event->object); |
318 | break; | 321 | break; |
319 | 322 | ||
320 | case SERIO_RESCAN: | 323 | case SERIO_RESCAN_PORT: |
321 | serio_disconnect_port(event->object); | 324 | serio_disconnect_port(event->object); |
322 | serio_find_driver(event->object); | 325 | serio_find_driver(event->object); |
323 | break; | 326 | break; |
324 | 327 | ||
325 | case SERIO_REGISTER_DRIVER: | 328 | case SERIO_ATTACH_DRIVER: |
326 | serio_add_driver(event->object); | 329 | serio_attach_driver(event->object); |
327 | break; | 330 | break; |
328 | 331 | ||
329 | default: | 332 | default: |
@@ -675,12 +678,12 @@ static void serio_disconnect_port(struct serio *serio) | |||
675 | 678 | ||
676 | void serio_rescan(struct serio *serio) | 679 | void serio_rescan(struct serio *serio) |
677 | { | 680 | { |
678 | serio_queue_event(serio, NULL, SERIO_RESCAN); | 681 | serio_queue_event(serio, NULL, SERIO_RESCAN_PORT); |
679 | } | 682 | } |
680 | 683 | ||
681 | void serio_reconnect(struct serio *serio) | 684 | void serio_reconnect(struct serio *serio) |
682 | { | 685 | { |
683 | serio_queue_event(serio, NULL, SERIO_RECONNECT); | 686 | serio_queue_event(serio, NULL, SERIO_RECONNECT_PORT); |
684 | } | 687 | } |
685 | 688 | ||
686 | /* | 689 | /* |
@@ -717,16 +720,6 @@ void serio_unregister_child_port(struct serio *serio) | |||
717 | mutex_unlock(&serio_mutex); | 720 | mutex_unlock(&serio_mutex); |
718 | } | 721 | } |
719 | 722 | ||
720 | /* | ||
721 | * Submits register request to kseriod for subsequent execution. | ||
722 | * Can be used when it is not obvious whether the serio_mutex is | ||
723 | * taken or not and when delayed execution is feasible. | ||
724 | */ | ||
725 | void __serio_unregister_port_delayed(struct serio *serio, struct module *owner) | ||
726 | { | ||
727 | serio_queue_event(serio, owner, SERIO_UNREGISTER_PORT); | ||
728 | } | ||
729 | |||
730 | 723 | ||
731 | /* | 724 | /* |
732 | * Serio driver operations | 725 | * Serio driver operations |
@@ -785,28 +778,52 @@ static int serio_driver_remove(struct device *dev) | |||
785 | return 0; | 778 | return 0; |
786 | } | 779 | } |
787 | 780 | ||
788 | static struct bus_type serio_bus = { | 781 | static void serio_attach_driver(struct serio_driver *drv) |
789 | .name = "serio", | ||
790 | .probe = serio_driver_probe, | ||
791 | .remove = serio_driver_remove, | ||
792 | }; | ||
793 | |||
794 | static void serio_add_driver(struct serio_driver *drv) | ||
795 | { | 782 | { |
796 | int error; | 783 | int error; |
797 | 784 | ||
798 | error = driver_register(&drv->driver); | 785 | error = driver_attach(&drv->driver); |
799 | if (error) | 786 | if (error) |
800 | printk(KERN_ERR | 787 | printk(KERN_WARNING |
801 | "serio: driver_register() failed for %s, error: %d\n", | 788 | "serio: driver_attach() failed for %s with error %d\n", |
802 | drv->driver.name, error); | 789 | drv->driver.name, error); |
803 | } | 790 | } |
804 | 791 | ||
805 | void __serio_register_driver(struct serio_driver *drv, struct module *owner) | 792 | int serio_register_driver(struct serio_driver *drv) |
806 | { | 793 | { |
794 | int manual_bind = drv->manual_bind; | ||
795 | int error; | ||
796 | |||
807 | drv->driver.bus = &serio_bus; | 797 | drv->driver.bus = &serio_bus; |
808 | 798 | ||
809 | serio_queue_event(drv, owner, SERIO_REGISTER_DRIVER); | 799 | /* |
800 | * Temporarily disable automatic binding because probing | ||
801 | * takes long time and we are better off doing it in kseriod | ||
802 | */ | ||
803 | drv->manual_bind = 1; | ||
804 | |||
805 | error = driver_register(&drv->driver); | ||
806 | if (error) { | ||
807 | printk(KERN_ERR | ||
808 | "serio: driver_register() failed for %s, error: %d\n", | ||
809 | drv->driver.name, error); | ||
810 | return error; | ||
811 | } | ||
812 | |||
813 | /* | ||
814 | * Restore original bind mode and let kseriod bind the | ||
815 | * driver to free ports | ||
816 | */ | ||
817 | if (!manual_bind) { | ||
818 | drv->manual_bind = 0; | ||
819 | error = serio_queue_event(drv, NULL, SERIO_ATTACH_DRIVER); | ||
820 | if (error) { | ||
821 | driver_unregister(&drv->driver); | ||
822 | return error; | ||
823 | } | ||
824 | } | ||
825 | |||
826 | return 0; | ||
810 | } | 827 | } |
811 | 828 | ||
812 | void serio_unregister_driver(struct serio_driver *drv) | 829 | void serio_unregister_driver(struct serio_driver *drv) |
@@ -947,15 +964,21 @@ irqreturn_t serio_interrupt(struct serio *serio, | |||
947 | return ret; | 964 | return ret; |
948 | } | 965 | } |
949 | 966 | ||
967 | static struct bus_type serio_bus = { | ||
968 | .name = "serio", | ||
969 | .dev_attrs = serio_device_attrs, | ||
970 | .drv_attrs = serio_driver_attrs, | ||
971 | .match = serio_bus_match, | ||
972 | .uevent = serio_uevent, | ||
973 | .probe = serio_driver_probe, | ||
974 | .remove = serio_driver_remove, | ||
975 | .resume = serio_resume, | ||
976 | }; | ||
977 | |||
950 | static int __init serio_init(void) | 978 | static int __init serio_init(void) |
951 | { | 979 | { |
952 | int error; | 980 | int error; |
953 | 981 | ||
954 | serio_bus.dev_attrs = serio_device_attrs; | ||
955 | serio_bus.drv_attrs = serio_driver_attrs; | ||
956 | serio_bus.match = serio_bus_match; | ||
957 | serio_bus.uevent = serio_uevent; | ||
958 | serio_bus.resume = serio_resume; | ||
959 | error = bus_register(&serio_bus); | 982 | error = bus_register(&serio_bus); |
960 | if (error) { | 983 | if (error) { |
961 | printk(KERN_ERR "serio: failed to register serio bus, error: %d\n", error); | 984 | printk(KERN_ERR "serio: failed to register serio bus, error: %d\n", error); |
diff --git a/drivers/input/serio/serio_raw.c b/drivers/input/serio/serio_raw.c index 7c8d0399ae82..088ebc348ba3 100644 --- a/drivers/input/serio/serio_raw.c +++ b/drivers/input/serio/serio_raw.c | |||
@@ -389,8 +389,7 @@ static struct serio_driver serio_raw_drv = { | |||
389 | 389 | ||
390 | static int __init serio_raw_init(void) | 390 | static int __init serio_raw_init(void) |
391 | { | 391 | { |
392 | serio_register_driver(&serio_raw_drv); | 392 | return serio_register_driver(&serio_raw_drv); |
393 | return 0; | ||
394 | } | 393 | } |
395 | 394 | ||
396 | static void __exit serio_raw_exit(void) | 395 | static void __exit serio_raw_exit(void) |