Lines Matching full:serio

3  *  The Serio abstraction module
14 #include <linux/serio.h>
22 MODULE_DESCRIPTION("Serio abstraction core");
26 * serio_mutex protects entire serio subsystem and is taken every time
27 * serio port or driver registered or unregistered.
33 static void serio_add_port(struct serio *serio);
34 static int serio_reconnect_port(struct serio *serio);
35 static void serio_disconnect_port(struct serio *serio);
36 static void serio_reconnect_subtree(struct serio *serio);
39 static int serio_connect_driver(struct serio *serio, struct serio_driver *drv) in serio_connect_driver() argument
43 mutex_lock(&serio->drv_mutex); in serio_connect_driver()
44 retval = drv->connect(serio, drv); in serio_connect_driver()
45 mutex_unlock(&serio->drv_mutex); in serio_connect_driver()
50 static int serio_reconnect_driver(struct serio *serio) in serio_reconnect_driver() argument
54 mutex_lock(&serio->drv_mutex); in serio_reconnect_driver()
55 if (serio->drv && serio->drv->reconnect) in serio_reconnect_driver()
56 retval = serio->drv->reconnect(serio); in serio_reconnect_driver()
57 mutex_unlock(&serio->drv_mutex); in serio_reconnect_driver()
62 static void serio_disconnect_driver(struct serio *serio) in serio_disconnect_driver() argument
64 mutex_lock(&serio->drv_mutex); in serio_disconnect_driver()
65 if (serio->drv) in serio_disconnect_driver()
66 serio->drv->disconnect(serio); in serio_disconnect_driver()
67 mutex_unlock(&serio->drv_mutex); in serio_disconnect_driver()
70 static int serio_match_port(const struct serio_device_id *ids, struct serio *serio) in serio_match_port() argument
73 if ((ids->type == SERIO_ANY || ids->type == serio->id.type) && in serio_match_port()
74 (ids->proto == SERIO_ANY || ids->proto == serio->id.proto) && in serio_match_port()
75 (ids->extra == SERIO_ANY || ids->extra == serio->id.extra) && in serio_match_port()
76 (ids->id == SERIO_ANY || ids->id == serio->id.id)) in serio_match_port()
84 * Basic serio -> driver core mappings
87 static int serio_bind_driver(struct serio *serio, struct serio_driver *drv) in serio_bind_driver() argument
91 if (serio_match_port(drv->id_table, serio)) { in serio_bind_driver()
93 serio->dev.driver = &drv->driver; in serio_bind_driver()
94 if (serio_connect_driver(serio, drv)) { in serio_bind_driver()
95 serio->dev.driver = NULL; in serio_bind_driver()
99 error = device_bind_driver(&serio->dev); in serio_bind_driver()
101 dev_warn(&serio->dev, in serio_bind_driver()
103 serio->phys, serio->name, in serio_bind_driver()
105 serio_disconnect_driver(serio); in serio_bind_driver()
106 serio->dev.driver = NULL; in serio_bind_driver()
113 static void serio_find_driver(struct serio *serio) in serio_find_driver() argument
117 error = device_attach(&serio->dev); in serio_find_driver()
119 dev_warn(&serio->dev, in serio_find_driver()
121 serio->phys, serio->name, error); in serio_find_driver()
126 * Serio event processing.
247 * Scan event list for the other events for the same serio port, in serio_queue_event()
290 * object, be it serio port or driver.
310 * Locate child serio port (if any) that has not been fully registered yet.
315 static struct serio *serio_get_pending_child(struct serio *parent) in serio_get_pending_child()
318 struct serio *serio, *child = NULL; in serio_get_pending_child() local
325 serio = event->object; in serio_get_pending_child()
326 if (serio->parent == parent) { in serio_get_pending_child()
327 child = serio; in serio_get_pending_child()
338 * Serio port operations
343 struct serio *serio = to_serio_port(dev); in serio_show_description() local
344 return sprintf(buf, "%s\n", serio->name); in serio_show_description()
349 struct serio *serio = to_serio_port(dev); in modalias_show() local
351 return sprintf(buf, "serio:ty%02Xpr%02Xid%02Xex%02X\n", in modalias_show()
352 serio->id.type, serio->id.proto, serio->id.id, serio->id.extra); in modalias_show()
357 struct serio *serio = to_serio_port(dev); in type_show() local
358 return sprintf(buf, "%02x\n", serio->id.type); in type_show()
363 struct serio *serio = to_serio_port(dev); in proto_show() local
364 return sprintf(buf, "%02x\n", serio->id.proto); in proto_show()
369 struct serio *serio = to_serio_port(dev); in id_show() local
370 return sprintf(buf, "%02x\n", serio->id.id); in id_show()
375 struct serio *serio = to_serio_port(dev); in extra_show() local
376 return sprintf(buf, "%02x\n", serio->id.extra); in extra_show()
381 struct serio *serio = to_serio_port(dev); in drvctl_store() local
390 serio_disconnect_port(serio); in drvctl_store()
392 serio_reconnect_subtree(serio); in drvctl_store()
394 serio_disconnect_port(serio); in drvctl_store()
395 serio_find_driver(serio); in drvctl_store()
396 serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT); in drvctl_store()
398 serio_disconnect_port(serio); in drvctl_store()
399 error = serio_bind_driver(serio, to_serio_driver(drv)); in drvctl_store()
400 serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT); in drvctl_store()
412 struct serio *serio = to_serio_port(dev); in serio_show_bind_mode() local
413 return sprintf(buf, "%s\n", serio->manual_bind ? "manual" : "auto"); in serio_show_bind_mode()
418 struct serio *serio = to_serio_port(dev); in serio_set_bind_mode() local
423 serio->manual_bind = true; in serio_set_bind_mode()
425 serio->manual_bind = false; in serio_set_bind_mode()
435 struct serio *serio = to_serio_port(dev); in firmware_id_show() local
437 return sprintf(buf, "%s\n", serio->firmware_id); in firmware_id_show()
485 struct serio *serio = to_serio_port(dev); in serio_release_port() local
487 kfree(serio); in serio_release_port()
492 * Prepare serio port for registration.
494 static void serio_init_port(struct serio *serio) in serio_init_port() argument
500 INIT_LIST_HEAD(&serio->node); in serio_init_port()
501 INIT_LIST_HEAD(&serio->child_node); in serio_init_port()
502 INIT_LIST_HEAD(&serio->children); in serio_init_port()
503 spin_lock_init(&serio->lock); in serio_init_port()
504 mutex_init(&serio->drv_mutex); in serio_init_port()
505 device_initialize(&serio->dev); in serio_init_port()
506 dev_set_name(&serio->dev, "serio%lu", in serio_init_port()
508 serio->dev.bus = &serio_bus; in serio_init_port()
509 serio->dev.release = serio_release_port; in serio_init_port()
510 serio->dev.groups = serio_device_attr_groups; in serio_init_port()
511 if (serio->parent) { in serio_init_port()
512 serio->dev.parent = &serio->parent->dev; in serio_init_port()
513 serio->depth = serio->parent->depth + 1; in serio_init_port()
515 serio->depth = 0; in serio_init_port()
516 lockdep_set_subclass(&serio->lock, serio->depth); in serio_init_port()
520 * Complete serio port registration.
523 static void serio_add_port(struct serio *serio) in serio_add_port() argument
525 struct serio *parent = serio->parent; in serio_add_port()
530 list_add_tail(&serio->child_node, &parent->children); in serio_add_port()
534 list_add_tail(&serio->node, &serio_list); in serio_add_port()
536 if (serio->start) in serio_add_port()
537 serio->start(serio); in serio_add_port()
539 error = device_add(&serio->dev); in serio_add_port()
541 dev_err(&serio->dev, in serio_add_port()
543 serio->phys, serio->name, error); in serio_add_port()
550 static void serio_destroy_port(struct serio *serio) in serio_destroy_port() argument
552 struct serio *child; in serio_destroy_port()
554 while ((child = serio_get_pending_child(serio)) != NULL) { in serio_destroy_port()
559 if (serio->stop) in serio_destroy_port()
560 serio->stop(serio); in serio_destroy_port()
562 if (serio->parent) { in serio_destroy_port()
563 serio_pause_rx(serio->parent); in serio_destroy_port()
564 list_del_init(&serio->child_node); in serio_destroy_port()
565 serio_continue_rx(serio->parent); in serio_destroy_port()
566 serio->parent = NULL; in serio_destroy_port()
569 if (device_is_registered(&serio->dev)) in serio_destroy_port()
570 device_del(&serio->dev); in serio_destroy_port()
572 list_del_init(&serio->node); in serio_destroy_port()
573 serio_remove_pending_events(serio); in serio_destroy_port()
574 put_device(&serio->dev); in serio_destroy_port()
578 * Reconnect serio port (re-initialize attached device).
583 static int serio_reconnect_port(struct serio *serio) in serio_reconnect_port() argument
585 int error = serio_reconnect_driver(serio); in serio_reconnect_port()
588 serio_disconnect_port(serio); in serio_reconnect_port()
589 serio_find_driver(serio); in serio_reconnect_port()
596 * Reconnect serio port and all its children (re-initialize attached
599 static void serio_reconnect_subtree(struct serio *root) in serio_reconnect_subtree()
601 struct serio *s = root; in serio_reconnect_subtree()
613 struct serio, child_node); in serio_reconnect_subtree()
624 struct serio *parent = s->parent; in serio_reconnect_subtree()
628 struct serio, child_node); in serio_reconnect_subtree()
641 static void serio_disconnect_port(struct serio *serio) in serio_disconnect_port() argument
643 struct serio *s = serio; in serio_disconnect_port()
649 while (!list_empty(&serio->children)) { in serio_disconnect_port()
654 struct serio, child_node); in serio_disconnect_port()
660 if (s != serio) { in serio_disconnect_port()
661 struct serio *parent = s->parent; in serio_disconnect_port()
673 device_release_driver(&serio->dev); in serio_disconnect_port()
676 void serio_rescan(struct serio *serio) in serio_rescan() argument
678 serio_queue_event(serio, NULL, SERIO_RESCAN_PORT); in serio_rescan()
682 void serio_reconnect(struct serio *serio) in serio_reconnect() argument
684 serio_queue_event(serio, NULL, SERIO_RECONNECT_SUBTREE); in serio_reconnect()
692 void __serio_register_port(struct serio *serio, struct module *owner) in __serio_register_port() argument
694 serio_init_port(serio); in __serio_register_port()
695 serio_queue_event(serio, owner, SERIO_REGISTER_PORT); in __serio_register_port()
700 * Synchronously unregisters serio port.
702 void serio_unregister_port(struct serio *serio) in serio_unregister_port() argument
705 serio_disconnect_port(serio); in serio_unregister_port()
706 serio_destroy_port(serio); in serio_unregister_port()
714 void serio_unregister_child_port(struct serio *serio) in serio_unregister_child_port() argument
716 struct serio *s, *next; in serio_unregister_child_port()
719 list_for_each_entry_safe(s, next, &serio->children, child_node) { in serio_unregister_child_port()
729 * Serio driver operations
772 struct serio *serio = to_serio_port(dev); in serio_driver_probe() local
775 return serio_connect_driver(serio, drv); in serio_driver_probe()
780 struct serio *serio = to_serio_port(dev); in serio_driver_remove() local
782 serio_disconnect_driver(serio); in serio_driver_remove()
785 static void serio_cleanup(struct serio *serio) in serio_cleanup() argument
787 mutex_lock(&serio->drv_mutex); in serio_cleanup()
788 if (serio->drv && serio->drv->cleanup) in serio_cleanup()
789 serio->drv->cleanup(serio); in serio_cleanup()
790 mutex_unlock(&serio->drv_mutex); in serio_cleanup()
795 struct serio *serio = to_serio_port(dev); in serio_shutdown() local
797 serio_cleanup(serio); in serio_shutdown()
851 struct serio *serio; in serio_unregister_driver() local
859 list_for_each_entry(serio, &serio_list, node) { in serio_unregister_driver()
860 if (serio->drv == drv) { in serio_unregister_driver()
861 serio_disconnect_port(serio); in serio_unregister_driver()
862 serio_find_driver(serio); in serio_unregister_driver()
873 static void serio_set_drv(struct serio *serio, struct serio_driver *drv) in serio_set_drv() argument
875 serio_pause_rx(serio); in serio_set_drv()
876 serio->drv = drv; in serio_set_drv()
877 serio_continue_rx(serio); in serio_set_drv()
882 struct serio *serio = to_serio_port(dev); in serio_bus_match() local
885 if (serio->manual_bind || serio_drv->manual_bind) in serio_bus_match()
888 return serio_match_port(serio_drv->id_table, serio); in serio_bus_match()
900 const struct serio *serio; in serio_uevent() local
905 serio = to_serio_port(dev); in serio_uevent()
907 SERIO_ADD_UEVENT_VAR("SERIO_TYPE=%02x", serio->id.type); in serio_uevent()
908 SERIO_ADD_UEVENT_VAR("SERIO_PROTO=%02x", serio->id.proto); in serio_uevent()
909 SERIO_ADD_UEVENT_VAR("SERIO_ID=%02x", serio->id.id); in serio_uevent()
910 SERIO_ADD_UEVENT_VAR("SERIO_EXTRA=%02x", serio->id.extra); in serio_uevent()
912 SERIO_ADD_UEVENT_VAR("MODALIAS=serio:ty%02Xpr%02Xid%02Xex%02X", in serio_uevent()
913 serio->id.type, serio->id.proto, serio->id.id, serio->id.extra); in serio_uevent()
915 if (serio->firmware_id[0]) in serio_uevent()
917 serio->firmware_id); in serio_uevent()
926 struct serio *serio = to_serio_port(dev); in serio_suspend() local
928 serio_cleanup(serio); in serio_suspend()
935 struct serio *serio = to_serio_port(dev); in serio_resume() local
938 mutex_lock(&serio->drv_mutex); in serio_resume()
939 if (serio->drv && serio->drv->fast_reconnect) { in serio_resume()
940 error = serio->drv->fast_reconnect(serio); in serio_resume()
945 mutex_unlock(&serio->drv_mutex); in serio_resume()
952 serio_queue_event(serio, NULL, SERIO_RECONNECT_PORT); in serio_resume()
967 int serio_open(struct serio *serio, struct serio_driver *drv) in serio_open() argument
969 serio_set_drv(serio, drv); in serio_open()
971 if (serio->open && serio->open(serio)) { in serio_open()
972 serio_set_drv(serio, NULL); in serio_open()
980 void serio_close(struct serio *serio) in serio_close() argument
982 if (serio->close) in serio_close()
983 serio->close(serio); in serio_close()
985 serio_set_drv(serio, NULL); in serio_close()
989 irqreturn_t serio_interrupt(struct serio *serio, in serio_interrupt() argument
995 spin_lock_irqsave(&serio->lock, flags); in serio_interrupt()
997 if (likely(serio->drv)) { in serio_interrupt()
998 ret = serio->drv->interrupt(serio, data, dfl); in serio_interrupt()
999 } else if (!dfl && device_is_registered(&serio->dev)) { in serio_interrupt()
1000 serio_rescan(serio); in serio_interrupt()
1004 spin_unlock_irqrestore(&serio->lock, flags); in serio_interrupt()
1011 .name = "serio",
1030 pr_err("Failed to register serio bus, error: %d\n", error); in serio_init()