diff --git a/drivers/staging/greybus/greybus_protocols.h b/drivers/staging/greybus/greybus_protocols.h index dfa3d29b78b3..2ffe07cb2a01 100644 --- a/drivers/staging/greybus/greybus_protocols.h +++ b/drivers/staging/greybus/greybus_protocols.h @@ -760,6 +760,7 @@ struct gb_spi_transfer_response { #define GB_SVC_TYPE_ROUTE_CREATE 0x0b #define GB_SVC_TYPE_ROUTE_DESTROY 0x0c #define GB_SVC_TYPE_INTF_SET_PWRM 0x10 +#define GB_SVC_TYPE_INTF_EJECT 0x11 /* * SVC version request/response has the same payload as @@ -801,6 +802,12 @@ struct gb_svc_intf_reset_request { } __packed; /* interface reset response has no payload */ +#define GB_SVC_EJECT_TIME 9000 +struct gb_svc_intf_eject_request { + __u8 intf_id; +} __packed; +/* interface eject response has no payload */ + struct gb_svc_conn_create_request { __u8 intf1_id; __le16 cport1_id; diff --git a/drivers/staging/greybus/svc.c b/drivers/staging/greybus/svc.c index c4c3bb54c9f7..ef10b67c7bf5 100644 --- a/drivers/staging/greybus/svc.c +++ b/drivers/staging/greybus/svc.c @@ -69,6 +69,23 @@ int gb_svc_intf_reset(struct gb_svc *svc, u8 intf_id) } EXPORT_SYMBOL_GPL(gb_svc_intf_reset); +int gb_svc_intf_eject(struct gb_svc *svc, u8 intf_id) +{ + struct gb_svc_intf_eject_request request; + + request.intf_id = intf_id; + + /* + * The pulse width for module release in svc is long so we need to + * increase the timeout so the operation will not return to soon. + */ + return gb_operation_sync_timeout(svc->connection, + GB_SVC_TYPE_INTF_EJECT, &request, + sizeof(request), NULL, 0, + GB_SVC_EJECT_TIME); +} +EXPORT_SYMBOL_GPL(gb_svc_intf_eject); + int gb_svc_dme_peer_get(struct gb_svc *svc, u8 intf_id, u16 attr, u16 selector, u32 *value) { diff --git a/drivers/staging/greybus/svc.h b/drivers/staging/greybus/svc.h index 0ebbed9c791f..8567615068a7 100644 --- a/drivers/staging/greybus/svc.h +++ b/drivers/staging/greybus/svc.h @@ -40,6 +40,7 @@ int gb_svc_connection_create(struct gb_svc *svc, u8 intf1_id, u16 cport1_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_intf_eject(struct gb_svc *svc, u8 intf_id); int gb_svc_dme_peer_get(struct gb_svc *svc, u8 intf_id, u16 attr, u16 selector, u32 *value); int gb_svc_dme_peer_set(struct gb_svc *svc, u8 intf_id, u16 attr, u16 selector,