From f8aeb3bb8657b207895aa10f75e63f2c48d08985 Mon Sep 17 00:00:00 2001 From: David Brownell Date: Fri, 20 Jan 2006 13:55:14 -0800 Subject: [PATCH] USB: EHCI and NF2 quirk This teaches the EHCI driver about a quirk seen in older NForce2 chips, adding a workaround to ignore selective suspend requests. Bus-wide (so-called "global") suspend still works, as does USB wakeup of a root hub that's globally suspended. There's still a hole in this support though. Strictly speaking, this should _fail_ selective suspend requests, rather than ignoring them, since doing it this way means that devices which should be able to issue remote wakeup are not going to be able to do that. For now, we'll just live with that problem ... since usbcore expects to do selective suspend on the way towards a full bus suspend, and usbcore needs to be able to do full bus suspend. Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'drivers/usb/host/ehci.h') diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 18e257c2bdb5..86af41c41de1 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -89,6 +89,8 @@ struct ehci_hcd { /* one per controller */ u32 command; unsigned is_tdi_rh_tt:1; /* TDI roothub with TT */ + unsigned no_selective_suspend:1; + u8 sbrn; /* packed release number */ /* irq statistics */ #ifdef EHCI_STATS @@ -97,7 +99,6 @@ struct ehci_hcd { /* one per controller */ #else # define COUNT(x) do {} while (0) #endif - u8 sbrn; /* packed release number */ }; /* convert between an HCD pointer and the corresponding EHCI_HCD */ -- cgit v1.2.3 From 8cd42e97bf451bbbb2f54dc571366ae5a72faaea Mon Sep 17 00:00:00 2001 From: Kumar Gala Date: Fri, 20 Jan 2006 13:57:52 -0800 Subject: [PATCH] USB: EHCI and Freescale 83xx quirk On the MPC834x processors the multiport host (MPH) EHCI controller has an erratum in which the port number in the queue head expects to be 0..N-1 instead of 1..N. If we are on one of these chips we subtract one from the port number before putting it into the queue head. Signed-off-by: Kumar Gala Signed-off-by: David Brownell Signed-off-by: Greg Kroah-Hartman --- drivers/usb/host/ehci-fsl.c | 10 ++++++++++ drivers/usb/host/ehci-q.c | 9 ++++++++- drivers/usb/host/ehci.h | 15 +++++++++++++++ 3 files changed, 33 insertions(+), 1 deletion(-) (limited to 'drivers/usb/host/ehci.h') diff --git a/drivers/usb/host/ehci-fsl.c b/drivers/usb/host/ehci-fsl.c index c6012d6cd527..59f90f76ee31 100644 --- a/drivers/usb/host/ehci-fsl.c +++ b/drivers/usb/host/ehci-fsl.c @@ -198,6 +198,16 @@ static void mpc83xx_usb_setup(struct usb_hcd *hcd) mpc83xx_setup_phy(ehci, pdata->phy_mode, 0); if (pdata->operating_mode == FSL_USB2_MPH_HOST) { + unsigned int chip, rev, svr; + + svr = mfspr(SPRN_SVR); + chip = svr >> 16; + rev = (svr >> 4) & 0xf; + + /* Deal with USB Erratum #14 on MPC834x Rev 1.0 & 1.1 chips */ + if ((rev == 1) && (chip >= 0x8050) && (chip <= 0x8055)) + ehci->has_fsl_port_bug = 1; + if (pdata->port_enables & FSL_USB2_PORT0_ENABLED) mpc83xx_setup_phy(ehci, pdata->phy_mode, 0); if (pdata->port_enables & FSL_USB2_PORT1_ENABLED) diff --git a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c index 9b13bf2fa98d..6e28e593c044 100644 --- a/drivers/usb/host/ehci-q.c +++ b/drivers/usb/host/ehci-q.c @@ -721,7 +721,14 @@ qh_make ( info1 |= maxp << 16; info2 |= (EHCI_TUNE_MULT_TT << 30); - info2 |= urb->dev->ttport << 23; + + /* Some Freescale processors have an erratum in which the + * port number in the queue head was 0..N-1 instead of 1..N. + */ + if (ehci_has_fsl_portno_bug(ehci)) + info2 |= (urb->dev->ttport-1) << 23; + else + info2 |= urb->dev->ttport << 23; /* set the address of the TT; for TDI's integrated * root hub tt, leave it zeroed. diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h index 86af41c41de1..679c1cdcc915 100644 --- a/drivers/usb/host/ehci.h +++ b/drivers/usb/host/ehci.h @@ -88,8 +88,11 @@ struct ehci_hcd { /* one per controller */ unsigned long next_statechange; u32 command; + /* SILICON QUIRKS */ unsigned is_tdi_rh_tt:1; /* TDI roothub with TT */ unsigned no_selective_suspend:1; + unsigned has_fsl_port_bug:1; /* FreeScale */ + u8 sbrn; /* packed release number */ /* irq statistics */ @@ -637,6 +640,18 @@ ehci_port_speed(struct ehci_hcd *ehci, unsigned int portsc) #define ehci_port_speed(ehci, portsc) (1<has_fsl_port_bug) +#else +#define ehci_has_fsl_portno_bug(e) (0) +#endif + + /*-------------------------------------------------------------------------*/ #ifndef DEBUG -- cgit v1.2.3