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

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

Merge "msm: ipa: disconnect sequence change for USB 2.0"

parents ee20f199 5d5f0e3f
Loading
Loading
Loading
Loading
+18 −0
Original line number Diff line number Diff line
@@ -251,6 +251,24 @@ int ipa_reset_endpoint(u32 clnt_hdl)
}
EXPORT_SYMBOL(ipa_reset_endpoint);

/**
* ipa_disable_endpoint() - Disable an endpoint from IPA perspective
* @clnt_hdl:	[in] IPA client handle
*
* Returns:	0 on success, negative on failure
*
* Note:		Should not be called from atomic context
*/
int ipa_disable_endpoint(u32 clnt_hdl)
{
	int ret;

	IPA_API_DISPATCH_RETURN(ipa_disable_endpoint, clnt_hdl);

	return ret;
}
EXPORT_SYMBOL(ipa_disable_endpoint);


/**
 * ipa_cfg_ep - IPA end-point configuration
+2 −0
Original line number Diff line number Diff line
@@ -26,6 +26,8 @@ struct ipa_api_controller {

	int (*ipa_clear_endpoint_delay)(u32 clnt_hdl);

	int (*ipa_disable_endpoint)(u32 clnt_hdl);

	int (*ipa_cfg_ep)(u32 clnt_hdl, const struct ipa_ep_cfg *ipa_ep_cfg);

	int (*ipa_cfg_ep_nat)(u32 clnt_hdl,
+96 −15
Original line number Diff line number Diff line
@@ -560,23 +560,31 @@ int ipa2_disconnect(u32 clnt_hdl)
	if (!ep->keep_ipa_awake)
		IPA_ACTIVE_CLIENTS_INC_EP(client_type);

	/* For USB 2.0 controller, first the ep will be disabled.
	 * so this sequence is not needed again when disconnecting the pipe.
	 */
	if (!ep->ep_disabled) {
		/* Set Disconnect in Progress flag. */
		spin_lock(&ipa_ctx->disconnect_lock);
		ep->disconnect_in_progress = true;
		spin_unlock(&ipa_ctx->disconnect_lock);

	/* Notify uc to stop monitoring holb on USB BAM Producer pipe. */
		/* Notify uc to stop monitoring holb on USB BAM
		 * Producer pipe.
		 */
		if (IPA_CLIENT_IS_USB_CONS(ep->client)) {
			ipa_uc_monitor_holb(ep->client, false);
		IPADBG("Disabling holb monitor for client: %d\n", ep->client);
			IPADBG("Disabling holb monitor for client: %d\n",
				ep->client);
		}

		result = ipa_disable_data_path(clnt_hdl);
		if (result) {
		IPAERR("disable data path failed res=%d clnt=%d.\n", result,
				clnt_hdl);
			IPAERR("disable data path failed res=%d clnt=%d.\n",
				result, clnt_hdl);
			return -EPERM;
		}
	}

	result = sps_disconnect(ep->ep_hdl);
	if (result) {
@@ -783,6 +791,79 @@ int ipa2_clear_endpoint_delay(u32 clnt_hdl)
	return 0;
}

/**
 * ipa2_disable_endpoint() - low-level IPA client disable endpoint
 * @clnt_hdl:	[in] opaque client handle assigned by IPA to client
 *
 * Should be called by the driver of the peripheral that wants to
 * disable the pipe from IPA in BAM-BAM mode.
 *
 * Returns:	0 on success, negative on failure
 *
 * Note:	Should not be called from atomic context
 */
int ipa2_disable_endpoint(u32 clnt_hdl)
{
	int result;
	struct ipa_ep_context *ep;
	enum ipa_client_type client_type;
	unsigned long bam;

	if (unlikely(!ipa_ctx)) {
		IPAERR("IPA driver was not initialized\n");
		return -EINVAL;
	}

	if (clnt_hdl >= ipa_ctx->ipa_num_pipes ||
		ipa_ctx->ep[clnt_hdl].valid == 0) {
		IPAERR("bad parm.\n");
		return -EINVAL;
	}

	ep = &ipa_ctx->ep[clnt_hdl];
	client_type = ipa2_get_client_mapping(clnt_hdl);
	if (!ep->keep_ipa_awake)
		IPA_ACTIVE_CLIENTS_INC_EP(client_type);

	/* Set Disconnect in Progress flag. */
	spin_lock(&ipa_ctx->disconnect_lock);
	ep->disconnect_in_progress = true;
	spin_unlock(&ipa_ctx->disconnect_lock);

	/* Notify uc to stop monitoring holb on USB BAM Producer pipe. */
	if (IPA_CLIENT_IS_USB_CONS(ep->client)) {
		ipa_uc_monitor_holb(ep->client, false);
		IPADBG("Disabling holb monitor for client: %d\n", ep->client);
	}

	result = ipa_disable_data_path(clnt_hdl);
	if (result) {
		IPAERR("disable data path failed res=%d clnt=%d.\n", result,
				clnt_hdl);
		return -EPERM;
	}

	if (IPA_CLIENT_IS_CONS(ep->client))
		bam = ep->connect.source;
	else
		bam = ep->connect.destination;

	result = sps_pipe_reset(bam, clnt_hdl);
	if (result) {
		IPAERR("SPS pipe reset failed.\n");
		return -EPERM;
	}

	ep->ep_disabled = true;

	IPA_ACTIVE_CLIENTS_DEC_EP(client_type);

	IPADBG("client (ep: %d) disabled\n", clnt_hdl);

	return 0;
}


/**
 * ipa_sps_connect_safe() - connect endpoint from BAM prespective
 * @h: [in] sps pipe handle
+6 −0
Original line number Diff line number Diff line
@@ -546,6 +546,7 @@ struct ipa_ep_context {
	bool disconnect_in_progress;
	u32 qmi_request_sent;
	enum ipa_wakelock_ref_client wakelock_client;
	bool ep_disabled;

	/* sys MUST be the last element of this struct */
	struct ipa_sys_context *sys;
@@ -1417,6 +1418,11 @@ int ipa2_reset_endpoint(u32 clnt_hdl);
 */
int ipa2_clear_endpoint_delay(u32 clnt_hdl);

/*
 * Disable ep
 */
int ipa2_disable_endpoint(u32 clnt_hdl);

/*
 * Configuration
 */
+1 −0
Original line number Diff line number Diff line
@@ -4984,6 +4984,7 @@ int ipa2_bind_api_controller(enum ipa_hw_type ipa_hw_type,
	api_ctrl->ipa_disconnect = ipa2_disconnect;
	api_ctrl->ipa_reset_endpoint = ipa2_reset_endpoint;
	api_ctrl->ipa_clear_endpoint_delay = ipa2_clear_endpoint_delay;
	api_ctrl->ipa_disable_endpoint = ipa2_disable_endpoint;
	api_ctrl->ipa_cfg_ep = ipa2_cfg_ep;
	api_ctrl->ipa_cfg_ep_nat = ipa2_cfg_ep_nat;
	api_ctrl->ipa_cfg_ep_hdr = ipa2_cfg_ep_hdr;
Loading