Linux Audio

Check our new training course

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