* [PATCH] USB: ehci: tegra: fix USB1 port reset issue
@ 2011-04-17 8:58 Mike Rapoport
[not found] ` <1303030705-20810-1-git-send-email-mike-UTxiZqZC01RS1MOuV/RT9w@public.gmane.org>
0 siblings, 1 reply; 3+ messages in thread
From: Mike Rapoport @ 2011-04-17 8:58 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA,
linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jim Lin, Olof Johansson,
Mike Rapoport
From: Jim Lin <jilin-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Tegra USB1 port needs to issue Port Reset twice internally, otherwise it
fails to enumerate devices attached to it
Signed-off-by: Jim Lin <jilin-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
Signed-off-by: Olof Johansson <olofj-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
[ squash two patches into one and minor style cleanups ]
Signed-off-by: Mike Rapoport <mike-UTxiZqZC01RS1MOuV/RT9w@public.gmane.org>
---
drivers/usb/host/ehci-tegra.c | 72 +++++++++++++++++++++++++++++++++++++++++
1 files changed, 72 insertions(+), 0 deletions(-)
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index a516af2..7359bcb 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -58,6 +58,71 @@ static void tegra_ehci_power_down(struct usb_hcd *hcd)
clk_disable(tegra->emc_clk);
}
+static int tegra_ehci_internal_port_reset(
+ struct ehci_hcd *ehci,
+ u32 __iomem *portsc_reg
+)
+{
+ u32 temp;
+ unsigned long flags;
+ int retval = 0;
+ int i, tries;
+ u32 saved_usbintr;
+
+ spin_lock_irqsave(&ehci->lock, flags);
+ saved_usbintr = ehci_readl(ehci, &ehci->regs->intr_enable);
+ /* disable USB interrupt */
+ ehci_writel(ehci, 0, &ehci->regs->intr_enable);
+ spin_unlock_irqrestore(&ehci->lock, flags);
+
+ /*
+ * Here we have to do Port Reset at most twice for
+ * Port Enable bit to be set.
+ */
+ for (i = 0; i < 2; i++) {
+ temp = ehci_readl(ehci, portsc_reg);
+ temp |= PORT_RESET;
+ ehci_writel(ehci, temp, portsc_reg);
+ mdelay(10);
+ temp &= ~PORT_RESET;
+ ehci_writel(ehci, temp, portsc_reg);
+ mdelay(1);
+ tries = 100;
+ do {
+ mdelay(1);
+ /*
+ * Up to this point, Port Enable bit is
+ * expected to be set after 2 ms waiting.
+ * USB1 usually takes extra 45 ms, for safety,
+ * we take 100 ms as timeout.
+ */
+ temp = ehci_readl(ehci, portsc_reg);
+ } while (!(temp & PORT_PE) && tries--);
+ if (temp & PORT_PE)
+ break;
+ }
+ if (i == 2)
+ retval = -ETIMEDOUT;
+
+ /*
+ * Clear Connect Status Change bit if it's set.
+ * We can't clear PORT_PEC. It will also cause PORT_PE to be cleared.
+ */
+ if (temp & PORT_CSC)
+ ehci_writel(ehci, PORT_CSC, portsc_reg);
+
+ /*
+ * Write to clear any interrupt status bits that might be set
+ * during port reset.
+ */
+ temp = ehci_readl(ehci, &ehci->regs->status);
+ ehci_writel(ehci, temp, &ehci->regs->status);
+
+ /* restore original interrupt enable bits */
+ ehci_writel(ehci, saved_usbintr, &ehci->regs->intr_enable);
+ return retval;
+}
+
static int tegra_ehci_hub_control(
struct usb_hcd *hcd,
u16 typeReq,
@@ -121,6 +186,13 @@ static int tegra_ehci_hub_control(
goto done;
}
+ /* For USB1 port we need to issue Port Reset twice internally */
+ if (tegra->phy->instance == 0 &&
+ (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_RESET)) {
+ spin_unlock_irqrestore(&ehci->lock, flags);
+ return tegra_ehci_internal_port_reset(ehci, status_reg);
+ }
+
/*
* Tegra host controller will time the resume operation to clear the bit
* when the port control state switches to HS or FS Idle. This behavior
--
1.7.3.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH] USB: ehci: tegra: fix USB1 port reset issue
[not found] ` <1303030705-20810-1-git-send-email-mike-UTxiZqZC01RS1MOuV/RT9w@public.gmane.org>
@ 2011-04-27 7:13 ` Mike Rapoport
[not found] ` <4DB7C211.80308-UTxiZqZC01RS1MOuV/RT9w@public.gmane.org>
0 siblings, 1 reply; 3+ messages in thread
From: Mike Rapoport @ 2011-04-27 7:13 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA,
linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jim Lin, Olof Johansson,
Mike Rapoport
Greg,
Any comments on this?
On 04/17/11 11:58, Mike Rapoport wrote:
> From: Jim Lin <jilin-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
>
> Tegra USB1 port needs to issue Port Reset twice internally, otherwise it
> fails to enumerate devices attached to it
>
> Signed-off-by: Jim Lin <jilin-DDmLM1+adcrQT0dZR+AlfA@public.gmane.org>
> Signed-off-by: Olof Johansson <olofj-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
>
> [ squash two patches into one and minor style cleanups ]
>
> Signed-off-by: Mike Rapoport <mike-UTxiZqZC01RS1MOuV/RT9w@public.gmane.org>
> ---
> drivers/usb/host/ehci-tegra.c | 72 +++++++++++++++++++++++++++++++++++++++++
> 1 files changed, 72 insertions(+), 0 deletions(-)
>
> diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
> index a516af2..7359bcb 100644
> --- a/drivers/usb/host/ehci-tegra.c
> +++ b/drivers/usb/host/ehci-tegra.c
> @@ -58,6 +58,71 @@ static void tegra_ehci_power_down(struct usb_hcd *hcd)
> clk_disable(tegra->emc_clk);
> }
>
> +static int tegra_ehci_internal_port_reset(
> + struct ehci_hcd *ehci,
> + u32 __iomem *portsc_reg
> +)
> +{
> + u32 temp;
> + unsigned long flags;
> + int retval = 0;
> + int i, tries;
> + u32 saved_usbintr;
> +
> + spin_lock_irqsave(&ehci->lock, flags);
> + saved_usbintr = ehci_readl(ehci, &ehci->regs->intr_enable);
> + /* disable USB interrupt */
> + ehci_writel(ehci, 0, &ehci->regs->intr_enable);
> + spin_unlock_irqrestore(&ehci->lock, flags);
> +
> + /*
> + * Here we have to do Port Reset at most twice for
> + * Port Enable bit to be set.
> + */
> + for (i = 0; i < 2; i++) {
> + temp = ehci_readl(ehci, portsc_reg);
> + temp |= PORT_RESET;
> + ehci_writel(ehci, temp, portsc_reg);
> + mdelay(10);
> + temp &= ~PORT_RESET;
> + ehci_writel(ehci, temp, portsc_reg);
> + mdelay(1);
> + tries = 100;
> + do {
> + mdelay(1);
> + /*
> + * Up to this point, Port Enable bit is
> + * expected to be set after 2 ms waiting.
> + * USB1 usually takes extra 45 ms, for safety,
> + * we take 100 ms as timeout.
> + */
> + temp = ehci_readl(ehci, portsc_reg);
> + } while (!(temp & PORT_PE) && tries--);
> + if (temp & PORT_PE)
> + break;
> + }
> + if (i == 2)
> + retval = -ETIMEDOUT;
> +
> + /*
> + * Clear Connect Status Change bit if it's set.
> + * We can't clear PORT_PEC. It will also cause PORT_PE to be cleared.
> + */
> + if (temp & PORT_CSC)
> + ehci_writel(ehci, PORT_CSC, portsc_reg);
> +
> + /*
> + * Write to clear any interrupt status bits that might be set
> + * during port reset.
> + */
> + temp = ehci_readl(ehci, &ehci->regs->status);
> + ehci_writel(ehci, temp, &ehci->regs->status);
> +
> + /* restore original interrupt enable bits */
> + ehci_writel(ehci, saved_usbintr, &ehci->regs->intr_enable);
> + return retval;
> +}
> +
> static int tegra_ehci_hub_control(
> struct usb_hcd *hcd,
> u16 typeReq,
> @@ -121,6 +186,13 @@ static int tegra_ehci_hub_control(
> goto done;
> }
>
> + /* For USB1 port we need to issue Port Reset twice internally */
> + if (tegra->phy->instance == 0 &&
> + (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_RESET)) {
> + spin_unlock_irqrestore(&ehci->lock, flags);
> + return tegra_ehci_internal_port_reset(ehci, status_reg);
> + }
> +
> /*
> * Tegra host controller will time the resume operation to clear the bit
> * when the port control state switches to HS or FS Idle. This behavior
--
Sincerely yours,
Mike.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH] USB: ehci: tegra: fix USB1 port reset issue
[not found] ` <4DB7C211.80308-UTxiZqZC01RS1MOuV/RT9w@public.gmane.org>
@ 2011-04-27 23:27 ` Greg KH
0 siblings, 0 replies; 3+ messages in thread
From: Greg KH @ 2011-04-27 23:27 UTC (permalink / raw)
To: Mike Rapoport
Cc: Greg Kroah-Hartman, linux-usb-u79uwXL29TY76Z2rM5mHXA,
linux-tegra-u79uwXL29TY76Z2rM5mHXA, Jim Lin, Olof Johansson
On Wed, Apr 27, 2011 at 10:13:21AM +0300, Mike Rapoport wrote:
> Greg,
>
> Any comments on this?
It's in my queue, sorry, I have a whole lot of things going on at the
moment in my "real life", I will get to this eventually, it's not
lost...
thanks,
greg k-h
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2011-04-27 23:27 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-04-17 8:58 [PATCH] USB: ehci: tegra: fix USB1 port reset issue Mike Rapoport
[not found] ` <1303030705-20810-1-git-send-email-mike-UTxiZqZC01RS1MOuV/RT9w@public.gmane.org>
2011-04-27 7:13 ` Mike Rapoport
[not found] ` <4DB7C211.80308-UTxiZqZC01RS1MOuV/RT9w@public.gmane.org>
2011-04-27 23:27 ` Greg KH
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox