On Thu, 8 Dec 2011, Geoff Levand wrote: > >From c31be6b8e75d54b883ce8cbf3e1b770eecf4cafc Mon Sep 17 00:00:00 2001 > From: Geoff Levand <geoff@xxxxxxxxxxxxx> > Date: Wed, 30 Nov 2011 16:40:57 -0800 > Subject: [PATCH 3/4] usb: Fix PS3 EHCI suspend > > The EHCI USB controller of the Cell Super Companion Chip used in the PS3 > will stop the root hub after all root hub ports are suspended. When in > this condition the ehci-hcd handshake routine will return -ETIMEDOUT and > the USB runtime suspend sequence will fail. The STS_HLT bit will not be > set, so inspection of the frame index is used to test for the condition. > > Add a new routine handshake_for_broken_root_hub() that is called after > an unsuccessful -ETIMEDOUT handshake. On PS3 handshake_for_broken_root_hub() > will test for the condition, and if found will return success to allow the > USB suspend to complete. For all other platforms > handshake_for_broken_root_hub() will return -ETIMEDOUT > > Signed-off-by: Geoff Levand <geoff@xxxxxxxxxxxxx> > --- > Here's a resend, the previous one had damaged whitespace. > > -Geoff > > v2: - Put work-around in handshake_on_error_set_halt(). > v3: - Put fix into handshake_for_broken_root_hub(). > > drivers/usb/host/ehci-hcd.c | 50 > +++++++++++++++++++++++++++++++++++++++++++ > 1 files changed, 50 insertions(+), 0 deletions(-) > > diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c > index 46dccbf..e0ca995 100644 > --- a/drivers/usb/host/ehci-hcd.c > +++ b/drivers/usb/host/ehci-hcd.c > @@ -48,6 +48,10 @@ > #include <asm/system.h> > #include <asm/unaligned.h> > > +#if defined(CONFIG_PPC_PS3) > +#include <asm/firmware.h> > +#endif > + > /*-------------------------------------------------------------------------*/ > > /* > @@ -230,12 +234,58 @@ static int ehci_halt (struct ehci_hcd *ehci) > STS_HALT, STS_HALT, 16 * 125); > } > > +#if defined(CONFIG_USB_SUSPEND) && defined(CONFIG_PPC_PS3) > + > +/* > + * The EHCI controller of the Cell Super Companion Chip used in the > + * PS3 will stop the root hub after all root hub ports are suspended. > + * When in this condition handshake will return -ETIMEDOUT. The > + * STS_HLT bit will not be set, so inspection of the frame index is > + * used here to test for the condition. If the condition is found > + * return success to allow the USB suspend to complete. > + */ > + > +static int handshake_for_broken_root_hub(struct ehci_hcd *ehci, > + void __iomem *ptr, u32 mask, u32 done, > + int usec) > +{ > + unsigned int old_index; > + int error; > + > + if (!firmware_has_feature(FW_FEATURE_PS3_LV1)) > + return -ETIMEDOUT; > + > + old_index = ehci_read_frame_index(ehci); > + > + error = handshake(ehci, ptr, mask, done, usec); > + > + if (error == -ETIMEDOUT && ehci_read_frame_index(ehci) == old_index) > + return 0; > + > + return error; > +} > + > +#else > + > +static int handshake_for_broken_root_hub(struct ehci_hcd *ehci, > + void __iomem *ptr, u32 mask, u32 done, > + int usec) > +{ > + return -ETIMEDOUT; > +} > + > +#endif > + > static int handshake_on_error_set_halt(struct ehci_hcd *ehci, void __iomem *ptr, > u32 mask, u32 done, int usec) > { > int error; > > error = handshake(ehci, ptr, mask, done, usec); > + if (error == -ETIMEDOUT) > + error = handshake_for_broken_root_hub(ehci, ptr, mask, done, > + usec); > + > if (error) { > ehci_halt(ehci); > ehci->rh_state = EHCI_RH_HALTED; Signed-off-by: Alan Stern <stern@xxxxxxxxxxxxxxxxxxx> -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html