usb: mtu3: fix the failure of qmu stop
This happens when do stress test of uvc stream on/off which will enable/disable endpoints. uvc has four tx requests, and may disable endpoint between queue tx requests as following: enable ep --> start qmu queue tx request0 queue tx request1 queue tx request2 --> resume qmu disable ep --> stop qmu may fail [1] queue tx request3 --> will resume qmu, may cause qmu can't work when enable ep next time [2] [1]: when the tx fifo has some data to transmit, and try to stop qmu (stop ep) meanwhile resume qmu (queue tx request), it may cause stop qmu timeout, then can be fixed by flushing fifo when stop qmu. [2]: it resumes qmu again, shall stop qmu again. Signed-off-by: Chunfeng Yun <chunfeng.yun@mediatek.com> Reported-by: Min Guo <min.guo@mediatek.com> Link: https://lore.kernel.org/r/20230119033322.21426-1-chunfeng.yun@mediatek.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
3e679bde52
commit
5aba179c34
@ -133,10 +133,9 @@ static int mtu3_ep_disable(struct mtu3_ep *mep)
|
||||
{
|
||||
struct mtu3 *mtu = mep->mtu;
|
||||
|
||||
mtu3_qmu_stop(mep);
|
||||
|
||||
/* abort all pending requests */
|
||||
nuke(mep, -ESHUTDOWN);
|
||||
mtu3_qmu_stop(mep);
|
||||
mtu3_deconfig_ep(mtu, mep);
|
||||
mtu3_gpd_ring_free(mep);
|
||||
|
||||
|
@ -128,6 +128,7 @@
|
||||
#define TX_FIFOEMPTY BIT(24)
|
||||
#define TX_SENTSTALL BIT(22)
|
||||
#define TX_SENDSTALL BIT(21)
|
||||
#define TX_FLUSHFIFO BIT(20)
|
||||
#define TX_TXPKTRDY BIT(16)
|
||||
#define TX_TXMAXPKTSZ_MSK GENMASK(10, 0)
|
||||
#define TX_TXMAXPKTSZ(x) ((x) & TX_TXMAXPKTSZ_MSK)
|
||||
|
@ -388,6 +388,9 @@ void mtu3_qmu_stop(struct mtu3_ep *mep)
|
||||
}
|
||||
mtu3_writel(mbase, qcsr, QMU_Q_STOP);
|
||||
|
||||
if (mep->is_in)
|
||||
mtu3_setbits(mbase, MU3D_EP_TXCR0(epnum), TX_FLUSHFIFO);
|
||||
|
||||
ret = readl_poll_timeout_atomic(mbase + qcsr, value,
|
||||
!(value & QMU_Q_ACTIVE), 1, 1000);
|
||||
if (ret) {
|
||||
@ -395,6 +398,10 @@ void mtu3_qmu_stop(struct mtu3_ep *mep)
|
||||
return;
|
||||
}
|
||||
|
||||
/* flush fifo again to make sure the fifo is empty */
|
||||
if (mep->is_in)
|
||||
mtu3_setbits(mbase, MU3D_EP_TXCR0(epnum), TX_FLUSHFIFO);
|
||||
|
||||
dev_dbg(mtu->dev, "%s's qmu stop now!\n", mep->name);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user