diff options
| author | Stephen Warren <swarren@nvidia.com> | 2013-05-24 15:03:17 -0600 | 
|---|---|---|
| committer | Marek Vasut <marex@denx.de> | 2013-06-12 22:22:52 +0200 | 
| commit | d3e07478468a4544e803ff89285e400da6bc7b2d (patch) | |
| tree | 6ae8dc65892324300b5f8d94df6795383a353607 /drivers/usb/host/ehci-hcd.c | |
| parent | 64cfd3f9645bebdadd4c867db5efcf8b7a568f77 (diff) | |
| download | olio-uboot-2014.01-d3e07478468a4544e803ff89285e400da6bc7b2d.tar.xz olio-uboot-2014.01-d3e07478468a4544e803ff89285e400da6bc7b2d.zip | |
usb: ehci: add missing cache managment
Commit 8f62ca6 "usb: ehci: Support interrupt transfers via periodic list"
didn't include any cache management in the new interrupt transfer path.
It also added an extra write to or_asynclistaddr in usb_lowlevel_init(),
without having flushed out the data there.
Add the missing cache management calls, so that the code works again.
This allows the USB keyboard on Tegra's Seaboard/Springbank boards to
work.
Cc: Patrick Georgi <patrick@georgi-clan.de>
Cc: Vincent Palatin <vpalatin@chromium.org>
Cc: Julius Werner <jwerner@chromium.org>
Cc: Simon Glass <sjg@chromium.org>
Cc: Marek Vasut <marex@denx.de>
Signed-off-by: Stephen Warren <swarren@nvidia.com>
Diffstat (limited to 'drivers/usb/host/ehci-hcd.c')
| -rw-r--r-- | drivers/usb/host/ehci-hcd.c | 30 | 
1 files changed, 30 insertions, 0 deletions
| diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c index 28b600790..706cf0cb7 100644 --- a/drivers/usb/host/ehci-hcd.c +++ b/drivers/usb/host/ehci-hcd.c @@ -926,6 +926,9 @@ int usb_lowlevel_init(int index, void **controller)  	qh_list->qh_overlay.qt_token =  			cpu_to_hc32(QT_TOKEN_STATUS(QT_TOKEN_STATUS_HALTED)); +	flush_dcache_range((uint32_t)qh_list, +			   ALIGN_END_ADDR(struct QH, qh_list, 1)); +  	/* Set async. queue head pointer. */  	ehci_writel(&ehcic[index].hcor->or_asynclistaddr, (uint32_t)qh_list); @@ -939,6 +942,9 @@ int usb_lowlevel_init(int index, void **controller)  	periodic->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);  	periodic->qh_overlay.qt_altnext = cpu_to_hc32(QT_NEXT_TERMINATE); +	flush_dcache_range((uint32_t)periodic, +			   ALIGN_END_ADDR(struct QH, periodic, 1)); +  	/*  	 * Step 2: Setup frame-list: Every microframe, USB tries the same list.  	 *         In particular, device specifications on polling frequency @@ -956,6 +962,10 @@ int usb_lowlevel_init(int index, void **controller)  						| QH_LINK_TYPE_QH;  	} +	flush_dcache_range((uint32_t)ehcic[index].periodic_list, +			   ALIGN_END_ADDR(uint32_t, ehcic[index].periodic_list, +					  1024)); +  	/* Set periodic list base address */  	ehci_writel(&ehcic[index].hcor->or_periodiclistbase,  		(uint32_t)ehcic[index].periodic_list); @@ -1170,6 +1180,16 @@ create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize,  		*buf = buffer + i * elementsize;  	} +	flush_dcache_range((uint32_t)buffer, +			   ALIGN_END_ADDR(char, buffer, +					  queuesize * elementsize)); +	flush_dcache_range((uint32_t)result->first, +			   ALIGN_END_ADDR(struct QH, result->first, +					  queuesize)); +	flush_dcache_range((uint32_t)result->tds, +			   ALIGN_END_ADDR(struct qTD, result->tds, +					  queuesize)); +  	if (disable_periodic(ctrl) < 0) {  		debug("FATAL: periodic should never fail, but did");  		goto fail3; @@ -1180,6 +1200,11 @@ create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize,  	result->last->qh_link = list->qh_link;  	list->qh_link = (uint32_t)result->first | QH_LINK_TYPE_QH; +	flush_dcache_range((uint32_t)result->last, +			   ALIGN_END_ADDR(struct QH, result->last, 1)); +	flush_dcache_range((uint32_t)list, +			   ALIGN_END_ADDR(struct QH, list, 1)); +  	if (enable_periodic(ctrl) < 0) {  		debug("FATAL: periodic should never fail, but did");  		goto fail3; @@ -1210,6 +1235,8 @@ void *poll_int_queue(struct usb_device *dev, struct int_queue *queue)  		return NULL;  	}  	/* still active */ +	invalidate_dcache_range((uint32_t)cur, +				ALIGN_END_ADDR(struct QH, cur, 1));  	if (cur->qh_overlay.qt_token & 0x80) {  		debug("Exit poll_int_queue with no completed intr transfer. "  		      "token is %x\n", cur->qh_overlay.qt_token); @@ -1316,6 +1343,9 @@ submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,  		return -EINVAL;  	} +	invalidate_dcache_range((uint32_t)buffer, +				ALIGN_END_ADDR(char, buffer, length)); +  	ret = destroy_int_queue(dev, queue);  	if (ret < 0)  		return ret; |