@@ -584,10 +584,17 @@ void mhi_fw_load_handler(struct mhi_controller *mhi_cntrl)
* device transitioning into MHI READY state
*/
if (fw_load_type == MHI_FW_LOAD_FBC) {
- ret = mhi_alloc_bhie_table(mhi_cntrl, &mhi_cntrl->fbc_image, fw_sz);
- if (ret) {
- release_firmware(firmware);
- goto error_fw_load;
+ if (mhi_cntrl->fbc_image && fw_sz != mhi_cntrl->prev_fw_sz) {
+ mhi_free_bhie_table(mhi_cntrl, mhi_cntrl->fbc_image);
+ mhi_cntrl->fbc_image = NULL;
+ }
+ if (!mhi_cntrl->fbc_image) {
+ ret = mhi_alloc_bhie_table(mhi_cntrl, &mhi_cntrl->fbc_image, fw_sz);
+ if (ret) {
+ release_firmware(firmware);
+ goto error_fw_load;
+ }
+ mhi_cntrl->prev_fw_sz = fw_sz;
}
/* Load the firmware into BHIE vec table */
@@ -1173,8 +1173,9 @@ int mhi_prepare_for_power_up(struct mhi_controller *mhi_cntrl)
/*
* Allocate RDDM table for debugging purpose if specified
*/
- mhi_alloc_bhie_table(mhi_cntrl, &mhi_cntrl->rddm_image,
- mhi_cntrl->rddm_size);
+ if (!mhi_cntrl->rddm_image)
+ mhi_alloc_bhie_table(mhi_cntrl, &mhi_cntrl->rddm_image,
+ mhi_cntrl->rddm_size);
if (mhi_cntrl->rddm_image) {
ret = mhi_rddm_prepare(mhi_cntrl,
mhi_cntrl->rddm_image);
@@ -1200,6 +1201,14 @@ int mhi_prepare_for_power_up(struct mhi_controller *mhi_cntrl)
}
EXPORT_SYMBOL_GPL(mhi_prepare_for_power_up);
+void __mhi_unprepare_keep_dev(struct mhi_controller *mhi_cntrl)
+{
+ mhi_cntrl->bhi = NULL;
+ mhi_cntrl->bhie = NULL;
+
+ mhi_deinit_dev_ctxt(mhi_cntrl);
+}
+
void mhi_unprepare_after_power_down(struct mhi_controller *mhi_cntrl)
{
if (mhi_cntrl->fbc_image) {
@@ -1212,10 +1221,7 @@ void mhi_unprepare_after_power_down(struct mhi_controller *mhi_cntrl)
mhi_cntrl->rddm_image = NULL;
}
- mhi_cntrl->bhi = NULL;
- mhi_cntrl->bhie = NULL;
-
- mhi_deinit_dev_ctxt(mhi_cntrl);
+ __mhi_unprepare_keep_dev(mhi_cntrl);
}
EXPORT_SYMBOL_GPL(mhi_unprepare_after_power_down);
@@ -427,4 +427,6 @@ void mhi_unmap_single_no_bb(struct mhi_controller *mhi_cntrl,
void mhi_unmap_single_use_bb(struct mhi_controller *mhi_cntrl,
struct mhi_buf_info *buf_info);
+void __mhi_unprepare_keep_dev(struct mhi_controller *mhi_cntrl);
+
#endif /* _MHI_INT_H */
@@ -1263,6 +1263,7 @@ void mhi_power_down_keep_dev(struct mhi_controller *mhi_cntrl,
bool graceful)
{
__mhi_power_down(mhi_cntrl, graceful, false);
+ __mhi_unprepare_keep_dev(mhi_cntrl);
}
EXPORT_SYMBOL_GPL(mhi_power_down_keep_dev);
@@ -460,12 +460,12 @@ void ath11k_mhi_stop(struct ath11k_pci *ab_pci, bool is_suspend)
* workaround, otherwise ath11k_core_resume() will timeout
* during resume.
*/
- if (is_suspend)
+ if (is_suspend) {
mhi_power_down_keep_dev(ab_pci->mhi_ctrl, true);
- else
+ } else {
mhi_power_down(ab_pci->mhi_ctrl, true);
-
- mhi_unprepare_after_power_down(ab_pci->mhi_ctrl);
+ mhi_unprepare_after_power_down(ab_pci->mhi_ctrl);
+ }
}
int ath11k_mhi_suspend(struct ath11k_pci *ab_pci)
@@ -601,6 +601,12 @@ static int ath12k_mhi_set_state(struct ath12k_pci *ab_pci,
ath12k_mhi_set_state_bit(ab_pci, mhi_state);
+ /* mhi_power_down_keep_dev() has been updated to DEINIT without
+ * freeing bhie tables
+ */
+ if (mhi_state == ATH12K_MHI_POWER_OFF_KEEP_DEV)
+ ath12k_mhi_set_state_bit(ab_pci, ATH12K_MHI_DEINIT);
+
return 0;
out:
@@ -635,12 +641,12 @@ void ath12k_mhi_stop(struct ath12k_pci *ab_pci, bool is_suspend)
* workaround, otherwise ath12k_core_resume() will timeout
* during resume.
*/
- if (is_suspend)
+ if (is_suspend) {
ath12k_mhi_set_state(ab_pci, ATH12K_MHI_POWER_OFF_KEEP_DEV);
- else
+ } else {
ath12k_mhi_set_state(ab_pci, ATH12K_MHI_POWER_OFF);
-
- ath12k_mhi_set_state(ab_pci, ATH12K_MHI_DEINIT);
+ ath12k_mhi_set_state(ab_pci, ATH12K_MHI_DEINIT);
+ }
}
void ath12k_mhi_suspend(struct ath12k_pci *ab_pci)
@@ -306,6 +306,7 @@ struct mhi_controller_config {
* if fw_image is NULL and fbc_download is true (optional)
* @fw_sz: Firmware image data size for normal booting, used only if fw_image
* is NULL and fbc_download is true (optional)
+ * @prev_fw_sz: Previous firmware image data size, when fbc_download is true
* @edl_image: Firmware image name for emergency download mode (optional)
* @rddm_size: RAM dump size that host should allocate for debugging purpose
* @sbl_size: SBL image size downloaded through BHIe (optional)
@@ -382,6 +383,7 @@ struct mhi_controller {
const char *fw_image;
const u8 *fw_data;
size_t fw_sz;
+ size_t prev_fw_sz;
const char *edl_image;
size_t rddm_size;
size_t sbl_size;