237 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Greybus Module code4 *5 * Copyright 2016 Google Inc.6 * Copyright 2016 Linaro Ltd.7 */8 9#include <linux/greybus.h>10#include "greybus_trace.h"11 12static ssize_t eject_store(struct device *dev,13 struct device_attribute *attr,14 const char *buf, size_t len)15{16 struct gb_module *module = to_gb_module(dev);17 struct gb_interface *intf;18 size_t i;19 long val;20 int ret;21 22 ret = kstrtol(buf, 0, &val);23 if (ret)24 return ret;25 26 if (!val)27 return len;28 29 for (i = 0; i < module->num_interfaces; ++i) {30 intf = module->interfaces[i];31 32 mutex_lock(&intf->mutex);33 /* Set flag to prevent concurrent activation. */34 intf->ejected = true;35 gb_interface_disable(intf);36 gb_interface_deactivate(intf);37 mutex_unlock(&intf->mutex);38 }39 40 /* Tell the SVC to eject the primary interface. */41 ret = gb_svc_intf_eject(module->hd->svc, module->module_id);42 if (ret)43 return ret;44 45 return len;46}47static DEVICE_ATTR_WO(eject);48 49static ssize_t module_id_show(struct device *dev,50 struct device_attribute *attr, char *buf)51{52 struct gb_module *module = to_gb_module(dev);53 54 return sprintf(buf, "%u\n", module->module_id);55}56static DEVICE_ATTR_RO(module_id);57 58static ssize_t num_interfaces_show(struct device *dev,59 struct device_attribute *attr, char *buf)60{61 struct gb_module *module = to_gb_module(dev);62 63 return sprintf(buf, "%zu\n", module->num_interfaces);64}65static DEVICE_ATTR_RO(num_interfaces);66 67static struct attribute *module_attrs[] = {68 &dev_attr_eject.attr,69 &dev_attr_module_id.attr,70 &dev_attr_num_interfaces.attr,71 NULL,72};73ATTRIBUTE_GROUPS(module);74 75static void gb_module_release(struct device *dev)76{77 struct gb_module *module = to_gb_module(dev);78 79 trace_gb_module_release(module);80 81 kfree(module);82}83 84const struct device_type greybus_module_type = {85 .name = "greybus_module",86 .release = gb_module_release,87};88 89struct gb_module *gb_module_create(struct gb_host_device *hd, u8 module_id,90 size_t num_interfaces)91{92 struct gb_interface *intf;93 struct gb_module *module;94 int i;95 96 module = kzalloc(struct_size(module, interfaces, num_interfaces),97 GFP_KERNEL);98 if (!module)99 return NULL;100 101 module->hd = hd;102 module->module_id = module_id;103 module->num_interfaces = num_interfaces;104 105 module->dev.parent = &hd->dev;106 module->dev.bus = &greybus_bus_type;107 module->dev.type = &greybus_module_type;108 module->dev.groups = module_groups;109 module->dev.dma_mask = hd->dev.dma_mask;110 device_initialize(&module->dev);111 dev_set_name(&module->dev, "%d-%u", hd->bus_id, module_id);112 113 trace_gb_module_create(module);114 115 for (i = 0; i < num_interfaces; ++i) {116 intf = gb_interface_create(module, module_id + i);117 if (!intf) {118 dev_err(&module->dev, "failed to create interface %u\n",119 module_id + i);120 goto err_put_interfaces;121 }122 module->interfaces[i] = intf;123 }124 125 return module;126 127err_put_interfaces:128 for (--i; i >= 0; --i)129 gb_interface_put(module->interfaces[i]);130 131 put_device(&module->dev);132 133 return NULL;134}135 136/*137 * Register and enable an interface after first attempting to activate it.138 */139static void gb_module_register_interface(struct gb_interface *intf)140{141 struct gb_module *module = intf->module;142 u8 intf_id = intf->interface_id;143 int ret;144 145 mutex_lock(&intf->mutex);146 147 ret = gb_interface_activate(intf);148 if (ret) {149 if (intf->type != GB_INTERFACE_TYPE_DUMMY) {150 dev_err(&module->dev,151 "failed to activate interface %u: %d\n",152 intf_id, ret);153 }154 155 gb_interface_add(intf);156 goto err_unlock;157 }158 159 ret = gb_interface_add(intf);160 if (ret)161 goto err_interface_deactivate;162 163 ret = gb_interface_enable(intf);164 if (ret) {165 dev_err(&module->dev, "failed to enable interface %u: %d\n",166 intf_id, ret);167 goto err_interface_deactivate;168 }169 170 mutex_unlock(&intf->mutex);171 172 return;173 174err_interface_deactivate:175 gb_interface_deactivate(intf);176err_unlock:177 mutex_unlock(&intf->mutex);178}179 180static void gb_module_deregister_interface(struct gb_interface *intf)181{182 /* Mark as disconnected to prevent I/O during disable. */183 if (intf->module->disconnected)184 intf->disconnected = true;185 186 mutex_lock(&intf->mutex);187 intf->removed = true;188 gb_interface_disable(intf);189 gb_interface_deactivate(intf);190 mutex_unlock(&intf->mutex);191 192 gb_interface_del(intf);193}194 195/* Register a module and its interfaces. */196int gb_module_add(struct gb_module *module)197{198 size_t i;199 int ret;200 201 ret = device_add(&module->dev);202 if (ret) {203 dev_err(&module->dev, "failed to register module: %d\n", ret);204 return ret;205 }206 207 trace_gb_module_add(module);208 209 for (i = 0; i < module->num_interfaces; ++i)210 gb_module_register_interface(module->interfaces[i]);211 212 return 0;213}214 215/* Deregister a module and its interfaces. */216void gb_module_del(struct gb_module *module)217{218 size_t i;219 220 for (i = 0; i < module->num_interfaces; ++i)221 gb_module_deregister_interface(module->interfaces[i]);222 223 trace_gb_module_del(module);224 225 device_del(&module->dev);226}227 228void gb_module_put(struct gb_module *module)229{230 size_t i;231 232 for (i = 0; i < module->num_interfaces; ++i)233 gb_interface_put(module->interfaces[i]);234 235 put_device(&module->dev);236}237