Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1638661 > unrolled thread

[PATCH v2 00/10] usb: musb: tusb6010_omap: Convert to DMAengine

Started byPeter Ujfalusi <peter.ujfalusi@ti.com>
First post2017-05-10 10:50 +0200
Last post2017-05-10 18:40 +0200
Articles 11 — 2 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH v2 00/10] usb: musb: tusb6010_omap: Convert to DMAengine Peter Ujfalusi <peter.ujfalusi@ti.com> - 2017-05-10 10:50 +0200
    [PATCH v2 02/10] usb: musb: Add quirk to avoid skb reserve in gadget mode Peter Ujfalusi <peter.ujfalusi@ti.com> - 2017-05-10 10:50 +0200
    [PATCH v2 06/10] usb: musb: tusb6010_omap: Create new struct for DMA data/parameters Peter Ujfalusi <peter.ujfalusi@ti.com> - 2017-05-10 10:50 +0200
    [PATCH v2 07/10] usb: musb: tusb6010_omap: Allocate DMA channels upfront Peter Ujfalusi <peter.ujfalusi@ti.com> - 2017-05-10 10:50 +0200
    [PATCH v2 04/10] usb: musb: tusb6010_omap: Use one musb_ep_select call in tusb_omap_dma_program Peter Ujfalusi <peter.ujfalusi@ti.com> - 2017-05-10 10:50 +0200
    [PATCH v2 08/10] usb: musb: tusb6010: Handle DMA TX completion in DMA callback as well Peter Ujfalusi <peter.ujfalusi@ti.com> - 2017-05-10 10:50 +0200
    [PATCH v2 09/10] ARM: OMAP2+: DMA: Add slave map entries for 24xx external request lines Peter Ujfalusi <peter.ujfalusi@ti.com> - 2017-05-10 10:50 +0200
      Re: [PATCH v2 09/10] ARM: OMAP2+: DMA: Add slave map entries for  24xx external request lines Tony Lindgren <tony@atomide.com> - 2017-05-10 18:40 +0200
    [PATCH v2 03/10] usb: musb: tusb6010: Add MUSB_G_NO_SKB_RESERVE to quirks Peter Ujfalusi <peter.ujfalusi@ti.com> - 2017-05-10 10:50 +0200
    [PATCH v2 10/10] usb: musb: tusb6010_omap: Convert to DMAengine API Peter Ujfalusi <peter.ujfalusi@ti.com> - 2017-05-10 11:00 +0200
    Re: [PATCH v2 00/10] usb: musb: tusb6010_omap: Convert to DMAengine Tony Lindgren <tony@atomide.com> - 2017-05-10 18:40 +0200

#1638661 — [PATCH v2 00/10] usb: musb: tusb6010_omap: Convert to DMAengine

FromPeter Ujfalusi <peter.ujfalusi@ti.com>
Date2017-05-10 10:50 +0200
Subject[PATCH v2 00/10] usb: musb: tusb6010_omap: Convert to DMAengine
Message-ID<tFvtL-6TH-5@gated-at.bofh.it>
Hi,

Changes since v1:
- Fix the port_window support in omap-dma DMAengine driver
- MUSB_G_NO_SKB_RESERVE quirk flag addition to msub core
- packet size corruption fix for tusb6010
- Handle DMA completion for TX also in the DMA callback

The v1 series was tested with g_cdc where only the DMA was only enabled for TX
and because of that I have not noticed that the sDMA code was not correct for RX,
it only worked for TX case.

The ASYNC mode of tusb6010 is really unstable, we get corrupted TX/RX offset
register quite easily, but the SYNC mode is stable.

The series was tested on top of next-20170510 with g_ncm module since with this
we can use the quirk to avoid skb_reserve and get properly aligned buffers for
DMA.
The n810 is using nfsroot.

The device would not boot to prompt most of the time before patch 5 (packet size
reset fix).
With that patch in, the device would boot up fine most of the cases, but will
fail pretty fast with my stress test [1].
After the first 9 patch the legacy DMA mode is going to be stable with g_ncm, it
boots to prompt, and survives the stress test [1].

The last patch is going the DMAengine conversion and I have run the stress test
against it over 3 hours (ping-test.sh wrap count is 139).

[1] Running these in parallel:
ping -f 192.168.0.2
ping -f -s 2048 192.168.0.2
ping-test.sh 192.168.0.2 1

and (nfsroot) time to time:
scp root@192.168.0.1:/usr/portage/distfiles/thunderbird-52.1.0.source.tar.xz /

$ ls -alh /usr/portage/distfiles/thunderbird-52.1.0.source.tar.xz 
218M Apr 30 15:46 /usr/portage/distfiles/thunderbird-52.1.0.source.tar.xz

In essence copy 218M from my host back to the host.

ping-test.sh (modified version from Tony to show the wrap count):
#!/bin/bash

device=$1
size=$2
wraps=0

while [ 1 ]; do
        #echo "Pinging with size $size"
        if ! ping -w0 -c1 -s$size $device > /dev/null 2>&1; then
                break;
        fi
        size=$(expr $size + 1)

        if [ $size -gt 8192 ]; then
	        wraps=$(expr $wraps + 1)
		echo "wrapping ($wraps) at $size"
                size=1
        fi
done
echo "Test ran up to $size"

Regards,
Peter

CC: dmaengine@vger.kernel.org
I only send the cover letter and the DMAengine patch for the dmaengine list, the
rest can be checked - if there is interest - via lkml
---
Peter Ujfalusi (10):
  dmaengine: omap-dma: port_window support correction for both direction
  usb: musb: Add quirk to avoid skb reserve in gadget mode
  usb: musb: tusb6010: Add MUSB_G_NO_SKB_RESERVE to quirks
  usb: musb: tusb6010_omap: Use one musb_ep_select call in
    tusb_omap_dma_program
  usb: musb: tusb6010_omap: Do not reset the other direction's packet
    size
  usb: musb: tusb6010_omap: Create new struct for DMA data/parameters
  usb: musb: tusb6010_omap: Allocate DMA channels upfront
  usb: musb: tusb6010: Handle DMA TX completion in DMA callback as well
  ARM: OMAP2+: DMA: Add slave map entries for 24xx external request
    lines
  usb: musb: tusb6010_omap: Convert to DMAengine API

 arch/arm/mach-omap2/dma.c        |  24 +++
 drivers/dma/omap-dma.c           |  39 ++--
 drivers/usb/musb/musb_core.c     |   3 +
 drivers/usb/musb/musb_core.h     |   1 +
 drivers/usb/musb/tusb6010.c      |  21 +--
 drivers/usb/musb/tusb6010_omap.c | 391 ++++++++++++++++-----------------------
 6 files changed, 211 insertions(+), 268 deletions(-)

-- 
2.12.2

[toc] | [next] | [standalone]


#1638662 — [PATCH v2 02/10] usb: musb: Add quirk to avoid skb reserve in gadget mode

FromPeter Ujfalusi <peter.ujfalusi@ti.com>
Date2017-05-10 10:50 +0200
Subject[PATCH v2 02/10] usb: musb: Add quirk to avoid skb reserve in gadget mode
Message-ID<tFvtM-6TH-25@gated-at.bofh.it>
In reply to#1638661
For tusb6010 the DMA functionality only possible if the buffer is 32bit
aligned (SYNC access to FIFO) since with ASYNC access the TX/RX offset
registers will corrupt eventually.
The MUSB_G_NO_SKB_RESERVE will set the quirk_avoids_skb_reserve flag in
usb_gadget struct to provide correctly aligned buffer.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 drivers/usb/musb/musb_core.c | 3 +++
 drivers/usb/musb/musb_core.h | 1 +
 2 files changed, 4 insertions(+)

diff --git a/drivers/usb/musb/musb_core.c b/drivers/usb/musb/musb_core.c
index 870da18f5077..87cbd56cc761 100644
--- a/drivers/usb/musb/musb_core.c
+++ b/drivers/usb/musb/musb_core.c
@@ -2224,6 +2224,9 @@ musb_init_controller(struct device *dev, int nIrq, void __iomem *ctrl)
 		musb->io.ep_select = musb_flat_ep_select;
 	}
 
+	if (musb->io.quirks & MUSB_G_NO_SKB_RESERVE)
+		musb->g.quirk_avoids_skb_reserve = 1;
+
 	/* At least tusb6010 has its own offsets */
 	if (musb->ops->ep_offset)
 		musb->io.ep_offset = musb->ops->ep_offset;
diff --git a/drivers/usb/musb/musb_core.h b/drivers/usb/musb/musb_core.h
index 3e98d4268a64..9f22c5b8ce37 100644
--- a/drivers/usb/musb/musb_core.h
+++ b/drivers/usb/musb/musb_core.h
@@ -172,6 +172,7 @@ struct musb_io;
  */
 struct musb_platform_ops {
 
+#define MUSB_G_NO_SKB_RESERVE	BIT(9)
 #define MUSB_DA8XX		BIT(8)
 #define MUSB_PRESERVE_SESSION	BIT(7)
 #define MUSB_DMA_UX500		BIT(6)
-- 
2.12.2

[toc] | [prev] | [next] | [standalone]


#1638664 — [PATCH v2 06/10] usb: musb: tusb6010_omap: Create new struct for DMA data/parameters

FromPeter Ujfalusi <peter.ujfalusi@ti.com>
Date2017-05-10 10:50 +0200
Subject[PATCH v2 06/10] usb: musb: tusb6010_omap: Create new struct for DMA data/parameters
Message-ID<tFvtM-6TH-15@gated-at.bofh.it>
In reply to#1638661
For the DMA we have ch (channel), dmareq and sync_dev parameters both
within the tusb_omap_dma_ch and tusb_omap_dma_ch struct.
By creating a common struct the code can be simplified when selecting
between the shared or multichannel DMA parameters.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 drivers/usb/musb/tusb6010_omap.c | 163 ++++++++++++++++++++-------------------
 1 file changed, 84 insertions(+), 79 deletions(-)

diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c
index 4e1a6e4a61b8..f1e58e15e5bb 100644
--- a/drivers/usb/musb/tusb6010_omap.c
+++ b/drivers/usb/musb/tusb6010_omap.c
@@ -31,6 +31,12 @@
 #define OMAP242X_DMA_EXT_DMAREQ4	16
 #define OMAP242X_DMA_EXT_DMAREQ5	64
 
+struct tusb_dma_data {
+	int			ch;
+	s8			dmareq;
+	s8			sync_dev;
+};
+
 struct tusb_omap_dma_ch {
 	struct musb		*musb;
 	void __iomem		*tbase;
@@ -39,9 +45,7 @@ struct tusb_omap_dma_ch {
 	u8			tx;
 	struct musb_hw_ep	*hw_ep;
 
-	int			ch;
-	s8			dmareq;
-	s8			sync_dev;
+	struct tusb_dma_data	dma_data;
 
 	struct tusb_omap_dma	*tusb_dma;
 
@@ -58,9 +62,7 @@ struct tusb_omap_dma {
 	struct dma_controller		controller;
 	void __iomem			*tbase;
 
-	int				ch;
-	s8				dmareq;
-	s8				sync_dev;
+	struct tusb_dma_data		dma_data;
 	unsigned			multichannel:1;
 };
 
@@ -119,9 +121,9 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data)
 	spin_lock_irqsave(&musb->lock, flags);
 
 	if (tusb_dma->multichannel)
-		ch = chdat->ch;
+		ch = chdat->dma_data.ch;
 	else
-		ch = tusb_dma->ch;
+		ch = tusb_dma->dma_data.ch;
 
 	if (ch_status != OMAP_DMA_BLOCK_IRQ)
 		printk(KERN_ERR "TUSB DMA error status: %i\n", ch_status);
@@ -140,8 +142,7 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data)
 	/* HW issue #10: XFR_SIZE may get corrupt on DMA (both async & sync) */
 	if (unlikely(remaining > chdat->transfer_len)) {
 		dev_dbg(musb->controller, "Corrupt %s dma ch%i XFR_SIZE: 0x%08lx\n",
-			chdat->tx ? "tx" : "rx", chdat->ch,
-			remaining);
+			chdat->tx ? "tx" : "rx", ch, remaining);
 		remaining = 0;
 	}
 
@@ -219,9 +220,7 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
 	u32				dma_remaining;
 	int				src_burst, dst_burst;
 	u16				csr;
-	int				ch;
-	s8				dmareq;
-	s8				sync_dev;
+	struct tusb_dma_data		*dma_data;
 
 	if (unlikely(dma_addr & 0x1) || (len < 32) || (len > packet_sz))
 		return false;
@@ -248,7 +247,7 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
 	dma_remaining = TUSB_EP_CONFIG_XFR_SIZE(dma_remaining);
 	if (dma_remaining) {
 		dev_dbg(musb->controller, "Busy %s dma ch%i, not using: %08x\n",
-			chdat->tx ? "tx" : "rx", chdat->ch,
+			chdat->tx ? "tx" : "rx", chdat->dma_data.ch,
 			dma_remaining);
 		return false;
 	}
@@ -261,15 +260,15 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
 		chdat->transfer_packet_sz = packet_sz;
 
 	if (tusb_dma->multichannel) {
-		ch = chdat->ch;
-		dmareq = chdat->dmareq;
-		sync_dev = chdat->sync_dev;
+		dma_data = &chdat->dma_data;
 	} else {
+		dma_data = &tusb_dma->dma_data;
+
 		if (tusb_omap_use_shared_dmareq(chdat) != 0) {
 			dev_dbg(musb->controller, "could not get dma for ep%i\n", chdat->epnum);
 			return false;
 		}
-		if (tusb_dma->ch < 0) {
+		if (dma_data->ch < 0) {
 			/* REVISIT: This should get blocked earlier, happens
 			 * with MSC ErrorRecoveryTest
 			 */
@@ -277,10 +276,7 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
 			return false;
 		}
 
-		ch = tusb_dma->ch;
-		dmareq = tusb_dma->dmareq;
-		sync_dev = tusb_dma->sync_dev;
-		omap_set_dma_callback(ch, tusb_omap_dma_cb, channel);
+		omap_set_dma_callback(dma_data->ch, tusb_omap_dma_cb, channel);
 	}
 
 	chdat->packet_sz = packet_sz;
@@ -311,7 +307,7 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
 
 	dev_dbg(musb->controller, "ep%i %s dma ch%i dma: %pad len: %u(%u) packet_sz: %i(%i)\n",
 		chdat->epnum, chdat->tx ? "tx" : "rx",
-		ch, &dma_addr, chdat->transfer_len, len,
+		dma_data->ch, &dma_addr, chdat->transfer_len, len,
 		chdat->transfer_packet_sz, packet_sz);
 
 	/*
@@ -328,7 +324,7 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
 		dma_params.dst_ei	= 1;
 		dma_params.dst_fi	= -31;	/* Loop 32 byte window */
 
-		dma_params.trigger	= sync_dev;
+		dma_params.trigger	= dma_data->sync_dev;
 		dma_params.sync_mode	= OMAP_DMA_SYNC_FRAME;
 		dma_params.src_or_dst_synch	= 0;	/* Dest sync */
 
@@ -345,7 +341,7 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
 		dma_params.dst_ei	= 0;
 		dma_params.dst_fi	= 0;
 
-		dma_params.trigger	= sync_dev;
+		dma_params.trigger	= dma_data->sync_dev;
 		dma_params.sync_mode	= OMAP_DMA_SYNC_FRAME;
 		dma_params.src_or_dst_synch	= 1;	/* Source sync */
 
@@ -359,10 +355,10 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
 		((dma_addr & 0x3) == 0) ? "sync" : "async",
 		dma_params.src_start, dma_params.dst_start);
 
-	omap_set_dma_params(ch, &dma_params);
-	omap_set_dma_src_burst_mode(ch, src_burst);
-	omap_set_dma_dest_burst_mode(ch, dst_burst);
-	omap_set_dma_write_mode(ch, OMAP_DMA_WRITE_LAST_NON_POSTED);
+	omap_set_dma_params(dma_data->ch, &dma_params);
+	omap_set_dma_src_burst_mode(dma_data->ch, src_burst);
+	omap_set_dma_dest_burst_mode(dma_data->ch, dst_burst);
+	omap_set_dma_write_mode(dma_data->ch, OMAP_DMA_WRITE_LAST_NON_POSTED);
 
 	/*
 	 * Prepare MUSB for DMA transfer
@@ -385,7 +381,7 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
 	/*
 	 * Start DMA transfer
 	 */
-	omap_start_dma(ch);
+	omap_start_dma(dma_data->ch);
 
 	if (chdat->tx) {
 		/* Send transfer_packet_sz packets at a time */
@@ -414,16 +410,17 @@ static int tusb_omap_dma_abort(struct dma_channel *channel)
 {
 	struct tusb_omap_dma_ch	*chdat = to_chdat(channel);
 	struct tusb_omap_dma	*tusb_dma = chdat->tusb_dma;
+	struct tusb_dma_data	*dma_data = &tusb_dma->dma_data;
 
 	if (!tusb_dma->multichannel) {
-		if (tusb_dma->ch >= 0) {
-			omap_stop_dma(tusb_dma->ch);
-			omap_free_dma(tusb_dma->ch);
-			tusb_dma->ch = -1;
+		if (dma_data->ch >= 0) {
+			omap_stop_dma(dma_data->ch);
+			omap_free_dma(dma_data->ch);
+			dma_data->ch = -1;
 		}
 
-		tusb_dma->dmareq = -1;
-		tusb_dma->sync_dev = -1;
+		dma_data->dmareq = -1;
+		dma_data->sync_dev = -1;
 	}
 
 	channel->status = MUSB_DMA_STATUS_FREE;
@@ -461,8 +458,8 @@ static inline int tusb_omap_dma_allocate_dmareq(struct tusb_omap_dma_ch *chdat)
 		reg |= ((1 << 4) << (dmareq_nr * 5));
 	musb_writel(chdat->tbase, TUSB_DMA_EP_MAP, reg);
 
-	chdat->dmareq = dmareq_nr;
-	chdat->sync_dev = sync_dev[chdat->dmareq];
+	chdat->dma_data.dmareq = dmareq_nr;
+	chdat->dma_data.sync_dev = sync_dev[chdat->dma_data.dmareq];
 
 	return 0;
 }
@@ -471,15 +468,15 @@ static inline void tusb_omap_dma_free_dmareq(struct tusb_omap_dma_ch *chdat)
 {
 	u32 reg;
 
-	if (!chdat || chdat->dmareq < 0)
+	if (!chdat || chdat->dma_data.dmareq < 0)
 		return;
 
 	reg = musb_readl(chdat->tbase, TUSB_DMA_EP_MAP);
-	reg &= ~(0x1f << (chdat->dmareq * 5));
+	reg &= ~(0x1f << (chdat->dma_data.dmareq * 5));
 	musb_writel(chdat->tbase, TUSB_DMA_EP_MAP, reg);
 
-	chdat->dmareq = -1;
-	chdat->sync_dev = -1;
+	chdat->dma_data.dmareq = -1;
+	chdat->dma_data.sync_dev = -1;
 }
 
 static struct dma_channel *dma_channel_pool[MAX_DMAREQ];
@@ -491,11 +488,13 @@ tusb_omap_dma_allocate(struct dma_controller *c,
 {
 	int ret, i;
 	const char		*dev_name;
+	void			*cb_data;
 	struct tusb_omap_dma	*tusb_dma;
 	struct musb		*musb;
 	void __iomem		*tbase;
 	struct dma_channel	*channel = NULL;
 	struct tusb_omap_dma_ch	*chdat = NULL;
+	struct tusb_dma_data	*dma_data = NULL;
 	u32			reg;
 
 	tusb_dma = container_of(c, struct tusb_omap_dma, controller);
@@ -528,56 +527,61 @@ tusb_omap_dma_allocate(struct dma_controller *c,
 	if (!channel)
 		return NULL;
 
-	if (tx) {
-		chdat->tx = 1;
-		dev_name = "TUSB transmit";
-	} else {
-		chdat->tx = 0;
-		dev_name = "TUSB receive";
-	}
-
 	chdat->musb = tusb_dma->controller.musb;
 	chdat->tbase = tusb_dma->tbase;
 	chdat->hw_ep = hw_ep;
 	chdat->epnum = hw_ep->epnum;
-	chdat->dmareq = -1;
 	chdat->completed_len = 0;
 	chdat->tusb_dma = tusb_dma;
+	if (tx)
+		chdat->tx = 1;
+	else
+		chdat->tx = 0;
 
 	channel->max_len = 0x7fffffff;
 	channel->desired_mode = 0;
 	channel->actual_len = 0;
 
 	if (tusb_dma->multichannel) {
+		dma_data = &chdat->dma_data;
 		ret = tusb_omap_dma_allocate_dmareq(chdat);
 		if (ret != 0)
 			goto free_dmareq;
 
-		ret = omap_request_dma(chdat->sync_dev, dev_name,
-				tusb_omap_dma_cb, channel, &chdat->ch);
-		if (ret != 0)
-			goto free_dmareq;
-	} else if (tusb_dma->ch == -1) {
-		tusb_dma->dmareq = 0;
-		tusb_dma->sync_dev = OMAP24XX_DMA_EXT_DMAREQ0;
-
+		if (chdat->tx)
+			dev_name = "TUSB transmit";
+		else
+			dev_name = "TUSB receive";
+		cb_data = channel;
+	} else if (tusb_dma->dma_data.ch == -1) {
+		dma_data = &tusb_dma->dma_data;
+		dma_data->dmareq = 0;
+		dma_data->sync_dev = OMAP24XX_DMA_EXT_DMAREQ0;
+
+		dev_name = "TUSB shared";
 		/* Callback data gets set later in the shared dmareq case */
-		ret = omap_request_dma(tusb_dma->sync_dev, "TUSB shared",
-				tusb_omap_dma_cb, NULL, &tusb_dma->ch);
+		cb_data = NULL;
+
+		chdat->dma_data.dmareq = -1;
+		chdat->dma_data.ch = -1;
+		chdat->dma_data.sync_dev = -1;
+	}
+
+	if (dma_data) {
+		ret = omap_request_dma(dma_data->sync_dev, dev_name,
+				       tusb_omap_dma_cb, cb_data, &dma_data->ch);
 		if (ret != 0)
 			goto free_dmareq;
-
-		chdat->dmareq = -1;
-		chdat->ch = -1;
+	} else {
+		/* Already allocated shared, single DMA channel. */
+		dma_data = &tusb_dma->dma_data;
 	}
 
 	dev_dbg(musb->controller, "ep%i %s dma: %s dma%i dmareq%i sync%i\n",
 		chdat->epnum,
 		chdat->tx ? "tx" : "rx",
-		chdat->ch >= 0 ? "dedicated" : "shared",
-		chdat->ch >= 0 ? chdat->ch : tusb_dma->ch,
-		chdat->dmareq >= 0 ? chdat->dmareq : tusb_dma->dmareq,
-		chdat->sync_dev >= 0 ? chdat->sync_dev : tusb_dma->sync_dev);
+		chdat->dma_data.ch >= 0 ? "dedicated" : "shared",
+		dma_data->ch, dma_data->dmareq, dma_data->sync_dev);
 
 	return channel;
 
@@ -597,7 +601,8 @@ static void tusb_omap_dma_release(struct dma_channel *channel)
 	void __iomem		*tbase = musb->ctrl_base;
 	u32			reg;
 
-	dev_dbg(musb->controller, "ep%i ch%i\n", chdat->epnum, chdat->ch);
+	dev_dbg(musb->controller, "ep%i ch%i\n", chdat->epnum,
+		chdat->dma_data.ch);
 
 	reg = musb_readl(tbase, TUSB_DMA_INT_MASK);
 	if (chdat->tx)
@@ -615,13 +620,13 @@ static void tusb_omap_dma_release(struct dma_channel *channel)
 
 	channel->status = MUSB_DMA_STATUS_UNKNOWN;
 
-	if (chdat->ch >= 0) {
-		omap_stop_dma(chdat->ch);
-		omap_free_dma(chdat->ch);
-		chdat->ch = -1;
+	if (chdat->dma_data.ch >= 0) {
+		omap_stop_dma(chdat->dma_data.ch);
+		omap_free_dma(chdat->dma_data.ch);
+		chdat->dma_data.ch = -1;
 	}
 
-	if (chdat->dmareq >= 0)
+	if (chdat->dma_data.dmareq >= 0)
 		tusb_omap_dma_free_dmareq(chdat);
 
 	channel = NULL;
@@ -641,8 +646,8 @@ void tusb_dma_controller_destroy(struct dma_controller *c)
 		}
 	}
 
-	if (tusb_dma && !tusb_dma->multichannel && tusb_dma->ch >= 0)
-		omap_free_dma(tusb_dma->ch);
+	if (tusb_dma && !tusb_dma->multichannel && tusb_dma->dma_data.ch >= 0)
+		omap_free_dma(tusb_dma->dma_data.ch);
 
 	kfree(tusb_dma);
 }
@@ -672,9 +677,9 @@ tusb_dma_controller_create(struct musb *musb, void __iomem *base)
 	tusb_dma->controller.musb = musb;
 	tusb_dma->tbase = musb->ctrl_base;
 
-	tusb_dma->ch = -1;
-	tusb_dma->dmareq = -1;
-	tusb_dma->sync_dev = -1;
+	tusb_dma->dma_data.ch = -1;
+	tusb_dma->dma_data.dmareq = -1;
+	tusb_dma->dma_data.sync_dev = -1;
 
 	tusb_dma->controller.channel_alloc = tusb_omap_dma_allocate;
 	tusb_dma->controller.channel_release = tusb_omap_dma_release;
-- 
2.12.2

[toc] | [prev] | [next] | [standalone]


#1638665 — [PATCH v2 07/10] usb: musb: tusb6010_omap: Allocate DMA channels upfront

FromPeter Ujfalusi <peter.ujfalusi@ti.com>
Date2017-05-10 10:50 +0200
Subject[PATCH v2 07/10] usb: musb: tusb6010_omap: Allocate DMA channels upfront
Message-ID<tFvtM-6TH-23@gated-at.bofh.it>
In reply to#1638661
Instead of requesting the DMA channel in tusb_omap_dma_allocate() do it
when the controller is created and in runtime work from the DMA channel
pool.

This change is needed for the DMAengine conversion of the driver since the
tusb_omap_dma_allocate() is called in interrupt context which might lead
to lock within the DMAengine API when requesting channel.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 drivers/usb/musb/tusb6010_omap.c | 184 +++++++++++++++++++--------------------
 1 file changed, 92 insertions(+), 92 deletions(-)

diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c
index f1e58e15e5bb..2daeef7e572d 100644
--- a/drivers/usb/musb/tusb6010_omap.c
+++ b/drivers/usb/musb/tusb6010_omap.c
@@ -45,7 +45,7 @@ struct tusb_omap_dma_ch {
 	u8			tx;
 	struct musb_hw_ep	*hw_ep;
 
-	struct tusb_dma_data	dma_data;
+	struct tusb_dma_data	*dma_data;
 
 	struct tusb_omap_dma	*tusb_dma;
 
@@ -62,7 +62,7 @@ struct tusb_omap_dma {
 	struct dma_controller		controller;
 	void __iomem			*tbase;
 
-	struct tusb_dma_data		dma_data;
+	struct tusb_dma_data		dma_pool[MAX_DMAREQ];
 	unsigned			multichannel:1;
 };
 
@@ -120,10 +120,7 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data)
 
 	spin_lock_irqsave(&musb->lock, flags);
 
-	if (tusb_dma->multichannel)
-		ch = chdat->dma_data.ch;
-	else
-		ch = tusb_dma->dma_data.ch;
+	ch = chdat->dma_data->ch;
 
 	if (ch_status != OMAP_DMA_BLOCK_IRQ)
 		printk(KERN_ERR "TUSB DMA error status: %i\n", ch_status);
@@ -247,7 +244,8 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
 	dma_remaining = TUSB_EP_CONFIG_XFR_SIZE(dma_remaining);
 	if (dma_remaining) {
 		dev_dbg(musb->controller, "Busy %s dma ch%i, not using: %08x\n",
-			chdat->tx ? "tx" : "rx", chdat->dma_data.ch,
+			chdat->tx ? "tx" : "rx",
+			chdat->dma_data ? chdat->dma_data->ch : -1,
 			dma_remaining);
 		return false;
 	}
@@ -259,11 +257,8 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
 	else
 		chdat->transfer_packet_sz = packet_sz;
 
-	if (tusb_dma->multichannel) {
-		dma_data = &chdat->dma_data;
-	} else {
-		dma_data = &tusb_dma->dma_data;
-
+	dma_data = chdat->dma_data;
+	if (!tusb_dma->multichannel) {
 		if (tusb_omap_use_shared_dmareq(chdat) != 0) {
 			dev_dbg(musb->controller, "could not get dma for ep%i\n", chdat->epnum);
 			return false;
@@ -275,10 +270,10 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
 			WARN_ON(1);
 			return false;
 		}
-
-		omap_set_dma_callback(dma_data->ch, tusb_omap_dma_cb, channel);
 	}
 
+	omap_set_dma_callback(dma_data->ch, tusb_omap_dma_cb, channel);
+
 	chdat->packet_sz = packet_sz;
 	chdat->len = len;
 	channel->actual_len = 0;
@@ -409,19 +404,9 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
 static int tusb_omap_dma_abort(struct dma_channel *channel)
 {
 	struct tusb_omap_dma_ch	*chdat = to_chdat(channel);
-	struct tusb_omap_dma	*tusb_dma = chdat->tusb_dma;
-	struct tusb_dma_data	*dma_data = &tusb_dma->dma_data;
 
-	if (!tusb_dma->multichannel) {
-		if (dma_data->ch >= 0) {
-			omap_stop_dma(dma_data->ch);
-			omap_free_dma(dma_data->ch);
-			dma_data->ch = -1;
-		}
-
-		dma_data->dmareq = -1;
-		dma_data->sync_dev = -1;
-	}
+	if (chdat->dma_data)
+		omap_stop_dma(chdat->dma_data->ch);
 
 	channel->status = MUSB_DMA_STATUS_FREE;
 
@@ -433,15 +418,6 @@ static inline int tusb_omap_dma_allocate_dmareq(struct tusb_omap_dma_ch *chdat)
 	u32		reg = musb_readl(chdat->tbase, TUSB_DMA_EP_MAP);
 	int		i, dmareq_nr = -1;
 
-	const int sync_dev[6] = {
-		OMAP24XX_DMA_EXT_DMAREQ0,
-		OMAP24XX_DMA_EXT_DMAREQ1,
-		OMAP242X_DMA_EXT_DMAREQ2,
-		OMAP242X_DMA_EXT_DMAREQ3,
-		OMAP242X_DMA_EXT_DMAREQ4,
-		OMAP242X_DMA_EXT_DMAREQ5,
-	};
-
 	for (i = 0; i < MAX_DMAREQ; i++) {
 		int cur = (reg & (0xf << (i * 5))) >> (i * 5);
 		if (cur == 0) {
@@ -458,8 +434,7 @@ static inline int tusb_omap_dma_allocate_dmareq(struct tusb_omap_dma_ch *chdat)
 		reg |= ((1 << 4) << (dmareq_nr * 5));
 	musb_writel(chdat->tbase, TUSB_DMA_EP_MAP, reg);
 
-	chdat->dma_data.dmareq = dmareq_nr;
-	chdat->dma_data.sync_dev = sync_dev[chdat->dma_data.dmareq];
+	chdat->dma_data = &chdat->tusb_dma->dma_pool[dmareq_nr];
 
 	return 0;
 }
@@ -468,15 +443,14 @@ static inline void tusb_omap_dma_free_dmareq(struct tusb_omap_dma_ch *chdat)
 {
 	u32 reg;
 
-	if (!chdat || chdat->dma_data.dmareq < 0)
+	if (!chdat || !chdat->dma_data || chdat->dma_data->dmareq < 0)
 		return;
 
 	reg = musb_readl(chdat->tbase, TUSB_DMA_EP_MAP);
-	reg &= ~(0x1f << (chdat->dma_data.dmareq * 5));
+	reg &= ~(0x1f << (chdat->dma_data->dmareq * 5));
 	musb_writel(chdat->tbase, TUSB_DMA_EP_MAP, reg);
 
-	chdat->dma_data.dmareq = -1;
-	chdat->dma_data.sync_dev = -1;
+	chdat->dma_data = NULL;
 }
 
 static struct dma_channel *dma_channel_pool[MAX_DMAREQ];
@@ -487,8 +461,6 @@ tusb_omap_dma_allocate(struct dma_controller *c,
 		u8 tx)
 {
 	int ret, i;
-	const char		*dev_name;
-	void			*cb_data;
 	struct tusb_omap_dma	*tusb_dma;
 	struct musb		*musb;
 	void __iomem		*tbase;
@@ -542,45 +514,22 @@ tusb_omap_dma_allocate(struct dma_controller *c,
 	channel->desired_mode = 0;
 	channel->actual_len = 0;
 
-	if (tusb_dma->multichannel) {
-		dma_data = &chdat->dma_data;
-		ret = tusb_omap_dma_allocate_dmareq(chdat);
-		if (ret != 0)
-			goto free_dmareq;
-
-		if (chdat->tx)
-			dev_name = "TUSB transmit";
-		else
-			dev_name = "TUSB receive";
-		cb_data = channel;
-	} else if (tusb_dma->dma_data.ch == -1) {
-		dma_data = &tusb_dma->dma_data;
-		dma_data->dmareq = 0;
-		dma_data->sync_dev = OMAP24XX_DMA_EXT_DMAREQ0;
-
-		dev_name = "TUSB shared";
-		/* Callback data gets set later in the shared dmareq case */
-		cb_data = NULL;
-
-		chdat->dma_data.dmareq = -1;
-		chdat->dma_data.ch = -1;
-		chdat->dma_data.sync_dev = -1;
+	if (!chdat->dma_data) {
+		if (tusb_dma->multichannel) {
+			ret = tusb_omap_dma_allocate_dmareq(chdat);
+			if (ret != 0)
+				goto free_dmareq;
+		} else {
+			chdat->dma_data = &tusb_dma->dma_pool[0];
+		}
 	}
 
-	if (dma_data) {
-		ret = omap_request_dma(dma_data->sync_dev, dev_name,
-				       tusb_omap_dma_cb, cb_data, &dma_data->ch);
-		if (ret != 0)
-			goto free_dmareq;
-	} else {
-		/* Already allocated shared, single DMA channel. */
-		dma_data = &tusb_dma->dma_data;
-	}
+	dma_data = chdat->dma_data;
 
 	dev_dbg(musb->controller, "ep%i %s dma: %s dma%i dmareq%i sync%i\n",
 		chdat->epnum,
 		chdat->tx ? "tx" : "rx",
-		chdat->dma_data.ch >= 0 ? "dedicated" : "shared",
+		tusb_dma->multichannel ? "shared" : "dedicated",
 		dma_data->ch, dma_data->dmareq, dma_data->sync_dev);
 
 	return channel;
@@ -602,7 +551,7 @@ static void tusb_omap_dma_release(struct dma_channel *channel)
 	u32			reg;
 
 	dev_dbg(musb->controller, "ep%i ch%i\n", chdat->epnum,
-		chdat->dma_data.ch);
+		chdat->dma_data->ch);
 
 	reg = musb_readl(tbase, TUSB_DMA_INT_MASK);
 	if (chdat->tx)
@@ -620,14 +569,8 @@ static void tusb_omap_dma_release(struct dma_channel *channel)
 
 	channel->status = MUSB_DMA_STATUS_UNKNOWN;
 
-	if (chdat->dma_data.ch >= 0) {
-		omap_stop_dma(chdat->dma_data.ch);
-		omap_free_dma(chdat->dma_data.ch);
-		chdat->dma_data.ch = -1;
-	}
-
-	if (chdat->dma_data.dmareq >= 0)
-		tusb_omap_dma_free_dmareq(chdat);
+	omap_stop_dma(chdat->dma_data->ch);
+	tusb_omap_dma_free_dmareq(chdat);
 
 	channel = NULL;
 }
@@ -644,15 +587,73 @@ void tusb_dma_controller_destroy(struct dma_controller *c)
 			kfree(ch->private_data);
 			kfree(ch);
 		}
-	}
 
-	if (tusb_dma && !tusb_dma->multichannel && tusb_dma->dma_data.ch >= 0)
-		omap_free_dma(tusb_dma->dma_data.ch);
+		/* Free up the DMA channels */
+		if (tusb_dma && tusb_dma->dma_pool[i].ch >= 0)
+			omap_free_dma(tusb_dma->dma_pool[i].ch);
+	}
 
 	kfree(tusb_dma);
 }
 EXPORT_SYMBOL_GPL(tusb_dma_controller_destroy);
 
+static int tusb_omap_allocate_dma_pool(struct tusb_omap_dma *tusb_dma)
+{
+	int i;
+	int ret = 0;
+	const int sync_dev[6] = {
+		OMAP24XX_DMA_EXT_DMAREQ0,
+		OMAP24XX_DMA_EXT_DMAREQ1,
+		OMAP242X_DMA_EXT_DMAREQ2,
+		OMAP242X_DMA_EXT_DMAREQ3,
+		OMAP242X_DMA_EXT_DMAREQ4,
+		OMAP242X_DMA_EXT_DMAREQ5,
+	};
+
+	for (i = 0; i < MAX_DMAREQ; i++) {
+		struct tusb_dma_data *dma_data = &tusb_dma->dma_pool[i];
+
+		/*
+		 * Request DMA channels:
+		 * - one channel in case of non multichannel mode
+		 * - MAX_DMAREQ number of channels in multichannel mode
+		 */
+		if (i == 0 || tusb_dma->multichannel) {
+			char ch_name[8];
+
+			sprintf(ch_name, "dmareq%d", i);
+			dma_data->sync_dev = sync_dev[i];
+			dma_data->ch = -1;
+			/* callback data is ngoing to be set later */
+			ret = omap_request_dma(dma_data->sync_dev, ch_name,
+					tusb_omap_dma_cb, NULL, &dma_data->ch);
+			if (ret != 0) {
+				dev_err(tusb_dma->controller.musb->controller,
+					"Failed to request %s\n", ch_name);
+				goto dma_error;
+			}
+
+			dma_data->dmareq = i;
+		} else {
+			dma_data->dmareq = -1;
+			dma_data->sync_dev = -1;
+			dma_data->ch = -1;
+		}
+	}
+
+	return 0;
+
+dma_error:
+	for (; i >= 0; i--) {
+		struct tusb_dma_data *dma_data = &tusb_dma->dma_pool[i];
+
+		if (dma_data->ch >= 0)
+			omap_free_dma(dma_data->ch);
+	}
+
+	return ret;
+}
+
 struct dma_controller *
 tusb_dma_controller_create(struct musb *musb, void __iomem *base)
 {
@@ -677,10 +678,6 @@ tusb_dma_controller_create(struct musb *musb, void __iomem *base)
 	tusb_dma->controller.musb = musb;
 	tusb_dma->tbase = musb->ctrl_base;
 
-	tusb_dma->dma_data.ch = -1;
-	tusb_dma->dma_data.dmareq = -1;
-	tusb_dma->dma_data.sync_dev = -1;
-
 	tusb_dma->controller.channel_alloc = tusb_omap_dma_allocate;
 	tusb_dma->controller.channel_release = tusb_omap_dma_release;
 	tusb_dma->controller.channel_program = tusb_omap_dma_program;
@@ -707,6 +704,9 @@ tusb_dma_controller_create(struct musb *musb, void __iomem *base)
 		ch->private_data = chdat;
 	}
 
+	if (tusb_omap_allocate_dma_pool(tusb_dma))
+		goto cleanup;
+
 	return &tusb_dma->controller;
 
 cleanup:
-- 
2.12.2

[toc] | [prev] | [next] | [standalone]


#1638667 — [PATCH v2 04/10] usb: musb: tusb6010_omap: Use one musb_ep_select call in tusb_omap_dma_program

FromPeter Ujfalusi <peter.ujfalusi@ti.com>
Date2017-05-10 10:50 +0200
Subject[PATCH v2 04/10] usb: musb: tusb6010_omap: Use one musb_ep_select call in tusb_omap_dma_program
Message-ID<tFvtM-6TH-31@gated-at.bofh.it>
In reply to#1638661
Having one musb_ep_select() instead the two calls in if/else is the same
thing, but makes the code a bit simpler to follow.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 drivers/usb/musb/tusb6010_omap.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c
index 8b43c4b99f04..db2e4c379ccf 100644
--- a/drivers/usb/musb/tusb6010_omap.c
+++ b/drivers/usb/musb/tusb6010_omap.c
@@ -367,15 +367,14 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
 	/*
 	 * Prepare MUSB for DMA transfer
 	 */
+	musb_ep_select(mbase, chdat->epnum);
 	if (chdat->tx) {
-		musb_ep_select(mbase, chdat->epnum);
 		csr = musb_readw(hw_ep->regs, MUSB_TXCSR);
 		csr |= (MUSB_TXCSR_AUTOSET | MUSB_TXCSR_DMAENAB
 			| MUSB_TXCSR_DMAMODE | MUSB_TXCSR_MODE);
 		csr &= ~MUSB_TXCSR_P_UNDERRUN;
 		musb_writew(hw_ep->regs, MUSB_TXCSR, csr);
 	} else {
-		musb_ep_select(mbase, chdat->epnum);
 		csr = musb_readw(hw_ep->regs, MUSB_RXCSR);
 		csr |= MUSB_RXCSR_DMAENAB;
 		csr &= ~(MUSB_RXCSR_AUTOCLEAR | MUSB_RXCSR_DMAMODE);
-- 
2.12.2

[toc] | [prev] | [next] | [standalone]


#1638669 — [PATCH v2 08/10] usb: musb: tusb6010: Handle DMA TX completion in DMA callback as well

FromPeter Ujfalusi <peter.ujfalusi@ti.com>
Date2017-05-10 10:50 +0200
Subject[PATCH v2 08/10] usb: musb: tusb6010: Handle DMA TX completion in DMA callback as well
Message-ID<tFvtM-6TH-27@gated-at.bofh.it>
In reply to#1638661
Handle the DMA TX in a similar way as we do for the RX: in the DMA
completion callback.

Since we are no longer using DMA completion interrupt for the TX we can as
wall keep these interrupts disabled, but keep the handler for debug
purposes.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 drivers/usb/musb/tusb6010.c      | 18 +++---------------
 drivers/usb/musb/tusb6010_omap.c | 34 +---------------------------------
 2 files changed, 4 insertions(+), 48 deletions(-)

diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c
index 4253bfb22043..4eb640c54f2c 100644
--- a/drivers/usb/musb/tusb6010.c
+++ b/drivers/usb/musb/tusb6010.c
@@ -881,26 +881,14 @@ static irqreturn_t tusb_musb_interrupt(int irq, void *__hci)
 				| TUSB_INT_SRC_ID_STATUS_CHNG))
 		idle_timeout = tusb_otg_ints(musb, int_src, tbase);
 
-	/* TX dma callback must be handled here, RX dma callback is
-	 * handled in tusb_omap_dma_cb.
+	/*
+	 * Just clear the DMA interrupt if it comes as the completion for both
+	 * TX and RX is handled by the DMA callback in tusb6010_omap
 	 */
 	if ((int_src & TUSB_INT_SRC_TXRX_DMA_DONE)) {
 		u32	dma_src = musb_readl(tbase, TUSB_DMA_INT_SRC);
-		u32	real_dma_src = musb_readl(tbase, TUSB_DMA_INT_MASK);
 
 		dev_dbg(musb->controller, "DMA IRQ %08x\n", dma_src);
-		real_dma_src = ~real_dma_src & dma_src;
-		if (tusb_dma_omap(musb) && real_dma_src) {
-			int	tx_source = (real_dma_src & 0xffff);
-			int	i;
-
-			for (i = 1; i <= 15; i++) {
-				if (tx_source & (1 << i)) {
-					dev_dbg(musb->controller, "completing ep%i %s\n", i, "tx");
-					musb_dma_completion(musb, i, 1);
-				}
-			}
-		}
 		musb_writel(tbase, TUSB_DMA_INT_CLEAR, dma_src);
 	}
 
diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c
index 2daeef7e572d..34e0115a4629 100644
--- a/drivers/usb/musb/tusb6010_omap.c
+++ b/drivers/usb/musb/tusb6010_omap.c
@@ -173,13 +173,7 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data)
 
 	channel->status = MUSB_DMA_STATUS_FREE;
 
-	/* Handle only RX callbacks here. TX callbacks must be handled based
-	 * on the TUSB DMA status interrupt.
-	 * REVISIT: Use both TUSB DMA status interrupt and OMAP DMA callback
-	 * interrupt for RX and TX.
-	 */
-	if (!chdat->tx)
-		musb_dma_completion(musb, chdat->epnum, chdat->tx);
+	musb_dma_completion(musb, chdat->epnum, chdat->tx);
 
 	/* We must terminate short tx transfers manually by setting TXPKTRDY.
 	 * REVISIT: This same problem may occur with other MUSB dma as well.
@@ -463,22 +457,12 @@ tusb_omap_dma_allocate(struct dma_controller *c,
 	int ret, i;
 	struct tusb_omap_dma	*tusb_dma;
 	struct musb		*musb;
-	void __iomem		*tbase;
 	struct dma_channel	*channel = NULL;
 	struct tusb_omap_dma_ch	*chdat = NULL;
 	struct tusb_dma_data	*dma_data = NULL;
-	u32			reg;
 
 	tusb_dma = container_of(c, struct tusb_omap_dma, controller);
 	musb = tusb_dma->controller.musb;
-	tbase = musb->ctrl_base;
-
-	reg = musb_readl(tbase, TUSB_DMA_INT_MASK);
-	if (tx)
-		reg &= ~(1 << hw_ep->epnum);
-	else
-		reg &= ~(1 << (hw_ep->epnum + 15));
-	musb_writel(tbase, TUSB_DMA_INT_MASK, reg);
 
 	/* REVISIT: Why does dmareq5 not work? */
 	if (hw_ep->epnum == 0) {
@@ -547,26 +531,10 @@ static void tusb_omap_dma_release(struct dma_channel *channel)
 {
 	struct tusb_omap_dma_ch	*chdat = to_chdat(channel);
 	struct musb		*musb = chdat->musb;
-	void __iomem		*tbase = musb->ctrl_base;
-	u32			reg;
 
 	dev_dbg(musb->controller, "ep%i ch%i\n", chdat->epnum,
 		chdat->dma_data->ch);
 
-	reg = musb_readl(tbase, TUSB_DMA_INT_MASK);
-	if (chdat->tx)
-		reg |= (1 << chdat->epnum);
-	else
-		reg |= (1 << (chdat->epnum + 15));
-	musb_writel(tbase, TUSB_DMA_INT_MASK, reg);
-
-	reg = musb_readl(tbase, TUSB_DMA_INT_CLEAR);
-	if (chdat->tx)
-		reg |= (1 << chdat->epnum);
-	else
-		reg |= (1 << (chdat->epnum + 15));
-	musb_writel(tbase, TUSB_DMA_INT_CLEAR, reg);
-
 	channel->status = MUSB_DMA_STATUS_UNKNOWN;
 
 	omap_stop_dma(chdat->dma_data->ch);
-- 
2.12.2

[toc] | [prev] | [next] | [standalone]


#1638672 — [PATCH v2 09/10] ARM: OMAP2+: DMA: Add slave map entries for 24xx external request lines

FromPeter Ujfalusi <peter.ujfalusi@ti.com>
Date2017-05-10 10:50 +0200
Subject[PATCH v2 09/10] ARM: OMAP2+: DMA: Add slave map entries for 24xx external request lines
Message-ID<tFvtN-6TH-37@gated-at.bofh.it>
In reply to#1638661
The external request lines are used by tusb6010 on OMAP24xx platforms.
Update the map so the driver can use dmaengine API to request the DMA
channel. At the same time add temporary map containing only the external
DMA request numbers for DT booted case on omap24xx since the tusb6010 stack
is not yet supports DT boot.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 arch/arm/mach-omap2/dma.c | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/arch/arm/mach-omap2/dma.c b/arch/arm/mach-omap2/dma.c
index e58c13a9bea5..0b77a0176018 100644
--- a/arch/arm/mach-omap2/dma.c
+++ b/arch/arm/mach-omap2/dma.c
@@ -249,6 +249,24 @@ static const struct dma_slave_map omap24xx_sdma_map[] = {
 	{ "omap_uart.2", "rx", SDMA_FILTER_PARAM(54) },
 	{ "omap_hsmmc.0", "tx", SDMA_FILTER_PARAM(61) },
 	{ "omap_hsmmc.0", "rx", SDMA_FILTER_PARAM(62) },
+
+	/* external DMA requests when tusb6010 is used */
+	{ "musb-tusb", "dmareq0", SDMA_FILTER_PARAM(2) },
+	{ "musb-tusb", "dmareq1", SDMA_FILTER_PARAM(3) },
+	{ "musb-tusb", "dmareq2", SDMA_FILTER_PARAM(14) }, /* OMAP2420 only */
+	{ "musb-tusb", "dmareq3", SDMA_FILTER_PARAM(15) }, /* OMAP2420 only */
+	{ "musb-tusb", "dmareq4", SDMA_FILTER_PARAM(16) }, /* OMAP2420 only */
+	{ "musb-tusb", "dmareq5", SDMA_FILTER_PARAM(64) }, /* OMAP2420 only */
+};
+
+static const struct dma_slave_map omap24xx_sdma_dt_map[] = {
+	/* external DMA requests when tusb6010 is used */
+	{ "musb-hdrc.1.auto", "dmareq0", SDMA_FILTER_PARAM(2) },
+	{ "musb-hdrc.1.auto", "dmareq1", SDMA_FILTER_PARAM(3) },
+	{ "musb-hdrc.1.auto", "dmareq2", SDMA_FILTER_PARAM(14) }, /* OMAP2420 only */
+	{ "musb-hdrc.1.auto", "dmareq3", SDMA_FILTER_PARAM(15) }, /* OMAP2420 only */
+	{ "musb-hdrc.1.auto", "dmareq4", SDMA_FILTER_PARAM(16) }, /* OMAP2420 only */
+	{ "musb-hdrc.1.auto", "dmareq5", SDMA_FILTER_PARAM(64) }, /* OMAP2420 only */
 };
 
 static const struct dma_slave_map omap3xxx_sdma_map[] = {
@@ -346,6 +364,12 @@ static int __init omap2_system_dma_init_dev(struct omap_hwmod *oh, void *unused)
 			       __func__);
 			return -ENODEV;
 		}
+	} else {
+		if (soc_is_omap24xx()) {
+			/* DMA slave map for drivers not yet converted to DT */
+			p.slave_map = omap24xx_sdma_dt_map;
+			p.slavecnt = ARRAY_SIZE(omap24xx_sdma_dt_map);
+		}
 	}
 
 	pdev = omap_device_build(name, 0, oh, &p, sizeof(p));
-- 
2.12.2

[toc] | [prev] | [next] | [standalone]


#1638960 — Re: [PATCH v2 09/10] ARM: OMAP2+: DMA: Add slave map entries for 24xx external request lines

FromTony Lindgren <tony@atomide.com>
Date2017-05-10 18:40 +0200
SubjectRe: [PATCH v2 09/10] ARM: OMAP2+: DMA: Add slave map entries for 24xx external request lines
Message-ID<tFCOC-31A-9@gated-at.bofh.it>
In reply to#1638672
* Peter Ujfalusi <peter.ujfalusi@ti.com> [170510 01:46]:
> The external request lines are used by tusb6010 on OMAP24xx platforms.
> Update the map so the driver can use dmaengine API to request the DMA
> channel. At the same time add temporary map containing only the external
> DMA request numbers for DT booted case on omap24xx since the tusb6010 stack
> is not yet supports DT boot.
> 
> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>

Best to merge this together with the series:

Acked-by: Tony Lindgren <tony@atomide.com>

[toc] | [prev] | [next] | [standalone]


#1638673 — [PATCH v2 03/10] usb: musb: tusb6010: Add MUSB_G_NO_SKB_RESERVE to quirks

FromPeter Ujfalusi <peter.ujfalusi@ti.com>
Date2017-05-10 10:50 +0200
Subject[PATCH v2 03/10] usb: musb: tusb6010: Add MUSB_G_NO_SKB_RESERVE to quirks
Message-ID<tFvtN-6TH-41@gated-at.bofh.it>
In reply to#1638661
When using the g_ncm for networking this flag will make sure that the
buffer is alligned to 32bit so the DMA can be used to offload the data
movement.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 drivers/usb/musb/tusb6010.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/usb/musb/tusb6010.c b/drivers/usb/musb/tusb6010.c
index e85cc8e4e7a9..4253bfb22043 100644
--- a/drivers/usb/musb/tusb6010.c
+++ b/drivers/usb/musb/tusb6010.c
@@ -1181,7 +1181,8 @@ static int tusb_musb_exit(struct musb *musb)
 }
 
 static const struct musb_platform_ops tusb_ops = {
-	.quirks		= MUSB_DMA_TUSB_OMAP | MUSB_IN_TUSB,
+	.quirks		= MUSB_DMA_TUSB_OMAP | MUSB_IN_TUSB |
+			  MUSB_G_NO_SKB_RESERVE,
 	.init		= tusb_musb_init,
 	.exit		= tusb_musb_exit,
 
-- 
2.12.2

[toc] | [prev] | [next] | [standalone]


#1638686 — [PATCH v2 10/10] usb: musb: tusb6010_omap: Convert to DMAengine API

FromPeter Ujfalusi <peter.ujfalusi@ti.com>
Date2017-05-10 11:00 +0200
Subject[PATCH v2 10/10] usb: musb: tusb6010_omap: Convert to DMAengine API
Message-ID<tFvDs-6WY-35@gated-at.bofh.it>
In reply to#1638661
With the port_window support in DMAengine and the sDMA driver we can
convert the driver to DMAengine.

Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
---
 drivers/usb/musb/tusb6010_omap.c | 201 ++++++++++++++++-----------------------
 1 file changed, 80 insertions(+), 121 deletions(-)

diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c
index 34e0115a4629..0c2bd0befe72 100644
--- a/drivers/usb/musb/tusb6010_omap.c
+++ b/drivers/usb/musb/tusb6010_omap.c
@@ -15,7 +15,7 @@
 #include <linux/platform_device.h>
 #include <linux/dma-mapping.h>
 #include <linux/slab.h>
-#include <linux/omap-dma.h>
+#include <linux/dmaengine.h>
 
 #include "musb_core.h"
 #include "tusb6010.h"
@@ -24,17 +24,9 @@
 
 #define MAX_DMAREQ		5	/* REVISIT: Really 6, but req5 not OK */
 
-#define OMAP24XX_DMA_EXT_DMAREQ0	2
-#define OMAP24XX_DMA_EXT_DMAREQ1	3
-#define OMAP242X_DMA_EXT_DMAREQ2	14
-#define OMAP242X_DMA_EXT_DMAREQ3	15
-#define OMAP242X_DMA_EXT_DMAREQ4	16
-#define OMAP242X_DMA_EXT_DMAREQ5	64
-
 struct tusb_dma_data {
-	int			ch;
 	s8			dmareq;
-	s8			sync_dev;
+	struct dma_chan		*chan;
 };
 
 struct tusb_omap_dma_ch {
@@ -105,7 +97,7 @@ static inline void tusb_omap_free_shared_dmareq(struct tusb_omap_dma_ch *chdat)
  * See also musb_dma_completion in plat_uds.c and musb_g_[tx|rx]() in
  * musb_gadget.c.
  */
-static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data)
+static void tusb_omap_dma_cb(void *data)
 {
 	struct dma_channel	*channel = (struct dma_channel *)data;
 	struct tusb_omap_dma_ch	*chdat = to_chdat(channel);
@@ -116,18 +108,11 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data)
 	void __iomem		*ep_conf = hw_ep->conf;
 	void __iomem		*mbase = musb->mregs;
 	unsigned long		remaining, flags, pio;
-	int			ch;
 
 	spin_lock_irqsave(&musb->lock, flags);
 
-	ch = chdat->dma_data->ch;
-
-	if (ch_status != OMAP_DMA_BLOCK_IRQ)
-		printk(KERN_ERR "TUSB DMA error status: %i\n", ch_status);
-
-	dev_dbg(musb->controller, "ep%i %s dma callback ch: %i status: %x\n",
-		chdat->epnum, chdat->tx ? "tx" : "rx",
-		ch, ch_status);
+	dev_dbg(musb->controller, "ep%i %s dma callback\n",
+		chdat->epnum, chdat->tx ? "tx" : "rx");
 
 	if (chdat->tx)
 		remaining = musb_readl(ep_conf, TUSB_EP_TX_OFFSET);
@@ -138,8 +123,8 @@ static void tusb_omap_dma_cb(int lch, u16 ch_status, void *data)
 
 	/* HW issue #10: XFR_SIZE may get corrupt on DMA (both async & sync) */
 	if (unlikely(remaining > chdat->transfer_len)) {
-		dev_dbg(musb->controller, "Corrupt %s dma ch%i XFR_SIZE: 0x%08lx\n",
-			chdat->tx ? "tx" : "rx", ch, remaining);
+		dev_dbg(musb->controller, "Corrupt %s XFR_SIZE: 0x%08lx\n",
+			chdat->tx ? "tx" : "rx", remaining);
 		remaining = 0;
 	}
 
@@ -206,12 +191,15 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
 	struct musb_hw_ep		*hw_ep = chdat->hw_ep;
 	void __iomem			*mbase = musb->mregs;
 	void __iomem			*ep_conf = hw_ep->conf;
-	dma_addr_t			fifo = hw_ep->fifo_sync;
-	struct omap_dma_channel_params	dma_params;
+	dma_addr_t			fifo_addr = hw_ep->fifo_sync;
 	u32				dma_remaining;
-	int				src_burst, dst_burst;
 	u16				csr;
 	struct tusb_dma_data		*dma_data;
+	struct dma_async_tx_descriptor	*dma_desc;
+	struct dma_slave_config		dma_cfg;
+	enum dma_transfer_direction	dma_dir;
+	u32				port_window;
+	int				ret;
 
 	if (unlikely(dma_addr & 0x1) || (len < 32) || (len > packet_sz))
 		return false;
@@ -237,10 +225,8 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
 
 	dma_remaining = TUSB_EP_CONFIG_XFR_SIZE(dma_remaining);
 	if (dma_remaining) {
-		dev_dbg(musb->controller, "Busy %s dma ch%i, not using: %08x\n",
-			chdat->tx ? "tx" : "rx",
-			chdat->dma_data ? chdat->dma_data->ch : -1,
-			dma_remaining);
+		dev_dbg(musb->controller, "Busy %s dma, not using: %08x\n",
+			chdat->tx ? "tx" : "rx", dma_remaining);
 		return false;
 	}
 
@@ -257,7 +243,7 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
 			dev_dbg(musb->controller, "could not get dma for ep%i\n", chdat->epnum);
 			return false;
 		}
-		if (dma_data->ch < 0) {
+		if (dma_data->dmareq < 0) {
 			/* REVISIT: This should get blocked earlier, happens
 			 * with MSC ErrorRecoveryTest
 			 */
@@ -266,8 +252,6 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
 		}
 	}
 
-	omap_set_dma_callback(dma_data->ch, tusb_omap_dma_cb, channel);
-
 	chdat->packet_sz = packet_sz;
 	chdat->len = len;
 	channel->actual_len = 0;
@@ -275,79 +259,68 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
 	channel->status = MUSB_DMA_STATUS_BUSY;
 
 	/* Since we're recycling dma areas, we need to clean or invalidate */
-	if (chdat->tx)
+	if (chdat->tx) {
+		dma_dir = DMA_MEM_TO_DEV;
 		dma_map_single(dev, phys_to_virt(dma_addr), len,
 				DMA_TO_DEVICE);
-	else
+	} else {
+		dma_dir = DMA_DEV_TO_MEM;
 		dma_map_single(dev, phys_to_virt(dma_addr), len,
 				DMA_FROM_DEVICE);
+	}
+
+	memset(&dma_cfg, 0, sizeof(dma_cfg));
 
 	/* Use 16-bit transfer if dma_addr is not 32-bit aligned */
 	if ((dma_addr & 0x3) == 0) {
-		dma_params.data_type = OMAP_DMA_DATA_TYPE_S32;
-		dma_params.elem_count = 8;		/* Elements in frame */
+		dma_cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+		dma_cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+		port_window = 8;
 	} else {
-		dma_params.data_type = OMAP_DMA_DATA_TYPE_S16;
-		dma_params.elem_count = 16;		/* Elements in frame */
-		fifo = hw_ep->fifo_async;
-	}
+		dma_cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
+		dma_cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
+		port_window = 16;
 
-	dma_params.frame_count	= chdat->transfer_len / 32; /* Burst sz frame */
+		fifo_addr = hw_ep->fifo_async;
+	}
 
-	dev_dbg(musb->controller, "ep%i %s dma ch%i dma: %pad len: %u(%u) packet_sz: %i(%i)\n",
-		chdat->epnum, chdat->tx ? "tx" : "rx",
-		dma_data->ch, &dma_addr, chdat->transfer_len, len,
-		chdat->transfer_packet_sz, packet_sz);
+	dev_dbg(musb->controller,
+		"ep%i %s dma: %pad len: %u(%u) packet_sz: %i(%i)\n",
+		chdat->epnum, chdat->tx ? "tx" : "rx", &dma_addr,
+		chdat->transfer_len, len, chdat->transfer_packet_sz, packet_sz);
+
+	dma_cfg.src_addr = fifo_addr;
+	dma_cfg.dst_addr = fifo_addr;
+	dma_cfg.src_port_window_size = port_window;
+	dma_cfg.src_maxburst = port_window;
+	dma_cfg.dst_port_window_size = port_window;
+	dma_cfg.dst_maxburst = port_window;
+
+	ret = dmaengine_slave_config(dma_data->chan, &dma_cfg);
+	if (ret) {
+		dev_err(musb->controller, "DMA slave config failed: %d\n", ret);
+		return false;
+	}
 
-	/*
-	 * Prepare omap DMA for transfer
-	 */
-	if (chdat->tx) {
-		dma_params.src_amode	= OMAP_DMA_AMODE_POST_INC;
-		dma_params.src_start	= (unsigned long)dma_addr;
-		dma_params.src_ei	= 0;
-		dma_params.src_fi	= 0;
-
-		dma_params.dst_amode	= OMAP_DMA_AMODE_DOUBLE_IDX;
-		dma_params.dst_start	= (unsigned long)fifo;
-		dma_params.dst_ei	= 1;
-		dma_params.dst_fi	= -31;	/* Loop 32 byte window */
-
-		dma_params.trigger	= dma_data->sync_dev;
-		dma_params.sync_mode	= OMAP_DMA_SYNC_FRAME;
-		dma_params.src_or_dst_synch	= 0;	/* Dest sync */
-
-		src_burst = OMAP_DMA_DATA_BURST_16;	/* 16x32 read */
-		dst_burst = OMAP_DMA_DATA_BURST_8;	/* 8x32 write */
-	} else {
-		dma_params.src_amode	= OMAP_DMA_AMODE_DOUBLE_IDX;
-		dma_params.src_start	= (unsigned long)fifo;
-		dma_params.src_ei	= 1;
-		dma_params.src_fi	= -31;	/* Loop 32 byte window */
-
-		dma_params.dst_amode	= OMAP_DMA_AMODE_POST_INC;
-		dma_params.dst_start	= (unsigned long)dma_addr;
-		dma_params.dst_ei	= 0;
-		dma_params.dst_fi	= 0;
-
-		dma_params.trigger	= dma_data->sync_dev;
-		dma_params.sync_mode	= OMAP_DMA_SYNC_FRAME;
-		dma_params.src_or_dst_synch	= 1;	/* Source sync */
-
-		src_burst = OMAP_DMA_DATA_BURST_8;	/* 8x32 read */
-		dst_burst = OMAP_DMA_DATA_BURST_16;	/* 16x32 write */
+	dma_desc = dmaengine_prep_slave_single(dma_data->chan, dma_addr,
+					chdat->transfer_len, dma_dir,
+					DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+	if (!dma_desc) {
+		dev_err(musb->controller, "DMA prep_slave_single failed\n");
+		return false;
 	}
 
-	dev_dbg(musb->controller, "ep%i %s using %i-bit %s dma from 0x%08lx to 0x%08lx\n",
+	dma_desc->callback = tusb_omap_dma_cb;
+	dma_desc->callback_param = channel;
+	dmaengine_submit(dma_desc);
+
+	dev_dbg(musb->controller,
+		"ep%i %s using %i-bit %s dma from %pad to %pad\n",
 		chdat->epnum, chdat->tx ? "tx" : "rx",
-		(dma_params.data_type == OMAP_DMA_DATA_TYPE_S32) ? 32 : 16,
+		dma_cfg.src_addr_width * 8,
 		((dma_addr & 0x3) == 0) ? "sync" : "async",
-		dma_params.src_start, dma_params.dst_start);
-
-	omap_set_dma_params(dma_data->ch, &dma_params);
-	omap_set_dma_src_burst_mode(dma_data->ch, src_burst);
-	omap_set_dma_dest_burst_mode(dma_data->ch, dst_burst);
-	omap_set_dma_write_mode(dma_data->ch, OMAP_DMA_WRITE_LAST_NON_POSTED);
+		(dma_dir == DMA_MEM_TO_DEV) ? &dma_addr : &fifo_addr,
+		(dma_dir == DMA_MEM_TO_DEV) ? &fifo_addr : &dma_addr);
 
 	/*
 	 * Prepare MUSB for DMA transfer
@@ -367,10 +340,8 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
 			csr | MUSB_RXCSR_P_WZC_BITS);
 	}
 
-	/*
-	 * Start DMA transfer
-	 */
-	omap_start_dma(dma_data->ch);
+	/* Start DMA transfer */
+	dma_async_issue_pending(dma_data->chan);
 
 	if (chdat->tx) {
 		/* Send transfer_packet_sz packets at a time */
@@ -400,7 +371,7 @@ static int tusb_omap_dma_abort(struct dma_channel *channel)
 	struct tusb_omap_dma_ch	*chdat = to_chdat(channel);
 
 	if (chdat->dma_data)
-		omap_stop_dma(chdat->dma_data->ch);
+		dmaengine_terminate_all(chdat->dma_data->chan);
 
 	channel->status = MUSB_DMA_STATUS_FREE;
 
@@ -510,11 +481,11 @@ tusb_omap_dma_allocate(struct dma_controller *c,
 
 	dma_data = chdat->dma_data;
 
-	dev_dbg(musb->controller, "ep%i %s dma: %s dma%i dmareq%i sync%i\n",
+	dev_dbg(musb->controller, "ep%i %s dma: %s dmareq%i\n",
 		chdat->epnum,
 		chdat->tx ? "tx" : "rx",
 		tusb_dma->multichannel ? "shared" : "dedicated",
-		dma_data->ch, dma_data->dmareq, dma_data->sync_dev);
+		dma_data->dmareq);
 
 	return channel;
 
@@ -532,12 +503,11 @@ static void tusb_omap_dma_release(struct dma_channel *channel)
 	struct tusb_omap_dma_ch	*chdat = to_chdat(channel);
 	struct musb		*musb = chdat->musb;
 
-	dev_dbg(musb->controller, "ep%i ch%i\n", chdat->epnum,
-		chdat->dma_data->ch);
+	dev_dbg(musb->controller, "Release for ep%i\n", chdat->epnum);
 
 	channel->status = MUSB_DMA_STATUS_UNKNOWN;
 
-	omap_stop_dma(chdat->dma_data->ch);
+	dmaengine_terminate_sync(chdat->dma_data->chan);
 	tusb_omap_dma_free_dmareq(chdat);
 
 	channel = NULL;
@@ -557,8 +527,8 @@ void tusb_dma_controller_destroy(struct dma_controller *c)
 		}
 
 		/* Free up the DMA channels */
-		if (tusb_dma && tusb_dma->dma_pool[i].ch >= 0)
-			omap_free_dma(tusb_dma->dma_pool[i].ch);
+		if (tusb_dma && tusb_dma->dma_pool[i].chan)
+			dma_release_channel(tusb_dma->dma_pool[i].chan);
 	}
 
 	kfree(tusb_dma);
@@ -567,16 +537,9 @@ EXPORT_SYMBOL_GPL(tusb_dma_controller_destroy);
 
 static int tusb_omap_allocate_dma_pool(struct tusb_omap_dma *tusb_dma)
 {
+	struct musb *musb = tusb_dma->controller.musb;
 	int i;
 	int ret = 0;
-	const int sync_dev[6] = {
-		OMAP24XX_DMA_EXT_DMAREQ0,
-		OMAP24XX_DMA_EXT_DMAREQ1,
-		OMAP242X_DMA_EXT_DMAREQ2,
-		OMAP242X_DMA_EXT_DMAREQ3,
-		OMAP242X_DMA_EXT_DMAREQ4,
-		OMAP242X_DMA_EXT_DMAREQ5,
-	};
 
 	for (i = 0; i < MAX_DMAREQ; i++) {
 		struct tusb_dma_data *dma_data = &tusb_dma->dma_pool[i];
@@ -590,22 +553,18 @@ static int tusb_omap_allocate_dma_pool(struct tusb_omap_dma *tusb_dma)
 			char ch_name[8];
 
 			sprintf(ch_name, "dmareq%d", i);
-			dma_data->sync_dev = sync_dev[i];
-			dma_data->ch = -1;
-			/* callback data is ngoing to be set later */
-			ret = omap_request_dma(dma_data->sync_dev, ch_name,
-					tusb_omap_dma_cb, NULL, &dma_data->ch);
-			if (ret != 0) {
-				dev_err(tusb_dma->controller.musb->controller,
+			dma_data->chan = dma_request_chan(musb->controller,
+							  ch_name);
+			if (IS_ERR(dma_data->chan)) {
+				dev_err(musb->controller,
 					"Failed to request %s\n", ch_name);
+				ret = PTR_ERR(dma_data->chan);
 				goto dma_error;
 			}
 
 			dma_data->dmareq = i;
 		} else {
 			dma_data->dmareq = -1;
-			dma_data->sync_dev = -1;
-			dma_data->ch = -1;
 		}
 	}
 
@@ -615,8 +574,8 @@ static int tusb_omap_allocate_dma_pool(struct tusb_omap_dma *tusb_dma)
 	for (; i >= 0; i--) {
 		struct tusb_dma_data *dma_data = &tusb_dma->dma_pool[i];
 
-		if (dma_data->ch >= 0)
-			omap_free_dma(dma_data->ch);
+		if (dma_data->dmareq >= 0)
+			dma_release_channel(dma_data->chan);
 	}
 
 	return ret;
-- 
2.12.2

[toc] | [prev] | [next] | [standalone]


#1638957

FromTony Lindgren <tony@atomide.com>
Date2017-05-10 18:40 +0200
Message-ID<tFCOC-31A-1@gated-at.bofh.it>
In reply to#1638661
* Peter Ujfalusi <peter.ujfalusi@ti.com> [170510 01:45]:
> The device would not boot to prompt most of the time before patch 5 (packet size
> reset fix).
> With that patch in, the device would boot up fine most of the cases, but will
> fail pretty fast with my stress test [1].
> After the first 9 patch the legacy DMA mode is going to be stable with g_ncm, it
> boots to prompt, and survives the stress test [1].

Best to merge that as a separate fix.

I already replied with acks to few patches, and for the entire
series please feel free to add:

Tested-by: Tony Lindgren <tony@atomide.com>

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web