4 * Copyright 2014 Google Inc.
6 * Released under the GPLv2 only.
11 /* XXX This could be per-host device */
12 static DEFINE_SPINLOCK(gb_modules_lock);
14 static int gb_module_match_one_id(struct gb_module *gmod,
15 const struct greybus_module_id *id)
17 if ((id->match_flags & GREYBUS_DEVICE_ID_MATCH_VENDOR) &&
18 (id->vendor != gmod->vendor))
21 if ((id->match_flags & GREYBUS_DEVICE_ID_MATCH_PRODUCT) &&
22 (id->product != gmod->product))
25 if ((id->match_flags & GREYBUS_DEVICE_ID_MATCH_SERIAL) &&
26 (id->unique_id != gmod->unique_id))
32 const struct greybus_module_id *gb_module_match_id(struct gb_module *gmod,
33 const struct greybus_module_id *id)
38 for (; id->vendor || id->product || id->unique_id ||
39 id->driver_info; id++) {
40 if (gb_module_match_one_id(gmod, id))
47 static void gb_module_interfaces_exit(struct gb_module *gmod)
49 struct gb_interface *interface;
50 struct gb_interface *next;
52 list_for_each_entry_safe(interface, next, &gmod->interfaces, links)
53 gb_interface_destroy(interface);
57 * A Greybus module represents a user-replacable component on an Ara
60 * Create a gb_module structure to represent a discovered module.
61 * The position within the Endo is encoded in the "module_id" argument.
62 * Returns a pointer to the new module or a null pointer if a
63 * failure occurs due to memory exhaustion.
65 struct gb_module *gb_module_create(struct greybus_host_device *hd, u8 module_id)
67 struct gb_module *gmod;
69 gmod = kzalloc(sizeof(*gmod), GFP_KERNEL);
73 gmod->hd = hd; /* XXX refcount? */
74 gmod->module_id = module_id; /* XXX check for dups */
75 INIT_LIST_HEAD(&gmod->interfaces);
77 spin_lock_irq(&gb_modules_lock);
78 list_add_tail(&gmod->links, &hd->modules);
79 spin_unlock_irq(&gb_modules_lock);
85 * Tear down a previously set up module.
87 void gb_module_destroy(struct gb_module *gmod)
92 spin_lock_irq(&gb_modules_lock);
93 list_del(&gmod->links);
94 spin_unlock_irq(&gb_modules_lock);
96 gb_module_interfaces_exit(gmod);
97 /* XXX Do something with gmod->gb_tty */
99 put_device(&gmod->dev);
100 /* kfree(gmod->dev->name); */
102 kfree(gmod->product_string);
103 kfree(gmod->vendor_string);
104 /* kref_put(module->hd); */
110 struct gb_module *gb_module_find(struct greybus_host_device *hd, u8 module_id)
112 struct gb_module *module;
114 list_for_each_entry(module, &hd->modules, links)
115 if (module->module_id == module_id)
121 void gb_module_interfaces_init(struct gb_module *gmod)
123 struct gb_interface *interface;
126 list_for_each_entry(interface, &gmod->interfaces, links) {
127 ret = gb_interface_connections_init(interface);
129 dev_err(gmod->hd->parent,
130 "module interface init error %d\n", ret);