summaryrefslogtreecommitdiffstats
path: root/drivers/usb/host/ehci-hcd.c
diff options
context:
space:
mode:
authorSascha Hauer <s.hauer@pengutronix.de>2012-11-30 00:24:19 +0100
committerSascha Hauer <s.hauer@pengutronix.de>2012-12-17 11:27:34 +0100
commit9239281a5ea4cee997d6423fb5530d17fb95337e (patch)
tree0607191c0230c1821b87954389bab8ca1b5164f0 /drivers/usb/host/ehci-hcd.c
parentda8b72508b845f11b59386bdf1c2f2147b1319c7 (diff)
downloadbarebox-9239281a5ea4cee997d6423fb5530d17fb95337e.tar.gz
barebox-9239281a5ea4cee997d6423fb5530d17fb95337e.tar.xz
USB ehci: Add powerup fixup for EfikaSB
The EfikaSB has a bug requiring to write to an ULPI register after powerup. It doesn't seem that this this bug is present on any other hardware, so add a workaround directly into the driver. Signed-off-by: Sascha Hauer <s.hauer@pengutronix.de>
Diffstat (limited to 'drivers/usb/host/ehci-hcd.c')
-rw-r--r--drivers/usb/host/ehci-hcd.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index d6083e08ce..ad8cf2f450 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -34,6 +34,7 @@
struct ehci_priv {
int rootdev;
+ struct device_d *dev;
struct ehci_hccr *hccr;
struct ehci_hcor *hcor;
struct usb_host host;
@@ -425,6 +426,27 @@ static inline int min3(int a, int b, int c)
return a;
}
+#ifdef CONFIG_MACH_EFIKA_MX_SMARTBOOK
+#include <usb/ulpi.h>
+/*
+ * Add support for setting CHRGVBUS to workaround a hardware bug on efika mx/sb
+ * boards.
+ * See http://lists.infradead.org/pipermail/linux-arm-kernel/2011-January/037341.html
+ */
+void ehci_powerup_fixup(struct ehci_priv *ehci)
+{
+ void *viewport = (void *)ehci->hcor + 0x30;
+
+ if (ehci->dev->id > 0)
+ ulpi_write(ULPI_OTG_CHRG_VBUS, ULPI_OTGCTL + ULPI_REG_SET,
+ viewport);
+}
+#else
+static inline void ehci_powerup_fixup(struct ehci_priv *ehci)
+{
+}
+#endif
+
static int
ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
int length, struct devrequest *req)
@@ -610,6 +632,7 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
* usb 2.0 specification say 50 ms resets on
* root
*/
+ ehci_powerup_fixup(ehci);
wait_ms(50);
ehci->portreset |= 1 << le16_to_cpu(req->index);
/* terminate the reset */
@@ -819,6 +842,7 @@ int ehci_register(struct device_d *dev, struct ehci_data *data)
ehci->flags = data->flags;
ehci->hccr = data->hccr;
ehci->hcor = data->hcor;
+ ehci->dev = dev;
ehci->qh_list = dma_alloc_coherent(sizeof(struct QH) * NUM_TD);
ehci->td = dma_alloc_coherent(sizeof(struct qTD) * NUM_TD);