[PATCH 1/5 v2] usb: Fix PS3 EHCI suspend

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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 fix implemented here is to check the result of the handshake
call done in handshake_on_error_set_halt() and if the condition
is found return success to allow the USB suspend to complete.
The STS_HLT bit will not be set, so inspection of the frame index
is used to test for the condition.

Signed-off-by: Geoff Levand <geoff@xxxxxxxxxxxxx>
---
Alan,

I did the logic so that there would be a minimal overhead
when running on PS3, and should be optimized out when
CONFIG_PPC_PS3=n.

-Geoff

v2: - Put work-around in handshake_on_error_set_halt();

 drivers/usb/host/ehci-hcd.c |   28 ++++++++++++++++++++++++++++
 1 files changed, 28 insertions(+), 0 deletions(-)

diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 46dccbf..4a8391c 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
+
 /*-------------------------------------------------------------------------*/
 
 /*
@@ -236,6 +240,30 @@ static int handshake_on_error_set_halt(struct ehci_hcd *ehci, void __iomem *ptr,
 	int error;
 
 	error = handshake(ehci, ptr, mask, done, usec);
+
+	/*
+	 * 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.
+	 */
+
+#if defined(CONFIG_USB_SUSPEND) && defined(CONFIG_PPC_PS3)
+	if (firmware_has_feature(FW_FEATURE_PS3_LV1) && error == -ETIMEDOUT) {
+#else
+	if (0) {
+#endif
+		unsigned int 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;
+	}
+
 	if (error) {
 		ehci_halt(ehci);
 		ehci->rh_state = EHCI_RH_HALTED;
-- 
1.7.0.4




--
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

[Index of Archives]     [Linux Media]     [Linux Input]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]     [Old Linux USB Devel Archive]

  Powered by Linux