diff options
Diffstat (limited to 'drivers')
| -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; |