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

Commit ede8a8aa authored by Hemant Kumar's avatar Hemant Kumar Committed by Stephen Boyd
Browse files

EHCI: HSIC: Set RUN/STOP bit after PORT_RESUME gets cleared



There is a possibility of HSIC phy getting locked up if RUN/STOP
bit is set before finishing the resume signaling. Hence do not
set the RUN/STOP bit before setting PORT_RESUME bit. Since
PORT_RESUME bit gets cleared automatically by HSIC HW after bus
resume is completed, need to set RUN/STOP bit right after that.

CRs-Fixed: 372145
Change-Id: Icb9effefe14c10f13cfbb3d8f1840c8bdd96aea4
Signed-off-by: default avatarHemant Kumar <hemantk@codeaurora.org>
parent 48dde407
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -400,6 +400,9 @@ static int __maybe_unused ehci_bus_resume(struct usb_hcd *hcd)
	ehci_writel(ehci, ehci->periodic_dma, &ehci->regs->frame_list);
	ehci_writel(ehci, (u32) ehci->async->qh_dma, &ehci->regs->async_next);

	/*CMD_RUN will be set after, PORT_RESUME gets cleared*/
	if (ehci->resume_sof_bug)
		ehci->command &= ~CMD_RUN;
	/* restore CMD_RUN, framelist size, and irq threshold */
	ehci->command |= CMD_RUN;
	ehci_writel(ehci, ehci->command, &ehci->regs->command);
@@ -459,6 +462,17 @@ static int __maybe_unused ehci_bus_resume(struct usb_hcd *hcd)
		ehci_writel(ehci, temp, &ehci->regs->port_status [i]);
	}

	if (ehci->resume_sof_bug && resume_needed) {
		/* root hub has only one port.
		 * PORT_RESUME gets cleared automatically. */
		handshake(ehci, &ehci->regs->port_status[0], PORT_RESUME, 0,
				20000);
		ehci_writel(ehci, ehci_readl(ehci,
				&ehci->regs->command) | CMD_RUN,
				&ehci->regs->command);
		goto skip_clear_resume;
	}

	/* msleep for 20ms only if code is trying to resume port */
	if (resume_needed) {
		spin_unlock_irq(&ehci->lock);
@@ -478,6 +492,7 @@ static int __maybe_unused ehci_bus_resume(struct usb_hcd *hcd)
		}
	}

skip_clear_resume:
	ehci->next_statechange = jiffies + msecs_to_jiffies(5);
	spin_unlock_irq(&ehci->lock);

+2 −7
Original line number Diff line number Diff line
@@ -738,13 +738,6 @@ static int msm_hsic_resume(struct msm_hsic_hcd *mehci)

skip_phy_resume:

	if (!(readl_relaxed(USB_USBCMD) & CMD_RUN) &&
			(readl_relaxed(USB_PORTSC) & PORT_SUSPEND)) {
		writel_relaxed(readl_relaxed(USB_USBCMD) | CMD_RUN ,
				USB_USBCMD);
		dbg_log_event(NULL, "Set RS", readl_relaxed(USB_USBCMD));
	}

	usb_hcd_resume_root_hub(hcd);

	atomic_set(&mehci->in_lpm, 0);
@@ -1221,6 +1214,8 @@ static int ehci_hsic_msm_probe(struct platform_device *pdev)
	mehci->ehci.susp_sof_bug = 1;
	mehci->ehci.reset_sof_bug = 1;

	mehci->ehci.resume_sof_bug = 1;

	mehci->ehci.max_log2_irq_thresh = 6;

	res = platform_get_resource_byname(pdev,
+1 −0
Original line number Diff line number Diff line
@@ -203,6 +203,7 @@ struct ehci_hcd { /* one per controller */
	unsigned		frame_index_bug:1; /* MosChip (AKA NetMos) */
	unsigned		need_oc_pp_cycle:1; /* MPC834X port power */
	unsigned		susp_sof_bug:1; /*Chip Idea HC*/
	unsigned		resume_sof_bug:1;/*Chip Idea HC*/
	unsigned		reset_sof_bug:1; /*Chip Idea HC*/

	/* required for usb32 quirk */