Loading drivers/platform/msm/ipa/ipa_dp.c +4 −2 Original line number Diff line number Diff line Loading @@ -1742,7 +1742,7 @@ begin: BUG(); } if (status->status_mask & IPA_HW_PKT_STATUS_MASK_TAG_VALID) { struct completion *comp; struct ipa_tag_completion *comp; IPADBG("TAG packet arrived\n"); if (status->tag_f_2 == IPA_COOKIE) { skb_pull(skb, IPA_PKT_STATUS_SIZE); Loading @@ -1752,7 +1752,9 @@ begin: } memcpy(&comp, skb->data, sizeof(comp)); skb_pull(skb, sizeof(comp)); complete(comp); complete(&comp->comp); if (atomic_dec_return(&comp->cnt) == 0) kfree(comp); continue; } else { IPADBG("ignoring TAG with wrong cookie\n"); Loading drivers/platform/msm/ipa/ipa_i.h +5 −0 Original line number Diff line number Diff line Loading @@ -646,6 +646,11 @@ struct ipa_active_clients { int cnt; }; struct ipa_tag_completion { struct completion comp; atomic_t cnt; }; struct ipa_controller; struct ipa_wdi_ctx { Loading drivers/platform/msm/ipa/ipa_utils.c +21 −6 Original line number Diff line number Diff line Loading @@ -3497,8 +3497,7 @@ int ipa_tag_process(struct ipa_desc desc[], int i; struct sk_buff *dummy_skb; int res; DECLARE_COMPLETION_ONSTACK(comp); void *comp_ptr = ∁ struct ipa_tag_completion *comp; /* Not enough room for the required descriptors for the tag process */ if (IPA_TAG_MAX_DESC - descs_num < REQUIRED_TAG_PROCESS_DESCRIPTORS) { Loading Loading @@ -3578,16 +3577,26 @@ int ipa_tag_process(struct ipa_desc desc[], sizeof(struct ipa_desc)); desc_idx += descs_num; comp = kzalloc(sizeof(*comp), GFP_KERNEL); if (!comp) { IPAERR("no mem\n"); res = -ENOMEM; goto fail_free_desc; } init_completion(&comp->comp); /* completion needs to be released from both here and rx handler */ atomic_set(&comp->cnt, 2); /* dummy packet to send to IPA. packet payload is a completion object */ dummy_skb = alloc_skb(sizeof(comp), GFP_KERNEL); if (!dummy_skb) { IPAERR("failed to allocate memory\n"); res = -ENOMEM; goto fail_free_desc; goto fail_free_skb; } memcpy(skb_put(dummy_skb, sizeof(comp_ptr)), &comp_ptr, sizeof(comp_ptr)); memcpy(skb_put(dummy_skb, sizeof(comp)), &comp, sizeof(comp)); tag_desc[desc_idx].pyld = dummy_skb->data; tag_desc[desc_idx].len = dummy_skb->len; Loading @@ -3607,14 +3616,18 @@ int ipa_tag_process(struct ipa_desc desc[], tag_desc = NULL; IPADBG("waiting for TAG response\n"); res = wait_for_completion_timeout(&comp, timeout); res = wait_for_completion_timeout(&comp->comp, timeout); if (res == 0) { IPAERR("timeout for waiting for TAG response\n"); WARN_ON(1); if (atomic_dec_return(&comp->cnt) == 0) kfree(comp); return -ETIME; } IPADBG("TAG response arrived!\n"); if (atomic_dec_return(&comp->cnt) == 0) kfree(comp); /* sleep for short period to ensure IPA wrote all packets to BAM */ usleep_range(IPA_TAG_SLEEP_MIN_USEC, IPA_TAG_SLEEP_MAX_USEC); Loading @@ -3624,6 +3637,8 @@ int ipa_tag_process(struct ipa_desc desc[], fail_send: dev_kfree_skb_any(dummy_skb); desc_idx--; fail_free_skb: kfree(comp); fail_free_desc: /* * Free only the first descriptors allocated here. Loading Loading
drivers/platform/msm/ipa/ipa_dp.c +4 −2 Original line number Diff line number Diff line Loading @@ -1742,7 +1742,7 @@ begin: BUG(); } if (status->status_mask & IPA_HW_PKT_STATUS_MASK_TAG_VALID) { struct completion *comp; struct ipa_tag_completion *comp; IPADBG("TAG packet arrived\n"); if (status->tag_f_2 == IPA_COOKIE) { skb_pull(skb, IPA_PKT_STATUS_SIZE); Loading @@ -1752,7 +1752,9 @@ begin: } memcpy(&comp, skb->data, sizeof(comp)); skb_pull(skb, sizeof(comp)); complete(comp); complete(&comp->comp); if (atomic_dec_return(&comp->cnt) == 0) kfree(comp); continue; } else { IPADBG("ignoring TAG with wrong cookie\n"); Loading
drivers/platform/msm/ipa/ipa_i.h +5 −0 Original line number Diff line number Diff line Loading @@ -646,6 +646,11 @@ struct ipa_active_clients { int cnt; }; struct ipa_tag_completion { struct completion comp; atomic_t cnt; }; struct ipa_controller; struct ipa_wdi_ctx { Loading
drivers/platform/msm/ipa/ipa_utils.c +21 −6 Original line number Diff line number Diff line Loading @@ -3497,8 +3497,7 @@ int ipa_tag_process(struct ipa_desc desc[], int i; struct sk_buff *dummy_skb; int res; DECLARE_COMPLETION_ONSTACK(comp); void *comp_ptr = ∁ struct ipa_tag_completion *comp; /* Not enough room for the required descriptors for the tag process */ if (IPA_TAG_MAX_DESC - descs_num < REQUIRED_TAG_PROCESS_DESCRIPTORS) { Loading Loading @@ -3578,16 +3577,26 @@ int ipa_tag_process(struct ipa_desc desc[], sizeof(struct ipa_desc)); desc_idx += descs_num; comp = kzalloc(sizeof(*comp), GFP_KERNEL); if (!comp) { IPAERR("no mem\n"); res = -ENOMEM; goto fail_free_desc; } init_completion(&comp->comp); /* completion needs to be released from both here and rx handler */ atomic_set(&comp->cnt, 2); /* dummy packet to send to IPA. packet payload is a completion object */ dummy_skb = alloc_skb(sizeof(comp), GFP_KERNEL); if (!dummy_skb) { IPAERR("failed to allocate memory\n"); res = -ENOMEM; goto fail_free_desc; goto fail_free_skb; } memcpy(skb_put(dummy_skb, sizeof(comp_ptr)), &comp_ptr, sizeof(comp_ptr)); memcpy(skb_put(dummy_skb, sizeof(comp)), &comp, sizeof(comp)); tag_desc[desc_idx].pyld = dummy_skb->data; tag_desc[desc_idx].len = dummy_skb->len; Loading @@ -3607,14 +3616,18 @@ int ipa_tag_process(struct ipa_desc desc[], tag_desc = NULL; IPADBG("waiting for TAG response\n"); res = wait_for_completion_timeout(&comp, timeout); res = wait_for_completion_timeout(&comp->comp, timeout); if (res == 0) { IPAERR("timeout for waiting for TAG response\n"); WARN_ON(1); if (atomic_dec_return(&comp->cnt) == 0) kfree(comp); return -ETIME; } IPADBG("TAG response arrived!\n"); if (atomic_dec_return(&comp->cnt) == 0) kfree(comp); /* sleep for short period to ensure IPA wrote all packets to BAM */ usleep_range(IPA_TAG_SLEEP_MIN_USEC, IPA_TAG_SLEEP_MAX_USEC); Loading @@ -3624,6 +3637,8 @@ int ipa_tag_process(struct ipa_desc desc[], fail_send: dev_kfree_skb_any(dummy_skb); desc_idx--; fail_free_skb: kfree(comp); fail_free_desc: /* * Free only the first descriptors allocated here. Loading