USB: ci13xxx_udc: Convert ATDTW loop into finite one

Currently while queueing requests to HW, waiting in infinite
loop till ATDTW bit set for HW semaphore to be released by HW
to avoid race conditions between HW and SW. This could lead to
watchdog timer expiry if bus infrastructure is stuck. Hence
convert this loop into finite loop of 100msec which is atmost
required for USB HW to release HW semaphore as per HW team.

CRs-Fixed: 368769
Change-Id: Ibb2ab281f22230cf40574554273c3e4faf453b50
Signed-off-by: Vijayavardhan Vennapusa <vvreddy@codeaurora.org>
This commit is contained in:
Vijayavardhan Vennapusa 2012-07-20 13:18:32 +05:30 committed by Stephen Boyd
parent 3b1a1ebb7b
commit 347109c92e

View file

@ -15,6 +15,7 @@
#include <linux/dmapool.h>
#include <linux/err.h>
#include <linux/irqreturn.h>
#include <linux/ratelimit.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/pm_runtime.h>
@ -28,6 +29,8 @@
#include "bits.h"
#include "debug.h"
#define ATDTW_SET_DELAY 100 /* 100msec delay */
/* control endpoint description */
static const struct usb_endpoint_descriptor
ctrl_endpt_out_desc = {
@ -442,6 +445,7 @@ static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
int n = hw_ep_bit(mEp->num, mEp->dir);
int tmp_stat;
u32 next = mReq->dma & TD_ADDR_MASK;
ktime_t start, diff;
mReqPrev = list_entry(mEp->qh.queue.prev,
struct ci13xxx_req, queue);
@ -452,9 +456,20 @@ static int _hardware_enqueue(struct ci13xxx_ep *mEp, struct ci13xxx_req *mReq)
wmb();
if (hw_read(ci, OP_ENDPTPRIME, BIT(n)))
goto done;
start = ktime_get();
do {
hw_write(ci, OP_USBCMD, USBCMD_ATDTW, USBCMD_ATDTW);
tmp_stat = hw_read(ci, OP_ENDPTSTAT, BIT(n));
diff = ktime_sub(ktime_get(), start);
/* poll for max. 100ms */
if (ktime_to_ms(diff) > ATDTW_SET_DELAY) {
if (hw_read(ci, OP_USBCMD, USBCMD_ATDTW))
break;
printk_ratelimited(KERN_ERR
"%s:queue failed ep#%d %s\n",
__func__, mEp->num, mEp->dir ? "IN" : "OUT");
return -EAGAIN;
}
} while (!hw_read(ci, OP_USBCMD, USBCMD_ATDTW));
hw_write(ci, OP_USBCMD, USBCMD_ATDTW, 0);
if (tmp_stat)