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

Commit b4ae4b99 authored by Vijayavardhan Vennapusa's avatar Vijayavardhan Vennapusa Committed by Manu Gautam
Browse files

USB: gadget: Perform BAM reset as part of disconnect processing



Currently BAM reset is not performed as part of disconnect processing.
This is causing EP flush issues during connect/disconnect and
composition switch, which results in basic USB functionality
failure. USB doesn't recover unless cable is reconnected. As per hardware
programming guide, it is required to do BAM reset during disconnect
processing. Hence make necessary changes to perform BAM reset during
disconnect.

Also disable USB interrupt before scheduling disconnect work in function
drivers which uses BAM2BAM mode and re-enable it once either disconnect
processing and BAM reset is done or one second timer expires to enable
forcefully.

CRs-Fixed: 830194
Change-Id: Ic7c3c5621b0a02ce33c04ea6fbfb2dd86383ece3
Signed-off-by: default avatarVijayavardhan Vennapusa <vvreddy@codeaurora.org>
parent 23eab882
Loading
Loading
Loading
Loading
+24 −2
Original line number Diff line number Diff line
@@ -2657,6 +2657,8 @@ int usb_bam_disconnect_pipe(u8 idx)
{
	struct usb_bam_pipe_connect *pipe_connect;
	int ret;
	struct msm_usb_bam_platform_data *pdata =
					ctx.usb_bam_pdev->dev.platform_data;

	pipe_connect = &usb_bam_connections[idx];

@@ -2682,6 +2684,22 @@ int usb_bam_disconnect_pipe(u8 idx)
	spin_unlock(&usb_bam_lock);
	log_event(1, "%s: success disconnecting pipe %d\n",
			 __func__, idx);

	if ((pdata->reset_on_disconnect[pipe_connect->bam_type] == true) &&
		(ctx.pipes_enabled_per_bam[pipe_connect->bam_type] == 0)) {
		if (pipe_connect->bam_type == CI_CTRL)
			msm_hw_bam_disable(1);

		sps_device_reset(ctx.h_bam[pipe_connect->bam_type]);

		if (pipe_connect->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 (pipe_connect->bam_type == CI_CTRL)
			msm_usb_irq_disable(false);
	}
	return 0;
}

@@ -2752,7 +2770,6 @@ int usb_bam_disconnect_ipa(struct usb_bam_connect_ipa_params *ipa_params)
				IPA_RM_RESOURCE_RELEASED,
				ipa_rm_resource_cons[cur_bam]);
		}

	}

out:
@@ -2830,7 +2847,7 @@ static struct msm_usb_bam_platform_data *usb_bam_dt_to_pdata(
	struct device_node *node = pdev->dev.of_node;
	int rc = 0;
	u8 i = 0;
	bool reset_bam;
	bool reset_bam, reset_bam_on_disconnect;
	u32 bam;
	u32 addr;
	u32 threshold;
@@ -2978,6 +2995,11 @@ static struct msm_usb_bam_platform_data *usb_bam_dt_to_pdata(
		if (reset_bam)
			pdata->reset_on_connect[bam] = true;

		reset_bam_on_disconnect = of_property_read_bool(node,
			"qcom,reset-bam-on-disconnect");
		if (reset_bam_on_disconnect)
			pdata->reset_on_disconnect[bam] = true;

		of_property_read_u32(node, "qcom,src-bam-physical-address",
			&usb_bam_connections[i].src_phy_addr);

+8 −0
Original line number Diff line number Diff line
@@ -591,6 +591,12 @@ static void qdss_disable(struct usb_function *f)
	case USB_GADGET_XPORT_BAM2BAM_IPA:
	case USB_GADGET_XPORT_BAM_DMUX:
		spin_unlock_irqrestore(&qdss->lock, flags);
		/* Disable usb irq for CI gadget. It will be enabled in
		 * usb_bam_disconnect_pipe() after disconnecting all pipes
		 * and USB BAM reset is done.
		 */
		if (!gadget_is_dwc3(qdss->cdev->gadget))
			msm_usb_irq_disable(true);
		usb_qdss_disconnect_work(&qdss->disconnect_w);
		return;
	default:
@@ -602,6 +608,8 @@ static void qdss_disable(struct usb_function *f)
	/*cancell all active xfers*/
	qdss_eps_disable(f);
	msm_bam_set_qdss_usb_active(true);
	if (!gadget_is_dwc3(qdss->cdev->gadget))
		msm_usb_irq_disable(true);
	queue_work(qdss->wq, &qdss->disconnect_w);
}

+8 −0
Original line number Diff line number Diff line
@@ -2049,6 +2049,14 @@ void gbam_disconnect(struct grmnet *gr, u8 port_num, enum transport_type trans)
		gr->out->driver_data = NULL;

	port->last_event = U_BAM_DISCONNECT_E;
	/* Disable usb irq for CI gadget. It will be enabled in
	 * usb_bam_disconnect_pipe() after disconnecting all pipes
	 * and USB BAM reset is done.
	 */
	if (!gadget_is_dwc3(port->gadget) &&
			(trans == USB_GADGET_XPORT_BAM2BAM_IPA))
		msm_usb_irq_disable(true);

	queue_work(gbam_wq, &port->disconnect_w);

	spin_unlock_irqrestore(&port->port_lock, flags);
+7 −0
Original line number Diff line number Diff line
@@ -1402,6 +1402,13 @@ void bam_data_disconnect(struct data_port *gr, enum function_type func,
	}

	port->last_event = U_BAM_DATA_DISCONNECT_E;
	/* Disable usb irq for CI gadget. It will be enabled in
	 * usb_bam_disconnect_pipe() after disconnecting all pipes
	 * and USB BAM reset is done.
	 */
	if (!gadget_is_dwc3(port->gadget))
		msm_usb_irq_disable(true);

	queue_work(bam_data_wq, &port->disconnect_w);

	spin_unlock_irqrestore(&port->port_lock, flags);
+4 −0
Original line number Diff line number Diff line
@@ -658,10 +658,14 @@ static inline void msm_bam_set_qdss_usb_active(bool is_active) {}
#endif
#ifdef CONFIG_USB_CI13XXX_MSM
void msm_hw_bam_disable(bool bam_disable);
void msm_usb_irq_disable(bool disable);
#else
static inline void msm_hw_bam_disable(bool bam_disable)
{
}
static inline void msm_usb_irq_disable(bool disable)
{
}
#endif

#ifdef CONFIG_USB_DWC3_MSM
Loading