]> git.karo-electronics.de Git - linux-beck.git/commitdiff
greybus: es2: add support for CDSI1 allocation
authorJohan Hovold <johan@hovoldconsulting.com>
Wed, 11 May 2016 08:18:04 +0000 (10:18 +0200)
committerGreg Kroah-Hartman <gregkh@google.com>
Fri, 13 May 2016 13:32:48 +0000 (15:32 +0200)
Use the new CPort-allocation callbacks to allow for rudimentary resource
management of the CDSI CPorts.

How to manage offloaded resources in a generic fashion is yet to be
determined, but this minimal implementation will allow core to manage
the camera data connection so that the current camera-driver hacks can
be removed. This is specifically required to be able to implement proper
connection closing and for power management.

Note that the CDSI CPorts can not (currently) be reset through the
USB vendor request.

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

index a8da9ca214bec2261ea303623d6df85bc42283bd..b152e2340591b4394255aad1b4950594cc95dec6 100644 (file)
@@ -16,6 +16,7 @@
 #define GB_CONNECTION_FLAG_CSD         BIT(0)
 #define GB_CONNECTION_FLAG_NO_FLOWCTRL BIT(1)
 #define GB_CONNECTION_FLAG_OFFLOADED   BIT(2)
+#define GB_CONNECTION_FLAG_CDSI1       BIT(3)
 
 enum gb_connection_state {
        GB_CONNECTION_STATE_INVALID     = 0,
index f06a322f851a099cf63758ae6fe4ebb4c29fb512..998b41ebc53e8fa5cb8b588412900204fe1ac17c 100644 (file)
@@ -99,6 +99,8 @@ struct es2_ap_dev {
        bool cport_out_urb_cancelled[NUM_CPORT_OUT_URB];
        spinlock_t cport_out_urb_lock;
 
+       bool cdsi1_in_use;
+
        int *cport_to_ep;
 
        struct task_struct *apb_log_task;
@@ -508,6 +510,8 @@ static int cport_reset(struct gb_host_device *hd, u16 cport_id)
 
        switch (cport_id) {
        case GB_SVC_CPORT_ID:
+       case ES2_CPORT_CDSI0:
+       case ES2_CPORT_CDSI1:
                return 0;
        }
 
@@ -525,6 +529,59 @@ static int cport_reset(struct gb_host_device *hd, u16 cport_id)
        return 0;
 }
 
+static int es2_cport_allocate(struct gb_host_device *hd, int cport_id,
+                               unsigned long flags)
+{
+       struct es2_ap_dev *es2 = hd_to_es2(hd);
+       struct ida *id_map = &hd->cport_id_map;
+       int ida_start, ida_end;
+
+       switch (cport_id) {
+       case ES2_CPORT_CDSI0:
+       case ES2_CPORT_CDSI1:
+               dev_err(&hd->dev, "cport %d not available\n", cport_id);
+               return -EBUSY;
+       }
+
+       if (flags & GB_CONNECTION_FLAG_OFFLOADED &&
+                       flags & GB_CONNECTION_FLAG_CDSI1) {
+               if (es2->cdsi1_in_use) {
+                       dev_err(&hd->dev, "CDSI1 already in use\n");
+                       return -EBUSY;
+               }
+
+               es2->cdsi1_in_use = true;
+
+               return ES2_CPORT_CDSI1;
+       }
+
+       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);
+}
+
+static void es2_cport_release(struct gb_host_device *hd, u16 cport_id)
+{
+       struct es2_ap_dev *es2 = hd_to_es2(hd);
+
+       switch (cport_id) {
+       case ES2_CPORT_CDSI1:
+               es2->cdsi1_in_use = false;
+               return;
+       }
+
+       ida_simple_remove(&hd->cport_id_map, cport_id);
+}
+
 static int cport_enable(struct gb_host_device *hd, u16 cport_id)
 {
        int retval;
@@ -621,6 +678,8 @@ static struct gb_hd_driver es2_driver = {
        .hd_priv_size           = sizeof(struct es2_ap_dev),
        .message_send           = message_send,
        .message_cancel         = message_cancel,
+       .cport_allocate         = es2_cport_allocate,
+       .cport_release          = es2_cport_release,
        .cport_enable           = cport_enable,
        .latency_tag_enable     = latency_tag_enable,
        .latency_tag_disable    = latency_tag_disable,