greybus: hd: add optional cport enable and disable callbacks
authorJohan Hovold <johan@hovoldconsulting.com>
Thu, 17 Sep 2015 11:17:26 +0000 (13:17 +0200)
committerGreg Kroah-Hartman <gregkh@google.com>
Thu, 17 Sep 2015 21:35:47 +0000 (14:35 -0700)
Add optional cport enable and disable callbacks to the greybus host
drivers, that can be used to initialise and allocate/release resources
associated with a cport during connection setup/teardown (e.g. software
queues and hardware state).

Signed-off-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
drivers/staging/greybus/connection.c
drivers/staging/greybus/greybus.h

index 91d1e477a6b6f620b9da6d8b2694a6440177101a..b4947f01d22bdd81739b2955026fd6f7817a1806 100644 (file)
@@ -284,6 +284,34 @@ err_remove_ida:
        return NULL;
 }
 
+static int gb_connection_hd_cport_enable(struct gb_connection *connection)
+{
+       struct greybus_host_device *hd = connection->hd;
+       int ret;
+
+       if (!hd->driver->cport_enable)
+               return 0;
+
+       ret = hd->driver->cport_enable(hd, connection->hd_cport_id);
+       if (ret) {
+               dev_err(&connection->dev,
+                               "failed to enable host cport: %d\n", ret);
+               return ret;
+       }
+
+       return 0;
+}
+
+static void gb_connection_hd_cport_disable(struct gb_connection *connection)
+{
+       struct greybus_host_device *hd = connection->hd;
+
+       if (!hd->driver->cport_disable)
+               return;
+
+       hd->driver->cport_disable(hd, connection->hd_cport_id);
+}
+
 struct gb_connection *gb_connection_create(struct gb_bundle *bundle,
                                u16 cport_id, u8 protocol_id)
 {
@@ -439,10 +467,14 @@ static int gb_connection_init(struct gb_connection *connection)
        struct gb_protocol *protocol = connection->protocol;
        int ret;
 
-       ret = gb_connection_svc_connection_create(connection);
+       ret = gb_connection_hd_cport_enable(connection);
        if (ret)
                return ret;
 
+       ret = gb_connection_svc_connection_create(connection);
+       if (ret)
+               goto err_hd_cport_disable;
+
        ret = gb_connection_control_connected(connection);
        if (ret)
                goto err_svc_destroy;
@@ -470,6 +502,8 @@ err_disconnect:
        gb_connection_control_disconnected(connection);
 err_svc_destroy:
        gb_connection_svc_connection_destroy(connection);
+err_hd_cport_disable:
+       gb_connection_hd_cport_disable(connection);
 
        return ret;
 }
@@ -492,6 +526,7 @@ static void gb_connection_exit(struct gb_connection *connection)
        connection->protocol->connection_exit(connection);
        gb_connection_control_disconnected(connection);
        gb_connection_svc_connection_destroy(connection);
+       gb_connection_hd_cport_disable(connection);
 }
 
 /*
index 9f2eb1f2e8a9c7192fb2e72f80ad220a99e7a7ee..a320d58a219a79013be5dd6dcd16f0b509194e23 100644 (file)
@@ -75,6 +75,8 @@ struct greybus_host_device;
 struct greybus_host_driver {
        size_t  hd_priv_size;
 
+       int (*cport_enable)(struct greybus_host_device *hd, u16 cport_id);
+       int (*cport_disable)(struct greybus_host_device *hd, u16 cport_id);
        void (*connection_create)(struct gb_connection *connection);
        void (*connection_destroy)(struct gb_connection *connection);
        int (*message_send)(struct greybus_host_device *hd, u16 dest_cport_id,