All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH v2 00/10] usb: musb: tusb6010_omap: Convert to DMAengine
@ 2017-05-10  8:42 ` Peter Ujfalusi
  0 siblings, 0 replies; 38+ messages in thread
From: Peter Ujfalusi @ 2017-05-10  8:42 UTC (permalink / raw)
  To: b-liu, tony, gregkh, vinod.koul
  Cc: linux-usb, linux-omap, balbi, linux-kernel, dmaengine

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

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

* [PATCH v2 00/10] usb: musb: tusb6010_omap: Convert to DMAengine
@ 2017-05-10  8:42 ` Peter Ujfalusi
  0 siblings, 0 replies; 38+ messages in thread
From: Peter Ujfalusi @ 2017-05-10  8:42 UTC (permalink / raw)
  To: b-liu, tony, gregkh, vinod.koul
  Cc: linux-usb, linux-omap, balbi, linux-kernel, dmaengine

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

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

* [PATCH v2 01/10] dmaengine: omap-dma: port_window support correction for both direction
  2017-05-10  8:42 ` Peter Ujfalusi
@ 2017-05-10  8:42   ` Peter Ujfalusi
  -1 siblings, 0 replies; 38+ messages in thread
From: Peter Ujfalusi @ 2017-05-10  8:42 UTC (permalink / raw)
  To: b-liu, tony, gregkh, vinod.koul
  Cc: linux-usb, linux-omap, balbi, linux-kernel, Russell King,
	dmaengine, dan.j.williams

When the port_window support was verified it was done on setup where only
the MEM_TO_DEV direction was enabled. This got un-noticed and thus only
this direction worked.

Now that I have managed to get a setup to verify both direction it turned
out that the setup was incorrect:
omap_desc members are settings for the slave port while the omap_sg members
apply to the memory side of the sDMA setup.

Fixes: 527a27591312 ("dmaengine: omap-dma: Fix the port_window support")
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Cc: Russell King <linux@armlinux.org.uk>
Cc: dmaengine@vger.kernel.org
Cc: dan.j.williams@intel.com
Cc: vinod.koul@intel.com
---
 drivers/dma/omap-dma.c | 39 +++++++++++++++------------------------
 1 file changed, 15 insertions(+), 24 deletions(-)

diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index eed745a598fa..4fc86d40b50c 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -948,12 +948,6 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
 		return NULL;
 	}
 
-	/* When the port_window is used, one frame must cover the window */
-	if (port_window) {
-		burst = port_window;
-		port_window_bytes = port_window * es_bytes[es];
-	}
-
 	/* Now allocate and setup the descriptor. */
 	d = kzalloc(sizeof(*d) + sglen * sizeof(d->sg[0]), GFP_ATOMIC);
 	if (!d)
@@ -963,6 +957,21 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
 	d->dev_addr = dev_addr;
 	d->es = es;
 
+	/* When the port_window is used, one frame must cover the window */
+	if (port_window) {
+		burst = port_window;
+		port_window_bytes = port_window * es_bytes[es];
+
+		d->ei = 1;
+		/*
+		 * One frame covers the port_window and by  configure
+		 * the source frame index to be -1 * (port_window - 1)
+		 * we instruct the sDMA that after a frame is processed
+		 * it should move back to the start of the window.
+		 */
+		d->fi = -(port_window_bytes - 1);
+	}
+
 	d->ccr = c->ccr | CCR_SYNC_FRAME;
 	if (dir == DMA_DEV_TO_MEM) {
 		d->csdp = CSDP_DST_BURST_64 | CSDP_DST_PACKED;
@@ -987,14 +996,6 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
 		d->ccr |= CCR_SRC_AMODE_POSTINC;
 		if (port_window) {
 			d->ccr |= CCR_DST_AMODE_DBLIDX;
-			d->ei = 1;
-			/*
-			 * One frame covers the port_window and by  configure
-			 * the source frame index to be -1 * (port_window - 1)
-			 * we instruct the sDMA that after a frame is processed
-			 * it should move back to the start of the window.
-			 */
-			d->fi = -(port_window_bytes - 1);
 
 			if (port_window_bytes >= 64)
 				d->csdp |= CSDP_DST_BURST_64;
@@ -1050,16 +1051,6 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
 		osg->addr = sg_dma_address(sgent);
 		osg->en = en;
 		osg->fn = sg_dma_len(sgent) / frame_bytes;
-		if (port_window && dir == DMA_DEV_TO_MEM) {
-			osg->ei = 1;
-			/*
-			 * One frame covers the port_window and by  configure
-			 * the source frame index to be -1 * (port_window - 1)
-			 * we instruct the sDMA that after a frame is processed
-			 * it should move back to the start of the window.
-			 */
-			osg->fi = -(port_window_bytes - 1);
-		}
 
 		if (d->using_ll) {
 			osg->t2_desc = dma_pool_alloc(od->desc_pool, GFP_ATOMIC,
-- 
2.12.2

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

* [PATCH v2 01/10] dmaengine: omap-dma: port_window support correction for both direction
@ 2017-05-10  8:42   ` Peter Ujfalusi
  0 siblings, 0 replies; 38+ messages in thread
From: Peter Ujfalusi @ 2017-05-10  8:42 UTC (permalink / raw)
  To: b-liu, tony, gregkh, vinod.koul
  Cc: linux-usb, linux-omap, balbi, linux-kernel, Russell King,
	dmaengine, dan.j.williams

When the port_window support was verified it was done on setup where only
the MEM_TO_DEV direction was enabled. This got un-noticed and thus only
this direction worked.

Now that I have managed to get a setup to verify both direction it turned
out that the setup was incorrect:
omap_desc members are settings for the slave port while the omap_sg members
apply to the memory side of the sDMA setup.

Fixes: 527a27591312 ("dmaengine: omap-dma: Fix the port_window support")
Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
Cc: Russell King <linux@armlinux.org.uk>
Cc: dmaengine@vger.kernel.org
Cc: dan.j.williams@intel.com
Cc: vinod.koul@intel.com
---
 drivers/dma/omap-dma.c | 39 +++++++++++++++------------------------
 1 file changed, 15 insertions(+), 24 deletions(-)

diff --git a/drivers/dma/omap-dma.c b/drivers/dma/omap-dma.c
index eed745a598fa..4fc86d40b50c 100644
--- a/drivers/dma/omap-dma.c
+++ b/drivers/dma/omap-dma.c
@@ -948,12 +948,6 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
 		return NULL;
 	}
 
-	/* When the port_window is used, one frame must cover the window */
-	if (port_window) {
-		burst = port_window;
-		port_window_bytes = port_window * es_bytes[es];
-	}
-
 	/* Now allocate and setup the descriptor. */
 	d = kzalloc(sizeof(*d) + sglen * sizeof(d->sg[0]), GFP_ATOMIC);
 	if (!d)
@@ -963,6 +957,21 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
 	d->dev_addr = dev_addr;
 	d->es = es;
 
+	/* When the port_window is used, one frame must cover the window */
+	if (port_window) {
+		burst = port_window;
+		port_window_bytes = port_window * es_bytes[es];
+
+		d->ei = 1;
+		/*
+		 * One frame covers the port_window and by  configure
+		 * the source frame index to be -1 * (port_window - 1)
+		 * we instruct the sDMA that after a frame is processed
+		 * it should move back to the start of the window.
+		 */
+		d->fi = -(port_window_bytes - 1);
+	}
+
 	d->ccr = c->ccr | CCR_SYNC_FRAME;
 	if (dir == DMA_DEV_TO_MEM) {
 		d->csdp = CSDP_DST_BURST_64 | CSDP_DST_PACKED;
@@ -987,14 +996,6 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
 		d->ccr |= CCR_SRC_AMODE_POSTINC;
 		if (port_window) {
 			d->ccr |= CCR_DST_AMODE_DBLIDX;
-			d->ei = 1;
-			/*
-			 * One frame covers the port_window and by  configure
-			 * the source frame index to be -1 * (port_window - 1)
-			 * we instruct the sDMA that after a frame is processed
-			 * it should move back to the start of the window.
-			 */
-			d->fi = -(port_window_bytes - 1);
 
 			if (port_window_bytes >= 64)
 				d->csdp |= CSDP_DST_BURST_64;
@@ -1050,16 +1051,6 @@ static struct dma_async_tx_descriptor *omap_dma_prep_slave_sg(
 		osg->addr = sg_dma_address(sgent);
 		osg->en = en;
 		osg->fn = sg_dma_len(sgent) / frame_bytes;
-		if (port_window && dir == DMA_DEV_TO_MEM) {
-			osg->ei = 1;
-			/*
-			 * One frame covers the port_window and by  configure
-			 * the source frame index to be -1 * (port_window - 1)
-			 * we instruct the sDMA that after a frame is processed
-			 * it should move back to the start of the window.
-			 */
-			osg->fi = -(port_window_bytes - 1);
-		}
 
 		if (d->using_ll) {
 			osg->t2_desc = dma_pool_alloc(od->desc_pool, GFP_ATOMIC,
-- 
2.12.2

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

* [PATCH v2 02/10] usb: musb: Add quirk to avoid skb reserve in gadget mode
  2017-05-10  8:42 ` Peter Ujfalusi
@ 2017-05-10  8:42   ` Peter Ujfalusi
  -1 siblings, 0 replies; 38+ messages in thread
From: Peter Ujfalusi @ 2017-05-10  8:42 UTC (permalink / raw)
  To: b-liu, tony, gregkh, vinod.koul
  Cc: linux-usb, linux-omap, balbi, linux-kernel

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

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

* [PATCH v2 02/10] usb: musb: Add quirk to avoid skb reserve in gadget mode
@ 2017-05-10  8:42   ` Peter Ujfalusi
  0 siblings, 0 replies; 38+ messages in thread
From: Peter Ujfalusi @ 2017-05-10  8:42 UTC (permalink / raw)
  To: b-liu, tony, gregkh, vinod.koul
  Cc: linux-usb, linux-omap, balbi, linux-kernel

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

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

* [PATCH v2 03/10] usb: musb: tusb6010: Add MUSB_G_NO_SKB_RESERVE to quirks
  2017-05-10  8:42 ` Peter Ujfalusi
@ 2017-05-10  8:42   ` Peter Ujfalusi
  -1 siblings, 0 replies; 38+ messages in thread
From: Peter Ujfalusi @ 2017-05-10  8:42 UTC (permalink / raw)
  To: b-liu, tony, gregkh, vinod.koul
  Cc: linux-usb, linux-omap, balbi, linux-kernel

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

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

* [PATCH v2 03/10] usb: musb: tusb6010: Add MUSB_G_NO_SKB_RESERVE to quirks
@ 2017-05-10  8:42   ` Peter Ujfalusi
  0 siblings, 0 replies; 38+ messages in thread
From: Peter Ujfalusi @ 2017-05-10  8:42 UTC (permalink / raw)
  To: b-liu, tony, gregkh, vinod.koul
  Cc: linux-usb, linux-omap, balbi, linux-kernel

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

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

* [PATCH v2 04/10] usb: musb: tusb6010_omap: Use one musb_ep_select call in tusb_omap_dma_program
  2017-05-10  8:42 ` Peter Ujfalusi
@ 2017-05-10  8:42   ` Peter Ujfalusi
  -1 siblings, 0 replies; 38+ messages in thread
From: Peter Ujfalusi @ 2017-05-10  8:42 UTC (permalink / raw)
  To: b-liu, tony, gregkh, vinod.koul
  Cc: linux-usb, linux-omap, balbi, linux-kernel

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

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

* [PATCH v2 04/10] usb: musb: tusb6010_omap: Use one musb_ep_select call in tusb_omap_dma_program
@ 2017-05-10  8:42   ` Peter Ujfalusi
  0 siblings, 0 replies; 38+ messages in thread
From: Peter Ujfalusi @ 2017-05-10  8:42 UTC (permalink / raw)
  To: b-liu, tony, gregkh, vinod.koul
  Cc: linux-usb, linux-omap, balbi, linux-kernel

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

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

* [PATCH v2 05/10] usb: musb: tusb6010_omap: Do not reset the other direction's packet size
  2017-05-10  8:42 ` Peter Ujfalusi
@ 2017-05-10  8:42   ` Peter Ujfalusi
  -1 siblings, 0 replies; 38+ messages in thread
From: Peter Ujfalusi @ 2017-05-10  8:42 UTC (permalink / raw)
  To: b-liu, tony, gregkh, vinod.koul
  Cc: linux-usb, linux-omap, balbi, linux-kernel

We have one register for each EP to set the maximum packet size for both
TX and RX.
If for example an RX programming would happen before the previous TX
transfer finishes we would reset the TX packet side.

To fix this issue, only modify the TX or RX part of the register.

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

diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c
index db2e4c379ccf..4e1a6e4a61b8 100644
--- a/drivers/usb/musb/tusb6010_omap.c
+++ b/drivers/usb/musb/tusb6010_omap.c
@@ -389,15 +389,19 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
 
 	if (chdat->tx) {
 		/* Send transfer_packet_sz packets at a time */
-		musb_writel(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET,
-			chdat->transfer_packet_sz);
+		u32 psize = musb_readl(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET);
+		psize &= ~0x7ff;
+		psize |= chdat->transfer_packet_sz;
+		musb_writel(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET, psize);
 
 		musb_writel(ep_conf, TUSB_EP_TX_OFFSET,
 			TUSB_EP_CONFIG_XFR_SIZE(chdat->transfer_len));
 	} else {
 		/* Receive transfer_packet_sz packets at a time */
-		musb_writel(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET,
-			chdat->transfer_packet_sz << 16);
+		u32 psize = musb_readl(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET);
+		psize &= ~(0x7ff << 16);
+		psize |= (chdat->transfer_packet_sz << 16);
+		musb_writel(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET, psize);
 
 		musb_writel(ep_conf, TUSB_EP_RX_OFFSET,
 			TUSB_EP_CONFIG_XFR_SIZE(chdat->transfer_len));
-- 
2.12.2

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

* [PATCH v2 05/10] usb: musb: tusb6010_omap: Do not reset the other direction's packet size
@ 2017-05-10  8:42   ` Peter Ujfalusi
  0 siblings, 0 replies; 38+ messages in thread
From: Peter Ujfalusi @ 2017-05-10  8:42 UTC (permalink / raw)
  To: b-liu, tony, gregkh, vinod.koul
  Cc: linux-usb, linux-omap, balbi, linux-kernel

We have one register for each EP to set the maximum packet size for both
TX and RX.
If for example an RX programming would happen before the previous TX
transfer finishes we would reset the TX packet side.

To fix this issue, only modify the TX or RX part of the register.

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

diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c
index db2e4c379ccf..4e1a6e4a61b8 100644
--- a/drivers/usb/musb/tusb6010_omap.c
+++ b/drivers/usb/musb/tusb6010_omap.c
@@ -389,15 +389,19 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
 
 	if (chdat->tx) {
 		/* Send transfer_packet_sz packets at a time */
-		musb_writel(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET,
-			chdat->transfer_packet_sz);
+		u32 psize = musb_readl(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET);
+		psize &= ~0x7ff;
+		psize |= chdat->transfer_packet_sz;
+		musb_writel(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET, psize);
 
 		musb_writel(ep_conf, TUSB_EP_TX_OFFSET,
 			TUSB_EP_CONFIG_XFR_SIZE(chdat->transfer_len));
 	} else {
 		/* Receive transfer_packet_sz packets at a time */
-		musb_writel(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET,
-			chdat->transfer_packet_sz << 16);
+		u32 psize = musb_readl(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET);
+		psize &= ~(0x7ff << 16);
+		psize |= (chdat->transfer_packet_sz << 16);
+		musb_writel(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET, psize);
 
 		musb_writel(ep_conf, TUSB_EP_RX_OFFSET,
 			TUSB_EP_CONFIG_XFR_SIZE(chdat->transfer_len));
-- 
2.12.2

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

* [PATCH v2 06/10] usb: musb: tusb6010_omap: Create new struct for DMA data/parameters
  2017-05-10  8:42 ` Peter Ujfalusi
@ 2017-05-10  8:42   ` Peter Ujfalusi
  -1 siblings, 0 replies; 38+ messages in thread
From: Peter Ujfalusi @ 2017-05-10  8:42 UTC (permalink / raw)
  To: b-liu, tony, gregkh, vinod.koul
  Cc: linux-usb, linux-omap, balbi, linux-kernel

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

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

* [PATCH v2 06/10] usb: musb: tusb6010_omap: Create new struct for DMA data/parameters
@ 2017-05-10  8:42   ` Peter Ujfalusi
  0 siblings, 0 replies; 38+ messages in thread
From: Peter Ujfalusi @ 2017-05-10  8:42 UTC (permalink / raw)
  To: b-liu, tony, gregkh, vinod.koul
  Cc: linux-usb, linux-omap, balbi, linux-kernel

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

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

* [PATCH v2 07/10] usb: musb: tusb6010_omap: Allocate DMA channels upfront
@ 2017-05-10  8:42   ` Peter Ujfalusi
  0 siblings, 0 replies; 38+ messages in thread
From: Peter Ujfalusi @ 2017-05-10  8:42 UTC (permalink / raw)
  To: b-liu, tony, gregkh, vinod.koul
  Cc: linux-usb, linux-omap, balbi, linux-kernel

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

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

* [PATCH v2 07/10] usb: musb: tusb6010_omap: Allocate DMA channels upfront
@ 2017-05-10  8:42   ` Peter Ujfalusi
  0 siblings, 0 replies; 38+ messages in thread
From: Peter Ujfalusi @ 2017-05-10  8:42 UTC (permalink / raw)
  To: b-liu-l0cyMroinI0, tony-4v6yS6AI5VpBDgjK7y7TUQ,
	gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	vinod.koul-ral2JQCrhuEAvxtiuMwx3w
  Cc: linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, balbi-DgEjT+Ai2ygdnm+yROfE0A,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

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-l0cyMroinI0@public.gmane.org>
---
 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;

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

* [PATCH v2 08/10] usb: musb: tusb6010: Handle DMA TX completion in DMA callback as well
  2017-05-10  8:42 ` Peter Ujfalusi
@ 2017-05-10  8:42   ` Peter Ujfalusi
  -1 siblings, 0 replies; 38+ messages in thread
From: Peter Ujfalusi @ 2017-05-10  8:42 UTC (permalink / raw)
  To: b-liu, tony, gregkh, vinod.koul
  Cc: linux-usb, linux-omap, balbi, linux-kernel

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

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

* [PATCH v2 08/10] usb: musb: tusb6010: Handle DMA TX completion in DMA callback as well
@ 2017-05-10  8:42   ` Peter Ujfalusi
  0 siblings, 0 replies; 38+ messages in thread
From: Peter Ujfalusi @ 2017-05-10  8:42 UTC (permalink / raw)
  To: b-liu, tony, gregkh, vinod.koul
  Cc: linux-usb, linux-omap, balbi, linux-kernel

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

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

* [PATCH v2 09/10] ARM: OMAP2+: DMA: Add slave map entries for 24xx external request lines
  2017-05-10  8:42 ` Peter Ujfalusi
@ 2017-05-10  8:42   ` Peter Ujfalusi
  -1 siblings, 0 replies; 38+ messages in thread
From: Peter Ujfalusi @ 2017-05-10  8:42 UTC (permalink / raw)
  To: b-liu, tony, gregkh, vinod.koul
  Cc: linux-usb, linux-omap, balbi, linux-kernel

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

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

* [PATCH v2 09/10] ARM: OMAP2+: DMA: Add slave map entries for 24xx external request lines
@ 2017-05-10  8:42   ` Peter Ujfalusi
  0 siblings, 0 replies; 38+ messages in thread
From: Peter Ujfalusi @ 2017-05-10  8:42 UTC (permalink / raw)
  To: b-liu, tony, gregkh, vinod.koul
  Cc: linux-usb, linux-omap, balbi, linux-kernel

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

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

* [PATCH v2 10/10] usb: musb: tusb6010_omap: Convert to DMAengine API
  2017-05-10  8:42 ` Peter Ujfalusi
@ 2017-05-10  8:51   ` Peter Ujfalusi
  -1 siblings, 0 replies; 38+ messages in thread
From: Peter Ujfalusi @ 2017-05-10  8:51 UTC (permalink / raw)
  To: b-liu, tony, gregkh, vinod.koul
  Cc: linux-usb, linux-omap, balbi, linux-kernel

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

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

* [PATCH v2 10/10] usb: musb: tusb6010_omap: Convert to DMAengine API
@ 2017-05-10  8:51   ` Peter Ujfalusi
  0 siblings, 0 replies; 38+ messages in thread
From: Peter Ujfalusi @ 2017-05-10  8:51 UTC (permalink / raw)
  To: b-liu, tony, gregkh, vinod.koul
  Cc: linux-usb, linux-omap, balbi, linux-kernel

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

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

* Re: [PATCH v2 05/10] usb: musb: tusb6010_omap: Do not reset the other direction's packet size
@ 2017-05-10 16:28     ` Tony Lindgren
  0 siblings, 0 replies; 38+ messages in thread
From: Tony Lindgren @ 2017-05-10 16:28 UTC (permalink / raw)
  To: Peter Ujfalusi
  Cc: b-liu, gregkh, vinod.koul, linux-usb, linux-omap, balbi, linux-kernel

* Peter Ujfalusi <peter.ujfalusi@ti.com> [170510 01:45]:
> We have one register for each EP to set the maximum packet size for both
> TX and RX.
> If for example an RX programming would happen before the previous TX
> transfer finishes we would reset the TX packet side.
> 
> To fix this issue, only modify the TX or RX part of the register.

Oh this is a nice one. I think we've always had this.

Bin, care to merge this one as a fix? This should have:

Fixes: 550a7375fe72 ("USB: Add MUSB and TUSB support")
Tested-by: Tony Lindgren <tony@atomide.com>

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

* Re: [PATCH v2 05/10] usb: musb: tusb6010_omap: Do not reset the other direction's packet size
@ 2017-05-10 16:28     ` Tony Lindgren
  0 siblings, 0 replies; 38+ messages in thread
From: Tony Lindgren @ 2017-05-10 16:28 UTC (permalink / raw)
  To: Peter Ujfalusi
  Cc: b-liu-l0cyMroinI0, gregkh-hQyY1W1yCW8ekmWlsbkhG0B+6BGkLq7r,
	vinod.koul-ral2JQCrhuEAvxtiuMwx3w,
	linux-usb-u79uwXL29TY76Z2rM5mHXA,
	linux-omap-u79uwXL29TY76Z2rM5mHXA, balbi-DgEjT+Ai2ygdnm+yROfE0A,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA

* Peter Ujfalusi <peter.ujfalusi-l0cyMroinI0@public.gmane.org> [170510 01:45]:
> We have one register for each EP to set the maximum packet size for both
> TX and RX.
> If for example an RX programming would happen before the previous TX
> transfer finishes we would reset the TX packet side.
> 
> To fix this issue, only modify the TX or RX part of the register.

Oh this is a nice one. I think we've always had this.

Bin, care to merge this one as a fix? This should have:

Fixes: 550a7375fe72 ("USB: Add MUSB and TUSB support")
Tested-by: Tony Lindgren <tony-4v6yS6AI5VpBDgjK7y7TUQ@public.gmane.org>
--
To unsubscribe from this list: send the line "unsubscribe linux-usb" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

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

* Re: [PATCH v2 01/10] dmaengine: omap-dma: port_window support correction for both direction
  2017-05-10  8:42   ` Peter Ujfalusi
  (?)
@ 2017-05-10 16:28   ` Tony Lindgren
  -1 siblings, 0 replies; 38+ messages in thread
From: Tony Lindgren @ 2017-05-10 16:28 UTC (permalink / raw)
  To: Peter Ujfalusi
  Cc: b-liu, gregkh, vinod.koul, linux-usb, linux-omap, balbi,
	linux-kernel, Russell King, dmaengine, dan.j.williams

* Peter Ujfalusi <peter.ujfalusi@ti.com> [170510 01:45]:
> When the port_window support was verified it was done on setup where only
> the MEM_TO_DEV direction was enabled. This got un-noticed and thus only
> this direction worked.
> 
> Now that I have managed to get a setup to verify both direction it turned
> out that the setup was incorrect:
> omap_desc members are settings for the slave port while the omap_sg members
> apply to the memory side of the sDMA setup.
> 
> Fixes: 527a27591312 ("dmaengine: omap-dma: Fix the port_window support")
> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> Cc: Russell King <linux@armlinux.org.uk>
> Cc: dmaengine@vger.kernel.org
> Cc: dan.j.williams@intel.com
> Cc: vinod.koul@intel.com

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

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

* Re: [PATCH v2 09/10] ARM: OMAP2+: DMA: Add slave map entries for 24xx external request lines
  2017-05-10  8:42   ` Peter Ujfalusi
  (?)
@ 2017-05-10 16:30   ` Tony Lindgren
  -1 siblings, 0 replies; 38+ messages in thread
From: Tony Lindgren @ 2017-05-10 16:30 UTC (permalink / raw)
  To: Peter Ujfalusi
  Cc: b-liu, gregkh, vinod.koul, linux-usb, linux-omap, balbi, linux-kernel

* 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>

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

* Re: [PATCH v2 00/10] usb: musb: tusb6010_omap: Convert to DMAengine
  2017-05-10  8:42 ` Peter Ujfalusi
                   ` (10 preceding siblings ...)
  (?)
@ 2017-05-10 16:32 ` Tony Lindgren
  -1 siblings, 0 replies; 38+ messages in thread
From: Tony Lindgren @ 2017-05-10 16:32 UTC (permalink / raw)
  To: Peter Ujfalusi
  Cc: b-liu, gregkh, vinod.koul, linux-usb, linux-omap, balbi,
	linux-kernel, dmaengine

* 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>

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

* Re: [PATCH v2 05/10] usb: musb: tusb6010_omap: Do not reset the other direction's packet size
  2017-05-10  8:42   ` Peter Ujfalusi
@ 2017-05-10 17:07     ` Bin Liu
  -1 siblings, 0 replies; 38+ messages in thread
From: Bin Liu @ 2017-05-10 17:07 UTC (permalink / raw)
  To: Peter Ujfalusi
  Cc: tony, gregkh, vinod.koul, linux-usb, linux-omap, balbi, linux-kernel

Hi,

On Wed, May 10, 2017 at 11:42:27AM +0300, Peter Ujfalusi wrote:
> We have one register for each EP to set the maximum packet size for both
> TX and RX.
> If for example an RX programming would happen before the previous TX
> transfer finishes we would reset the TX packet side.
> 
> To fix this issue, only modify the TX or RX part of the register.
> 
> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> ---
>  drivers/usb/musb/tusb6010_omap.c | 12 ++++++++----
>  1 file changed, 8 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c
> index db2e4c379ccf..4e1a6e4a61b8 100644
> --- a/drivers/usb/musb/tusb6010_omap.c
> +++ b/drivers/usb/musb/tusb6010_omap.c
> @@ -389,15 +389,19 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
>  
>  	if (chdat->tx) {
>  		/* Send transfer_packet_sz packets at a time */
> -		musb_writel(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET,
> -			chdat->transfer_packet_sz);
> +		u32 psize = musb_readl(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET);

checkpatch.pl complains about declaration and assignment together.

> +		psize &= ~0x7ff;
> +		psize |= chdat->transfer_packet_sz;
> +		musb_writel(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET, psize);
>  
>  		musb_writel(ep_conf, TUSB_EP_TX_OFFSET,
>  			TUSB_EP_CONFIG_XFR_SIZE(chdat->transfer_len));
>  	} else {
>  		/* Receive transfer_packet_sz packets at a time */
> -		musb_writel(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET,
> -			chdat->transfer_packet_sz << 16);
> +		u32 psize = musb_readl(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET);

and at here too.

> +		psize &= ~(0x7ff << 16);
> +		psize |= (chdat->transfer_packet_sz << 16);
> +		musb_writel(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET, psize);
>  
>  		musb_writel(ep_conf, TUSB_EP_RX_OFFSET,
>  			TUSB_EP_CONFIG_XFR_SIZE(chdat->transfer_len));

Regards,
-Bin.

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

* Re: [PATCH v2 05/10] usb: musb: tusb6010_omap: Do not reset the other direction's packet size
@ 2017-05-10 17:07     ` Bin Liu
  0 siblings, 0 replies; 38+ messages in thread
From: Bin Liu @ 2017-05-10 17:07 UTC (permalink / raw)
  To: Peter Ujfalusi
  Cc: tony, gregkh, vinod.koul, linux-usb, linux-omap, balbi, linux-kernel

Hi,

On Wed, May 10, 2017 at 11:42:27AM +0300, Peter Ujfalusi wrote:
> We have one register for each EP to set the maximum packet size for both
> TX and RX.
> If for example an RX programming would happen before the previous TX
> transfer finishes we would reset the TX packet side.
> 
> To fix this issue, only modify the TX or RX part of the register.
> 
> Signed-off-by: Peter Ujfalusi <peter.ujfalusi@ti.com>
> ---
>  drivers/usb/musb/tusb6010_omap.c | 12 ++++++++----
>  1 file changed, 8 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c
> index db2e4c379ccf..4e1a6e4a61b8 100644
> --- a/drivers/usb/musb/tusb6010_omap.c
> +++ b/drivers/usb/musb/tusb6010_omap.c
> @@ -389,15 +389,19 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
>  
>  	if (chdat->tx) {
>  		/* Send transfer_packet_sz packets at a time */
> -		musb_writel(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET,
> -			chdat->transfer_packet_sz);
> +		u32 psize = musb_readl(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET);

checkpatch.pl complains about declaration and assignment together.

> +		psize &= ~0x7ff;
> +		psize |= chdat->transfer_packet_sz;
> +		musb_writel(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET, psize);
>  
>  		musb_writel(ep_conf, TUSB_EP_TX_OFFSET,
>  			TUSB_EP_CONFIG_XFR_SIZE(chdat->transfer_len));
>  	} else {
>  		/* Receive transfer_packet_sz packets at a time */
> -		musb_writel(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET,
> -			chdat->transfer_packet_sz << 16);
> +		u32 psize = musb_readl(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET);

and at here too.

> +		psize &= ~(0x7ff << 16);
> +		psize |= (chdat->transfer_packet_sz << 16);
> +		musb_writel(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET, psize);
>  
>  		musb_writel(ep_conf, TUSB_EP_RX_OFFSET,
>  			TUSB_EP_CONFIG_XFR_SIZE(chdat->transfer_len));

Regards,
-Bin.

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

* Re: [PATCH v2 05/10] usb: musb: tusb6010_omap: Do not reset the other direction's packet size
  2017-05-10 17:07     ` Bin Liu
  (?)
@ 2017-05-10 23:16     ` Joe Perches
  2017-05-11  6:19         ` Peter Ujfalusi
  -1 siblings, 1 reply; 38+ messages in thread
From: Joe Perches @ 2017-05-10 23:16 UTC (permalink / raw)
  To: Bin Liu, Peter Ujfalusi
  Cc: tony, gregkh, vinod.koul, linux-usb, linux-omap, balbi, linux-kernel

On Wed, 2017-05-10 at 12:07 -0500, Bin Liu wrote:
> On Wed, May 10, 2017 at 11:42:27AM +0300, Peter Ujfalusi wrote:
> > We have one register for each EP to set the maximum packet size for both
> > TX and RX.
> > If for example an RX programming would happen before the previous TX
> > transfer finishes we would reset the TX packet side.
> > 
> > To fix this issue, only modify the TX or RX part of the register.
[]
> > diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c
[]
> > @@ -389,15 +389,19 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
> >  
> >  	if (chdat->tx) {
> >  		/* Send transfer_packet_sz packets at a time */
> > -		musb_writel(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET,
> > -			chdat->transfer_packet_sz);
> > +		u32 psize = musb_readl(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET);
> 
> checkpatch.pl complains about declaration and assignment together.

No it doesn't.

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

* Re: [PATCH v2 05/10] usb: musb: tusb6010_omap: Do not reset the other direction's packet size
  2017-05-10 23:16     ` Joe Perches
@ 2017-05-11  6:19         ` Peter Ujfalusi
  0 siblings, 0 replies; 38+ messages in thread
From: Peter Ujfalusi @ 2017-05-11  6:19 UTC (permalink / raw)
  To: Joe Perches, Bin Liu
  Cc: tony, gregkh, vinod.koul, linux-usb, linux-omap, balbi, linux-kernel



On 2017-05-11 02:16, Joe Perches wrote:
> On Wed, 2017-05-10 at 12:07 -0500, Bin Liu wrote:
>> On Wed, May 10, 2017 at 11:42:27AM +0300, Peter Ujfalusi wrote:
>>> We have one register for each EP to set the maximum packet size for both
>>> TX and RX.
>>> If for example an RX programming would happen before the previous TX
>>> transfer finishes we would reset the TX packet side.
>>>
>>> To fix this issue, only modify the TX or RX part of the register.
> []
>>> diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c
> []
>>> @@ -389,15 +389,19 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
>>>   
>>>   	if (chdat->tx) {
>>>   		/* Send transfer_packet_sz packets at a time */
>>> -		musb_writel(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET,
>>> -			chdat->transfer_packet_sz);
>>> +		u32 psize = musb_readl(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET);
>>
>> checkpatch.pl complains about declaration and assignment together.
> 
> No it doesn't.

It 'only' complains about:
WARNING: Missing a blank line after declarations

which is valid.

- Péter

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

* Re: [PATCH v2 05/10] usb: musb: tusb6010_omap: Do not reset the other direction's packet size
@ 2017-05-11  6:19         ` Peter Ujfalusi
  0 siblings, 0 replies; 38+ messages in thread
From: Peter Ujfalusi @ 2017-05-11  6:19 UTC (permalink / raw)
  To: Joe Perches, Bin Liu
  Cc: tony, gregkh, vinod.koul, linux-usb, linux-omap, balbi, linux-kernel



On 2017-05-11 02:16, Joe Perches wrote:
> On Wed, 2017-05-10 at 12:07 -0500, Bin Liu wrote:
>> On Wed, May 10, 2017 at 11:42:27AM +0300, Peter Ujfalusi wrote:
>>> We have one register for each EP to set the maximum packet size for both
>>> TX and RX.
>>> If for example an RX programming would happen before the previous TX
>>> transfer finishes we would reset the TX packet side.
>>>
>>> To fix this issue, only modify the TX or RX part of the register.
> []
>>> diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c
> []
>>> @@ -389,15 +389,19 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
>>>   
>>>   	if (chdat->tx) {
>>>   		/* Send transfer_packet_sz packets at a time */
>>> -		musb_writel(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET,
>>> -			chdat->transfer_packet_sz);
>>> +		u32 psize = musb_readl(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET);
>>
>> checkpatch.pl complains about declaration and assignment together.
> 
> No it doesn't.

It 'only' complains about:
WARNING: Missing a blank line after declarations

which is valid.

- Péter

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

* Re: [PATCH v2 05/10] usb: musb: tusb6010_omap: Do not reset the other direction's packet size
  2017-05-11  6:19         ` Peter Ujfalusi
@ 2017-05-11 14:12           ` Bin Liu
  -1 siblings, 0 replies; 38+ messages in thread
From: Bin Liu @ 2017-05-11 14:12 UTC (permalink / raw)
  To: Peter Ujfalusi
  Cc: Joe Perches, tony, gregkh, vinod.koul, linux-usb, linux-omap,
	balbi, linux-kernel

On Thu, May 11, 2017 at 09:19:17AM +0300, Peter Ujfalusi wrote:
> 
> 
> On 2017-05-11 02:16, Joe Perches wrote:
> >On Wed, 2017-05-10 at 12:07 -0500, Bin Liu wrote:
> >>On Wed, May 10, 2017 at 11:42:27AM +0300, Peter Ujfalusi wrote:
> >>>We have one register for each EP to set the maximum packet size for both
> >>>TX and RX.
> >>>If for example an RX programming would happen before the previous TX
> >>>transfer finishes we would reset the TX packet side.
> >>>
> >>>To fix this issue, only modify the TX or RX part of the register.
> >[]
> >>>diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c
> >[]
> >>>@@ -389,15 +389,19 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
> >>>  	if (chdat->tx) {
> >>>  		/* Send transfer_packet_sz packets at a time */
> >>>-		musb_writel(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET,
> >>>-			chdat->transfer_packet_sz);
> >>>+		u32 psize = musb_readl(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET);
> >>
> >>checkpatch.pl complains about declaration and assignment together.
> >
> >No it doesn't.
> 
> It 'only' complains about:
> WARNING: Missing a blank line after declarations

It was it. My bad, I was multi-tasking and didn't read the log
carefully.

> 
> which is valid.

So will you update the patch to move the declaration to the beginning of
the function to avoid this WARNING. I would just fix it locally if you
prefer.

Regards,
-Bin.

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

* Re: [PATCH v2 05/10] usb: musb: tusb6010_omap: Do not reset the other direction's packet size
@ 2017-05-11 14:12           ` Bin Liu
  0 siblings, 0 replies; 38+ messages in thread
From: Bin Liu @ 2017-05-11 14:12 UTC (permalink / raw)
  To: Peter Ujfalusi
  Cc: Joe Perches, tony, gregkh, vinod.koul, linux-usb, linux-omap,
	balbi, linux-kernel

On Thu, May 11, 2017 at 09:19:17AM +0300, Peter Ujfalusi wrote:
> 
> 
> On 2017-05-11 02:16, Joe Perches wrote:
> >On Wed, 2017-05-10 at 12:07 -0500, Bin Liu wrote:
> >>On Wed, May 10, 2017 at 11:42:27AM +0300, Peter Ujfalusi wrote:
> >>>We have one register for each EP to set the maximum packet size for both
> >>>TX and RX.
> >>>If for example an RX programming would happen before the previous TX
> >>>transfer finishes we would reset the TX packet side.
> >>>
> >>>To fix this issue, only modify the TX or RX part of the register.
> >[]
> >>>diff --git a/drivers/usb/musb/tusb6010_omap.c b/drivers/usb/musb/tusb6010_omap.c
> >[]
> >>>@@ -389,15 +389,19 @@ static int tusb_omap_dma_program(struct dma_channel *channel, u16 packet_sz,
> >>>  	if (chdat->tx) {
> >>>  		/* Send transfer_packet_sz packets at a time */
> >>>-		musb_writel(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET,
> >>>-			chdat->transfer_packet_sz);
> >>>+		u32 psize = musb_readl(ep_conf, TUSB_EP_MAX_PACKET_SIZE_OFFSET);
> >>
> >>checkpatch.pl complains about declaration and assignment together.
> >
> >No it doesn't.
> 
> It 'only' complains about:
> WARNING: Missing a blank line after declarations

It was it. My bad, I was multi-tasking and didn't read the log
carefully.

> 
> which is valid.

So will you update the patch to move the declaration to the beginning of
the function to avoid this WARNING. I would just fix it locally if you
prefer.

Regards,
-Bin.

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

* Re: [PATCH v2 05/10] usb: musb: tusb6010_omap: Do not reset the other direction's packet size
  2017-05-11 14:12           ` Bin Liu
@ 2017-05-12  6:53             ` Peter Ujfalusi
  -1 siblings, 0 replies; 38+ messages in thread
From: Peter Ujfalusi @ 2017-05-12  6:53 UTC (permalink / raw)
  To: Bin Liu, Joe Perches, tony, gregkh, vinod.koul, linux-usb,
	linux-omap, balbi, linux-kernel

Bin,

On 2017-05-11 17:12, Bin Liu wrote:
>> which is valid.
> 
> So will you update the patch to move the declaration to the beginning of
> the function to avoid this WARNING. I would just fix it locally if you
> prefer.

I was waiting for Vinod or someone from the DMAengine guys to say 
something for the first patch to send the v3, but I guess I can do it 
right away.

- Péter

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

* Re: [PATCH v2 05/10] usb: musb: tusb6010_omap: Do not reset the other direction's packet size
@ 2017-05-12  6:53             ` Peter Ujfalusi
  0 siblings, 0 replies; 38+ messages in thread
From: Peter Ujfalusi @ 2017-05-12  6:53 UTC (permalink / raw)
  To: Bin Liu, Joe Perches, tony, gregkh, vinod.koul, linux-usb,
	linux-omap, balbi, linux-kernel

Bin,

On 2017-05-11 17:12, Bin Liu wrote:
>> which is valid.
> 
> So will you update the patch to move the declaration to the beginning of
> the function to avoid this WARNING. I would just fix it locally if you
> prefer.

I was waiting for Vinod or someone from the DMAengine guys to say 
something for the first patch to send the v3, but I guess I can do it 
right away.

- Péter

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

* Re: [PATCH v2 05/10] usb: musb: tusb6010_omap: Do not reset the other direction's packet size
  2017-05-12  6:53             ` Peter Ujfalusi
@ 2017-05-12 12:07               ` Bin Liu
  -1 siblings, 0 replies; 38+ messages in thread
From: Bin Liu @ 2017-05-12 12:07 UTC (permalink / raw)
  To: Peter Ujfalusi
  Cc: Joe Perches, tony, gregkh, vinod.koul, linux-usb, linux-omap,
	balbi, linux-kernel

On Fri, May 12, 2017 at 09:53:55AM +0300, Peter Ujfalusi wrote:
> Bin,
> 
> On 2017-05-11 17:12, Bin Liu wrote:
> >>which is valid.
> >
> >So will you update the patch to move the declaration to the beginning of
> >the function to avoid this WARNING. I would just fix it locally if you
> >prefer.
> 
> I was waiting for Vinod or someone from the DMAengine guys to say
> something for the first patch to send the v3, but I guess I can do
> it right away.

Yeah, this patch can go to the -rc in next week, but the rest will go to
-next, so you can send this patch seperately.

Regards,
-Bin.

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

* Re: [PATCH v2 05/10] usb: musb: tusb6010_omap: Do not reset the other direction's packet size
@ 2017-05-12 12:07               ` Bin Liu
  0 siblings, 0 replies; 38+ messages in thread
From: Bin Liu @ 2017-05-12 12:07 UTC (permalink / raw)
  To: Peter Ujfalusi
  Cc: Joe Perches, tony, gregkh, vinod.koul, linux-usb, linux-omap,
	balbi, linux-kernel

On Fri, May 12, 2017 at 09:53:55AM +0300, Peter Ujfalusi wrote:
> Bin,
> 
> On 2017-05-11 17:12, Bin Liu wrote:
> >>which is valid.
> >
> >So will you update the patch to move the declaration to the beginning of
> >the function to avoid this WARNING. I would just fix it locally if you
> >prefer.
> 
> I was waiting for Vinod or someone from the DMAengine guys to say
> something for the first patch to send the v3, but I guess I can do
> it right away.

Yeah, this patch can go to the -rc in next week, but the rest will go to
-next, so you can send this patch seperately.

Regards,
-Bin.

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

end of thread, other threads:[~2017-05-12 12:09 UTC | newest]

Thread overview: 38+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2017-05-10  8:42 [PATCH v2 00/10] usb: musb: tusb6010_omap: Convert to DMAengine Peter Ujfalusi
2017-05-10  8:42 ` Peter Ujfalusi
2017-05-10  8:42 ` [PATCH v2 01/10] dmaengine: omap-dma: port_window support correction for both direction Peter Ujfalusi
2017-05-10  8:42   ` Peter Ujfalusi
2017-05-10 16:28   ` Tony Lindgren
2017-05-10  8:42 ` [PATCH v2 02/10] usb: musb: Add quirk to avoid skb reserve in gadget mode Peter Ujfalusi
2017-05-10  8:42   ` Peter Ujfalusi
2017-05-10  8:42 ` [PATCH v2 03/10] usb: musb: tusb6010: Add MUSB_G_NO_SKB_RESERVE to quirks Peter Ujfalusi
2017-05-10  8:42   ` Peter Ujfalusi
2017-05-10  8:42 ` [PATCH v2 04/10] usb: musb: tusb6010_omap: Use one musb_ep_select call in tusb_omap_dma_program Peter Ujfalusi
2017-05-10  8:42   ` Peter Ujfalusi
2017-05-10  8:42 ` [PATCH v2 05/10] usb: musb: tusb6010_omap: Do not reset the other direction's packet size Peter Ujfalusi
2017-05-10  8:42   ` Peter Ujfalusi
2017-05-10 16:28   ` Tony Lindgren
2017-05-10 16:28     ` Tony Lindgren
2017-05-10 17:07   ` Bin Liu
2017-05-10 17:07     ` Bin Liu
2017-05-10 23:16     ` Joe Perches
2017-05-11  6:19       ` Peter Ujfalusi
2017-05-11  6:19         ` Peter Ujfalusi
2017-05-11 14:12         ` Bin Liu
2017-05-11 14:12           ` Bin Liu
2017-05-12  6:53           ` Peter Ujfalusi
2017-05-12  6:53             ` Peter Ujfalusi
2017-05-12 12:07             ` Bin Liu
2017-05-12 12:07               ` Bin Liu
2017-05-10  8:42 ` [PATCH v2 06/10] usb: musb: tusb6010_omap: Create new struct for DMA data/parameters Peter Ujfalusi
2017-05-10  8:42   ` Peter Ujfalusi
2017-05-10  8:42 ` [PATCH v2 07/10] usb: musb: tusb6010_omap: Allocate DMA channels upfront Peter Ujfalusi
2017-05-10  8:42   ` Peter Ujfalusi
2017-05-10  8:42 ` [PATCH v2 08/10] usb: musb: tusb6010: Handle DMA TX completion in DMA callback as well Peter Ujfalusi
2017-05-10  8:42   ` Peter Ujfalusi
2017-05-10  8:42 ` [PATCH v2 09/10] ARM: OMAP2+: DMA: Add slave map entries for 24xx external request lines Peter Ujfalusi
2017-05-10  8:42   ` Peter Ujfalusi
2017-05-10 16:30   ` Tony Lindgren
2017-05-10  8:51 ` [PATCH v2 10/10] usb: musb: tusb6010_omap: Convert to DMAengine API Peter Ujfalusi
2017-05-10  8:51   ` Peter Ujfalusi
2017-05-10 16:32 ` [PATCH v2 00/10] usb: musb: tusb6010_omap: Convert to DMAengine Tony Lindgren

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.