usb: ehci: Fix accessors for big-endian platforms and descriptors
authorAlexey Brodkin <Alexey.Brodkin@synopsys.com>
Fri, 17 Nov 2017 13:26:30 +0000 (16:26 +0300)
committerMarek Vasut <marek.vasut+renesas@gmail.com>
Sun, 26 Nov 2017 01:22:36 +0000 (02:22 +0100)
Commit 9000eddbae0d ("drivers/usb/ehci: Use platform-specific accessors")
broke USB 2.0 on big-endian platforms because for them writel/readl()
does automatic conversion of BE data to LE.

Proper implementation requires to use "raw" variant of these accessors
which read/write data without messing with endianess.

While at it replace cpu_to_be32() to be32_to_cpu() in readl() to
keep sane semantics.

Signed-off-by: Alexey Brodkin <abrodkin@synopsys.com>
Cc: Marek Vasut <marex@denx.de>
Reported-by: Vladimir Boroda <boroda@yahoo.com>
drivers/usb/host/ehci.h

index 7c39becd247e03caab60ba0a787f6024a4f28434..18692b732ea65a162ca3390aeb9a0b03e8e578ca 100644 (file)
@@ -101,11 +101,11 @@ struct usb_linux_config_descriptor {
 } __attribute__ ((packed));
 
 #if defined CONFIG_EHCI_DESC_BIG_ENDIAN
-#define ehci_readl(x)          cpu_to_be32(readl(x))
-#define ehci_writel(a, b)      writel(cpu_to_be32(b), a)
+#define ehci_readl(x)          be32_to_cpu(__raw_readl(x))
+#define ehci_writel(a, b)      __raw_writel(cpu_to_be32(b), a)
 #else
-#define ehci_readl(x)          cpu_to_le32(readl(x))
-#define ehci_writel(a, b)      writel(cpu_to_le32(b), a)
+#define ehci_readl(x)          readl(x)
+#define ehci_writel(a, b)      writel(b, a)
 #endif
 
 #if defined CONFIG_EHCI_MMIO_BIG_ENDIAN