diff options
| -rw-r--r-- | drivers/platform/msm/gsi/gsi.c | 29 | ||||
| -rw-r--r-- | drivers/platform/msm/ipa/ipa_v3/ipa_mhi.c | 18 | ||||
| -rw-r--r-- | include/linux/msm_gsi.h | 18 |
3 files changed, 65 insertions, 0 deletions
diff --git a/drivers/platform/msm/gsi/gsi.c b/drivers/platform/msm/gsi/gsi.c index 08bffc344429..b111a5904952 100644 --- a/drivers/platform/msm/gsi/gsi.c +++ b/drivers/platform/msm/gsi/gsi.c @@ -1319,6 +1319,35 @@ int gsi_query_evt_ring_db_addr(unsigned long evt_ring_hdl, } EXPORT_SYMBOL(gsi_query_evt_ring_db_addr); +int gsi_ring_evt_ring_db(unsigned long evt_ring_hdl, uint64_t value) +{ + struct gsi_evt_ctx *ctx; + + if (!gsi_ctx) { + pr_err("%s:%d gsi context not allocated\n", __func__, __LINE__); + return -GSI_STATUS_NODEV; + } + + if (evt_ring_hdl >= gsi_ctx->max_ev) { + GSIERR("bad params evt_ring_hdl=%lu\n", evt_ring_hdl); + return -GSI_STATUS_INVALID_PARAMS; + } + + ctx = &gsi_ctx->evtr[evt_ring_hdl]; + + if (ctx->state != GSI_EVT_RING_STATE_ALLOCATED) { + GSIERR("bad state %d\n", + gsi_ctx->evtr[evt_ring_hdl].state); + return -GSI_STATUS_UNSUPPORTED_OP; + } + + ctx->ring.wp_local = value; + gsi_ring_evt_doorbell(ctx); + + return GSI_STATUS_SUCCESS; +} +EXPORT_SYMBOL(gsi_ring_evt_ring_db); + int gsi_reset_evt_ring(unsigned long evt_ring_hdl) { uint32_t val; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_mhi.c b/drivers/platform/msm/ipa/ipa_v3/ipa_mhi.c index 9e2ffe70170c..cd027c28e597 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_mhi.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_mhi.c @@ -255,6 +255,24 @@ static int ipa_mhi_start_gsi_channel(enum ipa_client_type client, ep->gsi_evt_ring_hdl = *params->cached_gsi_evt_ring_hdl; } + if (params->ev_ctx_host->wp == params->ev_ctx_host->rbase) { + IPA_MHI_ERR("event ring wp is not updated. base=wp=0x%llx\n", + params->ev_ctx_host->wp); + goto fail_alloc_ch; + return res; + } + + IPA_MHI_DBG("Ring event db: evt_ring_hdl=%lu host_wp=0x%llx\n", + ep->gsi_evt_ring_hdl, params->ev_ctx_host->wp); + res = gsi_ring_evt_ring_db(ep->gsi_evt_ring_hdl, + params->ev_ctx_host->wp); + if (res) { + IPA_MHI_ERR("fail to ring evt ring db %d. hdl=%lu wp=0x%llx\n", + res, ep->gsi_evt_ring_hdl, params->ev_ctx_host->wp); + goto fail_alloc_ch; + return res; + } + memset(&ch_props, 0, sizeof(ch_props)); ch_props.prot = GSI_CHAN_PROT_MHI; ch_props.dir = IPA_CLIENT_IS_PROD(client) ? diff --git a/include/linux/msm_gsi.h b/include/linux/msm_gsi.h index d4b4cc7f8737..b95ea88c2424 100644 --- a/include/linux/msm_gsi.h +++ b/include/linux/msm_gsi.h @@ -749,6 +749,18 @@ int gsi_query_evt_ring_db_addr(unsigned long evt_ring_hdl, uint32_t *db_addr_wp_lsb, uint32_t *db_addr_wp_msb); /** + * gsi_ring_evt_ring_db - Peripheral should call this function for + * ringing the event ring doorbell with given value + * + * @evt_ring_hdl: Client handle previously obtained from + * gsi_alloc_evt_ring + * @value: The value to be used for ringing the doorbell + * + * @Return gsi_status + */ +int gsi_ring_evt_ring_db(unsigned long evt_ring_hdl, uint64_t value); + +/** * gsi_reset_evt_ring - Peripheral should call this function to * reset an event ring to recover from error state * @@ -1138,6 +1150,12 @@ static inline int gsi_query_evt_ring_db_addr(unsigned long evt_ring_hdl, return -GSI_STATUS_UNSUPPORTED_OP; } +static inline int gsi_ring_evt_ring_db(unsigned long evt_ring_hdl, + uint64_t value) +{ + return -GSI_STATUS_UNSUPPORTED_OP; +} + static inline int gsi_reset_evt_ring(unsigned long evt_ring_hdl) { return -GSI_STATUS_UNSUPPORTED_OP; |
