mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-08 21:22:09 -04:00
Merge "msm: ipa: load IPA FW after smmu CB are probed"
This commit is contained in:
commit
7847fb4f8a
2 changed files with 104 additions and 13 deletions
|
|
@ -6174,6 +6174,9 @@ static void ipa3_load_ipa_fw(struct work_struct *work)
|
|||
result);
|
||||
return;
|
||||
}
|
||||
mutex_lock(&ipa3_ctx->fw_load_data.lock);
|
||||
ipa3_ctx->fw_load_data.state = IPA_FW_LOAD_STATE_LOADED;
|
||||
mutex_unlock(&ipa3_ctx->fw_load_data.lock);
|
||||
pr_info("IPA FW loaded successfully\n");
|
||||
|
||||
result = ipa3_post_init(&ipa3_res, ipa3_ctx->cdev.dev);
|
||||
|
|
@ -6201,6 +6204,58 @@ static void ipa3_load_ipa_fw(struct work_struct *work)
|
|||
}
|
||||
}
|
||||
|
||||
static void ipa_fw_load_sm_handle_event(enum ipa_fw_load_event ev)
|
||||
{
|
||||
mutex_lock(&ipa3_ctx->fw_load_data.lock);
|
||||
|
||||
IPADBG("state=%d event=%d\n", ipa3_ctx->fw_load_data.state, ev);
|
||||
|
||||
if (ev == IPA_FW_LOAD_EVNT_FWFILE_READY) {
|
||||
if (ipa3_ctx->fw_load_data.state == IPA_FW_LOAD_STATE_INIT) {
|
||||
ipa3_ctx->fw_load_data.state =
|
||||
IPA_FW_LOAD_STATE_FWFILE_READY;
|
||||
goto out;
|
||||
}
|
||||
if (ipa3_ctx->fw_load_data.state ==
|
||||
IPA_FW_LOAD_STATE_SMMU_DONE) {
|
||||
ipa3_ctx->fw_load_data.state =
|
||||
IPA_FW_LOAD_STATE_LOAD_READY;
|
||||
goto sched_fw_load;
|
||||
}
|
||||
IPAERR("ignore multiple requests to load FW\n");
|
||||
goto out;
|
||||
}
|
||||
if (ev == IPA_FW_LOAD_EVNT_SMMU_DONE) {
|
||||
if (ipa3_ctx->fw_load_data.state == IPA_FW_LOAD_STATE_INIT) {
|
||||
ipa3_ctx->fw_load_data.state =
|
||||
IPA_FW_LOAD_STATE_SMMU_DONE;
|
||||
goto out;
|
||||
}
|
||||
if (ipa3_ctx->fw_load_data.state ==
|
||||
IPA_FW_LOAD_STATE_FWFILE_READY) {
|
||||
ipa3_ctx->fw_load_data.state =
|
||||
IPA_FW_LOAD_STATE_LOAD_READY;
|
||||
goto sched_fw_load;
|
||||
}
|
||||
IPAERR("ignore multiple smmu done events\n");
|
||||
goto out;
|
||||
}
|
||||
IPAERR("invalid event ev=%d\n", ev);
|
||||
mutex_unlock(&ipa3_ctx->fw_load_data.lock);
|
||||
ipa_assert();
|
||||
return;
|
||||
|
||||
out:
|
||||
mutex_unlock(&ipa3_ctx->fw_load_data.lock);
|
||||
return;
|
||||
|
||||
sched_fw_load:
|
||||
IPADBG("Scheduled a work to load IPA FW\n");
|
||||
mutex_unlock(&ipa3_ctx->fw_load_data.lock);
|
||||
queue_work(ipa3_ctx->transport_power_mgmt_wq,
|
||||
&ipa3_fw_loading_work);
|
||||
}
|
||||
|
||||
static ssize_t ipa3_write(struct file *file, const char __user *buf,
|
||||
size_t count, loff_t *ppos)
|
||||
{
|
||||
|
|
@ -6280,19 +6335,8 @@ static ssize_t ipa3_write(struct file *file, const char __user *buf,
|
|||
ipa3_ctx->ipa_config_is_mhi ? "" : "non ");
|
||||
}
|
||||
|
||||
/* Prevent multiple calls from trying to load the FW again. */
|
||||
if (ipa3_ctx->fw_loaded) {
|
||||
IPAERR("not load FW again\n");
|
||||
return count;
|
||||
}
|
||||
ipa_fw_load_sm_handle_event(IPA_FW_LOAD_EVNT_FWFILE_READY);
|
||||
|
||||
/* Schedule WQ to load ipa-fws */
|
||||
ipa3_ctx->fw_loaded = true;
|
||||
|
||||
queue_work(ipa3_ctx->transport_power_mgmt_wq,
|
||||
&ipa3_fw_loading_work);
|
||||
|
||||
IPADBG("Scheduled a work to load IPA FW\n");
|
||||
return count;
|
||||
}
|
||||
|
||||
|
|
@ -6487,6 +6531,9 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p,
|
|||
goto fail_mem_ctx;
|
||||
}
|
||||
|
||||
ipa3_ctx->fw_load_data.state = IPA_FW_LOAD_STATE_INIT;
|
||||
mutex_init(&ipa3_ctx->fw_load_data.lock);
|
||||
|
||||
ipa3_ctx->logbuf = ipc_log_context_create(IPA_IPC_LOG_PAGES, "ipa", 0);
|
||||
if (ipa3_ctx->logbuf == NULL)
|
||||
IPADBG("failed to create IPC log, continue...\n");
|
||||
|
|
@ -8158,6 +8205,27 @@ static int ipa3_smp2p_probe(struct device *dev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void ipa_smmu_update_fw_loader(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (smmu_info.arm_smmu) {
|
||||
IPADBG("smmu is enabled\n");
|
||||
for (i = 0; i < IPA_SMMU_CB_MAX; i++) {
|
||||
if (!smmu_info.present[i]) {
|
||||
IPADBG("CB %d not probed yet\n", i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == IPA_SMMU_CB_MAX) {
|
||||
IPADBG("All %d CBs probed\n", IPA_SMMU_CB_MAX);
|
||||
ipa_fw_load_sm_handle_event(IPA_FW_LOAD_EVNT_SMMU_DONE);
|
||||
}
|
||||
} else {
|
||||
IPADBG("smmu is disabled\n");
|
||||
}
|
||||
}
|
||||
|
||||
int ipa3_plat_drv_probe(struct platform_device *pdev_p,
|
||||
struct ipa_api_controller *api_ctrl,
|
||||
const struct of_device_id *pdrv_match)
|
||||
|
|
@ -8177,6 +8245,7 @@ int ipa3_plat_drv_probe(struct platform_device *pdev_p,
|
|||
cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_AP);
|
||||
cb->dev = dev;
|
||||
smmu_info.present[IPA_SMMU_CB_AP] = true;
|
||||
ipa_smmu_update_fw_loader();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -8189,6 +8258,7 @@ int ipa3_plat_drv_probe(struct platform_device *pdev_p,
|
|||
cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_WLAN);
|
||||
cb->dev = dev;
|
||||
smmu_info.present[IPA_SMMU_CB_WLAN] = true;
|
||||
ipa_smmu_update_fw_loader();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -8201,6 +8271,7 @@ int ipa3_plat_drv_probe(struct platform_device *pdev_p,
|
|||
cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_UC);
|
||||
cb->dev = dev;
|
||||
smmu_info.present[IPA_SMMU_CB_UC] = true;
|
||||
ipa_smmu_update_fw_loader();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -8213,6 +8284,7 @@ int ipa3_plat_drv_probe(struct platform_device *pdev_p,
|
|||
cb = ipa3_get_smmu_ctx(IPA_SMMU_CB_11AD);
|
||||
cb->dev = dev;
|
||||
smmu_info.present[IPA_SMMU_CB_11AD] = true;
|
||||
ipa_smmu_update_fw_loader();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -8258,6 +8330,7 @@ int ipa3_plat_drv_probe(struct platform_device *pdev_p,
|
|||
return -EOPNOTSUPP;
|
||||
}
|
||||
}
|
||||
ipa_fw_load_sm_handle_event(IPA_FW_LOAD_EVNT_SMMU_DONE);
|
||||
}
|
||||
|
||||
/* Proceed to real initialization */
|
||||
|
|
|
|||
|
|
@ -1768,6 +1768,24 @@ struct ipa3_pc_mbox_data {
|
|||
struct mbox_chan *mbox;
|
||||
};
|
||||
|
||||
enum ipa_fw_load_state {
|
||||
IPA_FW_LOAD_STATE_INIT,
|
||||
IPA_FW_LOAD_STATE_FWFILE_READY,
|
||||
IPA_FW_LOAD_STATE_SMMU_DONE,
|
||||
IPA_FW_LOAD_STATE_LOAD_READY,
|
||||
IPA_FW_LOAD_STATE_LOADED,
|
||||
};
|
||||
|
||||
enum ipa_fw_load_event {
|
||||
IPA_FW_LOAD_EVNT_FWFILE_READY,
|
||||
IPA_FW_LOAD_EVNT_SMMU_DONE,
|
||||
};
|
||||
|
||||
struct ipa_fw_load_data {
|
||||
enum ipa_fw_load_state state;
|
||||
struct mutex lock;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct ipa3_context - IPA context
|
||||
* @cdev: cdev context
|
||||
|
|
@ -2025,7 +2043,7 @@ struct ipa3_context {
|
|||
|
||||
int (*client_lock_unlock[IPA_MAX_CLNT])(bool is_lock);
|
||||
|
||||
bool fw_loaded;
|
||||
struct ipa_fw_load_data fw_load_data;
|
||||
|
||||
bool (*get_teth_port_state[IPA_MAX_CLNT])(void);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue