greybus: USB: convert to a gpbridge driver
authorGreg Kroah-Hartman <gregkh@google.com>
Thu, 5 May 2016 09:02:36 +0000 (14:32 +0530)
committerGreg Kroah-Hartman <gregkh@google.com>
Thu, 5 May 2016 20:38:57 +0000 (13:38 -0700)
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 <gregkh@google.com>
Signed-off-by: Vaibhav Hiremath <vaibhav.hiremath@linaro.org>
[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 <viresh.kumar@linaro.org>
Tested-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
drivers/staging/greybus/gpbridge.c
drivers/staging/greybus/gpbridge.h
drivers/staging/greybus/legacy.c
drivers/staging/greybus/usb.c

index 1dc6c8f..993cfac 100644 (file)
@@ -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();
index ab39003..1af20d8 100644 (file)
@@ -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);
index 95d1eda..06bd85c 100644 (file)
@@ -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) },
        { }
 };
index 25a6c7e..2b4789b 100644 (file)
@@ -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);