mirror of
https://github.com/team-infusion-developers/android_kernel_samsung_msm8976.git
synced 2024-09-22 04:15:02 +00:00
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:
parent
3b1a1ebb7b
commit
347109c92e
1 changed files with 15 additions and 0 deletions
|
@ -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)
|
||||
|
|
Loading…
Reference in a new issue