mv_xor improvements
v3 cover mv_xor improvements
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(-)
Signature · 1 line
2.6.4
PATCH v3 1/3 dmaengine: mv_xor: remove mv_xor_chan->current_type field
Since commit 3e4f52e2da9f6 ("dma: mv_xor: Simplify the DMA_MEMCPY operation"), this field is no longer used, so 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
@@ -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)
drivers/dma/mv_xor.h +0 -1
@@ -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;
Signature · 1 line
2.6.4
PATCH v3 2/3 dmaengine: mv_xor: de-duplicate mv_chan_set_mode*()
In reply to Thomas PetazzoniWhen 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.
--- drivers/dma/mv_xor.c | 41 +++-------------------------------------- 1 file changed, 3 insertions(+), 38 deletions(-)
drivers/dma/mv_xor.c +3 -38
@@ -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);
Signature · 1 line
2.6.4
PATCH v3 3/3 dmaengine: mv_xor: add suspend/resume support
In reply to Thomas PetazzoniThis 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.
--- drivers/dma/mv_xor.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++++ drivers/dma/mv_xor.h | 1 + 2 files changed, 54 insertions(+)
drivers/dma/mv_xor.c +53 -0
@@ -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),
drivers/dma/mv_xor.h +1 -0
@@ -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; };/**
Signature · 1 line
2.6.4
Vinod Koul
Appliedv3 cover mv_xor improvements
In reply to Thomas PetazzoniQuoted 5 lines · Thomas Petazzoni
Hello Vinod,
Here is the third iteration of some
mv_xorimprovements patches. The previous iteration was sent in July earlier this year. Compared to the v2:
Applied, thanks
Signature · 1 line
~Vinod