summaryrefslogtreecommitdiff
path: root/drivers/platform
diff options
context:
space:
mode:
authorLinux Build Service Account <lnxbuild@localhost>2016-10-31 13:04:31 -0700
committerGerrit - the friendly Code Review server <code-review@localhost>2016-10-31 13:04:30 -0700
commitc1818afef3a0cf20354aa50985ed48405ac3592e (patch)
tree8e8ffcc3761ed1b7d69ef8943d617767151f3803 /drivers/platform
parentb333bf73d8f053eeb146a7736fad4f668d57a0bb (diff)
parent9f74c08e6e222287cc066f7ca9720f3bc37537b7 (diff)
Merge "msm: ipa3: wait for uC load before USB disconnect"
Diffstat (limited to 'drivers/platform')
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa.c11
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_client.c12
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_i.h1
3 files changed, 24 insertions, 0 deletions
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c
index ab62dbcddd22..8676b35914e2 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c
@@ -3790,6 +3790,12 @@ static int ipa3_gsi_pre_fw_load_init(void)
return 0;
}
+static void ipa3_uc_is_loaded(void)
+{
+ IPADBG("\n");
+ complete_all(&ipa3_ctx->uc_loaded_completion_obj);
+}
+
static enum gsi_ver ipa3_get_gsi_ver(enum ipa_hw_type ipa_hw_type)
{
enum gsi_ver gsi_ver;
@@ -3842,6 +3848,7 @@ static int ipa3_post_init(const struct ipa3_plat_drv_res *resource_p,
int result;
struct sps_bam_props bam_props = { 0 };
struct gsi_per_props gsi_props;
+ struct ipa3_uc_hdlrs uc_hdlrs = { 0 };
if (ipa3_ctx->transport_prototype == IPA_TRANSPORT_TYPE_GSI) {
memset(&gsi_props, 0, sizeof(gsi_props));
@@ -3918,6 +3925,9 @@ static int ipa3_post_init(const struct ipa3_plat_drv_res *resource_p,
else
IPADBG(":ipa Uc interface init ok\n");
+ uc_hdlrs.ipa_uc_loaded_hdlr = ipa3_uc_is_loaded;
+ ipa3_uc_register_handlers(IPA_HW_FEATURE_COMMON, &uc_hdlrs);
+
result = ipa3_wdi_init();
if (result)
IPAERR(":wdi init failed (%d)\n", -result);
@@ -4609,6 +4619,7 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p,
INIT_LIST_HEAD(&ipa3_ctx->ipa_ready_cb_list);
init_completion(&ipa3_ctx->init_completion_obj);
+ init_completion(&ipa3_ctx->uc_loaded_completion_obj);
/*
* For GSI, we can't register the GSI driver yet, as it expects
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c
index d176552a3533..26bd180624f1 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_client.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_client.c
@@ -99,6 +99,18 @@ int ipa3_disable_data_path(u32 clnt_hdl)
/* Suspend the pipe */
if (IPA_CLIENT_IS_CONS(ep->client)) {
+ /*
+ * for RG10 workaround uC needs to be loaded before pipe can
+ * be suspended in this case.
+ */
+ if (ipa3_ctx->apply_rg10_wa && ipa3_uc_state_check()) {
+ IPADBG("uC is not loaded yet, waiting...\n");
+ res = wait_for_completion_timeout(
+ &ipa3_ctx->uc_loaded_completion_obj, 60 * HZ);
+ if (res == 0)
+ IPADBG("timeout waiting for uC to load\n");
+ }
+
memset(&ep_cfg_ctrl, 0 , sizeof(struct ipa_ep_cfg_ctrl));
ep_cfg_ctrl.ipa_ep_suspend = true;
res = ipa3_cfg_ep_ctrl(clnt_hdl, &ep_cfg_ctrl);
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
index 96cd550d7ef6..40f1e93653f9 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h
@@ -1232,6 +1232,7 @@ struct ipa3_context {
bool ipa_initialization_complete;
struct list_head ipa_ready_cb_list;
struct completion init_completion_obj;
+ struct completion uc_loaded_completion_obj;
struct ipa3_smp2p_info smp2p_info;
u32 ipa_tz_unlock_reg_num;
struct ipa_tz_unlock_reg_info *ipa_tz_unlock_reg;