greybus: hd: move CPort allocation to host-device code
authorJohan Hovold <johan@hovoldconsulting.com>
Wed, 11 May 2016 08:17:59 +0000 (10:17 +0200)
committerGreg Kroah-Hartman <gregkh@google.com>
Fri, 13 May 2016 13:30:05 +0000 (15:30 +0200)
Move host-device CPort allocation to the host-device code.

Proper CPort allocation requires knowledge of the hardware and must be
handled by the host-device driver. This is an intermediate step that
moves the generic CPort-allocation code to the host-device code.

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/hd.c
drivers/staging/greybus/hd.h

index 95855d1..ac99fc0 100644 (file)
@@ -142,21 +142,8 @@ _gb_connection_create(struct gb_host_device *hd, int hd_cport_id,
                                unsigned long flags)
 {
        struct gb_connection *connection;
-       struct ida *id_map = &hd->cport_id_map;
-       int ida_start, ida_end;
        int ret;
 
-       if (hd_cport_id < 0) {
-               ida_start = 0;
-               ida_end = hd->num_cports;
-       } else if (hd_cport_id < hd->num_cports) {
-               ida_start = hd_cport_id;
-               ida_end = hd_cport_id + 1;
-       } else {
-               dev_err(&hd->dev, "cport %d not available\n", hd_cport_id);
-               return ERR_PTR(-EINVAL);
-       }
-
        mutex_lock(&gb_connection_mutex);
 
        if (intf && gb_connection_intf_find(intf, cport_id)) {
@@ -165,15 +152,17 @@ _gb_connection_create(struct gb_host_device *hd, int hd_cport_id,
                goto err_unlock;
        }
 
-       ret = ida_simple_get(id_map, ida_start, ida_end, GFP_KERNEL);
-       if (ret < 0)
+       ret = gb_hd_cport_allocate(hd, hd_cport_id);
+       if (ret < 0) {
+               dev_err(&hd->dev, "failed to allocate cport: %d\n", ret);
                goto err_unlock;
+       }
        hd_cport_id = ret;
 
        connection = kzalloc(sizeof(*connection), GFP_KERNEL);
        if (!connection) {
                ret = -ENOMEM;
-               goto err_remove_ida;
+               goto err_hd_cport_release;
        }
 
        connection->hd_cport_id = hd_cport_id;
@@ -219,8 +208,8 @@ _gb_connection_create(struct gb_host_device *hd, int hd_cport_id,
 
 err_free_connection:
        kfree(connection);
-err_remove_ida:
-       ida_simple_remove(id_map, hd_cport_id);
+err_hd_cport_release:
+       gb_hd_cport_release(hd, hd_cport_id);
 err_unlock:
        mutex_unlock(&gb_connection_mutex);
 
@@ -658,8 +647,6 @@ EXPORT_SYMBOL_GPL(gb_connection_disable);
 /* Caller must have disabled the connection before destroying it. */
 void gb_connection_destroy(struct gb_connection *connection)
 {
-       struct ida *id_map;
-
        if (!connection)
                return;
 
@@ -672,8 +659,7 @@ void gb_connection_destroy(struct gb_connection *connection)
 
        destroy_workqueue(connection->wq);
 
-       id_map = &connection->hd->cport_id_map;
-       ida_simple_remove(id_map, connection->hd_cport_id);
+       gb_hd_cport_release(connection->hd, connection->hd_cport_id);
        connection->hd_cport_id = CPORT_ID_BAD;
 
        mutex_unlock(&gb_connection_mutex);
index 2863472..f24e06b 100644 (file)
@@ -39,6 +39,32 @@ static struct attribute *bus_attrs[] = {
 };
 ATTRIBUTE_GROUPS(bus);
 
+/* Locking: Caller guarantees serialisation */
+int gb_hd_cport_allocate(struct gb_host_device *hd, int cport_id)
+{
+       struct ida *id_map = &hd->cport_id_map;
+       int ida_start, ida_end;
+
+       if (cport_id < 0) {
+               ida_start = 0;
+               ida_end = hd->num_cports;
+       } else if (cport_id < hd->num_cports) {
+               ida_start = cport_id;
+               ida_end = cport_id + 1;
+       } else {
+               dev_err(&hd->dev, "cport %d not available\n", cport_id);
+               return -EINVAL;
+       }
+
+       return ida_simple_get(id_map, ida_start, ida_end, GFP_KERNEL);
+}
+
+/* Locking: Caller guarantees serialisation */
+void gb_hd_cport_release(struct gb_host_device *hd, u16 cport_id)
+{
+       ida_simple_remove(&hd->cport_id_map, cport_id);
+}
+
 static void gb_hd_release(struct device *dev)
 {
        struct gb_host_device *hd = to_gb_host_device(dev);
index ff71936..4a197ac 100644 (file)
@@ -50,6 +50,9 @@ struct gb_host_device {
 };
 #define to_gb_host_device(d) container_of(d, struct gb_host_device, dev)
 
+int gb_hd_cport_allocate(struct gb_host_device *hd, int cport_id);
+void gb_hd_cport_release(struct gb_host_device *hd, u16 cport_id);
+
 struct gb_host_device *gb_hd_create(struct gb_hd_driver *driver,
                                        struct device *parent,
                                        size_t buffer_size_max,