Lines Matching full:serio
3 * The Serio abstraction module
17 #include <linux/serio.h>
25 MODULE_DESCRIPTION("Serio abstraction core");
29 * serio_mutex protects entire serio subsystem and is taken every time
30 * serio port or driver registered or unregistered.
36 static void serio_add_port(struct serio *serio);
37 static int serio_reconnect_port(struct serio *serio);
38 static void serio_disconnect_port(struct serio *serio);
39 static void serio_reconnect_subtree(struct serio *serio);
42 static int serio_connect_driver(struct serio *serio, struct serio_driver *drv) in serio_connect_driver() argument
46 mutex_lock(&serio->drv_mutex); in serio_connect_driver()
47 retval = drv->connect(serio, drv); in serio_connect_driver()
48 mutex_unlock(&serio->drv_mutex); in serio_connect_driver()
53 static int serio_reconnect_driver(struct serio *serio) in serio_reconnect_driver() argument
57 mutex_lock(&serio->drv_mutex); in serio_reconnect_driver()
58 if (serio->drv && serio->drv->reconnect) in serio_reconnect_driver()
59 retval = serio->drv->reconnect(serio); in serio_reconnect_driver()
60 mutex_unlock(&serio->drv_mutex); in serio_reconnect_driver()
65 static void serio_disconnect_driver(struct serio *serio) in serio_disconnect_driver() argument
67 mutex_lock(&serio->drv_mutex); in serio_disconnect_driver()
68 if (serio->drv) in serio_disconnect_driver()
69 serio->drv->disconnect(serio); in serio_disconnect_driver()
70 mutex_unlock(&serio->drv_mutex); in serio_disconnect_driver()
73 static int serio_match_port(const struct serio_device_id *ids, struct serio *serio) in serio_match_port() argument
76 if ((ids->type == SERIO_ANY || ids->type == serio->id.type) && in serio_match_port()
77 (ids->proto == SERIO_ANY || ids->proto == serio->id.proto) && in serio_match_port()
78 (ids->extra == SERIO_ANY || ids->extra == serio->id.extra) && in serio_match_port()
79 (ids->id == SERIO_ANY || ids->id == serio->id.id)) in serio_match_port()
87 * Basic serio -> driver core mappings
90 static int serio_bind_driver(struct serio *serio, struct serio_driver *drv) in serio_bind_driver() argument
94 if (serio_match_port(drv->id_table, serio)) { in serio_bind_driver()
96 serio->dev.driver = &drv->driver; in serio_bind_driver()
97 if (serio_connect_driver(serio, drv)) { in serio_bind_driver()
98 serio->dev.driver = NULL; in serio_bind_driver()
102 error = device_bind_driver(&serio->dev); in serio_bind_driver()
104 dev_warn(&serio->dev, in serio_bind_driver()
106 serio->phys, serio->name, in serio_bind_driver()
108 serio_disconnect_driver(serio); in serio_bind_driver()
109 serio->dev.driver = NULL; in serio_bind_driver()
116 static void serio_find_driver(struct serio *serio) in serio_find_driver() argument
120 error = device_attach(&serio->dev); in serio_find_driver()
122 dev_warn(&serio->dev, in serio_find_driver()
124 serio->phys, serio->name, error); in serio_find_driver()
129 * Serio event processing.
250 * Scan event list for the other events for the same serio port, in serio_queue_event()
293 * object, be it serio port or driver.
313 * Locate child serio port (if any) that has not been fully registered yet.
318 static struct serio *serio_get_pending_child(struct serio *parent) in serio_get_pending_child()
321 struct serio *serio, *child = NULL; in serio_get_pending_child() local
328 serio = event->object; in serio_get_pending_child()
329 if (serio->parent == parent) { in serio_get_pending_child()
330 child = serio; in serio_get_pending_child()
341 * Serio port operations
346 struct serio *serio = to_serio_port(dev); in serio_show_description() local
347 return sprintf(buf, "%s\n", serio->name); in serio_show_description()
352 struct serio *serio = to_serio_port(dev); in modalias_show() local
354 return sprintf(buf, "serio:ty%02Xpr%02Xid%02Xex%02X\n", in modalias_show()
355 serio->id.type, serio->id.proto, serio->id.id, serio->id.extra); in modalias_show()
360 struct serio *serio = to_serio_port(dev); in type_show() local
361 return sprintf(buf, "%02x\n", serio->id.type); in type_show()
366 struct serio *serio = to_serio_port(dev); in proto_show() local
367 return sprintf(buf, "%02x\n", serio->id.proto); in proto_show()
372 struct serio *serio = to_serio_port(dev); in id_show() local
373 return sprintf(buf, "%02x\n", serio->id.id); in id_show()
378 struct serio *serio = to_serio_port(dev); in extra_show() local
379 return sprintf(buf, "%02x\n", serio->id.extra); in extra_show()
384 struct serio *serio = to_serio_port(dev); in drvctl_store() local
393 serio_disconnect_port(serio); in drvctl_store()
395 serio_reconnect_subtree(serio); in drvctl_store()
397 serio_disconnect_port(serio); in drvctl_store()
398 serio_find_driver(serio); in drvctl_store()
399 serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT); in drvctl_store()
401 serio_disconnect_port(serio); in drvctl_store()
402 error = serio_bind_driver(serio, to_serio_driver(drv)); in drvctl_store()
403 serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT); in drvctl_store()
415 struct serio *serio = to_serio_port(dev); in serio_show_bind_mode() local
416 return sprintf(buf, "%s\n", serio->manual_bind ? "manual" : "auto"); in serio_show_bind_mode()
421 struct serio *serio = to_serio_port(dev); in serio_set_bind_mode() local
426 serio->manual_bind = true; in serio_set_bind_mode()
428 serio->manual_bind = false; in serio_set_bind_mode()
438 struct serio *serio = to_serio_port(dev); in firmware_id_show() local
440 return sprintf(buf, "%s\n", serio->firmware_id); in firmware_id_show()
488 struct serio *serio = to_serio_port(dev); in serio_release_port() local
490 kfree(serio); in serio_release_port()
495 * Prepare serio port for registration.
497 static void serio_init_port(struct serio *serio) in serio_init_port() argument
503 INIT_LIST_HEAD(&serio->node); in serio_init_port()
504 INIT_LIST_HEAD(&serio->child_node); in serio_init_port()
505 INIT_LIST_HEAD(&serio->children); in serio_init_port()
506 spin_lock_init(&serio->lock); in serio_init_port()
507 mutex_init(&serio->drv_mutex); in serio_init_port()
508 device_initialize(&serio->dev); in serio_init_port()
509 dev_set_name(&serio->dev, "serio%lu", in serio_init_port()
511 serio->dev.bus = &serio_bus; in serio_init_port()
512 serio->dev.release = serio_release_port; in serio_init_port()
513 serio->dev.groups = serio_device_attr_groups; in serio_init_port()
514 if (serio->parent) { in serio_init_port()
515 serio->dev.parent = &serio->parent->dev; in serio_init_port()
516 serio->depth = serio->parent->depth + 1; in serio_init_port()
518 serio->depth = 0; in serio_init_port()
519 lockdep_set_subclass(&serio->lock, serio->depth); in serio_init_port()
523 * Complete serio port registration.
526 static void serio_add_port(struct serio *serio) in serio_add_port() argument
528 struct serio *parent = serio->parent; in serio_add_port()
533 list_add_tail(&serio->child_node, &parent->children); in serio_add_port()
537 list_add_tail(&serio->node, &serio_list); in serio_add_port()
539 if (serio->start) in serio_add_port()
540 serio->start(serio); in serio_add_port()
542 error = device_add(&serio->dev); in serio_add_port()
544 dev_err(&serio->dev, in serio_add_port()
546 serio->phys, serio->name, error); in serio_add_port()
553 static void serio_destroy_port(struct serio *serio) in serio_destroy_port() argument
555 struct serio *child; in serio_destroy_port()
557 while ((child = serio_get_pending_child(serio)) != NULL) { in serio_destroy_port()
562 if (serio->stop) in serio_destroy_port()
563 serio->stop(serio); in serio_destroy_port()
565 if (serio->parent) { in serio_destroy_port()
566 serio_pause_rx(serio->parent); in serio_destroy_port()
567 list_del_init(&serio->child_node); in serio_destroy_port()
568 serio_continue_rx(serio->parent); in serio_destroy_port()
569 serio->parent = NULL; in serio_destroy_port()
572 if (device_is_registered(&serio->dev)) in serio_destroy_port()
573 device_del(&serio->dev); in serio_destroy_port()
575 list_del_init(&serio->node); in serio_destroy_port()
576 serio_remove_pending_events(serio); in serio_destroy_port()
577 put_device(&serio->dev); in serio_destroy_port()
581 * Reconnect serio port (re-initialize attached device).
586 static int serio_reconnect_port(struct serio *serio) in serio_reconnect_port() argument
588 int error = serio_reconnect_driver(serio); in serio_reconnect_port()
591 serio_disconnect_port(serio); in serio_reconnect_port()
592 serio_find_driver(serio); in serio_reconnect_port()
599 * Reconnect serio port and all its children (re-initialize attached
602 static void serio_reconnect_subtree(struct serio *root) in serio_reconnect_subtree()
604 struct serio *s = root; in serio_reconnect_subtree()
616 struct serio, child_node); in serio_reconnect_subtree()
627 struct serio *parent = s->parent; in serio_reconnect_subtree()
631 struct serio, child_node); in serio_reconnect_subtree()
644 static void serio_disconnect_port(struct serio *serio) in serio_disconnect_port() argument
646 struct serio *s = serio; in serio_disconnect_port()
652 while (!list_empty(&serio->children)) { in serio_disconnect_port()
657 struct serio, child_node); in serio_disconnect_port()
663 if (s != serio) { in serio_disconnect_port()
664 struct serio *parent = s->parent; in serio_disconnect_port()
676 device_release_driver(&serio->dev); in serio_disconnect_port()
679 void serio_rescan(struct serio *serio) in serio_rescan() argument
681 serio_queue_event(serio, NULL, SERIO_RESCAN_PORT); in serio_rescan()
685 void serio_reconnect(struct serio *serio) in serio_reconnect() argument
687 serio_queue_event(serio, NULL, SERIO_RECONNECT_SUBTREE); in serio_reconnect()
695 void __serio_register_port(struct serio *serio, struct module *owner) in __serio_register_port() argument
697 serio_init_port(serio); in __serio_register_port()
698 serio_queue_event(serio, owner, SERIO_REGISTER_PORT); in __serio_register_port()
703 * Synchronously unregisters serio port.
705 void serio_unregister_port(struct serio *serio) in serio_unregister_port() argument
708 serio_disconnect_port(serio); in serio_unregister_port()
709 serio_destroy_port(serio); in serio_unregister_port()
717 void serio_unregister_child_port(struct serio *serio) in serio_unregister_child_port() argument
719 struct serio *s, *next; in serio_unregister_child_port()
722 list_for_each_entry_safe(s, next, &serio->children, child_node) { in serio_unregister_child_port()
732 * Serio driver operations
775 struct serio *serio = to_serio_port(dev); in serio_driver_probe() local
778 return serio_connect_driver(serio, drv); in serio_driver_probe()
783 struct serio *serio = to_serio_port(dev); in serio_driver_remove() local
785 serio_disconnect_driver(serio); in serio_driver_remove()
789 static void serio_cleanup(struct serio *serio) in serio_cleanup() argument
791 mutex_lock(&serio->drv_mutex); in serio_cleanup()
792 if (serio->drv && serio->drv->cleanup) in serio_cleanup()
793 serio->drv->cleanup(serio); in serio_cleanup()
794 mutex_unlock(&serio->drv_mutex); in serio_cleanup()
799 struct serio *serio = to_serio_port(dev); in serio_shutdown() local
801 serio_cleanup(serio); in serio_shutdown()
855 struct serio *serio; in serio_unregister_driver() local
863 list_for_each_entry(serio, &serio_list, node) { in serio_unregister_driver()
864 if (serio->drv == drv) { in serio_unregister_driver()
865 serio_disconnect_port(serio); in serio_unregister_driver()
866 serio_find_driver(serio); in serio_unregister_driver()
877 static void serio_set_drv(struct serio *serio, struct serio_driver *drv) in serio_set_drv() argument
879 serio_pause_rx(serio); in serio_set_drv()
880 serio->drv = drv; in serio_set_drv()
881 serio_continue_rx(serio); in serio_set_drv()
886 struct serio *serio = to_serio_port(dev); in serio_bus_match() local
889 if (serio->manual_bind || serio_drv->manual_bind) in serio_bus_match()
892 return serio_match_port(serio_drv->id_table, serio); in serio_bus_match()
904 struct serio *serio; in serio_uevent() local
909 serio = to_serio_port(dev); in serio_uevent()
911 SERIO_ADD_UEVENT_VAR("SERIO_TYPE=%02x", serio->id.type); in serio_uevent()
912 SERIO_ADD_UEVENT_VAR("SERIO_PROTO=%02x", serio->id.proto); in serio_uevent()
913 SERIO_ADD_UEVENT_VAR("SERIO_ID=%02x", serio->id.id); in serio_uevent()
914 SERIO_ADD_UEVENT_VAR("SERIO_EXTRA=%02x", serio->id.extra); in serio_uevent()
916 SERIO_ADD_UEVENT_VAR("MODALIAS=serio:ty%02Xpr%02Xid%02Xex%02X", in serio_uevent()
917 serio->id.type, serio->id.proto, serio->id.id, serio->id.extra); in serio_uevent()
919 if (serio->firmware_id[0]) in serio_uevent()
921 serio->firmware_id); in serio_uevent()
930 struct serio *serio = to_serio_port(dev); in serio_suspend() local
932 serio_cleanup(serio); in serio_suspend()
939 struct serio *serio = to_serio_port(dev); in serio_resume() local
942 mutex_lock(&serio->drv_mutex); in serio_resume()
943 if (serio->drv && serio->drv->fast_reconnect) { in serio_resume()
944 error = serio->drv->fast_reconnect(serio); in serio_resume()
949 mutex_unlock(&serio->drv_mutex); in serio_resume()
956 serio_queue_event(serio, NULL, SERIO_RECONNECT_PORT); in serio_resume()
971 int serio_open(struct serio *serio, struct serio_driver *drv) in serio_open() argument
973 serio_set_drv(serio, drv); in serio_open()
975 if (serio->open && serio->open(serio)) { in serio_open()
976 serio_set_drv(serio, NULL); in serio_open()
984 void serio_close(struct serio *serio) in serio_close() argument
986 if (serio->close) in serio_close()
987 serio->close(serio); in serio_close()
989 serio_set_drv(serio, NULL); in serio_close()
993 irqreturn_t serio_interrupt(struct serio *serio, in serio_interrupt() argument
999 spin_lock_irqsave(&serio->lock, flags); in serio_interrupt()
1001 if (likely(serio->drv)) { in serio_interrupt()
1002 ret = serio->drv->interrupt(serio, data, dfl); in serio_interrupt()
1003 } else if (!dfl && device_is_registered(&serio->dev)) { in serio_interrupt()
1004 serio_rescan(serio); in serio_interrupt()
1008 spin_unlock_irqrestore(&serio->lock, flags); in serio_interrupt()
1015 .name = "serio",
1034 pr_err("Failed to register serio bus, error: %d\n", error); in serio_init()