diff options
| author | Sergei Shtylyov <sshtylyov@ru.mvista.com> | 2010-02-27 21:33:21 +0300 | 
|---|---|---|
| committer | Remy Bohmer <linux@bohmer.net> | 2010-04-08 21:39:59 +0200 | 
| commit | c8b2d1dc0f1667029f42c3fa21f70906414af325 (patch) | |
| tree | 0e912b33e762fc9ea2fc715e3d86bb93477a35e5 | |
| parent | e06a055bcd966adf62a5653c84db781915392e41 (diff) | |
| download | olio-uboot-2014.01-c8b2d1dc0f1667029f42c3fa21f70906414af325.tar.xz olio-uboot-2014.01-c8b2d1dc0f1667029f42c3fa21f70906414af325.zip | |
EHCI: fix port reset reporting
Commit b416191a14770c6bcc6fd67be7decf8159b2baee (Fix EHCI port reset.) didn't
move the code that checked for successful clearing of the port reset bit from
ehci_submit_root(), relying on wait_ms() call instead. The mentioned code also
erroneously reported port reset state when the reset was already completed.
Signed-off-by: Sergei Shtylyov <sshtylyov@mvista.com>
| -rw-r--r-- | drivers/usb/host/ehci-hcd.c | 32 | 
1 files changed, 17 insertions, 15 deletions
| diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index d90a23a1f..7784d92b6 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -630,19 +630,8 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,  			tmpbuf[0] |= USB_PORT_STAT_SUSPEND;  		if (reg & EHCI_PS_OCA)  			tmpbuf[0] |= USB_PORT_STAT_OVERCURRENT; -		if (reg & EHCI_PS_PR && -		    (portreset & (1 << le16_to_cpu(req->index)))) { -			int ret; -			/* force reset to complete */ -			reg = reg & ~(EHCI_PS_PR | EHCI_PS_CLEAR); -			ehci_writel(status_reg, reg); -			ret = handshake(status_reg, EHCI_PS_PR, 0, 2 * 1000); -			if (!ret) -				tmpbuf[0] |= USB_PORT_STAT_RESET; -			else -				printf("port(%d) reset error\n", -					le16_to_cpu(req->index) - 1); -		} +		if (reg & EHCI_PS_PR) +			tmpbuf[0] |= USB_PORT_STAT_RESET;  		if (reg & EHCI_PS_PP)  			tmpbuf[1] |= USB_PORT_STAT_POWER >> 8; @@ -699,6 +688,8 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,  				ehci_writel(status_reg, reg);  				break;  			} else { +				int ret; +  				reg |= EHCI_PS_PR;  				reg &= ~EHCI_PS_PE;  				ehci_writel(status_reg, reg); @@ -710,8 +701,19 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,  				wait_ms(50);  				/* terminate the reset */  				ehci_writel(status_reg, reg & ~EHCI_PS_PR); -				wait_ms(2); -				portreset |= 1 << le16_to_cpu(req->index); +				/* +				 * A host controller must terminate the reset +				 * and stabilize the state of the port within +				 * 2 milliseconds +				 */ +				ret = handshake(status_reg, EHCI_PS_PR, 0, +						2 * 1000); +				if (!ret) +					portreset |= +						1 << le16_to_cpu(req->index); +				else +					printf("port(%d) reset error\n", +					le16_to_cpu(req->index) - 1);  			}  			break;  		default: |