summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/staging/greybus/connection.c7
-rw-r--r--drivers/staging/greybus/greybus_protocols.h7
-rw-r--r--drivers/staging/greybus/interface.h3
-rw-r--r--drivers/staging/greybus/svc.c26
-rw-r--r--drivers/staging/greybus/svc.h2
5 files changed, 40 insertions, 5 deletions
diff --git a/drivers/staging/greybus/connection.c b/drivers/staging/greybus/connection.c
index 05a9b548b64a..6b56b3069fae 100644
--- a/drivers/staging/greybus/connection.c
+++ b/drivers/staging/greybus/connection.c
@@ -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);
diff --git a/drivers/staging/greybus/greybus_protocols.h b/drivers/staging/greybus/greybus_protocols.h
index 4819cd0e229e..dbf409fa16f3 100644
--- a/drivers/staging/greybus/greybus_protocols.h
+++ b/drivers/staging/greybus/greybus_protocols.h
@@ -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;
diff --git a/drivers/staging/greybus/interface.h b/drivers/staging/greybus/interface.h
index 42b5d0156cdc..9bce94f680a4 100644
--- a/drivers/staging/greybus/interface.h
+++ b/drivers/staging/greybus/interface.h
@@ -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)
diff --git a/drivers/staging/greybus/svc.c b/drivers/staging/greybus/svc.c
index da2ffd655122..4b9eb383652c 100644
--- a/drivers/staging/greybus/svc.c
+++ b/drivers/staging/greybus/svc.c
@@ -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);
diff --git a/drivers/staging/greybus/svc.h b/drivers/staging/greybus/svc.h
index 75518f8a199e..3357d317e9d9 100644
--- a/drivers/staging/greybus/svc.h
+++ b/drivers/staging/greybus/svc.h
@@ -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,