From 4dda7e96cfc6474d88682547180a9e42687c5a6e Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Thu, 5 May 2016 14:32:36 +0530 Subject: [PATCH] greybus: USB: convert to a gpbridge driver This converts the USB driver to be a gpbridge driver, moving it away from the "legacy" interface. It's not like this code even does anything at the moment, how much trouble could we cause with this change? :) Testing Done: Tested on gbsim. Signed-off-by: Greg Kroah-Hartman Signed-off-by: Vaibhav Hiremath [vaibhav.hiremath@linaro.org: 1.Changed code to retain init/exit fns of drivers. 2.Exit path fix. 3. Fixed review comments] Reviewed-by: Viresh Kumar Tested-by: Viresh Kumar Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/gpbridge.c | 11 ++--- drivers/staging/greybus/gpbridge.h | 4 +- drivers/staging/greybus/legacy.c | 1 - drivers/staging/greybus/usb.c | 68 +++++++++++++++++++++--------- 4 files changed, 55 insertions(+), 29 deletions(-) diff --git a/drivers/staging/greybus/gpbridge.c b/drivers/staging/greybus/gpbridge.c index 1dc6c8f85778..993cfacb65aa 100644 --- a/drivers/staging/greybus/gpbridge.c +++ b/drivers/staging/greybus/gpbridge.c @@ -258,6 +258,7 @@ static const struct greybus_bundle_id gb_gpbridge_id_table[] = { { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_SDIO) }, { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_SPI) }, { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_UART) }, + { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_USB) }, { }, }; MODULE_DEVICE_TABLE(greybus, gb_gpbridge_id_table); @@ -301,8 +302,8 @@ static int __init gpbridge_init(void) pr_err("error initializing sdio driver\n"); goto error_sdio; } - if (gb_usb_protocol_init()) { - pr_err("error initializing usb protocol\n"); + if (gb_usb_driver_init()) { + pr_err("error initializing usb driver\n"); goto error_usb; } if (gb_i2c_driver_init()) { @@ -319,7 +320,7 @@ static int __init gpbridge_init(void) error_spi: gb_i2c_driver_exit(); error_i2c: - gb_usb_protocol_exit(); + gb_usb_driver_exit(); error_usb: gb_sdio_driver_exit(); error_sdio: @@ -333,7 +334,7 @@ error_gpio: error_gpbridge: bus_unregister(&gpbridge_bus_type); ida_destroy(&gpbridge_id); - return -EPROTO; + return retval; } module_init(gpbridge_init); @@ -341,7 +342,7 @@ static void __exit gpbridge_exit(void) { gb_spi_driver_exit(); gb_i2c_driver_exit(); - gb_usb_protocol_exit(); + gb_usb_driver_exit(); gb_sdio_driver_exit(); gb_uart_driver_exit(); gb_pwm_driver_exit(); diff --git a/drivers/staging/greybus/gpbridge.h b/drivers/staging/greybus/gpbridge.h index ab3900363ec8..1af20d88af4b 100644 --- a/drivers/staging/greybus/gpbridge.h +++ b/drivers/staging/greybus/gpbridge.h @@ -78,8 +78,8 @@ extern void gb_uart_driver_exit(void); extern int gb_sdio_driver_init(void); extern void gb_sdio_driver_exit(void); -extern int gb_usb_protocol_init(void); -extern void gb_usb_protocol_exit(void); +extern int gb_usb_driver_init(void); +extern void gb_usb_driver_exit(void); extern int gb_i2c_driver_init(void); extern void gb_i2c_driver_exit(void); diff --git a/drivers/staging/greybus/legacy.c b/drivers/staging/greybus/legacy.c index 95d1eda98f72..06bd85cc4459 100644 --- a/drivers/staging/greybus/legacy.c +++ b/drivers/staging/greybus/legacy.c @@ -236,7 +236,6 @@ static void legacy_disconnect(struct gb_bundle *bundle) } static const struct greybus_bundle_id legacy_id_table[] = { - { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_USB) }, { GREYBUS_DEVICE_CLASS(GREYBUS_CLASS_CAMERA) }, { } }; diff --git a/drivers/staging/greybus/usb.c b/drivers/staging/greybus/usb.c index 25a6c7e5e5ba..2b4789bde0c2 100644 --- a/drivers/staging/greybus/usb.c +++ b/drivers/staging/greybus/usb.c @@ -38,6 +38,7 @@ struct gb_usb_hub_control_response { struct gb_usb_device { struct gb_connection *connection; + struct gpbridge_device *gpbdev; }; static inline struct gb_usb_device *to_gb_usb_device(struct usb_hcd *hcd) @@ -58,8 +59,7 @@ static void hcd_stop(struct usb_hcd *hcd) ret = gb_operation_sync(dev->connection, GB_USB_TYPE_HCD_STOP, NULL, 0, NULL, 0); if (ret) - dev_err(&dev->connection->bundle->dev, - "HCD stop failed '%d'\n", ret); + dev_err(&dev->gpbdev->dev, "HCD stop failed '%d'\n", ret); } static int hcd_start(struct usb_hcd *hcd) @@ -71,8 +71,7 @@ static int hcd_start(struct usb_hcd *hcd) ret = gb_operation_sync(dev->connection, GB_USB_TYPE_HCD_START, NULL, 0, NULL, 0); if (ret) { - dev_err(&dev->connection->bundle->dev, - "HCD start failed '%d'\n", ret); + dev_err(&dev->gpbdev->dev, "HCD start failed '%d'\n", ret); return ret; } @@ -162,24 +161,43 @@ static struct hc_driver usb_gb_hc_driver = { .hub_control = hub_control, }; -static int gb_usb_connection_init(struct gb_connection *connection) +static int gb_usb_probe(struct gpbridge_device *gpbdev, + const struct gpbridge_device_id *id) { - struct device *dev = &connection->bundle->dev; + struct gb_connection *connection; + struct device *dev = &gpbdev->dev; struct gb_usb_device *gb_usb_dev; struct usb_hcd *hcd; - int retval; hcd = usb_create_hcd(&usb_gb_hc_driver, dev, dev_name(dev)); if (!hcd) return -ENOMEM; + connection = gb_connection_create(gpbdev->bundle, + le16_to_cpu(gpbdev->cport_desc->id), + NULL); + if (IS_ERR(connection)) { + retval = PTR_ERR(connection); + goto exit_usb_put; + } + gb_usb_dev = to_gb_usb_device(hcd); gb_usb_dev->connection = connection; gb_connection_set_data(connection, gb_usb_dev); + gb_usb_dev->gpbdev = gpbdev; + gb_gpbridge_set_data(gpbdev, gb_usb_dev); hcd->has_tt = 1; + retval = gb_connection_enable(connection); + if (retval) + goto exit_connection_destroy; + + retval = gb_gpbridge_get_version(connection); + if (retval) + goto exit_connection_disable; + /* * FIXME: The USB bridged-PHY protocol driver depends on changes to * USB core which are not yet upstream. @@ -189,38 +207,46 @@ static int gb_usb_connection_init(struct gb_connection *connection) if (1) { dev_warn(dev, "USB protocol disabled\n"); retval = -EPROTONOSUPPORT; - goto err_put_hcd; + goto exit_connection_disable; } retval = usb_add_hcd(hcd, 0, 0); if (retval) - goto err_put_hcd; + goto exit_connection_disable; return 0; -err_put_hcd: +exit_connection_disable: + gb_connection_disable(connection); +exit_connection_destroy: + gb_connection_destroy(connection); +exit_usb_put: usb_put_hcd(hcd); return retval; } -static void gb_usb_connection_exit(struct gb_connection *connection) +static void gb_usb_remove(struct gpbridge_device *gpbdev) { - struct gb_usb_device *gb_usb_dev = gb_connection_get_data(connection); + struct gb_usb_device *gb_usb_dev = gb_gpbridge_get_data(gpbdev); + struct gb_connection *connection = gb_usb_dev->connection; struct usb_hcd *hcd = gb_usb_device_to_hcd(gb_usb_dev); usb_remove_hcd(hcd); + gb_connection_disable(connection); + gb_connection_destroy(connection); usb_put_hcd(hcd); } -static struct gb_protocol usb_protocol = { - .name = "usb", - .id = GREYBUS_PROTOCOL_USB, - .major = GB_USB_VERSION_MAJOR, - .minor = GB_USB_VERSION_MINOR, - .connection_init = gb_usb_connection_init, - .connection_exit = gb_usb_connection_exit, - .request_recv = NULL, /* FIXME we have requests!!! */ +static const struct gpbridge_device_id gb_usb_id_table[] = { + { GPBRIDGE_PROTOCOL(GREYBUS_PROTOCOL_USB) }, + { }, }; -gb_builtin_protocol_driver(usb_protocol); +static struct gpbridge_driver usb_driver = { + .name = "usb", + .probe = gb_usb_probe, + .remove = gb_usb_remove, + .id_table = gb_usb_id_table, +}; +gb_gpbridge_builtin_driver(usb_driver); -- 2.39.5