From 3b3f0cbc7776acf15f8945c11f6d6f9f13abf757 Mon Sep 17 00:00:00 2001 From: Jay Cheng Date: Mon, 22 Nov 2010 11:03:52 -0500 Subject: [PATCH] usb: host: tegra: Reduce busy polling duration Change-Id: I63e271409818e33b4c19bb99b00e556bc5a2a4b3 Signed-off-by: Jay Cheng --- drivers/usb/host/ehci-tegra.c | 50 +++++++++++++++++++---------------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c index 60db07950528..5cdad2531ba1 100644 --- a/drivers/usb/host/ehci-tegra.c +++ b/drivers/usb/host/ehci-tegra.c @@ -91,35 +91,34 @@ static int tegra_ehci_hub_control( status_reg = &ehci->regs->port_status[(wIndex & 0xff) - 1]; + spin_lock_irqsave(&ehci->lock, flags); + /* * In ehci_hub_control() for USB_PORT_FEAT_ENABLE clears the other bits * that are write on clear, by writing back the register read value, so * USB_PORT_FEAT_ENABLE is handled by masking the set on clear bits */ if (typeReq == ClearPortFeature && wValue == USB_PORT_FEAT_ENABLE) { - spin_lock_irqsave(&ehci->lock, flags); temp = ehci_readl(ehci, status_reg); ehci_writel(ehci, (temp & ~PORT_RWC_BITS) & ~PORT_PE, status_reg); - spin_unlock_irqrestore(&ehci->lock, flags); - return retval; + goto done; } - if (typeReq == GetPortStatus) { - spin_lock_irqsave(&ehci->lock, flags); + else if (typeReq == GetPortStatus) { temp = ehci_readl(ehci, status_reg); - if (tegra->port_resuming && !(temp & PORT_SUSPEND)) { + if (tegra->port_resuming && !(temp & PORT_SUSPEND)) { /* resume completed */ tegra->port_resuming = 0; tegra_usb_phy_postresume(tegra->phy); } - spin_unlock_irqrestore(&ehci->lock, flags); } - if (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_SUSPEND) { - spin_lock_irqsave(&ehci->lock, flags); + else if (typeReq == SetPortFeature && wValue == USB_PORT_FEAT_SUSPEND) { temp = ehci_readl(ehci, status_reg); - if ((temp & PORT_PE) == 0 || (temp & PORT_RESET) != 0) + if ((temp & PORT_PE) == 0 || (temp & PORT_RESET) != 0) { retval = -EPIPE; + goto done; + } /* After above check the port must be connected. * Set appropriate bit thus could put phy into low power @@ -131,8 +130,7 @@ static int tegra_ehci_hub_control( if (handshake(ehci, status_reg, PORT_SUSPEND, PORT_SUSPEND, 5000)) pr_err("%s: timeout waiting for PORT_SUSPEND\n", __func__); - spin_unlock_irqrestore(&ehci->lock, flags); - return retval; + goto done; } /* @@ -142,17 +140,16 @@ static int tegra_ehci_hub_control( * to set this bit to a zero after the resume duration is timed in the * driver. */ - if (typeReq == ClearPortFeature && wValue == USB_PORT_FEAT_SUSPEND) { - spin_lock_irqsave(&ehci->lock, flags); + else if (typeReq == ClearPortFeature && wValue == USB_PORT_FEAT_SUSPEND) { temp = ehci_readl(ehci, status_reg); - if ((temp & PORT_RESET) || !(temp & PORT_PE)) + if ((temp & PORT_RESET) || !(temp & PORT_PE)) { retval = -EPIPE; - - if (!(temp & PORT_SUSPEND)) { - spin_unlock_irqrestore(&ehci->lock, flags); - return retval; + goto done; } + if (!(temp & PORT_SUSPEND)) + goto done; + tegra_usb_phy_preresume(tegra->phy); /* reschedule root hub polling during resume signaling */ @@ -165,8 +162,12 @@ static int tegra_ehci_hub_control( /* start resume signalling */ ehci_writel(ehci, temp | PORT_RESUME, status_reg); + spin_unlock_irqrestore(&ehci->lock, flags); + msleep(20); + spin_lock_irqsave(&ehci->lock, flags); + /* polling PORT_RESUME until the controller clear this bit */ - if (handshake(ehci, status_reg, PORT_RESUME, 0, 20000)) + if (handshake(ehci, status_reg, PORT_RESUME, 0, 2000)) pr_err("%s: timeout waiting for PORT_RESUME\n", __func__); /* write PORT_RESUME to 0 to clear PORT_SUSPEND bit */ @@ -178,13 +179,16 @@ static int tegra_ehci_hub_control( pr_err("%s: timeout waiting for PORT_SUSPEND\n", __func__); tegra->port_resuming = 1; - - spin_unlock_irqrestore(&ehci->lock, flags); - return retval; + goto done; } + spin_unlock_irqrestore(&ehci->lock, flags); + /* Handle the hub control events here */ return ehci_hub_control(hcd, typeReq, wValue, wIndex, buf, wLength); +done: + spin_unlock_irqrestore(&ehci->lock, flags); + return retval; } static void tegra_ehci_restart(struct usb_hcd *hcd) -- 2.34.1