greybus: es2: add support for greybus cport flags
authorJohan Hovold <johan@hovoldconsulting.com>
Wed, 22 Jun 2016 09:42:05 +0000 (11:42 +0200)
committerGreg Kroah-Hartman <gregkh@google.com>
Fri, 24 Jun 2016 23:22:30 +0000 (16:22 -0700)
Add support for Greybus CPort flags that are sent to the bridge through
a new USB vendor request when enabling a CPort as part of connection
establishment.

Currently the Greybus control and high-priority connection flags are
recognised and forwarded to APBA.

Reviewed-by: Alex Elder <elder@linaro.org>
Signed-off-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
drivers/staging/greybus/es2.c
drivers/staging/greybus/greybus_protocols.h

index 89fe764..2217445 100644 (file)
@@ -607,6 +607,47 @@ static void es2_cport_release(struct gb_host_device *hd, u16 cport_id)
        ida_simple_remove(&hd->cport_id_map, cport_id);
 }
 
+static int cport_enable(struct gb_host_device *hd, u16 cport_id,
+                       unsigned long flags)
+{
+       struct es2_ap_dev *es2 = hd_to_es2(hd);
+       struct usb_device *udev = es2->usb_dev;
+       struct gb_apb_request_cport_flags *req;
+       int ret;
+
+       req = kzalloc(sizeof(*req), GFP_KERNEL);
+       if (!req)
+               return -ENOMEM;
+
+       if (flags & GB_CONNECTION_FLAG_CONTROL)
+               req->flags |= GB_APB_CPORT_FLAG_CONTROL;
+       if (flags & GB_CONNECTION_FLAG_HIGH_PRIO)
+               req->flags |= GB_APB_CPORT_FLAG_HIGH_PRIO;
+
+       dev_dbg(&hd->dev, "%s - cport = %u, flags = %02x\n", __func__,
+                       cport_id, req->flags);
+
+       ret = usb_control_msg(udev, usb_sndctrlpipe(udev, 0),
+                               GB_APB_REQUEST_CPORT_FLAGS,
+                               USB_DIR_OUT | USB_TYPE_VENDOR |
+                               USB_RECIP_INTERFACE, cport_id, 0,
+                               req, sizeof(*req), ES2_TIMEOUT);
+       if (ret != sizeof(*req)) {
+               dev_err(&udev->dev, "failed to set cport flags for port %d\n",
+                               cport_id);
+               if (ret >= 0)
+                       ret = -EIO;
+
+               goto out;
+       }
+
+       ret = 0;
+out:
+       kfree(req);
+
+       return ret;
+}
+
 static int cport_disable(struct gb_host_device *hd, u16 cport_id)
 {
        int retval;
@@ -799,6 +840,7 @@ static struct gb_hd_driver es2_driver = {
        .message_cancel                 = message_cancel,
        .cport_allocate                 = es2_cport_allocate,
        .cport_release                  = es2_cport_release,
+       .cport_enable                   = cport_enable,
        .cport_disable                  = cport_disable,
        .latency_tag_enable             = latency_tag_enable,
        .latency_tag_disable            = latency_tag_disable,
index 203bc46..327d01f 100644 (file)
@@ -225,6 +225,16 @@ struct gb_control_timesync_get_last_event_response {
 #define REQUEST_TIMESYNC_AUTHORITATIVE         0x0f
 #define REQUEST_TIMESYNC_GET_LAST_EVENT                0x10
 
+/* requests to set Greybus CPort flags */
+#define GB_APB_REQUEST_CPORT_FLAGS             0x11
+
+struct gb_apb_request_cport_flags {
+       u32     flags;
+#define GB_APB_CPORT_FLAG_CONTROL              0x01
+#define GB_APB_CPORT_FLAG_HIGH_PRIO            0x02
+} __packed;
+
+
 /* Firmware Download Protocol */
 
 /* Request Types */