greybus: es2: clean up CDSI CPort reservation
authorJohan Hovold <johan@hovoldconsulting.com>
Wed, 11 May 2016 08:18:01 +0000 (10:18 +0200)
committerGreg Kroah-Hartman <gregkh@google.com>
Fri, 13 May 2016 13:30:05 +0000 (15:30 +0200)
Clean up the CDSI CPort reservation by adding a host-device helper and
CPort defines.

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

index f8bc3ec..c8ee779 100644 (file)
 #include "connection.h"
 #include "greybus_trace.h"
 
+
+/* Fixed CPort numbers */
+#define ES2_CPORT_CDSI0                16
+#define ES2_CPORT_CDSI1                17
+
 /* Memory sizes for the buffers sent to/from the ES2 controller */
 #define ES2_GBUF_MSG_SIZE_MAX  2048
 
@@ -941,7 +946,6 @@ static int ap_probe(struct usb_interface *interface,
        int retval;
        int i;
        int num_cports;
-       int cport_id;
 
        udev = usb_get_dev(interface_to_usbdev(interface));
 
@@ -960,14 +964,6 @@ static int ap_probe(struct usb_interface *interface,
                return PTR_ERR(hd);
        }
 
-       /*
-        * CPorts 16 and 17 are reserved for CDSI0 and CDSI1, make sure they
-        * won't be allocated dynamically.
-        */
-       do {
-               cport_id = ida_simple_get(&hd->cport_id_map, 16, 18, GFP_KERNEL);
-       } while (cport_id > 0);
-
        es2 = hd_to_es2(hd);
        es2->hd = hd;
        es2->usb_intf = interface;
@@ -976,6 +972,17 @@ static int ap_probe(struct usb_interface *interface,
        INIT_KFIFO(es2->apb_log_fifo);
        usb_set_intfdata(interface, es2);
 
+       /*
+        * Reserve the CDSI0 and CDSI1 CPorts so they won't be allocated
+        * dynamically.
+        */
+       retval = gb_hd_cport_reserve(hd, ES2_CPORT_CDSI0);
+       if (retval)
+               goto error;
+       retval = gb_hd_cport_reserve(hd, ES2_CPORT_CDSI1);
+       if (retval)
+               goto error;
+
        es2->cport_to_ep = kcalloc(hd->num_cports, sizeof(*es2->cport_to_ep),
                                   GFP_KERNEL);
        if (!es2->cport_to_ep) {
index f24e06b..b87e086 100644 (file)
@@ -39,6 +39,21 @@ static struct attribute *bus_attrs[] = {
 };
 ATTRIBUTE_GROUPS(bus);
 
+int gb_hd_cport_reserve(struct gb_host_device *hd, u16 cport_id)
+{
+       struct ida *id_map = &hd->cport_id_map;
+       int ret;
+
+       ret = ida_simple_get(id_map, cport_id, cport_id + 1, GFP_KERNEL);
+       if (ret < 0) {
+               dev_err(&hd->dev, "failed to reserve cport %u\n", cport_id);
+               return ret;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(gb_hd_cport_reserve);
+
 /* Locking: Caller guarantees serialisation */
 int gb_hd_cport_allocate(struct gb_host_device *hd, int cport_id)
 {
index 4a197ac..5d74e0c 100644 (file)
@@ -50,6 +50,7 @@ struct gb_host_device {
 };
 #define to_gb_host_device(d) container_of(d, struct gb_host_device, dev)
 
+int gb_hd_cport_reserve(struct gb_host_device *hd, u16 cport_id);
 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);