From fc8a4027135252b49650a4dbfcf2a8fb434a6e6a Mon Sep 17 00:00:00 2001 From: David Lin Date: Thu, 7 Jul 2016 22:07:00 -0500 Subject: [PATCH] greybus: svc: add interface resume operation Add the AP implementation for the Greybus SVC Interface Resume Operation. This operation allows the AP to request the SVC to resume an Interface which was previously SUSPENDED, allowing it to later be ENUMERATED. Signed-off-by: David Lin Reviewed-by: Johan Hovold Signed-off-by: Alex Elder --- drivers/staging/greybus/greybus_protocols.h | 9 +++++++ drivers/staging/greybus/svc.c | 29 +++++++++++++++++++++ drivers/staging/greybus/svc.h | 2 ++ 3 files changed, 40 insertions(+) diff --git a/drivers/staging/greybus/greybus_protocols.h b/drivers/staging/greybus/greybus_protocols.h index dfee73716df7..1a12531944e9 100644 --- a/drivers/staging/greybus/greybus_protocols.h +++ b/drivers/staging/greybus/greybus_protocols.h @@ -1001,6 +1001,7 @@ struct gb_spi_transfer_response { #define GB_SVC_TYPE_INTF_UNIPRO_ENABLE 0x25 #define GB_SVC_TYPE_INTF_UNIPRO_DISABLE 0x26 #define GB_SVC_TYPE_INTF_ACTIVATE 0x27 +#define GB_SVC_TYPE_INTF_RESUME 0x28 #define GB_SVC_TYPE_INTF_MAILBOX_EVENT 0x29 /* Greybus SVC protocol status values */ @@ -1321,6 +1322,14 @@ struct gb_svc_intf_activate_response { __u8 intf_type; } __packed; +struct gb_svc_intf_resume_request { + __u8 intf_id; +} __packed; + +struct gb_svc_intf_resume_response { + __u8 status; +} __packed; + #define GB_SVC_INTF_MAILBOX_NONE 0x00 #define GB_SVC_INTF_MAILBOX_AP 0x01 #define GB_SVC_INTF_MAILBOX_GREYBUS 0x02 diff --git a/drivers/staging/greybus/svc.c b/drivers/staging/greybus/svc.c index 63d2a53b624f..a46d7fb0139b 100644 --- a/drivers/staging/greybus/svc.c +++ b/drivers/staging/greybus/svc.c @@ -14,6 +14,7 @@ #define SVC_INTF_EJECT_TIMEOUT 9000 #define SVC_INTF_ACTIVATE_TIMEOUT 6000 +#define SVC_INTF_RESUME_TIMEOUT 3000 struct gb_svc_deferred_request { struct work_struct work; @@ -354,6 +355,34 @@ int gb_svc_intf_activate(struct gb_svc *svc, u8 intf_id, u8 *intf_type) return 0; } +int gb_svc_intf_resume(struct gb_svc *svc, u8 intf_id) +{ + struct gb_svc_intf_resume_request request; + struct gb_svc_intf_resume_response response; + int ret; + + request.intf_id = intf_id; + + ret = gb_operation_sync_timeout(svc->connection, + GB_SVC_TYPE_INTF_RESUME, + &request, sizeof(request), + &response, sizeof(response), + SVC_INTF_RESUME_TIMEOUT); + if (ret < 0) { + dev_err(&svc->dev, "failed to send interface resume %u: %d\n", + intf_id, ret); + return ret; + } + + if (response.status != GB_SVC_OP_SUCCESS) { + dev_err(&svc->dev, "failed to resume interface %u: %u\n", + intf_id, response.status); + return -EREMOTEIO; + } + + return 0; +} + 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 7f5e534238bc..750eaff7d0cd 100644 --- a/drivers/staging/greybus/svc.h +++ b/drivers/staging/greybus/svc.h @@ -71,6 +71,8 @@ int gb_svc_intf_vsys_set(struct gb_svc *svc, u8 intf_id, bool enable); int gb_svc_intf_refclk_set(struct gb_svc *svc, u8 intf_id, bool enable); int gb_svc_intf_unipro_set(struct gb_svc *svc, u8 intf_id, bool enable); int gb_svc_intf_activate(struct gb_svc *svc, u8 intf_id, u8 *intf_type); +int gb_svc_intf_resume(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, -- 2.39.5