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:
Hemant Kumar
2012-06-27 12:47:19 -07:00
parent e44a4fe292
commit e404049ae6
3 changed files with 19 additions and 7 deletions
+16
View File
@@ -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) */
+2 -7
View File
@@ -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,
+1
View File
@@ -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 */