diff --git a/drivers/bus/mhi/core/mhi_boot.c b/drivers/bus/mhi/core/mhi_boot.c index d5a90cb2ecb7..667a1f9c5a9b 100644 --- a/drivers/bus/mhi/core/mhi_boot.c +++ b/drivers/bus/mhi/core/mhi_boot.c @@ -464,20 +464,22 @@ invalid_pm_state: } void mhi_free_bhie_table(struct mhi_controller *mhi_cntrl, - struct image_info *image_info) + struct image_info **image_info) { int i; - struct mhi_buf *mhi_buf = image_info->mhi_buf; + struct mhi_buf *mhi_buf = (*image_info)->mhi_buf; - if (!image_info) + if (mhi_cntrl->img_pre_alloc) return; - for (i = 0; i < image_info->entries; i++, mhi_buf++) + for (i = 0; i < (*image_info)->entries; i++, mhi_buf++) mhi_free_contig_coherent(mhi_cntrl, mhi_buf->len, mhi_buf->buf, mhi_buf->dma_addr); - kfree(image_info->mhi_buf); - kfree(image_info); + kfree((*image_info)->mhi_buf); + kfree(*image_info); + + *image_info = NULL; } int mhi_alloc_bhie_table(struct mhi_controller *mhi_cntrl, @@ -491,6 +493,9 @@ int mhi_alloc_bhie_table(struct mhi_controller *mhi_cntrl, struct image_info *img_info; struct mhi_buf *mhi_buf; + if (mhi_cntrl->img_pre_alloc) + return 0; + MHI_CNTRL_LOG("Allocating bytes:%zu seg_size:%zu total_seg:%u\n", alloc_size, seg_size, segments); @@ -662,7 +667,7 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl) firmware->size); if (ret) { MHI_CNTRL_ERR("Error alloc size:%zu\n", firmware->size); - goto fw_load_error_ready; + goto fw_load_error_release; } MHI_CNTRL_LOG("Copying firmware image into vector table\n"); @@ -715,8 +720,7 @@ fw_load_ee_pthru: return; fw_load_error_ready: - mhi_free_bhie_table(mhi_cntrl, mhi_cntrl->fbc_image); - mhi_cntrl->fbc_image = NULL; + mhi_free_bhie_table(mhi_cntrl, &mhi_cntrl->fbc_image); fw_load_error_release: release_firmware(firmware); diff --git a/drivers/bus/mhi/core/mhi_init.c b/drivers/bus/mhi/core/mhi_init.c index 42fc08c946ab..73d5301d0488 100644 --- a/drivers/bus/mhi/core/mhi_init.c +++ b/drivers/bus/mhi/core/mhi_init.c @@ -1820,10 +1820,8 @@ int mhi_prepare_for_power_up(struct mhi_controller *mhi_cntrl) return 0; bhie_error: - if (mhi_cntrl->rddm_image) { - mhi_free_bhie_table(mhi_cntrl, mhi_cntrl->rddm_image); - mhi_cntrl->rddm_image = NULL; - } + if (mhi_cntrl->rddm_image) + mhi_free_bhie_table(mhi_cntrl, &mhi_cntrl->rddm_image); error_dev_ctxt: mutex_unlock(&mhi_cntrl->pm_mutex); @@ -1834,15 +1832,11 @@ EXPORT_SYMBOL(mhi_prepare_for_power_up); void mhi_unprepare_after_power_down(struct mhi_controller *mhi_cntrl) { - if (mhi_cntrl->fbc_image) { - mhi_free_bhie_table(mhi_cntrl, mhi_cntrl->fbc_image); - mhi_cntrl->fbc_image = NULL; - } + if (mhi_cntrl->fbc_image) + mhi_free_bhie_table(mhi_cntrl, &mhi_cntrl->fbc_image); - if (mhi_cntrl->rddm_image) { - mhi_free_bhie_table(mhi_cntrl, mhi_cntrl->rddm_image); - mhi_cntrl->rddm_image = NULL; - } + if (mhi_cntrl->rddm_image) + mhi_free_bhie_table(mhi_cntrl, &mhi_cntrl->rddm_image); mhi_deinit_dev_ctxt(mhi_cntrl); mhi_cntrl->pre_init = false; diff --git a/drivers/bus/mhi/core/mhi_internal.h b/drivers/bus/mhi/core/mhi_internal.h index 63b99ac4d52c..8cebcec5a478 100644 --- a/drivers/bus/mhi/core/mhi_internal.h +++ b/drivers/bus/mhi/core/mhi_internal.h @@ -941,7 +941,7 @@ void mhi_create_devices(struct mhi_controller *mhi_cntrl); int mhi_alloc_bhie_table(struct mhi_controller *mhi_cntrl, struct image_info **image_info, size_t alloc_size); void mhi_free_bhie_table(struct mhi_controller *mhi_cntrl, - struct image_info *image_info); + struct image_info **image_info); int mhi_map_single_no_bb(struct mhi_controller *mhi_cntrl, struct mhi_buf_info *buf_info); diff --git a/drivers/bus/mhi/core/mhi_pm.c b/drivers/bus/mhi/core/mhi_pm.c index 318494c8b821..75bf575b7d7a 100644 --- a/drivers/bus/mhi/core/mhi_pm.c +++ b/drivers/bus/mhi/core/mhi_pm.c @@ -1125,10 +1125,9 @@ void mhi_power_down(struct mhi_controller *mhi_cntrl, bool graceful) if (!mhi_cntrl->pre_init) { /* free all allocated resources */ - if (mhi_cntrl->fbc_image) { - mhi_free_bhie_table(mhi_cntrl, mhi_cntrl->fbc_image); - mhi_cntrl->fbc_image = NULL; - } + if (mhi_cntrl->fbc_image) + mhi_free_bhie_table(mhi_cntrl, &mhi_cntrl->fbc_image); + mhi_deinit_dev_ctxt(mhi_cntrl); } diff --git a/drivers/net/wireless/cnss2/pci.c b/drivers/net/wireless/cnss2/pci.c index dc4a311cfac9..e398ee5ea9e4 100644 --- a/drivers/net/wireless/cnss2/pci.c +++ b/drivers/net/wireless/cnss2/pci.c @@ -1270,6 +1270,11 @@ static int cnss_pci_set_mhi_state(struct cnss_pci_data *pci_priv, break; case CNSS_MHI_POWER_ON: ret = mhi_sync_power_up(pci_priv->mhi_ctrl); + /* Only set img_pre_alloc when power up succeeds */ + if (!ret && !pci_priv->mhi_ctrl->img_pre_alloc) { + cnss_pr_dbg("Notify MHI to use already allocated images\n"); + pci_priv->mhi_ctrl->img_pre_alloc = true; + } break; case CNSS_MHI_POWER_OFF: mhi_power_down(pci_priv->mhi_ctrl, true); diff --git a/include/linux/mhi.h b/include/linux/mhi.h index 4969bb3e3170..1ff821e8af24 100644 --- a/include/linux/mhi.h +++ b/include/linux/mhi.h @@ -229,6 +229,7 @@ struct reg_write_info { * @rddm_size: RAM dump size that host should allocate for debugging purpose * @sbl_size: SBL image size * @seg_len: BHIe vector size + * @img_pre_alloc: allocate rddm and fbc image buffers one time * @fbc_image: Points to firmware image buffer * @rddm_image: Points to RAM dump buffer * @max_chan: Maximum number of channels controller support @@ -302,6 +303,8 @@ struct mhi_controller { size_t seg_len; u32 session_id; u32 sequence_id; + + bool img_pre_alloc; struct image_info *fbc_image; struct image_info *rddm_image;