提交 6070636c 编写于 作者: M Minas Harutyunyan 提交者: Greg Kroah-Hartman

usb: dwc2: Fix Stalling a Non-Isochronous OUT EP

Stalling a Non-Isochronous OUT Endpoint flow changed according
programming guide.
In dwc2_hsotg_ep_sethalt() function for OUT EP should not be set STALL bit.
Instead should set SGOUTNAK in DCTL register. Set STALL bit should be
set only after GOUTNAKEFF interrupt asserted.
Signed-off-by: NMinas Harutyunyan <hminas@synopsys.com>
Signed-off-by: NFelipe Balbi <felipe.balbi@linux.intel.com>
Signed-off-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
上级 2e708fa3
......@@ -3784,15 +3784,26 @@ static irqreturn_t dwc2_hsotg_irq(int irq, void *pw)
for (idx = 1; idx < hsotg->num_of_eps; idx++) {
hs_ep = hsotg->eps_out[idx];
/* Proceed only unmasked ISOC EPs */
if ((BIT(idx) & ~daintmsk) || !hs_ep->isochronous)
if (BIT(idx) & ~daintmsk)
continue;
epctrl = dwc2_readl(hsotg, DOEPCTL(idx));
if (epctrl & DXEPCTL_EPENA) {
//ISOC Ep's only
if ((epctrl & DXEPCTL_EPENA) && hs_ep->isochronous) {
epctrl |= DXEPCTL_SNAK;
epctrl |= DXEPCTL_EPDIS;
dwc2_writel(hsotg, epctrl, DOEPCTL(idx));
continue;
}
//Non-ISOC EP's
if (hs_ep->halted) {
if (!(epctrl & DXEPCTL_EPENA))
epctrl |= DXEPCTL_EPENA;
epctrl |= DXEPCTL_EPDIS;
epctrl |= DXEPCTL_STALL;
dwc2_writel(hsotg, epctrl, DOEPCTL(idx));
}
}
......@@ -4310,19 +4321,20 @@ static int dwc2_hsotg_ep_sethalt(struct usb_ep *ep, int value, bool now)
epctl = dwc2_readl(hs, epreg);
if (value) {
epctl |= DXEPCTL_STALL;
if (!(dwc2_readl(hs, GINTSTS) & GINTSTS_GOUTNAKEFF))
dwc2_set_bit(hs, DCTL, DCTL_SGOUTNAK);
// STALL bit will be set in GOUTNAKEFF interrupt handler
} else {
epctl &= ~DXEPCTL_STALL;
xfertype = epctl & DXEPCTL_EPTYPE_MASK;
if (xfertype == DXEPCTL_EPTYPE_BULK ||
xfertype == DXEPCTL_EPTYPE_INTERRUPT)
epctl |= DXEPCTL_SETD0PID;
dwc2_writel(hs, epctl, epreg);
}
dwc2_writel(hs, epctl, epreg);
}
hs_ep->halted = value;
return 0;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册