Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bf3e2d74 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "msm: ipa3: fix ipa3_reset_with_open_aggr_frame_wa() memory leak"

parents c158dba4 1677d3f9
Loading
Loading
Loading
Loading
+4 −24
Original line number Diff line number Diff line
@@ -768,15 +768,7 @@ static void ipa_chan_err_cb(struct gsi_chan_err_notify *notify)

static void ipa_xfer_cb(struct gsi_chan_xfer_notify *notify)
{
	struct ipa3_mem_buffer *xfer_data;

	IPADBG("event %d notified\n", notify->evt_id);
	BUG_ON(notify->xfer_user_data == NULL);

	xfer_data = (struct ipa3_mem_buffer *)notify->xfer_user_data;
	dma_free_coherent(ipa3_ctx->pdev, xfer_data->size,
		xfer_data->base, xfer_data->phys_base);
	kfree(xfer_data);
	return;
}

static int ipa3_reconfigure_channel_to_gpi(struct ipa3_ep_context *ep,
@@ -853,7 +845,6 @@ static int ipa3_reset_with_open_aggr_frame_wa(u32 clnt_hdl,
	void *buff;
	dma_addr_t dma_addr;
	struct gsi_xfer_elem xfer_elem;
	struct ipa3_mem_buffer *xfer_data;
	int i;
	int aggr_active_bitmap = 0;

@@ -897,17 +888,7 @@ static int ipa3_reset_with_open_aggr_frame_wa(u32 clnt_hdl,
	xfer_elem.len = 1;
	xfer_elem.flags = GSI_XFER_FLAG_EOT;
	xfer_elem.type = GSI_XFER_ELEM_DATA;
	xfer_data = kzalloc(sizeof(struct ipa3_mem_buffer),
		GFP_ATOMIC);
	if (xfer_data == NULL) {
		IPAERR("Error allocating memory\n");
		goto xfer_data_alloc_fail;
	}
	memset(xfer_data, 0, sizeof(struct ipa3_mem_buffer));
	xfer_data->base = buff;
	xfer_data->phys_base = dma_addr;
	xfer_data->size = 1;
	xfer_elem.xfer_user_data = (void *)xfer_data;

	gsi_res = gsi_queue_xfer(ep->gsi_chan_hdl, 1, &xfer_elem,
		true);
	if (gsi_res != GSI_STATUS_SUCCESS) {
@@ -931,6 +912,8 @@ static int ipa3_reset_with_open_aggr_frame_wa(u32 clnt_hdl,
		BUG();
	}

	dma_free_coherent(ipa3_ctx->pdev, 1, buff, dma_addr);

	result = ipa3_stop_gsi_channel(clnt_hdl);
	if (result) {
		IPAERR("Error stopping channel: %d\n", result);
@@ -953,13 +936,10 @@ static int ipa3_reset_with_open_aggr_frame_wa(u32 clnt_hdl,
	dma_free_coherent(ipa3_ctx->pdev, chan_dma.size,
		chan_dma.base, chan_dma.phys_base);


	return 0;

queue_xfer_fail:
	ipa3_stop_gsi_channel(clnt_hdl);
	kfree(xfer_data);
xfer_data_alloc_fail:
	dma_free_coherent(ipa3_ctx->pdev, 1, buff, dma_addr);
start_chan_fail:
	ipa3_restore_channel_properties(ep, &orig_chan_props,
+14 −8
Original line number Diff line number Diff line
@@ -5186,7 +5186,7 @@ int ipa3_inject_dma_task_for_gsi(void)
int ipa3_stop_gsi_channel(u32 clnt_hdl)
{
	struct ipa3_mem_buffer mem;
	int res;
	int res = 0;
	int i;
	struct ipa3_ep_context *ep;

@@ -5197,26 +5197,28 @@ int ipa3_stop_gsi_channel(u32 clnt_hdl)
	}

	ep = &ipa3_ctx->ep[clnt_hdl];
	if (!ep->keep_ipa_awake)

	ipa3_inc_client_enable_clks();

	memset(&mem, 0, sizeof(mem));

	if (IPA_CLIENT_IS_PROD(ep->client))
		return gsi_stop_channel(ep->gsi_chan_hdl);
	if (IPA_CLIENT_IS_PROD(ep->client)) {
		res = gsi_stop_channel(ep->gsi_chan_hdl);
		goto end_sequence;
	}

	for (i = 0; i < IPA_GSI_CHANNEL_STOP_MAX_RETRY; i++) {
		IPADBG("Calling gsi_stop_channel\n");
		res = gsi_stop_channel(ep->gsi_chan_hdl);
		IPADBG("gsi_stop_channel returned %d\n", res);
		if (res != -GSI_STATUS_AGAIN && res != -GSI_STATUS_TIMED_OUT)
			return res;
			goto end_sequence;

		/* Send a 1B packet DMA_RASK to IPA and try again*/
		res = ipa3_inject_dma_task_for_gsi();
		if (res) {
			IPAERR("ipa3_inject_dma_task_for_gsi failed\n");
			return res;
			goto end_sequence;
		}

		/* sleep for short period to flush IPA */
@@ -5224,7 +5226,11 @@ int ipa3_stop_gsi_channel(u32 clnt_hdl)
			IPA_GSI_CHANNEL_STOP_SLEEP_MAX_USEC);
	}

	return -EFAULT;
	res = -EFAULT;
end_sequence:
	ipa3_dec_client_disable_clks();

	return res;
}

/**