diff --git a/drivers/platform/msm/mhi_dev/mhi.c b/drivers/platform/msm/mhi_dev/mhi.c index 4e1a15dd8c72..5eca5c2d3214 100644 --- a/drivers/platform/msm/mhi_dev/mhi.c +++ b/drivers/platform/msm/mhi_dev/mhi.c @@ -91,6 +91,7 @@ static void mhi_dev_cmd_event_msi_cb(void *req); static int mhi_dev_alloc_cmd_ack_buf_req(struct mhi_dev *mhi); +static int mhi_dev_ring_init(struct mhi_dev *dev); static struct mhi_dev_uevent_info channel_state_info[MHI_MAX_CHANNELS]; static DECLARE_COMPLETION(read_from_host); @@ -2685,6 +2686,25 @@ static int mhi_dev_cache_host_cfg(struct mhi_dev *mhi) mhi->cfg.event_rings; mhi->ch_ctx_shadow.size = sizeof(struct mhi_dev_ch_ctx) * mhi->cfg.channels; + + /* Allocate ring elements, during M0 when host + * would have updated MHICFG register + */ + + if (!mhi->ring) { + mhi->ring = devm_kcalloc(&pdev->dev, + (mhi->cfg.channels + mhi->cfg.event_rings+1), + sizeof(struct mhi_dev_ring), + GFP_KERNEL); + if (!mhi->ring) { + rc = -ENOMEM; + goto exit; + } + mhi_log(MHI_MSG_INFO, + "MEM_ALLOC: size:%d RING_ALLOC\n", + (sizeof(struct mhi_dev_ring) * + (mhi->cfg.channels + mhi->cfg.event_rings + 1))); + } /* * This func mhi_dev_cache_host_cfg will be called when * processing mhi device reset as well, do not allocate @@ -2731,6 +2751,13 @@ static int mhi_dev_cache_host_cfg(struct mhi_dev *mhi) } memset(mhi->ch_ctx_cache, 0, sizeof(struct mhi_dev_ch_ctx) * mhi->cfg.channels); + + rc = mhi_dev_ring_init(mhi); + if (rc) { + mhi_log(MHI_MSG_VERBOSE, "MHI dev ring init failed\n"); + goto exit; + } + if (MHI_USE_DMA(mhi)) { data_transfer.phy_addr = mhi->cmd_ctx_cache_dma_handle; data_transfer.host_pa = mhi->cmd_ctx_shadow.host_pa; @@ -2761,21 +2788,43 @@ static int mhi_dev_cache_host_cfg(struct mhi_dev *mhi) mhi->ev_ctx_cache->rp, mhi->ev_ctx_cache->wp); - return mhi_ring_start(&mhi->ring[0], + rc = mhi_ring_start(&mhi->ring[0], (union mhi_dev_ring_ctx *)mhi->cmd_ctx_cache, mhi); + if (rc) { + pr_err("MHI ring start failed:%d\n", rc); + goto exit; + } + return 0; exit: - if (mhi->cmd_ctx_cache) + if (mhi->ring) { + devm_kfree(&pdev->dev, mhi->ring); + mhi->ring = NULL; + mhi_log(MHI_MSG_INFO, + "MEM_DEALLOC: size:%d RING_ALLOC\n", + (sizeof(struct mhi_dev_ring) * + (mhi->cfg.channels + mhi->cfg.event_rings + 1))); + } + if (mhi->cmd_ctx_cache) { dma_free_coherent(&pdev->dev, sizeof(struct mhi_dev_cmd_ctx), mhi->cmd_ctx_cache, mhi->cmd_ctx_cache_dma_handle); - if (mhi->ev_ctx_cache) + mhi_log(MHI_MSG_INFO, + "MEM_DEALLOC: size:%d CMD_CTX_CACHE\n", + sizeof(struct mhi_dev_cmd_ctx)); + } + if (mhi->ev_ctx_cache) { dma_free_coherent(&pdev->dev, sizeof(struct mhi_dev_ev_ctx) * mhi->cfg.event_rings, mhi->ev_ctx_cache, mhi->ev_ctx_cache_dma_handle); + mhi_log(MHI_MSG_INFO, + "MEM_DEALLOC: size:%d EV_CTX_CACHE\n", + sizeof(struct mhi_dev_ev_ctx) * + mhi->cfg.event_rings); + } return rc; } @@ -3675,13 +3724,6 @@ static void mhi_dev_enable(struct work_struct *work) } } - rc = mhi_dev_ring_init(mhi); - if (rc) { - pr_err("MHI dev ring init failed\n"); - return; - } - - rc = mhi_dev_mmio_get_mhi_state(mhi, &state, &mhi_reset); if (rc) { pr_err("%s: get mhi state failed\n", __func__); @@ -3995,14 +4037,6 @@ static int mhi_init(struct mhi_dev *mhi) return rc; } - if (!mhi->ring) - mhi->ring = devm_kzalloc(&pdev->dev, - (sizeof(struct mhi_dev_ring) * - (mhi->cfg.channels + mhi->cfg.event_rings + 1)), - GFP_KERNEL); - if (!mhi->ring) - return -ENOMEM; - /* * mhi_init is also called during device reset, in * which case channel mem will already be allocated.