greybus: svc: skip setting flags for boot over unipro
authorViresh Kumar <viresh.kumar@linaro.org>
Wed, 7 Oct 2015 19:40:24 +0000 (15:40 -0400)
committerGreg Kroah-Hartman <gregkh@google.com>
Fri, 9 Oct 2015 20:58:17 +0000 (13:58 -0700)
We need to skip setting E2EFC and other flags to the SVC connection
create request, for all cports, on an interface that need to boot over
unipro, i.e. interfaces required to download firmware.

This also adds a FIXME as we need to do it differently for ES3.

Tested-by: Eli Sennesh <esennesh@leaflabs.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off by: Eli Sennesh <esennesh@leaflabs.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
drivers/staging/greybus/connection.c
drivers/staging/greybus/greybus_protocols.h
drivers/staging/greybus/interface.h
drivers/staging/greybus/svc.c
drivers/staging/greybus/svc.h

index 05a9b548b64a95b71563cc474b8c30b293a6d3e3..6b56b3069faef26d761dd487088b92f979f6f098 100644 (file)
@@ -328,16 +328,19 @@ gb_connection_svc_connection_create(struct gb_connection *connection)
 {
        struct greybus_host_device *hd = connection->hd;
        struct gb_protocol *protocol = connection->protocol;
+       struct gb_interface *intf;
        int ret;
 
        if (protocol->flags & GB_PROTOCOL_SKIP_SVC_CONNECTION)
                return 0;
 
+       intf = connection->bundle->intf;
        ret = gb_svc_connection_create(hd->svc,
                        hd->endo->ap_intf_id,
                        connection->hd_cport_id,
-                       connection->bundle->intf->interface_id,
-                       connection->intf_cport_id);
+                       intf->interface_id,
+                       connection->intf_cport_id,
+                       intf->boot_over_unipro);
        if (ret) {
                dev_err(&connection->dev,
                                "failed to create svc connection: %d\n", ret);
index 4819cd0e229e57d702ff5f629b21cb7a93cdd6f6..dbf409fa16f352168142d0f264a0c8b145487651 100644 (file)
@@ -832,6 +832,13 @@ struct gb_svc_dme_peer_set_response {
 #define DME_ATTR_SELECTOR_INDEX                0
 #define DME_ATTR_T_TST_SRC_INCREMENT   0x4083
 
+/* Return value from TST_SRC_INCREMENT */
+#define DME_TSI_SPI_BOOT_STARTED               0x02
+#define DME_TSI_TRUSTED_SPI_BOOT_FINISHED      0x03
+#define DME_TSI_UNTRUSTED_SPI_BOOT_FINISHED    0x04
+#define DME_TSI_UNIPRO_BOOT_STARTED            0x06
+#define DME_TSI_FALLBACK_UNIPRO_BOOT_STARTED   0x09
+
 struct gb_svc_route_create_request {
        __u8    intf1_id;
        __u8    dev1_id;
index 42b5d0156cdc8c60df0086555431c144e27cb091..9bce94f680a42f4dbc1cd57ffc7747abb5ab683d 100644 (file)
@@ -36,6 +36,9 @@ struct gb_interface {
 
        struct gb_module *module;
        struct greybus_host_device *hd;
+
+       /* The interface needs to boot over unipro */
+       bool boot_over_unipro;
 };
 #define to_gb_interface(d) container_of(d, struct gb_interface, dev)
 
index da2ffd655122684d3123e07070451aa97ca5dba2..4b9eb383652c223a7a612114445f54d4e20134f6 100644 (file)
@@ -207,6 +207,18 @@ static int gb_svc_read_and_clear_module_boot_status(struct gb_interface *intf)
                return -ENODEV;
        }
 
+       /*
+        * Check if the module needs to boot from unipro.
+        * For ES2: We need to check lowest 8 bits of 'value'.
+        * For ES3: We need to check highest 8 bits out of 32 of 'value'.
+        *
+        * FIXME: Add code to find if we are on ES2 or ES3 to have separate
+        * checks.
+        */
+       if (value == DME_TSI_UNIPRO_BOOT_STARTED ||
+           value == DME_TSI_FALLBACK_UNIPRO_BOOT_STARTED)
+               intf->boot_over_unipro = true;
+
        return gb_svc_dme_peer_set(hd->svc, intf->interface_id,
                                   DME_ATTR_T_TST_SRC_INCREMENT,
                                   DME_ATTR_SELECTOR_INDEX, 0);
@@ -214,7 +226,8 @@ static int gb_svc_read_and_clear_module_boot_status(struct gb_interface *intf)
 
 int gb_svc_connection_create(struct gb_svc *svc,
                                u8 intf1_id, u16 cport1_id,
-                               u8 intf2_id, u16 cport2_id)
+                               u8 intf2_id, u16 cport2_id,
+                               bool boot_over_unipro)
 {
        struct gb_svc_conn_create_request request;
 
@@ -227,7 +240,16 @@ int gb_svc_connection_create(struct gb_svc *svc,
         * for now.
         */
        request.tc = 0;
-       request.flags = CPORT_FLAGS_CSV_N | CPORT_FLAGS_E2EFC;
+
+       /*
+        * We need to skip setting E2EFC and other flags to the connection
+        * create request, for all cports, on an interface that need to boot
+        * over unipro, i.e. interfaces required to download firmware.
+        */
+       if (boot_over_unipro)
+               request.flags = CPORT_FLAGS_CSV_N | CPORT_FLAGS_CSD_N;
+       else
+               request.flags = CPORT_FLAGS_CSV_N | CPORT_FLAGS_E2EFC;
 
        return gb_operation_sync(svc->connection, GB_SVC_TYPE_CONN_CREATE,
                                 &request, sizeof(request), NULL, 0);
index 75518f8a199e430ee1246d94c056fba3bb34db9a..3357d317e9d937c7ea66358b42342ef99978fe07 100644 (file)
@@ -14,7 +14,7 @@ struct gb_svc;
 
 int gb_svc_intf_reset(struct gb_svc *svc, u8 intf_id);
 int gb_svc_connection_create(struct gb_svc *svc, u8 intf1_id, u16 cport1_id,
-                                               u8 intf2_id, u16 cport2_id);
+                            u8 intf2_id, u16 cport2_id, bool boot_over_unipro);
 void gb_svc_connection_destroy(struct gb_svc *svc, u8 intf1_id, u16 cport1_id,
                               u8 intf2_id, u16 cport2_id);
 int gb_svc_dme_peer_get(struct gb_svc *svc, u8 intf_id, u16 attr, u16 selector,