Skip to contentSkip to conversation

Device Tree binding for the 'mv_xor' XOR engine DMA driver

PATCH New Thomas Petazzoni 3 participants 36 messages Nov 15, 2012 – Nov 19, 2012

Subsystems (5)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 Device Tree binding for the 'mv_xor' XOR engine DMA driver

Hello,

This patch set adds a Device Tree binding for the Marvell XOR engine driver, which allows to support these XOR engines in the Armada 370 and Armada XP SoCs.

As one can immediatly see, this Device Tree binding patch set is not as simple as most Device Tree bindings additions. This is due to the fact that the mv_xor driver has a fairly odd organization. Instead of registering a single platform_driver having platform_device structures being instantiated together with platform_data structures describing their specificities, this driver was organized around *two* platform_driver:

* One platform_driver named 'mv_xor_shared', for which one device was registered for each XOR engine (usually two in each Marvell SoC)

* One platform_driver named 'mv_xor', for which one device was registered for each XOR channel (usually two per XOR engine). When those devices were registered, they contained a reference to the corresponding 'mv_xor_shared' device.

This unusual organization is:

* useless, because the channels description can just as well be passed through platform_data of the 'mv_xor_shared' driver.

* annoying, as it prevents the addition of a simple Device Tree binding for the driver.

Therefore, before adding the Device Tree binding, we cleanup and reorganize the driver so that it registers a single platform_driver.

The patch set is organized as follows:

* Patch 1 and 2 are basic cleanups, not really important.

* Patch 3 to 8 are needed to remove the 'mv_xor' platform_driver. Instead of doing that as one big patch, we do it progressively, in small chunks, where each chunk builds and runs properly on the hardware.

- Patch 3 moves the channel registration/cleanup logic into separate utility functions, so that they can be used for both the old-style probing (through the 'mv_xor' sub-driver) and the new-style probing (through platform_data passed to the main 'mv_xor_shared' driver).

- Patch 4 adds the possibility of registering channels through platform_data passed to the 'mv_xor_shared' main driver.

- Patch 5 and Patch 6 respectively convert the XOR0 and XOR1 engine registrations to the new style probing.

- Patch 7 removes some code that became useless in the process.

- Patch 8 removes the sub-driver 'mv_xor'.

* Patch 8 to 26 are further cleanups to the driver, mainly fixing the following problems:

- All reference to the notion of 'shared' driver are removed.

- The mv_xor driver registers one DMA engine and one DMA channel per XOR channel, because the different XOR channels in a given XOR engine have different capabilities. However, the mv_xor driver was internally keeping two structures having a 1:1
mapping: mv_xor_device and mv_xor_chan, which was useless. We progressively convert the driver so that mv_xor_device represents one XOR engine, and mv_xor_chan represents one XOR channel.

- Removing useless properties from the platform_data in order to simplify the Device Tree binding.

* Patch 27 is a bug fix for the removal path, but it isn't very important as the driver cannot be compiled as a module.

* Patch 28 adds the Device Tree binding itself and its documentation.

* Patch 29 adds the Device Tree data to register the XOR engines on Armada 370/XP SoCs. Not Device Tree data is needed at the board level since those devices are purely internal to the SoC.

The resulting patch set is fully bisectable, and has been tested with the built-in XOR engine self-test of the driver on both a Kirkwood platform and a Armada XP platform.

The code is also available in the 'mvebu-xor' branch in the following Git repository:

git at github.com:MISL-EBU-System-SW/mainline-public.git

Note that PATCH 29 requires the clk patches from Gr?gory Clement for the Armada 370/XP SoCs, which have already been Ack'ed, but not merged yet.

Best regards,

Thomas

#1 lore raw

PATCH 1/29 mv_xor: use dev_(err|info|notice) instead of dev_printk

The usage of dev_printk() is deprecated, and the dev_err(), dev_info() and dev_notice() functions should be used instead.

---
 drivers/dma/mv_xor.c |   60 +++++++++++++++++++++++++-------------------------
 1 file changed, 30 insertions(+), 30 deletions(-)
drivers/dma/mv_xor.c +30 -30
index e362e2b..610d0b8 100644
@@ -206,9 +206,9 @@ static void mv_set_mode(struct mv_xor_chan *chan,
 		op_mode = XOR_OPERATION_MODE_MEMSET;
 		break;
 	default:
-		dev_printk(KERN_ERR, chan->device->common.dev,
-			   "error: unsupported operation %d.\n",
-			   type);
+		dev_err(chan->device->common.dev,
+			"error: unsupported operation %d.\n",
+			type);
 		BUG();
 		return;
 	}
@@ -828,28 +828,28 @@ static void mv_dump_xor_regs(struct mv_xor_chan *chan)
 	u32 val;
 
 	val = __raw_readl(XOR_CONFIG(chan));
-	dev_printk(KERN_ERR, chan->device->common.dev,
-		   "config       0x%08x.\n", val);
+	dev_err(chan->device->common.dev,
+		"config       0x%08x.\n", val);
 
 	val = __raw_readl(XOR_ACTIVATION(chan));
-	dev_printk(KERN_ERR, chan->device->common.dev,
-		   "activation   0x%08x.\n", val);
+	dev_err(chan->device->common.dev,
+		"activation   0x%08x.\n", val);
 
 	val = __raw_readl(XOR_INTR_CAUSE(chan));
-	dev_printk(KERN_ERR, chan->device->common.dev,
-		   "intr cause   0x%08x.\n", val);
+	dev_err(chan->device->common.dev,
+		"intr cause   0x%08x.\n", val);
 
 	val = __raw_readl(XOR_INTR_MASK(chan));
-	dev_printk(KERN_ERR, chan->device->common.dev,
-		   "intr mask    0x%08x.\n", val);
+	dev_err(chan->device->common.dev,
+		"intr mask    0x%08x.\n", val);
 
 	val = __raw_readl(XOR_ERROR_CAUSE(chan));
-	dev_printk(KERN_ERR, chan->device->common.dev,
-		   "error cause  0x%08x.\n", val);
+	dev_err(chan->device->common.dev,
+		"error cause  0x%08x.\n", val);
 
 	val = __raw_readl(XOR_ERROR_ADDR(chan));
-	dev_printk(KERN_ERR, chan->device->common.dev,
-		   "error addr   0x%08x.\n", val);
+	dev_err(chan->device->common.dev,
+		"error addr   0x%08x.\n", val);
 }
 
 static void mv_xor_err_interrupt_handler(struct mv_xor_chan *chan,
@@ -861,9 +861,9 @@ static void mv_xor_err_interrupt_handler(struct mv_xor_chan *chan,
 	     return;
 	}
 
-	dev_printk(KERN_ERR, chan->device->common.dev,
-		   "error on chan %d. intr cause 0x%08x.\n",
-		   chan->idx, intr_cause);
+	dev_err(chan->device->common.dev,
+		"error on chan %d. intr cause 0x%08x.\n",
+		chan->idx, intr_cause);
 
 	mv_dump_xor_regs(chan);
 	BUG();
@@ -950,8 +950,8 @@ static int __devinit mv_xor_memcpy_self_test(struct mv_xor_device *device)
 
 	if (mv_xor_status(dma_chan, cookie, NULL) !=
 	    DMA_SUCCESS) {
-		dev_printk(KERN_ERR, dma_chan->device->dev,
-			   "Self-test copy timed out, disabling\n");
+		dev_err(dma_chan->device->dev,
+			"Self-test copy timed out, disabling\n");
 		err = -ENODEV;
 		goto free_resources;
 	}
@@ -960,8 +960,8 @@ static int __devinit mv_xor_memcpy_self_test(struct mv_xor_device *device)
 	dma_sync_single_for_cpu(&mv_chan->device->pdev->dev, dest_dma,
 				MV_XOR_TEST_SIZE, DMA_FROM_DEVICE);
 	if (memcmp(src, dest, MV_XOR_TEST_SIZE)) {
-		dev_printk(KERN_ERR, dma_chan->device->dev,
-			   "Self-test copy failed compare, disabling\n");
+		dev_err(dma_chan->device->dev,
+			"Self-test copy failed compare, disabling\n");
 		err = -ENODEV;
 		goto free_resources;
 	}
@@ -1048,8 +1048,8 @@ mv_xor_xor_self_test(struct mv_xor_device *device)
 
 	if (mv_xor_status(dma_chan, cookie, NULL) !=
 	    DMA_SUCCESS) {
-		dev_printk(KERN_ERR, dma_chan->device->dev,
-			   "Self-test xor timed out, disabling\n");
+		dev_err(dma_chan->device->dev,
+			"Self-test xor timed out, disabling\n");
 		err = -ENODEV;
 		goto free_resources;
 	}
@@ -1060,10 +1060,10 @@ mv_xor_xor_self_test(struct mv_xor_device *device)
 	for (i = 0; i < (PAGE_SIZE / sizeof(u32)); i++) {
 		u32 *ptr = page_address(dest);
 		if (ptr[i] != cmp_word) {
-			dev_printk(KERN_ERR, dma_chan->device->dev,
-				   "Self-test xor failed compare, disabling."
-				   " index %d, data %x, expected %x\n", i,
-				   ptr[i], cmp_word);
+			dev_err(dma_chan->device->dev,
+				"Self-test xor failed compare, disabling."
+				" index %d, data %x, expected %x\n", i,
+				ptr[i], cmp_word);
 			err = -ENODEV;
 			goto free_resources;
 		}
@@ -1212,7 +1212,7 @@ static int __devinit mv_xor_probe(struct platform_device *pdev)
 			goto err_free_dma;
 	}
 
-	dev_printk(KERN_INFO, &pdev->dev, "Marvell XOR: "
+	dev_info(&pdev->dev, "Marvell XOR: "
 	  "( %s%s%s%s)\n",
 	  dma_has_cap(DMA_XOR, dma_dev->cap_mask) ? "xor " : "",
 	  dma_has_cap(DMA_MEMSET, dma_dev->cap_mask)  ? "fill " : "",
@@ -1275,7 +1275,7 @@ static int mv_xor_shared_probe(struct platform_device *pdev)
 	struct mv_xor_shared_private *msp;
 	struct resource *res;
 
-	dev_printk(KERN_NOTICE, &pdev->dev, "Marvell shared XOR driver\n");
+	dev_notice(&pdev->dev, "Marvell shared XOR driver\n");
 
 	msp = devm_kzalloc(&pdev->dev, sizeof(*msp), GFP_KERNEL);
 	if (!msp)
Signature · 1 line
1.7.9.5
#2 lore raw

PATCH 2/29 mv_xor: do not use pool_size from platform_data within the driver

In reply to Thomas Petazzoni

The driver currently pokes into the platform_data structure during its normal operation to get the pool_size value. Poking into the platform_data structure is not nice when moving to the Device Tree, so this commit adds a new pool_size field in the mv_xor_device structure, which gets initialized at ->probe() time. The driver then uses this field instead of the platform_data.

---
 drivers/dma/mv_xor.c |   10 ++++------
 drivers/dma/mv_xor.h |    1 +
 2 files changed, 5 insertions(+), 6 deletions(-)
drivers/dma/mv_xor.c +4 -6
index 610d0b8..7042772 100644
@@ -604,9 +604,7 @@ static int mv_xor_alloc_chan_resources(struct dma_chan *chan)
 	int idx;
 	struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan);
 	struct mv_xor_desc_slot *slot = NULL;
-	struct mv_xor_platform_data *plat_data =
-		mv_chan->device->pdev->dev.platform_data;
-	int num_descs_in_pool = plat_data->pool_size/MV_XOR_SLOT_SIZE;
+	int num_descs_in_pool = mv_chan->device->pool_size/MV_XOR_SLOT_SIZE;
 
 	/* Allocate descriptor slots */
 	idx = mv_chan->slots_allocated;
@@ -1084,11 +1082,10 @@ static int __devexit mv_xor_remove(struct platform_device *dev)
 	struct mv_xor_device *device = platform_get_drvdata(dev);
 	struct dma_chan *chan, *_chan;
 	struct mv_xor_chan *mv_chan;
-	struct mv_xor_platform_data *plat_data = dev->dev.platform_data;
 
 	dma_async_device_unregister(&device->common);
 
-	dma_free_coherent(&dev->dev, plat_data->pool_size,
+	dma_free_coherent(&dev->dev, device->pool_size,
 			device->dma_desc_pool_virt, device->dma_desc_pool);
 
 	list_for_each_entry_safe(chan, _chan, &device->common.channels,
@@ -1120,8 +1117,9 @@ static int __devinit mv_xor_probe(struct platform_device *pdev)
 	 * note: writecombine gives slightly better performance, but
 	 * requires that we explicitly flush the writes
 	 */
+	adev->pool_size = plat_data->pool_size;
 	adev->dma_desc_pool_virt = dma_alloc_writecombine(&pdev->dev,
-							  plat_data->pool_size,
+							  adev->pool_size,
 							  &adev->dma_desc_pool,
 							  GFP_KERNEL);
 	if (!adev->dma_desc_pool_virt)
drivers/dma/mv_xor.h +1 -0
index a5b422f..a0641ae 100644
@@ -72,6 +72,7 @@ struct mv_xor_device {
 	int				id;
 	dma_addr_t			dma_desc_pool;
 	void				*dma_desc_pool_virt;
+	size_t                          pool_size;
 	struct dma_device		common;
 	struct mv_xor_shared_private	*shared;
 };
Signature · 1 line
1.7.9.5
#3 lore raw

PATCH 3/29 mv_xor: split initialization/cleanup of XOR channels

In reply to Thomas Petazzoni

Instead of doing the initialization/cleanup of the XOR channels directly in the ->probe() and ->remove() hooks, we create separate utility functions mv_xor_channel_add() and mv_xor_channel_remove().

This will allow to easily introduce in a future patch a different way of registering XOR channels: instead of having one platform_device per channel, we'll trigger the registration of all XOR channels of a given XOR engine directly from the XOR engine ->probe() function.

---
 drivers/dma/mv_xor.c |   75 ++++++++++++++++++++++++++++++++------------------
 1 file changed, 48 insertions(+), 27 deletions(-)
drivers/dma/mv_xor.c +48 -27
index 7042772..312e611 100644
@@ -1077,19 +1077,18 @@ out:
 	return err;
 }
 
-static int __devexit mv_xor_remove(struct platform_device *dev)
+static int __devexit mv_xor_channel_remove(struct mv_xor_device *device)
 {
-	struct mv_xor_device *device = platform_get_drvdata(dev);
 	struct dma_chan *chan, *_chan;
 	struct mv_xor_chan *mv_chan;
 
 	dma_async_device_unregister(&device->common);
 
-	dma_free_coherent(&dev->dev, device->pool_size,
-			device->dma_desc_pool_virt, device->dma_desc_pool);
+	dma_free_coherent(&device->pdev->dev, device->pool_size,
+			  device->dma_desc_pool_virt, device->dma_desc_pool);
 
 	list_for_each_entry_safe(chan, _chan, &device->common.channels,
-				device_node) {
+				 device_node) {
 		mv_chan = to_mv_xor_chan(chan);
 		list_del(&chan->device_node);
 	}
@@ -1097,19 +1096,20 @@ static int __devexit mv_xor_remove(struct platform_device *dev)
 	return 0;
 }
 
-static int __devinit mv_xor_probe(struct platform_device *pdev)
+static struct mv_xor_device * __devinit
+mv_xor_channel_add(struct mv_xor_shared_private *msp,
+		   struct platform_device *pdev,
+		   int hw_id, dma_cap_mask_t cap_mask,
+		   size_t pool_size, int irq)
 {
 	int ret = 0;
-	int irq;
 	struct mv_xor_device *adev;
 	struct mv_xor_chan *mv_chan;
 	struct dma_device *dma_dev;
-	struct mv_xor_platform_data *plat_data = pdev->dev.platform_data;
-
 
 	adev = devm_kzalloc(&pdev->dev, sizeof(*adev), GFP_KERNEL);
 	if (!adev)
-		return -ENOMEM;
+		return ERR_PTR(-ENOMEM);
 
 	dma_dev = &adev->common;
 
@@ -1117,22 +1117,20 @@ static int __devinit mv_xor_probe(struct platform_device *pdev)
 	 * note: writecombine gives slightly better performance, but
 	 * requires that we explicitly flush the writes
 	 */
-	adev->pool_size = plat_data->pool_size;
+	adev->pool_size = pool_size;
 	adev->dma_desc_pool_virt = dma_alloc_writecombine(&pdev->dev,
 							  adev->pool_size,
 							  &adev->dma_desc_pool,
 							  GFP_KERNEL);
 	if (!adev->dma_desc_pool_virt)
-		return -ENOMEM;
+		return ERR_PTR(-ENOMEM);
 
-	adev->id = plat_data->hw_id;
+	adev->id = hw_id;
 
 	/* discover transaction capabilites from the platform data */
-	dma_dev->cap_mask = plat_data->cap_mask;
+	dma_dev->cap_mask = cap_mask;
 	adev->pdev = pdev;
-	platform_set_drvdata(pdev, adev);
-
-	adev->shared = platform_get_drvdata(plat_data->shared);
+	adev->shared = msp;
 
 	INIT_LIST_HEAD(&dma_dev->channels);
 
@@ -1159,7 +1157,7 @@ static int __devinit mv_xor_probe(struct platform_device *pdev)
 		goto err_free_dma;
 	}
 	mv_chan->device = adev;
-	mv_chan->idx = plat_data->hw_id;
+	mv_chan->idx = hw_id;
 	mv_chan->mmr_base = adev->shared->xor_base;
 
 	if (!mv_chan->mmr_base) {
@@ -1172,11 +1170,6 @@ static int __devinit mv_xor_probe(struct platform_device *pdev)
 	/* clear errors before enabling interrupts */
 	mv_xor_device_clear_err_status(mv_chan);
 
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0) {
-		ret = irq;
-		goto err_free_dma;
-	}
 	ret = devm_request_irq(&pdev->dev, irq,
 			       mv_xor_interrupt_handler,
 			       0, dev_name(&pdev->dev), mv_chan);
@@ -1218,13 +1211,41 @@ static int __devinit mv_xor_probe(struct platform_device *pdev)
 	  dma_has_cap(DMA_INTERRUPT, dma_dev->cap_mask) ? "intr " : "");
 
 	dma_async_device_register(dma_dev);
-	goto out;
+	return adev;
 
  err_free_dma:
-	dma_free_coherent(&adev->pdev->dev, plat_data->pool_size,
+	dma_free_coherent(&adev->pdev->dev, pool_size,
 			adev->dma_desc_pool_virt, adev->dma_desc_pool);
- out:
-	return ret;
+	return ERR_PTR(ret);
+}
+
+static int __devexit mv_xor_remove(struct platform_device *pdev)
+{
+	struct mv_xor_device *device = platform_get_drvdata(pdev);
+	return mv_xor_channel_remove(device);
+}
+
+static int __devinit mv_xor_probe(struct platform_device *pdev)
+{
+	struct mv_xor_platform_data *plat_data = pdev->dev.platform_data;
+	struct mv_xor_shared_private *msp =
+		platform_get_drvdata(plat_data->shared);
+	struct mv_xor_device *mv_xor_device;
+	int irq;
+
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		return irq;
+
+	mv_xor_device = mv_xor_channel_add(msp, pdev, plat_data->hw_id,
+					   plat_data->cap_mask,
+					   plat_data->pool_size, irq);
+	if (IS_ERR(mv_xor_device))
+		return PTR_ERR(mv_xor_device);
+
+	platform_set_drvdata(pdev, mv_xor_device);
+
+	return 0;
 }
 
 static void
Signature · 1 line
1.7.9.5
#4 lore raw

PATCH 4/29 mv_xor: allow channels to be registered directly from the main device

In reply to Thomas Petazzoni

Extend the XOR engine driver (currently called "mv_xor_shared") so that XOR channels can be passed in the platform_data structure, and be registered from there.

This will allow the users of the driver to be converted to the single platform_driver variant of the mv_xor driver.

---
 drivers/dma/mv_xor.c                     |   45 ++++++++++++++++++++++++++++++
 drivers/dma/mv_xor.h                     |    8 ++++--
 include/linux/platform_data/dma-mv_xor.h |    3 ++
 3 files changed, 53 insertions(+), 3 deletions(-)
drivers/dma/mv_xor.c +45 -0
index 312e611..3eaa0b2 100644
@@ -1292,7 +1292,9 @@ static int mv_xor_shared_probe(struct platform_device *pdev)
 {
 	const struct mbus_dram_target_info *dram;
 	struct mv_xor_shared_private *msp;
+	struct mv_xor_shared_platform_data *pdata = pdev->dev.platform_data;
 	struct resource *res;
+	int i, ret;
 
 	dev_notice(&pdev->dev, "Marvell shared XOR driver\n");
 
@@ -1334,12 +1336,55 @@ static int mv_xor_shared_probe(struct platform_device *pdev)
 	if (!IS_ERR(msp->clk))
 		clk_prepare_enable(msp->clk);
 
+	if (pdata && pdata->channels) {
+		for (i = 0; i < MV_XOR_MAX_CHANNELS; i++) {
+			struct mv_xor_platform_data *cd;
+			int irq;
+
+			cd = &pdata->channels[i];
+			if (!cd) {
+				ret = -ENODEV;
+				goto err_channel_add;
+			}
+
+			irq = platform_get_irq(pdev, i);
+			if (irq < 0) {
+				ret = irq;
+				goto err_channel_add;
+			}
+
+			msp->channels[i] =
+				mv_xor_channel_add(msp, pdev, cd->hw_id,
+						   cd->cap_mask,
+						   cd->pool_size, irq);
+			if (IS_ERR(msp->channels[i])) {
+				ret = PTR_ERR(msp->channels[i]);
+				goto err_channel_add;
+			}
+		}
+	}
+
 	return 0;
+
+err_channel_add:
+	for (i = 0; i < MV_XOR_MAX_CHANNELS; i++)
+		if (msp->channels[i])
+			mv_xor_channel_remove(msp->channels[i]);
+
+	clk_disable_unprepare(msp->clk);
+	clk_put(msp->clk);
+	return ret;
 }
 
 static int mv_xor_shared_remove(struct platform_device *pdev)
 {
 	struct mv_xor_shared_private *msp = platform_get_drvdata(pdev);
+	int i;
+
+	for (i = 0; i < MV_XOR_MAX_CHANNELS; i++) {
+		if (msp->channels[i])
+			mv_xor_channel_remove(msp->channels[i]);
+	}
 
 	if (!IS_ERR(msp->clk)) {
 		clk_disable_unprepare(msp->clk);
drivers/dma/mv_xor.h +5 -3
index a0641ae..686575f 100644
@@ -26,6 +26,7 @@
 #define USE_TIMER
 #define MV_XOR_SLOT_SIZE		64
 #define MV_XOR_THRESHOLD		1
+#define MV_XOR_MAX_CHANNELS             2
 
 #define XOR_OPERATION_MODE_XOR		0
 #define XOR_OPERATION_MODE_MEMCPY	2
@@ -53,9 +54,10 @@
 #define WINDOW_BAR_ENABLE(chan)	(0x240 + ((chan) << 2))
 
 struct mv_xor_shared_private {
-	void __iomem	*xor_base;
-	void __iomem	*xor_high_base;
-	struct clk	*clk;
+	void __iomem	     *xor_base;
+	void __iomem	     *xor_high_base;
+	struct clk	     *clk;
+	struct mv_xor_device *channels[MV_XOR_MAX_CHANNELS];
 };
 
 
include/linux/platform_data/dma-mv_xor.h +3 -0
index 2ba1f7d..f2aed97 100644
@@ -20,5 +20,8 @@ struct mv_xor_platform_data {
 	size_t				pool_size;
 };
 
+struct mv_xor_shared_platform_data {
+	struct mv_xor_platform_data    *channels;
+};
 
 #endif
Signature · 1 line
1.7.9.5
#5 lore raw

PATCH 5/29 arm: plat-orion: convert the registration of the xor0 engine to the single driver

In reply to Thomas Petazzoni

Instead of registering one 'mv_xor_shared' device for the XOR engine, and then two 'mv_xor' devices for the XOR channels, pass the channels properties as platform_data for the main 'mv_xor_shared' device.

---
 arch/arm/plat-orion/common.c |   94 +++++++++++++++++++-----------------------
 1 file changed, 42 insertions(+), 52 deletions(-)
arch/arm/plat-orion/common.c +42 -52
index b8a688c..800af19 100644
@@ -636,61 +636,43 @@ static struct resource orion_xor0_shared_resources[] = {
 	}, {
 		.name	= "xor 0 high",
 		.flags	= IORESOURCE_MEM,
+	}, {
+		.name   = "irq channel 0",
+		.flags  = IORESOURCE_IRQ,
+	}, {
+		.name   = "irq channel 1",
+		.flags  = IORESOURCE_IRQ,
 	},
 };
 
-static struct platform_device orion_xor0_shared = {
-	.name		= MV_XOR_SHARED_NAME,
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(orion_xor0_shared_resources),
-	.resource	= orion_xor0_shared_resources,
-};
-
-static struct resource orion_xor00_resources[] = {
-	[0] = {
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct mv_xor_platform_data orion_xor00_data = {
-	.shared		= &orion_xor0_shared,
-	.hw_id		= 0,
-	.pool_size	= PAGE_SIZE,
-};
+static struct platform_device orion_xor0_shared;
 
-static struct platform_device orion_xor00_channel = {
-	.name		= MV_XOR_NAME,
-	.id		= 0,
-	.num_resources	= ARRAY_SIZE(orion_xor00_resources),
-	.resource	= orion_xor00_resources,
-	.dev		= {
-		.dma_mask		= &orion_xor_dmamask,
-		.coherent_dma_mask	= DMA_BIT_MASK(64),
-		.platform_data		= &orion_xor00_data,
+static struct mv_xor_platform_data orion_xor0_channels_pdata[2] = {
+	{
+		.shared		= &orion_xor0_shared,
+		.hw_id		= 0,
+		.pool_size	= PAGE_SIZE,
 	},
-};
-
-static struct resource orion_xor01_resources[] = {
-	[0] = {
-		.flags	= IORESOURCE_IRQ,
+	{
+		.shared		= &orion_xor0_shared,
+		.hw_id		= 1,
+		.pool_size	= PAGE_SIZE,
 	},
 };
 
-static struct mv_xor_platform_data orion_xor01_data = {
-	.shared		= &orion_xor0_shared,
-	.hw_id		= 1,
-	.pool_size	= PAGE_SIZE,
+static struct mv_xor_shared_platform_data orion_xor0_pdata = {
+	.channels = orion_xor0_channels_pdata,
 };
 
-static struct platform_device orion_xor01_channel = {
-	.name		= MV_XOR_NAME,
-	.id		= 1,
-	.num_resources	= ARRAY_SIZE(orion_xor01_resources),
-	.resource	= orion_xor01_resources,
-	.dev		= {
-		.dma_mask		= &orion_xor_dmamask,
-		.coherent_dma_mask	= DMA_BIT_MASK(64),
-		.platform_data		= &orion_xor01_data,
+static struct platform_device orion_xor0_shared = {
+	.name		= MV_XOR_SHARED_NAME,
+	.id		= 0,
+	.num_resources	= ARRAY_SIZE(orion_xor0_shared_resources),
+	.resource	= orion_xor0_shared_resources,
+	.dev            = {
+		.dma_mask               = &orion_xor_dmamask,
+		.coherent_dma_mask      = DMA_BIT_MASK(64),
+		.platform_data          = &orion_xor0_pdata,
 	},
 };
 
@@ -704,15 +686,23 @@ void __init orion_xor0_init(unsigned long mapbase_low,
 	orion_xor0_shared_resources[1].start = mapbase_high;
 	orion_xor0_shared_resources[1].end = mapbase_high + 0xff;
 
-	orion_xor00_resources[0].start = irq_0;
-	orion_xor00_resources[0].end = irq_0;
-	orion_xor01_resources[0].start = irq_1;
-	orion_xor01_resources[0].end = irq_1;
+	orion_xor0_shared_resources[2].start = irq_0;
+	orion_xor0_shared_resources[2].end = irq_0;
+	orion_xor0_shared_resources[3].start = irq_1;
+	orion_xor0_shared_resources[3].end = irq_1;
 
-	platform_device_register(&orion_xor0_shared);
+	/*
+	 * two engines can't do memset simultaneously, this limitation
+	 * satisfied by removing memset support from one of the engines.
+	 */
+	dma_cap_set(DMA_MEMCPY, orion_xor0_channels_pdata[0].cap_mask);
+	dma_cap_set(DMA_XOR, orion_xor0_channels_pdata[0].cap_mask);
 
-	orion_xor_init_channels(&orion_xor00_data, &orion_xor00_channel,
-				&orion_xor01_data, &orion_xor01_channel);
+	dma_cap_set(DMA_MEMSET, orion_xor0_channels_pdata[1].cap_mask);
+	dma_cap_set(DMA_MEMCPY, orion_xor0_channels_pdata[1].cap_mask);
+	dma_cap_set(DMA_XOR, orion_xor0_channels_pdata[1].cap_mask);
+
+	platform_device_register(&orion_xor0_shared);
 }
 
 /*****************************************************************************
Signature · 1 line
1.7.9.5
#6 lore raw

PATCH 6/29 arm: plat-orion: convert the registration of the xor1 engine to the single driver

In reply to Thomas Petazzoni

Instead of registering one 'mv_xor_shared' device for the XOR engine, and then two 'mv_xor' devices for the XOR channels, pass the channels properties as platform_data for the main 'mv_xor_shared' device.

---
 arch/arm/plat-orion/common.c |   94 +++++++++++++++++++-----------------------
 1 file changed, 42 insertions(+), 52 deletions(-)
arch/arm/plat-orion/common.c +42 -52
index 800af19..afbbb97 100644
@@ -715,61 +715,43 @@ static struct resource orion_xor1_shared_resources[] = {
 	}, {
 		.name	= "xor 1 high",
 		.flags	= IORESOURCE_MEM,
+	}, {
+		.name   = "irq channel 0",
+		.flags  = IORESOURCE_IRQ,
+	}, {
+		.name   = "irq channel 1",
+		.flags  = IORESOURCE_IRQ,
 	},
 };
 
-static struct platform_device orion_xor1_shared = {
-	.name		= MV_XOR_SHARED_NAME,
-	.id		= 1,
-	.num_resources	= ARRAY_SIZE(orion_xor1_shared_resources),
-	.resource	= orion_xor1_shared_resources,
-};
-
-static struct resource orion_xor10_resources[] = {
-	[0] = {
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct mv_xor_platform_data orion_xor10_data = {
-	.shared		= &orion_xor1_shared,
-	.hw_id		= 0,
-	.pool_size	= PAGE_SIZE,
-};
+static struct platform_device orion_xor1_shared;
 
-static struct platform_device orion_xor10_channel = {
-	.name		= MV_XOR_NAME,
-	.id		= 2,
-	.num_resources	= ARRAY_SIZE(orion_xor10_resources),
-	.resource	= orion_xor10_resources,
-	.dev		= {
-		.dma_mask		= &orion_xor_dmamask,
-		.coherent_dma_mask	= DMA_BIT_MASK(64),
-		.platform_data		= &orion_xor10_data,
+static struct mv_xor_platform_data orion_xor1_channels_pdata[2] = {
+	{
+		.shared		= &orion_xor1_shared,
+		.hw_id		= 0,
+		.pool_size	= PAGE_SIZE,
 	},
-};
-
-static struct resource orion_xor11_resources[] = {
-	[0] = {
-		.flags	= IORESOURCE_IRQ,
+	{
+		.shared		= &orion_xor1_shared,
+		.hw_id		= 1,
+		.pool_size	= PAGE_SIZE,
 	},
 };
 
-static struct mv_xor_platform_data orion_xor11_data = {
-	.shared		= &orion_xor1_shared,
-	.hw_id		= 1,
-	.pool_size	= PAGE_SIZE,
+static struct mv_xor_shared_platform_data orion_xor1_pdata = {
+	.channels = orion_xor1_channels_pdata,
 };
 
-static struct platform_device orion_xor11_channel = {
-	.name		= MV_XOR_NAME,
-	.id		= 3,
-	.num_resources	= ARRAY_SIZE(orion_xor11_resources),
-	.resource	= orion_xor11_resources,
-	.dev		= {
-		.dma_mask		= &orion_xor_dmamask,
-		.coherent_dma_mask	= DMA_BIT_MASK(64),
-		.platform_data		= &orion_xor11_data,
+static struct platform_device orion_xor1_shared = {
+	.name		= MV_XOR_SHARED_NAME,
+	.id		= 1,
+	.num_resources	= ARRAY_SIZE(orion_xor1_shared_resources),
+	.resource	= orion_xor1_shared_resources,
+	.dev            = {
+		.dma_mask               = &orion_xor_dmamask,
+		.coherent_dma_mask      = DMA_BIT_MASK(64),
+		.platform_data          = &orion_xor1_pdata,
 	},
 };
 
@@ -783,15 +765,23 @@ void __init orion_xor1_init(unsigned long mapbase_low,
 	orion_xor1_shared_resources[1].start = mapbase_high;
 	orion_xor1_shared_resources[1].end = mapbase_high + 0xff;
 
-	orion_xor10_resources[0].start = irq_0;
-	orion_xor10_resources[0].end = irq_0;
-	orion_xor11_resources[0].start = irq_1;
-	orion_xor11_resources[0].end = irq_1;
+	orion_xor1_shared_resources[2].start = irq_0;
+	orion_xor1_shared_resources[2].end = irq_0;
+	orion_xor1_shared_resources[3].start = irq_1;
+	orion_xor1_shared_resources[3].end = irq_1;
 
-	platform_device_register(&orion_xor1_shared);
+	/*
+	 * two engines can't do memset simultaneously, this limitation
+	 * satisfied by removing memset support from one of the engines.
+	 */
+	dma_cap_set(DMA_MEMCPY, orion_xor1_channels_pdata[0].cap_mask);
+	dma_cap_set(DMA_XOR, orion_xor1_channels_pdata[0].cap_mask);
 
-	orion_xor_init_channels(&orion_xor10_data, &orion_xor10_channel,
-				&orion_xor11_data, &orion_xor11_channel);
+	dma_cap_set(DMA_MEMSET, orion_xor1_channels_pdata[1].cap_mask);
+	dma_cap_set(DMA_MEMCPY, orion_xor1_channels_pdata[1].cap_mask);
+	dma_cap_set(DMA_XOR, orion_xor1_channels_pdata[1].cap_mask);
+
+	platform_device_register(&orion_xor1_shared);
 }
 
 /*****************************************************************************
Signature · 1 line
1.7.9.5
#7 lore raw

PATCH 7/29 arm: plat-orion: remove unused orion_xor_init_channels()

In reply to Thomas Petazzoni

Now that xor0 and xor1 are registered in a single driver manner, the orion_xor_init_channels() function has become useless.

---
 arch/arm/plat-orion/common.c |   20 --------------------
 1 file changed, 20 deletions(-)
arch/arm/plat-orion/common.c +0 -20
index afbbb97..c6e6666 100644
@@ -606,26 +606,6 @@ void __init orion_wdt_init(void)
  ****************************************************************************/
 static u64 orion_xor_dmamask = DMA_BIT_MASK(32);
 
-void __init orion_xor_init_channels(
-	struct mv_xor_platform_data *orion_xor0_data,
-	struct platform_device *orion_xor0_channel,
-	struct mv_xor_platform_data *orion_xor1_data,
-	struct platform_device *orion_xor1_channel)
-{
-	/*
-	 * two engines can't do memset simultaneously, this limitation
-	 * satisfied by removing memset support from one of the engines.
-	 */
-	dma_cap_set(DMA_MEMCPY, orion_xor0_data->cap_mask);
-	dma_cap_set(DMA_XOR, orion_xor0_data->cap_mask);
-	platform_device_register(orion_xor0_channel);
-
-	dma_cap_set(DMA_MEMCPY, orion_xor1_data->cap_mask);
-	dma_cap_set(DMA_MEMSET, orion_xor1_data->cap_mask);
-	dma_cap_set(DMA_XOR, orion_xor1_data->cap_mask);
-	platform_device_register(orion_xor1_channel);
-}
-
 /*****************************************************************************
  * XOR0
  ****************************************************************************/
Signature · 1 line
1.7.9.5
#8 lore raw

PATCH 8/29 mv_xor: remove sub-driver 'mv_xor'

In reply to Thomas Petazzoni

Now that XOR channels are directly registered by the main 'mv_xor_shared' device ->probe() function and all users of the 'mv_xor' device have been removed, we can get rid of the latter.

---
 drivers/dma/mv_xor.c                     |   49 +-----------------------------
 include/linux/platform_data/dma-mv_xor.h |    1 -
 2 files changed, 1 insertion(+), 49 deletions(-)
drivers/dma/mv_xor.c +1 -48
index 3eaa0b2..614968e 100644
@@ -1219,35 +1219,6 @@ mv_xor_channel_add(struct mv_xor_shared_private *msp,
 	return ERR_PTR(ret);
 }
 
-static int __devexit mv_xor_remove(struct platform_device *pdev)
-{
-	struct mv_xor_device *device = platform_get_drvdata(pdev);
-	return mv_xor_channel_remove(device);
-}
-
-static int __devinit mv_xor_probe(struct platform_device *pdev)
-{
-	struct mv_xor_platform_data *plat_data = pdev->dev.platform_data;
-	struct mv_xor_shared_private *msp =
-		platform_get_drvdata(plat_data->shared);
-	struct mv_xor_device *mv_xor_device;
-	int irq;
-
-	irq = platform_get_irq(pdev, 0);
-	if (irq < 0)
-		return irq;
-
-	mv_xor_device = mv_xor_channel_add(msp, pdev, plat_data->hw_id,
-					   plat_data->cap_mask,
-					   plat_data->pool_size, irq);
-	if (IS_ERR(mv_xor_device))
-		return PTR_ERR(mv_xor_device);
-
-	platform_set_drvdata(pdev, mv_xor_device);
-
-	return 0;
-}
-
 static void
 mv_xor_conf_mbus_windows(struct mv_xor_shared_private *msp,
 			 const struct mbus_dram_target_info *dram)
@@ -1279,15 +1250,6 @@ mv_xor_conf_mbus_windows(struct mv_xor_shared_private *msp,
 	writel(win_enable, base + WINDOW_BAR_ENABLE(1));
 }
 
-static struct platform_driver mv_xor_driver = {
-	.probe		= mv_xor_probe,
-	.remove		= __devexit_p(mv_xor_remove),
-	.driver		= {
-		.owner	= THIS_MODULE,
-		.name	= MV_XOR_NAME,
-	},
-};
-
 static int mv_xor_shared_probe(struct platform_device *pdev)
 {
 	const struct mbus_dram_target_info *dram;
@@ -1406,15 +1368,7 @@ static struct platform_driver mv_xor_shared_driver = {
 
 static int __init mv_xor_init(void)
 {
-	int rc;
-
-	rc = platform_driver_register(&mv_xor_shared_driver);
-	if (!rc) {
-		rc = platform_driver_register(&mv_xor_driver);
-		if (rc)
-			platform_driver_unregister(&mv_xor_shared_driver);
-	}
-	return rc;
+	return platform_driver_register(&mv_xor_shared_driver);
 }
 module_init(mv_xor_init);
 
@@ -1422,7 +1376,6 @@ module_init(mv_xor_init);
 #if 0
 static void __exit mv_xor_exit(void)
 {
-	platform_driver_unregister(&mv_xor_driver);
 	platform_driver_unregister(&mv_xor_shared_driver);
 	return;
 }
include/linux/platform_data/dma-mv_xor.h +0 -1
index f2aed97..6abe5f9 100644
@@ -11,7 +11,6 @@
 #include <linux/mbus.h>
 
 #define MV_XOR_SHARED_NAME	"mv_xor_shared"
-#define MV_XOR_NAME		"mv_xor"
 
 struct mv_xor_platform_data {
 	struct platform_device		*shared;
Signature · 1 line
1.7.9.5
#9 lore raw

PATCH 9/29 mv_xor: remove 'shared' from mv_xor_platform_data

In reply to Thomas Petazzoni

This member of the platform_data structure is no longer used, so get rid of it.

---
 arch/arm/plat-orion/common.c             |    8 --------
 include/linux/platform_data/dma-mv_xor.h |    1 -
 2 files changed, 9 deletions(-)
arch/arm/plat-orion/common.c +0 -8
index c6e6666..5a66211 100644
@@ -625,16 +625,12 @@ static struct resource orion_xor0_shared_resources[] = {
 	},
 };
 
-static struct platform_device orion_xor0_shared;
-
 static struct mv_xor_platform_data orion_xor0_channels_pdata[2] = {
 	{
-		.shared		= &orion_xor0_shared,
 		.hw_id		= 0,
 		.pool_size	= PAGE_SIZE,
 	},
 	{
-		.shared		= &orion_xor0_shared,
 		.hw_id		= 1,
 		.pool_size	= PAGE_SIZE,
 	},
@@ -704,16 +700,12 @@ static struct resource orion_xor1_shared_resources[] = {
 	},
 };
 
-static struct platform_device orion_xor1_shared;
-
 static struct mv_xor_platform_data orion_xor1_channels_pdata[2] = {
 	{
-		.shared		= &orion_xor1_shared,
 		.hw_id		= 0,
 		.pool_size	= PAGE_SIZE,
 	},
 	{
-		.shared		= &orion_xor1_shared,
 		.hw_id		= 1,
 		.pool_size	= PAGE_SIZE,
 	},
include/linux/platform_data/dma-mv_xor.h +0 -1
index 6abe5f9..4a0980b 100644
@@ -13,7 +13,6 @@
 #define MV_XOR_SHARED_NAME	"mv_xor_shared"
 
 struct mv_xor_platform_data {
-	struct platform_device		*shared;
 	int				hw_id;
 	dma_cap_mask_t			cap_mask;
 	size_t				pool_size;
Signature · 1 line
1.7.9.5
#10 lore raw

PATCH 10/29 mv_xor: rename mv_xor_platform_data to mv_xor_channel_data

In reply to Thomas Petazzoni

mv_xor_platform_data used to be the platform_data structure associated to the 'mv_xor' driver. This driver no longer exists, and this data structure really contains the properties of each XOR channel part of a given XOR engine. Therefore 'struct mv_xor_channel_data' is a more appropriate name.

---
 arch/arm/plat-orion/common.c             |   28 ++++++++++++++--------------
 drivers/dma/mv_xor.c                     |    2 +-
 include/linux/platform_data/dma-mv_xor.h |    4 ++--
 3 files changed, 17 insertions(+), 17 deletions(-)
arch/arm/plat-orion/common.c +14 -14
index 5a66211..7ffbe77 100644
@@ -625,7 +625,7 @@ static struct resource orion_xor0_shared_resources[] = {
 	},
 };
 
-static struct mv_xor_platform_data orion_xor0_channels_pdata[2] = {
+static struct mv_xor_channel_data orion_xor0_channels_data[2] = {
 	{
 		.hw_id		= 0,
 		.pool_size	= PAGE_SIZE,
@@ -637,7 +637,7 @@ static struct mv_xor_platform_data orion_xor0_channels_pdata[2] = {
 };
 
 static struct mv_xor_shared_platform_data orion_xor0_pdata = {
-	.channels = orion_xor0_channels_pdata,
+	.channels = orion_xor0_channels_data,
 };
 
 static struct platform_device orion_xor0_shared = {
@@ -671,12 +671,12 @@ void __init orion_xor0_init(unsigned long mapbase_low,
 	 * two engines can't do memset simultaneously, this limitation
 	 * satisfied by removing memset support from one of the engines.
 	 */
-	dma_cap_set(DMA_MEMCPY, orion_xor0_channels_pdata[0].cap_mask);
-	dma_cap_set(DMA_XOR, orion_xor0_channels_pdata[0].cap_mask);
+	dma_cap_set(DMA_MEMCPY, orion_xor0_channels_data[0].cap_mask);
+	dma_cap_set(DMA_XOR, orion_xor0_channels_data[0].cap_mask);
 
-	dma_cap_set(DMA_MEMSET, orion_xor0_channels_pdata[1].cap_mask);
-	dma_cap_set(DMA_MEMCPY, orion_xor0_channels_pdata[1].cap_mask);
-	dma_cap_set(DMA_XOR, orion_xor0_channels_pdata[1].cap_mask);
+	dma_cap_set(DMA_MEMSET, orion_xor0_channels_data[1].cap_mask);
+	dma_cap_set(DMA_MEMCPY, orion_xor0_channels_data[1].cap_mask);
+	dma_cap_set(DMA_XOR, orion_xor0_channels_data[1].cap_mask);
 
 	platform_device_register(&orion_xor0_shared);
 }
@@ -700,7 +700,7 @@ static struct resource orion_xor1_shared_resources[] = {
 	},
 };
 
-static struct mv_xor_platform_data orion_xor1_channels_pdata[2] = {
+static struct mv_xor_channel_data orion_xor1_channels_data[2] = {
 	{
 		.hw_id		= 0,
 		.pool_size	= PAGE_SIZE,
@@ -712,7 +712,7 @@ static struct mv_xor_platform_data orion_xor1_channels_pdata[2] = {
 };
 
 static struct mv_xor_shared_platform_data orion_xor1_pdata = {
-	.channels = orion_xor1_channels_pdata,
+	.channels = orion_xor1_channels_data,
 };
 
 static struct platform_device orion_xor1_shared = {
@@ -746,12 +746,12 @@ void __init orion_xor1_init(unsigned long mapbase_low,
 	 * two engines can't do memset simultaneously, this limitation
 	 * satisfied by removing memset support from one of the engines.
 	 */
-	dma_cap_set(DMA_MEMCPY, orion_xor1_channels_pdata[0].cap_mask);
-	dma_cap_set(DMA_XOR, orion_xor1_channels_pdata[0].cap_mask);
+	dma_cap_set(DMA_MEMCPY, orion_xor1_channels_data[0].cap_mask);
+	dma_cap_set(DMA_XOR, orion_xor1_channels_data[0].cap_mask);
 
-	dma_cap_set(DMA_MEMSET, orion_xor1_channels_pdata[1].cap_mask);
-	dma_cap_set(DMA_MEMCPY, orion_xor1_channels_pdata[1].cap_mask);
-	dma_cap_set(DMA_XOR, orion_xor1_channels_pdata[1].cap_mask);
+	dma_cap_set(DMA_MEMSET, orion_xor1_channels_data[1].cap_mask);
+	dma_cap_set(DMA_MEMCPY, orion_xor1_channels_data[1].cap_mask);
+	dma_cap_set(DMA_XOR, orion_xor1_channels_data[1].cap_mask);
 
 	platform_device_register(&orion_xor1_shared);
 }
drivers/dma/mv_xor.c +1 -1
index 614968e..7383f3f 100644
@@ -1300,7 +1300,7 @@ static int mv_xor_shared_probe(struct platform_device *pdev)
 
 	if (pdata && pdata->channels) {
 		for (i = 0; i < MV_XOR_MAX_CHANNELS; i++) {
-			struct mv_xor_platform_data *cd;
+			struct mv_xor_channel_data *cd;
 			int irq;
 
 			cd = &pdata->channels[i];
include/linux/platform_data/dma-mv_xor.h +2 -2
index 4a0980b..40ea3d5 100644
@@ -12,14 +12,14 @@
 
 #define MV_XOR_SHARED_NAME	"mv_xor_shared"
 
-struct mv_xor_platform_data {
+struct mv_xor_channel_data {
 	int				hw_id;
 	dma_cap_mask_t			cap_mask;
 	size_t				pool_size;
 };
 
 struct mv_xor_shared_platform_data {
-	struct mv_xor_platform_data    *channels;
+	struct mv_xor_channel_data    *channels;
 };
 
 #endif
Signature · 1 line
1.7.9.5
#11 lore raw

PATCH 11/29 mv_xor: rename mv_xor_shared_platform_data to mv_xor_platform_data

In reply to Thomas Petazzoni

'struct mv_xor_shared_platform_data' used to be the platform_data structure for the 'mv_xor_shared', but this driver is going to be renamed simply 'mv_xor', so also rename its platform_data structure accordingly.

---
 arch/arm/plat-orion/common.c             |    4 ++--
 drivers/dma/mv_xor.c                     |    2 +-
 include/linux/platform_data/dma-mv_xor.h |    2 +-
 3 files changed, 4 insertions(+), 4 deletions(-)
arch/arm/plat-orion/common.c +2 -2
index 7ffbe77..edd57a6 100644
@@ -636,7 +636,7 @@ static struct mv_xor_channel_data orion_xor0_channels_data[2] = {
 	},
 };
 
-static struct mv_xor_shared_platform_data orion_xor0_pdata = {
+static struct mv_xor_platform_data orion_xor0_pdata = {
 	.channels = orion_xor0_channels_data,
 };
 
@@ -711,7 +711,7 @@ static struct mv_xor_channel_data orion_xor1_channels_data[2] = {
 	},
 };
 
-static struct mv_xor_shared_platform_data orion_xor1_pdata = {
+static struct mv_xor_platform_data orion_xor1_pdata = {
 	.channels = orion_xor1_channels_data,
 };
 
drivers/dma/mv_xor.c +1 -1
index 7383f3f..7172110 100644
@@ -1254,7 +1254,7 @@ static int mv_xor_shared_probe(struct platform_device *pdev)
 {
 	const struct mbus_dram_target_info *dram;
 	struct mv_xor_shared_private *msp;
-	struct mv_xor_shared_platform_data *pdata = pdev->dev.platform_data;
+	struct mv_xor_platform_data *pdata = pdev->dev.platform_data;
 	struct resource *res;
 	int i, ret;
 
include/linux/platform_data/dma-mv_xor.h +1 -1
index 40ea3d5..82a5f4b 100644
@@ -18,7 +18,7 @@ struct mv_xor_channel_data {
 	size_t				pool_size;
 };
 
-struct mv_xor_shared_platform_data {
+struct mv_xor_platform_data {
 	struct mv_xor_channel_data    *channels;
 };
 
Signature · 1 line
1.7.9.5
#12 lore raw

PATCH 12/29 mv_xor: change the driver name to 'mv_xor'

In reply to Thomas Petazzoni

Since we got rid of the per-XOR channel 'mv_xor' driver, now the per-XOR engine driver that used to be called 'mv_xor_shared' can simply be named 'mv_xor'.

---
 arch/arm/mach-kirkwood/common.c          |    4 ++--
 arch/arm/plat-orion/common.c             |    4 ++--
 drivers/dma/mv_xor.c                     |    2 +-
 include/linux/platform_data/dma-mv_xor.h |    2 +-
 4 files changed, 6 insertions(+), 6 deletions(-)
arch/arm/mach-kirkwood/common.c +2 -2
index 2c6c218..401dac1 100644
@@ -260,8 +260,8 @@ void __init kirkwood_clk_init(void)
 	orion_clkdev_add(NULL, "orion_nand", runit);
 	orion_clkdev_add(NULL, "mvsdio", sdio);
 	orion_clkdev_add(NULL, "mv_crypto", crypto);
-	orion_clkdev_add(NULL, MV_XOR_SHARED_NAME ".0", xor0);
-	orion_clkdev_add(NULL, MV_XOR_SHARED_NAME ".1", xor1);
+	orion_clkdev_add(NULL, MV_XOR_NAME ".0", xor0);
+	orion_clkdev_add(NULL, MV_XOR_NAME ".1", xor1);
 	orion_clkdev_add("0", "pcie", pex0);
 	orion_clkdev_add("1", "pcie", pex1);
 	orion_clkdev_add(NULL, "kirkwood-i2s", audio);
arch/arm/plat-orion/common.c +2 -2
index edd57a6..31517ce 100644
@@ -641,7 +641,7 @@ static struct mv_xor_platform_data orion_xor0_pdata = {
 };
 
 static struct platform_device orion_xor0_shared = {
-	.name		= MV_XOR_SHARED_NAME,
+	.name		= MV_XOR_NAME,
 	.id		= 0,
 	.num_resources	= ARRAY_SIZE(orion_xor0_shared_resources),
 	.resource	= orion_xor0_shared_resources,
@@ -716,7 +716,7 @@ static struct mv_xor_platform_data orion_xor1_pdata = {
 };
 
 static struct platform_device orion_xor1_shared = {
-	.name		= MV_XOR_SHARED_NAME,
+	.name		= MV_XOR_NAME,
 	.id		= 1,
 	.num_resources	= ARRAY_SIZE(orion_xor1_shared_resources),
 	.resource	= orion_xor1_shared_resources,
drivers/dma/mv_xor.c +1 -1
index 7172110..da794ba 100644
@@ -1361,7 +1361,7 @@ static struct platform_driver mv_xor_shared_driver = {
 	.remove		= mv_xor_shared_remove,
 	.driver		= {
 		.owner	= THIS_MODULE,
-		.name	= MV_XOR_SHARED_NAME,
+		.name	= MV_XOR_NAME,
 	},
 };
 
include/linux/platform_data/dma-mv_xor.h +1 -1
index 82a5f4b..367bb21 100644
@@ -10,7 +10,7 @@
 #include <linux/dmaengine.h>
 #include <linux/mbus.h>
 
-#define MV_XOR_SHARED_NAME	"mv_xor_shared"
+#define MV_XOR_NAME	"mv_xor"
 
 struct mv_xor_channel_data {
 	int				hw_id;
Signature · 1 line
1.7.9.5
#13 lore raw

PATCH 13/29 mv_xor: rename many symbols to remove the 'shared' word

In reply to Thomas Petazzoni

The 'shared' word no longer makes sense in a number of places as we renamed the 'mv_xor_shared' driver to 'mv_xor'.

---
 drivers/dma/mv_xor.c |   24 ++++++++++++------------
 drivers/dma/mv_xor.h |    4 ++--
 2 files changed, 14 insertions(+), 14 deletions(-)
drivers/dma/mv_xor.c +12 -12
index da794ba..7ebb918 100644
@@ -1097,7 +1097,7 @@ static int __devexit mv_xor_channel_remove(struct mv_xor_device *device)
 }
 
 static struct mv_xor_device * __devinit
-mv_xor_channel_add(struct mv_xor_shared_private *msp,
+mv_xor_channel_add(struct mv_xor_private *msp,
 		   struct platform_device *pdev,
 		   int hw_id, dma_cap_mask_t cap_mask,
 		   size_t pool_size, int irq)
@@ -1220,7 +1220,7 @@ mv_xor_channel_add(struct mv_xor_shared_private *msp,
 }
 
 static void
-mv_xor_conf_mbus_windows(struct mv_xor_shared_private *msp,
+mv_xor_conf_mbus_windows(struct mv_xor_private *msp,
 			 const struct mbus_dram_target_info *dram)
 {
 	void __iomem *base = msp->xor_base;
@@ -1250,15 +1250,15 @@ mv_xor_conf_mbus_windows(struct mv_xor_shared_private *msp,
 	writel(win_enable, base + WINDOW_BAR_ENABLE(1));
 }
 
-static int mv_xor_shared_probe(struct platform_device *pdev)
+static int mv_xor_probe(struct platform_device *pdev)
 {
 	const struct mbus_dram_target_info *dram;
-	struct mv_xor_shared_private *msp;
+	struct mv_xor_private *msp;
 	struct mv_xor_platform_data *pdata = pdev->dev.platform_data;
 	struct resource *res;
 	int i, ret;
 
-	dev_notice(&pdev->dev, "Marvell shared XOR driver\n");
+	dev_notice(&pdev->dev, "Marvell XOR driver\n");
 
 	msp = devm_kzalloc(&pdev->dev, sizeof(*msp), GFP_KERNEL);
 	if (!msp)
@@ -1338,9 +1338,9 @@ err_channel_add:
 	return ret;
 }
 
-static int mv_xor_shared_remove(struct platform_device *pdev)
+static int mv_xor_remove(struct platform_device *pdev)
 {
-	struct mv_xor_shared_private *msp = platform_get_drvdata(pdev);
+	struct mv_xor_private *msp = platform_get_drvdata(pdev);
 	int i;
 
 	for (i = 0; i < MV_XOR_MAX_CHANNELS; i++) {
@@ -1356,9 +1356,9 @@ static int mv_xor_shared_remove(struct platform_device *pdev)
 	return 0;
 }
 
-static struct platform_driver mv_xor_shared_driver = {
-	.probe		= mv_xor_shared_probe,
-	.remove		= mv_xor_shared_remove,
+static struct platform_driver mv_xor_driver = {
+	.probe		= mv_xor_probe,
+	.remove		= mv_xor_remove,
 	.driver		= {
 		.owner	= THIS_MODULE,
 		.name	= MV_XOR_NAME,
@@ -1368,7 +1368,7 @@ static struct platform_driver mv_xor_shared_driver = {
 
 static int __init mv_xor_init(void)
 {
-	return platform_driver_register(&mv_xor_shared_driver);
+	return platform_driver_register(&mv_xor_driver);
 }
 module_init(mv_xor_init);
 
@@ -1376,7 +1376,7 @@ module_init(mv_xor_init);
 #if 0
 static void __exit mv_xor_exit(void)
 {
-	platform_driver_unregister(&mv_xor_shared_driver);
+	platform_driver_unregister(&mv_xor_driver);
 	return;
 }
 
drivers/dma/mv_xor.h +2 -2
index 686575f..7812565 100644
@@ -53,7 +53,7 @@
 #define WINDOW_REMAP_HIGH(w)	(0x290 + ((w) << 2))
 #define WINDOW_BAR_ENABLE(chan)	(0x240 + ((chan) << 2))
 
-struct mv_xor_shared_private {
+struct mv_xor_private {
 	void __iomem	     *xor_base;
 	void __iomem	     *xor_high_base;
 	struct clk	     *clk;
@@ -76,7 +76,7 @@ struct mv_xor_device {
 	void				*dma_desc_pool_virt;
 	size_t                          pool_size;
 	struct dma_device		common;
-	struct mv_xor_shared_private	*shared;
+	struct mv_xor_private	        *shared;
 };
 
 /**
Signature · 1 line
1.7.9.5
#14 lore raw

PATCH 14/29 mv_xor: remove unused id field in mv_xor_device structure

In reply to Thomas Petazzoni
---
 drivers/dma/mv_xor.c |    2 --
 drivers/dma/mv_xor.h |    1 -
 2 files changed, 3 deletions(-)
drivers/dma/mv_xor.c +0 -2
index 7ebb918..25f814a 100644
@@ -1125,8 +1125,6 @@ mv_xor_channel_add(struct mv_xor_private *msp,
 	if (!adev->dma_desc_pool_virt)
 		return ERR_PTR(-ENOMEM);
 
-	adev->id = hw_id;
-
 	/* discover transaction capabilites from the platform data */
 	dma_dev->cap_mask = cap_mask;
 	adev->pdev = pdev;
drivers/dma/mv_xor.h +0 -1
index 7812565..52ca617 100644
@@ -71,7 +71,6 @@ struct mv_xor_private {
  */
 struct mv_xor_device {
 	struct platform_device		*pdev;
-	int				id;
 	dma_addr_t			dma_desc_pool;
 	void				*dma_desc_pool_virt;
 	size_t                          pool_size;
Signature · 1 line
1.7.9.5
#15 lore raw

PATCH 15/29 mv_xor: remove unused to_mv_xor_device() macro

In reply to Thomas Petazzoni
---
 drivers/dma/mv_xor.c |    3 ---
 1 file changed, 3 deletions(-)
drivers/dma/mv_xor.c +0 -3
index 25f814a..7129895 100644
@@ -36,9 +36,6 @@ static void mv_xor_issue_pending(struct dma_chan *chan);
 #define to_mv_xor_chan(chan)		\
 	container_of(chan, struct mv_xor_chan, common)
 
-#define to_mv_xor_device(dev)		\
-	container_of(dev, struct mv_xor_device, common)
-
 #define to_mv_xor_slot(tx)		\
 	container_of(tx, struct mv_xor_desc_slot, async_tx)
 
Signature · 1 line
1.7.9.5
#16 lore raw

PATCH 16/29 mv_xor: simplify dma_sync_single_for_cpu() calls

In reply to Thomas Petazzoni

In mv_xor_memcpy_self_test() and mv_xor_xor_self_test(), all DMA functions are called by passing dma_chan->device->dev as the 'device *', except the calls to dma_sync_single_for_cpu() which uselessly goes through mv_chan->device->pdev->dev.

Simplify this by using dma_chan->device->dev direclty in dma_sync_single_for_cpu() calls.

---
 drivers/dma/mv_xor.c |    8 ++------
 1 file changed, 2 insertions(+), 6 deletions(-)
drivers/dma/mv_xor.c +2 -6
index 7129895..2387f47 100644
@@ -905,7 +905,6 @@ static int __devinit mv_xor_memcpy_self_test(struct mv_xor_device *device)
 	dma_cookie_t cookie;
 	struct dma_async_tx_descriptor *tx;
 	int err = 0;
-	struct mv_xor_chan *mv_chan;
 
 	src = kmalloc(sizeof(u8) * MV_XOR_TEST_SIZE, GFP_KERNEL);
 	if (!src)
@@ -951,8 +950,7 @@ static int __devinit mv_xor_memcpy_self_test(struct mv_xor_device *device)
 		goto free_resources;
 	}
 
-	mv_chan = to_mv_xor_chan(dma_chan);
-	dma_sync_single_for_cpu(&mv_chan->device->pdev->dev, dest_dma,
+	dma_sync_single_for_cpu(dma_chan->device->dev, dest_dma,
 				MV_XOR_TEST_SIZE, DMA_FROM_DEVICE);
 	if (memcmp(src, dest, MV_XOR_TEST_SIZE)) {
 		dev_err(dma_chan->device->dev,
@@ -984,7 +982,6 @@ mv_xor_xor_self_test(struct mv_xor_device *device)
 	u8 cmp_byte = 0;
 	u32 cmp_word;
 	int err = 0;
-	struct mv_xor_chan *mv_chan;
 
 	for (src_idx = 0; src_idx < MV_XOR_NUM_SRC_TEST; src_idx++) {
 		xor_srcs[src_idx] = alloc_page(GFP_KERNEL);
@@ -1049,8 +1046,7 @@ mv_xor_xor_self_test(struct mv_xor_device *device)
 		goto free_resources;
 	}
 
-	mv_chan = to_mv_xor_chan(dma_chan);
-	dma_sync_single_for_cpu(&mv_chan->device->pdev->dev, dest_dma,
+	dma_sync_single_for_cpu(dma_chan->device->dev, dest_dma,
 				PAGE_SIZE, DMA_FROM_DEVICE);
 	for (i = 0; i < (PAGE_SIZE / sizeof(u32)); i++) {
 		u32 *ptr = page_address(dest);
Signature · 1 line
1.7.9.5
#17 lore raw

PATCH 17/29 mv_xor: introduce a mv_chan_to_devp() helper

In reply to Thomas Petazzoni

In many place, we need to get the 'struct device *' pointer from a 'struct mv_chan *', so we add a helper that makes this a bit easier. It will also help reducing the change noise in further patches.

---
 drivers/dma/mv_xor.c |   61 ++++++++++++++++++++++++++------------------------
 1 file changed, 32 insertions(+), 29 deletions(-)
drivers/dma/mv_xor.c +32 -29
index 2387f47..9a3b804 100644
@@ -39,6 +39,9 @@ static void mv_xor_issue_pending(struct dma_chan *chan);
 #define to_mv_xor_slot(tx)		\
 	container_of(tx, struct mv_xor_desc_slot, async_tx)
 
+#define mv_chan_to_devp(chan)           \
+	((chan)->device->common.dev)
+
 static void mv_desc_init(struct mv_xor_desc_slot *desc, unsigned long flags)
 {
 	struct mv_xor_desc *hw_desc = desc->hw_desc;
@@ -163,7 +166,7 @@ static int mv_is_err_intr(u32 intr_cause)
 static void mv_xor_device_clear_eoc_cause(struct mv_xor_chan *chan)
 {
 	u32 val = ~(1 << (chan->idx * 16));
-	dev_dbg(chan->device->common.dev, "%s, val 0x%08x\n", __func__, val);
+	dev_dbg(mv_chan_to_devp(chan), "%s, val 0x%08x\n", __func__, val);
 	__raw_writel(val, XOR_INTR_CAUSE(chan));
 }
 
@@ -203,7 +206,7 @@ static void mv_set_mode(struct mv_xor_chan *chan,
 		op_mode = XOR_OPERATION_MODE_MEMSET;
 		break;
 	default:
-		dev_err(chan->device->common.dev,
+		dev_err(mv_chan_to_devp(chan),
 			"error: unsupported operation %d.\n",
 			type);
 		BUG();
@@ -220,7 +223,7 @@ static void mv_chan_activate(struct mv_xor_chan *chan)
 {
 	u32 activation;
 
-	dev_dbg(chan->device->common.dev, " activate chan.\n");
+	dev_dbg(mv_chan_to_devp(chan), " activate chan.\n");
 	activation = __raw_readl(XOR_ACTIVATION(chan));
 	activation |= 0x1;
 	__raw_writel(activation, XOR_ACTIVATION(chan));
@@ -248,7 +251,7 @@ static int mv_chan_xor_slot_count(size_t len, int src_cnt)
 static void mv_xor_free_slots(struct mv_xor_chan *mv_chan,
 			      struct mv_xor_desc_slot *slot)
 {
-	dev_dbg(mv_chan->device->common.dev, "%s %d slot %p\n",
+	dev_dbg(mv_chan_to_devp(mv_chan), "%s %d slot %p\n",
 		__func__, __LINE__, slot);
 
 	slot->slots_per_op = 0;
@@ -263,7 +266,7 @@ static void mv_xor_free_slots(struct mv_xor_chan *mv_chan,
 static void mv_xor_start_new_chain(struct mv_xor_chan *mv_chan,
 				   struct mv_xor_desc_slot *sw_desc)
 {
-	dev_dbg(mv_chan->device->common.dev, "%s %d: sw_desc %p\n",
+	dev_dbg(mv_chan_to_devp(mv_chan), "%s %d: sw_desc %p\n",
 		__func__, __LINE__, sw_desc);
 	if (sw_desc->type != mv_chan->current_type)
 		mv_set_mode(mv_chan, sw_desc->type);
@@ -350,7 +353,7 @@ mv_xor_clean_completed_slots(struct mv_xor_chan *mv_chan)
 {
 	struct mv_xor_desc_slot *iter, *_iter;
 
-	dev_dbg(mv_chan->device->common.dev, "%s %d\n", __func__, __LINE__);
+	dev_dbg(mv_chan_to_devp(mv_chan), "%s %d\n", __func__, __LINE__);
 	list_for_each_entry_safe(iter, _iter, &mv_chan->completed_slots,
 				 completed_node) {
 
@@ -366,7 +369,7 @@ static int
 mv_xor_clean_slot(struct mv_xor_desc_slot *desc,
 	struct mv_xor_chan *mv_chan)
 {
-	dev_dbg(mv_chan->device->common.dev, "%s %d: desc %p flags %d\n",
+	dev_dbg(mv_chan_to_devp(mv_chan), "%s %d: desc %p flags %d\n",
 		__func__, __LINE__, desc, desc->async_tx.flags);
 	list_del(&desc->chain_node);
 	/* the client is allowed to attach dependent operations
@@ -390,8 +393,8 @@ static void __mv_xor_slot_cleanup(struct mv_xor_chan *mv_chan)
 	u32 current_desc = mv_chan_get_current_desc(mv_chan);
 	int seen_current = 0;
 
-	dev_dbg(mv_chan->device->common.dev, "%s %d\n", __func__, __LINE__);
-	dev_dbg(mv_chan->device->common.dev, "current_desc %x\n", current_desc);
+	dev_dbg(mv_chan_to_devp(mv_chan), "%s %d\n", __func__, __LINE__);
+	dev_dbg(mv_chan_to_devp(mv_chan), "current_desc %x\n", current_desc);
 	mv_xor_clean_completed_slots(mv_chan);
 
 	/* free completed slots from the chain starting with
@@ -544,7 +547,7 @@ mv_xor_tx_submit(struct dma_async_tx_descriptor *tx)
 	dma_cookie_t cookie;
 	int new_hw_chain = 1;
 
-	dev_dbg(mv_chan->device->common.dev,
+	dev_dbg(mv_chan_to_devp(mv_chan),
 		"%s sw_desc %p: async_tx %p\n",
 		__func__, sw_desc, &sw_desc->async_tx);
 
@@ -567,7 +570,7 @@ mv_xor_tx_submit(struct dma_async_tx_descriptor *tx)
 		if (!mv_can_chain(grp_start))
 			goto submit_done;
 
-		dev_dbg(mv_chan->device->common.dev, "Append to last desc %x\n",
+		dev_dbg(mv_chan_to_devp(mv_chan), "Append to last desc %x\n",
 			old_chain_tail->async_tx.phys);
 
 		/* fix up the hardware chain */
@@ -636,7 +639,7 @@ static int mv_xor_alloc_chan_resources(struct dma_chan *chan)
 					struct mv_xor_desc_slot,
 					slot_node);
 
-	dev_dbg(mv_chan->device->common.dev,
+	dev_dbg(mv_chan_to_devp(mv_chan),
 		"allocated %d descriptor slots last_used: %p\n",
 		mv_chan->slots_allocated, mv_chan->last_used);
 
@@ -651,7 +654,7 @@ mv_xor_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
 	struct mv_xor_desc_slot *sw_desc, *grp_start;
 	int slot_cnt;
 
-	dev_dbg(mv_chan->device->common.dev,
+	dev_dbg(mv_chan_to_devp(mv_chan),
 		"%s dest: %x src %x len: %u flags: %ld\n",
 		__func__, dest, src, len, flags);
 	if (unlikely(len < MV_XOR_MIN_BYTE_COUNT))
@@ -675,7 +678,7 @@ mv_xor_prep_dma_memcpy(struct dma_chan *chan, dma_addr_t dest, dma_addr_t src,
 	}
 	spin_unlock_bh(&mv_chan->lock);
 
-	dev_dbg(mv_chan->device->common.dev,
+	dev_dbg(mv_chan_to_devp(mv_chan),
 		"%s sw_desc %p async_tx %p\n",
 		__func__, sw_desc, sw_desc ? &sw_desc->async_tx : 0);
 
@@ -690,7 +693,7 @@ mv_xor_prep_dma_memset(struct dma_chan *chan, dma_addr_t dest, int value,
 	struct mv_xor_desc_slot *sw_desc, *grp_start;
 	int slot_cnt;
 
-	dev_dbg(mv_chan->device->common.dev,
+	dev_dbg(mv_chan_to_devp(mv_chan),
 		"%s dest: %x len: %u flags: %ld\n",
 		__func__, dest, len, flags);
 	if (unlikely(len < MV_XOR_MIN_BYTE_COUNT))
@@ -713,7 +716,7 @@ mv_xor_prep_dma_memset(struct dma_chan *chan, dma_addr_t dest, int value,
 		sw_desc->unmap_len = len;
 	}
 	spin_unlock_bh(&mv_chan->lock);
-	dev_dbg(mv_chan->device->common.dev,
+	dev_dbg(mv_chan_to_devp(mv_chan),
 		"%s sw_desc %p async_tx %p \n",
 		__func__, sw_desc, &sw_desc->async_tx);
 	return sw_desc ? &sw_desc->async_tx : NULL;
@@ -732,7 +735,7 @@ mv_xor_prep_dma_xor(struct dma_chan *chan, dma_addr_t dest, dma_addr_t *src,
 
 	BUG_ON(len > MV_XOR_MAX_BYTE_COUNT);
 
-	dev_dbg(mv_chan->device->common.dev,
+	dev_dbg(mv_chan_to_devp(mv_chan),
 		"%s src_cnt: %d len: dest %x %u flags: %ld\n",
 		__func__, src_cnt, len, dest, flags);
 
@@ -753,7 +756,7 @@ mv_xor_prep_dma_xor(struct dma_chan *chan, dma_addr_t dest, dma_addr_t *src,
 			mv_desc_set_src_addr(grp_start, src_cnt, src[src_cnt]);
 	}
 	spin_unlock_bh(&mv_chan->lock);
-	dev_dbg(mv_chan->device->common.dev,
+	dev_dbg(mv_chan_to_devp(mv_chan),
 		"%s sw_desc %p async_tx %p \n",
 		__func__, sw_desc, &sw_desc->async_tx);
 	return sw_desc ? &sw_desc->async_tx : NULL;
@@ -786,12 +789,12 @@ static void mv_xor_free_chan_resources(struct dma_chan *chan)
 	}
 	mv_chan->last_used = NULL;
 
-	dev_dbg(mv_chan->device->common.dev, "%s slots_allocated %d\n",
+	dev_dbg(mv_chan_to_devp(mv_chan), "%s slots_allocated %d\n",
 		__func__, mv_chan->slots_allocated);
 	spin_unlock_bh(&mv_chan->lock);
 
 	if (in_use_descs)
-		dev_err(mv_chan->device->common.dev,
+		dev_err(mv_chan_to_devp(mv_chan),
 			"freeing %d in use descriptors!\n", in_use_descs);
 }
 
@@ -823,27 +826,27 @@ static void mv_dump_xor_regs(struct mv_xor_chan *chan)
 	u32 val;
 
 	val = __raw_readl(XOR_CONFIG(chan));
-	dev_err(chan->device->common.dev,
+	dev_err(mv_chan_to_devp(chan),
 		"config       0x%08x.\n", val);
 
 	val = __raw_readl(XOR_ACTIVATION(chan));
-	dev_err(chan->device->common.dev,
+	dev_err(mv_chan_to_devp(chan),
 		"activation   0x%08x.\n", val);
 
 	val = __raw_readl(XOR_INTR_CAUSE(chan));
-	dev_err(chan->device->common.dev,
+	dev_err(mv_chan_to_devp(chan),
 		"intr cause   0x%08x.\n", val);
 
 	val = __raw_readl(XOR_INTR_MASK(chan));
-	dev_err(chan->device->common.dev,
+	dev_err(mv_chan_to_devp(chan),
 		"intr mask    0x%08x.\n", val);
 
 	val = __raw_readl(XOR_ERROR_CAUSE(chan));
-	dev_err(chan->device->common.dev,
+	dev_err(mv_chan_to_devp(chan),
 		"error cause  0x%08x.\n", val);
 
 	val = __raw_readl(XOR_ERROR_ADDR(chan));
-	dev_err(chan->device->common.dev,
+	dev_err(mv_chan_to_devp(chan),
 		"error addr   0x%08x.\n", val);
 }
 
@@ -851,12 +854,12 @@ static void mv_xor_err_interrupt_handler(struct mv_xor_chan *chan,
 					 u32 intr_cause)
 {
 	if (intr_cause & (1 << 4)) {
-	     dev_dbg(chan->device->common.dev,
+	     dev_dbg(mv_chan_to_devp(chan),
 		     "ignore this error\n");
 	     return;
 	}
 
-	dev_err(chan->device->common.dev,
+	dev_err(mv_chan_to_devp(chan),
 		"error on chan %d. intr cause 0x%08x.\n",
 		chan->idx, intr_cause);
 
@@ -869,7 +872,7 @@ static irqreturn_t mv_xor_interrupt_handler(int irq, void *data)
 	struct mv_xor_chan *chan = data;
 	u32 intr_cause = mv_chan_get_intr_cause(chan);
 
-	dev_dbg(chan->device->common.dev, "intr cause %x\n", intr_cause);
+	dev_dbg(mv_chan_to_devp(chan), "intr cause %x\n", intr_cause);
 
 	if (mv_is_err_intr(intr_cause))
 		mv_xor_err_interrupt_handler(chan, intr_cause);
Signature · 1 line
1.7.9.5
#18 lore raw

PATCH 18/29 mv_xor: get rid of the pdev pointer in mv_xor_device

In reply to Thomas Petazzoni

It was only used in places where we could get the 'struct device *' pointer through a different way.

---
 drivers/dma/mv_xor.c |    9 ++++-----
 drivers/dma/mv_xor.h |    1 -
 2 files changed, 4 insertions(+), 6 deletions(-)
drivers/dma/mv_xor.c +4 -5
index 9a3b804..3278782 100644
@@ -308,8 +308,7 @@ mv_xor_run_tx_complete_actions(struct mv_xor_desc_slot *desc,
 		 */
 		if (desc->group_head && desc->unmap_len) {
 			struct mv_xor_desc_slot *unmap = desc->group_head;
-			struct device *dev =
-				&mv_chan->device->pdev->dev;
+			struct device *dev = mv_chan_to_devp(mv_chan);
 			u32 len = unmap->unmap_len;
 			enum dma_ctrl_flags flags = desc->async_tx.flags;
 			u32 src_cnt;
@@ -1077,10 +1076,11 @@ static int __devexit mv_xor_channel_remove(struct mv_xor_device *device)
 {
 	struct dma_chan *chan, *_chan;
 	struct mv_xor_chan *mv_chan;
+	struct device *dev = device->common.dev;
 
 	dma_async_device_unregister(&device->common);
 
-	dma_free_coherent(&device->pdev->dev, device->pool_size,
+	dma_free_coherent(dev, device->pool_size,
 			  device->dma_desc_pool_virt, device->dma_desc_pool);
 
 	list_for_each_entry_safe(chan, _chan, &device->common.channels,
@@ -1123,7 +1123,6 @@ mv_xor_channel_add(struct mv_xor_private *msp,
 
 	/* discover transaction capabilites from the platform data */
 	dma_dev->cap_mask = cap_mask;
-	adev->pdev = pdev;
 	adev->shared = msp;
 
 	INIT_LIST_HEAD(&dma_dev->channels);
@@ -1208,7 +1207,7 @@ mv_xor_channel_add(struct mv_xor_private *msp,
 	return adev;
 
  err_free_dma:
-	dma_free_coherent(&adev->pdev->dev, pool_size,
+	dma_free_coherent(&pdev->dev, pool_size,
 			adev->dma_desc_pool_virt, adev->dma_desc_pool);
 	return ERR_PTR(ret);
 }
drivers/dma/mv_xor.h +0 -1
index 52ca617..05add24 100644
@@ -70,7 +70,6 @@ struct mv_xor_private {
  * @common: embedded struct dma_device
  */
 struct mv_xor_device {
-	struct platform_device		*pdev;
 	dma_addr_t			dma_desc_pool;
 	void				*dma_desc_pool_virt;
 	size_t                          pool_size;
Signature · 1 line
1.7.9.5
#19 lore raw

PATCH 19/29 mv_xor: in mv_xor_chan, rename 'common' to 'dmachan'

In reply to Thomas Petazzoni

The mv_xor_chan structure embeds a 'struct dma_chan', which is named 'common', a not very meaningful name. Rename it to 'dmachan', which will help avoid confusions later as we merge the mv_xor_device and mv_xor_chan structures together.

---
 drivers/dma/mv_xor.c |   12 ++++++------
 drivers/dma/mv_xor.h |    2 +-
 2 files changed, 7 insertions(+), 7 deletions(-)
drivers/dma/mv_xor.c +6 -6
index 3278782..aa6d96c 100644
@@ -34,7 +34,7 @@
 static void mv_xor_issue_pending(struct dma_chan *chan);
 
 #define to_mv_xor_chan(chan)		\
-	container_of(chan, struct mv_xor_chan, common)
+	container_of(chan, struct mv_xor_chan, dmachan)
 
 #define to_mv_xor_slot(tx)		\
 	container_of(tx, struct mv_xor_desc_slot, async_tx)
@@ -284,7 +284,7 @@ static void mv_xor_start_new_chain(struct mv_xor_chan *mv_chan,
 		mv_chan_set_next_descriptor(mv_chan, sw_desc->async_tx.phys);
 	}
 	mv_chan->pending += sw_desc->slot_cnt;
-	mv_xor_issue_pending(&mv_chan->common);
+	mv_xor_issue_pending(&mv_chan->dmachan);
 }
 
 static dma_cookie_t
@@ -437,7 +437,7 @@ static void __mv_xor_slot_cleanup(struct mv_xor_chan *mv_chan)
 	}
 
 	if (cookie > 0)
-		mv_chan->common.completed_cookie = cookie;
+		mv_chan->dmachan.completed_cookie = cookie;
 }
 
 static void
@@ -1177,10 +1177,10 @@ mv_xor_channel_add(struct mv_xor_private *msp,
 	INIT_LIST_HEAD(&mv_chan->chain);
 	INIT_LIST_HEAD(&mv_chan->completed_slots);
 	INIT_LIST_HEAD(&mv_chan->all_slots);
-	mv_chan->common.device = dma_dev;
-	dma_cookie_init(&mv_chan->common);
+	mv_chan->dmachan.device = dma_dev;
+	dma_cookie_init(&mv_chan->dmachan);
 
-	list_add_tail(&mv_chan->common.device_node, &dma_dev->channels);
+	list_add_tail(&mv_chan->dmachan.device_node, &dma_dev->channels);
 
 	if (dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask)) {
 		ret = mv_xor_memcpy_self_test(adev);
drivers/dma/mv_xor.h +1 -1
index 05add24..ad18f64 100644
@@ -101,7 +101,7 @@ struct mv_xor_chan {
 	struct list_head	chain;
 	struct list_head	completed_slots;
 	struct mv_xor_device	*device;
-	struct dma_chan		common;
+	struct dma_chan		dmachan;
 	struct mv_xor_desc_slot	*last_used;
 	struct list_head	all_slots;
 	int			slots_allocated;
Signature · 1 line
1.7.9.5
#20 lore raw

PATCH 20/29 mv_xor: in mv_xor_device, rename 'common' to 'dmadev'

In reply to Thomas Petazzoni

The mv_xor_device structure embeds a 'struct dma_device', which is named 'common', a not very meaningful name. Rename it to 'dmadev', which will help avoid confusions later as we merge the mv_xor_device and mv_xor_chan structures together.

---
 drivers/dma/mv_xor.c |   14 +++++++-------
 drivers/dma/mv_xor.h |    2 +-
 2 files changed, 8 insertions(+), 8 deletions(-)
drivers/dma/mv_xor.c +7 -7
index aa6d96c..cbcc441 100644
@@ -40,7 +40,7 @@ static void mv_xor_issue_pending(struct dma_chan *chan);
 	container_of(tx, struct mv_xor_desc_slot, async_tx)
 
 #define mv_chan_to_devp(chan)           \
-	((chan)->device->common.dev)
+	((chan)->device->dmadev.dev)
 
 static void mv_desc_init(struct mv_xor_desc_slot *desc, unsigned long flags)
 {
@@ -923,7 +923,7 @@ static int __devinit mv_xor_memcpy_self_test(struct mv_xor_device *device)
 		((u8 *) src)[i] = (u8)i;
 
 	/* Start copy, using first DMA channel */
-	dma_chan = container_of(device->common.channels.next,
+	dma_chan = container_of(device->dmadev.channels.next,
 				struct dma_chan,
 				device_node);
 	if (mv_xor_alloc_chan_resources(dma_chan) < 1) {
@@ -1016,7 +1016,7 @@ mv_xor_xor_self_test(struct mv_xor_device *device)
 
 	memset(page_address(dest), 0, PAGE_SIZE);
 
-	dma_chan = container_of(device->common.channels.next,
+	dma_chan = container_of(device->dmadev.channels.next,
 				struct dma_chan,
 				device_node);
 	if (mv_xor_alloc_chan_resources(dma_chan) < 1) {
@@ -1076,14 +1076,14 @@ static int __devexit mv_xor_channel_remove(struct mv_xor_device *device)
 {
 	struct dma_chan *chan, *_chan;
 	struct mv_xor_chan *mv_chan;
-	struct device *dev = device->common.dev;
+	struct device *dev = device->dmadev.dev;
 
-	dma_async_device_unregister(&device->common);
+	dma_async_device_unregister(&device->dmadev);
 
 	dma_free_coherent(dev, device->pool_size,
 			  device->dma_desc_pool_virt, device->dma_desc_pool);
 
-	list_for_each_entry_safe(chan, _chan, &device->common.channels,
+	list_for_each_entry_safe(chan, _chan, &device->dmadev.channels,
 				 device_node) {
 		mv_chan = to_mv_xor_chan(chan);
 		list_del(&chan->device_node);
@@ -1107,7 +1107,7 @@ mv_xor_channel_add(struct mv_xor_private *msp,
 	if (!adev)
 		return ERR_PTR(-ENOMEM);
 
-	dma_dev = &adev->common;
+	dma_dev = &adev->dmadev;
 
 	/* allocate coherent memory for hardware descriptors
 	 * note: writecombine gives slightly better performance, but
drivers/dma/mv_xor.h +1 -1
index ad18f64..84255e6 100644
@@ -73,7 +73,7 @@ struct mv_xor_device {
 	dma_addr_t			dma_desc_pool;
 	void				*dma_desc_pool_virt;
 	size_t                          pool_size;
-	struct dma_device		common;
+	struct dma_device		dmadev;
 	struct mv_xor_private	        *shared;
 };
 
Signature · 1 line
1.7.9.5
#21 lore raw

PATCH 21/29 mv_xor: use mv_xor_chan pointers as arguments to self-test functions

In reply to Thomas Petazzoni

In preparation for the removal of the mv_xor_device structure, we directly pass mv_xor_chan pointers to the self-test functions included in the driver. These functions were anyway selecting the first (and only channel) available in each DMA device, so the behaviour is unchanged.

---
 drivers/dma/mv_xor.c |   17 ++++++-----------
 1 file changed, 6 insertions(+), 11 deletions(-)
drivers/dma/mv_xor.c +6 -11
index cbcc441..280430a 100644
@@ -898,7 +898,7 @@ static void mv_xor_issue_pending(struct dma_chan *chan)
  */
 #define MV_XOR_TEST_SIZE 2000
 
-static int __devinit mv_xor_memcpy_self_test(struct mv_xor_device *device)
+static int __devinit mv_xor_memcpy_self_test(struct mv_xor_chan *mv_chan)
 {
 	int i;
 	void *src, *dest;
@@ -922,10 +922,7 @@ static int __devinit mv_xor_memcpy_self_test(struct mv_xor_device *device)
 	for (i = 0; i < MV_XOR_TEST_SIZE; i++)
 		((u8 *) src)[i] = (u8)i;
 
-	/* Start copy, using first DMA channel */
-	dma_chan = container_of(device->dmadev.channels.next,
-				struct dma_chan,
-				device_node);
+	dma_chan = &mv_chan->dmachan;
 	if (mv_xor_alloc_chan_resources(dma_chan) < 1) {
 		err = -ENODEV;
 		goto out;
@@ -971,7 +968,7 @@ out:
 
 #define MV_XOR_NUM_SRC_TEST 4 /* must be <= 15 */
 static int __devinit
-mv_xor_xor_self_test(struct mv_xor_device *device)
+mv_xor_xor_self_test(struct mv_xor_chan *mv_chan)
 {
 	int i, src_idx;
 	struct page *dest;
@@ -1016,9 +1013,7 @@ mv_xor_xor_self_test(struct mv_xor_device *device)
 
 	memset(page_address(dest), 0, PAGE_SIZE);
 
-	dma_chan = container_of(device->dmadev.channels.next,
-				struct dma_chan,
-				device_node);
+	dma_chan = &mv_chan->dmachan;
 	if (mv_xor_alloc_chan_resources(dma_chan) < 1) {
 		err = -ENODEV;
 		goto out;
@@ -1183,14 +1178,14 @@ mv_xor_channel_add(struct mv_xor_private *msp,
 	list_add_tail(&mv_chan->dmachan.device_node, &dma_dev->channels);
 
 	if (dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask)) {
-		ret = mv_xor_memcpy_self_test(adev);
+		ret = mv_xor_memcpy_self_test(mv_chan);
 		dev_dbg(&pdev->dev, "memcpy self test returned %d\n", ret);
 		if (ret)
 			goto err_free_dma;
 	}
 
 	if (dma_has_cap(DMA_XOR, dma_dev->cap_mask)) {
-		ret = mv_xor_xor_self_test(adev);
+		ret = mv_xor_xor_self_test(mv_chan);
 		dev_dbg(&pdev->dev, "xor self test returned %d\n", ret);
 		if (ret)
 			goto err_free_dma;
Signature · 1 line
1.7.9.5
#22 lore raw

PATCH 22/29 mv_xor: merge mv_xor_device and mv_xor_chan

In reply to Thomas Petazzoni

Even though the DMA engine infrastructure has support for multiple channels per device, the mv_xor driver registers one DMA engine device for each channel, because the mv_xor channels inside the same XOR engine have different capabilities, and the DMA engine infrastructure only allows to express capabilities at the DMA engine device level.

The mv_xor driver has therefore been registering one DMA engine device and one DMA engine channel for each XOR channel since its introduction in the kernel. However, it kept two separate internal structures, mv_xor_device and mv_xor_channel, which didn't make a lot of sense since there was a 1:1 mapping between those structures.

This patch gets rid of this duplication, and merges everything into the mv_xor_chan structure.

---
 drivers/dma/mv_xor.c |   64 ++++++++++++++++++++++----------------------------
 drivers/dma/mv_xor.h |   25 +++++---------------
 2 files changed, 34 insertions(+), 55 deletions(-)
drivers/dma/mv_xor.c +28 -36
index 280430a..fc89139 100644
@@ -40,7 +40,7 @@ static void mv_xor_issue_pending(struct dma_chan *chan);
 	container_of(tx, struct mv_xor_desc_slot, async_tx)
 
 #define mv_chan_to_devp(chan)           \
-	((chan)->device->dmadev.dev)
+	((chan)->dmadev.dev)
 
 static void mv_desc_init(struct mv_xor_desc_slot *desc, unsigned long flags)
 {
@@ -603,7 +603,7 @@ static int mv_xor_alloc_chan_resources(struct dma_chan *chan)
 	int idx;
 	struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan);
 	struct mv_xor_desc_slot *slot = NULL;
-	int num_descs_in_pool = mv_chan->device->pool_size/MV_XOR_SLOT_SIZE;
+	int num_descs_in_pool = mv_chan->pool_size/MV_XOR_SLOT_SIZE;
 
 	/* Allocate descriptor slots */
 	idx = mv_chan->slots_allocated;
@@ -614,7 +614,7 @@ static int mv_xor_alloc_chan_resources(struct dma_chan *chan)
 				" %d descriptor slots", idx);
 			break;
 		}
-		hw_desc = (char *) mv_chan->device->dma_desc_pool_virt;
+		hw_desc = (char *) mv_chan->dma_desc_pool_virt;
 		slot->hw_desc = (void *) &hw_desc[idx * MV_XOR_SLOT_SIZE];
 
 		dma_async_tx_descriptor_init(&slot->async_tx, chan);
@@ -622,7 +622,7 @@ static int mv_xor_alloc_chan_resources(struct dma_chan *chan)
 		INIT_LIST_HEAD(&slot->chain_node);
 		INIT_LIST_HEAD(&slot->slot_node);
 		INIT_LIST_HEAD(&slot->tx_list);
-		hw_desc = (char *) mv_chan->device->dma_desc_pool;
+		hw_desc = (char *) mv_chan->dma_desc_pool;
 		slot->async_tx.phys =
 			(dma_addr_t) &hw_desc[idx * MV_XOR_SLOT_SIZE];
 		slot->idx = idx++;
@@ -1067,58 +1067,58 @@ out:
 	return err;
 }
 
-static int __devexit mv_xor_channel_remove(struct mv_xor_device *device)
+static int __devexit mv_xor_channel_remove(struct mv_xor_chan *mv_chan)
 {
 	struct dma_chan *chan, *_chan;
-	struct mv_xor_chan *mv_chan;
-	struct device *dev = device->dmadev.dev;
+	struct device *dev = mv_chan->dmadev.dev;
 
-	dma_async_device_unregister(&device->dmadev);
+	dma_async_device_unregister(&mv_chan->dmadev);
 
-	dma_free_coherent(dev, device->pool_size,
-			  device->dma_desc_pool_virt, device->dma_desc_pool);
+	dma_free_coherent(dev, mv_chan->pool_size,
+			  mv_chan->dma_desc_pool_virt, mv_chan->dma_desc_pool);
 
-	list_for_each_entry_safe(chan, _chan, &device->dmadev.channels,
+	list_for_each_entry_safe(chan, _chan, &mv_chan->dmadev.channels,
 				 device_node) {
-		mv_chan = to_mv_xor_chan(chan);
 		list_del(&chan->device_node);
 	}
 
 	return 0;
 }
 
-static struct mv_xor_device * __devinit
+static struct mv_xor_chan * __devinit
 mv_xor_channel_add(struct mv_xor_private *msp,
 		   struct platform_device *pdev,
 		   int hw_id, dma_cap_mask_t cap_mask,
 		   size_t pool_size, int irq)
 {
 	int ret = 0;
-	struct mv_xor_device *adev;
 	struct mv_xor_chan *mv_chan;
 	struct dma_device *dma_dev;
 
-	adev = devm_kzalloc(&pdev->dev, sizeof(*adev), GFP_KERNEL);
-	if (!adev)
-		return ERR_PTR(-ENOMEM);
+	mv_chan = devm_kzalloc(&pdev->dev, sizeof(*mv_chan), GFP_KERNEL);
+	if (!mv_chan) {
+		ret = -ENOMEM;
+		goto err_free_dma;
+	}
+
+	mv_chan->idx = hw_id;
 
-	dma_dev = &adev->dmadev;
+	dma_dev = &mv_chan->dmadev;
 
 	/* allocate coherent memory for hardware descriptors
 	 * note: writecombine gives slightly better performance, but
 	 * requires that we explicitly flush the writes
 	 */
-	adev->pool_size = pool_size;
-	adev->dma_desc_pool_virt = dma_alloc_writecombine(&pdev->dev,
-							  adev->pool_size,
-							  &adev->dma_desc_pool,
-							  GFP_KERNEL);
-	if (!adev->dma_desc_pool_virt)
+	mv_chan->pool_size = pool_size;
+	mv_chan->dma_desc_pool_virt =
+	  dma_alloc_writecombine(&pdev->dev, mv_chan->pool_size,
+				 &mv_chan->dma_desc_pool, GFP_KERNEL);
+	if (!mv_chan->dma_desc_pool_virt)
 		return ERR_PTR(-ENOMEM);
 
 	/* discover transaction capabilites from the platform data */
 	dma_dev->cap_mask = cap_mask;
-	adev->shared = msp;
+	mv_chan->shared = msp;
 
 	INIT_LIST_HEAD(&dma_dev->channels);
 
@@ -1139,15 +1139,7 @@ mv_xor_channel_add(struct mv_xor_private *msp,
 		dma_dev->device_prep_dma_xor = mv_xor_prep_dma_xor;
 	}
 
-	mv_chan = devm_kzalloc(&pdev->dev, sizeof(*mv_chan), GFP_KERNEL);
-	if (!mv_chan) {
-		ret = -ENOMEM;
-		goto err_free_dma;
-	}
-	mv_chan->device = adev;
-	mv_chan->idx = hw_id;
-	mv_chan->mmr_base = adev->shared->xor_base;
-
+	mv_chan->mmr_base = msp->xor_base;
 	if (!mv_chan->mmr_base) {
 		ret = -ENOMEM;
 		goto err_free_dma;
@@ -1199,11 +1191,11 @@ mv_xor_channel_add(struct mv_xor_private *msp,
 	  dma_has_cap(DMA_INTERRUPT, dma_dev->cap_mask) ? "intr " : "");
 
 	dma_async_device_register(dma_dev);
-	return adev;
+	return mv_chan;
 
  err_free_dma:
 	dma_free_coherent(&pdev->dev, pool_size,
-			adev->dma_desc_pool_virt, adev->dma_desc_pool);
+			  mv_chan->dma_desc_pool_virt, mv_chan->dma_desc_pool);
 	return ERR_PTR(ret);
 }
 
drivers/dma/mv_xor.h +6 -19
index 84255e6..16de1f6 100644
@@ -57,24 +57,7 @@ struct mv_xor_private {
 	void __iomem	     *xor_base;
 	void __iomem	     *xor_high_base;
 	struct clk	     *clk;
-	struct mv_xor_device *channels[MV_XOR_MAX_CHANNELS];
-};
-
-
-/**
- * struct mv_xor_device - internal representation of a XOR device
- * @pdev: Platform device
- * @id: HW XOR Device selector
- * @dma_desc_pool: base of DMA descriptor region (DMA address)
- * @dma_desc_pool_virt: base of DMA descriptor region (CPU address)
- * @common: embedded struct dma_device
- */
-struct mv_xor_device {
-	dma_addr_t			dma_desc_pool;
-	void				*dma_desc_pool_virt;
-	size_t                          pool_size;
-	struct dma_device		dmadev;
-	struct mv_xor_private	        *shared;
+	struct mv_xor_chan   *channels[MV_XOR_MAX_CHANNELS];
 };
 
 /**
@@ -100,7 +83,11 @@ struct mv_xor_chan {
 	enum dma_transaction_type	current_type;
 	struct list_head	chain;
 	struct list_head	completed_slots;
-	struct mv_xor_device	*device;
+	dma_addr_t		dma_desc_pool;
+	void			*dma_desc_pool_virt;
+	size_t                  pool_size;
+	struct dma_device	dmadev;
+	struct mv_xor_private	*shared;
 	struct dma_chan		dmachan;
 	struct mv_xor_desc_slot	*last_used;
 	struct list_head	all_slots;
Signature · 1 line
1.7.9.5
#23 lore raw

PATCH 23/29 mv_xor: rename mv_xor_private to mv_xor_device

In reply to Thomas Petazzoni

Now that mv_xor_device is no longer used to designate the per-channel DMA devices, use it know to designate the XOR engine themselves (currently composed of two XOR channels).

So, now we have the nice organization where:

- mv_xor_device represents each XOR engine in the system
- mv_xor_chan represents each XOR channel of a given XOR engine

---
 drivers/dma/mv_xor.c |   66 +++++++++++++++++++++++++-------------------------
 drivers/dma/mv_xor.h |    4 +--
 2 files changed, 35 insertions(+), 35 deletions(-)
drivers/dma/mv_xor.c +33 -33
index fc89139..d934f8b 100644
@@ -1086,7 +1086,7 @@ static int __devexit mv_xor_channel_remove(struct mv_xor_chan *mv_chan)
 }
 
 static struct mv_xor_chan * __devinit
-mv_xor_channel_add(struct mv_xor_private *msp,
+mv_xor_channel_add(struct mv_xor_device *xordev,
 		   struct platform_device *pdev,
 		   int hw_id, dma_cap_mask_t cap_mask,
 		   size_t pool_size, int irq)
@@ -1118,7 +1118,7 @@ mv_xor_channel_add(struct mv_xor_private *msp,
 
 	/* discover transaction capabilites from the platform data */
 	dma_dev->cap_mask = cap_mask;
-	mv_chan->shared = msp;
+	mv_chan->shared = xordev;
 
 	INIT_LIST_HEAD(&dma_dev->channels);
 
@@ -1139,7 +1139,7 @@ mv_xor_channel_add(struct mv_xor_private *msp,
 		dma_dev->device_prep_dma_xor = mv_xor_prep_dma_xor;
 	}
 
-	mv_chan->mmr_base = msp->xor_base;
+	mv_chan->mmr_base = xordev->xor_base;
 	if (!mv_chan->mmr_base) {
 		ret = -ENOMEM;
 		goto err_free_dma;
@@ -1200,10 +1200,10 @@ mv_xor_channel_add(struct mv_xor_private *msp,
 }
 
 static void
-mv_xor_conf_mbus_windows(struct mv_xor_private *msp,
+mv_xor_conf_mbus_windows(struct mv_xor_device *xordev,
 			 const struct mbus_dram_target_info *dram)
 {
-	void __iomem *base = msp->xor_base;
+	void __iomem *base = xordev->xor_base;
 	u32 win_enable = 0;
 	int i;
 
@@ -1233,50 +1233,50 @@ mv_xor_conf_mbus_windows(struct mv_xor_private *msp,
 static int mv_xor_probe(struct platform_device *pdev)
 {
 	const struct mbus_dram_target_info *dram;
-	struct mv_xor_private *msp;
+	struct mv_xor_device *xordev;
 	struct mv_xor_platform_data *pdata = pdev->dev.platform_data;
 	struct resource *res;
 	int i, ret;
 
 	dev_notice(&pdev->dev, "Marvell XOR driver\n");
 
-	msp = devm_kzalloc(&pdev->dev, sizeof(*msp), GFP_KERNEL);
-	if (!msp)
+	xordev = devm_kzalloc(&pdev->dev, sizeof(*xordev), GFP_KERNEL);
+	if (!xordev)
 		return -ENOMEM;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	if (!res)
 		return -ENODEV;
 
-	msp->xor_base = devm_ioremap(&pdev->dev, res->start,
-				     resource_size(res));
-	if (!msp->xor_base)
+	xordev->xor_base = devm_ioremap(&pdev->dev, res->start,
+					resource_size(res));
+	if (!xordev->xor_base)
 		return -EBUSY;
 
 	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 	if (!res)
 		return -ENODEV;
 
-	msp->xor_high_base = devm_ioremap(&pdev->dev, res->start,
-					  resource_size(res));
-	if (!msp->xor_high_base)
+	xordev->xor_high_base = devm_ioremap(&pdev->dev, res->start,
+					     resource_size(res));
+	if (!xordev->xor_high_base)
 		return -EBUSY;
 
-	platform_set_drvdata(pdev, msp);
+	platform_set_drvdata(pdev, xordev);
 
 	/*
 	 * (Re-)program MBUS remapping windows if we are asked to.
 	 */
 	dram = mv_mbus_dram_info();
 	if (dram)
-		mv_xor_conf_mbus_windows(msp, dram);
+		mv_xor_conf_mbus_windows(xordev, dram);
 
 	/* Not all platforms can gate the clock, so it is not
 	 * an error if the clock does not exists.
 	 */
-	msp->clk = clk_get(&pdev->dev, NULL);
-	if (!IS_ERR(msp->clk))
-		clk_prepare_enable(msp->clk);
+	xordev->clk = clk_get(&pdev->dev, NULL);
+	if (!IS_ERR(xordev->clk))
+		clk_prepare_enable(xordev->clk);
 
 	if (pdata && pdata->channels) {
 		for (i = 0; i < MV_XOR_MAX_CHANNELS; i++) {
@@ -1295,12 +1295,12 @@ static int mv_xor_probe(struct platform_device *pdev)
 				goto err_channel_add;
 			}
 
-			msp->channels[i] =
-				mv_xor_channel_add(msp, pdev, cd->hw_id,
+			xordev->channels[i] =
+				mv_xor_channel_add(xordev, pdev, cd->hw_id,
 						   cd->cap_mask,
 						   cd->pool_size, irq);
-			if (IS_ERR(msp->channels[i])) {
-				ret = PTR_ERR(msp->channels[i]);
+			if (IS_ERR(xordev->channels[i])) {
+				ret = PTR_ERR(xordev->channels[i]);
 				goto err_channel_add;
 			}
 		}
@@ -1310,27 +1310,27 @@ static int mv_xor_probe(struct platform_device *pdev)
 
 err_channel_add:
 	for (i = 0; i < MV_XOR_MAX_CHANNELS; i++)
-		if (msp->channels[i])
-			mv_xor_channel_remove(msp->channels[i]);
+		if (xordev->channels[i])
+			mv_xor_channel_remove(xordev->channels[i]);
 
-	clk_disable_unprepare(msp->clk);
-	clk_put(msp->clk);
+	clk_disable_unprepare(xordev->clk);
+	clk_put(xordev->clk);
 	return ret;
 }
 
 static int mv_xor_remove(struct platform_device *pdev)
 {
-	struct mv_xor_private *msp = platform_get_drvdata(pdev);
+	struct mv_xor_device *xordev = platform_get_drvdata(pdev);
 	int i;
 
 	for (i = 0; i < MV_XOR_MAX_CHANNELS; i++) {
-		if (msp->channels[i])
-			mv_xor_channel_remove(msp->channels[i]);
+		if (xordev->channels[i])
+			mv_xor_channel_remove(xordev->channels[i]);
 	}
 
-	if (!IS_ERR(msp->clk)) {
-		clk_disable_unprepare(msp->clk);
-		clk_put(msp->clk);
+	if (!IS_ERR(xordev->clk)) {
+		clk_disable_unprepare(xordev->clk);
+		clk_put(xordev->clk);
 	}
 
 	return 0;
drivers/dma/mv_xor.h +2 -2
index 16de1f6..cedeaa0 100644
@@ -53,7 +53,7 @@
 #define WINDOW_REMAP_HIGH(w)	(0x290 + ((w) << 2))
 #define WINDOW_BAR_ENABLE(chan)	(0x240 + ((chan) << 2))
 
-struct mv_xor_private {
+struct mv_xor_device {
 	void __iomem	     *xor_base;
 	void __iomem	     *xor_high_base;
 	struct clk	     *clk;
@@ -87,7 +87,7 @@ struct mv_xor_chan {
 	void			*dma_desc_pool_virt;
 	size_t                  pool_size;
 	struct dma_device	dmadev;
-	struct mv_xor_private	*shared;
+	struct mv_xor_device	*shared;
 	struct dma_chan		dmachan;
 	struct mv_xor_desc_slot	*last_used;
 	struct list_head	all_slots;
Signature · 1 line
1.7.9.5
#24 lore raw

PATCH 24/29 mv_xor: remove useless backpointer from mv_xor_chan to mv_xor_device

In reply to Thomas Petazzoni

The backpointer from mv_xor_chan to mv_xor_device is now useless, get rid of it.

---
 drivers/dma/mv_xor.c |    1 -
 drivers/dma/mv_xor.h |    1 -
 2 files changed, 2 deletions(-)
drivers/dma/mv_xor.c +0 -1
index d934f8b..4e941f2 100644
@@ -1118,7 +1118,6 @@ mv_xor_channel_add(struct mv_xor_device *xordev,
 
 	/* discover transaction capabilites from the platform data */
 	dma_dev->cap_mask = cap_mask;
-	mv_chan->shared = xordev;
 
 	INIT_LIST_HEAD(&dma_dev->channels);
 
drivers/dma/mv_xor.h +0 -1
index cedeaa0..dab9f30 100644
@@ -87,7 +87,6 @@ struct mv_xor_chan {
 	void			*dma_desc_pool_virt;
 	size_t                  pool_size;
 	struct dma_device	dmadev;
-	struct mv_xor_device	*shared;
 	struct dma_chan		dmachan;
 	struct mv_xor_desc_slot	*last_used;
 	struct list_head	all_slots;
Signature · 1 line
1.7.9.5
#25 lore raw

PATCH 25/29 mv_xor: remove hw_id field from platform_data

In reply to Thomas Petazzoni

There is no need for the platform_data to give this ID, it is simply the channel number, so we can compute it inside the driver when registering the channels.

---
 arch/arm/plat-orion/common.c             |    4 ----
 drivers/dma/mv_xor.c                     |    6 +++---
 include/linux/platform_data/dma-mv_xor.h |    1 -
 3 files changed, 3 insertions(+), 8 deletions(-)
arch/arm/plat-orion/common.c +0 -4
index 31517ce..09d8360 100644
@@ -627,11 +627,9 @@ static struct resource orion_xor0_shared_resources[] = {
 
 static struct mv_xor_channel_data orion_xor0_channels_data[2] = {
 	{
-		.hw_id		= 0,
 		.pool_size	= PAGE_SIZE,
 	},
 	{
-		.hw_id		= 1,
 		.pool_size	= PAGE_SIZE,
 	},
 };
@@ -702,11 +700,9 @@ static struct resource orion_xor1_shared_resources[] = {
 
 static struct mv_xor_channel_data orion_xor1_channels_data[2] = {
 	{
-		.hw_id		= 0,
 		.pool_size	= PAGE_SIZE,
 	},
 	{
-		.hw_id		= 1,
 		.pool_size	= PAGE_SIZE,
 	},
 };
drivers/dma/mv_xor.c +3 -3
index 4e941f2..4236d02 100644
@@ -1088,7 +1088,7 @@ static int __devexit mv_xor_channel_remove(struct mv_xor_chan *mv_chan)
 static struct mv_xor_chan * __devinit
 mv_xor_channel_add(struct mv_xor_device *xordev,
 		   struct platform_device *pdev,
-		   int hw_id, dma_cap_mask_t cap_mask,
+		   int idx, dma_cap_mask_t cap_mask,
 		   size_t pool_size, int irq)
 {
 	int ret = 0;
@@ -1101,7 +1101,7 @@ mv_xor_channel_add(struct mv_xor_device *xordev,
 		goto err_free_dma;
 	}
 
-	mv_chan->idx = hw_id;
+	mv_chan->idx = idx;
 
 	dma_dev = &mv_chan->dmadev;
 
@@ -1295,7 +1295,7 @@ static int mv_xor_probe(struct platform_device *pdev)
 			}
 
 			xordev->channels[i] =
-				mv_xor_channel_add(xordev, pdev, cd->hw_id,
+				mv_xor_channel_add(xordev, pdev, i,
 						   cd->cap_mask,
 						   cd->pool_size, irq);
 			if (IS_ERR(xordev->channels[i])) {
include/linux/platform_data/dma-mv_xor.h +0 -1
index 367bb21..b18dc24 100644
@@ -13,7 +13,6 @@
 #define MV_XOR_NAME	"mv_xor"
 
 struct mv_xor_channel_data {
-	int				hw_id;
 	dma_cap_mask_t			cap_mask;
 	size_t				pool_size;
 };
Signature · 1 line
1.7.9.5
#26 lore raw

PATCH 26/29 mv_xor: remove the pool_size from platform_data

In reply to Thomas Petazzoni

The pool_size is always PAGE_SIZE, and since it is a software configuration paramter (and not a hardware description parameter), we cannot make it part of the Device Tree binding, so we'd better remove it from the platform_data as well.

---
 arch/arm/plat-orion/common.c             |   18 ++----------------
 drivers/dma/mv_xor.c                     |   15 ++++++---------
 drivers/dma/mv_xor.h                     |    1 +
 include/linux/platform_data/dma-mv_xor.h |    1 -
 4 files changed, 9 insertions(+), 26 deletions(-)
arch/arm/plat-orion/common.c +2 -16
index 09d8360..2d4b641 100644
@@ -625,14 +625,7 @@ static struct resource orion_xor0_shared_resources[] = {
 	},
 };
 
-static struct mv_xor_channel_data orion_xor0_channels_data[2] = {
-	{
-		.pool_size	= PAGE_SIZE,
-	},
-	{
-		.pool_size	= PAGE_SIZE,
-	},
-};
+static struct mv_xor_channel_data orion_xor0_channels_data[2];
 
 static struct mv_xor_platform_data orion_xor0_pdata = {
 	.channels = orion_xor0_channels_data,
@@ -698,14 +691,7 @@ static struct resource orion_xor1_shared_resources[] = {
 	},
 };
 
-static struct mv_xor_channel_data orion_xor1_channels_data[2] = {
-	{
-		.pool_size	= PAGE_SIZE,
-	},
-	{
-		.pool_size	= PAGE_SIZE,
-	},
-};
+static struct mv_xor_channel_data orion_xor1_channels_data[2];
 
 static struct mv_xor_platform_data orion_xor1_pdata = {
 	.channels = orion_xor1_channels_data,
drivers/dma/mv_xor.c +6 -9
index 4236d02..e7c5366 100644
@@ -603,7 +603,7 @@ static int mv_xor_alloc_chan_resources(struct dma_chan *chan)
 	int idx;
 	struct mv_xor_chan *mv_chan = to_mv_xor_chan(chan);
 	struct mv_xor_desc_slot *slot = NULL;
-	int num_descs_in_pool = mv_chan->pool_size/MV_XOR_SLOT_SIZE;
+	int num_descs_in_pool = MV_XOR_POOL_SIZE/MV_XOR_SLOT_SIZE;
 
 	/* Allocate descriptor slots */
 	idx = mv_chan->slots_allocated;
@@ -1074,7 +1074,7 @@ static int __devexit mv_xor_channel_remove(struct mv_xor_chan *mv_chan)
 
 	dma_async_device_unregister(&mv_chan->dmadev);
 
-	dma_free_coherent(dev, mv_chan->pool_size,
+	dma_free_coherent(dev, MV_XOR_POOL_SIZE,
 			  mv_chan->dma_desc_pool_virt, mv_chan->dma_desc_pool);
 
 	list_for_each_entry_safe(chan, _chan, &mv_chan->dmadev.channels,
@@ -1088,8 +1088,7 @@ static int __devexit mv_xor_channel_remove(struct mv_xor_chan *mv_chan)
 static struct mv_xor_chan * __devinit
 mv_xor_channel_add(struct mv_xor_device *xordev,
 		   struct platform_device *pdev,
-		   int idx, dma_cap_mask_t cap_mask,
-		   size_t pool_size, int irq)
+		   int idx, dma_cap_mask_t cap_mask, int irq)
 {
 	int ret = 0;
 	struct mv_xor_chan *mv_chan;
@@ -1109,9 +1108,8 @@ mv_xor_channel_add(struct mv_xor_device *xordev,
 	 * note: writecombine gives slightly better performance, but
 	 * requires that we explicitly flush the writes
 	 */
-	mv_chan->pool_size = pool_size;
 	mv_chan->dma_desc_pool_virt =
-	  dma_alloc_writecombine(&pdev->dev, mv_chan->pool_size,
+	  dma_alloc_writecombine(&pdev->dev, MV_XOR_POOL_SIZE,
 				 &mv_chan->dma_desc_pool, GFP_KERNEL);
 	if (!mv_chan->dma_desc_pool_virt)
 		return ERR_PTR(-ENOMEM);
@@ -1193,7 +1191,7 @@ mv_xor_channel_add(struct mv_xor_device *xordev,
 	return mv_chan;
 
  err_free_dma:
-	dma_free_coherent(&pdev->dev, pool_size,
+	dma_free_coherent(&pdev->dev, MV_XOR_POOL_SIZE,
 			  mv_chan->dma_desc_pool_virt, mv_chan->dma_desc_pool);
 	return ERR_PTR(ret);
 }
@@ -1296,8 +1294,7 @@ static int mv_xor_probe(struct platform_device *pdev)
 
 			xordev->channels[i] =
 				mv_xor_channel_add(xordev, pdev, i,
-						   cd->cap_mask,
-						   cd->pool_size, irq);
+						   cd->cap_mask, irq);
 			if (IS_ERR(xordev->channels[i])) {
 				ret = PTR_ERR(xordev->channels[i]);
 				goto err_channel_add;
drivers/dma/mv_xor.h +1 -0
index dab9f30..698b448 100644
@@ -24,6 +24,7 @@
 #include <linux/interrupt.h>
 
 #define USE_TIMER
+#define MV_XOR_POOL_SIZE		PAGE_SIZE
 #define MV_XOR_SLOT_SIZE		64
 #define MV_XOR_THRESHOLD		1
 #define MV_XOR_MAX_CHANNELS             2
include/linux/platform_data/dma-mv_xor.h +0 -1
index b18dc24..8ec18f6 100644
@@ -14,7 +14,6 @@
 
 struct mv_xor_channel_data {
 	dma_cap_mask_t			cap_mask;
-	size_t				pool_size;
 };
 
 struct mv_xor_platform_data {
Signature · 1 line
1.7.9.5
#27 lore raw

PATCH 27/29 mv_xor: add missing free_irq() call

In reply to Thomas Petazzoni

Even though the driver cannot be unloaded at the moment, it is still good to properly free the IRQ handlers in the channel removal function.

---
 drivers/dma/mv_xor.c |    5 ++++-
 drivers/dma/mv_xor.h |    1 +
 2 files changed, 5 insertions(+), 1 deletion(-)
drivers/dma/mv_xor.c +4 -1
index e7c5366..71cbb0e 100644
@@ -1082,6 +1082,8 @@ static int __devexit mv_xor_channel_remove(struct mv_xor_chan *mv_chan)
 		list_del(&chan->device_node);
 	}
 
+	free_irq(mv_chan->irq, mv_chan);
+
 	return 0;
 }
 
@@ -1101,6 +1103,7 @@ mv_xor_channel_add(struct mv_xor_device *xordev,
 	}
 
 	mv_chan->idx = idx;
+	mv_chan->irq = irq;
 
 	dma_dev = &mv_chan->dmadev;
 
@@ -1147,7 +1150,7 @@ mv_xor_channel_add(struct mv_xor_device *xordev,
 	/* clear errors before enabling interrupts */
 	mv_xor_device_clear_err_status(mv_chan);
 
-	ret = devm_request_irq(&pdev->dev, irq,
+	ret = devm_request_irq(&pdev->dev, mv_chan->irq,
 			       mv_xor_interrupt_handler,
 			       0, dev_name(&pdev->dev), mv_chan);
 	if (ret)
drivers/dma/mv_xor.h +1 -0
index 698b448..1704328 100644
@@ -81,6 +81,7 @@ struct mv_xor_chan {
 	spinlock_t		lock; /* protects the descriptor slot pool */
 	void __iomem		*mmr_base;
 	unsigned int		idx;
+	int                     irq;
 	enum dma_transaction_type	current_type;
 	struct list_head	chain;
 	struct list_head	completed_slots;
Signature · 1 line
1.7.9.5
#28 lore raw

PATCH 28/29 mv_xor: add Device Tree binding

In reply to Thomas Petazzoni
Cc devicetree-discuss at lists.ozlabs.org
---
 Documentation/devicetree/bindings/dma/mv-xor.txt |   40 +++++++++++++++
 drivers/dma/mv_xor.c                             |   57 ++++++++++++++++++++--
 2 files changed, 93 insertions(+), 4 deletions(-)
 create mode 100644 Documentation/devicetree/bindings/dma/mv-xor.txt
Documentation/devicetree/bindings/dma/mv-xor.txt new file +40 -0
new file mode 100644
index 0000000..7c6cb7f
@@ -0,0 +1,40 @@
+* Marvell XOR engines
+
+Required properties:
+- compatible: Should be "marvell,orion-xor"
+- reg: Should contain registers location and length (two sets)
+    the first set is the low registers, the second set the high
+    registers for the XOR engine.
+- clocks: pointer to the reference clock
+
+The DT node must also contains sub-nodes for each XOR channel that the
+XOR engine has. Those sub-nodes have the following required
+properties:
+- interrupts: interrupt of the XOR channel
+
+And the following optional properties:
+- dmacap,memcpy to indicate that the XOR channel is capable of memcpy operations
+- dmacap,memset to indicate that the XOR channel is capable of memset operations
+- dmacap,xor to indicate that the XOR channel is capable of xor operations
+
+Example:
+
+xor at d0060900 {
+	compatible = "marvell,orion-xor";
+	reg = <0xd0060900 0x100
+	       0xd0060b00 0x100>;
+	clocks = <&coreclk 0>;
+	status = "okay";
+
+	xor00 {
+	      interrupts = <51>;
+	      dmacap,memcpy;
+	      dmacap,xor;
+	};
+	xor01 {
+	      interrupts = <52>;
+	      dmacap,memcpy;
+	      dmacap,xor;
+	      dmacap,memset;
+	};
+};
drivers/dma/mv_xor.c +53 -4

86 lines not on this page · raw message

Signature · 1 line
1.7.9.5
#29 lore raw

PATCH 29/29 arm: mvebu: add XOR engines to Armada 370/XP .dtsi

In reply to Thomas Petazzoni

This patch adds the necessary DT data in the Armada 370/XP Device Trees.

---
 arch/arm/boot/dts/armada-370-xp.dtsi |   20 ++++++++++++++++++++
 1 file changed, 20 insertions(+)
arch/arm/boot/dts/armada-370-xp.dtsi +20 -0
index 94b4b9e..8a3d490 100644
@@ -69,6 +69,26 @@
 			compatible = "marvell,armada-addr-decoding-controller";
 			reg = <0xd0020000 0x258>;
 		};
+
+		xor at d0060900 {
+			compatible = "marvell,orion-xor";
+			reg = <0xd0060900 0x100
+			       0xd0060b00 0x100>;
+			clocks = <&coreclk 0>;
+			status = "okay";
+
+			xor00 {
+			      interrupts = <51>;
+			      dmacap,memcpy;
+			      dmacap,xor;
+			};
+			xor01 {
+			      interrupts = <52>;
+			      dmacap,memcpy;
+			      dmacap,xor;
+			      dmacap,memset;
+			};
+		};
 	};
 };
 
Signature · 1 line
1.7.9.5
maintainer
#30 lore raw

PATCH 1/1 Device Tree binding for the 'mv_xor' XOR engine DMA driver

In reply to Thomas Petazzoni
Quoted 5 lines · Thomas Petazzoni

Hello,

This patch set adds a Device Tree binding for the Marvell XOR engine driver, which allows to support these XOR engines in the Armada 370 and Armada XP SoCs.

Hi Thomas

I tested on kirkwood, both old style and DT. I tested using the dmatest kernel module. That shows up an old issue, pre-dating your patchset. It dmatest dereferences a NULL pointer during cleanup, due to a missing function in the driver. I will submit a patch for this soon.

The dmatest shows up a second issue:

root at qnap:~# insmod ./dmatest.ko iterations=100
dmatest: Started 2 threads using dma0chan0
dmatest: Started 2 threads using dma1chan0
dmatest: Started 2 threads using dma2chan0
dmatest: Started 2 threads using dma3chan0
dma3chan0-xor0: #3: prep error with src_off=0x13c2 dst_off=0x2c7c len=0x5d
dma1chan0-copy0: #16: prep error with src_off=0x1f50 dst_off=0x904 len=0x33
dma3chan0-copy0: #22: prep error with src_off=0x14c2 dst_off=0x389b len=0x6f
dma0chan0-copy0: #31: prep error with src_off=0x10b6 dst_off=0x323c len=0x2f
dma3chan0-copy0: #49: prep error with src_off=0x17b5 dst_off=0x3eca len=0x29

The driver refuses any operation where the buffer is less than 128 bytes. The datasheet for Kirkwood says the buffer length must be 8 bytes or more. So maybe we should reduce this 128 limit down to 8?

But is the driver allowed to refuse small copies? Is the caller expected to fall back to software? Does the dma core implement this fallback? Lots of questions i don't know the answers to.

Anyway, you can add a

since with your patches it works just as well as before your patches.

Andrew

#31 lore raw

PATCH 1/1 Device Tree binding for the 'mv_xor' XOR engine DMA driver

Dear Andrew Lunn,

Quoted 5 lines · Andrew Lunn

I tested on kirkwood, both old style and DT. I tested using the dmatest kernel module. That shows up an old issue, pre-dating your patchset. It dmatest dereferences a NULL pointer during cleanup, due to a missing function in the driver. I will submit a patch for this soon.

Ok.

Quoted 13 lines

The dmatest shows up a second issue:

root at qnap:~# insmod ./dmatest.ko iterations=100
dmatest: Started 2 threads using dma0chan0
dmatest: Started 2 threads using dma1chan0
dmatest: Started 2 threads using dma2chan0
dmatest: Started 2 threads using dma3chan0
dma3chan0-xor0: #3: prep error with src_off=0x13c2 dst_off=0x2c7c len=0x5d
dma1chan0-copy0: #16: prep error with src_off=0x1f50 dst_off=0x904 len=0x33
dma3chan0-copy0: #22: prep error with src_off=0x14c2 dst_off=0x389b len=0x6f
dma0chan0-copy0: #31: prep error with src_off=0x10b6 dst_off=0x323c len=0x2f
dma3chan0-copy0: #49: prep error with src_off=0x17b5 dst_off=0x3eca len=0x29

Quoted 7 lines

The driver refuses any operation where the buffer is less than 128 bytes. The datasheet for Kirkwood says the buffer length must be 8 bytes or more. So maybe we should reduce this 128 limit down to 8?

But is the driver allowed to refuse small copies? Is the caller expected to fall back to software? Does the dma core implement this fallback? Lots of questions i don't know the answers to.

Thanks a lot for all this testing. I guess we can try to sort out those issues as follow-up patches. I'll add bug tracker entries for those items so that we remember to get to them at some point.

Quoted 5 lines

Anyway, you can add a

since with your patches it works just as well as before your patches.

Excellent, thanks!

I'll try to fix the few issues found by Sebastian tomorrow, integrate your two patches and send a formal pull request to Jason if you're OK.

Best regards,

Thomas

Signature · 4 lines
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
maintainer
#32 lore raw

PATCH 1/1 Device Tree binding for the 'mv_xor' XOR engine DMA driver

Hi Thomas

Quoted 2 lines

I'll try to fix the few issues found by Sebastian tomorrow, integrate your two patches and send a formal pull request to Jason if you're OK.

Yes, thats O.K.

Andrew

#33 lore raw

PATCH 1/1 Device Tree binding for the 'mv_xor' XOR engine DMA driver

In reply to Andrew Lunn
Quoted 42 lines

-----Original Message-----
From: Andrew Lunn [mailto:andrew at lunn.ch]
Sent: Sunday, November 18, 2012 12:36 PM
To: Thomas Petazzoni
Cc: Vinod Koul; Dan Williams; Saeed Bishara; Jason Cooper; Andrew Lunn; Gregory Clement; Lior Amsalem; Maen Suleiman; linux-arm- kernel at lists.infradead.org; Sebastian Hesselbarth
Subject: Re: [PATCH] Device Tree binding for the 'mv_xor' XOR engine DMA driver

Quoted 5 lines · Thomas Petazzoni

Hello,

This patch set adds a Device Tree binding for the Marvell XOR engine driver, which allows to support these XOR engines in the Armada 370 and Armada XP SoCs.

Hi Thomas

I tested on kirkwood, both old style and DT. I tested using the dmatest kernel module. That shows up an old issue, pre-dating your patchset. It dmatest dereferences a NULL pointer during cleanup, due to a missing function in the driver. I will submit a patch for this soon.

The dmatest shows up a second issue:

root at qnap:~# insmod ./dmatest.ko iterations=100
dmatest: Started 2 threads using dma0chan0
dmatest: Started 2 threads using dma1chan0
dmatest: Started 2 threads using dma2chan0
dmatest: Started 2 threads using dma3chan0
dma3chan0-xor0: #3: prep error with src_off=0x13c2 dst_off=0x2c7c len=0x5d
dma1chan0-copy0: #16: prep error with src_off=0x1f50 dst_off=0x904 len=0x33
dma3chan0-copy0: #22: prep error with src_off=0x14c2 dst_off=0x389b len=0x6f
dma0chan0-copy0: #31: prep error with src_off=0x10b6 dst_off=0x323c len=0x2f
dma3chan0-copy0: #49: prep error with src_off=0x17b5 dst_off=0x3eca len=0x29

Quoted 3 lines

The driver refuses any operation where the buffer is less than 128 bytes. The datasheet for Kirkwood says the buffer length must be 8 bytes or more. So maybe we should reduce this 128 limit down to 8?

This limitation (128B) is only in memset operations (set in registers and not descriptors). If I recall correctly the limit is 16B and not 8B.

In any way, this 128 bytes seems like a good logical boundary for XOR HW enabling. (performance wise)

Quoted 5 lines

But is the driver allowed to refuse small copies? Is the caller expected to fall back to software? Does the dma core implement this fallback? Lots of questions i don't know the answers to.

Quoted 7 lines

Anyway, you can add a

since with your patches it works just as well as before your patches.

Andrew

Regards,
Lior Amsalem

maintainer
#34 lore raw

PATCH 1/1 Device Tree binding for the 'mv_xor' XOR engine DMA driver

Quoted 18 lines
Quoted 18 lines

The dmatest shows up a second issue:

root at qnap:~# insmod ./dmatest.ko iterations=100
dmatest: Started 2 threads using dma0chan0
dmatest: Started 2 threads using dma1chan0
dmatest: Started 2 threads using dma2chan0
dmatest: Started 2 threads using dma3chan0
dma3chan0-xor0: #3: prep error with src_off=0x13c2 dst_off=0x2c7c len=0x5d
dma1chan0-copy0: #16: prep error with src_off=0x1f50 dst_off=0x904 len=0x33
dma3chan0-copy0: #22: prep error with src_off=0x14c2 dst_off=0x389b len=0x6f
dma0chan0-copy0: #31: prep error with src_off=0x10b6 dst_off=0x323c len=0x2f
dma3chan0-copy0: #49: prep error with src_off=0x17b5 dst_off=0x3eca len=0x29

Quoted 8 lines
Quoted 3 lines

The driver refuses any operation where the buffer is less than 128 bytes. The datasheet for Kirkwood says the buffer length must be 8 bytes or more. So maybe we should reduce this 128 limit down to 8?

This limitation (128B) is only in memset operations (set in registers and not descriptors). If I recall correctly the limit is 16B and not 8B.

In any way, this 128 bytes seems like a good logical boundary for XOR HW enabling. (performance wise)

Hi Lior

Agreed. Anything smaller than that, and you spend more time setting up the hardware and dealing with interrupts when its finished than doing it in software.

I had quick look at some of the call sites. Users of the DMA API under the crypto directory all fall back to software operations when the DMA API returns an error. Also, raid uses the crypto API for memcpy and XOR. So raid seems O.K. I could not find any other users of the DMA API for _xor, _copy, or _memset. So it seems safe to return an error for inefficient usage.

Andrew

#35 lore raw

PATCH 1/1 Device Tree binding for the 'mv_xor' XOR engine DMA driver

Quoted 45 lines

-----Original Message-----
From: Andrew Lunn [mailto:andrew at lunn.ch]
Sent: Monday, November 19, 2012 8:41 AM
To: Lior Amsalem
Cc: Andrew Lunn; Thomas Petazzoni; Vinod Koul; Dan Williams; Saeed Bishara; Jason Cooper; Gregory Clement; Maen Suleiman; linux-arm- kernel at lists.infradead.org; Sebastian Hesselbarth
Subject: Re: [PATCH] Device Tree binding for the 'mv_xor' XOR engine DMA driver

Quoted 18 lines
Quoted 18 lines

The dmatest shows up a second issue:

root at qnap:~# insmod ./dmatest.ko iterations=100
dmatest: Started 2 threads using dma0chan0
dmatest: Started 2 threads using dma1chan0
dmatest: Started 2 threads using dma2chan0
dmatest: Started 2 threads using dma3chan0
dma3chan0-xor0: #3: prep error with src_off=0x13c2 dst_off=0x2c7c len=0x5d
dma1chan0-copy0: #16: prep error with src_off=0x1f50 dst_off=0x904 len=0x33
dma3chan0-copy0: #22: prep error with src_off=0x14c2 dst_off=0x389b len=0x6f
dma0chan0-copy0: #31: prep error with src_off=0x10b6 dst_off=0x323c len=0x2f
dma3chan0-copy0: #49: prep error with src_off=0x17b5 dst_off=0x3eca len=0x29

Quoted 5 lines
Quoted 3 lines

The driver refuses any operation where the buffer is less than 128 bytes. The datasheet for Kirkwood says the buffer length must be 8 bytes or more. So maybe we should reduce this 128 limit down to 8?

This limitation (128B) is only in memset operations (set in registers and not

descriptors).

Quoted 4 lines

If I recall correctly the limit is 16B and not 8B.

In any way, this 128 bytes seems like a good logical boundary for XOR HW enabling. (performance wise)

Hi Lior

Agreed. Anything smaller than that, and you spend more time setting up the hardware and dealing with interrupts when its finished than doing it in software.

Quoted 5 lines

I had quick look at some of the call sites. Users of the DMA API under the crypto directory all fall back to software operations when the DMA API returns an error. Also, raid uses the crypto API for memcpy and XOR. So raid seems O.K. I could not find any other users of the DMA API for _xor, _copy, or _memset. So it seems safe to return an error for inefficient usage.

I'm not aware for any other user of the DMA APIs, we use it mainly for RAID5 XOR offload. So yes, it seems ok to return an error.

Quoted 2 lines

Andrew

Regards,
Lior Amsalem