linux-arm-kernel.lists.infradead.org archive mirror
 help / color / mirror / Atom feed
* [PATCHv3 0/3] mv_xor improvements
@ 2015-12-22 10:43 Thomas Petazzoni
  2015-12-22 10:43 ` [PATCHv3 1/3] dmaengine: mv_xor: remove mv_xor_chan->current_type field Thomas Petazzoni
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Thomas Petazzoni @ 2015-12-22 10:43 UTC (permalink / raw)
  To: linux-arm-kernel

Hello Vinod,

Here is the third iteration of some mv_xor improvements patches. The
previous iteration was sent in July earlier this year. Compared to the
v2:

 - rebased on top of v4.4-rc1

 - dropped patches that were merged

 - as you suggested, add a comment in the code to explain that our
   suspend/resume implementation makes the assumption that there are
   no in-flight DMA transactions because mv_xor is only used for
   RAID5, and the block layer will have already suspended I/O
   activity, so not special care needs to be taken in the driver
   itself.

I have retested this with a RAID5 array on Armada 388 GP, while the
array is in reconstruction, and doing some suspend/resume cycles in
the middle.

Thanks!

Thomas

Thomas Petazzoni (3):
  dmaengine: mv_xor: remove mv_xor_chan->current_type field
  dmaengine: mv_xor: de-duplicate mv_chan_set_mode*()
  dmaengine: mv_xor: add suspend/resume support

 drivers/dma/mv_xor.c | 95 +++++++++++++++++++++++++++++++---------------------
 drivers/dma/mv_xor.h |  2 +-
 2 files changed, 57 insertions(+), 40 deletions(-)

-- 
2.6.4

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

* [PATCHv3 1/3] dmaengine: mv_xor: remove mv_xor_chan->current_type field
  2015-12-22 10:43 [PATCHv3 0/3] mv_xor improvements Thomas Petazzoni
@ 2015-12-22 10:43 ` Thomas Petazzoni
  2015-12-22 10:43 ` [PATCHv3 2/3] dmaengine: mv_xor: de-duplicate mv_chan_set_mode*() Thomas Petazzoni
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Thomas Petazzoni @ 2015-12-22 10:43 UTC (permalink / raw)
  To: linux-arm-kernel

Since commit 3e4f52e2da9f6 ("dma: mv_xor: Simplify the DMA_MEMCPY
operation"), this field is no longer used, so get rid of it.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Reviewed-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/dma/mv_xor.c | 1 -
 drivers/dma/mv_xor.h | 1 -
 2 files changed, 2 deletions(-)

diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index 1c2de9a..2d03379 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -169,7 +169,6 @@ static void mv_chan_set_mode(struct mv_xor_chan *chan,
 #endif
 
 	writel_relaxed(config, XOR_CONFIG(chan));
-	chan->current_type = type;
 }
 
 static void mv_chan_set_mode_to_desc(struct mv_xor_chan *chan)
diff --git a/drivers/dma/mv_xor.h b/drivers/dma/mv_xor.h
index b7455b4..3438914 100644
--- a/drivers/dma/mv_xor.h
+++ b/drivers/dma/mv_xor.h
@@ -110,7 +110,6 @@ struct mv_xor_chan {
 	void __iomem		*mmr_high_base;
 	unsigned int		idx;
 	int                     irq;
-	enum dma_transaction_type	current_type;
 	struct list_head	chain;
 	struct list_head	free_slots;
 	struct list_head	allocated_slots;
-- 
2.6.4

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

* [PATCHv3 2/3] dmaengine: mv_xor: de-duplicate mv_chan_set_mode*()
  2015-12-22 10:43 [PATCHv3 0/3] mv_xor improvements Thomas Petazzoni
  2015-12-22 10:43 ` [PATCHv3 1/3] dmaengine: mv_xor: remove mv_xor_chan->current_type field Thomas Petazzoni
@ 2015-12-22 10:43 ` Thomas Petazzoni
  2015-12-22 10:43 ` [PATCHv3 3/3] dmaengine: mv_xor: add suspend/resume support Thomas Petazzoni
  2016-01-06 10:13 ` [PATCHv3 0/3] mv_xor improvements Vinod Koul
  3 siblings, 0 replies; 5+ messages in thread
From: Thomas Petazzoni @ 2015-12-22 10:43 UTC (permalink / raw)
  To: linux-arm-kernel

When commit 6f166312c6ea2 ("dmaengine: mv_xor: add support for a38x
command in descriptor mode") added support for the descriptor mode
available in Marvell Armada 38x and later SoCs, it added a new
function mv_chan_set_mode_to_desc() which allows to configure a XOR
channel to get the specific operation to be done from each individual
DMA descriptor.

However, this function was mainly a duplicate of the existing
mv_chan_set_mode(), with just the operation being different.

This commit re-organizes the code into a single mv_chan_set_mode()
function, which takes the operation mode as argument, and the
mv_xor_channel_add() function decides whether to use
XOR_OPERATION_MODE_IN_DESC or XOR_OPERATION_MODE_XOR.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
Reviewed-by: Maxime Ripard <maxime.ripard@free-electrons.com>
---
 drivers/dma/mv_xor.c | 41 +++--------------------------------------
 1 file changed, 3 insertions(+), 38 deletions(-)

diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index 2d03379..a95878c 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -139,45 +139,10 @@ static void mv_chan_clear_err_status(struct mv_xor_chan *chan)
 }
 
 static void mv_chan_set_mode(struct mv_xor_chan *chan,
-			     enum dma_transaction_type type)
+			     u32 op_mode)
 {
-	u32 op_mode;
 	u32 config = readl_relaxed(XOR_CONFIG(chan));
 
-	switch (type) {
-	case DMA_XOR:
-		op_mode = XOR_OPERATION_MODE_XOR;
-		break;
-	case DMA_MEMCPY:
-		op_mode = XOR_OPERATION_MODE_MEMCPY;
-		break;
-	default:
-		dev_err(mv_chan_to_devp(chan),
-			"error: unsupported operation %d\n",
-			type);
-		BUG();
-		return;
-	}
-
-	config &= ~0x7;
-	config |= op_mode;
-
-#if defined(__BIG_ENDIAN)
-	config |= XOR_DESCRIPTOR_SWAP;
-#else
-	config &= ~XOR_DESCRIPTOR_SWAP;
-#endif
-
-	writel_relaxed(config, XOR_CONFIG(chan));
-}
-
-static void mv_chan_set_mode_to_desc(struct mv_xor_chan *chan)
-{
-	u32 op_mode;
-	u32 config = readl_relaxed(XOR_CONFIG(chan));
-
-	op_mode = XOR_OPERATION_MODE_IN_DESC;
-
 	config &= ~0x7;
 	config |= op_mode;
 
@@ -1042,9 +1007,9 @@ mv_xor_channel_add(struct mv_xor_device *xordev,
 	mv_chan_unmask_interrupts(mv_chan);
 
 	if (mv_chan->op_in_desc == XOR_MODE_IN_DESC)
-		mv_chan_set_mode_to_desc(mv_chan);
+		mv_chan_set_mode(mv_chan, XOR_OPERATION_MODE_IN_DESC);
 	else
-		mv_chan_set_mode(mv_chan, DMA_XOR);
+		mv_chan_set_mode(mv_chan, XOR_OPERATION_MODE_XOR);
 
 	spin_lock_init(&mv_chan->lock);
 	INIT_LIST_HEAD(&mv_chan->chain);
-- 
2.6.4

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

* [PATCHv3 3/3] dmaengine: mv_xor: add suspend/resume support
  2015-12-22 10:43 [PATCHv3 0/3] mv_xor improvements Thomas Petazzoni
  2015-12-22 10:43 ` [PATCHv3 1/3] dmaengine: mv_xor: remove mv_xor_chan->current_type field Thomas Petazzoni
  2015-12-22 10:43 ` [PATCHv3 2/3] dmaengine: mv_xor: de-duplicate mv_chan_set_mode*() Thomas Petazzoni
@ 2015-12-22 10:43 ` Thomas Petazzoni
  2016-01-06 10:13 ` [PATCHv3 0/3] mv_xor improvements Vinod Koul
  3 siblings, 0 replies; 5+ messages in thread
From: Thomas Petazzoni @ 2015-12-22 10:43 UTC (permalink / raw)
  To: linux-arm-kernel

This commit adds suspend/resume support to the mv_xor driver. The
config and interrupt mask registers must be saved and restored, and
upon resume, the MBus windows configuration must also be done again.

Tested on Armada 388 GP, with a RAID 5 array, accessed before and
after a suspend to RAM cycle.

Based on work from Ofer Heifetz and Lior Amsalem.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
 drivers/dma/mv_xor.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 drivers/dma/mv_xor.h |  1 +
 2 files changed, 54 insertions(+)

diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c
index a95878c..14091f8 100644
--- a/drivers/dma/mv_xor.c
+++ b/drivers/dma/mv_xor.c
@@ -1085,6 +1085,57 @@ mv_xor_conf_mbus_windows(struct mv_xor_device *xordev,
 	writel(0, base + WINDOW_OVERRIDE_CTRL(1));
 }
 
+/*
+ * Since this XOR driver is basically used only for RAID5, we don't
+ * need to care about synchronizing ->suspend with DMA activity,
+ * because the DMA engine will naturally be quiet due to the block
+ * devices being suspended.
+ */
+static int mv_xor_suspend(struct platform_device *pdev, pm_message_t state)
+{
+	struct mv_xor_device *xordev = platform_get_drvdata(pdev);
+	int i;
+
+	for (i = 0; i < MV_XOR_MAX_CHANNELS; i++) {
+		struct mv_xor_chan *mv_chan = xordev->channels[i];
+
+		if (!mv_chan)
+			continue;
+
+		mv_chan->saved_config_reg =
+			readl_relaxed(XOR_CONFIG(mv_chan));
+		mv_chan->saved_int_mask_reg =
+			readl_relaxed(XOR_INTR_MASK(mv_chan));
+	}
+
+	return 0;
+}
+
+static int mv_xor_resume(struct platform_device *dev)
+{
+	struct mv_xor_device *xordev = platform_get_drvdata(dev);
+	const struct mbus_dram_target_info *dram;
+	int i;
+
+	for (i = 0; i < MV_XOR_MAX_CHANNELS; i++) {
+		struct mv_xor_chan *mv_chan = xordev->channels[i];
+
+		if (!mv_chan)
+			continue;
+
+		writel_relaxed(mv_chan->saved_config_reg,
+			       XOR_CONFIG(mv_chan));
+		writel_relaxed(mv_chan->saved_int_mask_reg,
+			       XOR_INTR_MASK(mv_chan));
+	}
+
+	dram = mv_mbus_dram_info();
+	if (dram)
+		mv_xor_conf_mbus_windows(xordev, dram);
+
+	return 0;
+}
+
 static const struct of_device_id mv_xor_dt_ids[] = {
 	{ .compatible = "marvell,orion-xor", .data = (void *)XOR_MODE_IN_REG },
 	{ .compatible = "marvell,armada-380-xor", .data = (void *)XOR_MODE_IN_DESC },
@@ -1246,6 +1297,8 @@ err_channel_add:
 
 static struct platform_driver mv_xor_driver = {
 	.probe		= mv_xor_probe,
+	.suspend        = mv_xor_suspend,
+	.resume         = mv_xor_resume,
 	.driver		= {
 		.name	        = MV_XOR_NAME,
 		.of_match_table = of_match_ptr(mv_xor_dt_ids),
diff --git a/drivers/dma/mv_xor.h b/drivers/dma/mv_xor.h
index 3438914..c19fe30 100644
--- a/drivers/dma/mv_xor.h
+++ b/drivers/dma/mv_xor.h
@@ -125,6 +125,7 @@ struct mv_xor_chan {
 	char			dummy_src[MV_XOR_MIN_BYTE_COUNT];
 	char			dummy_dst[MV_XOR_MIN_BYTE_COUNT];
 	dma_addr_t		dummy_src_addr, dummy_dst_addr;
+	u32                     saved_config_reg, saved_int_mask_reg;
 };
 
 /**
-- 
2.6.4

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

* [PATCHv3 0/3] mv_xor improvements
  2015-12-22 10:43 [PATCHv3 0/3] mv_xor improvements Thomas Petazzoni
                   ` (2 preceding siblings ...)
  2015-12-22 10:43 ` [PATCHv3 3/3] dmaengine: mv_xor: add suspend/resume support Thomas Petazzoni
@ 2016-01-06 10:13 ` Vinod Koul
  3 siblings, 0 replies; 5+ messages in thread
From: Vinod Koul @ 2016-01-06 10:13 UTC (permalink / raw)
  To: linux-arm-kernel

On Tue, Dec 22, 2015 at 11:43:26AM +0100, Thomas Petazzoni wrote:
> Hello Vinod,
> 
> Here is the third iteration of some mv_xor improvements patches. The
> previous iteration was sent in July earlier this year. Compared to the
> v2:

Applied, thanks

-- 
~Vinod

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

end of thread, other threads:[~2016-01-06 10:13 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-12-22 10:43 [PATCHv3 0/3] mv_xor improvements Thomas Petazzoni
2015-12-22 10:43 ` [PATCHv3 1/3] dmaengine: mv_xor: remove mv_xor_chan->current_type field Thomas Petazzoni
2015-12-22 10:43 ` [PATCHv3 2/3] dmaengine: mv_xor: de-duplicate mv_chan_set_mode*() Thomas Petazzoni
2015-12-22 10:43 ` [PATCHv3 3/3] dmaengine: mv_xor: add suspend/resume support Thomas Petazzoni
2016-01-06 10:13 ` [PATCHv3 0/3] mv_xor improvements Vinod Koul

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