greybus: interface: Get manifest using Control protocol
[cascardo/linux.git] / drivers / staging / greybus / ap.c
index ef64068..113fd87 100644 (file)
@@ -2,6 +2,7 @@
  * Greybus "AP" message loop handling
  *
  * Copyright 2014 Google Inc.
+ * Copyright 2014 Linaro Ltd.
  *
  * Released under the GPLv2 only.
  */
@@ -60,7 +61,7 @@ static int svc_msg_send(struct svc_msg *svc_msg, struct greybus_host_device *hd)
 }
 
 
-int svc_set_route_send(struct gb_interface *interface,
+int svc_set_route_send(struct gb_bundle *bundle,
                               struct greybus_host_device *hd)
 {
        struct svc_msg *svc_msg;
@@ -69,11 +70,10 @@ int svc_set_route_send(struct gb_interface *interface,
        if (!svc_msg)
                return -ENOMEM;
 
-       svc_msg->header.function_id = SVC_FUNCTION_UNIPRO_NETWORK_MANAGEMENT;
        svc_msg->header.message_type = SVC_MSG_DATA;
        svc_msg->header.payload_length =
                cpu_to_le16(sizeof(struct svc_function_unipro_set_route));
-       svc_msg->management.set_route.device_id = interface->device_id;
+       svc_msg->management.set_route.device_id = bundle->device_id;
 
        return svc_msg_send(svc_msg, hd);
 }
@@ -83,7 +83,7 @@ static void svc_handshake(struct svc_function_handshake *handshake,
 {
        struct svc_msg *svc_msg;
 
-       if (payload_length != sizeof(struct svc_function_handshake)) {
+       if (payload_length != sizeof(*handshake)) {
                dev_err(hd->parent,
                        "Illegal size of svc handshake message %d\n",
                        payload_length);
@@ -91,9 +91,10 @@ static void svc_handshake(struct svc_function_handshake *handshake,
        }
 
        /* A new SVC communication channel, let's verify a supported version */
-       if ((handshake->version_major != GREYBUS_VERSION_MAJOR) &&
+       if ((handshake->version_major != GREYBUS_VERSION_MAJOR) ||
            (handshake->version_minor != GREYBUS_VERSION_MINOR)) {
-               dev_dbg(hd->parent, "received invalid greybus version %d:%d\n",
+               dev_warn(hd->parent,
+                       "received invalid greybus version %u.%u\n",
                        handshake->version_major, handshake->version_minor);
                return;
        }
@@ -111,10 +112,9 @@ static void svc_handshake(struct svc_function_handshake *handshake,
        if (!svc_msg)
                return;
 
-       svc_msg->header.function_id = SVC_FUNCTION_HANDSHAKE;
        svc_msg->header.message_type = SVC_MSG_DATA;
        svc_msg->header.payload_length =
-               cpu_to_le16(sizeof(struct svc_function_handshake));
+               cpu_to_le16(sizeof(*handshake));
        svc_msg->handshake.version_major = GREYBUS_VERSION_MAJOR;
        svc_msg->handshake.version_minor = GREYBUS_VERSION_MINOR;
        svc_msg->handshake.handshake_type = SVC_HANDSHAKE_AP_HELLO;
@@ -125,10 +125,10 @@ static void svc_handshake(struct svc_function_handshake *handshake,
 static void svc_management(struct svc_function_unipro_management *management,
                           int payload_length, struct greybus_host_device *hd)
 {
-       struct gb_module *module;
+       struct gb_interface *intf;
        int ret;
 
-       if (payload_length != sizeof(struct svc_function_unipro_management)) {
+       if (payload_length != sizeof(*management)) {
                dev_err(hd->parent,
                        "Illegal size of svc management message %d\n",
                        payload_length);
@@ -140,20 +140,19 @@ static void svc_management(struct svc_function_unipro_management *management,
                hd->device_id = management->ap_id.device_id;
                break;
        case SVC_MANAGEMENT_LINK_UP:
-               module = gb_module_find(hd, management->link_up.module_id);
-               if (!module) {
-                       dev_err(hd->parent, "Module ID %d not found\n",
-                               management->link_up.module_id);
+               intf = gb_interface_find(hd, management->link_up.interface_id);
+               if (!intf) {
+                       dev_err(hd->parent, "Interface ID %d not found\n",
+                               management->link_up.interface_id);
+                       return;
+               }
+               ret = gb_interface_init(intf, management->link_up.device_id);
+               if (ret) {
+                       dev_err(hd->parent,
+                               "error %d initializing interface %hhu\n",
+                               ret, management->link_up.interface_id);
                        return;
                }
-               ret = gb_interface_init(module,
-                               management->link_up.interface_id,
-                               management->link_up.device_id);
-               if (ret)
-                       dev_err(hd->parent, "error %d initializing "
-                               "module %hhu interface %hhu\n",
-                               ret, management->link_up.module_id,
-                               management->link_up.interface_id);
                break;
        default:
                dev_err(hd->parent, "Unhandled UniPro management message\n");
@@ -163,25 +162,24 @@ static void svc_management(struct svc_function_unipro_management *management,
 static void svc_hotplug(struct svc_function_hotplug *hotplug,
                        int payload_length, struct greybus_host_device *hd)
 {
-       u8 module_id = hotplug->module_id;
+       u8 interface_id = hotplug->interface_id;
 
        switch (hotplug->hotplug_event) {
        case SVC_HOTPLUG_EVENT:
-               /* Add a new module to the system */
+               /* Add a new interface to the system */
                if (payload_length < 0x03) {
-                       /* Hotplug message is at lest 3 bytes big */
+                       /* Hotplug message is at least 3 bytes big */
                        dev_err(hd->parent,
                                "Illegal size of svc hotplug message %d\n",
                                payload_length);
                        return;
                }
-               dev_dbg(hd->parent, "module id %d added\n", module_id);
-               gb_add_module(hd, module_id, hotplug->data,
-                             payload_length - 0x02);
+               dev_dbg(hd->parent, "interface id %d added\n", interface_id);
+               gb_interface_create(hd, interface_id);
                break;
 
        case SVC_HOTUNPLUG_EVENT:
-               /* Remove a module from the system */
+               /* Remove a interface from the system */
                if (payload_length != 0x02) {
                        /* Hotunplug message is only 2 bytes big */
                        dev_err(hd->parent,
@@ -189,8 +187,8 @@ static void svc_hotplug(struct svc_function_hotplug *hotplug,
                                payload_length);
                        return;
                }
-               dev_dbg(hd->parent, "module id %d removed\n", module_id);
-               gb_remove_module(hd, module_id);
+               dev_dbg(hd->parent, "interface id %d removed\n", interface_id);
+               gb_interface_remove(hd, interface_id);
                break;
 
        default:
@@ -204,7 +202,7 @@ static void svc_hotplug(struct svc_function_hotplug *hotplug,
 static void svc_power(struct svc_function_power *power,
                      int payload_length, struct greybus_host_device *hd)
 {
-       u8 module_id = power->module_id;
+       u8 interface_id = power->interface_id;
 
        /*
         * The AP is only allowed to get a Battery Status message, not a Battery
@@ -221,15 +219,15 @@ static void svc_power(struct svc_function_power *power,
         * big, we can just check the union of the whole structure to validate
         * the size of this message.
         */
-       if (payload_length != sizeof(struct svc_function_power)) {
+       if (payload_length != sizeof(*power)) {
                dev_err(hd->parent,
                        "Illegal size of svc power message %d\n",
                        payload_length);
                return;
        }
 
-       dev_dbg(hd->parent, "power status for module id %d is %d\n",
-               module_id, power->status.status);
+       dev_dbg(hd->parent, "power status for interface id %d is %d\n",
+               interface_id, power->status.status);
 
        // FIXME - do something with the power information, like update our
        // battery information...
@@ -355,9 +353,9 @@ int greybus_svc_in(struct greybus_host_device *hd, u8 *data, int size)
 }
 EXPORT_SYMBOL_GPL(greybus_svc_in);
 
-int gb_ap_init(void)
+int __init gb_ap_init(void)
 {
-       ap_workqueue = alloc_workqueue("greybus_ap", 0, 1);
+       ap_workqueue = alloc_ordered_workqueue("greybus_ap", 0);
        if (!ap_workqueue)
                return -ENOMEM;