Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

greybus: core: add module abstraction

Add Greybus module abstraction that will be used to implement controlled
module removal (eject) and represent module geometry.

Greybus module devices correspond to physical modules and have one or
more interfaces. Modules have an id that is identical to the id of their
primary interface, which in turn is the interface with lowest numbered
id. The module name is constructed from the bus and module id:

<bus_id>-<module_id>

Interfaces, bundles, and control devices are consequently renamed as

<bus_id>-<module_id>.<interface_id>
<bus_id>-<module_id>.<interface_id>.<bundle_id>
<bus_id>-<module_id>.<interface_id>.ctrl

As before, interface ids (and therefore in a sense now also module ids)
correspond to physical interface positions on the frame.

Modules have the following attributes:

module_id
num_interfaces

where module_id is the id of the module and num_interface the number of
interfaces the module has.

Note that until SVC module-size detection has been implemented, all
interfaces are considered to be part of 1x2 modules. Specifically, the
two interfaces of a 2x2 module will be presented as two 1x2 modules for
now.

Signed-off-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>

authored by

Johan Hovold and committed by
Greg Kroah-Hartman
b15d97d7 844fcbfe

+333 -96
+43 -20
drivers/staging/greybus/Documentation/sysfs-bus-greybus
··· 6 6 The "root" greybus device for the Greybus device tree, or bus, 7 7 where N is a dynamically assigned 1-based id. 8 8 9 - What: /sys/bus/greybus/device/N-I 9 + What: /sys/bus/greybus/device/N-M 10 + Date: March 2016 11 + KernelVersion: 4.XX 12 + Contact: Greg Kroah-Hartman <greg@kroah.com> 13 + Description: 14 + A Module M on the bus N, where M is the 1-byte interface 15 + ID of the module's primary interface. 16 + 17 + What: /sys/bus/greybus/device/N-M/module_id 18 + Date: March 2016 19 + KernelVersion: 4.XX 20 + Contact: Greg Kroah-Hartman <greg@kroah.com> 21 + Description: 22 + The ID of a Greybus module, corresponding to the ID of its 23 + primary interface. 24 + 25 + What: /sys/bus/greybus/device/N-M/num_interfaces 26 + Date: March 2016 27 + KernelVersion: 4.XX 28 + Contact: Greg Kroah-Hartman <greg@kroah.com> 29 + Description: 30 + The number of interfaces of a module. 31 + 32 + What: /sys/bus/greybus/device/N-M.I 10 33 Date: October 2015 11 34 KernelVersion: 4.XX 12 35 Contact: Greg Kroah-Hartman <greg@kroah.com> 13 36 Description: 14 - An Interface I on the bus N, where I is the 1-byte interface 15 - ID. 37 + An Interface I on the bus N and module N-M, where I is the 38 + 1-byte interface ID. 16 39 17 - What: /sys/bus/greybus/device/N-I/current_now 40 + What: /sys/bus/greybus/device/N-M.I/current_now 18 41 Date: March 2016 19 42 KernelVersion: 4.XX 20 43 Contact: Greg Kroah-Hartman <greg@kroah.com> 21 44 Description: 22 45 Current measurement of the interface in microamps (uA) 23 46 24 - What: /sys/bus/greybus/device/N-I/ddbl1_manufacturer_id 47 + What: /sys/bus/greybus/device/N-M.I/ddbl1_manufacturer_id 25 48 Date: October 2015 26 49 KernelVersion: 4.XX 27 50 Contact: Greg Kroah-Hartman <greg@kroah.com> ··· 52 29 Unipro Device Descriptor Block Level 1 manufacturer ID for the 53 30 greybus Interface. 54 31 55 - What: /sys/bus/greybus/device/N-I/ddbl1_product_id 32 + What: /sys/bus/greybus/device/N-M.I/ddbl1_product_id 56 33 Date: October 2015 57 34 KernelVersion: 4.XX 58 35 Contact: Greg Kroah-Hartman <greg@kroah.com> ··· 60 37 Unipro Device Descriptor Block Level 1 product ID for the 61 38 greybus Interface. 62 39 63 - What: /sys/bus/greybus/device/N-I/interface_id 40 + What: /sys/bus/greybus/device/N-M.I/interface_id 64 41 Date: October 2015 65 42 KernelVersion: 4.XX 66 43 Contact: Greg Kroah-Hartman <greg@kroah.com> 67 44 Description: 68 45 The ID of a Greybus interface. 69 46 70 - What: /sys/bus/greybus/device/N-I/power_now 47 + What: /sys/bus/greybus/device/N-M.I/power_now 71 48 Date: March 2016 72 49 KernelVersion: 4.XX 73 50 Contact: Greg Kroah-Hartman <greg@kroah.com> 74 51 Description: 75 52 Power measurement of the interface in microwatts (uW) 76 53 77 - What: /sys/bus/greybus/device/N-I/product_id 54 + What: /sys/bus/greybus/device/N-M.I/product_id 78 55 Date: October 2015 79 56 KernelVersion: 4.XX 80 57 Contact: Greg Kroah-Hartman <greg@kroah.com> 81 58 Description: 82 59 Product ID of a Greybus interface. 83 60 84 - What: /sys/bus/greybus/device/N-I/serial_number 61 + What: /sys/bus/greybus/device/N-M.I/serial_number 85 62 Date: October 2015 86 63 KernelVersion: 4.XX 87 64 Contact: Greg Kroah-Hartman <greg@kroah.com> ··· 89 66 Serial Number of the Greybus interface, represented by a 64 bit 90 67 hexadecimal number. 91 68 92 - What: /sys/bus/greybus/device/N-I/vendor_id 69 + What: /sys/bus/greybus/device/N-M.I/vendor_id 93 70 Date: October 2015 94 71 KernelVersion: 4.XX 95 72 Contact: Greg Kroah-Hartman <greg@kroah.com> 96 73 Description: 97 74 Vendor ID of a Greybus interface. 98 75 99 - What: /sys/bus/greybus/device/N-I/version 76 + What: /sys/bus/greybus/device/N-M.I/version 100 77 Date: October 2015 101 78 KernelVersion: 4.XX 102 79 Contact: Greg Kroah-Hartman <greg@kroah.com> ··· 104 81 Interface version represented as <16 bit major number>.<16 bit 105 82 minor number>. 106 83 107 - What: /sys/bus/greybus/device/N-I/voltage_now 84 + What: /sys/bus/greybus/device/N-M.I/voltage_now 108 85 Date: March 2016 109 86 KernelVersion: 4.XX 110 87 Contact: Greg Kroah-Hartman <greg@kroah.com> 111 88 Description: 112 89 Voltage measurement of the interface in microvolts (uV) 113 90 114 - What: /sys/bus/greybus/device/N-I.ctrl 91 + What: /sys/bus/greybus/device/N-M.I.ctrl 115 92 Date: October 2015 116 93 KernelVersion: 4.XX 117 94 Contact: Greg Kroah-Hartman <greg@kroah.com> ··· 119 96 Abstract control device for interface I that represents the 120 97 current mode of an enumerated Greybus interface. 121 98 122 - What: /sys/bus/greybus/device/N-I.ctrl/product_string 99 + What: /sys/bus/greybus/device/N-M.I.ctrl/product_string 123 100 Date: October 2015 124 101 KernelVersion: 4.XX 125 102 Contact: Greg Kroah-Hartman <greg@kroah.com> 126 103 Description: 127 104 Product ID string of a Greybus interface. 128 105 129 - What: /sys/bus/greybus/device/N-I.ctrl/vendor_string 106 + What: /sys/bus/greybus/device/N-M.I.ctrl/vendor_string 130 107 Date: October 2015 131 108 KernelVersion: 4.XX 132 109 Contact: Greg Kroah-Hartman <greg@kroah.com> 133 110 Description: 134 111 Vendor ID string of a Greybus interface. 135 112 136 - What: /sys/bus/greybus/device/N-I.B 113 + What: /sys/bus/greybus/device/N-M.I.B 137 114 Date: October 2015 138 115 KernelVersion: 4.XX 139 116 Contact: Greg Kroah-Hartman <greg@kroah.com> ··· 141 118 A bundle B on the Interface I, B is replaced by a 1-byte 142 119 number representing the bundle. 143 120 144 - What: /sys/bus/greybus/device/N-I.B/bundle_class 121 + What: /sys/bus/greybus/device/N-M.I.B/bundle_class 145 122 Date: October 2015 146 123 KernelVersion: 4.XX 147 124 Contact: Greg Kroah-Hartman <greg@kroah.com> 148 125 Description: 149 126 The greybus class of the bundle B. 150 127 151 - What: /sys/bus/greybus/device/N-I.B/bundle_id 128 + What: /sys/bus/greybus/device/N-M.I.B/bundle_id 152 129 Date: October 2015 153 130 KernelVersion: 4.XX 154 131 Contact: Greg Kroah-Hartman <greg@kroah.com> 155 132 Description: 156 133 The interface-unique id of the bundle B. 157 134 158 - What: /sys/bus/greybus/device/N-I.B/state 135 + What: /sys/bus/greybus/device/N-M.I.B/state 159 136 Date: October 2015 160 137 KernelVersion: 4.XX 161 138 Contact: Greg Kroah-Hartman <greg@kroah.com>
+1
drivers/staging/greybus/Makefile
··· 2 2 debugfs.o \ 3 3 hd.o \ 4 4 manifest.o \ 5 + module.o \ 5 6 interface.o \ 6 7 bundle.o \ 7 8 connection.o \
+11
drivers/staging/greybus/core.c
··· 85 85 static int greybus_uevent(struct device *dev, struct kobj_uevent_env *env) 86 86 { 87 87 struct gb_host_device *hd; 88 + struct gb_module *module = NULL; 88 89 struct gb_interface *intf = NULL; 89 90 struct gb_control *control = NULL; 90 91 struct gb_bundle *bundle = NULL; ··· 93 92 94 93 if (is_gb_host_device(dev)) { 95 94 hd = to_gb_host_device(dev); 95 + } else if (is_gb_module(dev)) { 96 + module = to_gb_module(dev); 97 + hd = module->hd; 96 98 } else if (is_gb_interface(dev)) { 97 99 intf = to_gb_interface(dev); 100 + module = intf->module; 98 101 hd = intf->hd; 99 102 } else if (is_gb_control(dev)) { 100 103 control = to_gb_control(dev); ··· 107 102 } else if (is_gb_bundle(dev)) { 108 103 bundle = to_gb_bundle(dev); 109 104 intf = bundle->intf; 105 + module = intf->module; 110 106 hd = intf->hd; 111 107 } else if (is_gb_svc(dev)) { 112 108 svc = to_gb_svc(dev); ··· 119 113 120 114 if (add_uevent_var(env, "BUS=%u", hd->bus_id)) 121 115 return -ENOMEM; 116 + 117 + if (module) { 118 + if (add_uevent_var(env, "MODULE=%u", module->module_id)) 119 + return -ENOMEM; 120 + } 122 121 123 122 if (intf) { 124 123 if (add_uevent_var(env, "INTERFACE=%u", intf->interface_id))
+7
drivers/staging/greybus/greybus.h
··· 28 28 #include "hd.h" 29 29 #include "svc.h" 30 30 #include "control.h" 31 + #include "module.h" 31 32 #include "interface.h" 32 33 #include "bundle.h" 33 34 #include "connection.h" ··· 113 112 extern struct bus_type greybus_bus_type; 114 113 115 114 extern struct device_type greybus_hd_type; 115 + extern struct device_type greybus_module_type; 116 116 extern struct device_type greybus_interface_type; 117 117 extern struct device_type greybus_control_type; 118 118 extern struct device_type greybus_bundle_type; ··· 122 120 static inline int is_gb_host_device(const struct device *dev) 123 121 { 124 122 return dev->type == &greybus_hd_type; 123 + } 124 + 125 + static inline int is_gb_module(const struct device *dev) 126 + { 127 + return dev->type == &greybus_module_type; 125 128 } 126 129 127 130 static inline int is_gb_interface(const struct device *dev)
+1 -1
drivers/staging/greybus/hd.c
··· 89 89 hd->bus_id = ret; 90 90 91 91 hd->driver = driver; 92 - INIT_LIST_HEAD(&hd->interfaces); 92 + INIT_LIST_HEAD(&hd->modules); 93 93 INIT_LIST_HEAD(&hd->connections); 94 94 ida_init(&hd->cport_id_map); 95 95 hd->buffer_size_max = buffer_size_max;
+1 -1
drivers/staging/greybus/hd.h
··· 34 34 int bus_id; 35 35 const struct gb_hd_driver *driver; 36 36 37 - struct list_head interfaces; 37 + struct list_head modules; 38 38 struct list_head connections; 39 39 struct ida cport_id_map; 40 40
+12 -28
drivers/staging/greybus/interface.c
··· 333 333 }; 334 334 ATTRIBUTE_GROUPS(interface); 335 335 336 - 337 - // FIXME, odds are you don't want to call this function, rework the caller to 338 - // not need it please. 339 - struct gb_interface *gb_interface_find(struct gb_host_device *hd, 340 - u8 interface_id) 341 - { 342 - struct gb_interface *intf; 343 - 344 - list_for_each_entry(intf, &hd->interfaces, links) 345 - if (intf->interface_id == interface_id) 346 - return intf; 347 - 348 - return NULL; 349 - } 350 - 351 336 static void gb_interface_release(struct device *dev) 352 337 { 353 338 struct gb_interface *intf = to_gb_interface(dev); ··· 356 371 * 357 372 * Returns a pointer to the new interfce or a null pointer if a 358 373 * failure occurs due to memory exhaustion. 359 - * 360 - * Locking: Caller ensures serialisation with gb_interface_remove and 361 - * gb_interface_find. 362 374 */ 363 - struct gb_interface *gb_interface_create(struct gb_host_device *hd, 375 + struct gb_interface *gb_interface_create(struct gb_module *module, 364 376 u8 interface_id) 365 377 { 378 + struct gb_host_device *hd = module->hd; 366 379 struct gb_interface *intf; 367 380 368 381 intf = kzalloc(sizeof(*intf), GFP_KERNEL); ··· 368 385 return NULL; 369 386 370 387 intf->hd = hd; /* XXX refcount? */ 388 + intf->module = module; 371 389 intf->interface_id = interface_id; 372 390 INIT_LIST_HEAD(&intf->bundles); 373 391 INIT_LIST_HEAD(&intf->manifest_descs); ··· 376 392 /* Invalid device id to start with */ 377 393 intf->device_id = GB_INTERFACE_DEVICE_ID_BAD; 378 394 379 - intf->dev.parent = &hd->dev; 395 + intf->dev.parent = &module->dev; 380 396 intf->dev.bus = &greybus_bus_type; 381 397 intf->dev.type = &greybus_interface_type; 382 398 intf->dev.groups = interface_groups; 383 - intf->dev.dma_mask = hd->dev.dma_mask; 399 + intf->dev.dma_mask = module->dev.dma_mask; 384 400 device_initialize(&intf->dev); 385 - dev_set_name(&intf->dev, "%d-%d", hd->bus_id, interface_id); 386 - 387 - list_add(&intf->links, &hd->interfaces); 401 + dev_set_name(&intf->dev, "%s.%u", dev_name(&module->dev), 402 + interface_id); 388 403 389 404 return intf; 390 405 } ··· 562 579 return 0; 563 580 } 564 581 565 - /* Deregister an interface and drop its reference. */ 566 - void gb_interface_remove(struct gb_interface *intf) 582 + /* Deregister an interface. */ 583 + void gb_interface_del(struct gb_interface *intf) 567 584 { 568 585 if (device_is_registered(&intf->dev)) { 569 586 device_del(&intf->dev); 570 587 dev_info(&intf->dev, "Interface removed\n"); 571 588 } 589 + } 572 590 573 - list_del(&intf->links); 574 - 591 + void gb_interface_put(struct gb_interface *intf) 592 + { 575 593 put_device(&intf->dev); 576 594 }
+5 -3
drivers/staging/greybus/interface.h
··· 20 20 struct gb_control *control; 21 21 22 22 struct list_head bundles; 23 - struct list_head links; /* gb_host_device->interfaces */ 23 + struct list_head module_node; 24 24 struct list_head manifest_descs; 25 25 u8 interface_id; /* Physical location within the Endo */ 26 26 u8 device_id; ··· 35 35 u16 version_minor; 36 36 37 37 struct gb_host_device *hd; 38 + struct gb_module *module; 38 39 39 40 unsigned long quirks; 40 41 ··· 47 46 struct gb_interface *gb_interface_find(struct gb_host_device *hd, 48 47 u8 interface_id); 49 48 50 - struct gb_interface *gb_interface_create(struct gb_host_device *hd, 49 + struct gb_interface *gb_interface_create(struct gb_module *module, 51 50 u8 interface_id); 52 51 int gb_interface_activate(struct gb_interface *intf); 53 52 void gb_interface_deactivate(struct gb_interface *intf); 54 53 int gb_interface_enable(struct gb_interface *intf); 55 54 void gb_interface_disable(struct gb_interface *intf); 56 55 int gb_interface_add(struct gb_interface *intf); 57 - void gb_interface_remove(struct gb_interface *intf); 56 + void gb_interface_del(struct gb_interface *intf); 57 + void gb_interface_put(struct gb_interface *intf); 58 58 59 59 #endif /* __INTERFACE_H */
+178
drivers/staging/greybus/module.c
··· 1 + /* 2 + * Greybus Module code 3 + * 4 + * Copyright 2016 Google Inc. 5 + * Copyright 2016 Linaro Ltd. 6 + * 7 + * Released under the GPLv2 only. 8 + */ 9 + 10 + #include "greybus.h" 11 + 12 + 13 + static ssize_t module_id_show(struct device *dev, 14 + struct device_attribute *attr, char *buf) 15 + { 16 + struct gb_module *module = to_gb_module(dev); 17 + 18 + return sprintf(buf, "%u\n", module->module_id); 19 + } 20 + static DEVICE_ATTR_RO(module_id); 21 + 22 + static ssize_t num_interfaces_show(struct device *dev, 23 + struct device_attribute *attr, char *buf) 24 + { 25 + struct gb_module *module = to_gb_module(dev); 26 + 27 + return sprintf(buf, "%zu\n", module->num_interfaces); 28 + } 29 + static DEVICE_ATTR_RO(num_interfaces); 30 + 31 + static struct attribute *module_attrs[] = { 32 + &dev_attr_module_id.attr, 33 + &dev_attr_num_interfaces.attr, 34 + NULL, 35 + }; 36 + ATTRIBUTE_GROUPS(module); 37 + 38 + static void gb_module_release(struct device *dev) 39 + { 40 + struct gb_module *module = to_gb_module(dev); 41 + 42 + kfree(module); 43 + } 44 + 45 + struct device_type greybus_module_type = { 46 + .name = "greybus_module", 47 + .release = gb_module_release, 48 + }; 49 + 50 + struct gb_module *gb_module_create(struct gb_host_device *hd, u8 module_id, 51 + size_t num_interfaces) 52 + { 53 + struct gb_interface *intf; 54 + struct gb_module *module; 55 + int i; 56 + 57 + module = kzalloc(sizeof(*module) + num_interfaces * sizeof(intf), 58 + GFP_KERNEL); 59 + if (!module) 60 + return NULL; 61 + 62 + module->hd = hd; 63 + module->module_id = module_id; 64 + module->num_interfaces = num_interfaces; 65 + 66 + module->dev.parent = &hd->dev; 67 + module->dev.bus = &greybus_bus_type; 68 + module->dev.type = &greybus_module_type; 69 + module->dev.groups = module_groups; 70 + module->dev.dma_mask = hd->dev.dma_mask; 71 + device_initialize(&module->dev); 72 + dev_set_name(&module->dev, "%d-%u", hd->bus_id, module_id); 73 + 74 + for (i = 0; i < num_interfaces; ++i) { 75 + intf = gb_interface_create(module, module_id + i); 76 + if (!intf) { 77 + dev_err(&module->dev, "failed to create interface %u\n", 78 + module_id + i); 79 + goto err_put_interfaces; 80 + } 81 + module->interfaces[i] = intf; 82 + } 83 + 84 + return module; 85 + 86 + err_put_interfaces: 87 + for (--i; i > 0; --i) 88 + gb_interface_put(module->interfaces[i]); 89 + 90 + put_device(&module->dev); 91 + 92 + return NULL; 93 + } 94 + 95 + /* 96 + * Register and enable an interface after first attempting to activate it. 97 + */ 98 + static void gb_module_register_interface(struct gb_interface *intf) 99 + { 100 + struct gb_module *module = intf->module; 101 + u8 intf_id = intf->interface_id; 102 + int ret; 103 + 104 + ret = gb_interface_activate(intf); 105 + if (ret) { 106 + dev_err(&module->dev, "failed to activate interface %u: %d\n", 107 + intf_id, ret); 108 + gb_interface_add(intf); 109 + return; 110 + } 111 + 112 + ret = gb_interface_add(intf); 113 + if (ret) 114 + goto err_interface_deactivate; 115 + 116 + ret = gb_interface_enable(intf); 117 + if (ret) { 118 + dev_err(&module->dev, "failed to enable interface %u: %d\n", 119 + intf_id, ret); 120 + goto err_interface_deactivate; 121 + } 122 + 123 + return; 124 + 125 + err_interface_deactivate: 126 + gb_interface_deactivate(intf); 127 + } 128 + 129 + static void gb_module_deregister_interface(struct gb_interface *intf) 130 + { 131 + /* Mark as disconnected to prevent I/O during disable. */ 132 + if (intf->module->disconnected) 133 + intf->disconnected = true; 134 + 135 + gb_interface_disable(intf); 136 + gb_interface_deactivate(intf); 137 + 138 + gb_interface_del(intf); 139 + } 140 + 141 + /* Register a module and its interfaces. */ 142 + int gb_module_add(struct gb_module *module) 143 + { 144 + size_t i; 145 + int ret; 146 + 147 + ret = device_add(&module->dev); 148 + if (ret) { 149 + dev_err(&module->dev, "failed to register module: %d\n", ret); 150 + return ret; 151 + } 152 + 153 + for (i = 0; i < module->num_interfaces; ++i) 154 + gb_module_register_interface(module->interfaces[i]); 155 + 156 + return 0; 157 + } 158 + 159 + /* Deregister a module and its interfaces. */ 160 + void gb_module_del(struct gb_module *module) 161 + { 162 + size_t i; 163 + 164 + for (i = 0; i < module->num_interfaces; ++i) 165 + gb_module_deregister_interface(module->interfaces[i]); 166 + 167 + device_del(&module->dev); 168 + } 169 + 170 + void gb_module_put(struct gb_module *module) 171 + { 172 + size_t i; 173 + 174 + for (i = 0; i < module->num_interfaces; ++i) 175 + gb_interface_put(module->interfaces[i]); 176 + 177 + put_device(&module->dev); 178 + }
+34
drivers/staging/greybus/module.h
··· 1 + /* 2 + * Greybus Module code 3 + * 4 + * Copyright 2016 Google Inc. 5 + * Copyright 2016 Linaro Ltd. 6 + * 7 + * Released under the GPLv2 only. 8 + */ 9 + 10 + #ifndef __MODULE_H 11 + #define __MODULE_H 12 + 13 + struct gb_module { 14 + struct device dev; 15 + struct gb_host_device *hd; 16 + 17 + struct list_head hd_node; 18 + 19 + u8 module_id; 20 + size_t num_interfaces; 21 + 22 + bool disconnected; 23 + 24 + struct gb_interface *interfaces[0]; 25 + }; 26 + #define to_gb_module(d) container_of(d, struct gb_module, dev) 27 + 28 + struct gb_module *gb_module_create(struct gb_host_device *hd, u8 module_id, 29 + size_t num_interfaces); 30 + int gb_module_add(struct gb_module *module); 31 + void gb_module_del(struct gb_module *module); 32 + void gb_module_put(struct gb_module *module); 33 + 34 + #endif /* __MODULE_H */
+40 -43
drivers/staging/greybus/svc.c
··· 665 665 return 0; 666 666 } 667 667 668 + static struct gb_module *gb_svc_module_lookup(struct gb_svc *svc, u8 module_id) 669 + { 670 + struct gb_host_device *hd = svc->hd; 671 + struct gb_module *module; 672 + 673 + list_for_each_entry(module, &hd->modules, hd_node) { 674 + if (module->module_id == module_id) 675 + return module; 676 + } 677 + 678 + return NULL; 679 + } 680 + 668 681 static void gb_svc_intf_reenable(struct gb_svc *svc, struct gb_interface *intf) 669 682 { 670 683 int ret; ··· 702 689 struct gb_connection *connection = operation->connection; 703 690 struct gb_svc *svc = gb_connection_get_data(connection); 704 691 struct gb_host_device *hd = connection->hd; 705 - struct gb_interface *intf; 692 + struct gb_module *module; 706 693 u8 intf_id; 707 694 int ret; 708 695 ··· 712 699 713 700 dev_dbg(&svc->dev, "%s - id = %u\n", __func__, intf_id); 714 701 715 - intf = gb_interface_find(hd, intf_id); 716 - if (intf) { 702 + /* All modules are considered 1x2 for now */ 703 + module = gb_svc_module_lookup(svc, intf_id); 704 + if (module) { 717 705 dev_info(&svc->dev, "mode switch detected on interface %u\n", 718 706 intf_id); 719 707 720 - return gb_svc_intf_reenable(svc, intf); 708 + return gb_svc_intf_reenable(svc, module->interfaces[0]); 721 709 } 722 710 723 - intf = gb_interface_create(hd, intf_id); 724 - if (!intf) { 725 - dev_err(&svc->dev, "failed to create interface %u\n", 726 - intf_id); 711 + module = gb_module_create(hd, intf_id, 1); 712 + if (!module) { 713 + dev_err(&svc->dev, "failed to create module\n"); 727 714 return; 728 715 } 729 716 730 - ret = gb_interface_activate(intf); 717 + ret = gb_module_add(module); 731 718 if (ret) { 732 - dev_err(&svc->dev, "failed to activate interface %u: %d\n", 733 - intf_id, ret); 734 - gb_interface_add(intf); 719 + gb_module_put(module); 735 720 return; 736 721 } 737 722 738 - ret = gb_interface_add(intf); 739 - if (ret) 740 - goto err_interface_deactivate; 741 - 742 - ret = gb_interface_enable(intf); 743 - if (ret) { 744 - dev_err(&svc->dev, "failed to enable interface %u: %d\n", 745 - intf_id, ret); 746 - goto err_interface_deactivate; 747 - } 748 - 749 - return; 750 - 751 - err_interface_deactivate: 752 - gb_interface_deactivate(intf); 723 + list_add(&module->hd_node, &hd->modules); 753 724 } 754 725 755 726 static void gb_svc_process_intf_hot_unplug(struct gb_operation *operation) 756 727 { 757 728 struct gb_svc *svc = gb_connection_get_data(operation->connection); 758 729 struct gb_svc_intf_hot_unplug_request *request; 759 - struct gb_host_device *hd = operation->connection->hd; 760 - struct gb_interface *intf; 730 + struct gb_module *module; 761 731 u8 intf_id; 762 732 763 733 /* The request message size has already been verified. */ ··· 749 753 750 754 dev_dbg(&svc->dev, "%s - id = %u\n", __func__, intf_id); 751 755 752 - intf = gb_interface_find(hd, intf_id); 753 - if (!intf) { 756 + /* All modules are considered 1x2 for now */ 757 + module = gb_svc_module_lookup(svc, intf_id); 758 + if (!module) { 754 759 dev_warn(&svc->dev, "could not find hot-unplug interface %u\n", 755 760 intf_id); 756 761 return; 757 762 } 758 763 759 - /* Mark as disconnected to prevent I/O during disable. */ 760 - intf->disconnected = true; 764 + module->disconnected = true; 761 765 762 - gb_interface_disable(intf); 763 - gb_interface_deactivate(intf); 764 - gb_interface_remove(intf); 766 + gb_module_del(module); 767 + list_del(&module->hd_node); 768 + gb_module_put(module); 765 769 } 766 770 767 771 static void gb_svc_process_deferred_request(struct work_struct *work) ··· 1100 1104 return 0; 1101 1105 } 1102 1106 1103 - static void gb_svc_remove_interfaces(struct gb_svc *svc) 1107 + static void gb_svc_remove_modules(struct gb_svc *svc) 1104 1108 { 1105 - struct gb_interface *intf, *tmp; 1109 + struct gb_host_device *hd = svc->hd; 1110 + struct gb_module *module, *tmp; 1106 1111 1107 - list_for_each_entry_safe(intf, tmp, &svc->hd->interfaces, links) { 1108 - gb_interface_disable(intf); 1109 - gb_interface_deactivate(intf); 1110 - gb_interface_remove(intf); 1112 + list_for_each_entry_safe(module, tmp, &hd->modules, hd_node) { 1113 + gb_module_del(module); 1114 + list_del(&module->hd_node); 1115 + gb_module_put(module); 1111 1116 } 1112 1117 } 1113 1118 ··· 1129 1132 1130 1133 flush_workqueue(svc->wq); 1131 1134 1132 - gb_svc_remove_interfaces(svc); 1135 + gb_svc_remove_modules(svc); 1133 1136 } 1134 1137 1135 1138 void gb_svc_put(struct gb_svc *svc)