diff options
Diffstat (limited to 'drivers/input/serio/serio.c')
| -rw-r--r-- | drivers/input/serio/serio.c | 65 |
1 files changed, 51 insertions, 14 deletions
diff --git a/drivers/input/serio/serio.c b/drivers/input/serio/serio.c index 6521034bc933..3e76ad71c9a0 100644 --- a/drivers/input/serio/serio.c +++ b/drivers/input/serio/serio.c | |||
| @@ -62,6 +62,7 @@ static LIST_HEAD(serio_list); | |||
| 62 | 62 | ||
| 63 | static struct bus_type serio_bus; | 63 | static struct bus_type serio_bus; |
| 64 | 64 | ||
| 65 | static void serio_add_driver(struct serio_driver *drv); | ||
| 65 | static void serio_add_port(struct serio *serio); | 66 | static void serio_add_port(struct serio *serio); |
| 66 | static void serio_destroy_port(struct serio *serio); | 67 | static void serio_destroy_port(struct serio *serio); |
| 67 | static void serio_reconnect_port(struct serio *serio); | 68 | static void serio_reconnect_port(struct serio *serio); |
| @@ -140,8 +141,14 @@ static void serio_release_driver(struct serio *serio) | |||
| 140 | 141 | ||
| 141 | static void serio_find_driver(struct serio *serio) | 142 | static void serio_find_driver(struct serio *serio) |
| 142 | { | 143 | { |
| 144 | int error; | ||
| 145 | |||
| 143 | down_write(&serio_bus.subsys.rwsem); | 146 | down_write(&serio_bus.subsys.rwsem); |
| 144 | device_attach(&serio->dev); | 147 | error = device_attach(&serio->dev); |
| 148 | if (error < 0) | ||
| 149 | printk(KERN_WARNING | ||
| 150 | "serio: device_attach() failed for %s (%s), error: %d\n", | ||
| 151 | serio->phys, serio->name, error); | ||
| 145 | up_write(&serio_bus.subsys.rwsem); | 152 | up_write(&serio_bus.subsys.rwsem); |
| 146 | } | 153 | } |
| 147 | 154 | ||
| @@ -272,7 +279,6 @@ static struct serio_event *serio_get_event(void) | |||
| 272 | static void serio_handle_event(void) | 279 | static void serio_handle_event(void) |
| 273 | { | 280 | { |
| 274 | struct serio_event *event; | 281 | struct serio_event *event; |
| 275 | struct serio_driver *serio_drv; | ||
| 276 | 282 | ||
| 277 | mutex_lock(&serio_mutex); | 283 | mutex_lock(&serio_mutex); |
| 278 | 284 | ||
| @@ -304,8 +310,7 @@ static void serio_handle_event(void) | |||
| 304 | break; | 310 | break; |
| 305 | 311 | ||
| 306 | case SERIO_REGISTER_DRIVER: | 312 | case SERIO_REGISTER_DRIVER: |
| 307 | serio_drv = event->object; | 313 | serio_add_driver(event->object); |
| 308 | driver_register(&serio_drv->driver); | ||
| 309 | break; | 314 | break; |
| 310 | 315 | ||
| 311 | default: | 316 | default: |
| @@ -525,6 +530,7 @@ static void serio_init_port(struct serio *serio) | |||
| 525 | 530 | ||
| 526 | __module_get(THIS_MODULE); | 531 | __module_get(THIS_MODULE); |
| 527 | 532 | ||
| 533 | INIT_LIST_HEAD(&serio->node); | ||
| 528 | spin_lock_init(&serio->lock); | 534 | spin_lock_init(&serio->lock); |
| 529 | mutex_init(&serio->drv_mutex); | 535 | mutex_init(&serio->drv_mutex); |
| 530 | device_initialize(&serio->dev); | 536 | device_initialize(&serio->dev); |
| @@ -542,6 +548,8 @@ static void serio_init_port(struct serio *serio) | |||
| 542 | */ | 548 | */ |
| 543 | static void serio_add_port(struct serio *serio) | 549 | static void serio_add_port(struct serio *serio) |
| 544 | { | 550 | { |
| 551 | int error; | ||
| 552 | |||
| 545 | if (serio->parent) { | 553 | if (serio->parent) { |
| 546 | serio_pause_rx(serio->parent); | 554 | serio_pause_rx(serio->parent); |
| 547 | serio->parent->child = serio; | 555 | serio->parent->child = serio; |
| @@ -551,9 +559,19 @@ static void serio_add_port(struct serio *serio) | |||
| 551 | list_add_tail(&serio->node, &serio_list); | 559 | list_add_tail(&serio->node, &serio_list); |
| 552 | if (serio->start) | 560 | if (serio->start) |
| 553 | serio->start(serio); | 561 | serio->start(serio); |
| 554 | device_add(&serio->dev); | 562 | error = device_add(&serio->dev); |
| 555 | sysfs_create_group(&serio->dev.kobj, &serio_id_attr_group); | 563 | if (error) |
| 556 | serio->registered = 1; | 564 | printk(KERN_ERR |
| 565 | "serio: device_add() failed for %s (%s), error: %d\n", | ||
| 566 | serio->phys, serio->name, error); | ||
| 567 | else { | ||
| 568 | serio->registered = 1; | ||
| 569 | error = sysfs_create_group(&serio->dev.kobj, &serio_id_attr_group); | ||
| 570 | if (error) | ||
| 571 | printk(KERN_ERR | ||
| 572 | "serio: sysfs_create_group() failed for %s (%s), error: %d\n", | ||
| 573 | serio->phys, serio->name, error); | ||
| 574 | } | ||
| 557 | } | 575 | } |
| 558 | 576 | ||
| 559 | /* | 577 | /* |
| @@ -583,10 +601,10 @@ static void serio_destroy_port(struct serio *serio) | |||
| 583 | if (serio->registered) { | 601 | if (serio->registered) { |
| 584 | sysfs_remove_group(&serio->dev.kobj, &serio_id_attr_group); | 602 | sysfs_remove_group(&serio->dev.kobj, &serio_id_attr_group); |
| 585 | device_del(&serio->dev); | 603 | device_del(&serio->dev); |
| 586 | list_del_init(&serio->node); | ||
| 587 | serio->registered = 0; | 604 | serio->registered = 0; |
| 588 | } | 605 | } |
| 589 | 606 | ||
| 607 | list_del_init(&serio->node); | ||
| 590 | serio_remove_pending_events(serio); | 608 | serio_remove_pending_events(serio); |
| 591 | put_device(&serio->dev); | 609 | put_device(&serio->dev); |
| 592 | } | 610 | } |
| @@ -756,6 +774,17 @@ static struct bus_type serio_bus = { | |||
| 756 | .remove = serio_driver_remove, | 774 | .remove = serio_driver_remove, |
| 757 | }; | 775 | }; |
| 758 | 776 | ||
| 777 | static void serio_add_driver(struct serio_driver *drv) | ||
| 778 | { | ||
| 779 | int error; | ||
| 780 | |||
| 781 | error = driver_register(&drv->driver); | ||
| 782 | if (error) | ||
| 783 | printk(KERN_ERR | ||
| 784 | "serio: driver_register() failed for %s, error: %d\n", | ||
| 785 | drv->driver.name, error); | ||
| 786 | } | ||
| 787 | |||
| 759 | void __serio_register_driver(struct serio_driver *drv, struct module *owner) | 788 | void __serio_register_driver(struct serio_driver *drv, struct module *owner) |
| 760 | { | 789 | { |
| 761 | drv->driver.bus = &serio_bus; | 790 | drv->driver.bus = &serio_bus; |
| @@ -903,18 +932,26 @@ irqreturn_t serio_interrupt(struct serio *serio, | |||
| 903 | 932 | ||
| 904 | static int __init serio_init(void) | 933 | static int __init serio_init(void) |
| 905 | { | 934 | { |
| 906 | serio_task = kthread_run(serio_thread, NULL, "kseriod"); | 935 | int error; |
| 907 | if (IS_ERR(serio_task)) { | ||
| 908 | printk(KERN_ERR "serio: Failed to start kseriod\n"); | ||
| 909 | return PTR_ERR(serio_task); | ||
| 910 | } | ||
| 911 | 936 | ||
| 912 | serio_bus.dev_attrs = serio_device_attrs; | 937 | serio_bus.dev_attrs = serio_device_attrs; |
| 913 | serio_bus.drv_attrs = serio_driver_attrs; | 938 | serio_bus.drv_attrs = serio_driver_attrs; |
| 914 | serio_bus.match = serio_bus_match; | 939 | serio_bus.match = serio_bus_match; |
| 915 | serio_bus.uevent = serio_uevent; | 940 | serio_bus.uevent = serio_uevent; |
| 916 | serio_bus.resume = serio_resume; | 941 | serio_bus.resume = serio_resume; |
| 917 | bus_register(&serio_bus); | 942 | error = bus_register(&serio_bus); |
| 943 | if (error) { | ||
| 944 | printk(KERN_ERR "serio: failed to register serio bus, error: %d\n", error); | ||
| 945 | return error; | ||
| 946 | } | ||
| 947 | |||
| 948 | serio_task = kthread_run(serio_thread, NULL, "kseriod"); | ||
| 949 | if (IS_ERR(serio_task)) { | ||
| 950 | bus_unregister(&serio_bus); | ||
| 951 | error = PTR_ERR(serio_task); | ||
| 952 | printk(KERN_ERR "serio: Failed to start kseriod, error: %d\n", error); | ||
| 953 | return error; | ||
| 954 | } | ||
| 918 | 955 | ||
| 919 | return 0; | 956 | return 0; |
| 920 | } | 957 | } |
