[Cbe-oss-dev] [PATCH 1/5 v3] usb: Fix PS3 EHCI suspend

Alan Stern stern at rowland.harvard.edu
Fri Dec 9 03:33:34 EST 2011


On Thu, 8 Dec 2011, Geoff Levand wrote:

> >From c31be6b8e75d54b883ce8cbf3e1b770eecf4cafc Mon Sep 17 00:00:00 2001
> From: Geoff Levand <geoff at infradead.org>
> 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 at infradead.org>
> ---
> 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 at rowland.harvard.edu>



More information about the cbe-oss-dev mailing list