stable.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/2] usb: musb: fix bogus rx endpoint interrupt
@ 2016-11-24  4:43 Bin Liu
  2016-11-24  4:43 ` [PATCH 1/2] usb: musb: core: add clear_ep_rxintr() to musb_platform_ops Bin Liu
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Bin Liu @ 2016-11-24  4:43 UTC (permalink / raw)
  To: linux-usb; +Cc: stable

Hi,

This fixes a long standing musb bogus rx interrupt problem. I am not sure on
other platforms, but on AM335x with CPPI DMA enabled, occasionally any of the
following kernel messages shows up from musb driver. (The endpoint number is
random, of cause.)

    musb_host_rx 1853: BOGUS RX2 ready, csr 0000, count 0

    musb_host_rx 1936: RX3 dma busy, csr 2020

In one of the test cases with FT4232H I observed the issue when sometimes
closing the uart port. It turns out the issue is that during handling urb
dequeue, the controller is still receiving data while the CPPI channel is
already aborted, then musb core generates endpoint rx interrupt, instead of
rx dma interrupt in normal rx transfer.

Based on the inline comments, the fix is to call the new platform ops to clear
the rx ep interrupt in musb_cleanup_urb().

I am not sure if this fix should be back ported to all stable trees, but I
only tested up to v4.1, so cc'd stable v4.1+.

Regards,
-Bin.
---

Bin Liu (2):
  usb: musb: core: add clear_ep_rxintr() to musb_platform_ops
  usb: musb: dsps: implement clear_ep_rxintr() callback

 drivers/usb/musb/musb_core.h |  7 +++++++
 drivers/usb/musb/musb_dsps.c | 12 ++++++++++++
 drivers/usb/musb/musb_host.c | 10 ++++------
 3 files changed, 23 insertions(+), 6 deletions(-)

-- 
1.9.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH 1/2] usb: musb: core: add clear_ep_rxintr() to musb_platform_ops
  2016-11-24  4:43 [PATCH 0/2] usb: musb: fix bogus rx endpoint interrupt Bin Liu
@ 2016-11-24  4:43 ` Bin Liu
  2016-11-24  4:43 ` [PATCH 2/2] usb: musb: dsps: implement clear_ep_rxintr() callback Bin Liu
  2016-11-24  4:54 ` [PATCH 0/2] usb: musb: fix bogus rx endpoint interrupt Bin Liu
  2 siblings, 0 replies; 4+ messages in thread
From: Bin Liu @ 2016-11-24  4:43 UTC (permalink / raw)
  To: linux-usb; +Cc: stable

During dma teardown for dequque urb, musb might generate bogus rx ep
interrupt even when the rx fifo is flushed. As mentioned in the current
inline comment, clearing ep interrupt in the teardown path avoids the
bogus interrupt.

Before this change, any of the follow log messages could happen when
musb load is high.

	musb_host_rx 1853: BOGUS RX2 ready, csr 0000, count 0

	musb_host_rx 1936: RX3 dma busy, csr 2020

cc: stable@vger.kernel.org # 4.1+
Signed-off-by: Bin Liu <b-liu@ti.com>
---
 drivers/usb/musb/musb_core.h |  7 +++++++
 drivers/usb/musb/musb_host.c | 10 ++++------
 2 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index ed5e354b0891..deb64fe896b2 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -216,6 +216,7 @@ struct musb_platform_ops {
 	void	(*pre_root_reset_end)(struct musb *musb);
 	void	(*post_root_reset_end)(struct musb *musb);
 	int	(*phy_callback)(enum musb_vbus_id_status status);
+	void	(*clear_ep_rxintr)(struct musb *musb, int epnum);
 };
 
 /*
@@ -619,6 +620,12 @@ static inline void musb_platform_post_root_reset_end(struct musb *musb)
 		musb->ops->post_root_reset_end(musb);
 }
 
+static inline void musb_platform_clear_ep_rxintr(struct musb *musb, int epnum)
+{
+	if (musb->ops->clear_ep_rxintr)
+		musb->ops->clear_ep_rxintr(musb, epnum);
+}
+
 /*
  * gets the "dr_mode" property from DT and converts it into musb_mode
  * if the property is not found or not recognized returns MUSB_OTG
diff --git a/drivers/usb/musb/musb_host.c b/drivers/usb/musb/musb_host.c
index 30d394b3f2f6..613009abd766 100644
--- a/drivers/usb/musb/musb_host.c
+++ b/drivers/usb/musb/musb_host.c
@@ -2374,12 +2374,11 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh)
 	int			is_in = usb_pipein(urb->pipe);
 	int			status = 0;
 	u16			csr;
+	struct dma_channel	*dma = NULL;
 
 	musb_ep_select(regs, hw_end);
 
 	if (is_dma_capable()) {
-		struct dma_channel	*dma;
-
 		dma = is_in ? ep->rx_channel : ep->tx_channel;
 		if (dma) {
 			status = ep->musb->dma_controller->channel_abort(dma);
@@ -2395,10 +2394,9 @@ static int musb_cleanup_urb(struct urb *urb, struct musb_qh *qh)
 		/* giveback saves bulk toggle */
 		csr = musb_h_flush_rxfifo(ep, 0);
 
-		/* REVISIT we still get an irq; should likely clear the
-		 * endpoint's irq status here to avoid bogus irqs.
-		 * clearing that status is platform-specific...
-		 */
+		/* clear the endpoint's irq status here to avoid bogus irqs */
+		if (is_dma_capable() && dma)
+			musb_platform_clear_ep_rxintr(musb, ep->epnum);
 	} else if (ep->epnum) {
 		csr = musb_readw(epio, MUSB_TXCSR);
 		if (csr & MUSB_TXCSR_FIFONOTEMPTY) {
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH 2/2] usb: musb: dsps: implement clear_ep_rxintr() callback
  2016-11-24  4:43 [PATCH 0/2] usb: musb: fix bogus rx endpoint interrupt Bin Liu
  2016-11-24  4:43 ` [PATCH 1/2] usb: musb: core: add clear_ep_rxintr() to musb_platform_ops Bin Liu
@ 2016-11-24  4:43 ` Bin Liu
  2016-11-24  4:54 ` [PATCH 0/2] usb: musb: fix bogus rx endpoint interrupt Bin Liu
  2 siblings, 0 replies; 4+ messages in thread
From: Bin Liu @ 2016-11-24  4:43 UTC (permalink / raw)
  To: linux-usb; +Cc: stable

This is for avoiding rx ep bogus interrupt during CPPI channel teardown.

cc: stable@vger.kernel.org # 4.1+
Signed-off-by: Bin Liu <b-liu@ti.com>
---
 drivers/usb/musb/musb_dsps.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/drivers/usb/musb/musb_dsps.c b/drivers/usb/musb/musb_dsps.c
index 0f17d2140db6..092e255e6f77 100644
--- a/drivers/usb/musb/musb_dsps.c
+++ b/drivers/usb/musb/musb_dsps.c
@@ -251,6 +251,17 @@ static void otg_timer(unsigned long _musb)
 	pm_runtime_put_autosuspend(dev);
 }
 
+void dsps_musb_clear_ep_rxintr(struct musb *musb, int epnum)
+{
+	u32 epintr;
+	struct dsps_glue *glue = dev_get_drvdata(musb->controller->parent);
+	const struct dsps_musb_wrapper *wrp = glue->wrp;
+
+	/* musb->lock might already been held */
+	epintr = (1 << epnum) << wrp->rxep_shift;
+	musb_writel(musb->ctrl_base, wrp->epintr_status, epintr);
+}
+
 static irqreturn_t dsps_interrupt(int irq, void *hci)
 {
 	struct musb  *musb = hci;
@@ -606,6 +617,7 @@ static void dsps_read_fifo32(struct musb_hw_ep *hw_ep, u16 len, u8 *dst)
 
 	.set_mode	= dsps_musb_set_mode,
 	.recover	= dsps_musb_recover,
+	.clear_ep_rxintr = dsps_musb_clear_ep_rxintr,
 };
 
 static u64 musb_dmamask = DMA_BIT_MASK(32);
-- 
1.9.1


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 0/2] usb: musb: fix bogus rx endpoint interrupt
  2016-11-24  4:43 [PATCH 0/2] usb: musb: fix bogus rx endpoint interrupt Bin Liu
  2016-11-24  4:43 ` [PATCH 1/2] usb: musb: core: add clear_ep_rxintr() to musb_platform_ops Bin Liu
  2016-11-24  4:43 ` [PATCH 2/2] usb: musb: dsps: implement clear_ep_rxintr() callback Bin Liu
@ 2016-11-24  4:54 ` Bin Liu
  2 siblings, 0 replies; 4+ messages in thread
From: Bin Liu @ 2016-11-24  4:54 UTC (permalink / raw)
  To: linux-usb; +Cc: stable

On Wed, Nov 23, 2016 at 10:43:32PM -0600, Bin Liu wrote:
> Hi,
> 
> This fixes a long standing musb bogus rx interrupt problem. I am not sure on
> other platforms, but on AM335x with CPPI DMA enabled, occasionally any of the
> following kernel messages shows up from musb driver. (The endpoint number is
> random, of cause.)
> 
>     musb_host_rx 1853: BOGUS RX2 ready, csr 0000, count 0
> 
>     musb_host_rx 1936: RX3 dma busy, csr 2020
> 
> In one of the test cases with FT4232H I observed the issue when sometimes
> closing the uart port. It turns out the issue is that during handling urb
> dequeue, the controller is still receiving data while the CPPI channel is
> already aborted, then musb core generates endpoint rx interrupt, instead of
> rx dma interrupt in normal rx transfer.
rx dma interrupt _as_ in normal rx transfer.

> 
> Based on the inline comments, the fix is to call the new platform ops to clear
> the rx ep interrupt in musb_cleanup_urb().
> 
> I am not sure if this fix should be back ported to all stable trees, but I
> only tested up to v4.1, so cc'd stable v4.1+.
> 
> Regards,
> -Bin.
> ---
> 
> Bin Liu (2):
>   usb: musb: core: add clear_ep_rxintr() to musb_platform_ops
>   usb: musb: dsps: implement clear_ep_rxintr() callback
> 
>  drivers/usb/musb/musb_core.h |  7 +++++++
>  drivers/usb/musb/musb_dsps.c | 12 ++++++++++++
>  drivers/usb/musb/musb_host.c | 10 ++++------
>  3 files changed, 23 insertions(+), 6 deletions(-)
> 
> -- 
> 1.9.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-usb" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2016-11-24  4:54 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-11-24  4:43 [PATCH 0/2] usb: musb: fix bogus rx endpoint interrupt Bin Liu
2016-11-24  4:43 ` [PATCH 1/2] usb: musb: core: add clear_ep_rxintr() to musb_platform_ops Bin Liu
2016-11-24  4:43 ` [PATCH 2/2] usb: musb: dsps: implement clear_ep_rxintr() callback Bin Liu
2016-11-24  4:54 ` [PATCH 0/2] usb: musb: fix bogus rx endpoint interrupt Bin Liu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).