[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