aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/usb/gadget/udc/fotg210-udc.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/usb/gadget/udc/fotg210-udc.c')
-rw-r--r--drivers/usb/gadget/udc/fotg210-udc.c26
1 files changed, 18 insertions, 8 deletions
diff --git a/drivers/usb/gadget/udc/fotg210-udc.c b/drivers/usb/gadget/udc/fotg210-udc.c
index 6866a0be249e..9440973cdb44 100644
--- a/drivers/usb/gadget/udc/fotg210-udc.c
+++ b/drivers/usb/gadget/udc/fotg210-udc.c
@@ -340,15 +340,16 @@ static void fotg210_start_dma(struct fotg210_ep *ep,
} else {
buffer = req->req.buf + req->req.actual;
length = ioread32(ep->fotg210->reg +
- FOTG210_FIBCR(ep->epnum - 1));
- length &= FIBCR_BCFX;
+ FOTG210_FIBCR(ep->epnum - 1)) & FIBCR_BCFX;
+ if (length > req->req.length - req->req.actual)
+ length = req->req.length - req->req.actual;
}
} else {
buffer = req->req.buf + req->req.actual;
if (req->req.length - req->req.actual > ep->ep.maxpacket)
length = ep->ep.maxpacket;
else
- length = req->req.length;
+ length = req->req.length - req->req.actual;
}
d = dma_map_single(NULL, buffer, length,
@@ -385,8 +386,7 @@ static void fotg210_ep0_queue(struct fotg210_ep *ep,
}
if (ep->dir_in) { /* if IN */
fotg210_start_dma(ep, req);
- if ((req->req.length == req->req.actual) ||
- (req->req.actual < ep->ep.maxpacket))
+ if (req->req.length == req->req.actual)
fotg210_done(ep, req, 0);
} else { /* OUT */
u32 value = ioread32(ep->fotg210->reg + FOTG210_DMISGR0);
@@ -827,7 +827,7 @@ static void fotg210_ep0in(struct fotg210_udc *fotg210)
if (req->req.length)
fotg210_start_dma(ep, req);
- if ((req->req.length - req->req.actual) < ep->ep.maxpacket)
+ if (req->req.actual == req->req.length)
fotg210_done(ep, req, 0);
} else {
fotg210_set_cxdone(fotg210);
@@ -856,12 +856,16 @@ static void fotg210_out_fifo_handler(struct fotg210_ep *ep)
{
struct fotg210_request *req = list_entry(ep->queue.next,
struct fotg210_request, queue);
+ int disgr1 = ioread32(ep->fotg210->reg + FOTG210_DISGR1);
fotg210_start_dma(ep, req);
- /* finish out transfer */
+ /* Complete the request when it's full or a short packet arrived.
+ * Like other drivers, short_not_ok isn't handled.
+ */
+
if (req->req.length == req->req.actual ||
- req->req.actual < ep->ep.maxpacket)
+ (disgr1 & DISGR1_SPK_INT(ep->epnum - 1)))
fotg210_done(ep, req, 0);
}
@@ -1034,6 +1038,12 @@ static void fotg210_init(struct fotg210_udc *fotg210)
value &= ~DMCR_GLINT_EN;
iowrite32(value, fotg210->reg + FOTG210_DMCR);
+ /* enable only grp2 irqs we handle */
+ iowrite32(~(DISGR2_DMA_ERROR | DISGR2_RX0BYTE_INT | DISGR2_TX0BYTE_INT
+ | DISGR2_ISO_SEQ_ABORT_INT | DISGR2_ISO_SEQ_ERR_INT
+ | DISGR2_RESM_INT | DISGR2_SUSP_INT | DISGR2_USBRST_INT),
+ fotg210->reg + FOTG210_DMISGR2);
+
/* disable all fifo interrupt */
iowrite32(~(u32)0, fotg210->reg + FOTG210_DMISGR1);