From: Johan Hovold Date: Tue, 29 Mar 2016 22:56:03 +0000 (-0400) Subject: greybus: interface: clean up ES3-bootroom-quirk handling X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=ec199ccdd2a3c215f5088052377f08a5855f560e;p=linux-beck.git greybus: interface: clean up ES3-bootroom-quirk handling Clean up handling of the ES3-bootrom quirks by adding an interface quirk-flags field that is set appropriately when we detect that the ES3 bootrom is running. Note that we need to reserve the DME_DIS_UNIPRO_BOOT_STARTED and DME_DIS_FALLBACK_UNIPRO_BOOT_STARTED status values for the ES3 bootrom, which does not support any CPort features (unlike later boot stages). Add a BOOTROM infix to the defines to make this more clear. Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/staging/greybus/connection.c b/drivers/staging/greybus/connection.c index 64fa20a06da0..1880f8f6065f 100644 --- a/drivers/staging/greybus/connection.c +++ b/drivers/staging/greybus/connection.c @@ -337,9 +337,12 @@ gb_connection_svc_connection_create(struct gb_connection *connection) intf = connection->intf; - /* The ES2/ES3 bootrom requires E2EFC, CSD and CSV to be disabled. */ + /* + * Enable either E2EFC or CSD, unless the interface does not support + * any CPort features. + */ cport_flags = GB_SVC_CPORT_FLAG_CSV_N; - if (intf->boot_over_unipro) { + if (intf->quirks & GB_INTERFACE_QUIRK_NO_CPORT_FEATURES) { cport_flags |= GB_SVC_CPORT_FLAG_CSD_N; } else if (gb_connection_e2efc_enabled(connection)) { cport_flags |= GB_SVC_CPORT_FLAG_CSD_N | diff --git a/drivers/staging/greybus/control.c b/drivers/staging/greybus/control.c index 83be255bb534..8475f1577325 100644 --- a/drivers/staging/greybus/control.c +++ b/drivers/staging/greybus/control.c @@ -155,8 +155,7 @@ int gb_control_get_interface_version_operation(struct gb_interface *intf) struct gb_connection *connection = intf->control->connection; int ret; - /* The ES3 bootrom fails to boot if this request it sent to it */ - if (intf->boot_over_unipro) + if (intf->quirks & GB_INTERFACE_QUIRK_NO_INTERFACE_VERSION) return 0; ret = gb_operation_sync(connection, GB_CONTROL_TYPE_INTERFACE_VERSION, diff --git a/drivers/staging/greybus/greybus_protocols.h b/drivers/staging/greybus/greybus_protocols.h index 31e772a61f48..8370cfead6f2 100644 --- a/drivers/staging/greybus/greybus_protocols.h +++ b/drivers/staging/greybus/greybus_protocols.h @@ -894,11 +894,11 @@ struct gb_svc_dme_peer_set_response { #define DME_ATTR_ES3_INIT_STATUS 0x6101 /* Return value from init-status attributes listed above */ -#define DME_DIS_SPI_BOOT_STARTED 0x02 -#define DME_DIS_TRUSTED_SPI_BOOT_FINISHED 0x03 -#define DME_DIS_UNTRUSTED_SPI_BOOT_FINISHED 0x04 -#define DME_DIS_UNIPRO_BOOT_STARTED 0x06 -#define DME_DIS_FALLBACK_UNIPRO_BOOT_STARTED 0x09 +#define DME_DIS_SPI_BOOT_STARTED 0x02 +#define DME_DIS_TRUSTED_SPI_BOOT_FINISHED 0x03 +#define DME_DIS_UNTRUSTED_SPI_BOOT_FINISHED 0x04 +#define DME_DIS_BOOTROM_UNIPRO_BOOT_STARTED 0x06 +#define DME_DIS_BOOTROM_FALLBACK_UNIPRO_BOOT_STARTED 0x09 struct gb_svc_route_create_request { __u8 intf1_id; diff --git a/drivers/staging/greybus/interface.c b/drivers/staging/greybus/interface.c index 569403c9d142..a13b221131bc 100644 --- a/drivers/staging/greybus/interface.c +++ b/drivers/staging/greybus/interface.c @@ -55,7 +55,7 @@ static int gb_interface_read_and_clear_init_status(struct gb_interface *intf) } /* - * Check if the interface needs to boot over UniPro. + * Extract the init status. * * 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'. @@ -67,9 +67,18 @@ static int gb_interface_read_and_clear_init_status(struct gb_interface *intf) else init_status = value >> 24; - if (init_status == DME_DIS_UNIPRO_BOOT_STARTED || - init_status == DME_DIS_FALLBACK_UNIPRO_BOOT_STARTED) - intf->boot_over_unipro = true; + /* + * Check if the interface is executing the quirky ES3 bootrom that + * requires E2EFC, CSD and CSV to be disabled and that does not + * support the interface-version request. + */ + switch (init_status) { + case DME_DIS_BOOTROM_UNIPRO_BOOT_STARTED: + case DME_DIS_BOOTROM_FALLBACK_UNIPRO_BOOT_STARTED: + intf->quirks |= GB_INTERFACE_QUIRK_NO_CPORT_FEATURES; + intf->quirks |= GB_INTERFACE_QUIRK_NO_INTERFACE_VERSION; + break; + } /* Clear the init status. */ return gb_svc_dme_peer_set(hd->svc, intf->interface_id, attr, diff --git a/drivers/staging/greybus/interface.h b/drivers/staging/greybus/interface.h index d4c55abae258..96caabc8a73f 100644 --- a/drivers/staging/greybus/interface.h +++ b/drivers/staging/greybus/interface.h @@ -10,6 +10,9 @@ #ifndef __INTERFACE_H #define __INTERFACE_H +#define GB_INTERFACE_QUIRK_NO_CPORT_FEATURES BIT(0) +#define GB_INTERFACE_QUIRK_NO_INTERFACE_VERSION BIT(1) + struct gb_interface { struct device dev; struct gb_control *control; @@ -36,8 +39,8 @@ struct gb_interface { struct gb_host_device *hd; - /* The interface needs to boot over unipro */ - bool boot_over_unipro; + unsigned long quirks; + bool disconnected; }; #define to_gb_interface(d) container_of(d, struct gb_interface, dev)