summaryrefslogtreecommitdiff
path: root/drivers/platform/msm
diff options
context:
space:
mode:
authorGhanim Fodi <gfodi@codeaurora.org>2016-08-28 21:50:15 +0300
committerGerrit - the friendly Code Review server <code-review@localhost>2016-08-30 01:35:19 -0700
commit634732c1bb02bdaf20b8a6140c5ae9eeb998dfe4 (patch)
treef0ecd5e671e6c882bda0444406b6d2e802f0c1a6 /drivers/platform/msm
parent166af733db5dd13712fffc3cf6e0352413909fed (diff)
msm: ipa3: fix GSI ring DMA allocation parameters
DMA coherent allocation was done with inappropriate flags causing memory allocation to fail occasionally. Use GFP_KERNEL flag as well as fix up some cleanup actions. CRs-Fixed: 1060305 Change-Id: I93c9340439dd65c50764dd078071bf66f65a9464 Signed-off-by: Ghanim Fodi <gfodi@codeaurora.org>
Diffstat (limited to 'drivers/platform/msm')
-rw-r--r--drivers/platform/msm/ipa/ipa_v3/ipa_dp.c31
1 files changed, 25 insertions, 6 deletions
diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
index 19eb1ee9c881..9e346f12a108 100644
--- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
+++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c
@@ -3836,6 +3836,7 @@ static int ipa_gsi_setup_channel(struct ipa_sys_connect_params *in,
union __packed gsi_channel_scratch ch_scratch;
struct ipa_gsi_ep_config *gsi_ep_info;
dma_addr_t dma_addr;
+ dma_addr_t evt_dma_addr;
int result;
if (!ep) {
@@ -3844,13 +3845,13 @@ static int ipa_gsi_setup_channel(struct ipa_sys_connect_params *in,
}
ep->gsi_evt_ring_hdl = ~0;
+ memset(&gsi_evt_ring_props, 0, sizeof(gsi_evt_ring_props));
/*
* allocate event ring for all interrupt-policy
* pipes and IPA consumers pipes
*/
if (ep->sys->policy != IPA_POLICY_NOINTR_MODE ||
IPA_CLIENT_IS_CONS(ep->client)) {
- memset(&gsi_evt_ring_props, 0, sizeof(gsi_evt_ring_props));
gsi_evt_ring_props.intf = GSI_EVT_CHTYPE_GPI_EV;
gsi_evt_ring_props.intr = GSI_INTR_IRQ;
gsi_evt_ring_props.re_size =
@@ -3859,8 +3860,13 @@ static int ipa_gsi_setup_channel(struct ipa_sys_connect_params *in,
gsi_evt_ring_props.ring_len = IPA_GSI_EVT_RING_LEN;
gsi_evt_ring_props.ring_base_vaddr =
dma_alloc_coherent(ipa3_ctx->pdev, IPA_GSI_EVT_RING_LEN,
- &dma_addr, 0);
- gsi_evt_ring_props.ring_base_addr = dma_addr;
+ &evt_dma_addr, GFP_KERNEL);
+ if (!gsi_evt_ring_props.ring_base_vaddr) {
+ IPAERR("fail to dma alloc %u bytes\n",
+ IPA_GSI_EVT_RING_LEN);
+ return -ENOMEM;
+ }
+ gsi_evt_ring_props.ring_base_addr = evt_dma_addr;
/* copy mem info */
ep->gsi_mem_info.evt_ring_len = gsi_evt_ring_props.ring_len;
@@ -3895,7 +3901,7 @@ static int ipa_gsi_setup_channel(struct ipa_sys_connect_params *in,
if (!gsi_ep_info) {
IPAERR("Invalid ep number\n");
result = -EINVAL;
- goto fail_alloc_evt_ring;
+ goto fail_get_gsi_ep_info;
} else
gsi_channel_props.ch_id = gsi_ep_info->ipa_gsi_chan_num;
@@ -3914,7 +3920,12 @@ static int ipa_gsi_setup_channel(struct ipa_sys_connect_params *in,
gsi_channel_props.ring_len = 2 * in->desc_fifo_sz;
gsi_channel_props.ring_base_vaddr =
dma_alloc_coherent(ipa3_ctx->pdev, gsi_channel_props.ring_len,
- &dma_addr, 0);
+ &dma_addr, GFP_KERNEL);
+ if (!gsi_channel_props.ring_base_vaddr) {
+ IPAERR("fail to dma alloc %u bytes\n",
+ gsi_channel_props.ring_len);
+ goto fail_alloc_channel_ring;
+ }
gsi_channel_props.ring_base_addr = dma_addr;
/* copy mem info */
@@ -3950,7 +3961,7 @@ static int ipa_gsi_setup_channel(struct ipa_sys_connect_params *in,
result = gsi_write_channel_scratch(ep->gsi_chan_hdl, ch_scratch);
if (result != GSI_STATUS_SUCCESS) {
IPAERR("failed to write scratch %d\n", result);
- goto fail_start_channel;
+ goto fail_write_channel_scratch;
}
result = gsi_start_channel(ep->gsi_chan_hdl);
@@ -3962,17 +3973,25 @@ static int ipa_gsi_setup_channel(struct ipa_sys_connect_params *in,
return 0;
fail_start_channel:
+fail_write_channel_scratch:
if (gsi_dealloc_channel(ep->gsi_chan_hdl)
!= GSI_STATUS_SUCCESS) {
IPAERR("Failed to dealloc GSI chan.\n");
BUG();
}
fail_alloc_channel:
+ dma_free_coherent(ipa3_ctx->pdev, gsi_channel_props.ring_len,
+ gsi_channel_props.ring_base_vaddr, dma_addr);
+fail_alloc_channel_ring:
+fail_get_gsi_ep_info:
if (ep->gsi_evt_ring_hdl != ~0) {
gsi_dealloc_evt_ring(ep->gsi_evt_ring_hdl);
ep->gsi_evt_ring_hdl = ~0;
}
fail_alloc_evt_ring:
+ if (gsi_evt_ring_props.ring_base_vaddr)
+ dma_free_coherent(ipa3_ctx->pdev, IPA_GSI_EVT_RING_LEN,
+ gsi_evt_ring_props.ring_base_vaddr, evt_dma_addr);
IPAERR("Return with err: %d\n", result);
return result;
}