Lines Matching refs:serio
54 static void serio_add_port(struct serio *serio);
55 static int serio_reconnect_port(struct serio *serio);
56 static void serio_disconnect_port(struct serio *serio);
57 static void serio_reconnect_subtree(struct serio *serio);
60 static int serio_connect_driver(struct serio *serio, struct serio_driver *drv) in serio_connect_driver() argument
64 mutex_lock(&serio->drv_mutex); in serio_connect_driver()
65 retval = drv->connect(serio, drv); in serio_connect_driver()
66 mutex_unlock(&serio->drv_mutex); in serio_connect_driver()
71 static int serio_reconnect_driver(struct serio *serio) in serio_reconnect_driver() argument
75 mutex_lock(&serio->drv_mutex); in serio_reconnect_driver()
76 if (serio->drv && serio->drv->reconnect) in serio_reconnect_driver()
77 retval = serio->drv->reconnect(serio); in serio_reconnect_driver()
78 mutex_unlock(&serio->drv_mutex); in serio_reconnect_driver()
83 static void serio_disconnect_driver(struct serio *serio) in serio_disconnect_driver() argument
85 mutex_lock(&serio->drv_mutex); in serio_disconnect_driver()
86 if (serio->drv) in serio_disconnect_driver()
87 serio->drv->disconnect(serio); in serio_disconnect_driver()
88 mutex_unlock(&serio->drv_mutex); in serio_disconnect_driver()
91 static int serio_match_port(const struct serio_device_id *ids, struct serio *serio) in serio_match_port() argument
94 if ((ids->type == SERIO_ANY || ids->type == serio->id.type) && in serio_match_port()
95 (ids->proto == SERIO_ANY || ids->proto == serio->id.proto) && in serio_match_port()
96 (ids->extra == SERIO_ANY || ids->extra == serio->id.extra) && in serio_match_port()
97 (ids->id == SERIO_ANY || ids->id == serio->id.id)) in serio_match_port()
108 static int serio_bind_driver(struct serio *serio, struct serio_driver *drv) in serio_bind_driver() argument
112 if (serio_match_port(drv->id_table, serio)) { in serio_bind_driver()
114 serio->dev.driver = &drv->driver; in serio_bind_driver()
115 if (serio_connect_driver(serio, drv)) { in serio_bind_driver()
116 serio->dev.driver = NULL; in serio_bind_driver()
120 error = device_bind_driver(&serio->dev); in serio_bind_driver()
122 dev_warn(&serio->dev, in serio_bind_driver()
124 serio->phys, serio->name, in serio_bind_driver()
126 serio_disconnect_driver(serio); in serio_bind_driver()
127 serio->dev.driver = NULL; in serio_bind_driver()
134 static void serio_find_driver(struct serio *serio) in serio_find_driver() argument
138 error = device_attach(&serio->dev); in serio_find_driver()
140 dev_warn(&serio->dev, in serio_find_driver()
142 serio->phys, serio->name, error); in serio_find_driver()
336 static struct serio *serio_get_pending_child(struct serio *parent) in serio_get_pending_child()
339 struct serio *serio, *child = NULL; in serio_get_pending_child() local
346 serio = event->object; in serio_get_pending_child()
347 if (serio->parent == parent) { in serio_get_pending_child()
348 child = serio; in serio_get_pending_child()
364 struct serio *serio = to_serio_port(dev); in serio_show_description() local
365 return sprintf(buf, "%s\n", serio->name); in serio_show_description()
370 struct serio *serio = to_serio_port(dev); in serio_show_modalias() local
373 serio->id.type, serio->id.proto, serio->id.id, serio->id.extra); in serio_show_modalias()
378 struct serio *serio = to_serio_port(dev); in serio_show_id_type() local
379 return sprintf(buf, "%02x\n", serio->id.type); in serio_show_id_type()
384 struct serio *serio = to_serio_port(dev); in serio_show_id_proto() local
385 return sprintf(buf, "%02x\n", serio->id.proto); in serio_show_id_proto()
390 struct serio *serio = to_serio_port(dev); in serio_show_id_id() local
391 return sprintf(buf, "%02x\n", serio->id.id); in serio_show_id_id()
396 struct serio *serio = to_serio_port(dev); in serio_show_id_extra() local
397 return sprintf(buf, "%02x\n", serio->id.extra); in serio_show_id_extra()
425 struct serio *serio = to_serio_port(dev); in serio_rebind_driver() local
434 serio_disconnect_port(serio); in serio_rebind_driver()
436 serio_reconnect_subtree(serio); in serio_rebind_driver()
438 serio_disconnect_port(serio); in serio_rebind_driver()
439 serio_find_driver(serio); in serio_rebind_driver()
440 serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT); in serio_rebind_driver()
442 serio_disconnect_port(serio); in serio_rebind_driver()
443 error = serio_bind_driver(serio, to_serio_driver(drv)); in serio_rebind_driver()
444 serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT); in serio_rebind_driver()
456 struct serio *serio = to_serio_port(dev); in serio_show_bind_mode() local
457 return sprintf(buf, "%s\n", serio->manual_bind ? "manual" : "auto"); in serio_show_bind_mode()
462 struct serio *serio = to_serio_port(dev); in serio_set_bind_mode() local
467 serio->manual_bind = true; in serio_set_bind_mode()
469 serio->manual_bind = false; in serio_set_bind_mode()
488 struct serio *serio = to_serio_port(dev); in serio_release_port() local
490 kfree(serio); in serio_release_port()
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%ld", 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()
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()
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()
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()
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()
774 struct serio *serio = to_serio_port(dev); in serio_driver_probe() local
777 return serio_connect_driver(serio, drv); in serio_driver_probe()
782 struct serio *serio = to_serio_port(dev); in serio_driver_remove() local
784 serio_disconnect_driver(serio); in serio_driver_remove()
788 static void serio_cleanup(struct serio *serio) in serio_cleanup() argument
790 mutex_lock(&serio->drv_mutex); in serio_cleanup()
791 if (serio->drv && serio->drv->cleanup) in serio_cleanup()
792 serio->drv->cleanup(serio); in serio_cleanup()
793 mutex_unlock(&serio->drv_mutex); in serio_cleanup()
798 struct serio *serio = to_serio_port(dev); in serio_shutdown() local
800 serio_cleanup(serio); in serio_shutdown()
854 struct serio *serio; in serio_unregister_driver() local
862 list_for_each_entry(serio, &serio_list, node) { in serio_unregister_driver()
863 if (serio->drv == drv) { in serio_unregister_driver()
864 serio_disconnect_port(serio); in serio_unregister_driver()
865 serio_find_driver(serio); in serio_unregister_driver()
876 static void serio_set_drv(struct serio *serio, struct serio_driver *drv) in serio_set_drv() argument
878 serio_pause_rx(serio); in serio_set_drv()
879 serio->drv = drv; in serio_set_drv()
880 serio_continue_rx(serio); in serio_set_drv()
885 struct serio *serio = to_serio_port(dev); in serio_bus_match() local
888 if (serio->manual_bind || serio_drv->manual_bind) in serio_bus_match()
891 return serio_match_port(serio_drv->id_table, serio); in serio_bus_match()
903 struct serio *serio; in serio_uevent() local
908 serio = to_serio_port(dev); in serio_uevent()
910 SERIO_ADD_UEVENT_VAR("SERIO_TYPE=%02x", serio->id.type); in serio_uevent()
911 SERIO_ADD_UEVENT_VAR("SERIO_PROTO=%02x", serio->id.proto); in serio_uevent()
912 SERIO_ADD_UEVENT_VAR("SERIO_ID=%02x", serio->id.id); in serio_uevent()
913 SERIO_ADD_UEVENT_VAR("SERIO_EXTRA=%02x", serio->id.extra); in serio_uevent()
915 serio->id.type, serio->id.proto, serio->id.id, serio->id.extra); in serio_uevent()
924 struct serio *serio = to_serio_port(dev); in serio_suspend() local
926 serio_cleanup(serio); in serio_suspend()
933 struct serio *serio = to_serio_port(dev); in serio_resume() local
939 serio_queue_event(serio, NULL, SERIO_RECONNECT_PORT); in serio_resume()
953 int serio_open(struct serio *serio, struct serio_driver *drv) in serio_open() argument
955 serio_set_drv(serio, drv); in serio_open()
957 if (serio->open && serio->open(serio)) { in serio_open()
958 serio_set_drv(serio, NULL); in serio_open()
966 void serio_close(struct serio *serio) in serio_close() argument
968 if (serio->close) in serio_close()
969 serio->close(serio); in serio_close()
971 serio_set_drv(serio, NULL); in serio_close()
975 irqreturn_t serio_interrupt(struct serio *serio, in serio_interrupt() argument
981 spin_lock_irqsave(&serio->lock, flags); in serio_interrupt()
983 if (likely(serio->drv)) { in serio_interrupt()
984 ret = serio->drv->interrupt(serio, data, dfl); in serio_interrupt()
985 } else if (!dfl && device_is_registered(&serio->dev)) { in serio_interrupt()
986 serio_rescan(serio); in serio_interrupt()
990 spin_unlock_irqrestore(&serio->lock, flags); in serio_interrupt()