greybus: hd: make svc-connection life time coincide with host-device
authorJohan Hovold <johan@hovoldconsulting.com>
Mon, 7 Dec 2015 14:05:36 +0000 (15:05 +0100)
committerGreg Kroah-Hartman <gregkh@google.com>
Tue, 8 Dec 2015 20:31:14 +0000 (15:31 -0500)
Create the svc-connection as part of the host device, and destroy it in
the host-device destructor.

The svc-connection is enabled when registering the host device, and
disabled when the host device is deregistered.

Signed-off-by: Johan Hovold <johan@hovoldconsulting.com>
Reviewed-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
drivers/staging/greybus/connection.c
drivers/staging/greybus/connection.h
drivers/staging/greybus/hd.c

index c93650268b9971ae5d28c0cdc4c33e29f50d84ef..38604e8971d16d53090ed1c75d7262c303efe826 100644 (file)
@@ -437,7 +437,7 @@ err_unbind_protocol:
        return ret;
 }
 
-static void gb_connection_exit(struct gb_connection *connection)
+void gb_connection_exit(struct gb_connection *connection)
 {
        spin_lock_irq(&connection->lock);
        if (connection->state != GB_CONNECTION_STATE_ENABLED) {
index 329b705bd42586bea4357cdaad6a950173c80803..b795b44c1859c5b6f8de5c7a86fe8911013a8ad9 100644 (file)
@@ -64,6 +64,7 @@ static inline bool gb_connection_is_static(struct gb_connection *connection)
 }
 
 int gb_connection_init(struct gb_connection *connection);
+void gb_connection_exit(struct gb_connection *connection);
 
 void greybus_data_rcvd(struct gb_host_device *hd, u16 cport_id,
                        u8 *data, size_t length);
index e38c41c31f047df7e4e26d38bd1fd390cc7cdf66..469b31e0023718ede8e93c81971170c088f73af6 100644 (file)
@@ -21,6 +21,8 @@ static void gb_hd_release(struct device *dev)
 {
        struct gb_host_device *hd = to_gb_host_device(dev);
 
+       if (hd->svc_connection)
+               gb_connection_destroy(hd->svc_connection);
        ida_simple_remove(&gb_hd_bus_id_map, hd->bus_id);
        ida_destroy(&hd->cport_id_map);
        kfree(hd);
@@ -93,21 +95,17 @@ struct gb_host_device *gb_hd_create(struct gb_hd_driver *driver,
        device_initialize(&hd->dev);
        dev_set_name(&hd->dev, "greybus%d", hd->bus_id);
 
-       return hd;
-}
-EXPORT_SYMBOL_GPL(gb_hd_create);
-
-static int gb_hd_create_svc_connection(struct gb_host_device *hd)
-{
        hd->svc_connection = gb_connection_create_static(hd, GB_SVC_CPORT_ID,
                                                        GREYBUS_PROTOCOL_SVC);
        if (!hd->svc_connection) {
                dev_err(&hd->dev, "failed to create svc connection\n");
-               return -ENOMEM;
+               put_device(&hd->dev);
+               return ERR_PTR(-ENOMEM);
        }
 
-       return 0;
+       return hd;
 }
+EXPORT_SYMBOL_GPL(gb_hd_create);
 
 int gb_hd_add(struct gb_host_device *hd)
 {
@@ -117,15 +115,8 @@ int gb_hd_add(struct gb_host_device *hd)
        if (ret)
                return ret;
 
-       ret = gb_hd_create_svc_connection(hd);
-       if (ret) {
-               device_del(&hd->dev);
-               return ret;
-       }
-
        ret = gb_connection_init(hd->svc_connection);
        if (ret) {
-               gb_connection_destroy(hd->svc_connection);
                device_del(&hd->dev);
                return ret;
        }
@@ -138,7 +129,7 @@ void gb_hd_del(struct gb_host_device *hd)
 {
        gb_interfaces_remove(hd);
 
-       gb_connection_destroy(hd->svc_connection);
+       gb_connection_exit(hd->svc_connection);
 
        device_del(&hd->dev);
 }