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

Commit b7a5d98d authored by Mohammed Javid's avatar Mohammed Javid Committed by Gerrit - the friendly Code Review server
Browse files

msm: ipa: Set ep delay on USB_PROD ep



During SSR, set ep delay on USB_PROD ep
for RMNET/MBIM config to avoid USB pushing data
towards IPA.

Change-Id: I51b7048f42fd393110f90939b67354006eb1411f
Signed-off-by: default avatarMohammed Javid <mjavid@codeaurora.org>
parent 035363ab
Loading
Loading
Loading
Loading
+18 −1
Original line number Diff line number Diff line
/* Copyright (c) 2015, 2016 The Linux Foundation. All rights reserved.
/* Copyright (c) 2015, 2016, 2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -2098,6 +2098,18 @@ static void ipa_usb_debugfs_init(void){}
static void ipa_usb_debugfs_remove(void){}
#endif /* CONFIG_DEBUG_FS */

static int ipa_usb_set_lock_unlock(bool is_lock)
{
	IPA_USB_DBG("entry\n");
	if (is_lock)
		mutex_lock(&ipa3_usb_ctx->general_mutex);
	else
		mutex_unlock(&ipa3_usb_ctx->general_mutex);
	IPA_USB_DBG("exit\n");

	return 0;
}



int ipa_usb_xdci_connect(struct ipa_usb_xdci_chan_params *ul_chan_params,
@@ -2160,6 +2172,9 @@ int ipa_usb_xdci_connect(struct ipa_usb_xdci_chan_params *ul_chan_params,
		goto connect_fail;
	}

	/* Register for xdci lock/unlock callback with ipa core driver */
	ipa3_register_lock_unlock_callback(&ipa_usb_set_lock_unlock,
		ul_out_params->clnt_hdl);
	IPA_USB_DBG_LOW("exit\n");
	mutex_unlock(&ipa3_usb_ctx->general_mutex);
	return 0;
@@ -2236,6 +2251,8 @@ static int ipa_usb_xdci_dismiss_channels(u32 ul_clnt_hdl, u32 dl_clnt_hdl,
		}
	}

	ipa3_deregister_lock_unlock_callback(ul_clnt_hdl);

	/* Change state to STOPPED */
	if (!ipa3_usb_set_state(IPA_USB_STOPPED, false, ttype))
		IPA_USB_ERR("failed to change state to stopped\n");
+3 −1
Original line number Diff line number Diff line
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -2566,6 +2566,8 @@ void ipa3_q6_pre_shutdown_cleanup(void)
	  */
	ipa3_q6_pipe_delay(false);

	ipa3_set_usb_prod_pipe_delay();

	IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
	IPADBG_LOW("Exit with success\n");
}
+104 −1
Original line number Diff line number Diff line
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -1167,6 +1167,69 @@ int ipa3_smmu_map_peer_buff(u64 iova, phys_addr_t phys_addr, u32 size, bool map)
	return 0;
}

void ipa3_register_lock_unlock_callback(int (*client_cb)(bool is_lock),
						u32 ipa_ep_idx)
{
	struct ipa3_ep_context *ep;

	IPADBG("entry\n");

	ep = &ipa3_ctx->ep[ipa_ep_idx];

	if (!ep->valid) {
		IPAERR("Invalid EP\n");
		return;
	}

	if (client_cb == NULL) {
		IPAERR("Bad Param");
		return;
	}

	ep->client_lock_unlock = client_cb;
	IPADBG("exit\n");
}

void ipa3_deregister_lock_unlock_callback(u32 ipa_ep_idx)
{
	struct ipa3_ep_context *ep;

	IPADBG("entry\n");

	ep = &ipa3_ctx->ep[ipa_ep_idx];

	if (!ep->valid) {
		IPAERR("Invalid EP\n");
		return;
	}

	if (ep->client_lock_unlock == NULL) {
		IPAERR("client_lock_unlock is already NULL");
		return;
	}

	ep->client_lock_unlock = NULL;
	IPADBG("exit\n");
}

static void client_lock_unlock_cb(u32 ipa_ep_idx, bool is_lock)
{
	struct ipa3_ep_context *ep;

	IPADBG("entry\n");

	ep = &ipa3_ctx->ep[ipa_ep_idx];

	if (!ep->valid) {
		IPAERR("Invalid EP\n");
		return;
	}

	if (ep->client_lock_unlock)
		ep->client_lock_unlock(is_lock);

	IPADBG("exit\n");
}

int ipa3_request_gsi_channel(struct ipa_request_gsi_channel_params *params,
			     struct ipa_req_chan_out_params *out_params)
@@ -1784,6 +1847,46 @@ exit:
	return result;
}

/*
 * Set USB PROD pipe delay for MBIM/RMNET config
 * Clocks, should be voted before calling this API
 * locks should be taken before calling this API
*/

void ipa3_set_usb_prod_pipe_delay(void)
{
	int result;
	int pipe_idx;
	struct ipa3_ep_context *ep;
	struct ipa_ep_cfg_ctrl ep_ctrl;

	memset(&ep_ctrl, 0, sizeof(struct ipa_ep_cfg_ctrl));
	ep_ctrl.ipa_ep_delay = true;


	pipe_idx = ipa3_get_ep_mapping(IPA_CLIENT_USB_PROD);

	if (pipe_idx == IPA_EP_NOT_ALLOCATED) {
		IPAERR("client (%d) not valid\n", IPA_CLIENT_USB_PROD);
		return;
	}

	ep = &ipa3_ctx->ep[pipe_idx];

	/* Setting delay on USB_PROD with skip_ep_cfg */
	client_lock_unlock_cb(pipe_idx, true);
	if (ep->valid && ep->skip_ep_cfg) {
		ep->ep_delay_set = ep_ctrl.ipa_ep_delay;
		result = ipa3_cfg_ep_ctrl(pipe_idx, &ep_ctrl);
		if (result)
			IPAERR("client (ep: %d) failed result=%d\n",
				pipe_idx, result);
		else
			IPADBG("client (ep: %d) success\n", pipe_idx);
	}
	client_lock_unlock_cb(pipe_idx, false);
}

void ipa3_xdci_ep_delay_rm(u32 clnt_hdl)
{
	struct ipa3_ep_context *ep;
+8 −1
Original line number Diff line number Diff line
/* Copyright (c) 2012-2017, The Linux Foundation. All rights reserved.
/* Copyright (c) 2012-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -577,6 +577,8 @@ struct ipa3_status_stats {
 * @disconnect_in_progress: Indicates client disconnect in progress.
 * @qmi_request_sent: Indicates whether QMI request to enable clear data path
 *					request is sent or not.
 * @client_lock_unlock: callback function to take mutex lock/unlock for USB
 *				clients
 */
struct ipa3_ep_context {
	int valid;
@@ -615,6 +617,8 @@ struct ipa3_ep_context {
	u32 qmi_request_sent;
	bool ep_delay_set;

	int (*client_lock_unlock)(bool is_lock);

	/* sys MUST be the last element of this struct */
	struct ipa3_sys_context *sys;
};
@@ -1524,6 +1528,9 @@ int ipa3_xdci_connect(u32 clnt_hdl);
int ipa3_xdci_disconnect(u32 clnt_hdl, bool should_force_clear, u32 qmi_req_id);

void ipa3_xdci_ep_delay_rm(u32 clnt_hdl);
void ipa3_register_lock_unlock_callback(int (*client_cb)(bool), u32 ipa_ep_idx);
void ipa3_deregister_lock_unlock_callback(u32 ipa_ep_idx);
void ipa3_set_usb_prod_pipe_delay(void);

int ipa3_xdci_suspend(u32 ul_clnt_hdl, u32 dl_clnt_hdl,
	bool should_force_clear, u32 qmi_req_id, bool is_dpl);