diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-13 10:59:52 -0800 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2016-01-13 10:59:52 -0800 |
commit | d6a322774cb7096ca683fc46ddc9482e02ee6133 (patch) | |
tree | 0e5b95d9899eefa5c58f23af8ecadd7e93010586 /drivers/dma/mv_xor.c | |
parent | 4c257ec37bc365614933c7f0a7fe9b0688dfd1e7 (diff) | |
parent | 8b648436eb45c1f561164b24aafd35fb2bee9cfc (diff) | |
download | linux-d6a322774cb7096ca683fc46ddc9482e02ee6133.tar.gz linux-d6a322774cb7096ca683fc46ddc9482e02ee6133.tar.bz2 linux-d6a322774cb7096ca683fc46ddc9482e02ee6133.zip |
Merge tag 'dmaengine-4.5-rc1' of git://git.infradead.org/users/vkoul/slave-dma
Pull dmaengine updates from Vinod Koul:
"This round we have few new features, new driver and updates to few
drivers.
The new features to dmaengine core are:
- Synchronized transfer termination API to terminate the dmaengine
transfers in synchronized and async fashion as required by users.
We have its user now in ALSA dmaengine lib, img, at_xdma, axi_dmac
drivers.
- Universal API for channel request and start consolidation of
request flows. It's user is ompa-dma driver.
- Introduce reuse of descriptors and use in pxa_dma driver
Add/Remove:
- New STM32 DMA driver
- Removal of unused R-Car HPB-DMAC driver
Updates:
- ti-dma-crossbar updates for supporting eDMA
- tegra-apb pm updates
- idma64
- mv_xor updates
- ste_dma updates"
* tag 'dmaengine-4.5-rc1' of git://git.infradead.org/users/vkoul/slave-dma: (54 commits)
dmaengine: mv_xor: add suspend/resume support
dmaengine: mv_xor: de-duplicate mv_chan_set_mode*()
dmaengine: mv_xor: remove mv_xor_chan->current_type field
dmaengine: omap-dma: Add support for DMA filter mapping to slave devices
dmaengine: edma: Add support for DMA filter mapping to slave devices
dmaengine: core: Introduce new, universal API to request a channel
dmaengine: core: Move and merge the code paths using private_candidate
dmaengine: core: Skip mask matching when it is not provided to private_candidate
dmaengine: mdc: Correct terminate_all handling
dmaengine: edma: Add probe callback to edma_tptc_driver
dmaengine: dw: fix potential memory leak in dw_dma_parse_dt()
dmaengine: stm32-dma: Fix unchecked deference of chan->desc
dmaengine: sh: Remove unused R-Car HPB-DMAC driver
dmaengine: usb-dmac: Document SoC specific compatibility strings
ste_dma40: Delete an unnecessary variable initialisation in d40_probe()
ste_dma40: Delete another unnecessary check in d40_probe()
ste_dma40: Delete an unnecessary check before the function call "kmem_cache_destroy"
dmaengine: tegra-apb: Free interrupts before killing tasklets
dmaengine: tegra-apb: Update driver to use GFP_NOWAIT
dmaengine: tegra-apb: Only save channel state for those in use
...
Diffstat (limited to 'drivers/dma/mv_xor.c')
-rw-r--r-- | drivers/dma/mv_xor.c | 95 |
1 files changed, 56 insertions, 39 deletions
diff --git a/drivers/dma/mv_xor.c b/drivers/dma/mv_xor.c index 1c2de9a834a9..14091f878f80 100644 --- a/drivers/dma/mv_xor.c +++ b/drivers/dma/mv_xor.c @@ -139,46 +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)); - chan->current_type = type; -} - -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; @@ -1043,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); @@ -1121,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 }, @@ -1282,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), |