From 85269c6e8836046ee117d55839e2d0f0792f88dc Mon Sep 17 00:00:00 2001 From: Bhaumik Bhatt Date: Fri, 23 Oct 2020 17:51:00 -0700 Subject: [PATCH] bus: mhi: core: Add support to pre allocate image buffers This allows controller to keep the memory allocated for bhi vector table for rddm and fbc images. Memory remains allocated after controller powers down and is freed when the controller unregisters with MHI. Add a controller flag to make the decision for memory allocation. Change-Id: I974e44d3b927da1003e232455067c50fdf6fb42b Signed-off-by: Bhaumik Bhatt Signed-off-by: Lazarus Motha --- drivers/bus/mhi/host/boot.c | 24 +++++++++++++++--------- drivers/bus/mhi/host/init.c | 20 ++++++++++---------- drivers/bus/mhi/host/internal.h | 2 +- drivers/bus/mhi/host/pm.c | 2 ++ include/linux/mhi.h | 2 ++ 5 files changed, 30 insertions(+), 20 deletions(-) diff --git a/drivers/bus/mhi/host/boot.c b/drivers/bus/mhi/host/boot.c index 65aa9b9de487..c712a2654aec 100644 --- a/drivers/bus/mhi/host/boot.c +++ b/drivers/bus/mhi/host/boot.c @@ -299,17 +299,22 @@ static int mhi_fw_load_bhi(struct mhi_controller *mhi_cntrl, } 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; - for (i = 0; i < image_info->entries; i++, mhi_buf++) + if (mhi_cntrl->img_pre_alloc) + return; + + for (i = 0; i < (*image_info)->entries; i++, mhi_buf++) dma_free_coherent(mhi_cntrl->cntrl_dev, 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, @@ -322,6 +327,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; + img_info = kzalloc(sizeof(*img_info), GFP_KERNEL); if (!img_info) return -ENOMEM; @@ -516,10 +524,8 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl) return; error_ready_state: - if (mhi_cntrl->fbc_download) { - mhi_free_bhie_table(mhi_cntrl, mhi_cntrl->fbc_image); - mhi_cntrl->fbc_image = NULL; - } + if (mhi_cntrl->fbc_download) + mhi_free_bhie_table(mhi_cntrl, &mhi_cntrl->fbc_image); error_fw_load: mhi_cntrl->pm_state = MHI_PM_FW_DL_ERR; diff --git a/drivers/bus/mhi/host/init.c b/drivers/bus/mhi/host/init.c index b5c696a4cb2a..6b660d014eea 100644 --- a/drivers/bus/mhi/host/init.c +++ b/drivers/bus/mhi/host/init.c @@ -1040,8 +1040,15 @@ void mhi_unregister_controller(struct mhi_controller *mhi_cntrl) unsigned int i; mhi_deinit_free_irq(mhi_cntrl); + /* Free the memory controller wanted to preserve for BHIe images */ + if (mhi_cntrl->img_pre_alloc) { + mhi_cntrl->img_pre_alloc = false; + 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_destroy_debugfs(mhi_cntrl); - destroy_workqueue(mhi_cntrl->hiprio_wq); kfree(mhi_cntrl->mhi_cmd); kfree(mhi_cntrl->mhi_event); @@ -1162,15 +1169,8 @@ EXPORT_SYMBOL_GPL(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->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_cntrl->bhi = NULL; mhi_cntrl->bhie = NULL; diff --git a/drivers/bus/mhi/host/internal.h b/drivers/bus/mhi/host/internal.h index 3d62b836a67c..193a3493627e 100644 --- a/drivers/bus/mhi/host/internal.h +++ b/drivers/bus/mhi/host/internal.h @@ -277,7 +277,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); /* Power management APIs */ enum mhi_pm_state __must_check mhi_tryset_pm_state( diff --git a/drivers/bus/mhi/host/pm.c b/drivers/bus/mhi/host/pm.c index b60021d73efc..cda374bfc9ef 100644 --- a/drivers/bus/mhi/host/pm.c +++ b/drivers/bus/mhi/host/pm.c @@ -1186,6 +1186,8 @@ void mhi_power_down(struct mhi_controller *mhi_cntrl, bool graceful) flush_work(&mhi_cntrl->st_worker); disable_irq(mhi_cntrl->irq[0]); + if (mhi_cntrl->fbc_image) + mhi_free_bhie_table(mhi_cntrl, &mhi_cntrl->fbc_image); } EXPORT_SYMBOL_GPL(mhi_power_down); diff --git a/include/linux/mhi.h b/include/linux/mhi.h index 33952bfd76d9..e251cb6e9407 100644 --- a/include/linux/mhi.h +++ b/include/linux/mhi.h @@ -366,6 +366,7 @@ struct mhi_controller_config { * @reset: Controller specific reset function (optional) * @buffer_len: Bounce buffer length * @index: Index of the MHI controller instance + * @img_pre_alloc: allocate rddm and fbc image buffers one time * @bounce_buf: Use of bounce buffer * @fbc_download: MHI host needs to do complete image transfer (optional) * @wake_set: Device wakeup set flag @@ -461,6 +462,7 @@ struct mhi_controller { size_t buffer_len; int index; + bool img_pre_alloc; bool bounce_buf; bool fbc_download; bool wake_set;