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
41 guard(mutex)(&serio->drv_mutex); in serio_connect_driver()
43 return drv->connect(serio, drv); in serio_connect_driver()
46 static int serio_reconnect_driver(struct serio *serio) in serio_reconnect_driver() argument
48 guard(mutex)(&serio->drv_mutex); in serio_reconnect_driver()
50 if (serio->drv && serio->drv->reconnect) in serio_reconnect_driver()
51 return serio->drv->reconnect(serio); in serio_reconnect_driver()
56 static void serio_disconnect_driver(struct serio *serio) in serio_disconnect_driver() argument
58 guard(mutex)(&serio->drv_mutex); in serio_disconnect_driver()
60 if (serio->drv) in serio_disconnect_driver()
61 serio->drv->disconnect(serio); in serio_disconnect_driver()
64 static int serio_match_port(const struct serio_device_id *ids, struct serio *serio) in serio_match_port() argument
67 if ((ids->type == SERIO_ANY || ids->type == serio->id.type) && in serio_match_port()
68 (ids->proto == SERIO_ANY || ids->proto == serio->id.proto) && in serio_match_port()
69 (ids->extra == SERIO_ANY || ids->extra == serio->id.extra) && in serio_match_port()
70 (ids->id == SERIO_ANY || ids->id == serio->id.id)) in serio_match_port()
78 * Basic serio -> driver core mappings
81 static int serio_bind_driver(struct serio *serio, struct serio_driver *drv) in serio_bind_driver() argument
85 if (serio_match_port(drv->id_table, serio)) { in serio_bind_driver()
87 serio->dev.driver = &drv->driver; in serio_bind_driver()
88 if (serio_connect_driver(serio, drv)) { in serio_bind_driver()
89 serio->dev.driver = NULL; in serio_bind_driver()
93 error = device_bind_driver(&serio->dev); in serio_bind_driver()
95 dev_warn(&serio->dev, in serio_bind_driver()
97 serio->phys, serio->name, in serio_bind_driver()
99 serio_disconnect_driver(serio); in serio_bind_driver()
100 serio->dev.driver = NULL; in serio_bind_driver()
107 static void serio_find_driver(struct serio *serio) in serio_find_driver() argument
111 error = device_attach(&serio->dev); in serio_find_driver()
113 dev_warn(&serio->dev, in serio_find_driver()
115 serio->phys, serio->name, error); in serio_find_driver()
120 * Serio event processing.
232 * Scan event list for the other events for the same serio port, in serio_queue_event()
271 * object, be it serio port or driver.
288 * Locate child serio port (if any) that has not been fully registered yet.
293 static struct serio *serio_get_pending_child(struct serio *parent) in serio_get_pending_child()
296 struct serio *serio; in serio_get_pending_child() local
302 serio = event->object; in serio_get_pending_child()
303 if (serio->parent == parent) in serio_get_pending_child()
304 return serio; in serio_get_pending_child()
312 * Serio port operations
317 struct serio *serio = to_serio_port(dev); in serio_show_description() local
318 return sprintf(buf, "%s\n", serio->name); in serio_show_description()
323 struct serio *serio = to_serio_port(dev); in modalias_show() local
325 return sprintf(buf, "serio:ty%02Xpr%02Xid%02Xex%02X\n", in modalias_show()
326 serio->id.type, serio->id.proto, serio->id.id, serio->id.extra); in modalias_show()
331 struct serio *serio = to_serio_port(dev); in type_show() local
332 return sprintf(buf, "%02x\n", serio->id.type); in type_show()
337 struct serio *serio = to_serio_port(dev); in proto_show() local
338 return sprintf(buf, "%02x\n", serio->id.proto); in proto_show()
343 struct serio *serio = to_serio_port(dev); in id_show() local
344 return sprintf(buf, "%02x\n", serio->id.id); in id_show()
349 struct serio *serio = to_serio_port(dev); in extra_show() local
350 return sprintf(buf, "%02x\n", serio->id.extra); in extra_show()
355 struct serio *serio = to_serio_port(dev); in drvctl_store() local
361 serio_disconnect_port(serio); in drvctl_store()
363 serio_reconnect_subtree(serio); in drvctl_store()
365 serio_disconnect_port(serio); in drvctl_store()
366 serio_find_driver(serio); in drvctl_store()
367 serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT); in drvctl_store()
369 serio_disconnect_port(serio); in drvctl_store()
370 error = serio_bind_driver(serio, to_serio_driver(drv)); in drvctl_store()
371 serio_remove_duplicate_events(serio, SERIO_RESCAN_PORT); in drvctl_store()
384 struct serio *serio = to_serio_port(dev); in serio_show_bind_mode() local
385 return sprintf(buf, "%s\n", serio->manual_bind ? "manual" : "auto"); in serio_show_bind_mode()
390 struct serio *serio = to_serio_port(dev); in serio_set_bind_mode() local
395 serio->manual_bind = true; in serio_set_bind_mode()
397 serio->manual_bind = false; in serio_set_bind_mode()
407 struct serio *serio = to_serio_port(dev); in firmware_id_show() local
409 return sprintf(buf, "%s\n", serio->firmware_id); in firmware_id_show()
457 struct serio *serio = to_serio_port(dev); in serio_release_port() local
459 kfree(serio); in serio_release_port()
464 * Prepare serio port for registration.
466 static void serio_init_port(struct serio *serio) in serio_init_port() argument
472 INIT_LIST_HEAD(&serio->node); in serio_init_port()
473 INIT_LIST_HEAD(&serio->child_node); in serio_init_port()
474 INIT_LIST_HEAD(&serio->children); in serio_init_port()
475 spin_lock_init(&serio->lock); in serio_init_port()
476 mutex_init(&serio->drv_mutex); in serio_init_port()
477 device_initialize(&serio->dev); in serio_init_port()
478 dev_set_name(&serio->dev, "serio%lu", in serio_init_port()
480 serio->dev.bus = &serio_bus; in serio_init_port()
481 serio->dev.release = serio_release_port; in serio_init_port()
482 serio->dev.groups = serio_device_attr_groups; in serio_init_port()
483 if (serio->parent) { in serio_init_port()
484 serio->dev.parent = &serio->parent->dev; in serio_init_port()
485 serio->depth = serio->parent->depth + 1; in serio_init_port()
487 serio->depth = 0; in serio_init_port()
488 lockdep_set_subclass(&serio->lock, serio->depth); in serio_init_port()
492 * Complete serio port registration.
495 static void serio_add_port(struct serio *serio) in serio_add_port() argument
497 struct serio *parent = serio->parent; in serio_add_port()
503 list_add_tail(&serio->child_node, &parent->children); in serio_add_port()
506 list_add_tail(&serio->node, &serio_list); in serio_add_port()
508 if (serio->start) in serio_add_port()
509 serio->start(serio); in serio_add_port()
511 error = device_add(&serio->dev); in serio_add_port()
513 dev_err(&serio->dev, in serio_add_port()
515 serio->phys, serio->name, error); in serio_add_port()
522 static void serio_destroy_port(struct serio *serio) in serio_destroy_port() argument
524 struct serio *child; in serio_destroy_port()
526 while ((child = serio_get_pending_child(serio)) != NULL) { in serio_destroy_port()
531 if (serio->stop) in serio_destroy_port()
532 serio->stop(serio); in serio_destroy_port()
534 if (serio->parent) { in serio_destroy_port()
535 guard(serio_pause_rx)(serio->parent); in serio_destroy_port()
537 list_del_init(&serio->child_node); in serio_destroy_port()
538 serio->parent = NULL; in serio_destroy_port()
541 if (device_is_registered(&serio->dev)) in serio_destroy_port()
542 device_del(&serio->dev); in serio_destroy_port()
544 list_del_init(&serio->node); in serio_destroy_port()
545 serio_remove_pending_events(serio); in serio_destroy_port()
546 put_device(&serio->dev); in serio_destroy_port()
550 * Reconnect serio port (re-initialize attached device).
555 static int serio_reconnect_port(struct serio *serio) in serio_reconnect_port() argument
557 int error = serio_reconnect_driver(serio); in serio_reconnect_port()
560 serio_disconnect_port(serio); in serio_reconnect_port()
561 serio_find_driver(serio); in serio_reconnect_port()
568 * Reconnect serio port and all its children (re-initialize attached
571 static void serio_reconnect_subtree(struct serio *root) in serio_reconnect_subtree()
573 struct serio *s = root; in serio_reconnect_subtree()
585 struct serio, child_node); in serio_reconnect_subtree()
596 struct serio *parent = s->parent; in serio_reconnect_subtree()
600 struct serio, child_node); in serio_reconnect_subtree()
613 static void serio_disconnect_port(struct serio *serio) in serio_disconnect_port() argument
615 struct serio *s = serio; in serio_disconnect_port()
621 while (!list_empty(&serio->children)) { in serio_disconnect_port()
626 struct serio, child_node); in serio_disconnect_port()
632 if (s != serio) { in serio_disconnect_port()
633 struct serio *parent = s->parent; in serio_disconnect_port()
645 device_release_driver(&serio->dev); in serio_disconnect_port()
648 void serio_rescan(struct serio *serio) in serio_rescan() argument
650 serio_queue_event(serio, NULL, SERIO_RESCAN_PORT); in serio_rescan()
654 void serio_reconnect(struct serio *serio) in serio_reconnect() argument
656 serio_queue_event(serio, NULL, SERIO_RECONNECT_SUBTREE); in serio_reconnect()
664 void __serio_register_port(struct serio *serio, struct module *owner) in __serio_register_port() argument
666 serio_init_port(serio); in __serio_register_port()
667 serio_queue_event(serio, owner, SERIO_REGISTER_PORT); in __serio_register_port()
672 * Synchronously unregisters serio port.
674 void serio_unregister_port(struct serio *serio) in serio_unregister_port() argument
678 serio_disconnect_port(serio); in serio_unregister_port()
679 serio_destroy_port(serio); in serio_unregister_port()
686 void serio_unregister_child_port(struct serio *serio) in serio_unregister_child_port() argument
688 struct serio *s, *next; in serio_unregister_child_port()
692 list_for_each_entry_safe(s, next, &serio->children, child_node) { in serio_unregister_child_port()
701 * Serio driver operations
744 struct serio *serio = to_serio_port(dev); in serio_driver_probe() local
747 return serio_connect_driver(serio, drv); in serio_driver_probe()
752 struct serio *serio = to_serio_port(dev); in serio_driver_remove() local
754 serio_disconnect_driver(serio); in serio_driver_remove()
757 static void serio_cleanup(struct serio *serio) in serio_cleanup() argument
759 guard(mutex)(&serio->drv_mutex); in serio_cleanup()
761 if (serio->drv && serio->drv->cleanup) in serio_cleanup()
762 serio->drv->cleanup(serio); in serio_cleanup()
767 struct serio *serio = to_serio_port(dev); in serio_shutdown() local
769 serio_cleanup(serio); in serio_shutdown()
823 struct serio *serio; in serio_unregister_driver() local
831 list_for_each_entry(serio, &serio_list, node) { in serio_unregister_driver()
832 if (serio->drv == drv) { in serio_unregister_driver()
833 serio_disconnect_port(serio); in serio_unregister_driver()
834 serio_find_driver(serio); in serio_unregister_driver()
844 static void serio_set_drv(struct serio *serio, struct serio_driver *drv) in serio_set_drv() argument
846 guard(serio_pause_rx)(serio); in serio_set_drv()
848 serio->drv = drv; in serio_set_drv()
853 struct serio *serio = to_serio_port(dev); in serio_bus_match() local
856 if (serio->manual_bind || serio_drv->manual_bind) in serio_bus_match()
859 return serio_match_port(serio_drv->id_table, serio); in serio_bus_match()
871 const struct serio *serio; in serio_uevent() local
876 serio = to_serio_port(dev); in serio_uevent()
878 SERIO_ADD_UEVENT_VAR("SERIO_TYPE=%02x", serio->id.type); in serio_uevent()
879 SERIO_ADD_UEVENT_VAR("SERIO_PROTO=%02x", serio->id.proto); in serio_uevent()
880 SERIO_ADD_UEVENT_VAR("SERIO_ID=%02x", serio->id.id); in serio_uevent()
881 SERIO_ADD_UEVENT_VAR("SERIO_EXTRA=%02x", serio->id.extra); in serio_uevent()
883 SERIO_ADD_UEVENT_VAR("MODALIAS=serio:ty%02Xpr%02Xid%02Xex%02X", in serio_uevent()
884 serio->id.type, serio->id.proto, serio->id.id, serio->id.extra); in serio_uevent()
886 if (serio->firmware_id[0]) in serio_uevent()
888 serio->firmware_id); in serio_uevent()
897 struct serio *serio = to_serio_port(dev); in serio_suspend() local
899 serio_cleanup(serio); in serio_suspend()
906 struct serio *serio = to_serio_port(dev); in serio_resume() local
909 scoped_guard(mutex, &serio->drv_mutex) { in serio_resume()
910 if (serio->drv && serio->drv->fast_reconnect) { in serio_resume()
911 error = serio->drv->fast_reconnect(serio); in serio_resume()
923 serio_queue_event(serio, NULL, SERIO_RECONNECT_PORT); in serio_resume()
938 int serio_open(struct serio *serio, struct serio_driver *drv) in serio_open() argument
940 serio_set_drv(serio, drv); in serio_open()
942 if (serio->open && serio->open(serio)) { in serio_open()
943 serio_set_drv(serio, NULL); in serio_open()
951 void serio_close(struct serio *serio) in serio_close() argument
953 if (serio->close) in serio_close()
954 serio->close(serio); in serio_close()
956 serio_set_drv(serio, NULL); in serio_close()
960 irqreturn_t serio_interrupt(struct serio *serio, in serio_interrupt() argument
963 guard(spinlock_irqsave)(&serio->lock); in serio_interrupt()
965 if (likely(serio->drv)) in serio_interrupt()
966 return serio->drv->interrupt(serio, data, dfl); in serio_interrupt()
968 if (!dfl && device_is_registered(&serio->dev)) { in serio_interrupt()
969 serio_rescan(serio); in serio_interrupt()
978 .name = "serio",
997 pr_err("Failed to register serio bus, error: %d\n", error); in serio_init()