2 * Greybus GP Bridge driver
4 * Copyright 2014 Google Inc.
5 * Copyright 2014 Linaro Ltd.
7 * Released under the GPLv2 only.
10 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
12 #include <linux/types.h>
13 #include <linux/module.h>
14 #include <linux/moduleparam.h>
15 #include <linux/kernel.h>
16 #include <linux/slab.h>
17 #include <linux/device.h>
22 struct gpbridge_host {
23 struct gb_bundle *bundle;
24 struct list_head devices;
27 static DEFINE_IDA(gpbridge_id);
29 static ssize_t protocol_id_show(struct device *dev,
30 struct device_attribute *attr, char *buf)
32 struct gpbridge_device *gpbdev = to_gpbridge_dev(dev);
34 return sprintf(buf, "0x%02x\n", gpbdev->cport_desc->protocol_id);
36 static DEVICE_ATTR_RO(protocol_id);
38 static struct attribute *gpbdev_attrs[] = {
39 &dev_attr_protocol_id.attr,
43 ATTRIBUTE_GROUPS(gpbdev);
45 static void gpbdev_release(struct device *dev)
47 struct gpbridge_device *gpbdev = to_gpbridge_dev(dev);
49 ida_simple_remove(&gpbridge_id, gpbdev->id);
53 struct device_type greybus_gpbdev_type = {
54 .name = "gpbridge_device",
55 .release = gpbdev_release,
58 static int gpbdev_uevent(struct device *dev, struct kobj_uevent_env *env)
60 struct gpbridge_device *gpbdev = to_gpbridge_dev(dev);
61 struct greybus_descriptor_cport *cport_desc = gpbdev->cport_desc;
62 struct gb_bundle *bundle = gpbdev->bundle;
63 struct gb_interface *intf = bundle->intf;
64 struct gb_module *module = intf->module;
65 struct gb_host_device *hd = intf->hd;
67 if (add_uevent_var(env, "BUS=%u", hd->bus_id))
69 if (add_uevent_var(env, "MODULE=%u", module->module_id))
71 if (add_uevent_var(env, "INTERFACE=%u", intf->interface_id))
73 if (add_uevent_var(env, "GREYBUS_ID=%08x/%08x",
74 intf->vendor_id, intf->product_id))
76 if (add_uevent_var(env, "BUNDLE=%u", gpbdev->bundle->id))
78 if (add_uevent_var(env, "BUNDLE_CLASS=%02x", bundle->class))
80 if (add_uevent_var(env, "GPBDEV_ID=%u", gpbdev->id))
82 if (add_uevent_var(env, "PROTOCOL_ID=%02x", cport_desc->protocol_id))
88 static const struct gpbridge_device_id *
89 gpbdev_match_id(struct gpbridge_device *gpbdev, struct gpbridge_driver *gpbdrv)
91 const struct gpbridge_device_id *id = gpbdrv->id_table;
96 for (; id->protocol_id; id++)
97 if (id->protocol_id == gpbdev->cport_desc->protocol_id)
103 static int gpbdev_match(struct device *dev, struct device_driver *drv)
105 struct gpbridge_driver *gpbdrv = to_gpbridge_driver(drv);
106 struct gpbridge_device *gpbdev = to_gpbridge_dev(dev);
107 const struct gpbridge_device_id *id;
109 id = gpbdev_match_id(gpbdev, gpbdrv);
116 static int gpbdev_probe(struct device *dev)
118 struct gpbridge_driver *gpbdrv = to_gpbridge_driver(dev->driver);
119 struct gpbridge_device *gpbdev = to_gpbridge_dev(dev);
120 const struct gpbridge_device_id *id;
122 id = gpbdev_match_id(gpbdev, gpbdrv);
126 return gpbdrv->probe(gpbdev, id);
129 static int gpbdev_remove(struct device *dev)
131 struct gpbridge_driver *gpbdrv = to_gpbridge_driver(dev->driver);
132 struct gpbridge_device *gpbdev = to_gpbridge_dev(dev);
134 gpbdrv->remove(gpbdev);
138 static struct bus_type gpbridge_bus_type = {
140 .match = gpbdev_match,
141 .probe = gpbdev_probe,
142 .remove = gpbdev_remove,
143 .uevent = gpbdev_uevent,
146 int gb_gpbridge_register_driver(struct gpbridge_driver *driver,
147 struct module *owner, const char *mod_name)
151 if (greybus_disabled())
154 driver->driver.bus = &gpbridge_bus_type;
155 driver->driver.name = driver->name;
156 driver->driver.owner = owner;
157 driver->driver.mod_name = mod_name;
159 retval = driver_register(&driver->driver);
163 pr_info("registered new driver %s\n", driver->name);
166 EXPORT_SYMBOL_GPL(gb_gpbridge_register_driver);
168 void gb_gpbridge_deregister_driver(struct gpbridge_driver *driver)
170 driver_unregister(&driver->driver);
172 EXPORT_SYMBOL_GPL(gb_gpbridge_deregister_driver);
174 int gb_gpbridge_get_version(struct gb_connection *connection)
176 struct gb_protocol_version_request request;
177 struct gb_protocol_version_response response;
183 retval = gb_operation_sync(connection, GB_REQUEST_TYPE_PROTOCOL_VERSION,
184 &request, sizeof(request), &response,
189 /* FIXME - do proper version negotiation here someday... */
191 connection->module_major = response.major;
192 connection->module_minor = response.minor;
194 dev_dbg(&connection->hd->dev, "%s: v%u.%u\n", connection->name,
195 response.major, response.minor);
199 EXPORT_SYMBOL_GPL(gb_gpbridge_get_version);
201 static struct gpbridge_device *gb_gpbridge_create_dev(struct gb_bundle *bundle,
202 struct greybus_descriptor_cport *cport_desc)
204 struct gpbridge_device *gpbdev;
208 id = ida_simple_get(&gpbridge_id, 1, 0, GFP_KERNEL);
212 gpbdev = kzalloc(sizeof(*gpbdev), GFP_KERNEL);
214 ida_simple_remove(&gpbridge_id, id);
215 return ERR_PTR(-ENOMEM);
219 gpbdev->bundle = bundle;
220 gpbdev->cport_desc = cport_desc;
221 gpbdev->dev.parent = &bundle->dev;
222 gpbdev->dev.bus = &gpbridge_bus_type;
223 gpbdev->dev.type = &greybus_gpbdev_type;
224 gpbdev->dev.groups = gpbdev_groups;
225 gpbdev->dev.dma_mask = bundle->dev.dma_mask;
226 dev_set_name(&gpbdev->dev, "gpb%d", id);
228 retval = device_register(&gpbdev->dev);
230 put_device(&gpbdev->dev);
231 return ERR_PTR(retval);
237 static void gb_gpbridge_disconnect(struct gb_bundle *bundle)
239 struct gpbridge_host *gpb_host = greybus_get_drvdata(bundle);
240 struct gpbridge_device *gpbdev, *temp;
242 list_for_each_entry_safe(gpbdev, temp, &gpb_host->devices, list) {
243 list_del(&gpbdev->list);
244 device_unregister(&gpbdev->dev);
250 static int gb_gpbridge_probe(struct gb_bundle *bundle,
251 const struct greybus_bundle_id *id)
253 struct gpbridge_host *gpb_host;
254 struct gpbridge_device *gpbdev;
257 if (bundle->num_cports == 0)
260 gpb_host = kzalloc(sizeof(*gpb_host), GFP_KERNEL);
264 gpb_host->bundle = bundle;
265 INIT_LIST_HEAD(&gpb_host->devices);
266 greybus_set_drvdata(bundle, gpb_host);
269 * Create a bunch of children devices, one per cport, and bind the
270 * bridged phy drivers to them.
272 for (i = 0; i < bundle->num_cports; ++i) {
273 gpbdev = gb_gpbridge_create_dev(bundle, &bundle->cport_desc[i]);
274 if (IS_ERR(gpbdev)) {
275 gb_gpbridge_disconnect(bundle);
276 return PTR_ERR(gpbdev);
278 list_add(&gpbdev->list, &gpb_host->devices);
284 static const struct greybus_bundle_id gb_gpbridge_id_table[] = {
285 { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_BRIDGED_PHY) },
288 MODULE_DEVICE_TABLE(greybus, gb_gpbridge_id_table);
290 static struct greybus_driver gb_gpbridge_driver = {
292 .probe = gb_gpbridge_probe,
293 .disconnect = gb_gpbridge_disconnect,
294 .id_table = gb_gpbridge_id_table,
297 static int __init gpbridge_init(void)
301 retval = bus_register(&gpbridge_bus_type);
303 pr_err("gpbridge bus register failed (%d)\n", retval);
307 retval = greybus_register(&gb_gpbridge_driver);
309 pr_err("error registering greybus driver\n");
316 bus_unregister(&gpbridge_bus_type);
317 ida_destroy(&gpbridge_id);
320 module_init(gpbridge_init);
322 static void __exit gpbridge_exit(void)
324 greybus_deregister(&gb_gpbridge_driver);
325 bus_unregister(&gpbridge_bus_type);
326 ida_destroy(&gpbridge_id);
328 module_exit(gpbridge_exit);
330 MODULE_LICENSE("GPL v2");