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

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

Merge "ARM: dts: msm: Don't set reset-bam-on-disconnect for msm8940/8952"

parents 3d35f9e9 3b66e69b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -40,6 +40,7 @@
	qcom,usbbam@78c4000 {
		qcom,enable-hsusb-bam-on-boot;

		/delete-property/ qcom,reset-bam-on-disconnect;
		/delete-node/ qcom,pipe0;
		qcom,pipe0 {
			label = "hsusb-ipa-out-0";
+0 −1
Original line number Diff line number Diff line
@@ -1069,7 +1069,6 @@
			qcom,ignore-core-reset-ack;
			qcom,disable-clk-gating;
			qcom,usb-bam-max-mbps-highspeed = <400>;
			qcom,reset-bam-on-disconnect;

			qcom,pipe0 {
				label = "hsusb-ipa-out-0";
+127 −5
Original line number Diff line number Diff line
@@ -2644,12 +2644,12 @@ int usb_bam_disconnect_pipe(enum usb_ctrl bam_type, u8 idx)

		if (bam_type == CI_CTRL)
			msm_hw_bam_disable(0);
	}
	/* Enable usb irq here which is disabled in function drivers
	 * during disconnect after BAM reset.
	 */
		if (bam_type == CI_CTRL)
	if (!ctx->pipes_enabled_per_bam && (bam_type == CI_CTRL))
		msm_usb_irq_disable(false);
	}
	/* This function is directly called by USB Transport drivers
	 * to disconnect pipes. Drop runtime usage count here. For
	 * IPA, caller takes care of it
@@ -3053,6 +3053,7 @@ static int usb_bam_init(struct platform_device *pdev)
	if (pdata->enable_hsusb_bam_on_boot && bam_type == CI_CTRL) {
		pr_debug("Register and enable HSUSB BAM\n");
		props.options |= SPS_BAM_OPT_ENABLE_AT_BOOT;
		props.options |= SPS_BAM_FORCE_RESET;
	}
	ret = sps_register_bam_device(&props, &ctx->h_bam);

@@ -3395,6 +3396,127 @@ int usb_bam_get_bam_type(const char *core_name)
}
EXPORT_SYMBOL(usb_bam_get_bam_type);

/*
 * This function makes sure ipa endpoints are disabled for both USB->IPA
 * and IPA->USB pipes before USB bam reset. USB BAM reset is required to
 * to avoid EP flush issues while disabling USB endpoints on disconnect.
 */
int msm_do_bam_disable_enable(enum usb_ctrl bam)
{
	struct usb_bam_ctx_type *ctx = &msm_usb_bam[bam];
	struct sps_pipe *pipe;
	u32 timeout = 10, pipe_empty;
	int ret = 0, i;
	struct sps_connect *sps_connection;
	struct usb_bam_sps_type usb_bam_sps = ctx->usb_bam_sps;
	struct usb_bam_pipe_connect *pipe_connect;
	int qdss_idx;
	struct msm_usb_bam_platform_data *pdata;

	if (!ctx->usb_bam_pdev)
		return 0;

	pdata = ctx->usb_bam_pdev->dev.platform_data;
	if ((bam != CI_CTRL) || !pdata->enable_hsusb_bam_on_boot)
		return 0;

	if (!ctx->pipes_enabled_per_bam || info[bam].pipes_suspended)
		return 0;

	if (in_interrupt()) {
		pr_err("%s:API called in interrupt context\n", __func__);
		return 0;
	}

	mutex_lock(&info[bam].suspend_resume_mutex);
	log_event_dbg("%s: Perform USB BAM reset\n", __func__);
	/* Get QDSS pipe index to avoid pipe reset */
	qdss_idx = usb_bam_get_connection_idx(qdss_usb_bam_type, QDSS_P_BAM,
		PEER_PERIPHERAL_TO_USB, USB_BAM_DEVICE, 0);

	for (i = 0; i < ctx->max_connections; i++) {
		pipe_connect = &ctx->usb_bam_connections[i];
		if (pipe_connect->enabled &&
				(pipe_connect->dir == PEER_PERIPHERAL_TO_USB) &&
							(qdss_idx != i)) {
			/* Call to disable IPA producer endpoint */
			ipa_disable_endpoint(pipe_connect->ipa_clnt_hdl);
			sps_pipe_reset(ctx->h_bam,
						pipe_connect->dst_pipe_index);
		}
	}

	for (i = 0; i < ctx->max_connections; i++) {
		pipe_connect = &ctx->usb_bam_connections[i];
		if (pipe_connect->enabled &&
				(pipe_connect->dir == USB_TO_PEER_PERIPHERAL) &&
							(qdss_idx != i)) {
			pipe = ctx->usb_bam_sps.sps_pipes[i];
			sps_connection = &usb_bam_sps.sps_connections[i];
			timeout = 10;
			/*
			 * On some platforms, there is a chance that flow
			 * control is disabled from IPA side, due to this IPA
			 * core may not consume data from USB. Hence notify IPA
			 * to enable flow control and then check sps pipe is
			 * empty or not before processing USB->IPA disconnect.
			 */
			ipa_clear_endpoint_delay(pipe_connect->ipa_clnt_hdl);

			/* Make sure pipes are empty before disconnecting it */
			while (1) {
				ret = sps_is_pipe_empty(pipe, &pipe_empty);
				if (ret) {
					log_event_err("%s: pipeempty fail %d\n",
								__func__, ret);
					goto err;
				}
				if (pipe_empty || !--timeout)
					break;

				/* Check again */
				usleep_range(1000, 2000);
			}
			if (!pipe_empty) {
				log_event_dbg("%s: Inject ZLT\n", __func__);
				sps_pipe_inject_zlt(sps_connection->destination,
					sps_connection->dest_pipe_index);

				timeout = 0;
				while (1) {
					ret = sps_is_pipe_empty(pipe,
								&pipe_empty);
					if (ret)
						goto err;

					if (pipe_empty)
						break;

					timeout++;
					/* Check again */
					usleep_range(1000, 2000);
				}
			}
			/* Call to disable IPA consumer endpoint */
			ipa_disable_endpoint(pipe_connect->ipa_clnt_hdl);
			sps_pipe_reset(ctx->h_bam,
						pipe_connect->src_pipe_index);
		}
	}

	/* Perform USB BAM reset */
	msm_hw_bam_disable(1);
	sps_device_reset(ctx->h_bam);
	msm_hw_bam_disable(0);
	log_event_dbg("%s: USB BAM reset done\n", __func__);
	ret = 0;

err:
	mutex_unlock(&info[bam].suspend_resume_mutex);
	return ret;
}
EXPORT_SYMBOL(msm_do_bam_disable_enable);

bool msm_usb_bam_enable(enum usb_ctrl bam, bool bam_enable)
{
	struct msm_usb_bam_platform_data *pdata;
+21 −2
Original line number Diff line number Diff line
@@ -18,7 +18,9 @@
#include <linux/device.h>
#include <linux/utsname.h>

#include "gadget_chips.h"
#include <linux/usb/composite.h>
#include <linux/usb/msm_hsusb.h>
#include <asm/unaligned.h>

#include "u_os_desc.h"
@@ -722,6 +724,11 @@ static void reset_config(struct usb_composite_dev *cdev)

	DBG(cdev, "reset config\n");

	if (!cdev->config) {
		pr_err("%s:cdev->config is already NULL\n", __func__);
		return;
	}

	list_for_each_entry(f, &cdev->config->functions, list) {
		if (f->disable)
			f->disable(f);
@@ -1023,8 +1030,14 @@ void usb_remove_config(struct usb_composite_dev *cdev,
		return;
	}

	if (cdev->config == config)
	if (cdev->config == config) {
		if (!gadget_is_dwc3(cdev->gadget) && !cdev->suspended) {
			spin_unlock_irqrestore(&cdev->lock, flags);
			msm_do_bam_disable_enable(CI_CTRL);
			spin_lock_irqsave(&cdev->lock, flags);
		}
		reset_config(cdev);
	}

	list_del(&config->list);

@@ -2015,8 +2028,14 @@ void composite_disconnect(struct usb_gadget *gadget)
	 * disconnect callbacks?
	 */
	spin_lock_irqsave(&cdev->lock, flags);
	if (cdev->config)
	if (cdev->config) {
		if (!gadget_is_dwc3(gadget) && !cdev->suspended) {
			spin_unlock_irqrestore(&cdev->lock, flags);
			msm_do_bam_disable_enable(CI_CTRL);
			spin_lock_irqsave(&cdev->lock, flags);
		}
		reset_config(cdev);
	}
	if (cdev->driver->disconnect)
		cdev->driver->disconnect(cdev);
	if (cdev->delayed_status != 0) {
+9 −9
Original line number Diff line number Diff line
@@ -2091,6 +2091,15 @@ void gbam_disconnect(struct grmnet *gr, u8 port_num, enum transport_type trans)
	spin_unlock(&port->port_lock_dl);
	spin_unlock_irqrestore(&port->port_lock_ul, flags_ul);

	usb_ep_disable(gr->in);
	if (trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
		spin_lock_irqsave(&port->port_lock_dl, flags_dl);
		if (d->tx_req) {
			usb_ep_free_request(gr->in, d->tx_req);
			d->tx_req = NULL;
		}
		spin_unlock_irqrestore(&port->port_lock_dl, flags_dl);
	}
	/* disable endpoints */
	if (gr->out) {
		usb_ep_disable(gr->out);
@@ -2103,15 +2112,6 @@ void gbam_disconnect(struct grmnet *gr, u8 port_num, enum transport_type trans)
			spin_unlock_irqrestore(&port->port_lock_ul, flags_ul);
		}
	}
	usb_ep_disable(gr->in);
	if (trans == USB_GADGET_XPORT_BAM2BAM_IPA) {
		spin_lock_irqsave(&port->port_lock_dl, flags_dl);
		if (d->tx_req) {
			usb_ep_free_request(gr->in, d->tx_req);
			d->tx_req = NULL;
		}
		spin_unlock_irqrestore(&port->port_lock_dl, flags_dl);
	}

	/*
	 * Set endless flag to false as USB Endpoint is already
Loading