Merge "msm: ipa: ipa_tx_dp issued after suspend"
diff --git a/drivers/platform/msm/ipa/ipa_clients/ipa_gsb.c b/drivers/platform/msm/ipa/ipa_clients/ipa_gsb.c
index 54e82f3a..bc04ed4 100644
--- a/drivers/platform/msm/ipa/ipa_clients/ipa_gsb.c
+++ b/drivers/platform/msm/ipa/ipa_clients/ipa_gsb.c
@@ -161,6 +161,7 @@
spinlock_t iface_spinlock[MAX_SUPPORTED_IFACE];
u32 pm_hdl;
atomic_t disconnect_in_progress;
+ atomic_t suspend_in_progress;
};
static struct ipa_gsb_context *ipa_gsb_ctx;
@@ -1070,20 +1071,24 @@
IPA_GSB_DBG_LOW("client hdl: %d\n", hdl);
mutex_lock(&ipa_gsb_ctx->iface_lock[hdl]);
+ atomic_set(&ipa_gsb_ctx->suspend_in_progress, 1);
if (!ipa_gsb_ctx->iface[hdl]) {
IPA_GSB_ERR("fail to find interface, hdl: %d\n", hdl);
+ atomic_set(&ipa_gsb_ctx->suspend_in_progress, 0);
mutex_unlock(&ipa_gsb_ctx->iface_lock[hdl]);
return -EFAULT;
}
if (!ipa_gsb_ctx->iface[hdl]->is_connected) {
IPA_GSB_ERR("iface is not connected\n");
+ atomic_set(&ipa_gsb_ctx->suspend_in_progress, 0);
mutex_unlock(&ipa_gsb_ctx->iface_lock[hdl]);
return -EFAULT;
}
if (!ipa_gsb_ctx->iface[hdl]->is_resumed) {
IPA_GSB_DBG_LOW("iface was already suspended\n");
+ atomic_set(&ipa_gsb_ctx->suspend_in_progress, 0);
mutex_unlock(&ipa_gsb_ctx->iface_lock[hdl]);
return 0;
}
@@ -1096,6 +1101,7 @@
IPA_GSB_ERR(
"fail to stop cons ep %d\n",
ret);
+ atomic_set(&ipa_gsb_ctx->suspend_in_progress, 0);
mutex_unlock(&ipa_gsb_ctx->lock);
mutex_unlock(&ipa_gsb_ctx->iface_lock[hdl]);
return ret;
@@ -1105,6 +1111,7 @@
if (ret) {
IPA_GSB_ERR("fail to deactivate ipa pm\n");
ipa_start_gsi_channel(ipa_gsb_ctx->cons_hdl);
+ atomic_set(&ipa_gsb_ctx->suspend_in_progress, 0);
mutex_unlock(&ipa_gsb_ctx->lock);
mutex_unlock(&ipa_gsb_ctx->iface_lock[hdl]);
return ret;
@@ -1115,7 +1122,7 @@
ipa_gsb_ctx->num_resumed_iface--;
IPA_GSB_DBG_LOW("num resumed iface: %d\n",
ipa_gsb_ctx->num_resumed_iface);
-
+ atomic_set(&ipa_gsb_ctx->suspend_in_progress, 0);
mutex_unlock(&ipa_gsb_ctx->lock);
mutex_unlock(&ipa_gsb_ctx->iface_lock[hdl]);
return 0;
@@ -1169,6 +1176,16 @@
return -EFAULT;
}
+ if (unlikely(atomic_read(&ipa_gsb_ctx->suspend_in_progress))) {
+ IPA_GSB_ERR("ipa bridge suspend_in_progress\n");
+ return -EFAULT;
+ }
+
+ if (unlikely(!ipa_gsb_ctx->iface[hdl]->is_resumed)) {
+ IPA_GSB_ERR("iface %d was suspended\n", hdl);
+ return -EFAULT;
+ }
+
/* make sure skb has enough headroom */
if (unlikely(skb_headroom(skb) < sizeof(struct ipa_gsb_mux_hdr))) {
IPA_GSB_DBG_LOW("skb doesn't have enough headroom\n");