diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2012-11-30 00:24:19 +0100 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2012-12-17 11:27:34 +0100 |
commit | 9239281a5ea4cee997d6423fb5530d17fb95337e (patch) | |
tree | 0607191c0230c1821b87954389bab8ca1b5164f0 /drivers/usb/host/ehci-hcd.c | |
parent | da8b72508b845f11b59386bdf1c2f2147b1319c7 (diff) | |
download | barebox-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.c | 24 |
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); |