diff options
author | Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com> | 2021-06-24 15:20:39 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2021-07-28 12:12:19 +0300 |
commit | 6ac12b808a7abe0c29c2cc4103c6663087312f03 (patch) | |
tree | 4a09934f3f503e923174f99142a482b03251b8b8 | |
parent | edddc79c4391f8001095320d3ca423214b9aa4bf (diff) | |
download | linux-6ac12b808a7abe0c29c2cc4103c6663087312f03.tar.xz |
usb: renesas_usbhs: Fix superfluous irqs happen after usb_pkt_pop()
commit 5719df243e118fb343725e8b2afb1637e1af1373 upstream.
This driver has a potential issue which this driver is possible to
cause superfluous irqs after usb_pkt_pop() is called. So, after
the commit 3af32605289e ("usb: renesas_usbhs: fix error return
code of usbhsf_pkt_handler()") had been applied, we could observe
the following error happened when we used g_audio.
renesas_usbhs e6590000.usb: irq_ready run_error 1 : -22
To fix the issue, disable the tx or rx interrupt in usb_pkt_pop().
Fixes: 2743e7f90dc0 ("usb: renesas_usbhs: fix the usb_pkt_pop()")
Cc: <stable@vger.kernel.org> # v4.4+
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Link: https://lore.kernel.org/r/20210624122039.596528-1-yoshihiro.shimoda.uh@renesas.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r-- | drivers/usb/renesas_usbhs/fifo.c | 7 |
1 files changed, 7 insertions, 0 deletions
diff --git a/drivers/usb/renesas_usbhs/fifo.c b/drivers/usb/renesas_usbhs/fifo.c index 3637d5edab74..e22aaed652ac 100644 --- a/drivers/usb/renesas_usbhs/fifo.c +++ b/drivers/usb/renesas_usbhs/fifo.c @@ -112,6 +112,8 @@ static struct dma_chan *usbhsf_dma_chan_get(struct usbhs_fifo *fifo, #define usbhsf_dma_map(p) __usbhsf_dma_map_ctrl(p, 1) #define usbhsf_dma_unmap(p) __usbhsf_dma_map_ctrl(p, 0) static int __usbhsf_dma_map_ctrl(struct usbhs_pkt *pkt, int map); +static void usbhsf_tx_irq_ctrl(struct usbhs_pipe *pipe, int enable); +static void usbhsf_rx_irq_ctrl(struct usbhs_pipe *pipe, int enable); struct usbhs_pkt *usbhs_pkt_pop(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt) { struct usbhs_priv *priv = usbhs_pipe_to_priv(pipe); @@ -135,6 +137,11 @@ struct usbhs_pkt *usbhs_pkt_pop(struct usbhs_pipe *pipe, struct usbhs_pkt *pkt) dmaengine_terminate_all(chan); usbhsf_fifo_clear(pipe, fifo); usbhsf_dma_unmap(pkt); + } else { + if (usbhs_pipe_is_dir_in(pipe)) + usbhsf_rx_irq_ctrl(pipe, 0); + else + usbhsf_tx_irq_ctrl(pipe, 0); } usbhs_pipe_running(pipe, 0); |