Lines Matching +full:drv +full:- +full:id
1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * Copyright (c) 1999-2004 Vojtech Pavlik
37 static void serio_attach_driver(struct serio_driver *drv);
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()
52 int retval = -1; in serio_reconnect_driver()
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()
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()
72 while (ids->type || ids->proto) { in serio_match_port()
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()
96 return -ENODEV; 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()
104 drv->description, error); in serio_bind_driver()
106 serio->dev.driver = NULL; in serio_bind_driver()
117 error = device_attach(&serio->dev); in serio_find_driver()
118 if (error < 0 && error != -EPROBE_DEFER) in serio_find_driver()
119 dev_warn(&serio->dev, in serio_find_driver()
121 serio->phys, serio->name, error); in serio_find_driver()
157 list_del_init(&event->node); in serio_get_event()
166 module_put(event->owner); in serio_free_event()
179 if (object == e->object) { in serio_remove_duplicate_events()
182 * look further - we only suppress duplicate events in serio_remove_duplicate_events()
183 * that were sent back-to-back. in serio_remove_duplicate_events()
185 if (type != e->type) in serio_remove_duplicate_events()
188 list_del_init(&e->node); in serio_remove_duplicate_events()
204 switch (event->type) { in serio_handle_event()
207 serio_add_port(event->object); in serio_handle_event()
211 serio_reconnect_port(event->object); in serio_handle_event()
215 serio_disconnect_port(event->object); in serio_handle_event()
216 serio_find_driver(event->object); in serio_handle_event()
220 serio_reconnect_subtree(event->object); in serio_handle_event()
224 serio_attach_driver(event->object); in serio_handle_event()
228 serio_remove_duplicate_events(event->object, event->type); in serio_handle_event()
254 if (event->object == object) { in serio_queue_event()
255 if (event->type == event_type) in serio_queue_event()
264 retval = -ENOMEM; in serio_queue_event()
272 retval = -EINVAL; in serio_queue_event()
276 event->type = event_type; in serio_queue_event()
277 event->object = object; in serio_queue_event()
278 event->owner = owner; in serio_queue_event()
280 list_add_tail(&event->node, &serio_event_list); in serio_queue_event()
300 if (event->object == object) { in serio_remove_pending_events()
301 list_del_init(&event->node); in serio_remove_pending_events()
324 if (event->type == SERIO_REGISTER_PORT) { in serio_get_pending_child()
325 serio = event->object; in serio_get_pending_child()
326 if (serio->parent == parent) { in serio_get_pending_child()
344 return sprintf(buf, "%s\n", serio->name); in serio_show_description()
352 serio->id.type, serio->id.proto, serio->id.id, serio->id.extra); in modalias_show()
358 return sprintf(buf, "%02x\n", serio->id.type); in type_show()
364 return sprintf(buf, "%02x\n", serio->id.proto); in proto_show()
370 return sprintf(buf, "%02x\n", serio->id.id); in id_show()
376 return sprintf(buf, "%02x\n", serio->id.extra); in extra_show()
382 struct device_driver *drv; in drvctl_store() local
397 } else if ((drv = driver_find(buf, &serio_bus)) != NULL) { in drvctl_store()
399 error = serio_bind_driver(serio, to_serio_driver(drv)); in drvctl_store()
402 error = -EINVAL; in drvctl_store()
413 return sprintf(buf, "%s\n", serio->manual_bind ? "manual" : "auto"); in serio_show_bind_mode()
423 serio->manual_bind = true; in serio_set_bind_mode()
425 serio->manual_bind = false; in serio_set_bind_mode()
427 retval = -EINVAL; in serio_set_bind_mode()
437 return sprintf(buf, "%s\n", serio->firmware_id); in firmware_id_show()
442 static DEVICE_ATTR_RO(id);
454 .name = "id",
496 static atomic_t serio_no = ATOMIC_INIT(-1); in serio_init_port()
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()
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()
556 put_device(&child->dev); 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()
574 put_device(&serio->dev); in serio_destroy_port()
578 * Reconnect serio port (re-initialize attached device).
596 * Reconnect serio port and all its children (re-initialize attached
611 if (!list_empty(&s->children)) { in serio_reconnect_subtree()
612 s = list_first_entry(&s->children, in serio_reconnect_subtree()
624 struct serio *parent = s->parent; in serio_reconnect_subtree()
626 if (!list_is_last(&s->child_node, &parent->children)) { in serio_reconnect_subtree()
627 s = list_entry(s->child_node.next, in serio_reconnect_subtree()
647 * first; we travel the tree in depth-first order. in serio_disconnect_port()
649 while (!list_empty(&serio->children)) { in serio_disconnect_port()
652 while (!list_empty(&s->children)) in serio_disconnect_port()
653 s = list_first_entry(&s->children, in serio_disconnect_port()
661 struct serio *parent = s->parent; in serio_disconnect_port()
663 device_release_driver(&s->dev); in serio_disconnect_port()
673 device_release_driver(&serio->dev); in serio_disconnect_port()
719 list_for_each_entry_safe(s, next, &serio->children, child_node) { in serio_unregister_child_port()
732 static ssize_t description_show(struct device_driver *drv, char *buf) in description_show() argument
734 struct serio_driver *driver = to_serio_driver(drv); in description_show()
735 return sprintf(buf, "%s\n", driver->description ? driver->description : "(none)"); in description_show()
739 static ssize_t bind_mode_show(struct device_driver *drv, char *buf) in bind_mode_show() argument
741 struct serio_driver *serio_drv = to_serio_driver(drv); in bind_mode_show()
742 return sprintf(buf, "%s\n", serio_drv->manual_bind ? "manual" : "auto"); in bind_mode_show()
745 static ssize_t bind_mode_store(struct device_driver *drv, const char *buf, size_t count) in bind_mode_store() argument
747 struct serio_driver *serio_drv = to_serio_driver(drv); in bind_mode_store()
752 serio_drv->manual_bind = true; in bind_mode_store()
754 serio_drv->manual_bind = false; in bind_mode_store()
756 retval = -EINVAL; in bind_mode_store()
773 struct serio_driver *drv = to_serio_driver(dev->driver); in serio_driver_probe() local
775 return serio_connect_driver(serio, drv); in serio_driver_probe()
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()
800 static void serio_attach_driver(struct serio_driver *drv) in serio_attach_driver() argument
804 error = driver_attach(&drv->driver); in serio_attach_driver()
807 drv->driver.name, error); in serio_attach_driver()
810 int __serio_register_driver(struct serio_driver *drv, struct module *owner, const char *mod_name) in __serio_register_driver() argument
812 bool manual_bind = drv->manual_bind; in __serio_register_driver()
815 drv->driver.bus = &serio_bus; in __serio_register_driver()
816 drv->driver.owner = owner; in __serio_register_driver()
817 drv->driver.mod_name = mod_name; in __serio_register_driver()
823 drv->manual_bind = true; in __serio_register_driver()
825 error = driver_register(&drv->driver); in __serio_register_driver()
828 drv->driver.name, error); in __serio_register_driver()
837 drv->manual_bind = false; in __serio_register_driver()
838 error = serio_queue_event(drv, NULL, SERIO_ATTACH_DRIVER); in __serio_register_driver()
840 driver_unregister(&drv->driver); in __serio_register_driver()
849 void serio_unregister_driver(struct serio_driver *drv) in serio_unregister_driver() argument
855 drv->manual_bind = true; /* so serio_find_driver ignores it */ in serio_unregister_driver()
856 serio_remove_pending_events(drv); in serio_unregister_driver()
860 if (serio->drv == drv) { in serio_unregister_driver()
868 driver_unregister(&drv->driver); in serio_unregister_driver()
873 static void serio_set_drv(struct serio *serio, struct serio_driver *drv) in serio_set_drv() argument
876 serio->drv = drv; in serio_set_drv()
880 static int serio_bus_match(struct device *dev, const struct device_driver *drv) in serio_bus_match() argument
883 const struct serio_driver *serio_drv = to_serio_driver(drv); in serio_bus_match()
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()
903 return -ENODEV; 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()
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()
936 int error = -ENOENT; in serio_resume()
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()
941 if (error && error != -ENOENT) in serio_resume()
945 mutex_unlock(&serio->drv_mutex); in serio_resume()
966 /* called from serio_driver->connect/disconnect methods under serio_mutex */
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()
973 return -1; in serio_open()
979 /* called from serio_driver->connect/disconnect methods under serio_mutex */
982 if (serio->close) in serio_close()
983 serio->close(serio); in serio_close()
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()
1004 spin_unlock_irqrestore(&serio->lock, flags); in serio_interrupt()