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 05a9b54..6b56b30 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 4819cd0..dbf409f 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 42b5d01..9bce94f 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 da2ffd6..4b9eb38 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 75518f8..3357d31 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,