diff --git a/drivers/staging/greybus/Makefile b/drivers/staging/greybus/Makefile index b1272cbd55ee..1e24509bdb4d 100644 --- a/drivers/staging/greybus/Makefile +++ b/drivers/staging/greybus/Makefile @@ -9,7 +9,8 @@ greybus-y := core.o \ control.o \ svc.o \ firmware.o \ - operation.o + operation.o \ + legacy.o gb-phy-y := gpbridge.o \ sdio.o \ diff --git a/drivers/staging/greybus/bundle.c b/drivers/staging/greybus/bundle.c index fb775ff1895d..ec52bdecb5c1 100644 --- a/drivers/staging/greybus/bundle.c +++ b/drivers/staging/greybus/bundle.c @@ -152,21 +152,11 @@ int gb_bundle_add(struct gb_bundle *bundle) return 0; } -static void gb_bundle_connections_exit(struct gb_bundle *bundle) -{ - struct gb_connection *connection; - - list_for_each_entry(connection, &bundle->connections, bundle_links) - gb_connection_exit(connection); -} - /* * Tear down a previously set up bundle. */ void gb_bundle_destroy(struct gb_bundle *bundle) { - gb_bundle_connections_exit(bundle); - if (device_is_registered(&bundle->dev)) device_del(&bundle->dev); diff --git a/drivers/staging/greybus/connection.c b/drivers/staging/greybus/connection.c index 6295d28a4be4..21e6eb52c437 100644 --- a/drivers/staging/greybus/connection.c +++ b/drivers/staging/greybus/connection.c @@ -464,6 +464,7 @@ int gb_connection_init(struct gb_connection *connection) return ret; } +EXPORT_SYMBOL_GPL(gb_connection_init); void gb_connection_exit(struct gb_connection *connection) { @@ -482,6 +483,7 @@ void gb_connection_exit(struct gb_connection *connection) gb_connection_unbind_protocol(connection); } +EXPORT_SYMBOL_GPL(gb_connection_exit); /* * Tear down a previously set up connection. diff --git a/drivers/staging/greybus/core.c b/drivers/staging/greybus/core.c index 0e2f99df6cfa..28f48d79b005 100644 --- a/drivers/staging/greybus/core.c +++ b/drivers/staging/greybus/core.c @@ -12,6 +12,7 @@ #define CREATE_TRACE_POINTS #include "greybus.h" #include "greybus_trace.h" +#include "legacy.h" EXPORT_TRACEPOINT_SYMBOL_GPL(gb_host_device_send); EXPORT_TRACEPOINT_SYMBOL_GPL(gb_host_device_recv); @@ -240,8 +241,16 @@ static int __init gb_init(void) goto error_firmware; } + retval = gb_legacy_init(); + if (retval) { + pr_err("gb_legacy_init failed\n"); + goto error_legacy; + } + return 0; /* Success */ +error_legacy: + gb_firmware_protocol_exit(); error_firmware: gb_svc_protocol_exit(); error_svc: @@ -261,6 +270,7 @@ module_init(gb_init); static void __exit gb_exit(void) { + gb_legacy_exit(); gb_firmware_protocol_exit(); gb_svc_protocol_exit(); gb_control_protocol_exit(); diff --git a/drivers/staging/greybus/interface.c b/drivers/staging/greybus/interface.c index edac2383e492..c3453502ae22 100644 --- a/drivers/staging/greybus/interface.c +++ b/drivers/staging/greybus/interface.c @@ -183,7 +183,6 @@ void gb_interfaces_remove(struct gb_host_device *hd) int gb_interface_init(struct gb_interface *intf, u8 device_id) { struct gb_bundle *bundle, *tmp; - struct gb_connection *connection; int ret, size; void *manifest; @@ -242,15 +241,6 @@ int gb_interface_init(struct gb_interface *intf, u8 device_id) gb_bundle_destroy(bundle); continue; } - - list_for_each_entry(connection, &bundle->connections, - bundle_links) { - ret = gb_connection_init(connection); - if (ret) - break; - } - if (ret) - gb_bundle_destroy(bundle); } ret = 0; diff --git a/drivers/staging/greybus/legacy.c b/drivers/staging/greybus/legacy.c new file mode 100644 index 000000000000..26a7d1a05256 --- /dev/null +++ b/drivers/staging/greybus/legacy.c @@ -0,0 +1,95 @@ +/* + * Greybus legacy-protocol driver + * + * Copyright 2015 Google Inc. + * Copyright 2015 Linaro Ltd. + * + * Released under the GPLv2 only. + */ + +#include "greybus.h" +#include "legacy.h" + +static int legacy_probe(struct gb_bundle *bundle, + const struct greybus_bundle_id *id) +{ + struct gb_connection *connection; + int ret; + + dev_dbg(&bundle->dev, "%s - bundle class = 0x%02x\n", __func__, + bundle->class); + + list_for_each_entry(connection, &bundle->connections, bundle_links) { + dev_dbg(&bundle->dev, "enabling connection %s\n", + connection->name); + + ret = gb_connection_init(connection); + if (ret) + goto err_connections_disable; + } + + return 0; + +err_connections_disable: + list_for_each_entry_reverse(connection, &bundle->connections, + bundle_links) { + gb_connection_exit(connection); + } + + return ret; +} + +static void legacy_disconnect(struct gb_bundle *bundle) +{ + struct gb_connection *connection; + + dev_dbg(&bundle->dev, "%s - bundle class = 0x%02x\n", __func__, + bundle->class); + + list_for_each_entry_reverse(connection, &bundle->connections, + bundle_links) { + gb_connection_exit(connection); + } +} + +static const struct greybus_bundle_id legacy_id_table[] = { + { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_GPIO) }, + { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_I2C) }, + { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_UART) }, + { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_HID) }, + { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_USB) }, + { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_SDIO) }, + { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_POWER_SUPPLY) }, + { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_PWM) }, + { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_SPI) }, + { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_DISPLAY) }, + { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_CAMERA) }, + { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_SENSOR) }, + { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_LIGHTS) }, + { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_VIBRATOR) }, + { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_LOOPBACK) }, + { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_AUDIO_MGMT) }, + { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_AUDIO_DATA) }, + { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_SVC) }, + { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_FIRMWARE) }, + { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_RAW) }, + { } +}; +MODULE_DEVICE_TABLE(greybus, legacy_id_table); + +static struct greybus_driver legacy_driver = { + .name = "legacy", + .probe = legacy_probe, + .disconnect = legacy_disconnect, + .id_table = legacy_id_table, +}; + +int gb_legacy_init(void) +{ + return greybus_register(&legacy_driver); +} + +void gb_legacy_exit(void) +{ + greybus_deregister(&legacy_driver); +} diff --git a/drivers/staging/greybus/legacy.h b/drivers/staging/greybus/legacy.h new file mode 100644 index 000000000000..2177f6aaed3c --- /dev/null +++ b/drivers/staging/greybus/legacy.h @@ -0,0 +1,16 @@ +/* + * Greybus legacy-protocol driver + * + * Copyright 2015 Google Inc. + * Copyright 2015 Linaro Ltd. + * + * Released under the GPLv2 only. + */ + +#ifndef __LEGACY_H +#define __LEGACY_H + +int gb_legacy_init(void); +void gb_legacy_exit(void); + +#endif /* __LEGACY_H */