Skip to content

Commit 30500d9

Browse files
committed
Merge pull request #330 from P33M/rpi-3.6.y
dwc_otg: more robust interrupt handling
2 parents 914396f + c46c85b commit 30500d9

File tree

1 file changed

+42
-0
lines changed

1 file changed

+42
-0
lines changed

drivers/usb/host/dwc_otg/dwc_otg_hcd_intr.c

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -324,6 +324,27 @@ int fiq_hcintr_handle(int channel, hfnum_data_t hfnum)
324324
}
325325
}
326326
}
327+
else
328+
{
329+
/*
330+
* If we have any of NAK, ACK, Datatlgerr active on a
331+
* non-split channel, the sole reason is to reset error
332+
* counts for a previously broken transaction. The FIQ
333+
* will thrash on NAK IN and ACK OUT in particular so
334+
* handle it "once" and allow the IRQ to do the rest.
335+
*/
336+
hcint.d32 &= hcintmsk.d32;
337+
if(hcint.b.nak)
338+
{
339+
hcintmsk.b.nak = 0;
340+
FIQ_WRITE((dwc_regs_base + 0x500 + (channel * 0x20) + 0xc), hcintmsk.d32);
341+
}
342+
if (hcint.b.ack)
343+
{
344+
hcintmsk.b.ack = 0;
345+
FIQ_WRITE((dwc_regs_base + 0x500 + (channel * 0x20) + 0xc), hcintmsk.d32);
346+
}
347+
}
327348

328349
// Clear the interrupt, this will also clear the HAINT bit
329350
FIQ_WRITE((dwc_regs_base + 0x500 + (channel * 0x20) + 0x8), hcint.d32);
@@ -1851,7 +1872,11 @@ static int32_t handle_hc_nak_intr(dwc_otg_hcd_t * hcd,
18511872
* transfers in DMA mode for the sole purpose of
18521873
* resetting the error count after a transaction error
18531874
* occurs. The core will continue transferring data.
1875+
* Disable other interrupts unmasked for the same
1876+
* reason.
18541877
*/
1878+
disable_hc_int(hc_regs, datatglerr);
1879+
disable_hc_int(hc_regs, ack);
18551880
qtd->error_count = 0;
18561881
goto handle_nak_done;
18571882
}
@@ -1963,6 +1988,15 @@ static int32_t handle_hc_ack_intr(dwc_otg_hcd_t * hcd,
19631988
halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_ACK);
19641989
}
19651990
} else {
1991+
/*
1992+
* An unmasked ACK on a non-split DMA transaction is
1993+
* for the sole purpose of resetting error counts. Disable other
1994+
* interrupts unmasked for the same reason.
1995+
*/
1996+
if(hcd->core_if->dma_enable) {
1997+
disable_hc_int(hc_regs, datatglerr);
1998+
disable_hc_int(hc_regs, nak);
1999+
}
19662000
qtd->error_count = 0;
19672001

19682002
if (hc->qh->ping_state) {
@@ -2328,6 +2362,14 @@ static int32_t handle_hc_datatglerr_intr(dwc_otg_hcd_t * hcd,
23282362
qtd->urb, qtd, DWC_OTG_HC_XFER_XACT_ERR);
23292363
halt_channel(hcd, hc, qtd, DWC_OTG_HC_XFER_XACT_ERR);
23302364
} else if (hc->ep_is_in) {
2365+
/* An unmasked data toggle error on a non-split DMA transaction is
2366+
* for the sole purpose of resetting error counts. Disable other
2367+
* interrupts unmasked for the same reason.
2368+
*/
2369+
if(hcd->core_if->dma_enable) {
2370+
disable_hc_int(hc_regs, ack);
2371+
disable_hc_int(hc_regs, nak);
2372+
}
23312373
qtd->error_count = 0;
23322374
}
23332375

0 commit comments

Comments
 (0)