[PATCH 10/10] dma: imx-sdma: extract sdma_set_buffer_descriptor()

Joshua Clayton stillcompiling at gmail.com
Mon Jun 15 09:21:45 PDT 2015


extract common per/buffer descriptor setup
from dma prep functions

Signed-off-by: Joshua Clayton <stillcompiling at gmail.com>
---
 drivers/dma/imx-sdma.c | 111 ++++++++++++++++++++++++-------------------------
 1 file changed, 54 insertions(+), 57 deletions(-)

diff --git a/drivers/dma/imx-sdma.c b/drivers/dma/imx-sdma.c
index dfebef9..13a3574 100644
--- a/drivers/dma/imx-sdma.c
+++ b/drivers/dma/imx-sdma.c
@@ -1046,6 +1046,50 @@ int sdma_prep_common(struct sdma_channel *sdmac, int buf_count,
 	return sdma_load_context(sdmac);
 }
 
+int sdma_set_buffer_descriptor(struct sdma_channel *sdmac,
+		struct sdma_buffer_descriptor *bd, u32 addr,
+		int len, u32 status)
+{
+	struct sdma_engine *sdma = to_sdma_engine(sdmac);
+
+	bd->buffer_addr = addr;
+
+	if (len > 0xffff) {
+		dev_err(sdma->dev, "SDMA channel %d: maximum buffer description size exceeded: %d > %d\n",
+			sdmac->channel, len, 0xffff);
+		return -EINVAL;
+	}
+
+	bd->mode.count = len;
+
+	switch (sdmac->word_size) {
+	case DMA_SLAVE_BUSWIDTH_4_BYTES:
+		bd->mode.command = 0;
+		if (len & 3 || addr & 3)
+			return -EFAULT;
+		break;
+	case DMA_SLAVE_BUSWIDTH_2_BYTES:
+		bd->mode.command = 2;
+		if (len & 1 || addr & 1)
+			return -EFAULT;
+		break;
+	case DMA_SLAVE_BUSWIDTH_1_BYTE:
+		bd->mode.command = 1;
+		break;
+	default:
+		return -EFAULT;
+	}
+
+	dev_dbg(sdma->dev, "count: %d dma: %#llx %s%s\n",
+			len, (u64)addr,
+			status & BD_WRAP ? "wrap" : "",
+			status & BD_INTR ? " intr" : "");
+
+	bd->mode.status = status;
+
+	return 0;
+}
+
 static void sdma_free_chan_resources(struct dma_chan *chan)
 {
 	struct sdma_channel *sdmac = to_sdma_chan(chan);
@@ -1077,7 +1121,7 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg(
 {
 	struct sdma_channel *sdmac = to_sdma_chan(chan);
 	struct sdma_engine *sdma = to_sdma_engine(sdmac);
-	int ret, i, count;
+	int ret, i;
 	int channel = sdmac->channel;
 	struct scatterlist *sg;
 
@@ -1090,41 +1134,9 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg(
 
 	sdmac->chn_count = 0;
 	for_each_sg(sgl, sg, sg_len, i) {
-		struct sdma_buffer_descriptor *bd = &sdmac->bd[i];
 		int param;
 
-		bd->buffer_addr = sg->dma_address;
-
-		count = sg_dma_len(sg);
-
-		if (count > 0xffff) {
-			dev_err(sdma->dev, "SDMA channel %d: maximum bytes for sg entry exceeded: %d > %d\n",
-					channel, count, 0xffff);
-			ret = -EINVAL;
-			goto err_out;
-		}
-
-		bd->mode.count = count;
-		sdmac->chn_count += count;
-
-		switch (sdmac->word_size) {
-		case DMA_SLAVE_BUSWIDTH_4_BYTES:
-			bd->mode.command = 0;
-			if (count & 3 || sg->dma_address & 3)
-				return NULL;
-			break;
-		case DMA_SLAVE_BUSWIDTH_2_BYTES:
-			bd->mode.command = 2;
-			if (count & 1 || sg->dma_address & 1)
-				return NULL;
-			break;
-		case DMA_SLAVE_BUSWIDTH_1_BYTE:
-			bd->mode.command = 1;
-			break;
-		default:
-			return NULL;
-		}
-
+		sdmac->chn_count += sg_dma_len(sg);
 		param = BD_DONE | BD_EXTD | BD_CONT;
 
 		if (i + 1 == sg_len) {
@@ -1133,12 +1145,10 @@ static struct dma_async_tx_descriptor *sdma_prep_slave_sg(
 			param &= ~BD_CONT;
 		}
 
-		dev_dbg(sdma->dev, "entry %d: count: %d dma: %#llx %s%s\n",
-				i, count, (u64)sg->dma_address,
-				param & BD_WRAP ? "wrap" : "",
-				param & BD_INTR ? " intr" : "");
-
-		bd->mode.status = param;
+		ret = sdma_set_buffer_descriptor(sdmac, &sdmac->bd[i],
+				sg->dma_address, sg_dma_len(sg), param);
+		if (ret)
+			goto err_out;
 	}
 
 	sdma->channel_control[channel].current_bd_ptr = sdmac->bd_phys;
@@ -1167,28 +1177,15 @@ static struct dma_async_tx_descriptor *sdma_prep_dma_cyclic(
 	sdmac->flags |= IMX_DMA_SG_LOOP;
 
 	for (i = 0; i < num_periods; i++) {
-		struct sdma_buffer_descriptor *bd = &sdmac->bd[i];
 		int param;
-
-		bd->buffer_addr = dma_addr;
-
-		bd->mode.count = period_len;
-
-		if (sdmac->word_size == DMA_SLAVE_BUSWIDTH_4_BYTES)
-			bd->mode.command = 0;
-		else
-			bd->mode.command = sdmac->word_size;
-
 		param = BD_DONE | BD_EXTD | BD_CONT | BD_INTR;
 		if (i + 1 == num_periods)
 			param |= BD_WRAP;
 
-		dev_dbg(sdma->dev, "entry %d: count: %d dma: %#llx %s%s\n",
-				i, period_len, (u64)dma_addr,
-				param & BD_WRAP ? "wrap" : "",
-				param & BD_INTR ? " intr" : "");
-
-		bd->mode.status = param;
+		ret = sdma_set_buffer_descriptor(sdmac, &sdmac->bd[i],
+				dma_addr, sdmac->period_len, param);
+		if (ret)
+			goto err_out;
 
 		dma_addr += period_len;
 	}
-- 
2.1.4




More information about the linux-arm-kernel mailing list