mirror of
https://github.com/LineageOS/android_kernel_samsung_msm8226.git
synced 2026-10-08 00:01:05 +02:00
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: Hemant Kumar <hemantk@codeaurora.org>
This commit is contained in:
@@ -380,6 +380,9 @@ static int 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_writel(ehci, ehci->command, &ehci->regs->command);
|
||||
ehci->rh_state = EHCI_RH_RUNNING;
|
||||
@@ -422,6 +425,17 @@ static int 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);
|
||||
@@ -438,6 +452,8 @@ static int ehci_bus_resume (struct usb_hcd *hcd)
|
||||
ehci_vdbg (ehci, "resumed port %d\n", i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
skip_clear_resume:
|
||||
(void) ehci_readl(ehci, &ehci->regs->command);
|
||||
|
||||
/* maybe re-activate the schedule(s) */
|
||||
|
||||
@@ -730,13 +730,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);
|
||||
@@ -1246,6 +1239,8 @@ static int __devinit 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,
|
||||
|
||||
@@ -152,6 +152,7 @@ struct ehci_hcd { /* one per controller */
|
||||
unsigned has_synopsys_hc_bug:1; /* Synopsys HC */
|
||||
unsigned frame_index_bug:1; /* MosChip (AKA NetMos) */
|
||||
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 */
|
||||
|
||||
Reference in New Issue
Block a user