Skip to content

Commit

Permalink
usb: mtu3: fix the failure of qmu stop
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Chunfeng Yun authored and gregkh committed Jan 19, 2023
1 parent 3e679bd commit 5aba179
Show file tree
Hide file tree
Showing 3 changed files with 9 additions and 2 deletions.
3 changes: 1 addition & 2 deletions drivers/usb/mtu3/mtu3_gadget.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
1 change: 1 addition & 0 deletions drivers/usb/mtu3/mtu3_hw_regs.h
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
7 changes: 7 additions & 0 deletions drivers/usb/mtu3/mtu3_qmu.c
Original file line number Diff line number Diff line change
Expand Up @@ -388,13 +388,20 @@ 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) {
dev_err(mtu->dev, "stop %s's qmu failed\n", mep->name);
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);
}

Expand Down

0 comments on commit 5aba179

Please sign in to comment.