]> Pileus Git - ~andy/linux/commitdiff
Merge branch 'next' of git://git.infradead.org/users/vkoul/slave-dma
authorLinus Torvalds <torvalds@linux-foundation.org>
Tue, 26 Feb 2013 17:24:48 +0000 (09:24 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Tue, 26 Feb 2013 17:24:48 +0000 (09:24 -0800)
Pull slave-dmaengine updates from Vinod Koul:
 "This is fairly big pull by my standards as I had missed last merge
  window.  So we have the support for device tree for slave-dmaengine,
  large updates to dw_dmac driver from Andy for reusing on different
  architectures.  Along with this we have fixes on bunch of the drivers"

Fix up trivial conflicts, usually due to #include line movement next to
each other.

* 'next' of git://git.infradead.org/users/vkoul/slave-dma: (111 commits)
  Revert "ARM: SPEAr13xx: Pass DW DMAC platform data from DT"
  ARM: dts: pl330: Add #dma-cells for generic dma binding support
  DMA: PL330: Register the DMA controller with the generic DMA helpers
  DMA: PL330: Add xlate function
  DMA: PL330: Add new pl330 filter for DT case.
  dma: tegra20-apb-dma: remove unnecessary assignment
  edma: do not waste memory for dma_mask
  dma: coh901318: set residue only if dma is in progress
  dma: coh901318: avoid unbalanced locking
  dmaengine.h: remove redundant else keyword
  dma: of-dma: protect list write operation by spin_lock
  dmaengine: ste_dma40: do not remove descriptors for cyclic transfers
  dma: of-dma.c: fix memory leakage
  dw_dmac: apply default dma_mask if needed
  dmaengine: ioat - fix spare sparse complain
  dmaengine: move drivers/of/dma.c -> drivers/dma/of-dma.c
  ioatdma: fix race between updating ioat->head and IOAT_COMPLETION_PENDING
  dw_dmac: add support for Lynxpoint DMA controllers
  dw_dmac: return proper residue value
  dw_dmac: fill individual length of descriptor
  ...

25 files changed:
1  2 
arch/arm/boot/dts/exynos5250.dtsi
arch/arm/mach-s3c64xx/dma.c
arch/arm/mach-spear3xx/spear3xx.c
arch/arm/mach-spear6xx/spear6xx.c
drivers/dma/Kconfig
drivers/dma/Makefile
drivers/dma/coh901318.c
drivers/dma/coh901318_lli.c
drivers/dma/dw_dmac.c
drivers/dma/edma.c
drivers/dma/ioat/dma.c
drivers/dma/ioat/dma.h
drivers/dma/ioat/dma_v2.c
drivers/dma/ioat/dma_v3.c
drivers/dma/ioat/pci.c
drivers/dma/iop-adma.c
drivers/dma/mmp_pdma.c
drivers/dma/mv_xor.c
drivers/dma/pch_dma.c
drivers/dma/pl330.c
drivers/dma/sh/shdma.c
drivers/dma/sirf-dma.c
drivers/dma/tegra20-apb-dma.c
drivers/mtd/nand/fsmc_nand.c
net/ipv4/tcp.c

index f50b4e854355342bf0fe18d69bd4cf41ffc0c06f,c774aae3f82db5c1dea1ea973650297836b4bc48..b1ac73e21c80da0de48e6e9d70a585c62c243706
                compatible = "samsung,exynos4210-spi";
                reg = <0x12d20000 0x100>;
                interrupts = <0 66 0>;
 -              tx-dma-channel = <&pdma0 5>; /* preliminary */
 -              rx-dma-channel = <&pdma0 4>; /* preliminary */
 +              dmas = <&pdma0 5
 +                      &pdma0 4>;
 +              dma-names = "tx", "rx";
                #address-cells = <1>;
                #size-cells = <0>;
        };
                compatible = "samsung,exynos4210-spi";
                reg = <0x12d30000 0x100>;
                interrupts = <0 67 0>;
 -              tx-dma-channel = <&pdma1 5>; /* preliminary */
 -              rx-dma-channel = <&pdma1 4>; /* preliminary */
 +              dmas = <&pdma1 5
 +                      &pdma1 4>;
 +              dma-names = "tx", "rx";
                #address-cells = <1>;
                #size-cells = <0>;
        };
                compatible = "samsung,exynos4210-spi";
                reg = <0x12d40000 0x100>;
                interrupts = <0 68 0>;
 -              tx-dma-channel = <&pdma0 7>; /* preliminary */
 -              rx-dma-channel = <&pdma0 6>; /* preliminary */
 +              dmas = <&pdma0 7
 +                      &pdma0 6>;
 +              dma-names = "tx", "rx";
                #address-cells = <1>;
                #size-cells = <0>;
        };
                #size-cells = <0>;
        };
  
 +      i2s0: i2s@03830000 {
 +              compatible = "samsung,i2s-v5";
 +              reg = <0x03830000 0x100>;
 +              dmas = <&pdma0 10
 +                      &pdma0 9
 +                      &pdma0 8>;
 +              dma-names = "tx", "rx", "tx-sec";
 +              samsung,supports-6ch;
 +              samsung,supports-rstclr;
 +              samsung,supports-secdai;
 +              samsung,idma-addr = <0x03000000>;
 +      };
 +
 +      i2s1: i2s@12D60000 {
 +              compatible = "samsung,i2s-v5";
 +              reg = <0x12D60000 0x100>;
 +              dmas = <&pdma1 12
 +                      &pdma1 11>;
 +              dma-names = "tx", "rx";
 +      };
 +
 +      i2s2: i2s@12D70000 {
 +              compatible = "samsung,i2s-v5";
 +              reg = <0x12D70000 0x100>;
 +              dmas = <&pdma0 12
 +                      &pdma0 11>;
 +              dma-names = "tx", "rx";
 +      };
 +
        amba {
                #address-cells = <1>;
                #size-cells = <1>;
                        compatible = "arm,pl330", "arm,primecell";
                        reg = <0x121A0000 0x1000>;
                        interrupts = <0 34 0>;
+                       #dma-cells = <1>;
+                       #dma-channels = <8>;
+                       #dma-requests = <32>;
                };
  
                pdma1: pdma@121B0000 {
                        compatible = "arm,pl330", "arm,primecell";
                        reg = <0x121B0000 0x1000>;
                        interrupts = <0 35 0>;
+                       #dma-cells = <1>;
+                       #dma-channels = <8>;
+                       #dma-requests = <32>;
                };
  
                mdma0: mdma@10800000 {
                        compatible = "arm,pl330", "arm,primecell";
                        reg = <0x10800000 0x1000>;
                        interrupts = <0 33 0>;
+                       #dma-cells = <1>;
+                       #dma-channels = <8>;
+                       #dma-requests = <1>;
                };
  
                mdma1: mdma@11C10000 {
                        compatible = "arm,pl330", "arm,primecell";
                        reg = <0x11C10000 0x1000>;
                        interrupts = <0 124 0>;
+                       #dma-cells = <1>;
+                       #dma-channels = <8>;
+                       #dma-requests = <1>;
                };
        };
  
  
        hdmi {
                compatible = "samsung,exynos5-hdmi";
 -              reg = <0x14530000 0x100000>;
 +              reg = <0x14530000 0x70000>;
                interrupts = <0 95 0>;
        };
  
index ec29b35f25c02a02c45c4bd4d7633d2fd125a057,a77f5214bbe82bbde9b0d9dbb70ddb4823480552..6af1aa1ef213293267063c4a20afa07b1a486b4b
  #include <linux/clk.h>
  #include <linux/err.h>
  #include <linux/io.h>
+ #include <linux/amba/pl080.h>
  
  #include <mach/dma.h>
  #include <mach/map.h>
  #include <mach/irqs.h>
  
- #include <asm/hardware/pl080.h>
 -#include <mach/regs-sys.h>
--
 +#include "regs-sys.h"
  
  /* dma channel state information */
  
index b2ba516ca2d4ee4a46e8eb9a4a328bebb09aa3dd,3d9b1b5e8ed9a2126e7130c24fd51b0e1fdf2e88..f9d754f90c5991e6bce11371fa5702f9a8d81c16
  
  #include <linux/amba/pl022.h>
  #include <linux/amba/pl08x.h>
 -#include <linux/irqchip/spear-shirq.h>
 -#include <linux/of_irq.h>
  #include <linux/io.h>
- #include <asm/hardware/pl080.h>
 -#include <asm/hardware/vic.h>
  #include <plat/pl080.h>
  #include <mach/generic.h>
  #include <mach/spear.h>
@@@ -84,7 -86,7 +83,7 @@@ void __init spear3xx_map_io(void
        iotable_init(spear3xx_io_desc, ARRAY_SIZE(spear3xx_io_desc));
  }
  
 -static void __init spear3xx_timer_init(void)
 +void __init spear3xx_timer_init(void)
  {
        char pclk_name[] = "pll3_clk";
        struct clk *gpt_clk, *pclk;
  
        spear_setup_of_timer();
  }
 -
 -struct sys_timer spear3xx_timer = {
 -      .init = spear3xx_timer_init,
 -};
 -
 -static const struct of_device_id vic_of_match[] __initconst = {
 -      { .compatible = "arm,pl190-vic", .data = vic_of_init, },
 -      { .compatible = "st,spear300-shirq", .data = spear300_shirq_of_init, },
 -      { .compatible = "st,spear310-shirq", .data = spear310_shirq_of_init, },
 -      { .compatible = "st,spear320-shirq", .data = spear320_shirq_of_init, },
 -      { /* Sentinel */ }
 -};
 -
 -void __init spear3xx_dt_init_irq(void)
 -{
 -      of_irq_init(vic_of_match);
 -}
index b8bd33ca88bdba6a7d880bfd8ef56d8cf3507dc3,8ce65a23b06e2d139d4d1f182fd47c197b8fe63f..8904d8a52d8486b9b8023c4b49b7846dfd6f99a0
  #include <linux/amba/pl08x.h>
  #include <linux/clk.h>
  #include <linux/err.h>
 +#include <linux/irqchip.h>
  #include <linux/of.h>
  #include <linux/of_address.h>
 -#include <linux/of_irq.h>
  #include <linux/of_platform.h>
- #include <asm/hardware/pl080.h>
+ #include <linux/amba/pl080.h>
 -#include <asm/hardware/vic.h>
  #include <asm/mach/arch.h>
  #include <asm/mach/time.h>
  #include <asm/mach/map.h>
@@@ -373,7 -374,7 +373,7 @@@ void __init spear6xx_map_io(void
        iotable_init(spear6xx_io_desc, ARRAY_SIZE(spear6xx_io_desc));
  }
  
 -static void __init spear6xx_timer_init(void)
 +void __init spear6xx_timer_init(void)
  {
        char pclk_name[] = "pll3_clk";
        struct clk *gpt_clk, *pclk;
        spear_setup_of_timer();
  }
  
 -struct sys_timer spear6xx_timer = {
 -      .init = spear6xx_timer_init,
 -};
 -
  /* Add auxdata to pass platform data */
  struct of_dev_auxdata spear6xx_auxdata_lookup[] __initdata = {
        OF_DEV_AUXDATA("arm,pl080", SPEAR6XX_ICM3_DMA_BASE, NULL,
@@@ -420,10 -425,21 +420,10 @@@ static const char *spear600_dt_board_co
        NULL
  };
  
 -static const struct of_device_id vic_of_match[] __initconst = {
 -      { .compatible = "arm,pl190-vic", .data = vic_of_init, },
 -      { /* Sentinel */ }
 -};
 -
 -static void __init spear6xx_dt_init_irq(void)
 -{
 -      of_irq_init(vic_of_match);
 -}
 -
  DT_MACHINE_START(SPEAR600_DT, "ST SPEAr600 (Flattened Device Tree)")
        .map_io         =       spear6xx_map_io,
 -      .init_irq       =       spear6xx_dt_init_irq,
 -      .handle_irq     =       vic_handle_irq,
 -      .timer          =       &spear6xx_timer,
 +      .init_irq       =       irqchip_init,
 +      .init_time      =       spear6xx_timer_init,
        .init_machine   =       spear600_dt_init,
        .restart        =       spear_restart,
        .dt_compat      =       spear600_dt_board_compat,
diff --combined drivers/dma/Kconfig
index 40179e749f08065d47d02c280608e16ca8411fc5,e92b5f0f8a5f613495119e65c134ca92de785e9c..80b69971cf28d01752abd3654a8cc296f25a8380
@@@ -51,7 -51,7 +51,7 @@@ config ASYNC_TX_ENABLE_CHANNEL_SWITC
  
  config AMBA_PL08X
        bool "ARM PrimeCell PL080 or PL081 support"
-       depends on ARM_AMBA && EXPERIMENTAL
+       depends on ARM_AMBA
        select DMA_ENGINE
        select DMA_VIRTUAL_CHANNELS
        help
@@@ -83,7 -83,6 +83,6 @@@ config INTEL_IOP_ADM
  
  config DW_DMAC
        tristate "Synopsys DesignWare AHB DMA support"
-       depends on HAVE_CLK
        select DMA_ENGINE
        default y if CPU_AT32AP7000
        help
@@@ -125,8 -124,6 +124,8 @@@ config MPC512X_DM
        ---help---
          Enable support for the Freescale MPC512x built-in DMA engine.
  
 +source "drivers/dma/bestcomm/Kconfig"
 +
  config MV_XOR
        bool "Marvell XOR engine support"
        depends on PLAT_ORION
@@@ -215,8 -212,8 +214,8 @@@ config TIMB_DM
          Enable support for the Timberdale FPGA DMA engine.
  
  config SIRF_DMA
-       tristate "CSR SiRFprimaII DMA support"
-       depends on ARCH_PRIMA2
+       tristate "CSR SiRFprimaII/SiRFmarco DMA support"
+       depends on ARCH_SIRF
        select DMA_ENGINE
        help
          Enable support for the CSR SiRFprimaII DMA engine.
@@@ -328,6 -325,10 +327,10 @@@ config DMA_ENGIN
  config DMA_VIRTUAL_CHANNELS
        tristate
  
+ config DMA_OF
+       def_bool y
+       depends on OF
  comment "DMA Clients"
        depends on DMA_ENGINE
  
diff --combined drivers/dma/Makefile
index 642d96736cf522c2d3960936515fd632b07e405f,c1ed644be9e2da60ebf0b781c0fe777742142b5d..488e3ff85b522840ce1ba506916c534ff3116455
@@@ -3,6 -3,8 +3,8 @@@ ccflags-$(CONFIG_DMADEVICES_VDEBUG) += 
  
  obj-$(CONFIG_DMA_ENGINE) += dmaengine.o
  obj-$(CONFIG_DMA_VIRTUAL_CHANNELS) += virt-dma.o
+ obj-$(CONFIG_DMA_OF) += of-dma.o
  obj-$(CONFIG_NET_DMA) += iovlock.o
  obj-$(CONFIG_INTEL_MID_DMAC) += intel_mid_dma.o
  obj-$(CONFIG_DMATEST) += dmatest.o
@@@ -10,7 -12,6 +12,7 @@@ obj-$(CONFIG_INTEL_IOATDMA) += ioat
  obj-$(CONFIG_INTEL_IOP_ADMA) += iop-adma.o
  obj-$(CONFIG_FSL_DMA) += fsldma.o
  obj-$(CONFIG_MPC512X_DMA) += mpc512x_dma.o
 +obj-$(CONFIG_PPC_BESTCOMM) += bestcomm/
  obj-$(CONFIG_MV_XOR) += mv_xor.o
  obj-$(CONFIG_DW_DMAC) += dw_dmac.o
  obj-$(CONFIG_AT_HDMAC) += at_hdmac.o
diff --combined drivers/dma/coh901318.c
index a2f079aca550b4e0b3fb6ecb3db2fcec53c89a24,671e759623700cd461dedd09ce45097eb16e9116..797940e532ff71dbf9a53000f4bfb65017b79433
  #include <linux/io.h>
  #include <linux/uaccess.h>
  #include <linux/debugfs.h>
 -#include <mach/coh901318.h>
 +#include <linux/platform_data/dma-coh901318.h>
  
 -#include "coh901318_lli.h"
 +#include "coh901318.h"
  #include "dmaengine.h"
  
 +#define COH901318_MOD32_MASK                                  (0x1F)
 +#define COH901318_WORD_MASK                                   (0xFFFFFFFF)
 +/* INT_STATUS - Interrupt Status Registers 32bit (R/-) */
 +#define COH901318_INT_STATUS1                                 (0x0000)
 +#define COH901318_INT_STATUS2                                 (0x0004)
 +/* TC_INT_STATUS - Terminal Count Interrupt Status Registers 32bit (R/-) */
 +#define COH901318_TC_INT_STATUS1                              (0x0008)
 +#define COH901318_TC_INT_STATUS2                              (0x000C)
 +/* TC_INT_CLEAR - Terminal Count Interrupt Clear Registers 32bit (-/W) */
 +#define COH901318_TC_INT_CLEAR1                                       (0x0010)
 +#define COH901318_TC_INT_CLEAR2                                       (0x0014)
 +/* RAW_TC_INT_STATUS - Raw Term Count Interrupt Status Registers 32bit (R/-) */
 +#define COH901318_RAW_TC_INT_STATUS1                          (0x0018)
 +#define COH901318_RAW_TC_INT_STATUS2                          (0x001C)
 +/* BE_INT_STATUS - Bus Error Interrupt Status Registers 32bit (R/-) */
 +#define COH901318_BE_INT_STATUS1                              (0x0020)
 +#define COH901318_BE_INT_STATUS2                              (0x0024)
 +/* BE_INT_CLEAR - Bus Error Interrupt Clear Registers 32bit (-/W) */
 +#define COH901318_BE_INT_CLEAR1                                       (0x0028)
 +#define COH901318_BE_INT_CLEAR2                                       (0x002C)
 +/* RAW_BE_INT_STATUS - Raw Term Count Interrupt Status Registers 32bit (R/-) */
 +#define COH901318_RAW_BE_INT_STATUS1                          (0x0030)
 +#define COH901318_RAW_BE_INT_STATUS2                          (0x0034)
 +
 +/*
 + * CX_CFG - Channel Configuration Registers 32bit (R/W)
 + */
 +#define COH901318_CX_CFG                                      (0x0100)
 +#define COH901318_CX_CFG_SPACING                              (0x04)
 +/* Channel enable activates tha dma job */
 +#define COH901318_CX_CFG_CH_ENABLE                            (0x00000001)
 +#define COH901318_CX_CFG_CH_DISABLE                           (0x00000000)
 +/* Request Mode */
 +#define COH901318_CX_CFG_RM_MASK                              (0x00000006)
 +#define COH901318_CX_CFG_RM_MEMORY_TO_MEMORY                  (0x0 << 1)
 +#define COH901318_CX_CFG_RM_PRIMARY_TO_MEMORY                 (0x1 << 1)
 +#define COH901318_CX_CFG_RM_MEMORY_TO_PRIMARY                 (0x1 << 1)
 +#define COH901318_CX_CFG_RM_PRIMARY_TO_SECONDARY              (0x3 << 1)
 +#define COH901318_CX_CFG_RM_SECONDARY_TO_PRIMARY              (0x3 << 1)
 +/* Linked channel request field. RM must == 11 */
 +#define COH901318_CX_CFG_LCRF_SHIFT                           3
 +#define COH901318_CX_CFG_LCRF_MASK                            (0x000001F8)
 +#define COH901318_CX_CFG_LCR_DISABLE                          (0x00000000)
 +/* Terminal Counter Interrupt Request Mask */
 +#define COH901318_CX_CFG_TC_IRQ_ENABLE                                (0x00000200)
 +#define COH901318_CX_CFG_TC_IRQ_DISABLE                               (0x00000000)
 +/* Bus Error interrupt Mask */
 +#define COH901318_CX_CFG_BE_IRQ_ENABLE                                (0x00000400)
 +#define COH901318_CX_CFG_BE_IRQ_DISABLE                               (0x00000000)
 +
 +/*
 + * CX_STAT - Channel Status Registers 32bit (R/-)
 + */
 +#define COH901318_CX_STAT                                     (0x0200)
 +#define COH901318_CX_STAT_SPACING                             (0x04)
 +#define COH901318_CX_STAT_RBE_IRQ_IND                         (0x00000008)
 +#define COH901318_CX_STAT_RTC_IRQ_IND                         (0x00000004)
 +#define COH901318_CX_STAT_ACTIVE                              (0x00000002)
 +#define COH901318_CX_STAT_ENABLED                             (0x00000001)
 +
 +/*
 + * CX_CTRL - Channel Control Registers 32bit (R/W)
 + */
 +#define COH901318_CX_CTRL                                     (0x0400)
 +#define COH901318_CX_CTRL_SPACING                             (0x10)
 +/* Transfer Count Enable */
 +#define COH901318_CX_CTRL_TC_ENABLE                           (0x00001000)
 +#define COH901318_CX_CTRL_TC_DISABLE                          (0x00000000)
 +/* Transfer Count Value 0 - 4095 */
 +#define COH901318_CX_CTRL_TC_VALUE_MASK                               (0x00000FFF)
 +/* Burst count */
 +#define COH901318_CX_CTRL_BURST_COUNT_MASK                    (0x0000E000)
 +#define COH901318_CX_CTRL_BURST_COUNT_64_BYTES                        (0x7 << 13)
 +#define COH901318_CX_CTRL_BURST_COUNT_48_BYTES                        (0x6 << 13)
 +#define COH901318_CX_CTRL_BURST_COUNT_32_BYTES                        (0x5 << 13)
 +#define COH901318_CX_CTRL_BURST_COUNT_16_BYTES                        (0x4 << 13)
 +#define COH901318_CX_CTRL_BURST_COUNT_8_BYTES                 (0x3 << 13)
 +#define COH901318_CX_CTRL_BURST_COUNT_4_BYTES                 (0x2 << 13)
 +#define COH901318_CX_CTRL_BURST_COUNT_2_BYTES                 (0x1 << 13)
 +#define COH901318_CX_CTRL_BURST_COUNT_1_BYTE                  (0x0 << 13)
 +/* Source bus size  */
 +#define COH901318_CX_CTRL_SRC_BUS_SIZE_MASK                   (0x00030000)
 +#define COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS                        (0x2 << 16)
 +#define COH901318_CX_CTRL_SRC_BUS_SIZE_16_BITS                        (0x1 << 16)
 +#define COH901318_CX_CTRL_SRC_BUS_SIZE_8_BITS                 (0x0 << 16)
 +/* Source address increment */
 +#define COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE                 (0x00040000)
 +#define COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE                        (0x00000000)
 +/* Destination Bus Size */
 +#define COH901318_CX_CTRL_DST_BUS_SIZE_MASK                   (0x00180000)
 +#define COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS                        (0x2 << 19)
 +#define COH901318_CX_CTRL_DST_BUS_SIZE_16_BITS                        (0x1 << 19)
 +#define COH901318_CX_CTRL_DST_BUS_SIZE_8_BITS                 (0x0 << 19)
 +/* Destination address increment */
 +#define COH901318_CX_CTRL_DST_ADDR_INC_ENABLE                 (0x00200000)
 +#define COH901318_CX_CTRL_DST_ADDR_INC_DISABLE                        (0x00000000)
 +/* Master Mode (Master2 is only connected to MSL) */
 +#define COH901318_CX_CTRL_MASTER_MODE_MASK                    (0x00C00000)
 +#define COH901318_CX_CTRL_MASTER_MODE_M2R_M1W                 (0x3 << 22)
 +#define COH901318_CX_CTRL_MASTER_MODE_M1R_M2W                 (0x2 << 22)
 +#define COH901318_CX_CTRL_MASTER_MODE_M2RW                    (0x1 << 22)
 +#define COH901318_CX_CTRL_MASTER_MODE_M1RW                    (0x0 << 22)
 +/* Terminal Count flag to PER enable */
 +#define COH901318_CX_CTRL_TCP_ENABLE                          (0x01000000)
 +#define COH901318_CX_CTRL_TCP_DISABLE                         (0x00000000)
 +/* Terminal Count flags to CPU enable */
 +#define COH901318_CX_CTRL_TC_IRQ_ENABLE                               (0x02000000)
 +#define COH901318_CX_CTRL_TC_IRQ_DISABLE                      (0x00000000)
 +/* Hand shake to peripheral */
 +#define COH901318_CX_CTRL_HSP_ENABLE                          (0x04000000)
 +#define COH901318_CX_CTRL_HSP_DISABLE                         (0x00000000)
 +#define COH901318_CX_CTRL_HSS_ENABLE                          (0x08000000)
 +#define COH901318_CX_CTRL_HSS_DISABLE                         (0x00000000)
 +/* DMA mode */
 +#define COH901318_CX_CTRL_DDMA_MASK                           (0x30000000)
 +#define COH901318_CX_CTRL_DDMA_LEGACY                         (0x0 << 28)
 +#define COH901318_CX_CTRL_DDMA_DEMAND_DMA1                    (0x1 << 28)
 +#define COH901318_CX_CTRL_DDMA_DEMAND_DMA2                    (0x2 << 28)
 +/* Primary Request Data Destination */
 +#define COH901318_CX_CTRL_PRDD_MASK                           (0x40000000)
 +#define COH901318_CX_CTRL_PRDD_DEST                           (0x1 << 30)
 +#define COH901318_CX_CTRL_PRDD_SOURCE                         (0x0 << 30)
 +
 +/*
 + * CX_SRC_ADDR - Channel Source Address Registers 32bit (R/W)
 + */
 +#define COH901318_CX_SRC_ADDR                                 (0x0404)
 +#define COH901318_CX_SRC_ADDR_SPACING                         (0x10)
 +
 +/*
 + * CX_DST_ADDR - Channel Destination Address Registers 32bit R/W
 + */
 +#define COH901318_CX_DST_ADDR                                 (0x0408)
 +#define COH901318_CX_DST_ADDR_SPACING                         (0x10)
 +
 +/*
 + * CX_LNK_ADDR - Channel Link Address Registers 32bit (R/W)
 + */
 +#define COH901318_CX_LNK_ADDR                                 (0x040C)
 +#define COH901318_CX_LNK_ADDR_SPACING                         (0x10)
 +#define COH901318_CX_LNK_LINK_IMMEDIATE                               (0x00000001)
 +
 +/**
 + * struct coh901318_params - parameters for DMAC configuration
 + * @config: DMA config register
 + * @ctrl_lli_last: DMA control register for the last lli in the list
 + * @ctrl_lli: DMA control register for an lli
 + * @ctrl_lli_chained: DMA control register for a chained lli
 + */
 +struct coh901318_params {
 +      u32 config;
 +      u32 ctrl_lli_last;
 +      u32 ctrl_lli;
 +      u32 ctrl_lli_chained;
 +};
 +
 +/**
 + * struct coh_dma_channel - dma channel base
 + * @name: ascii name of dma channel
 + * @number: channel id number
 + * @desc_nbr_max: number of preallocated descriptors
 + * @priority_high: prio of channel, 0 low otherwise high.
 + * @param: configuration parameters
 + */
 +struct coh_dma_channel {
 +      const char name[32];
 +      const int number;
 +      const int desc_nbr_max;
 +      const int priority_high;
 +      const struct coh901318_params param;
 +};
 +
 +/**
 + * struct powersave - DMA power save structure
 + * @lock: lock protecting data in this struct
 + * @started_channels: bit mask indicating active dma channels
 + */
 +struct powersave {
 +      spinlock_t lock;
 +      u64 started_channels;
 +};
 +
 +/* points out all dma slave channels.
 + * Syntax is [A1, B1, A2, B2, .... ,-1,-1]
 + * Select all channels from A to B, end of list is marked with -1,-1
 + */
 +static int dma_slave_channels[] = {
 +      U300_DMA_MSL_TX_0, U300_DMA_SPI_RX,
 +      U300_DMA_UART1_TX, U300_DMA_UART1_RX, -1, -1};
 +
 +/* points out all dma memcpy channels. */
 +static int dma_memcpy_channels[] = {
 +      U300_DMA_GENERAL_PURPOSE_0, U300_DMA_GENERAL_PURPOSE_8, -1, -1};
 +
 +#define flags_memcpy_config (COH901318_CX_CFG_CH_DISABLE | \
 +                      COH901318_CX_CFG_RM_MEMORY_TO_MEMORY | \
 +                      COH901318_CX_CFG_LCR_DISABLE | \
 +                      COH901318_CX_CFG_TC_IRQ_ENABLE | \
 +                      COH901318_CX_CFG_BE_IRQ_ENABLE)
 +#define flags_memcpy_lli_chained (COH901318_CX_CTRL_TC_ENABLE | \
 +                      COH901318_CX_CTRL_BURST_COUNT_32_BYTES | \
 +                      COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | \
 +                      COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE | \
 +                      COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | \
 +                      COH901318_CX_CTRL_DST_ADDR_INC_ENABLE | \
 +                      COH901318_CX_CTRL_MASTER_MODE_M1RW | \
 +                      COH901318_CX_CTRL_TCP_DISABLE | \
 +                      COH901318_CX_CTRL_TC_IRQ_DISABLE | \
 +                      COH901318_CX_CTRL_HSP_DISABLE | \
 +                      COH901318_CX_CTRL_HSS_DISABLE | \
 +                      COH901318_CX_CTRL_DDMA_LEGACY | \
 +                      COH901318_CX_CTRL_PRDD_SOURCE)
 +#define flags_memcpy_lli (COH901318_CX_CTRL_TC_ENABLE | \
 +                      COH901318_CX_CTRL_BURST_COUNT_32_BYTES | \
 +                      COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | \
 +                      COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE | \
 +                      COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | \
 +                      COH901318_CX_CTRL_DST_ADDR_INC_ENABLE | \
 +                      COH901318_CX_CTRL_MASTER_MODE_M1RW | \
 +                      COH901318_CX_CTRL_TCP_DISABLE | \
 +                      COH901318_CX_CTRL_TC_IRQ_DISABLE | \
 +                      COH901318_CX_CTRL_HSP_DISABLE | \
 +                      COH901318_CX_CTRL_HSS_DISABLE | \
 +                      COH901318_CX_CTRL_DDMA_LEGACY | \
 +                      COH901318_CX_CTRL_PRDD_SOURCE)
 +#define flags_memcpy_lli_last (COH901318_CX_CTRL_TC_ENABLE | \
 +                      COH901318_CX_CTRL_BURST_COUNT_32_BYTES | \
 +                      COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS | \
 +                      COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE | \
 +                      COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS | \
 +                      COH901318_CX_CTRL_DST_ADDR_INC_ENABLE | \
 +                      COH901318_CX_CTRL_MASTER_MODE_M1RW | \
 +                      COH901318_CX_CTRL_TCP_DISABLE | \
 +                      COH901318_CX_CTRL_TC_IRQ_ENABLE | \
 +                      COH901318_CX_CTRL_HSP_DISABLE | \
 +                      COH901318_CX_CTRL_HSS_DISABLE | \
 +                      COH901318_CX_CTRL_DDMA_LEGACY | \
 +                      COH901318_CX_CTRL_PRDD_SOURCE)
 +
 +const struct coh_dma_channel chan_config[U300_DMA_CHANNELS] = {
 +      {
 +              .number = U300_DMA_MSL_TX_0,
 +              .name = "MSL TX 0",
 +              .priority_high = 0,
 +      },
 +      {
 +              .number = U300_DMA_MSL_TX_1,
 +              .name = "MSL TX 1",
 +              .priority_high = 0,
 +              .param.config = COH901318_CX_CFG_CH_DISABLE |
 +                              COH901318_CX_CFG_LCR_DISABLE |
 +                              COH901318_CX_CFG_TC_IRQ_ENABLE |
 +                              COH901318_CX_CFG_BE_IRQ_ENABLE,
 +              .param.ctrl_lli_chained = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
 +                              COH901318_CX_CTRL_TCP_DISABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_DISABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY |
 +                              COH901318_CX_CTRL_PRDD_SOURCE,
 +              .param.ctrl_lli = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
 +                              COH901318_CX_CTRL_TCP_ENABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_DISABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY |
 +                              COH901318_CX_CTRL_PRDD_SOURCE,
 +              .param.ctrl_lli_last = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
 +                              COH901318_CX_CTRL_TCP_ENABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_ENABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY |
 +                              COH901318_CX_CTRL_PRDD_SOURCE,
 +      },
 +      {
 +              .number = U300_DMA_MSL_TX_2,
 +              .name = "MSL TX 2",
 +              .priority_high = 0,
 +              .param.config = COH901318_CX_CFG_CH_DISABLE |
 +                              COH901318_CX_CFG_LCR_DISABLE |
 +                              COH901318_CX_CFG_TC_IRQ_ENABLE |
 +                              COH901318_CX_CFG_BE_IRQ_ENABLE,
 +              .param.ctrl_lli_chained = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
 +                              COH901318_CX_CTRL_TCP_DISABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_DISABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY |
 +                              COH901318_CX_CTRL_PRDD_SOURCE,
 +              .param.ctrl_lli = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
 +                              COH901318_CX_CTRL_TCP_ENABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_DISABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY |
 +                              COH901318_CX_CTRL_PRDD_SOURCE,
 +              .param.ctrl_lli_last = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
 +                              COH901318_CX_CTRL_TCP_ENABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_ENABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY |
 +                              COH901318_CX_CTRL_PRDD_SOURCE,
 +              .desc_nbr_max = 10,
 +      },
 +      {
 +              .number = U300_DMA_MSL_TX_3,
 +              .name = "MSL TX 3",
 +              .priority_high = 0,
 +              .param.config = COH901318_CX_CFG_CH_DISABLE |
 +                              COH901318_CX_CFG_LCR_DISABLE |
 +                              COH901318_CX_CFG_TC_IRQ_ENABLE |
 +                              COH901318_CX_CFG_BE_IRQ_ENABLE,
 +              .param.ctrl_lli_chained = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
 +                              COH901318_CX_CTRL_TCP_DISABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_DISABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY |
 +                              COH901318_CX_CTRL_PRDD_SOURCE,
 +              .param.ctrl_lli = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
 +                              COH901318_CX_CTRL_TCP_ENABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_DISABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY |
 +                              COH901318_CX_CTRL_PRDD_SOURCE,
 +              .param.ctrl_lli_last = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
 +                              COH901318_CX_CTRL_TCP_ENABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_ENABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY |
 +                              COH901318_CX_CTRL_PRDD_SOURCE,
 +      },
 +      {
 +              .number = U300_DMA_MSL_TX_4,
 +              .name = "MSL TX 4",
 +              .priority_high = 0,
 +              .param.config = COH901318_CX_CFG_CH_DISABLE |
 +                              COH901318_CX_CFG_LCR_DISABLE |
 +                              COH901318_CX_CFG_TC_IRQ_ENABLE |
 +                              COH901318_CX_CFG_BE_IRQ_ENABLE,
 +              .param.ctrl_lli_chained = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
 +                              COH901318_CX_CTRL_TCP_DISABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_DISABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY |
 +                              COH901318_CX_CTRL_PRDD_SOURCE,
 +              .param.ctrl_lli = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
 +                              COH901318_CX_CTRL_TCP_ENABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_DISABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY |
 +                              COH901318_CX_CTRL_PRDD_SOURCE,
 +              .param.ctrl_lli_last = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1R_M2W |
 +                              COH901318_CX_CTRL_TCP_ENABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_ENABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY |
 +                              COH901318_CX_CTRL_PRDD_SOURCE,
 +      },
 +      {
 +              .number = U300_DMA_MSL_TX_5,
 +              .name = "MSL TX 5",
 +              .priority_high = 0,
 +      },
 +      {
 +              .number = U300_DMA_MSL_TX_6,
 +              .name = "MSL TX 6",
 +              .priority_high = 0,
 +      },
 +      {
 +              .number = U300_DMA_MSL_RX_0,
 +              .name = "MSL RX 0",
 +              .priority_high = 0,
 +      },
 +      {
 +              .number = U300_DMA_MSL_RX_1,
 +              .name = "MSL RX 1",
 +              .priority_high = 0,
 +              .param.config = COH901318_CX_CFG_CH_DISABLE |
 +                              COH901318_CX_CFG_LCR_DISABLE |
 +                              COH901318_CX_CFG_TC_IRQ_ENABLE |
 +                              COH901318_CX_CFG_BE_IRQ_ENABLE,
 +              .param.ctrl_lli_chained = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
 +                              COH901318_CX_CTRL_TCP_DISABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_DISABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
 +                              COH901318_CX_CTRL_PRDD_DEST,
 +              .param.ctrl_lli = 0,
 +              .param.ctrl_lli_last = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
 +                              COH901318_CX_CTRL_TCP_DISABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_ENABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
 +                              COH901318_CX_CTRL_PRDD_DEST,
 +      },
 +      {
 +              .number = U300_DMA_MSL_RX_2,
 +              .name = "MSL RX 2",
 +              .priority_high = 0,
 +              .param.config = COH901318_CX_CFG_CH_DISABLE |
 +                              COH901318_CX_CFG_LCR_DISABLE |
 +                              COH901318_CX_CFG_TC_IRQ_ENABLE |
 +                              COH901318_CX_CFG_BE_IRQ_ENABLE,
 +              .param.ctrl_lli_chained = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
 +                              COH901318_CX_CTRL_TCP_DISABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_DISABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
 +                              COH901318_CX_CTRL_PRDD_DEST,
 +              .param.ctrl_lli = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
 +                              COH901318_CX_CTRL_TCP_DISABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_ENABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
 +                              COH901318_CX_CTRL_PRDD_DEST,
 +              .param.ctrl_lli_last = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
 +                              COH901318_CX_CTRL_TCP_DISABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_ENABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
 +                              COH901318_CX_CTRL_PRDD_DEST,
 +      },
 +      {
 +              .number = U300_DMA_MSL_RX_3,
 +              .name = "MSL RX 3",
 +              .priority_high = 0,
 +              .param.config = COH901318_CX_CFG_CH_DISABLE |
 +                              COH901318_CX_CFG_LCR_DISABLE |
 +                              COH901318_CX_CFG_TC_IRQ_ENABLE |
 +                              COH901318_CX_CFG_BE_IRQ_ENABLE,
 +              .param.ctrl_lli_chained = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
 +                              COH901318_CX_CTRL_TCP_DISABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_DISABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
 +                              COH901318_CX_CTRL_PRDD_DEST,
 +              .param.ctrl_lli = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
 +                              COH901318_CX_CTRL_TCP_DISABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_ENABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
 +                              COH901318_CX_CTRL_PRDD_DEST,
 +              .param.ctrl_lli_last = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
 +                              COH901318_CX_CTRL_TCP_DISABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_ENABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
 +                              COH901318_CX_CTRL_PRDD_DEST,
 +      },
 +      {
 +              .number = U300_DMA_MSL_RX_4,
 +              .name = "MSL RX 4",
 +              .priority_high = 0,
 +              .param.config = COH901318_CX_CFG_CH_DISABLE |
 +                              COH901318_CX_CFG_LCR_DISABLE |
 +                              COH901318_CX_CFG_TC_IRQ_ENABLE |
 +                              COH901318_CX_CFG_BE_IRQ_ENABLE,
 +              .param.ctrl_lli_chained = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
 +                              COH901318_CX_CTRL_TCP_DISABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_DISABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
 +                              COH901318_CX_CTRL_PRDD_DEST,
 +              .param.ctrl_lli = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
 +                              COH901318_CX_CTRL_TCP_DISABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_ENABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
 +                              COH901318_CX_CTRL_PRDD_DEST,
 +              .param.ctrl_lli_last = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
 +                              COH901318_CX_CTRL_TCP_DISABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_ENABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
 +                              COH901318_CX_CTRL_PRDD_DEST,
 +      },
 +      {
 +              .number = U300_DMA_MSL_RX_5,
 +              .name = "MSL RX 5",
 +              .priority_high = 0,
 +              .param.config = COH901318_CX_CFG_CH_DISABLE |
 +                              COH901318_CX_CFG_LCR_DISABLE |
 +                              COH901318_CX_CFG_TC_IRQ_ENABLE |
 +                              COH901318_CX_CFG_BE_IRQ_ENABLE,
 +              .param.ctrl_lli_chained = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
 +                              COH901318_CX_CTRL_TCP_DISABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_DISABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
 +                              COH901318_CX_CTRL_PRDD_DEST,
 +              .param.ctrl_lli = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
 +                              COH901318_CX_CTRL_TCP_DISABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_ENABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
 +                              COH901318_CX_CTRL_PRDD_DEST,
 +              .param.ctrl_lli_last = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_32_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M2R_M1W |
 +                              COH901318_CX_CTRL_TCP_DISABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_ENABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_DEMAND_DMA1 |
 +                              COH901318_CX_CTRL_PRDD_DEST,
 +      },
 +      {
 +              .number = U300_DMA_MSL_RX_6,
 +              .name = "MSL RX 6",
 +              .priority_high = 0,
 +      },
 +      /*
 +       * Don't set up device address, burst count or size of src
 +       * or dst bus for this peripheral - handled by PrimeCell
 +       * DMA extension.
 +       */
 +      {
 +              .number = U300_DMA_MMCSD_RX_TX,
 +              .name = "MMCSD RX TX",
 +              .priority_high = 0,
 +              .param.config = COH901318_CX_CFG_CH_DISABLE |
 +                              COH901318_CX_CFG_LCR_DISABLE |
 +                              COH901318_CX_CFG_TC_IRQ_ENABLE |
 +                              COH901318_CX_CFG_BE_IRQ_ENABLE,
 +              .param.ctrl_lli_chained = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1RW |
 +                              COH901318_CX_CTRL_TCP_ENABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_DISABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY,
 +              .param.ctrl_lli = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1RW |
 +                              COH901318_CX_CTRL_TCP_ENABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_DISABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY,
 +              .param.ctrl_lli_last = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1RW |
 +                              COH901318_CX_CTRL_TCP_DISABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_ENABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY,
 +
 +      },
 +      {
 +              .number = U300_DMA_MSPRO_TX,
 +              .name = "MSPRO TX",
 +              .priority_high = 0,
 +      },
 +      {
 +              .number = U300_DMA_MSPRO_RX,
 +              .name = "MSPRO RX",
 +              .priority_high = 0,
 +      },
 +      /*
 +       * Don't set up device address, burst count or size of src
 +       * or dst bus for this peripheral - handled by PrimeCell
 +       * DMA extension.
 +       */
 +      {
 +              .number = U300_DMA_UART0_TX,
 +              .name = "UART0 TX",
 +              .priority_high = 0,
 +              .param.config = COH901318_CX_CFG_CH_DISABLE |
 +                              COH901318_CX_CFG_LCR_DISABLE |
 +                              COH901318_CX_CFG_TC_IRQ_ENABLE |
 +                              COH901318_CX_CFG_BE_IRQ_ENABLE,
 +              .param.ctrl_lli_chained = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1RW |
 +                              COH901318_CX_CTRL_TCP_ENABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_DISABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY,
 +              .param.ctrl_lli = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1RW |
 +                              COH901318_CX_CTRL_TCP_ENABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_ENABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY,
 +              .param.ctrl_lli_last = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1RW |
 +                              COH901318_CX_CTRL_TCP_ENABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_ENABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY,
 +      },
 +      {
 +              .number = U300_DMA_UART0_RX,
 +              .name = "UART0 RX",
 +              .priority_high = 0,
 +              .param.config = COH901318_CX_CFG_CH_DISABLE |
 +                              COH901318_CX_CFG_LCR_DISABLE |
 +                              COH901318_CX_CFG_TC_IRQ_ENABLE |
 +                              COH901318_CX_CFG_BE_IRQ_ENABLE,
 +              .param.ctrl_lli_chained = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1RW |
 +                              COH901318_CX_CTRL_TCP_ENABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_DISABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY,
 +              .param.ctrl_lli = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1RW |
 +                              COH901318_CX_CTRL_TCP_ENABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_ENABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY,
 +              .param.ctrl_lli_last = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1RW |
 +                              COH901318_CX_CTRL_TCP_ENABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_ENABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY,
 +      },
 +      {
 +              .number = U300_DMA_APEX_TX,
 +              .name = "APEX TX",
 +              .priority_high = 0,
 +      },
 +      {
 +              .number = U300_DMA_APEX_RX,
 +              .name = "APEX RX",
 +              .priority_high = 0,
 +      },
 +      {
 +              .number = U300_DMA_PCM_I2S0_TX,
 +              .name = "PCM I2S0 TX",
 +              .priority_high = 1,
 +              .param.config = COH901318_CX_CFG_CH_DISABLE |
 +                              COH901318_CX_CFG_LCR_DISABLE |
 +                              COH901318_CX_CFG_TC_IRQ_ENABLE |
 +                              COH901318_CX_CFG_BE_IRQ_ENABLE,
 +              .param.ctrl_lli_chained = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1RW |
 +                              COH901318_CX_CTRL_TCP_DISABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_DISABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY |
 +                              COH901318_CX_CTRL_PRDD_SOURCE,
 +              .param.ctrl_lli = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1RW |
 +                              COH901318_CX_CTRL_TCP_ENABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_DISABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY |
 +                              COH901318_CX_CTRL_PRDD_SOURCE,
 +              .param.ctrl_lli_last = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1RW |
 +                              COH901318_CX_CTRL_TCP_ENABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_DISABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY |
 +                              COH901318_CX_CTRL_PRDD_SOURCE,
 +      },
 +      {
 +              .number = U300_DMA_PCM_I2S0_RX,
 +              .name = "PCM I2S0 RX",
 +              .priority_high = 1,
 +              .param.config = COH901318_CX_CFG_CH_DISABLE |
 +                              COH901318_CX_CFG_LCR_DISABLE |
 +                              COH901318_CX_CFG_TC_IRQ_ENABLE |
 +                              COH901318_CX_CFG_BE_IRQ_ENABLE,
 +              .param.ctrl_lli_chained = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1RW |
 +                              COH901318_CX_CTRL_TCP_DISABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_DISABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY |
 +                              COH901318_CX_CTRL_PRDD_DEST,
 +              .param.ctrl_lli = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1RW |
 +                              COH901318_CX_CTRL_TCP_ENABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_DISABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY |
 +                              COH901318_CX_CTRL_PRDD_DEST,
 +              .param.ctrl_lli_last = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1RW |
 +                              COH901318_CX_CTRL_TCP_ENABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_ENABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY |
 +                              COH901318_CX_CTRL_PRDD_DEST,
 +      },
 +      {
 +              .number = U300_DMA_PCM_I2S1_TX,
 +              .name = "PCM I2S1 TX",
 +              .priority_high = 1,
 +              .param.config = COH901318_CX_CFG_CH_DISABLE |
 +                              COH901318_CX_CFG_LCR_DISABLE |
 +                              COH901318_CX_CFG_TC_IRQ_ENABLE |
 +                              COH901318_CX_CFG_BE_IRQ_ENABLE,
 +              .param.ctrl_lli_chained = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1RW |
 +                              COH901318_CX_CTRL_TCP_DISABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_DISABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY |
 +                              COH901318_CX_CTRL_PRDD_SOURCE,
 +              .param.ctrl_lli = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1RW |
 +                              COH901318_CX_CTRL_TCP_ENABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_DISABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY |
 +                              COH901318_CX_CTRL_PRDD_SOURCE,
 +              .param.ctrl_lli_last = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1RW |
 +                              COH901318_CX_CTRL_TCP_ENABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_ENABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY |
 +                              COH901318_CX_CTRL_PRDD_SOURCE,
 +      },
 +      {
 +              .number = U300_DMA_PCM_I2S1_RX,
 +              .name = "PCM I2S1 RX",
 +              .priority_high = 1,
 +              .param.config = COH901318_CX_CFG_CH_DISABLE |
 +                              COH901318_CX_CFG_LCR_DISABLE |
 +                              COH901318_CX_CFG_TC_IRQ_ENABLE |
 +                              COH901318_CX_CFG_BE_IRQ_ENABLE,
 +              .param.ctrl_lli_chained = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1RW |
 +                              COH901318_CX_CTRL_TCP_DISABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_DISABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY |
 +                              COH901318_CX_CTRL_PRDD_DEST,
 +              .param.ctrl_lli = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1RW |
 +                              COH901318_CX_CTRL_TCP_ENABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_DISABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY |
 +                              COH901318_CX_CTRL_PRDD_DEST,
 +              .param.ctrl_lli_last = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_BURST_COUNT_16_BYTES |
 +                              COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_SRC_ADDR_INC_DISABLE |
 +                              COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS |
 +                              COH901318_CX_CTRL_DST_ADDR_INC_ENABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1RW |
 +                              COH901318_CX_CTRL_TCP_ENABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_ENABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY |
 +                              COH901318_CX_CTRL_PRDD_DEST,
 +      },
 +      {
 +              .number = U300_DMA_XGAM_CDI,
 +              .name = "XGAM CDI",
 +              .priority_high = 0,
 +      },
 +      {
 +              .number = U300_DMA_XGAM_PDI,
 +              .name = "XGAM PDI",
 +              .priority_high = 0,
 +      },
 +      /*
 +       * Don't set up device address, burst count or size of src
 +       * or dst bus for this peripheral - handled by PrimeCell
 +       * DMA extension.
 +       */
 +      {
 +              .number = U300_DMA_SPI_TX,
 +              .name = "SPI TX",
 +              .priority_high = 0,
 +              .param.config = COH901318_CX_CFG_CH_DISABLE |
 +                              COH901318_CX_CFG_LCR_DISABLE |
 +                              COH901318_CX_CFG_TC_IRQ_ENABLE |
 +                              COH901318_CX_CFG_BE_IRQ_ENABLE,
 +              .param.ctrl_lli_chained = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1RW |
 +                              COH901318_CX_CTRL_TCP_DISABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_DISABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY,
 +              .param.ctrl_lli = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1RW |
 +                              COH901318_CX_CTRL_TCP_DISABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_ENABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY,
 +              .param.ctrl_lli_last = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1RW |
 +                              COH901318_CX_CTRL_TCP_DISABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_ENABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY,
 +      },
 +      {
 +              .number = U300_DMA_SPI_RX,
 +              .name = "SPI RX",
 +              .priority_high = 0,
 +              .param.config = COH901318_CX_CFG_CH_DISABLE |
 +                              COH901318_CX_CFG_LCR_DISABLE |
 +                              COH901318_CX_CFG_TC_IRQ_ENABLE |
 +                              COH901318_CX_CFG_BE_IRQ_ENABLE,
 +              .param.ctrl_lli_chained = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1RW |
 +                              COH901318_CX_CTRL_TCP_DISABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_DISABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY,
 +              .param.ctrl_lli = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1RW |
 +                              COH901318_CX_CTRL_TCP_DISABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_ENABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY,
 +              .param.ctrl_lli_last = 0 |
 +                              COH901318_CX_CTRL_TC_ENABLE |
 +                              COH901318_CX_CTRL_MASTER_MODE_M1RW |
 +                              COH901318_CX_CTRL_TCP_DISABLE |
 +                              COH901318_CX_CTRL_TC_IRQ_ENABLE |
 +                              COH901318_CX_CTRL_HSP_ENABLE |
 +                              COH901318_CX_CTRL_HSS_DISABLE |
 +                              COH901318_CX_CTRL_DDMA_LEGACY,
 +
 +      },
 +      {
 +              .number = U300_DMA_GENERAL_PURPOSE_0,
 +              .name = "GENERAL 00",
 +              .priority_high = 0,
 +
 +              .param.config = flags_memcpy_config,
 +              .param.ctrl_lli_chained = flags_memcpy_lli_chained,
 +              .param.ctrl_lli = flags_memcpy_lli,
 +              .param.ctrl_lli_last = flags_memcpy_lli_last,
 +      },
 +      {
 +              .number = U300_DMA_GENERAL_PURPOSE_1,
 +              .name = "GENERAL 01",
 +              .priority_high = 0,
 +
 +              .param.config = flags_memcpy_config,
 +              .param.ctrl_lli_chained = flags_memcpy_lli_chained,
 +              .param.ctrl_lli = flags_memcpy_lli,
 +              .param.ctrl_lli_last = flags_memcpy_lli_last,
 +      },
 +      {
 +              .number = U300_DMA_GENERAL_PURPOSE_2,
 +              .name = "GENERAL 02",
 +              .priority_high = 0,
 +
 +              .param.config = flags_memcpy_config,
 +              .param.ctrl_lli_chained = flags_memcpy_lli_chained,
 +              .param.ctrl_lli = flags_memcpy_lli,
 +              .param.ctrl_lli_last = flags_memcpy_lli_last,
 +      },
 +      {
 +              .number = U300_DMA_GENERAL_PURPOSE_3,
 +              .name = "GENERAL 03",
 +              .priority_high = 0,
 +
 +              .param.config = flags_memcpy_config,
 +              .param.ctrl_lli_chained = flags_memcpy_lli_chained,
 +              .param.ctrl_lli = flags_memcpy_lli,
 +              .param.ctrl_lli_last = flags_memcpy_lli_last,
 +      },
 +      {
 +              .number = U300_DMA_GENERAL_PURPOSE_4,
 +              .name = "GENERAL 04",
 +              .priority_high = 0,
 +
 +              .param.config = flags_memcpy_config,
 +              .param.ctrl_lli_chained = flags_memcpy_lli_chained,
 +              .param.ctrl_lli = flags_memcpy_lli,
 +              .param.ctrl_lli_last = flags_memcpy_lli_last,
 +      },
 +      {
 +              .number = U300_DMA_GENERAL_PURPOSE_5,
 +              .name = "GENERAL 05",
 +              .priority_high = 0,
 +
 +              .param.config = flags_memcpy_config,
 +              .param.ctrl_lli_chained = flags_memcpy_lli_chained,
 +              .param.ctrl_lli = flags_memcpy_lli,
 +              .param.ctrl_lli_last = flags_memcpy_lli_last,
 +      },
 +      {
 +              .number = U300_DMA_GENERAL_PURPOSE_6,
 +              .name = "GENERAL 06",
 +              .priority_high = 0,
 +
 +              .param.config = flags_memcpy_config,
 +              .param.ctrl_lli_chained = flags_memcpy_lli_chained,
 +              .param.ctrl_lli = flags_memcpy_lli,
 +              .param.ctrl_lli_last = flags_memcpy_lli_last,
 +      },
 +      {
 +              .number = U300_DMA_GENERAL_PURPOSE_7,
 +              .name = "GENERAL 07",
 +              .priority_high = 0,
 +
 +              .param.config = flags_memcpy_config,
 +              .param.ctrl_lli_chained = flags_memcpy_lli_chained,
 +              .param.ctrl_lli = flags_memcpy_lli,
 +              .param.ctrl_lli_last = flags_memcpy_lli_last,
 +      },
 +      {
 +              .number = U300_DMA_GENERAL_PURPOSE_8,
 +              .name = "GENERAL 08",
 +              .priority_high = 0,
 +
 +              .param.config = flags_memcpy_config,
 +              .param.ctrl_lli_chained = flags_memcpy_lli_chained,
 +              .param.ctrl_lli = flags_memcpy_lli,
 +              .param.ctrl_lli_last = flags_memcpy_lli_last,
 +      },
 +      {
 +              .number = U300_DMA_UART1_TX,
 +              .name = "UART1 TX",
 +              .priority_high = 0,
 +      },
 +      {
 +              .number = U300_DMA_UART1_RX,
 +              .name = "UART1 RX",
 +              .priority_high = 0,
 +      }
 +};
 +
  #define COHC_2_DEV(cohc) (&cohc->chan.dev->device)
  
  #ifdef VERBOSE_DEBUG
@@@ -1284,6 -54,7 +1284,6 @@@ struct coh901318_base 
        struct dma_device dma_slave;
        struct dma_device dma_memcpy;
        struct coh901318_chan *chans;
 -      struct coh901318_platform *platform;
  };
  
  struct coh901318_chan {
        unsigned long nbr_active_done;
        unsigned long busy;
  
 -      u32 runtime_addr;
 -      u32 runtime_ctrl;
 +      u32 addr;
 +      u32 ctrl;
  
        struct coh901318_base *base;
  };
@@@ -1351,7 -122,7 +1351,7 @@@ static int coh901318_debugfs_read(struc
  
        tmp += sprintf(tmp, "DMA -- enabled dma channels\n");
  
 -      for (i = 0; i < debugfs_dma_base->platform->max_channels; i++)
 +      for (i = 0; i < U300_DMA_CHANNELS; i++)
                if (started_channels & (1 << i))
                        tmp += sprintf(tmp, "channel %d\n", i);
  
@@@ -1416,16 -187,25 +1416,16 @@@ static inline struct coh901318_chan *to
        return container_of(chan, struct coh901318_chan, chan);
  }
  
 -static inline dma_addr_t
 -cohc_dev_addr(struct coh901318_chan *cohc)
 -{
 -      /* Runtime supplied address will take precedence */
 -      if (cohc->runtime_addr)
 -              return cohc->runtime_addr;
 -      return cohc->base->platform->chan_conf[cohc->id].dev_addr;
 -}
 -
  static inline const struct coh901318_params *
  cohc_chan_param(struct coh901318_chan *cohc)
  {
 -      return &cohc->base->platform->chan_conf[cohc->id].param;
 +      return &chan_config[cohc->id].param;
  }
  
  static inline const struct coh_dma_channel *
  cohc_chan_conf(struct coh901318_chan *cohc)
  {
 -      return &cohc->base->platform->chan_conf[cohc->id];
 +      return &chan_config[cohc->id];
  }
  
  static void enable_powersave(struct coh901318_chan *cohc)
  
        pm->started_channels &= ~(1ULL << cohc->id);
  
 -      if (!pm->started_channels) {
 -              /* DMA no longer intends to access memory */
 -              cohc->base->platform->access_memory_state(cohc->base->dev,
 -                                                        false);
 -      }
 -
        spin_unlock_irqrestore(&pm->lock, flags);
  }
  static void disable_powersave(struct coh901318_chan *cohc)
  
        spin_lock_irqsave(&pm->lock, flags);
  
 -      if (!pm->started_channels) {
 -              /* DMA intends to access memory */
 -              cohc->base->platform->access_memory_state(cohc->base->dev,
 -                                                        true);
 -      }
 -
        pm->started_channels |= (1ULL << cohc->id);
  
        spin_unlock_irqrestore(&pm->lock, flags);
@@@ -1804,7 -596,7 +1804,7 @@@ static int coh901318_config(struct coh9
        if (param)
                p = param;
        else
 -              p = &cohc->base->platform->chan_conf[channel].param;
 +              p = cohc_chan_param(cohc);
  
        /* Clear any pending BE or TC interrupt */
        if (channel < 32) {
@@@ -2260,9 -1052,9 +2260,9 @@@ coh901318_prep_slave_sg(struct dma_cha
         * sure the bits you set per peripheral channel are
         * cleared in the default config from the platform.
         */
 -      ctrl_chained |= cohc->runtime_ctrl;
 -      ctrl_last |= cohc->runtime_ctrl;
 -      ctrl |= cohc->runtime_ctrl;
 +      ctrl_chained |= cohc->ctrl;
 +      ctrl_last |= cohc->ctrl;
 +      ctrl |= cohc->ctrl;
  
        if (direction == DMA_MEM_TO_DEV) {
                u32 tx_flags = COH901318_CX_CTRL_PRDD_SOURCE |
  
        /* initiate allocated lli list */
        ret = coh901318_lli_fill_sg(&cohc->base->pool, lli, sgl, sg_len,
 -                                  cohc_dev_addr(cohc),
 +                                  cohc->addr,
                                    ctrl_chained,
                                    ctrl,
                                    ctrl_last,
@@@ -2355,7 -1147,9 +2355,9 @@@ coh901318_tx_status(struct dma_chan *ch
        enum dma_status ret;
  
        ret = dma_cookie_status(chan, cookie, txstate);
-       /* FIXME: should be conditional on ret != DMA_SUCCESS? */
+       if (ret == DMA_SUCCESS)
+               return ret;
        dma_set_residue(txstate, coh901318_get_bytes_left(chan));
  
        if (ret == DMA_IN_PROGRESS && cohc->stopped)
@@@ -2452,7 -1246,7 +2454,7 @@@ static void coh901318_dma_set_runtimeco
        dma_addr_t addr;
        enum dma_slave_buswidth addr_width;
        u32 maxburst;
 -      u32 runtime_ctrl = 0;
 +      u32 ctrl = 0;
        int i = 0;
  
        /* We only support mem to per or per to mem transfers */
                addr_width);
        switch (addr_width)  {
        case DMA_SLAVE_BUSWIDTH_1_BYTE:
 -              runtime_ctrl |=
 +              ctrl |=
                        COH901318_CX_CTRL_SRC_BUS_SIZE_8_BITS |
                        COH901318_CX_CTRL_DST_BUS_SIZE_8_BITS;
  
  
                break;
        case DMA_SLAVE_BUSWIDTH_2_BYTES:
 -              runtime_ctrl |=
 +              ctrl |=
                        COH901318_CX_CTRL_SRC_BUS_SIZE_16_BITS |
                        COH901318_CX_CTRL_DST_BUS_SIZE_16_BITS;
  
                break;
        case DMA_SLAVE_BUSWIDTH_4_BYTES:
                /* Direction doesn't matter here, it's 32/32 bits */
 -              runtime_ctrl |=
 +              ctrl |=
                        COH901318_CX_CTRL_SRC_BUS_SIZE_32_BITS |
                        COH901318_CX_CTRL_DST_BUS_SIZE_32_BITS;
  
                return;
        }
  
 -      runtime_ctrl |= burst_sizes[i].reg;
 +      ctrl |= burst_sizes[i].reg;
        dev_dbg(COHC_2_DEV(cohc),
                "selected burst size %d bytes for address width %d bytes, maxburst %d\n",
                burst_sizes[i].burst_8bit, addr_width, maxburst);
  
 -      cohc->runtime_addr = addr;
 -      cohc->runtime_ctrl = runtime_ctrl;
 +      cohc->addr = addr;
 +      cohc->ctrl = ctrl;
  }
  
  static int
@@@ -2639,6 -1433,7 +2641,6 @@@ void coh901318_base_init(struct dma_dev
  static int __init coh901318_probe(struct platform_device *pdev)
  {
        int err = 0;
 -      struct coh901318_platform *pdata;
        struct coh901318_base *base;
        int irq;
        struct resource *io;
                                    pdev->dev.driver->name) == NULL)
                return -ENOMEM;
  
 -      pdata = pdev->dev.platform_data;
 -      if (!pdata)
 -              return -ENODEV;
 -
        base = devm_kzalloc(&pdev->dev,
                            ALIGN(sizeof(struct coh901318_base), 4) +
 -                          pdata->max_channels *
 +                          U300_DMA_CHANNELS *
                            sizeof(struct coh901318_chan),
                            GFP_KERNEL);
        if (!base)
                return -ENOMEM;
  
        base->dev = &pdev->dev;
 -      base->platform = pdata;
        spin_lock_init(&base->pm.lock);
        base->pm.started_channels = 0;
  
                return err;
  
        /* init channels for device transfers */
 -      coh901318_base_init(&base->dma_slave,  base->platform->chans_slave,
 +      coh901318_base_init(&base->dma_slave, dma_slave_channels,
                            base);
  
        dma_cap_zero(base->dma_slave.cap_mask);
                goto err_register_slave;
  
        /* init channels for memcpy */
 -      coh901318_base_init(&base->dma_memcpy, base->platform->chans_memcpy,
 +      coh901318_base_init(&base->dma_memcpy, dma_memcpy_channels,
                            base);
  
        dma_cap_zero(base->dma_memcpy.cap_mask);
index 3e96610e18e29a5e6829261ef6d912640c0ad266,fe9cc5eeddaed222ac17d93dfb71ebdcace99124..702112d547c83214bb2f0e77cd8b3a879979e541
@@@ -11,9 -11,9 +11,9 @@@
  #include <linux/memory.h>
  #include <linux/gfp.h>
  #include <linux/dmapool.h>
 -#include <mach/coh901318.h>
 +#include <linux/dmaengine.h>
  
 -#include "coh901318_lli.h"
 +#include "coh901318.h"
  
  #if (defined(CONFIG_DEBUG_FS) && defined(CONFIG_U300_DEBUG))
  #define DEBUGFS_POOL_COUNTER_RESET(pool) (pool->debugfs_pool_counter = 0)
@@@ -61,7 -61,7 +61,7 @@@ coh901318_lli_alloc(struct coh901318_po
        dma_addr_t phy;
  
        if (len == 0)
-               goto err;
+               return NULL;
  
        spin_lock(&pool->lock);
  
diff --combined drivers/dma/dw_dmac.c
index b33d1f6e13332400beab684bee3a092776531854,4c83f18803f1b351a09962775d0a78a8ccdef9d7..51c3ea2ed41af67e26dc09169fb51fbcc6117ac4
@@@ -1,6 -1,5 +1,5 @@@
  /*
-  * Driver for the Synopsys DesignWare DMA Controller (aka DMACA on
-  * AVR32 systems.)
+  * Core driver for the Synopsys DesignWare DMA Controller
   *
   * Copyright (C) 2007-2008 Atmel Corporation
   * Copyright (C) 2010-2011 ST Microelectronics
@@@ -9,12 -8,13 +8,14 @@@
   * it under the terms of the GNU General Public License version 2 as
   * published by the Free Software Foundation.
   */
  #include <linux/bitops.h>
  #include <linux/clk.h>
  #include <linux/delay.h>
  #include <linux/dmaengine.h>
  #include <linux/dma-mapping.h>
+ #include <linux/dmapool.h>
 +#include <linux/err.h>
  #include <linux/init.h>
  #include <linux/interrupt.h>
  #include <linux/io.h>
@@@ -47,15 -47,32 +48,32 @@@ static inline unsigned int dwc_get_sms(
        return slave ? slave->src_master : 1;
  }
  
+ #define SRC_MASTER    0
+ #define DST_MASTER    1
+ static inline unsigned int dwc_get_master(struct dma_chan *chan, int master)
+ {
+       struct dw_dma *dw = to_dw_dma(chan->device);
+       struct dw_dma_slave *dws = chan->private;
+       unsigned int m;
+       if (master == SRC_MASTER)
+               m = dwc_get_sms(dws);
+       else
+               m = dwc_get_dms(dws);
+       return min_t(unsigned int, dw->nr_masters - 1, m);
+ }
  #define DWC_DEFAULT_CTLLO(_chan) ({                           \
-               struct dw_dma_slave *__slave = (_chan->private);        \
                struct dw_dma_chan *_dwc = to_dw_dma_chan(_chan);       \
                struct dma_slave_config *_sconfig = &_dwc->dma_sconfig; \
-               int _dms = dwc_get_dms(__slave);                \
-               int _sms = dwc_get_sms(__slave);                \
-               u8 _smsize = __slave ? _sconfig->src_maxburst : \
+               bool _is_slave = is_slave_direction(_dwc->direction);   \
+               int _dms = dwc_get_master(_chan, DST_MASTER);           \
+               int _sms = dwc_get_master(_chan, SRC_MASTER);           \
+               u8 _smsize = _is_slave ? _sconfig->src_maxburst :       \
                        DW_DMA_MSIZE_16;                        \
-               u8 _dmsize = __slave ? _sconfig->dst_maxburst : \
+               u8 _dmsize = _is_slave ? _sconfig->dst_maxburst :       \
                        DW_DMA_MSIZE_16;                        \
                                                                \
                (DWC_CTLL_DST_MSIZE(_dmsize)                    \
   */
  #define NR_DESCS_PER_CHANNEL  64
  
- /*----------------------------------------------------------------------*/
+ static inline unsigned int dwc_get_data_width(struct dma_chan *chan, int master)
+ {
+       struct dw_dma *dw = to_dw_dma(chan->device);
  
- /*
-  * Because we're not relying on writeback from the controller (it may not
-  * even be configured into the core!) we don't need to use dma_pool.  These
-  * descriptors -- and associated data -- are cacheable.  We do need to make
-  * sure their dcache entries are written back before handing them off to
-  * the controller, though.
-  */
+       return dw->data_width[dwc_get_master(chan, master)];
+ }
+ /*----------------------------------------------------------------------*/
  
  static struct device *chan2dev(struct dma_chan *chan)
  {
@@@ -94,7 -110,7 +111,7 @@@ static struct device *chan2parent(struc
  
  static struct dw_desc *dwc_first_active(struct dw_dma_chan *dwc)
  {
-       return list_entry(dwc->active_list.next, struct dw_desc, desc_node);
+       return to_dw_desc(dwc->active_list.next);
  }
  
  static struct dw_desc *dwc_desc_get(struct dw_dma_chan *dwc)
        return ret;
  }
  
- static void dwc_sync_desc_for_cpu(struct dw_dma_chan *dwc, struct dw_desc *desc)
- {
-       struct dw_desc  *child;
-       list_for_each_entry(child, &desc->tx_list, desc_node)
-               dma_sync_single_for_cpu(chan2parent(&dwc->chan),
-                               child->txd.phys, sizeof(child->lli),
-                               DMA_TO_DEVICE);
-       dma_sync_single_for_cpu(chan2parent(&dwc->chan),
-                       desc->txd.phys, sizeof(desc->lli),
-                       DMA_TO_DEVICE);
- }
  /*
   * Move a descriptor, including any children, to the free list.
   * `desc' must not be on any lists.
@@@ -145,8 -148,6 +149,6 @@@ static void dwc_desc_put(struct dw_dma_
        if (desc) {
                struct dw_desc *child;
  
-               dwc_sync_desc_for_cpu(dwc, desc);
                spin_lock_irqsave(&dwc->lock, flags);
                list_for_each_entry(child, &desc->tx_list, desc_node)
                        dev_vdbg(chan2dev(&dwc->chan),
@@@ -179,9 -180,9 +181,9 @@@ static void dwc_initialize(struct dw_dm
                cfghi = dws->cfg_hi;
                cfglo |= dws->cfg_lo & ~DWC_CFGL_CH_PRIOR_MASK;
        } else {
-               if (dwc->dma_sconfig.direction == DMA_MEM_TO_DEV)
+               if (dwc->direction == DMA_MEM_TO_DEV)
                        cfghi = DWC_CFGH_DST_PER(dwc->dma_sconfig.slave_id);
-               else if (dwc->dma_sconfig.direction == DMA_DEV_TO_MEM)
+               else if (dwc->direction == DMA_DEV_TO_MEM)
                        cfghi = DWC_CFGH_SRC_PER(dwc->dma_sconfig.slave_id);
        }
  
@@@ -223,7 -224,6 +225,6 @@@ static inline void dwc_dump_chan_regs(s
                channel_readl(dwc, CTL_LO));
  }
  
  static inline void dwc_chan_disable(struct dw_dma *dw, struct dw_dma_chan *dwc)
  {
        channel_clear_bit(dw, CH_EN, dwc->mask);
@@@ -249,6 -249,9 +250,9 @@@ static inline void dwc_do_single_block(
        channel_writel(dwc, CTL_LO, ctllo);
        channel_writel(dwc, CTL_HI, desc->lli.ctlhi);
        channel_set_bit(dw, CH_EN, dwc->mask);
+       /* Move pointer to next descriptor */
+       dwc->tx_node_active = dwc->tx_node_active->next;
  }
  
  /* Called with dwc->lock held and bh disabled */
@@@ -279,9 -282,10 +283,10 @@@ static void dwc_dostart(struct dw_dma_c
  
                dwc_initialize(dwc);
  
-               dwc->tx_list = &first->tx_list;
-               dwc->tx_node_active = first->tx_list.next;
+               dwc->residue = first->total_len;
+               dwc->tx_node_active = &first->tx_list;
  
+               /* Submit first block */
                dwc_do_single_block(dwc, first);
  
                return;
@@@ -317,8 -321,6 +322,6 @@@ dwc_descriptor_complete(struct dw_dma_c
                param = txd->callback_param;
        }
  
-       dwc_sync_desc_for_cpu(dwc, desc);
        /* async_tx_ack */
        list_for_each_entry(child, &desc->tx_list, desc_node)
                async_tx_ack(&child->txd);
        list_splice_init(&desc->tx_list, &dwc->free_list);
        list_move(&desc->desc_node, &dwc->free_list);
  
-       if (!dwc->chan.private) {
+       if (!is_slave_direction(dwc->direction)) {
                struct device *parent = chan2parent(&dwc->chan);
                if (!(txd->flags & DMA_COMPL_SKIP_DEST_UNMAP)) {
                        if (txd->flags & DMA_COMPL_DEST_UNMAP_SINGLE)
                                dma_unmap_single(parent, desc->lli.dar,
-                                               desc->len, DMA_FROM_DEVICE);
+                                       desc->total_len, DMA_FROM_DEVICE);
                        else
                                dma_unmap_page(parent, desc->lli.dar,
-                                               desc->len, DMA_FROM_DEVICE);
+                                       desc->total_len, DMA_FROM_DEVICE);
                }
                if (!(txd->flags & DMA_COMPL_SKIP_SRC_UNMAP)) {
                        if (txd->flags & DMA_COMPL_SRC_UNMAP_SINGLE)
                                dma_unmap_single(parent, desc->lli.sar,
-                                               desc->len, DMA_TO_DEVICE);
+                                       desc->total_len, DMA_TO_DEVICE);
                        else
                                dma_unmap_page(parent, desc->lli.sar,
-                                               desc->len, DMA_TO_DEVICE);
+                                       desc->total_len, DMA_TO_DEVICE);
                }
        }
  
        spin_unlock_irqrestore(&dwc->lock, flags);
  
-       if (callback_required && callback)
+       if (callback)
                callback(param);
  }
  
@@@ -384,6 -386,15 +387,15 @@@ static void dwc_complete_all(struct dw_
                dwc_descriptor_complete(dwc, desc, true);
  }
  
+ /* Returns how many bytes were already received from source */
+ static inline u32 dwc_get_sent(struct dw_dma_chan *dwc)
+ {
+       u32 ctlhi = channel_readl(dwc, CTL_HI);
+       u32 ctllo = channel_readl(dwc, CTL_LO);
+       return (ctlhi & DWC_CTLH_BLOCK_TS_MASK) * (1 << (ctllo >> 4 & 7));
+ }
  static void dwc_scan_descriptors(struct dw_dma *dw, struct dw_dma_chan *dwc)
  {
        dma_addr_t llp;
        if (status_xfer & dwc->mask) {
                /* Everything we've submitted is done */
                dma_writel(dw, CLEAR.XFER, dwc->mask);
+               if (test_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags)) {
+                       struct list_head *head, *active = dwc->tx_node_active;
+                       /*
+                        * We are inside first active descriptor.
+                        * Otherwise something is really wrong.
+                        */
+                       desc = dwc_first_active(dwc);
+                       head = &desc->tx_list;
+                       if (active != head) {
+                               /* Update desc to reflect last sent one */
+                               if (active != head->next)
+                                       desc = to_dw_desc(active->prev);
+                               dwc->residue -= desc->len;
+                               child = to_dw_desc(active);
+                               /* Submit next block */
+                               dwc_do_single_block(dwc, child);
+                               spin_unlock_irqrestore(&dwc->lock, flags);
+                               return;
+                       }
+                       /* We are done here */
+                       clear_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags);
+               }
+               dwc->residue = 0;
                spin_unlock_irqrestore(&dwc->lock, flags);
  
                dwc_complete_all(dw, dwc);
        }
  
        if (list_empty(&dwc->active_list)) {
+               dwc->residue = 0;
+               spin_unlock_irqrestore(&dwc->lock, flags);
+               return;
+       }
+       if (test_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags)) {
+               dev_vdbg(chan2dev(&dwc->chan), "%s: soft LLP mode\n", __func__);
                spin_unlock_irqrestore(&dwc->lock, flags);
                return;
        }
                        (unsigned long long)llp);
  
        list_for_each_entry_safe(desc, _desc, &dwc->active_list, desc_node) {
+               /* initial residue value */
+               dwc->residue = desc->total_len;
                /* check first descriptors addr */
                if (desc->txd.phys == llp) {
                        spin_unlock_irqrestore(&dwc->lock, flags);
                /* check first descriptors llp */
                if (desc->lli.llp == llp) {
                        /* This one is currently in progress */
+                       dwc->residue -= dwc_get_sent(dwc);
                        spin_unlock_irqrestore(&dwc->lock, flags);
                        return;
                }
  
-               list_for_each_entry(child, &desc->tx_list, desc_node)
+               dwc->residue -= desc->len;
+               list_for_each_entry(child, &desc->tx_list, desc_node) {
                        if (child->lli.llp == llp) {
                                /* Currently in progress */
+                               dwc->residue -= dwc_get_sent(dwc);
                                spin_unlock_irqrestore(&dwc->lock, flags);
                                return;
                        }
+                       dwc->residue -= child->len;
+               }
  
                /*
                 * No descriptors so far seem to be in progress, i.e.
  
  static inline void dwc_dump_lli(struct dw_dma_chan *dwc, struct dw_lli *lli)
  {
-       dev_printk(KERN_CRIT, chan2dev(&dwc->chan),
-                       "  desc: s0x%x d0x%x l0x%x c0x%x:%x\n",
-                       lli->sar, lli->dar, lli->llp, lli->ctlhi, lli->ctllo);
+       dev_crit(chan2dev(&dwc->chan), "  desc: s0x%x d0x%x l0x%x c0x%x:%x\n",
+                lli->sar, lli->dar, lli->llp, lli->ctlhi, lli->ctllo);
  }
  
  static void dwc_handle_error(struct dw_dma *dw, struct dw_dma_chan *dwc)
                dwc_dostart(dwc, dwc_first_active(dwc));
  
        /*
-        * KERN_CRITICAL may seem harsh, but since this only happens
+        * WARN may seem harsh, but since this only happens
         * when someone submits a bad physical address in a
         * descriptor, we should consider ourselves lucky that the
         * controller flagged an error instead of scribbling over
         * random memory locations.
         */
-       dev_printk(KERN_CRIT, chan2dev(&dwc->chan),
-                       "Bad descriptor submitted for DMA!\n");
-       dev_printk(KERN_CRIT, chan2dev(&dwc->chan),
-                       "  cookie: %d\n", bad_desc->txd.cookie);
+       dev_WARN(chan2dev(&dwc->chan), "Bad descriptor submitted for DMA!\n"
+                                      "  cookie: %d\n", bad_desc->txd.cookie);
        dwc_dump_lli(dwc, &bad_desc->lli);
        list_for_each_entry(child, &bad_desc->tx_list, desc_node)
                dwc_dump_lli(dwc, &child->lli);
@@@ -598,36 -654,8 +655,8 @@@ static void dw_dma_tasklet(unsigned lon
                        dwc_handle_cyclic(dw, dwc, status_err, status_xfer);
                else if (status_err & (1 << i))
                        dwc_handle_error(dw, dwc);
-               else if (status_xfer & (1 << i)) {
-                       unsigned long flags;
-                       spin_lock_irqsave(&dwc->lock, flags);
-                       if (test_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags)) {
-                               if (dwc->tx_node_active != dwc->tx_list) {
-                                       struct dw_desc *desc =
-                                               list_entry(dwc->tx_node_active,
-                                                          struct dw_desc,
-                                                          desc_node);
-                                       dma_writel(dw, CLEAR.XFER, dwc->mask);
-                                       /* move pointer to next descriptor */
-                                       dwc->tx_node_active =
-                                               dwc->tx_node_active->next;
-                                       dwc_do_single_block(dwc, desc);
-                                       spin_unlock_irqrestore(&dwc->lock, flags);
-                                       continue;
-                               } else {
-                                       /* we are done here */
-                                       clear_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags);
-                               }
-                       }
-                       spin_unlock_irqrestore(&dwc->lock, flags);
+               else if (status_xfer & (1 << i))
                        dwc_scan_descriptors(dw, dwc);
-               }
        }
  
        /*
@@@ -709,7 -737,6 +738,6 @@@ dwc_prep_dma_memcpy(struct dma_chan *ch
                size_t len, unsigned long flags)
  {
        struct dw_dma_chan      *dwc = to_dw_dma_chan(chan);
-       struct dw_dma_slave     *dws = chan->private;
        struct dw_desc          *desc;
        struct dw_desc          *first;
        struct dw_desc          *prev;
                return NULL;
        }
  
-       data_width = min_t(unsigned int, dwc->dw->data_width[dwc_get_sms(dws)],
-                                        dwc->dw->data_width[dwc_get_dms(dws)]);
+       dwc->direction = DMA_MEM_TO_MEM;
+       data_width = min_t(unsigned int, dwc_get_data_width(chan, SRC_MASTER),
+                          dwc_get_data_width(chan, DST_MASTER));
  
        src_width = dst_width = min_t(unsigned int, data_width,
                                      dwc_fast_fls(src | dest | len));
                desc->lli.dar = dest + offset;
                desc->lli.ctllo = ctllo;
                desc->lli.ctlhi = xfer_count;
+               desc->len = xfer_count << src_width;
  
                if (!first) {
                        first = desc;
                } else {
                        prev->lli.llp = desc->txd.phys;
-                       dma_sync_single_for_device(chan2parent(chan),
-                                       prev->txd.phys, sizeof(prev->lli),
-                                       DMA_TO_DEVICE);
                        list_add_tail(&desc->desc_node,
                                        &first->tx_list);
                }
                prev = desc;
        }
  
        if (flags & DMA_PREP_INTERRUPT)
                /* Trigger interrupt after last block */
                prev->lli.ctllo |= DWC_CTLL_INT_EN;
  
        prev->lli.llp = 0;
-       dma_sync_single_for_device(chan2parent(chan),
-                       prev->txd.phys, sizeof(prev->lli),
-                       DMA_TO_DEVICE);
        first->txd.flags = flags;
-       first->len = len;
+       first->total_len = len;
  
        return &first->txd;
  
@@@ -796,7 -818,6 +819,6 @@@ dwc_prep_slave_sg(struct dma_chan *chan
                unsigned long flags, void *context)
  {
        struct dw_dma_chan      *dwc = to_dw_dma_chan(chan);
-       struct dw_dma_slave     *dws = chan->private;
        struct dma_slave_config *sconfig = &dwc->dma_sconfig;
        struct dw_desc          *prev;
        struct dw_desc          *first;
  
        dev_vdbg(chan2dev(chan), "%s\n", __func__);
  
-       if (unlikely(!dws || !sg_len))
+       if (unlikely(!is_slave_direction(direction) || !sg_len))
                return NULL;
  
+       dwc->direction = direction;
        prev = first = NULL;
  
        switch (direction) {
                ctllo |= sconfig->device_fc ? DWC_CTLL_FC(DW_DMA_FC_P_M2P) :
                        DWC_CTLL_FC(DW_DMA_FC_D_M2P);
  
-               data_width = dwc->dw->data_width[dwc_get_sms(dws)];
+               data_width = dwc_get_data_width(chan, SRC_MASTER);
  
                for_each_sg(sgl, sg, sg_len, i) {
                        struct dw_desc  *desc;
@@@ -861,15 -884,12 +885,12 @@@ slave_sg_todev_fill_desc
                        }
  
                        desc->lli.ctlhi = dlen >> mem_width;
+                       desc->len = dlen;
  
                        if (!first) {
                                first = desc;
                        } else {
                                prev->lli.llp = desc->txd.phys;
-                               dma_sync_single_for_device(chan2parent(chan),
-                                               prev->txd.phys,
-                                               sizeof(prev->lli),
-                                               DMA_TO_DEVICE);
                                list_add_tail(&desc->desc_node,
                                                &first->tx_list);
                        }
                ctllo |= sconfig->device_fc ? DWC_CTLL_FC(DW_DMA_FC_P_P2M) :
                        DWC_CTLL_FC(DW_DMA_FC_D_P2M);
  
-               data_width = dwc->dw->data_width[dwc_get_dms(dws)];
+               data_width = dwc_get_data_width(chan, DST_MASTER);
  
                for_each_sg(sgl, sg, sg_len, i) {
                        struct dw_desc  *desc;
@@@ -923,15 -943,12 +944,12 @@@ slave_sg_fromdev_fill_desc
                                len = 0;
                        }
                        desc->lli.ctlhi = dlen >> reg_width;
+                       desc->len = dlen;
  
                        if (!first) {
                                first = desc;
                        } else {
                                prev->lli.llp = desc->txd.phys;
-                               dma_sync_single_for_device(chan2parent(chan),
-                                               prev->txd.phys,
-                                               sizeof(prev->lli),
-                                               DMA_TO_DEVICE);
                                list_add_tail(&desc->desc_node,
                                                &first->tx_list);
                        }
                prev->lli.ctllo |= DWC_CTLL_INT_EN;
  
        prev->lli.llp = 0;
-       dma_sync_single_for_device(chan2parent(chan),
-                       prev->txd.phys, sizeof(prev->lli),
-                       DMA_TO_DEVICE);
-       first->len = total_len;
+       first->total_len = total_len;
  
        return &first->txd;
  
@@@ -985,11 -998,12 +999,12 @@@ set_runtime_config(struct dma_chan *cha
  {
        struct dw_dma_chan *dwc = to_dw_dma_chan(chan);
  
-       /* Check if it is chan is configured for slave transfers */
-       if (!chan->private)
+       /* Check if chan will be configured for slave transfers */
+       if (!is_slave_direction(sconfig->direction))
                return -EINVAL;
  
        memcpy(&dwc->dma_sconfig, sconfig, sizeof(*sconfig));
+       dwc->direction = sconfig->direction;
  
        convert_burst(&dwc->dma_sconfig.src_maxburst);
        convert_burst(&dwc->dma_sconfig.dst_maxburst);
        return 0;
  }
  
+ static inline void dwc_chan_pause(struct dw_dma_chan *dwc)
+ {
+       u32 cfglo = channel_readl(dwc, CFG_LO);
+       channel_writel(dwc, CFG_LO, cfglo | DWC_CFGL_CH_SUSP);
+       while (!(channel_readl(dwc, CFG_LO) & DWC_CFGL_FIFO_EMPTY))
+               cpu_relax();
+       dwc->paused = true;
+ }
+ static inline void dwc_chan_resume(struct dw_dma_chan *dwc)
+ {
+       u32 cfglo = channel_readl(dwc, CFG_LO);
+       channel_writel(dwc, CFG_LO, cfglo & ~DWC_CFGL_CH_SUSP);
+       dwc->paused = false;
+ }
  static int dwc_control(struct dma_chan *chan, enum dma_ctrl_cmd cmd,
                       unsigned long arg)
  {
        struct dw_dma           *dw = to_dw_dma(chan->device);
        struct dw_desc          *desc, *_desc;
        unsigned long           flags;
-       u32                     cfglo;
        LIST_HEAD(list);
  
        if (cmd == DMA_PAUSE) {
                spin_lock_irqsave(&dwc->lock, flags);
  
-               cfglo = channel_readl(dwc, CFG_LO);
-               channel_writel(dwc, CFG_LO, cfglo | DWC_CFGL_CH_SUSP);
-               while (!(channel_readl(dwc, CFG_LO) & DWC_CFGL_FIFO_EMPTY))
-                       cpu_relax();
+               dwc_chan_pause(dwc);
  
-               dwc->paused = true;
                spin_unlock_irqrestore(&dwc->lock, flags);
        } else if (cmd == DMA_RESUME) {
                if (!dwc->paused)
  
                spin_lock_irqsave(&dwc->lock, flags);
  
-               cfglo = channel_readl(dwc, CFG_LO);
-               channel_writel(dwc, CFG_LO, cfglo & ~DWC_CFGL_CH_SUSP);
-               dwc->paused = false;
+               dwc_chan_resume(dwc);
  
                spin_unlock_irqrestore(&dwc->lock, flags);
        } else if (cmd == DMA_TERMINATE_ALL) {
  
                dwc_chan_disable(dw, dwc);
  
-               dwc->paused = false;
+               dwc_chan_resume(dwc);
  
                /* active_list entries will end up before queued entries */
                list_splice_init(&dwc->queue, &list);
        return 0;
  }
  
+ static inline u32 dwc_get_residue(struct dw_dma_chan *dwc)
+ {
+       unsigned long flags;
+       u32 residue;
+       spin_lock_irqsave(&dwc->lock, flags);
+       residue = dwc->residue;
+       if (test_bit(DW_DMA_IS_SOFT_LLP, &dwc->flags) && residue)
+               residue -= dwc_get_sent(dwc);
+       spin_unlock_irqrestore(&dwc->lock, flags);
+       return residue;
+ }
  static enum dma_status
  dwc_tx_status(struct dma_chan *chan,
              dma_cookie_t cookie,
        }
  
        if (ret != DMA_SUCCESS)
-               dma_set_residue(txstate, dwc_first_active(dwc)->len);
+               dma_set_residue(txstate, dwc_get_residue(dwc));
  
        if (dwc->paused)
                return DMA_PAUSED;
@@@ -1114,22 -1156,22 +1157,22 @@@ static int dwc_alloc_chan_resources(str
        spin_lock_irqsave(&dwc->lock, flags);
        i = dwc->descs_allocated;
        while (dwc->descs_allocated < NR_DESCS_PER_CHANNEL) {
+               dma_addr_t phys;
                spin_unlock_irqrestore(&dwc->lock, flags);
  
-               desc = kzalloc(sizeof(struct dw_desc), GFP_KERNEL);
-               if (!desc) {
-                       dev_info(chan2dev(chan),
-                               "only allocated %d descriptors\n", i);
-                       spin_lock_irqsave(&dwc->lock, flags);
-                       break;
-               }
+               desc = dma_pool_alloc(dw->desc_pool, GFP_ATOMIC, &phys);
+               if (!desc)
+                       goto err_desc_alloc;
+               memset(desc, 0, sizeof(struct dw_desc));
  
                INIT_LIST_HEAD(&desc->tx_list);
                dma_async_tx_descriptor_init(&desc->txd, chan);
                desc->txd.tx_submit = dwc_tx_submit;
                desc->txd.flags = DMA_CTRL_ACK;
-               desc->txd.phys = dma_map_single(chan2parent(chan), &desc->lli,
-                               sizeof(desc->lli), DMA_TO_DEVICE);
+               desc->txd.phys = phys;
                dwc_desc_put(dwc, desc);
  
                spin_lock_irqsave(&dwc->lock, flags);
  
        dev_dbg(chan2dev(chan), "%s: allocated %d descriptors\n", __func__, i);
  
+       return i;
+ err_desc_alloc:
+       dev_info(chan2dev(chan), "only allocated %d descriptors\n", i);
        return i;
  }
  
@@@ -1172,14 -1219,56 +1220,56 @@@ static void dwc_free_chan_resources(str
  
        list_for_each_entry_safe(desc, _desc, &list, desc_node) {
                dev_vdbg(chan2dev(chan), "  freeing descriptor %p\n", desc);
-               dma_unmap_single(chan2parent(chan), desc->txd.phys,
-                               sizeof(desc->lli), DMA_TO_DEVICE);
-               kfree(desc);
+               dma_pool_free(dw->desc_pool, desc, desc->txd.phys);
        }
  
        dev_vdbg(chan2dev(chan), "%s: done\n", __func__);
  }
  
+ bool dw_dma_generic_filter(struct dma_chan *chan, void *param)
+ {
+       struct dw_dma *dw = to_dw_dma(chan->device);
+       static struct dw_dma *last_dw;
+       static char *last_bus_id;
+       int i = -1;
+       /*
+        * dmaengine framework calls this routine for all channels of all dma
+        * controller, until true is returned. If 'param' bus_id is not
+        * registered with a dma controller (dw), then there is no need of
+        * running below function for all channels of dw.
+        *
+        * This block of code does this by saving the parameters of last
+        * failure. If dw and param are same, i.e. trying on same dw with
+        * different channel, return false.
+        */
+       if ((last_dw == dw) && (last_bus_id == param))
+               return false;
+       /*
+        * Return true:
+        * - If dw_dma's platform data is not filled with slave info, then all
+        *   dma controllers are fine for transfer.
+        * - Or if param is NULL
+        */
+       if (!dw->sd || !param)
+               return true;
+       while (++i < dw->sd_count) {
+               if (!strcmp(dw->sd[i].bus_id, param)) {
+                       chan->private = &dw->sd[i];
+                       last_dw = NULL;
+                       last_bus_id = NULL;
+                       return true;
+               }
+       }
+       last_dw = dw;
+       last_bus_id = param;
+       return false;
+ }
+ EXPORT_SYMBOL(dw_dma_generic_filter);
  /* --------------------- Cyclic DMA API extensions -------------------- */
  
  /**
@@@ -1299,6 -1388,11 +1389,11 @@@ struct dw_cyclic_desc *dw_dma_cyclic_pr
  
        retval = ERR_PTR(-EINVAL);
  
+       if (unlikely(!is_slave_direction(direction)))
+               goto out_err;
+       dwc->direction = direction;
        if (direction == DMA_MEM_TO_DEV)
                reg_width = __ffs(sconfig->dst_addr_width);
        else
                goto out_err;
        if (unlikely(buf_addr & ((1 << reg_width) - 1)))
                goto out_err;
-       if (unlikely(!(direction & (DMA_MEM_TO_DEV | DMA_DEV_TO_MEM))))
-               goto out_err;
  
        retval = ERR_PTR(-ENOMEM);
  
                desc->lli.ctlhi = (period_len >> reg_width);
                cdesc->desc[i] = desc;
  
-               if (last) {
+               if (last)
                        last->lli.llp = desc->txd.phys;
-                       dma_sync_single_for_device(chan2parent(chan),
-                                       last->txd.phys, sizeof(last->lli),
-                                       DMA_TO_DEVICE);
-               }
  
                last = desc;
        }
  
        /* lets make a cyclic list */
        last->lli.llp = cdesc->desc[0]->txd.phys;
-       dma_sync_single_for_device(chan2parent(chan), last->txd.phys,
-                       sizeof(last->lli), DMA_TO_DEVICE);
  
        dev_dbg(chan2dev(&dwc->chan), "cyclic prepared buf 0x%llx len %zu "
                        "period %zu periods %d\n", (unsigned long long)buf_addr,
@@@ -1463,6 -1549,91 +1550,91 @@@ static void dw_dma_off(struct dw_dma *d
                dw->chan[i].initialized = false;
  }
  
+ #ifdef CONFIG_OF
+ static struct dw_dma_platform_data *
+ dw_dma_parse_dt(struct platform_device *pdev)
+ {
+       struct device_node *sn, *cn, *np = pdev->dev.of_node;
+       struct dw_dma_platform_data *pdata;
+       struct dw_dma_slave *sd;
+       u32 tmp, arr[4];
+       if (!np) {
+               dev_err(&pdev->dev, "Missing DT data\n");
+               return NULL;
+       }
+       pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+       if (!pdata)
+               return NULL;
+       if (of_property_read_u32(np, "nr_channels", &pdata->nr_channels))
+               return NULL;
+       if (of_property_read_bool(np, "is_private"))
+               pdata->is_private = true;
+       if (!of_property_read_u32(np, "chan_allocation_order", &tmp))
+               pdata->chan_allocation_order = (unsigned char)tmp;
+       if (!of_property_read_u32(np, "chan_priority", &tmp))
+               pdata->chan_priority = tmp;
+       if (!of_property_read_u32(np, "block_size", &tmp))
+               pdata->block_size = tmp;
+       if (!of_property_read_u32(np, "nr_masters", &tmp)) {
+               if (tmp > 4)
+                       return NULL;
+               pdata->nr_masters = tmp;
+       }
+       if (!of_property_read_u32_array(np, "data_width", arr,
+                               pdata->nr_masters))
+               for (tmp = 0; tmp < pdata->nr_masters; tmp++)
+                       pdata->data_width[tmp] = arr[tmp];
+       /* parse slave data */
+       sn = of_find_node_by_name(np, "slave_info");
+       if (!sn)
+               return pdata;
+       /* calculate number of slaves */
+       tmp = of_get_child_count(sn);
+       if (!tmp)
+               return NULL;
+       sd = devm_kzalloc(&pdev->dev, sizeof(*sd) * tmp, GFP_KERNEL);
+       if (!sd)
+               return NULL;
+       pdata->sd = sd;
+       pdata->sd_count = tmp;
+       for_each_child_of_node(sn, cn) {
+               sd->dma_dev = &pdev->dev;
+               of_property_read_string(cn, "bus_id", &sd->bus_id);
+               of_property_read_u32(cn, "cfg_hi", &sd->cfg_hi);
+               of_property_read_u32(cn, "cfg_lo", &sd->cfg_lo);
+               if (!of_property_read_u32(cn, "src_master", &tmp))
+                       sd->src_master = tmp;
+               if (!of_property_read_u32(cn, "dst_master", &tmp))
+                       sd->dst_master = tmp;
+               sd++;
+       }
+       return pdata;
+ }
+ #else
+ static inline struct dw_dma_platform_data *
+ dw_dma_parse_dt(struct platform_device *pdev)
+ {
+       return NULL;
+ }
+ #endif
  static int dw_probe(struct platform_device *pdev)
  {
        struct dw_dma_platform_data *pdata;
        int                     err;
        int                     i;
  
-       pdata = dev_get_platdata(&pdev->dev);
-       if (!pdata || pdata->nr_channels > DW_DMA_MAX_NR_CHANNELS)
-               return -EINVAL;
        io = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!io)
                return -EINVAL;
        if (irq < 0)
                return irq;
  
 -      regs = devm_request_and_ioremap(&pdev->dev, io);
 -      if (!regs)
 -              return -EBUSY;
 +      regs = devm_ioremap_resource(&pdev->dev, io);
 +      if (IS_ERR(regs))
 +              return PTR_ERR(regs);
  
+       /* Apply default dma_mask if needed */
+       if (!pdev->dev.dma_mask) {
+               pdev->dev.dma_mask = &pdev->dev.coherent_dma_mask;
+               pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+       }
        dw_params = dma_read_byaddr(regs, DW_PARAMS);
        autocfg = dw_params >> DW_PARAMS_EN & 0x1;
  
+       dev_dbg(&pdev->dev, "DW_PARAMS: 0x%08x\n", dw_params);
+       pdata = dev_get_platdata(&pdev->dev);
+       if (!pdata)
+               pdata = dw_dma_parse_dt(pdev);
+       if (!pdata && autocfg) {
+               pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+               if (!pdata)
+                       return -ENOMEM;
+               /* Fill platform data with the default values */
+               pdata->is_private = true;
+               pdata->chan_allocation_order = CHAN_ALLOCATION_ASCENDING;
+               pdata->chan_priority = CHAN_PRIORITY_ASCENDING;
+       } else if (!pdata || pdata->nr_channels > DW_DMA_MAX_NR_CHANNELS)
+               return -EINVAL;
        if (autocfg)
                nr_channels = (dw_params >> DW_PARAMS_NR_CHAN & 0x7) + 1;
        else
        clk_prepare_enable(dw->clk);
  
        dw->regs = regs;
+       dw->sd = pdata->sd;
+       dw->sd_count = pdata->sd_count;
  
        /* get hardware configuration parameters */
        if (autocfg) {
  
        platform_set_drvdata(pdev, dw);
  
+       /* create a pool of consistent memory blocks for hardware descriptors */
+       dw->desc_pool = dmam_pool_create("dw_dmac_desc_pool", &pdev->dev,
+                                        sizeof(struct dw_desc), 4, 0);
+       if (!dw->desc_pool) {
+               dev_err(&pdev->dev, "No memory for descriptors dma pool\n");
+               return -ENOMEM;
+       }
        tasklet_init(&dw->tasklet, dw_dma_tasklet, (unsigned long)dw);
  
        INIT_LIST_HEAD(&dw->dma.channels);
  
                channel_clear_bit(dw, CH_EN, dwc->mask);
  
-               dwc->dw = dw;
+               dwc->direction = DMA_TRANS_NONE;
  
                /* hardware configuration */
                if (autocfg) {
                        dwc_params = dma_read_byaddr(regs + r * sizeof(u32),
                                                     DWC_PARAMS);
  
+                       dev_dbg(&pdev->dev, "DWC_PARAMS[%d]: 0x%08x\n", i,
+                                           dwc_params);
                        /* Decode maximum block size for given channel. The
                         * stored 4 bit value represents blocks from 0x00 for 3
                         * up to 0x0a for 4095. */
  
        dma_writel(dw, CFG, DW_CFG_DMA_EN);
  
-       printk(KERN_INFO "%s: DesignWare DMA Controller, %d channels\n",
-                       dev_name(&pdev->dev), nr_channels);
+       dev_info(&pdev->dev, "DesignWare DMA Controller, %d channels\n",
+                nr_channels);
  
        dma_async_device_register(&dw->dma);
  
        return 0;
  }
  
 -static int __devexit dw_remove(struct platform_device *pdev)
 +static int dw_remove(struct platform_device *pdev)
  {
        struct dw_dma           *dw = platform_get_drvdata(pdev);
        struct dw_dma_chan      *dwc, *_dwc;
@@@ -1658,7 -1862,7 +1863,7 @@@ static void dw_shutdown(struct platform
  {
        struct dw_dma   *dw = platform_get_drvdata(pdev);
  
-       dw_dma_off(platform_get_drvdata(pdev));
+       dw_dma_off(dw);
        clk_disable_unprepare(dw->clk);
  }
  
@@@ -1667,7 -1871,7 +1872,7 @@@ static int dw_suspend_noirq(struct devi
        struct platform_device *pdev = to_platform_device(dev);
        struct dw_dma   *dw = platform_get_drvdata(pdev);
  
-       dw_dma_off(platform_get_drvdata(pdev));
+       dw_dma_off(dw);
        clk_disable_unprepare(dw->clk);
  
        return 0;
@@@ -1680,6 -1884,7 +1885,7 @@@ static int dw_resume_noirq(struct devic
  
        clk_prepare_enable(dw->clk);
        dma_writel(dw, CFG, DW_CFG_DMA_EN);
        return 0;
  }
  
@@@ -1700,7 -1905,13 +1906,13 @@@ static const struct of_device_id dw_dma
  MODULE_DEVICE_TABLE(of, dw_dma_id_table);
  #endif
  
+ static const struct platform_device_id dw_dma_ids[] = {
+       { "INTL9C60", 0 },
+       { }
+ };
  static struct platform_driver dw_driver = {
+       .probe          = dw_probe,
        .remove         = dw_remove,
        .shutdown       = dw_shutdown,
        .driver = {
                .pm     = &dw_dev_pm_ops,
                .of_match_table = of_match_ptr(dw_dma_id_table),
        },
+       .id_table       = dw_dma_ids,
  };
  
  static int __init dw_init(void)
  {
-       return platform_driver_probe(&dw_driver, dw_probe);
+       return platform_driver_register(&dw_driver);
  }
  subsys_initcall(dw_init);
  
diff --combined drivers/dma/edma.c
index f424298f1ac5094513f6ac9f3e3a64cbaa681ba6,af44cadb8de190a6c249a4e3513ecee7b845ce96..cd7e3280fadd121e9dfbd13fef93212c4b217435
@@@ -69,9 -69,7 +69,7 @@@ struct edma_chan 
        int                             ch_num;
        bool                            alloced;
        int                             slot[EDMA_MAX_SLOTS];
-       dma_addr_t                      addr;
-       int                             addr_width;
-       int                             maxburst;
+       struct dma_slave_config         cfg;
  };
  
  struct edma_cc {
@@@ -178,29 -176,14 +176,14 @@@ static int edma_terminate_all(struct ed
        return 0;
  }
  
  static int edma_slave_config(struct edma_chan *echan,
-       struct dma_slave_config *config)
+       struct dma_slave_config *cfg)
  {
-       if ((config->src_addr_width > DMA_SLAVE_BUSWIDTH_4_BYTES) ||
-           (config->dst_addr_width > DMA_SLAVE_BUSWIDTH_4_BYTES))
+       if (cfg->src_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES ||
+           cfg->dst_addr_width == DMA_SLAVE_BUSWIDTH_8_BYTES)
                return -EINVAL;
  
-       if (config->direction == DMA_MEM_TO_DEV) {
-               if (config->dst_addr)
-                       echan->addr = config->dst_addr;
-               if (config->dst_addr_width)
-                       echan->addr_width = config->dst_addr_width;
-               if (config->dst_maxburst)
-                       echan->maxburst = config->dst_maxburst;
-       } else if (config->direction == DMA_DEV_TO_MEM) {
-               if (config->src_addr)
-                       echan->addr = config->src_addr;
-               if (config->src_addr_width)
-                       echan->addr_width = config->src_addr_width;
-               if (config->src_maxburst)
-                       echan->maxburst = config->src_maxburst;
-       }
+       memcpy(&echan->cfg, cfg, sizeof(echan->cfg));
  
        return 0;
  }
@@@ -235,6 -218,9 +218,9 @@@ static struct dma_async_tx_descriptor *
        struct edma_chan *echan = to_edma_chan(chan);
        struct device *dev = chan->device->dev;
        struct edma_desc *edesc;
+       dma_addr_t dev_addr;
+       enum dma_slave_buswidth dev_width;
+       u32 burst;
        struct scatterlist *sg;
        int i;
        int acnt, bcnt, ccnt, src, dst, cidx;
        if (unlikely(!echan || !sgl || !sg_len))
                return NULL;
  
-       if (echan->addr_width == DMA_SLAVE_BUSWIDTH_UNDEFINED) {
+       if (direction == DMA_DEV_TO_MEM) {
+               dev_addr = echan->cfg.src_addr;
+               dev_width = echan->cfg.src_addr_width;
+               burst = echan->cfg.src_maxburst;
+       } else if (direction == DMA_MEM_TO_DEV) {
+               dev_addr = echan->cfg.dst_addr;
+               dev_width = echan->cfg.dst_addr_width;
+               burst = echan->cfg.dst_maxburst;
+       } else {
+               dev_err(dev, "%s: bad direction?\n", __func__);
+               return NULL;
+       }
+       if (dev_width == DMA_SLAVE_BUSWIDTH_UNDEFINED) {
                dev_err(dev, "Undefined slave buswidth\n");
                return NULL;
        }
                        }
                }
  
-               acnt = echan->addr_width;
+               acnt = dev_width;
  
                /*
                 * If the maxburst is equal to the fifo width, use
                 * A-synced transfers. This allows for large contiguous
                 * buffer transfers using only one PaRAM set.
                 */
-               if (echan->maxburst == 1) {
+               if (burst == 1) {
                        edesc->absync = false;
                        ccnt = sg_dma_len(sg) / acnt / (SZ_64K - 1);
                        bcnt = sg_dma_len(sg) / acnt - ccnt * (SZ_64K - 1);
                 */
                } else {
                        edesc->absync = true;
-                       bcnt = echan->maxburst;
+                       bcnt = burst;
                        ccnt = sg_dma_len(sg) / (acnt * bcnt);
                        if (ccnt > (SZ_64K - 1)) {
                                dev_err(dev, "Exceeded max SG segment size\n");
  
                if (direction == DMA_MEM_TO_DEV) {
                        src = sg_dma_address(sg);
-                       dst = echan->addr;
+                       dst = dev_addr;
                        src_bidx = acnt;
                        src_cidx = cidx;
                        dst_bidx = 0;
                        dst_cidx = 0;
                } else {
-                       src = echan->addr;
+                       src = dev_addr;
                        dst = sg_dma_address(sg);
                        src_bidx = 0;
                        src_cidx = 0;
@@@ -585,7 -584,7 +584,7 @@@ err_reg1
        return ret;
  }
  
 -static int __devexit edma_remove(struct platform_device *pdev)
 +static int edma_remove(struct platform_device *pdev)
  {
        struct device *dev = &pdev->dev;
        struct edma_cc *ecc = dev_get_drvdata(dev);
@@@ -621,13 -620,11 +620,11 @@@ static struct platform_device *pdev0, *
  static const struct platform_device_info edma_dev_info0 = {
        .name = "edma-dma-engine",
        .id = 0,
-       .dma_mask = DMA_BIT_MASK(32),
  };
  
  static const struct platform_device_info edma_dev_info1 = {
        .name = "edma-dma-engine",
        .id = 1,
-       .dma_mask = DMA_BIT_MASK(32),
  };
  
  static int edma_init(void)
                        ret = PTR_ERR(pdev0);
                        goto out;
                }
+               pdev0->dev.dma_mask = &pdev0->dev.coherent_dma_mask;
+               pdev0->dev.coherent_dma_mask = DMA_BIT_MASK(32);
        }
  
        if (EDMA_CTLRS == 2) {
                        platform_device_unregister(pdev0);
                        ret = PTR_ERR(pdev1);
                }
+               pdev1->dev.dma_mask = &pdev1->dev.coherent_dma_mask;
+               pdev1->dev.coherent_dma_mask = DMA_BIT_MASK(32);
        }
  
  out:
diff --combined drivers/dma/ioat/dma.c
index 1a68a8ba87e6c74f2f5afb72afac2d0254eae5cd,464138a8a7827b7b835fe865be1c2bd062f2637a..1879a5942bfc73ffb74e498cdcb7229ee0a52aaf
@@@ -782,7 -782,7 +782,7 @@@ static void ioat1_dma_start_null_desc(s
   */
  #define IOAT_TEST_SIZE 2000
  
 -static void __devinit ioat_dma_test_callback(void *dma_async_param)
 +static void ioat_dma_test_callback(void *dma_async_param)
  {
        struct completion *cmp = dma_async_param;
  
   * ioat_dma_self_test - Perform a IOAT transaction to verify the HW works.
   * @device: device to be tested
   */
 -int __devinit ioat_dma_self_test(struct ioatdma_device *device)
 +int ioat_dma_self_test(struct ioatdma_device *device)
  {
        int i;
        u8 *src;
  
        dma_src = dma_map_single(dev, src, IOAT_TEST_SIZE, DMA_TO_DEVICE);
        dma_dest = dma_map_single(dev, dest, IOAT_TEST_SIZE, DMA_FROM_DEVICE);
-       flags = DMA_COMPL_SRC_UNMAP_SINGLE | DMA_COMPL_DEST_UNMAP_SINGLE |
+       flags = DMA_COMPL_SKIP_SRC_UNMAP | DMA_COMPL_SKIP_DEST_UNMAP |
                DMA_PREP_INTERRUPT;
        tx = device->common.device_prep_dma_memcpy(dma_chan, dma_dest, dma_src,
                                                   IOAT_TEST_SIZE, flags);
        if (!tx) {
                dev_err(dev, "Self-test prep failed, disabling\n");
                err = -ENODEV;
-               goto free_resources;
+               goto unmap_dma;
        }
  
        async_tx_ack(tx);
        if (cookie < 0) {
                dev_err(dev, "Self-test setup failed, disabling\n");
                err = -ENODEV;
-               goto free_resources;
+               goto unmap_dma;
        }
        dma->device_issue_pending(dma_chan);
  
                                        != DMA_SUCCESS) {
                dev_err(dev, "Self-test copy timed out, disabling\n");
                err = -ENODEV;
-               goto free_resources;
+               goto unmap_dma;
        }
        if (memcmp(src, dest, IOAT_TEST_SIZE)) {
                dev_err(dev, "Self-test copy failed compare, disabling\n");
                goto free_resources;
        }
  
+ unmap_dma:
+       dma_unmap_single(dev, dma_src, IOAT_TEST_SIZE, DMA_TO_DEVICE);
+       dma_unmap_single(dev, dma_dest, IOAT_TEST_SIZE, DMA_FROM_DEVICE);
  free_resources:
        dma->device_free_chan_resources(dma_chan);
  out:
@@@ -994,7 -997,7 +997,7 @@@ static void ioat_disable_interrupts(str
        writeb(0, device->reg_base + IOAT_INTRCTRL_OFFSET);
  }
  
 -int __devinit ioat_probe(struct ioatdma_device *device)
 +int ioat_probe(struct ioatdma_device *device)
  {
        int err = -ENODEV;
        struct dma_device *dma = &device->common;
@@@ -1049,7 -1052,7 +1052,7 @@@ err_dma_pool
        return err;
  }
  
 -int __devinit ioat_register(struct ioatdma_device *device)
 +int ioat_register(struct ioatdma_device *device)
  {
        int err = dma_async_device_register(&device->common);
  
@@@ -1183,7 -1186,7 +1186,7 @@@ void ioat_kobject_del(struct ioatdma_de
        }
  }
  
 -int __devinit ioat1_dma_probe(struct ioatdma_device *device, int dca)
 +int ioat1_dma_probe(struct ioatdma_device *device, int dca)
  {
        struct pci_dev *pdev = device->pdev;
        struct dma_device *dma;
        return err;
  }
  
 -void __devexit ioat_dma_remove(struct ioatdma_device *device)
 +void ioat_dma_remove(struct ioatdma_device *device)
  {
        struct dma_device *dma = &device->common;
  
diff --combined drivers/dma/ioat/dma.h
index 087935f1565f583df394476ae8bf85abfd84c6d0,1020598b80d3ed20c2686270dbc7fd6ef0be6c9b..53a4cbb78f4790f24be88100f6661805942671f5
@@@ -97,6 -97,7 +97,7 @@@ struct ioat_chan_common 
        #define IOAT_KOBJ_INIT_FAIL 3
        #define IOAT_RESHAPE_PENDING 4
        #define IOAT_RUN 5
+       #define IOAT_CHAN_ACTIVE 6
        struct timer_list timer;
        #define COMPLETION_TIMEOUT msecs_to_jiffies(100)
        #define IDLE_TIMEOUT msecs_to_jiffies(2000)
@@@ -303,12 -304,13 +304,12 @@@ static inline void ioat_unmap(struct pc
                pci_unmap_page(pdev, addr, len, direction);
  }
  
 -int __devinit ioat_probe(struct ioatdma_device *device);
 -int __devinit ioat_register(struct ioatdma_device *device);
 -int __devinit ioat1_dma_probe(struct ioatdma_device *dev, int dca);
 -int __devinit ioat_dma_self_test(struct ioatdma_device *device);
 -void __devexit ioat_dma_remove(struct ioatdma_device *device);
 -struct dca_provider * __devinit ioat_dca_init(struct pci_dev *pdev,
 -                                            void __iomem *iobase);
 +int ioat_probe(struct ioatdma_device *device);
 +int ioat_register(struct ioatdma_device *device);
 +int ioat1_dma_probe(struct ioatdma_device *dev, int dca);
 +int ioat_dma_self_test(struct ioatdma_device *device);
 +void ioat_dma_remove(struct ioatdma_device *device);
 +struct dca_provider *ioat_dca_init(struct pci_dev *pdev, void __iomem *iobase);
  dma_addr_t ioat_get_current_completion(struct ioat_chan_common *chan);
  void ioat_init_channel(struct ioatdma_device *device,
                       struct ioat_chan_common *chan, int idx);
index 82d4e306c32e8d8efb609834d859dc3723fbe30d,e2b2c70f03dbebc2240d5c58b7e1a74a47795614..b925e1b1d139bddbc6edf86f34d4b943ebfb086c
@@@ -269,61 -269,22 +269,22 @@@ static void ioat2_restart_channel(struc
        __ioat2_restart_chan(ioat);
  }
  
void ioat2_timer_event(unsigned long data)
static void check_active(struct ioat2_dma_chan *ioat)
  {
-       struct ioat2_dma_chan *ioat = to_ioat2_chan((void *) data);
        struct ioat_chan_common *chan = &ioat->base;
  
-       if (test_bit(IOAT_COMPLETION_PENDING, &chan->state)) {
-               dma_addr_t phys_complete;
-               u64 status;
-               status = ioat_chansts(chan);
-               /* when halted due to errors check for channel
-                * programming errors before advancing the completion state
-                */
-               if (is_ioat_halted(status)) {
-                       u32 chanerr;
-                       chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET);
-                       dev_err(to_dev(chan), "%s: Channel halted (%x)\n",
-                               __func__, chanerr);
-                       if (test_bit(IOAT_RUN, &chan->state))
-                               BUG_ON(is_ioat_bug(chanerr));
-                       else /* we never got off the ground */
-                               return;
-               }
-               /* if we haven't made progress and we have already
-                * acknowledged a pending completion once, then be more
-                * forceful with a restart
-                */
-               spin_lock_bh(&chan->cleanup_lock);
-               if (ioat_cleanup_preamble(chan, &phys_complete)) {
-                       __cleanup(ioat, phys_complete);
-               } else if (test_bit(IOAT_COMPLETION_ACK, &chan->state)) {
-                       spin_lock_bh(&ioat->prep_lock);
-                       ioat2_restart_channel(ioat);
-                       spin_unlock_bh(&ioat->prep_lock);
-               } else {
-                       set_bit(IOAT_COMPLETION_ACK, &chan->state);
-                       mod_timer(&chan->timer, jiffies + COMPLETION_TIMEOUT);
-               }
-               spin_unlock_bh(&chan->cleanup_lock);
-       } else {
-               u16 active;
+       if (ioat2_ring_active(ioat)) {
+               mod_timer(&chan->timer, jiffies + COMPLETION_TIMEOUT);
+               return;
+       }
  
+       if (test_and_clear_bit(IOAT_CHAN_ACTIVE, &chan->state))
+               mod_timer(&chan->timer, jiffies + IDLE_TIMEOUT);
+       else if (ioat->alloc_order > ioat_get_alloc_order()) {
                /* if the ring is idle, empty, and oversized try to step
                 * down the size
                 */
-               spin_lock_bh(&chan->cleanup_lock);
-               spin_lock_bh(&ioat->prep_lock);
-               active = ioat2_ring_active(ioat);
-               if (active == 0 && ioat->alloc_order > ioat_get_alloc_order())
-                       reshape_ring(ioat, ioat->alloc_order-1);
-               spin_unlock_bh(&ioat->prep_lock);
-               spin_unlock_bh(&chan->cleanup_lock);
+               reshape_ring(ioat, ioat->alloc_order - 1);
  
                /* keep shrinking until we get back to our minimum
                 * default size
                if (ioat->alloc_order > ioat_get_alloc_order())
                        mod_timer(&chan->timer, jiffies + IDLE_TIMEOUT);
        }
+ }
+ void ioat2_timer_event(unsigned long data)
+ {
+       struct ioat2_dma_chan *ioat = to_ioat2_chan((void *) data);
+       struct ioat_chan_common *chan = &ioat->base;
+       dma_addr_t phys_complete;
+       u64 status;
+       status = ioat_chansts(chan);
+       /* when halted due to errors check for channel
+        * programming errors before advancing the completion state
+        */
+       if (is_ioat_halted(status)) {
+               u32 chanerr;
+               chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET);
+               dev_err(to_dev(chan), "%s: Channel halted (%x)\n",
+                       __func__, chanerr);
+               if (test_bit(IOAT_RUN, &chan->state))
+                       BUG_ON(is_ioat_bug(chanerr));
+               else /* we never got off the ground */
+                       return;
+       }
+       /* if we haven't made progress and we have already
+        * acknowledged a pending completion once, then be more
+        * forceful with a restart
+        */
+       spin_lock_bh(&chan->cleanup_lock);
+       if (ioat_cleanup_preamble(chan, &phys_complete))
+               __cleanup(ioat, phys_complete);
+       else if (test_bit(IOAT_COMPLETION_ACK, &chan->state)) {
+               spin_lock_bh(&ioat->prep_lock);
+               ioat2_restart_channel(ioat);
+               spin_unlock_bh(&ioat->prep_lock);
+               spin_unlock_bh(&chan->cleanup_lock);
+               return;
+       } else {
+               set_bit(IOAT_COMPLETION_ACK, &chan->state);
+               mod_timer(&chan->timer, jiffies + COMPLETION_TIMEOUT);
+       }
+       if (ioat2_ring_active(ioat))
+               mod_timer(&chan->timer, jiffies + COMPLETION_TIMEOUT);
+       else {
+               spin_lock_bh(&ioat->prep_lock);
+               check_active(ioat);
+               spin_unlock_bh(&ioat->prep_lock);
+       }
+       spin_unlock_bh(&chan->cleanup_lock);
  }
  
  static int ioat2_reset_hw(struct ioat_chan_common *chan)
@@@ -404,7 -419,7 +419,7 @@@ static dma_cookie_t ioat2_tx_submit_unl
        cookie = dma_cookie_assign(tx);
        dev_dbg(to_dev(&ioat->base), "%s: cookie: %d\n", __func__, cookie);
  
-       if (!test_and_set_bit(IOAT_COMPLETION_PENDING, &chan->state))
+       if (!test_and_set_bit(IOAT_CHAN_ACTIVE, &chan->state))
                mod_timer(&chan->timer, jiffies + COMPLETION_TIMEOUT);
  
        /* make descriptor updates visible before advancing ioat->head,
@@@ -862,7 -877,7 +877,7 @@@ struct kobj_type ioat2_ktype = 
        .default_attrs = ioat2_attrs,
  };
  
 -int __devinit ioat2_dma_probe(struct ioatdma_device *device, int dca)
 +int ioat2_dma_probe(struct ioatdma_device *device, int dca)
  {
        struct pci_dev *pdev = device->pdev;
        struct dma_device *dma;
index 3e9d66920eb3491d85b8c6027ac786a76242e107,2acd1ad57fd6f587a3edfbc45a20bef5fbd5f0d6..e8336cce360b8f03a504890dc5ee426a2179f3ff
@@@ -342,61 -342,22 +342,22 @@@ static void ioat3_restart_channel(struc
        __ioat2_restart_chan(ioat);
  }
  
- static void ioat3_timer_event(unsigned long data)
+ static void check_active(struct ioat2_dma_chan *ioat)
  {
-       struct ioat2_dma_chan *ioat = to_ioat2_chan((void *) data);
        struct ioat_chan_common *chan = &ioat->base;
  
-       if (test_bit(IOAT_COMPLETION_PENDING, &chan->state)) {
-               dma_addr_t phys_complete;
-               u64 status;
-               status = ioat_chansts(chan);
-               /* when halted due to errors check for channel
-                * programming errors before advancing the completion state
-                */
-               if (is_ioat_halted(status)) {
-                       u32 chanerr;
-                       chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET);
-                       dev_err(to_dev(chan), "%s: Channel halted (%x)\n",
-                               __func__, chanerr);
-                       if (test_bit(IOAT_RUN, &chan->state))
-                               BUG_ON(is_ioat_bug(chanerr));
-                       else /* we never got off the ground */
-                               return;
-               }
-               /* if we haven't made progress and we have already
-                * acknowledged a pending completion once, then be more
-                * forceful with a restart
-                */
-               spin_lock_bh(&chan->cleanup_lock);
-               if (ioat_cleanup_preamble(chan, &phys_complete))
-                       __cleanup(ioat, phys_complete);
-               else if (test_bit(IOAT_COMPLETION_ACK, &chan->state)) {
-                       spin_lock_bh(&ioat->prep_lock);
-                       ioat3_restart_channel(ioat);
-                       spin_unlock_bh(&ioat->prep_lock);
-               } else {
-                       set_bit(IOAT_COMPLETION_ACK, &chan->state);
-                       mod_timer(&chan->timer, jiffies + COMPLETION_TIMEOUT);
-               }
-               spin_unlock_bh(&chan->cleanup_lock);
-       } else {
-               u16 active;
+       if (ioat2_ring_active(ioat)) {
+               mod_timer(&chan->timer, jiffies + COMPLETION_TIMEOUT);
+               return;
+       }
  
+       if (test_and_clear_bit(IOAT_CHAN_ACTIVE, &chan->state))
+               mod_timer(&chan->timer, jiffies + IDLE_TIMEOUT);
+       else if (ioat->alloc_order > ioat_get_alloc_order()) {
                /* if the ring is idle, empty, and oversized try to step
                 * down the size
                 */
-               spin_lock_bh(&chan->cleanup_lock);
-               spin_lock_bh(&ioat->prep_lock);
-               active = ioat2_ring_active(ioat);
-               if (active == 0 && ioat->alloc_order > ioat_get_alloc_order())
-                       reshape_ring(ioat, ioat->alloc_order-1);
-               spin_unlock_bh(&ioat->prep_lock);
-               spin_unlock_bh(&chan->cleanup_lock);
+               reshape_ring(ioat, ioat->alloc_order - 1);
  
                /* keep shrinking until we get back to our minimum
                 * default size
                if (ioat->alloc_order > ioat_get_alloc_order())
                        mod_timer(&chan->timer, jiffies + IDLE_TIMEOUT);
        }
+ }
+ static void ioat3_timer_event(unsigned long data)
+ {
+       struct ioat2_dma_chan *ioat = to_ioat2_chan((void *) data);
+       struct ioat_chan_common *chan = &ioat->base;
+       dma_addr_t phys_complete;
+       u64 status;
+       status = ioat_chansts(chan);
+       /* when halted due to errors check for channel
+        * programming errors before advancing the completion state
+        */
+       if (is_ioat_halted(status)) {
+               u32 chanerr;
+               chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET);
+               dev_err(to_dev(chan), "%s: Channel halted (%x)\n",
+                       __func__, chanerr);
+               if (test_bit(IOAT_RUN, &chan->state))
+                       BUG_ON(is_ioat_bug(chanerr));
+               else /* we never got off the ground */
+                       return;
+       }
+       /* if we haven't made progress and we have already
+        * acknowledged a pending completion once, then be more
+        * forceful with a restart
+        */
+       spin_lock_bh(&chan->cleanup_lock);
+       if (ioat_cleanup_preamble(chan, &phys_complete))
+               __cleanup(ioat, phys_complete);
+       else if (test_bit(IOAT_COMPLETION_ACK, &chan->state)) {
+               spin_lock_bh(&ioat->prep_lock);
+               ioat3_restart_channel(ioat);
+               spin_unlock_bh(&ioat->prep_lock);
+               spin_unlock_bh(&chan->cleanup_lock);
+               return;
+       } else {
+               set_bit(IOAT_COMPLETION_ACK, &chan->state);
+               mod_timer(&chan->timer, jiffies + COMPLETION_TIMEOUT);
+       }
+       if (ioat2_ring_active(ioat))
+               mod_timer(&chan->timer, jiffies + COMPLETION_TIMEOUT);
+       else {
+               spin_lock_bh(&ioat->prep_lock);
+               check_active(ioat);
+               spin_unlock_bh(&ioat->prep_lock);
+       }
+       spin_unlock_bh(&chan->cleanup_lock);
  }
  
  static enum dma_status
@@@ -836,7 -851,7 +851,7 @@@ ioat3_prep_interrupt_lock(struct dma_ch
        return &desc->txd;
  }
  
 -static void __devinit ioat3_dma_test_callback(void *dma_async_param)
 +static void ioat3_dma_test_callback(void *dma_async_param)
  {
        struct completion *cmp = dma_async_param;
  
  }
  
  #define IOAT_NUM_SRC_TEST 6 /* must be <= 8 */
 -static int __devinit ioat_xor_val_self_test(struct ioatdma_device *device)
 +static int ioat_xor_val_self_test(struct ioatdma_device *device)
  {
        int i, src_idx;
        struct page *dest;
        unsigned long tmo;
        struct device *dev = &device->pdev->dev;
        struct dma_device *dma = &device->common;
+       u8 op = 0;
  
        dev_dbg(dev, "%s\n", __func__);
  
        }
  
        /* test xor */
+       op = IOAT_OP_XOR;
        dest_dma = dma_map_page(dev, dest, 0, PAGE_SIZE, DMA_FROM_DEVICE);
        for (i = 0; i < IOAT_NUM_SRC_TEST; i++)
                dma_srcs[i] = dma_map_page(dev, xor_srcs[i], 0, PAGE_SIZE,
                                           DMA_TO_DEVICE);
        tx = dma->device_prep_dma_xor(dma_chan, dest_dma, dma_srcs,
                                      IOAT_NUM_SRC_TEST, PAGE_SIZE,
-                                     DMA_PREP_INTERRUPT);
+                                     DMA_PREP_INTERRUPT |
+                                     DMA_COMPL_SKIP_SRC_UNMAP |
+                                     DMA_COMPL_SKIP_DEST_UNMAP);
  
        if (!tx) {
                dev_err(dev, "Self-test xor prep failed\n");
                err = -ENODEV;
-               goto free_resources;
+               goto dma_unmap;
        }
  
        async_tx_ack(tx);
        if (cookie < 0) {
                dev_err(dev, "Self-test xor setup failed\n");
                err = -ENODEV;
-               goto free_resources;
+               goto dma_unmap;
        }
        dma->device_issue_pending(dma_chan);
  
        if (dma->device_tx_status(dma_chan, cookie, NULL) != DMA_SUCCESS) {
                dev_err(dev, "Self-test xor timed out\n");
                err = -ENODEV;
-               goto free_resources;
+               goto dma_unmap;
        }
  
+       dma_unmap_page(dev, dest_dma, PAGE_SIZE, DMA_FROM_DEVICE);
+       for (i = 0; i < IOAT_NUM_SRC_TEST; i++)
+               dma_unmap_page(dev, dma_srcs[i], PAGE_SIZE, DMA_TO_DEVICE);
        dma_sync_single_for_cpu(dev, dest_dma, PAGE_SIZE, DMA_FROM_DEVICE);
        for (i = 0; i < (PAGE_SIZE / sizeof(u32)); i++) {
                u32 *ptr = page_address(dest);
                        goto free_resources;
                }
        }
 -      dma_sync_single_for_device(dev, dest_dma, PAGE_SIZE, DMA_TO_DEVICE);
 +      dma_sync_single_for_device(dev, dest_dma, PAGE_SIZE, DMA_FROM_DEVICE);
  
        /* skip validate if the capability is not present */
        if (!dma_has_cap(DMA_XOR_VAL, dma_chan->device->cap_mask))
                goto free_resources;
  
+       op = IOAT_OP_XOR_VAL;
        /* validate the sources with the destintation page */
        for (i = 0; i < IOAT_NUM_SRC_TEST; i++)
                xor_val_srcs[i] = xor_srcs[i];
                                           DMA_TO_DEVICE);
        tx = dma->device_prep_dma_xor_val(dma_chan, dma_srcs,
                                          IOAT_NUM_SRC_TEST + 1, PAGE_SIZE,
-                                         &xor_val_result, DMA_PREP_INTERRUPT);
+                                         &xor_val_result, DMA_PREP_INTERRUPT |
+                                         DMA_COMPL_SKIP_SRC_UNMAP |
+                                         DMA_COMPL_SKIP_DEST_UNMAP);
        if (!tx) {
                dev_err(dev, "Self-test zero prep failed\n");
                err = -ENODEV;
-               goto free_resources;
+               goto dma_unmap;
        }
  
        async_tx_ack(tx);
        if (cookie < 0) {
                dev_err(dev, "Self-test zero setup failed\n");
                err = -ENODEV;
-               goto free_resources;
+               goto dma_unmap;
        }
        dma->device_issue_pending(dma_chan);
  
        if (dma->device_tx_status(dma_chan, cookie, NULL) != DMA_SUCCESS) {
                dev_err(dev, "Self-test validate timed out\n");
                err = -ENODEV;
-               goto free_resources;
+               goto dma_unmap;
        }
  
+       for (i = 0; i < IOAT_NUM_SRC_TEST + 1; i++)
+               dma_unmap_page(dev, dma_srcs[i], PAGE_SIZE, DMA_TO_DEVICE);
        if (xor_val_result != 0) {
                dev_err(dev, "Self-test validate failed compare\n");
                err = -ENODEV;
                goto free_resources;
  
        /* test memset */
+       op = IOAT_OP_FILL;
        dma_addr = dma_map_page(dev, dest, 0,
                        PAGE_SIZE, DMA_FROM_DEVICE);
        tx = dma->device_prep_dma_memset(dma_chan, dma_addr, 0, PAGE_SIZE,
-                                        DMA_PREP_INTERRUPT);
+                                        DMA_PREP_INTERRUPT |
+                                        DMA_COMPL_SKIP_SRC_UNMAP |
+                                        DMA_COMPL_SKIP_DEST_UNMAP);
        if (!tx) {
                dev_err(dev, "Self-test memset prep failed\n");
                err = -ENODEV;
-               goto free_resources;
+               goto dma_unmap;
        }
  
        async_tx_ack(tx);
        if (cookie < 0) {
                dev_err(dev, "Self-test memset setup failed\n");
                err = -ENODEV;
-               goto free_resources;
+               goto dma_unmap;
        }
        dma->device_issue_pending(dma_chan);
  
        if (dma->device_tx_status(dma_chan, cookie, NULL) != DMA_SUCCESS) {
                dev_err(dev, "Self-test memset timed out\n");
                err = -ENODEV;
-               goto free_resources;
+               goto dma_unmap;
        }
  
+       dma_unmap_page(dev, dma_addr, PAGE_SIZE, DMA_FROM_DEVICE);
        for (i = 0; i < PAGE_SIZE/sizeof(u32); i++) {
                u32 *ptr = page_address(dest);
                if (ptr[i]) {
        }
  
        /* test for non-zero parity sum */
+       op = IOAT_OP_XOR_VAL;
        xor_val_result = 0;
        for (i = 0; i < IOAT_NUM_SRC_TEST + 1; i++)
                dma_srcs[i] = dma_map_page(dev, xor_val_srcs[i], 0, PAGE_SIZE,
                                           DMA_TO_DEVICE);
        tx = dma->device_prep_dma_xor_val(dma_chan, dma_srcs,
                                          IOAT_NUM_SRC_TEST + 1, PAGE_SIZE,
-                                         &xor_val_result, DMA_PREP_INTERRUPT);
+                                         &xor_val_result, DMA_PREP_INTERRUPT |
+                                         DMA_COMPL_SKIP_SRC_UNMAP |
+                                         DMA_COMPL_SKIP_DEST_UNMAP);
        if (!tx) {
                dev_err(dev, "Self-test 2nd zero prep failed\n");
                err = -ENODEV;
-               goto free_resources;
+               goto dma_unmap;
        }
  
        async_tx_ack(tx);
        if (cookie < 0) {
                dev_err(dev, "Self-test  2nd zero setup failed\n");
                err = -ENODEV;
-               goto free_resources;
+               goto dma_unmap;
        }
        dma->device_issue_pending(dma_chan);
  
        if (dma->device_tx_status(dma_chan, cookie, NULL) != DMA_SUCCESS) {
                dev_err(dev, "Self-test 2nd validate timed out\n");
                err = -ENODEV;
-               goto free_resources;
+               goto dma_unmap;
        }
  
        if (xor_val_result != SUM_CHECK_P_RESULT) {
                dev_err(dev, "Self-test validate failed compare\n");
                err = -ENODEV;
-               goto free_resources;
+               goto dma_unmap;
        }
  
+       for (i = 0; i < IOAT_NUM_SRC_TEST + 1; i++)
+               dma_unmap_page(dev, dma_srcs[i], PAGE_SIZE, DMA_TO_DEVICE);
+       goto free_resources;
+ dma_unmap:
+       if (op == IOAT_OP_XOR) {
+               dma_unmap_page(dev, dest_dma, PAGE_SIZE, DMA_FROM_DEVICE);
+               for (i = 0; i < IOAT_NUM_SRC_TEST; i++)
+                       dma_unmap_page(dev, dma_srcs[i], PAGE_SIZE,
+                                      DMA_TO_DEVICE);
+       } else if (op == IOAT_OP_XOR_VAL) {
+               for (i = 0; i < IOAT_NUM_SRC_TEST + 1; i++)
+                       dma_unmap_page(dev, dma_srcs[i], PAGE_SIZE,
+                                      DMA_TO_DEVICE);
+       } else if (op == IOAT_OP_FILL)
+               dma_unmap_page(dev, dma_addr, PAGE_SIZE, DMA_FROM_DEVICE);
  free_resources:
        dma->device_free_chan_resources(dma_chan);
  out:
        return err;
  }
  
 -static int __devinit ioat3_dma_self_test(struct ioatdma_device *device)
 +static int ioat3_dma_self_test(struct ioatdma_device *device)
  {
        int rc = ioat_dma_self_test(device);
  
@@@ -1126,12 -1183,7 +1183,7 @@@ static int ioat3_reset_hw(struct ioat_c
        chanerr = readl(chan->reg_base + IOAT_CHANERR_OFFSET);
        writel(chanerr, chan->reg_base + IOAT_CHANERR_OFFSET);
  
-       /* -= IOAT ver.3 workarounds =- */
-       /* Write CHANERRMSK_INT with 3E07h to mask out the errors
-        * that can cause stability issues for IOAT ver.3, and clear any
-        * pending errors
-        */
-       pci_write_config_dword(pdev, IOAT_PCI_CHANERRMASK_INT_OFFSET, 0x3e07);
+       /* clear any pending errors */
        err = pci_read_config_dword(pdev, IOAT_PCI_CHANERR_INT_OFFSET, &chanerr);
        if (err) {
                dev_err(&pdev->dev, "channel error register unreachable\n");
@@@ -1187,7 -1239,27 +1239,27 @@@ static bool is_snb_ioat(struct pci_dev 
        }
  }
  
 -int __devinit ioat3_dma_probe(struct ioatdma_device *device, int dca)
+ static bool is_ivb_ioat(struct pci_dev *pdev)
+ {
+       switch (pdev->device) {
+       case PCI_DEVICE_ID_INTEL_IOAT_IVB0:
+       case PCI_DEVICE_ID_INTEL_IOAT_IVB1:
+       case PCI_DEVICE_ID_INTEL_IOAT_IVB2:
+       case PCI_DEVICE_ID_INTEL_IOAT_IVB3:
+       case PCI_DEVICE_ID_INTEL_IOAT_IVB4:
+       case PCI_DEVICE_ID_INTEL_IOAT_IVB5:
+       case PCI_DEVICE_ID_INTEL_IOAT_IVB6:
+       case PCI_DEVICE_ID_INTEL_IOAT_IVB7:
+       case PCI_DEVICE_ID_INTEL_IOAT_IVB8:
+       case PCI_DEVICE_ID_INTEL_IOAT_IVB9:
+               return true;
+       default:
+               return false;
+       }
+ }
 +int ioat3_dma_probe(struct ioatdma_device *device, int dca)
  {
        struct pci_dev *pdev = device->pdev;
        int dca_en = system_has_dca_enabled(pdev);
        dma->device_alloc_chan_resources = ioat2_alloc_chan_resources;
        dma->device_free_chan_resources = ioat2_free_chan_resources;
  
-       if (is_jf_ioat(pdev) || is_snb_ioat(pdev))
+       if (is_jf_ioat(pdev) || is_snb_ioat(pdev) || is_ivb_ioat(pdev))
                dma->copy_align = 6;
  
        dma_cap_set(DMA_INTERRUPT, dma->cap_mask);
diff --combined drivers/dma/ioat/pci.c
index 4f686c527ab606750951c98af85acdb007f303ed,f4e6163a1e73bebce1ac929c72b5e1a7a170684a..71c7ecd80fac8d3b9b33dd909ba2533da17e2e83
@@@ -40,17 -40,6 +40,6 @@@ MODULE_VERSION(IOAT_DMA_VERSION)
  MODULE_LICENSE("Dual BSD/GPL");
  MODULE_AUTHOR("Intel Corporation");
  
- #define PCI_DEVICE_ID_INTEL_IOAT_IVB0 0x0e20
- #define PCI_DEVICE_ID_INTEL_IOAT_IVB1 0x0e21
- #define PCI_DEVICE_ID_INTEL_IOAT_IVB2 0x0e22
- #define PCI_DEVICE_ID_INTEL_IOAT_IVB3 0x0e23
- #define PCI_DEVICE_ID_INTEL_IOAT_IVB4 0x0e24
- #define PCI_DEVICE_ID_INTEL_IOAT_IVB5 0x0e25
- #define PCI_DEVICE_ID_INTEL_IOAT_IVB6 0x0e26
- #define PCI_DEVICE_ID_INTEL_IOAT_IVB7 0x0e27
- #define PCI_DEVICE_ID_INTEL_IOAT_IVB8 0x0e2e
- #define PCI_DEVICE_ID_INTEL_IOAT_IVB9 0x0e2f
  static struct pci_device_id ioat_pci_tbl[] = {
        /* I/OAT v1 platforms */
        { PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_IOAT) },
  };
  MODULE_DEVICE_TABLE(pci, ioat_pci_tbl);
  
 -static int __devinit ioat_pci_probe(struct pci_dev *pdev,
 -                                  const struct pci_device_id *id);
 -static void __devexit ioat_remove(struct pci_dev *pdev);
 +static int ioat_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id);
 +static void ioat_remove(struct pci_dev *pdev);
  
  static int ioat_dca_enabled = 1;
  module_param(ioat_dca_enabled, int, 0644);
@@@ -140,7 -130,7 +129,7 @@@ alloc_ioatdma(struct pci_dev *pdev, voi
        return d;
  }
  
 -static int __devinit ioat_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
 +static int ioat_pci_probe(struct pci_dev *pdev, const struct pci_device_id *id)
  {
        void __iomem * const *iomap;
        struct device *dev = &pdev->dev;
        return 0;
  }
  
 -static void __devexit ioat_remove(struct pci_dev *pdev)
 +static void ioat_remove(struct pci_dev *pdev)
  {
        struct ioatdma_device *device = pci_get_drvdata(pdev);
  
diff --combined drivers/dma/iop-adma.c
index eacb8be99812dc85168d0d521346f5e7f4d01ea6,62a59fd657237af5280ac523ae56c85f20bc59a4..7dafb9f3785fdd22f4a942ce36a77913c84da27b
@@@ -936,7 -936,7 +936,7 @@@ static irqreturn_t iop_adma_err_handler
        struct iop_adma_chan *chan = data;
        unsigned long status = iop_chan_get_status(chan);
  
-       dev_printk(KERN_ERR, chan->device->common.dev,
+       dev_err(chan->device->common.dev,
                "error ( %s%s%s%s%s%s%s)\n",
                iop_is_err_int_parity(status, chan) ? "int_parity " : "",
                iop_is_err_mcu_abort(status, chan) ? "mcu_abort " : "",
@@@ -1017,7 -1017,7 +1017,7 @@@ static int iop_adma_memcpy_self_test(st
  
        if (iop_adma_status(dma_chan, cookie, NULL) !=
                        DMA_SUCCESS) {
-               dev_printk(KERN_ERR, dma_chan->device->dev,
+               dev_err(dma_chan->device->dev,
                        "Self-test copy timed out, disabling\n");
                err = -ENODEV;
                goto free_resources;
        dma_sync_single_for_cpu(&iop_chan->device->pdev->dev, dest_dma,
                IOP_ADMA_TEST_SIZE, DMA_FROM_DEVICE);
        if (memcmp(src, dest, IOP_ADMA_TEST_SIZE)) {
-               dev_printk(KERN_ERR, dma_chan->device->dev,
+               dev_err(dma_chan->device->dev,
                        "Self-test copy failed compare, disabling\n");
                err = -ENODEV;
                goto free_resources;
@@@ -1117,7 -1117,7 +1117,7 @@@ iop_adma_xor_val_self_test(struct iop_a
  
        if (iop_adma_status(dma_chan, cookie, NULL) !=
                DMA_SUCCESS) {
-               dev_printk(KERN_ERR, dma_chan->device->dev,
+               dev_err(dma_chan->device->dev,
                        "Self-test xor timed out, disabling\n");
                err = -ENODEV;
                goto free_resources;
        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,
+                       dev_err(dma_chan->device->dev,
                                "Self-test xor failed compare, disabling\n");
                        err = -ENODEV;
                        goto free_resources;
        msleep(8);
  
        if (iop_adma_status(dma_chan, cookie, NULL) != DMA_SUCCESS) {
-               dev_printk(KERN_ERR, dma_chan->device->dev,
+               dev_err(dma_chan->device->dev,
                        "Self-test zero sum timed out, disabling\n");
                err = -ENODEV;
                goto free_resources;
        }
  
        if (zero_sum_result != 0) {
-               dev_printk(KERN_ERR, dma_chan->device->dev,
+               dev_err(dma_chan->device->dev,
                        "Self-test zero sum failed compare, disabling\n");
                err = -ENODEV;
                goto free_resources;
        msleep(8);
  
        if (iop_adma_status(dma_chan, cookie, NULL) != DMA_SUCCESS) {
-               dev_printk(KERN_ERR, dma_chan->device->dev,
+               dev_err(dma_chan->device->dev,
                        "Self-test memset timed out, disabling\n");
                err = -ENODEV;
                goto free_resources;
        for (i = 0; i < PAGE_SIZE/sizeof(u32); i++) {
                u32 *ptr = page_address(dest);
                if (ptr[i]) {
-                       dev_printk(KERN_ERR, dma_chan->device->dev,
+                       dev_err(dma_chan->device->dev,
                                "Self-test memset failed compare, disabling\n");
                        err = -ENODEV;
                        goto free_resources;
        msleep(8);
  
        if (iop_adma_status(dma_chan, cookie, NULL) != DMA_SUCCESS) {
-               dev_printk(KERN_ERR, dma_chan->device->dev,
+               dev_err(dma_chan->device->dev,
                        "Self-test non-zero sum timed out, disabling\n");
                err = -ENODEV;
                goto free_resources;
        }
  
        if (zero_sum_result != 1) {
-               dev_printk(KERN_ERR, dma_chan->device->dev,
+               dev_err(dma_chan->device->dev,
                        "Self-test non-zero sum failed compare, disabling\n");
                err = -ENODEV;
                goto free_resources;
@@@ -1406,7 -1406,7 +1406,7 @@@ out
  }
  #endif
  
 -static int __devexit iop_adma_remove(struct platform_device *dev)
 +static int iop_adma_remove(struct platform_device *dev)
  {
        struct iop_adma_device *device = platform_get_drvdata(dev);
        struct dma_chan *chan, *_chan;
@@@ -1579,15 -1579,14 +1579,14 @@@ static int iop_adma_probe(struct platfo
                        goto err_free_iop_chan;
        }
  
-       dev_printk(KERN_INFO, &pdev->dev, "Intel(R) IOP: "
-         "( %s%s%s%s%s%s%s)\n",
-         dma_has_cap(DMA_PQ, dma_dev->cap_mask) ? "pq " : "",
-         dma_has_cap(DMA_PQ_VAL, dma_dev->cap_mask) ? "pq_val " : "",
-         dma_has_cap(DMA_XOR, dma_dev->cap_mask) ? "xor " : "",
-         dma_has_cap(DMA_XOR_VAL, dma_dev->cap_mask) ? "xor_val " : "",
-         dma_has_cap(DMA_MEMSET, dma_dev->cap_mask)  ? "fill " : "",
-         dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask) ? "cpy " : "",
-         dma_has_cap(DMA_INTERRUPT, dma_dev->cap_mask) ? "intr " : "");
+       dev_info(&pdev->dev, "Intel(R) IOP: ( %s%s%s%s%s%s%s)\n",
+                dma_has_cap(DMA_PQ, dma_dev->cap_mask) ? "pq " : "",
+                dma_has_cap(DMA_PQ_VAL, dma_dev->cap_mask) ? "pq_val " : "",
+                dma_has_cap(DMA_XOR, dma_dev->cap_mask) ? "xor " : "",
+                dma_has_cap(DMA_XOR_VAL, dma_dev->cap_mask) ? "xor_val " : "",
+                dma_has_cap(DMA_MEMSET, dma_dev->cap_mask)  ? "fill " : "",
+                dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask) ? "cpy " : "",
+                dma_has_cap(DMA_INTERRUPT, dma_dev->cap_mask) ? "intr " : "");
  
        dma_async_device_register(dma_dev);
        goto out;
@@@ -1651,8 -1650,8 +1650,8 @@@ static void iop_chan_start_null_memcpy(
                /* run the descriptor */
                iop_chan_enable(iop_chan);
        } else
-               dev_printk(KERN_ERR, iop_chan->device->common.dev,
-                        "failed to allocate null descriptor\n");
+               dev_err(iop_chan->device->common.dev,
+                       "failed to allocate null descriptor\n");
        spin_unlock_bh(&iop_chan->lock);
  }
  
@@@ -1704,7 -1703,7 +1703,7 @@@ static void iop_chan_start_null_xor(str
                /* run the descriptor */
                iop_chan_enable(iop_chan);
        } else
-               dev_printk(KERN_ERR, iop_chan->device->common.dev,
+               dev_err(iop_chan->device->common.dev,
                        "failed to allocate null descriptor\n");
        spin_unlock_bh(&iop_chan->lock);
  }
diff --combined drivers/dma/mmp_pdma.c
index dc7466563507e6cc2d164556b4e8ce3f242ac51f,41ad6a62f8383a72ca35f7a2380b7f4aca529677..c26699f9c4dfdbcec1c3f0d6ee0cf3d173227294
@@@ -5,7 -5,6 +5,7 @@@
   * it under the terms of the GNU General Public License version 2 as
   * published by the Free Software Foundation.
   */
 +#include <linux/err.h>
  #include <linux/module.h>
  #include <linux/init.h>
  #include <linux/types.h>
@@@ -618,10 -617,8 +618,8 @@@ static int mmp_pdma_control(struct dma_
                else if (maxburst == 32)
                        chan->dcmd |= DCMD_BURST32;
  
-               if (cfg) {
-                       chan->dir = cfg->direction;
-                       chan->drcmr = cfg->slave_id;
-               }
+               chan->dir = cfg->direction;
+               chan->drcmr = cfg->slave_id;
                chan->dev_addr = addr;
                break;
        default:
@@@ -713,7 -710,7 +711,7 @@@ static void dma_do_tasklet(unsigned lon
        }
  }
  
 -static int __devexit mmp_pdma_remove(struct platform_device *op)
 +static int mmp_pdma_remove(struct platform_device *op)
  {
        struct mmp_pdma_device *pdev = platform_get_drvdata(op);
  
@@@ -783,9 -780,9 +781,9 @@@ static int mmp_pdma_probe(struct platfo
        if (!iores)
                return -EINVAL;
  
 -      pdev->base = devm_request_and_ioremap(pdev->dev, iores);
 -      if (!pdev->base)
 -              return -EADDRNOTAVAIL;
 +      pdev->base = devm_ioremap_resource(pdev->dev, iores);
 +      if (IS_ERR(pdev->base))
 +              return PTR_ERR(pdev->base);
  
        of_id = of_match_device(mmp_pdma_dt_ids, pdev->dev);
        if (of_id)
diff --combined drivers/dma/mv_xor.c
index e17fad03cb804b7d538bd2928923a50928475d4f,e26de4f680e1ef0b704ba79fadfe62569bcf86af..d64ae14f2706e52c5c80144ae1ea73b0607b9aad
@@@ -210,7 -210,7 +210,7 @@@ static void mv_set_mode(struct mv_xor_c
                break;
        default:
                dev_err(mv_chan_to_devp(chan),
-                       "error: unsupported operation %d.\n",
+                       "error: unsupported operation %d\n",
                        type);
                BUG();
                return;
@@@ -828,28 -828,22 +828,22 @@@ static void mv_dump_xor_regs(struct mv_
        u32 val;
  
        val = __raw_readl(XOR_CONFIG(chan));
-       dev_err(mv_chan_to_devp(chan),
-               "config       0x%08x.\n", val);
+       dev_err(mv_chan_to_devp(chan), "config       0x%08x\n", val);
  
        val = __raw_readl(XOR_ACTIVATION(chan));
-       dev_err(mv_chan_to_devp(chan),
-               "activation   0x%08x.\n", val);
+       dev_err(mv_chan_to_devp(chan), "activation   0x%08x\n", val);
  
        val = __raw_readl(XOR_INTR_CAUSE(chan));
-       dev_err(mv_chan_to_devp(chan),
-               "intr cause   0x%08x.\n", val);
+       dev_err(mv_chan_to_devp(chan), "intr cause   0x%08x\n", val);
  
        val = __raw_readl(XOR_INTR_MASK(chan));
-       dev_err(mv_chan_to_devp(chan),
-               "intr mask    0x%08x.\n", val);
+       dev_err(mv_chan_to_devp(chan), "intr mask    0x%08x\n", val);
  
        val = __raw_readl(XOR_ERROR_CAUSE(chan));
-       dev_err(mv_chan_to_devp(chan),
-               "error cause  0x%08x.\n", val);
+       dev_err(mv_chan_to_devp(chan), "error cause  0x%08x\n", val);
  
        val = __raw_readl(XOR_ERROR_ADDR(chan));
-       dev_err(mv_chan_to_devp(chan),
-               "error addr   0x%08x.\n", val);
+       dev_err(mv_chan_to_devp(chan), "error addr   0x%08x\n", val);
  }
  
  static void mv_xor_err_interrupt_handler(struct mv_xor_chan *chan,
        }
  
        dev_err(mv_chan_to_devp(chan),
-               "error on chan %d. intr cause 0x%08x.\n",
+               "error on chan %d. intr cause 0x%08x\n",
                chan->idx, intr_cause);
  
        mv_dump_xor_regs(chan);
@@@ -1052,9 -1046,8 +1046,8 @@@ mv_xor_xor_self_test(struct mv_xor_cha
                u32 *ptr = page_address(dest);
                if (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);
+                               "Self-test xor failed compare, disabling. index %d, data %x, expected %x\n",
+                               i, ptr[i], cmp_word);
                        err = -ENODEV;
                        goto free_resources;
                }
@@@ -1194,12 -1187,11 +1187,11 @@@ mv_xor_channel_add(struct mv_xor_devic
                        goto err_free_irq;
        }
  
-       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 " : "",
-         dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask) ? "cpy " : "",
-         dma_has_cap(DMA_INTERRUPT, dma_dev->cap_mask) ? "intr " : "");
+       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 " : "",
+                dma_has_cap(DMA_MEMCPY, dma_dev->cap_mask) ? "cpy " : "",
+                dma_has_cap(DMA_INTERRUPT, dma_dev->cap_mask) ? "intr " : "");
  
        dma_async_device_register(dma_dev);
        return mv_chan;
@@@ -1253,7 -1245,7 +1245,7 @@@ static int mv_xor_probe(struct platform
        struct resource *res;
        int i, ret;
  
-       dev_notice(&pdev->dev, "Marvell XOR driver\n");
+       dev_notice(&pdev->dev, "Marvell shared XOR driver\n");
  
        xordev = devm_kzalloc(&pdev->dev, sizeof(*xordev), GFP_KERNEL);
        if (!xordev)
  err_channel_add:
        for (i = 0; i < MV_XOR_MAX_CHANNELS; i++)
                if (xordev->channels[i]) {
 +                      mv_xor_channel_remove(xordev->channels[i]);
                        if (pdev->dev.of_node)
                                irq_dispose_mapping(xordev->channels[i]->irq);
 -                      mv_xor_channel_remove(xordev->channels[i]);
                }
  
 -      clk_disable_unprepare(xordev->clk);
 -      clk_put(xordev->clk);
 +      if (!IS_ERR(xordev->clk)) {
 +              clk_disable_unprepare(xordev->clk);
 +              clk_put(xordev->clk);
 +      }
 +
        return ret;
  }
  
diff --combined drivers/dma/pch_dma.c
index 3f2617255ef21b07fde6a6d71279e1ec80ba91ce,aed6e0c117ede6c580a6a0a9bc9f7027f284bf14..d01faeb0f27c15ee9a55e78d257caf58136ff8d9
@@@ -961,7 -961,7 +961,7 @@@ err_free_mem
        return err;
  }
  
 -static void __devexit pch_dma_remove(struct pci_dev *pdev)
 +static void pch_dma_remove(struct pci_dev *pdev)
  {
        struct pch_dma *pd = pci_get_drvdata(pdev);
        struct pch_dma_chan *pd_chan;
@@@ -1029,18 -1029,7 +1029,7 @@@ static struct pci_driver pch_dma_drive
  #endif
  };
  
- static int __init pch_dma_init(void)
- {
-       return pci_register_driver(&pch_dma_driver);
- }
- static void __exit pch_dma_exit(void)
- {
-       pci_unregister_driver(&pch_dma_driver);
- }
- module_init(pch_dma_init);
- module_exit(pch_dma_exit);
+ module_pci_driver(pch_dma_driver);
  
  MODULE_DESCRIPTION("Intel EG20T PCH / LAPIS Semicon ML7213/ML7223/ML7831 IOH "
                   "DMA controller driver");
diff --combined drivers/dma/pl330.c
index 80680eee017141aa86f72388e0a98305533e7966,fc9c8001737878c15a9579db020a5609f49ef0ad..7181531227595475a907a4955b69324bb5c5e460
@@@ -25,6 -25,7 +25,7 @@@
  #include <linux/amba/pl330.h>
  #include <linux/scatterlist.h>
  #include <linux/of.h>
+ #include <linux/of_dma.h>
  
  #include "dmaengine.h"
  #define PL330_MAX_CHAN                8
@@@ -606,6 -607,11 +607,11 @@@ struct dma_pl330_desc 
        struct dma_pl330_chan *pchan;
  };
  
+ struct dma_pl330_filter_args {
+       struct dma_pl330_dmac *pdmac;
+       unsigned int chan_id;
+ };
  static inline void _callback(struct pl330_req *r, enum pl330_op_err err)
  {
        if (r && r->xfer_cb)
@@@ -2352,6 -2358,16 +2358,16 @@@ static void dma_pl330_rqcb(void *token
        tasklet_schedule(&pch->task);
  }
  
+ static bool pl330_dt_filter(struct dma_chan *chan, void *param)
+ {
+       struct dma_pl330_filter_args *fargs = param;
+       if (chan->device != &fargs->pdmac->ddma)
+               return false;
+       return (chan->chan_id == fargs->chan_id);
+ }
  bool pl330_filter(struct dma_chan *chan, void *param)
  {
        u8 *peri_id;
        if (chan->device->dev->driver != &pl330_driver.drv)
                return false;
  
- #ifdef CONFIG_OF
-       if (chan->device->dev->of_node) {
-               const __be32 *prop_value;
-               phandle phandle;
-               struct device_node *node;
-               prop_value = ((struct property *)param)->value;
-               phandle = be32_to_cpup(prop_value++);
-               node = of_find_node_by_phandle(phandle);
-               return ((chan->private == node) &&
-                               (chan->chan_id == be32_to_cpup(prop_value)));
-       }
- #endif
        peri_id = chan->private;
        return *peri_id == (unsigned)param;
  }
  EXPORT_SYMBOL(pl330_filter);
  
+ static struct dma_chan *of_dma_pl330_xlate(struct of_phandle_args *dma_spec,
+                                               struct of_dma *ofdma)
+ {
+       int count = dma_spec->args_count;
+       struct dma_pl330_dmac *pdmac = ofdma->of_dma_data;
+       struct dma_pl330_filter_args fargs;
+       dma_cap_mask_t cap;
+       if (!pdmac)
+               return NULL;
+       if (count != 1)
+               return NULL;
+       fargs.pdmac = pdmac;
+       fargs.chan_id = dma_spec->args[0];
+       dma_cap_zero(cap);
+       dma_cap_set(DMA_SLAVE, cap);
+       dma_cap_set(DMA_CYCLIC, cap);
+       return dma_request_channel(cap, pl330_dt_filter, &fargs);
+ }
  static int pl330_alloc_chan_resources(struct dma_chan *chan)
  {
        struct dma_pl330_chan *pch = to_pchan(chan);
@@@ -2866,7 -2892,7 +2892,7 @@@ pl330_probe(struct amba_device *adev, c
        pdat = adev->dev.platform_data;
  
        /* Allocate a new DMAC and its Channels */
-       pdmac = kzalloc(sizeof(*pdmac), GFP_KERNEL);
+       pdmac = devm_kzalloc(&adev->dev, sizeof(*pdmac), GFP_KERNEL);
        if (!pdmac) {
                dev_err(&adev->dev, "unable to allocate mem\n");
                return -ENOMEM;
        pi->mcbufsz = pdat ? pdat->mcbuf_sz : 0;
  
        res = &adev->res;
-       request_mem_region(res->start, resource_size(res), "dma-pl330");
-       pi->base = ioremap(res->start, resource_size(res));
-       if (!pi->base) {
-               ret = -ENXIO;
-               goto probe_err1;
-       }
+       pi->base = devm_request_and_ioremap(&adev->dev, res);
+       if (!pi->base)
+               return -ENXIO;
  
        amba_set_drvdata(adev, pdmac);
  
        ret = request_irq(irq, pl330_irq_handler, 0,
                        dev_name(&adev->dev), pi);
        if (ret)
-               goto probe_err2;
+               return ret;
  
        ret = pl330_add(pi);
        if (ret)
-               goto probe_err3;
+               goto probe_err1;
  
        INIT_LIST_HEAD(&pdmac->desc_pool);
        spin_lock_init(&pdmac->pool_lock);
        if (!pdmac->peripherals) {
                ret = -ENOMEM;
                dev_err(&adev->dev, "unable to allocate pdmac->peripherals\n");
-               goto probe_err4;
+               goto probe_err2;
        }
  
        for (i = 0; i < num_chan; i++) {
        ret = dma_async_device_register(pd);
        if (ret) {
                dev_err(&adev->dev, "unable to register DMAC\n");
-               goto probe_err4;
+               goto probe_err2;
        }
  
        dev_info(&adev->dev,
                pi->pcfg.data_bus_width / 8, pi->pcfg.num_chan,
                pi->pcfg.num_peri, pi->pcfg.num_events);
  
+       ret = of_dma_controller_register(adev->dev.of_node,
+                                        of_dma_pl330_xlate, pdmac);
+       if (ret) {
+               dev_err(&adev->dev,
+               "unable to register DMA to the generic DT DMA helpers\n");
+               goto probe_err2;
+       }
        return 0;
  
- probe_err4:
-       pl330_del(pi);
- probe_err3:
-       free_irq(irq, pi);
  probe_err2:
-       iounmap(pi->base);
+       pl330_del(pi);
  probe_err1:
-       release_mem_region(res->start, resource_size(res));
-       kfree(pdmac);
+       free_irq(irq, pi);
  
        return ret;
  }
  
 -static int __devexit pl330_remove(struct amba_device *adev)
 +static int pl330_remove(struct amba_device *adev)
  {
        struct dma_pl330_dmac *pdmac = amba_get_drvdata(adev);
        struct dma_pl330_chan *pch, *_p;
        struct pl330_info *pi;
-       struct resource *res;
        int irq;
  
        if (!pdmac)
                return 0;
  
+       of_dma_controller_free(adev->dev.of_node);
        amba_set_drvdata(adev, NULL);
  
        /* Idle the DMAC */
        irq = adev->irq[0];
        free_irq(irq, pi);
  
-       iounmap(pi->base);
-       res = &adev->res;
-       release_mem_region(res->start, resource_size(res));
-       kfree(pdmac);
        return 0;
  }
  
diff --combined drivers/dma/sh/shdma.c
index 3315e4be9b854e6b100fcfe002b3d616190fbe25,62eff48005210be4e93c1df0ff3301bde43676ec..b70709b030d804e7e2d465fb98754bbb582f9199
@@@ -326,7 -326,7 +326,7 @@@ static int sh_dmae_set_slave(struct shd
                                                    shdma_chan);
        const struct sh_dmae_slave_config *cfg = dmae_find_slave(sh_chan, slave_id);
        if (!cfg)
-               return -ENODEV;
+               return -ENXIO;
  
        if (!try)
                sh_chan->config = cfg;
@@@ -880,7 -880,7 +880,7 @@@ ermrdmars
        return err;
  }
  
 -static int __devexit sh_dmae_remove(struct platform_device *pdev)
 +static int sh_dmae_remove(struct platform_device *pdev)
  {
        struct sh_dmae_device *shdev = platform_get_drvdata(pdev);
        struct dma_device *dma_dev = &shdev->shdma_dev.dma_dev;
diff --combined drivers/dma/sirf-dma.c
index 94674a96c64613a0b2e79b04a62d4c1f4007c0d0,fb5790d8a0b0e2bf55f88dd350fe999a68144839..1d627e2391f495ef2b8b9fd2e6b5359da940df2d
@@@ -32,7 -32,9 +32,9 @@@
  #define SIRFSOC_DMA_CH_VALID                    0x140
  #define SIRFSOC_DMA_CH_INT                      0x144
  #define SIRFSOC_DMA_INT_EN                      0x148
+ #define SIRFSOC_DMA_INT_EN_CLR                        0x14C
  #define SIRFSOC_DMA_CH_LOOP_CTRL                0x150
+ #define SIRFSOC_DMA_CH_LOOP_CTRL_CLR            0x15C
  
  #define SIRFSOC_DMA_MODE_CTRL_BIT               4
  #define SIRFSOC_DMA_DIR_CTRL_BIT                5
@@@ -76,6 -78,7 +78,7 @@@ struct sirfsoc_dma 
        struct sirfsoc_dma_chan         channels[SIRFSOC_DMA_CHANNELS];
        void __iomem                    *base;
        int                             irq;
+       bool                            is_marco;
  };
  
  #define DRV_NAME      "sirfsoc_dma"
@@@ -288,17 -291,67 +291,67 @@@ static int sirfsoc_dma_terminate_all(st
        int cid = schan->chan.chan_id;
        unsigned long flags;
  
-       writel_relaxed(readl_relaxed(sdma->base + SIRFSOC_DMA_INT_EN) &
-               ~(1 << cid), sdma->base + SIRFSOC_DMA_INT_EN);
-       writel_relaxed(1 << cid, sdma->base + SIRFSOC_DMA_CH_VALID);
+       spin_lock_irqsave(&schan->lock, flags);
  
-       writel_relaxed(readl_relaxed(sdma->base + SIRFSOC_DMA_CH_LOOP_CTRL)
-               & ~((1 << cid) | 1 << (cid + 16)),
+       if (!sdma->is_marco) {
+               writel_relaxed(readl_relaxed(sdma->base + SIRFSOC_DMA_INT_EN) &
+                       ~(1 << cid), sdma->base + SIRFSOC_DMA_INT_EN);
+               writel_relaxed(readl_relaxed(sdma->base + SIRFSOC_DMA_CH_LOOP_CTRL)
+                       & ~((1 << cid) | 1 << (cid + 16)),
                        sdma->base + SIRFSOC_DMA_CH_LOOP_CTRL);
+       } else {
+               writel_relaxed(1 << cid, sdma->base + SIRFSOC_DMA_INT_EN_CLR);
+               writel_relaxed((1 << cid) | 1 << (cid + 16),
+                       sdma->base + SIRFSOC_DMA_CH_LOOP_CTRL_CLR);
+       }
+       writel_relaxed(1 << cid, sdma->base + SIRFSOC_DMA_CH_VALID);
  
-       spin_lock_irqsave(&schan->lock, flags);
        list_splice_tail_init(&schan->active, &schan->free);
        list_splice_tail_init(&schan->queued, &schan->free);
+       spin_unlock_irqrestore(&schan->lock, flags);
+       return 0;
+ }
+ static int sirfsoc_dma_pause_chan(struct sirfsoc_dma_chan *schan)
+ {
+       struct sirfsoc_dma *sdma = dma_chan_to_sirfsoc_dma(&schan->chan);
+       int cid = schan->chan.chan_id;
+       unsigned long flags;
+       spin_lock_irqsave(&schan->lock, flags);
+       if (!sdma->is_marco)
+               writel_relaxed(readl_relaxed(sdma->base + SIRFSOC_DMA_CH_LOOP_CTRL)
+                       & ~((1 << cid) | 1 << (cid + 16)),
+                       sdma->base + SIRFSOC_DMA_CH_LOOP_CTRL);
+       else
+               writel_relaxed((1 << cid) | 1 << (cid + 16),
+                       sdma->base + SIRFSOC_DMA_CH_LOOP_CTRL_CLR);
+       spin_unlock_irqrestore(&schan->lock, flags);
+       return 0;
+ }
+ static int sirfsoc_dma_resume_chan(struct sirfsoc_dma_chan *schan)
+ {
+       struct sirfsoc_dma *sdma = dma_chan_to_sirfsoc_dma(&schan->chan);
+       int cid = schan->chan.chan_id;
+       unsigned long flags;
+       spin_lock_irqsave(&schan->lock, flags);
+       if (!sdma->is_marco)
+               writel_relaxed(readl_relaxed(sdma->base + SIRFSOC_DMA_CH_LOOP_CTRL)
+                       | ((1 << cid) | 1 << (cid + 16)),
+                       sdma->base + SIRFSOC_DMA_CH_LOOP_CTRL);
+       else
+               writel_relaxed((1 << cid) | 1 << (cid + 16),
+                       sdma->base + SIRFSOC_DMA_CH_LOOP_CTRL);
        spin_unlock_irqrestore(&schan->lock, flags);
  
        return 0;
@@@ -311,6 -364,10 +364,10 @@@ static int sirfsoc_dma_control(struct d
        struct sirfsoc_dma_chan *schan = dma_chan_to_sirfsoc_dma_chan(chan);
  
        switch (cmd) {
+       case DMA_PAUSE:
+               return sirfsoc_dma_pause_chan(schan);
+       case DMA_RESUME:
+               return sirfsoc_dma_resume_chan(schan);
        case DMA_TERMINATE_ALL:
                return sirfsoc_dma_terminate_all(schan);
        case DMA_SLAVE_CONFIG:
@@@ -568,6 -625,9 +625,9 @@@ static int sirfsoc_dma_probe(struct pla
                return -ENOMEM;
        }
  
+       if (of_device_is_compatible(dn, "sirf,marco-dmac"))
+               sdma->is_marco = true;
        if (of_property_read_u32(dn, "cell-index", &id)) {
                dev_err(dev, "Fail to get DMAC index\n");
                return -ENODEV;
@@@ -655,7 -715,7 +715,7 @@@ irq_dispose
        return ret;
  }
  
 -static int __devexit sirfsoc_dma_remove(struct platform_device *op)
 +static int sirfsoc_dma_remove(struct platform_device *op)
  {
        struct device *dev = &op->dev;
        struct sirfsoc_dma *sdma = dev_get_drvdata(dev);
  
  static struct of_device_id sirfsoc_dma_match[] = {
        { .compatible = "sirf,prima2-dmac", },
+       { .compatible = "sirf,marco-dmac", },
        {},
  };
  
index f6c018f1b4532e1cd4a6405babe1c2b08d27ed84,c71812f8d9c17d42c140b456c723ea687a032c4a..fcee27eae1f6d35d9635a009e3fe991fc87a0eeb
@@@ -21,7 -21,6 +21,7 @@@
  #include <linux/delay.h>
  #include <linux/dmaengine.h>
  #include <linux/dma-mapping.h>
 +#include <linux/err.h>
  #include <linux/init.h>
  #include <linux/interrupt.h>
  #include <linux/io.h>
@@@ -32,8 -31,8 +32,8 @@@
  #include <linux/platform_device.h>
  #include <linux/pm_runtime.h>
  #include <linux/slab.h>
 +#include <linux/clk/tegra.h>
  
 -#include <mach/clk.h>
  #include "dmaengine.h"
  
  #define TEGRA_APBDMA_GENERAL                  0x0
@@@ -63,6 -62,9 +63,9 @@@
  #define TEGRA_APBDMA_STATUS_COUNT_SHIFT               2
  #define TEGRA_APBDMA_STATUS_COUNT_MASK                0xFFFC
  
+ #define TEGRA_APBDMA_CHAN_CSRE                        0x00C
+ #define TEGRA_APBDMA_CHAN_CSRE_PAUSE          (1 << 31)
  /* AHB memory address */
  #define TEGRA_APBDMA_CHAN_AHBPTR              0x010
  
@@@ -113,10 -115,12 +116,12 @@@ struct tegra_dma
   * tegra_dma_chip_data Tegra chip specific DMA data
   * @nr_channels: Number of channels available in the controller.
   * @max_dma_count: Maximum DMA transfer count supported by DMA controller.
+  * @support_channel_pause: Support channel wise pause of dma.
   */
  struct tegra_dma_chip_data {
        int nr_channels;
        int max_dma_count;
+       bool support_channel_pause;
  };
  
  /* DMA channel registers */
@@@ -267,7 -271,6 +272,7 @@@ static struct tegra_dma_desc *tegra_dma
                if (async_tx_test_ack(&dma_desc->txd)) {
                        list_del(&dma_desc->node);
                        spin_unlock_irqrestore(&tdc->lock, flags);
 +                      dma_desc->txd.flags = 0;
                        return dma_desc;
                }
        }
@@@ -355,6 -358,32 +360,32 @@@ static void tegra_dma_global_resume(str
        spin_unlock(&tdma->global_lock);
  }
  
+ static void tegra_dma_pause(struct tegra_dma_channel *tdc,
+       bool wait_for_burst_complete)
+ {
+       struct tegra_dma *tdma = tdc->tdma;
+       if (tdma->chip_data->support_channel_pause) {
+               tdc_write(tdc, TEGRA_APBDMA_CHAN_CSRE,
+                               TEGRA_APBDMA_CHAN_CSRE_PAUSE);
+               if (wait_for_burst_complete)
+                       udelay(TEGRA_APBDMA_BURST_COMPLETE_TIME);
+       } else {
+               tegra_dma_global_pause(tdc, wait_for_burst_complete);
+       }
+ }
+ static void tegra_dma_resume(struct tegra_dma_channel *tdc)
+ {
+       struct tegra_dma *tdma = tdc->tdma;
+       if (tdma->chip_data->support_channel_pause) {
+               tdc_write(tdc, TEGRA_APBDMA_CHAN_CSRE, 0);
+       } else {
+               tegra_dma_global_resume(tdc);
+       }
+ }
  static void tegra_dma_stop(struct tegra_dma_channel *tdc)
  {
        u32 csr;
@@@ -410,7 -439,7 +441,7 @@@ static void tegra_dma_configure_for_nex
         * If there is already IEC status then interrupt handler need to
         * load new configuration.
         */
-       tegra_dma_global_pause(tdc, false);
+       tegra_dma_pause(tdc, false);
        status  = tdc_read(tdc, TEGRA_APBDMA_CHAN_STATUS);
  
        /*
        if (status & TEGRA_APBDMA_STATUS_ISE_EOC) {
                dev_err(tdc2dev(tdc),
                        "Skipping new configuration as interrupt is pending\n");
-               tegra_dma_global_resume(tdc);
+               tegra_dma_resume(tdc);
                return;
        }
  
                                nsg_req->ch_regs.csr | TEGRA_APBDMA_CSR_ENB);
        nsg_req->configured = true;
  
-       tegra_dma_global_resume(tdc);
+       tegra_dma_resume(tdc);
  }
  
  static void tdc_start_head_req(struct tegra_dma_channel *tdc)
@@@ -692,7 -721,7 +723,7 @@@ static void tegra_dma_terminate_all(str
                goto skip_dma_stop;
  
        /* Pause DMA before checking the queue status */
-       tegra_dma_global_pause(tdc, true);
+       tegra_dma_pause(tdc, true);
  
        status = tdc_read(tdc, TEGRA_APBDMA_CHAN_STATUS);
        if (status & TEGRA_APBDMA_STATUS_ISE_EOC) {
                sgreq->dma_desc->bytes_transferred +=
                                get_current_xferred_count(tdc, sgreq, status);
        }
-       tegra_dma_global_resume(tdc);
+       tegra_dma_resume(tdc);
  
  skip_dma_stop:
        tegra_dma_abort_all(tdc);
@@@ -738,7 -767,6 +769,6 @@@ static enum dma_status tegra_dma_tx_sta
  
        ret = dma_cookie_status(dc, cookie, txstate);
        if (ret == DMA_SUCCESS) {
-               dma_set_residue(txstate, 0);
                spin_unlock_irqrestore(&tdc->lock, flags);
                return ret;
        }
@@@ -1052,9 -1080,7 +1082,9 @@@ struct dma_async_tx_descriptor *tegra_d
                                        TEGRA_APBDMA_AHBSEQ_WRAP_SHIFT;
        ahb_seq |= TEGRA_APBDMA_AHBSEQ_BUS_WIDTH_32;
  
 -      csr |= TEGRA_APBDMA_CSR_FLOW | TEGRA_APBDMA_CSR_IE_EOC;
 +      csr |= TEGRA_APBDMA_CSR_FLOW;
 +      if (flags & DMA_PREP_INTERRUPT)
 +              csr |= TEGRA_APBDMA_CSR_IE_EOC;
        csr |= tdc->dma_sconfig.slave_id << TEGRA_APBDMA_CSR_REQ_SEL_SHIFT;
  
        apb_seq |= TEGRA_APBDMA_APBSEQ_WRAP_WORD_1;
                mem += len;
        }
        sg_req->last_sg = true;
 -      dma_desc->txd.flags = 0;
 +      if (flags & DMA_CTRL_ACK)
 +              dma_desc->txd.flags = DMA_CTRL_ACK;
  
        /*
         * Make sure that mode should not be conflicting with currently
@@@ -1180,6 -1205,7 +1210,7 @@@ static void tegra_dma_free_chan_resourc
  static const struct tegra_dma_chip_data tegra20_dma_chip_data = {
        .nr_channels            = 16,
        .max_dma_count          = 1024UL * 64,
+       .support_channel_pause  = false,
  };
  
  #if defined(CONFIG_OF)
  static const struct tegra_dma_chip_data tegra30_dma_chip_data = {
        .nr_channels            = 32,
        .max_dma_count          = 1024UL * 64,
+       .support_channel_pause  = false,
  };
  
+ /* Tegra114 specific DMA controller information */
+ static const struct tegra_dma_chip_data tegra114_dma_chip_data = {
+       .nr_channels            = 32,
+       .max_dma_count          = 1024UL * 64,
+       .support_channel_pause  = true,
+ };
  static const struct of_device_id tegra_dma_of_match[] = {
        {
+               .compatible = "nvidia,tegra114-apbdma",
+               .data = &tegra114_dma_chip_data,
+       }, {
                .compatible = "nvidia,tegra30-apbdma",
                .data = &tegra30_dma_chip_data,
        }, {
@@@ -1241,9 -1279,12 +1284,9 @@@ static int tegra_dma_probe(struct platf
                return -EINVAL;
        }
  
 -      tdma->base_addr = devm_request_and_ioremap(&pdev->dev, res);
 -      if (!tdma->base_addr) {
 -              dev_err(&pdev->dev,
 -                      "Cannot request memregion/iomap dma address\n");
 -              return -EADDRNOTAVAIL;
 -      }
 +      tdma->base_addr = devm_ioremap_resource(&pdev->dev, res);
 +      if (IS_ERR(tdma->base_addr))
 +              return PTR_ERR(tdma->base_addr);
  
        tdma->dma_clk = devm_clk_get(&pdev->dev, NULL);
        if (IS_ERR(tdma->dma_clk)) {
@@@ -1362,7 -1403,7 +1405,7 @@@ err_pm_disable
        return ret;
  }
  
 -static int __devexit tegra_dma_remove(struct platform_device *pdev)
 +static int tegra_dma_remove(struct platform_device *pdev)
  {
        struct tegra_dma *tdma = platform_get_drvdata(pdev);
        int i;
@@@ -1405,7 -1446,7 +1448,7 @@@ static int tegra_dma_runtime_resume(str
        return 0;
  }
  
 -static const struct dev_pm_ops tegra_dma_dev_pm_ops __devinitconst = {
 +static const struct dev_pm_ops tegra_dma_dev_pm_ops = {
  #ifdef CONFIG_PM_RUNTIME
        .runtime_suspend = tegra_dma_runtime_suspend,
        .runtime_resume = tegra_dma_runtime_resume,
index 09af555408b773a52c5b806436af5274d395d643,a66576863e539011ee024e62c6f0b61c699cb93d..05ba3f0c2d194ee5c6a0d745f0a78b6744f23486
@@@ -573,23 -573,22 +573,22 @@@ static int dma_xfer(struct fsmc_nand_da
        dma_dev = chan->device;
        dma_addr = dma_map_single(dma_dev->dev, buffer, len, direction);
  
+       flags |= DMA_COMPL_SKIP_SRC_UNMAP | DMA_COMPL_SKIP_DEST_UNMAP;
        if (direction == DMA_TO_DEVICE) {
                dma_src = dma_addr;
                dma_dst = host->data_pa;
-               flags |= DMA_COMPL_SRC_UNMAP_SINGLE | DMA_COMPL_SKIP_DEST_UNMAP;
        } else {
                dma_src = host->data_pa;
                dma_dst = dma_addr;
-               flags |= DMA_COMPL_DEST_UNMAP_SINGLE | DMA_COMPL_SKIP_SRC_UNMAP;
        }
  
        tx = dma_dev->device_prep_dma_memcpy(chan, dma_dst, dma_src,
                        len, flags);
        if (!tx) {
                dev_err(host->dev, "device_prep_dma_memcpy error\n");
-               dma_unmap_single(dma_dev->dev, dma_addr, len, direction);
-               return -EIO;
+               ret = -EIO;
+               goto unmap_dma;
        }
  
        tx->callback = dma_complete;
        ret = dma_submit_error(cookie);
        if (ret) {
                dev_err(host->dev, "dma_submit_error %d\n", cookie);
-               return ret;
+               goto unmap_dma;
        }
  
        dma_async_issue_pending(chan);
        if (ret <= 0) {
                chan->device->device_control(chan, DMA_TERMINATE_ALL, 0);
                dev_err(host->dev, "wait_for_completion_timeout\n");
-               return ret ? ret : -ETIMEDOUT;
+               if (!ret)
+                       ret = -ETIMEDOUT;
+               goto unmap_dma;
        }
  
-       return 0;
+       ret = 0;
+ unmap_dma:
+       dma_unmap_single(dma_dev->dev, dma_addr, len, direction);
+       return ret;
  }
  
  /*
@@@ -865,7 -871,7 +871,7 @@@ static bool filter(struct dma_chan *cha
  
  #ifdef CONFIG_OF
  static int fsmc_nand_probe_config_dt(struct platform_device *pdev,
 -                                             struct device_node *np)
 +                                   struct device_node *np)
  {
        struct fsmc_nand_platform_data *pdata = dev_get_platdata(&pdev->dev);
        u32 val;
  }
  #else
  static int fsmc_nand_probe_config_dt(struct platform_device *pdev,
 -                                             struct device_node *np)
 +                                   struct device_node *np)
  {
        return -ENOSYS;
  }
@@@ -937,35 -943,42 +943,35 @@@ static int __init fsmc_nand_probe(struc
        if (!res)
                return -EINVAL;
  
 -      host->data_va = devm_request_and_ioremap(&pdev->dev, res);
 -      if (!host->data_va) {
 -              dev_err(&pdev->dev, "data ioremap failed\n");
 -              return -ENOMEM;
 -      }
 +      host->data_va = devm_ioremap_resource(&pdev->dev, res);
 +      if (IS_ERR(host->data_va))
 +              return PTR_ERR(host->data_va);
 +      
        host->data_pa = (dma_addr_t)res->start;
  
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_addr");
        if (!res)
                return -EINVAL;
  
 -      host->addr_va = devm_request_and_ioremap(&pdev->dev, res);
 -      if (!host->addr_va) {
 -              dev_err(&pdev->dev, "ale ioremap failed\n");
 -              return -ENOMEM;
 -      }
 +      host->addr_va = devm_ioremap_resource(&pdev->dev, res);
 +      if (IS_ERR(host->addr_va))
 +              return PTR_ERR(host->addr_va);
  
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "nand_cmd");
        if (!res)
                return -EINVAL;
  
 -      host->cmd_va = devm_request_and_ioremap(&pdev->dev, res);
 -      if (!host->cmd_va) {
 -              dev_err(&pdev->dev, "ale ioremap failed\n");
 -              return -ENOMEM;
 -      }
 +      host->cmd_va = devm_ioremap_resource(&pdev->dev, res);
 +      if (IS_ERR(host->cmd_va))
 +              return PTR_ERR(host->cmd_va);
  
        res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "fsmc_regs");
        if (!res)
                return -EINVAL;
  
 -      host->regs_va = devm_request_and_ioremap(&pdev->dev, res);
 -      if (!host->regs_va) {
 -              dev_err(&pdev->dev, "regs ioremap failed\n");
 -              return -ENOMEM;
 -      }
 +      host->regs_va = devm_ioremap_resource(&pdev->dev, res);
 +      if (IS_ERR(host->regs_va))
 +              return PTR_ERR(host->regs_va);
  
        host->clk = clk_get(&pdev->dev, NULL);
        if (IS_ERR(host->clk)) {
@@@ -1211,7 -1224,6 +1217,7 @@@ static SIMPLE_DEV_PM_OPS(fsmc_nand_pm_o
  #ifdef CONFIG_OF
  static const struct of_device_id fsmc_nand_id_table[] = {
        { .compatible = "st,spear600-fsmc-nand" },
 +      { .compatible = "stericsson,fsmc-nand" },
        {}
  };
  MODULE_DEVICE_TABLE(of, fsmc_nand_id_table);
diff --combined net/ipv4/tcp.c
index 7a5ba48c2cc985616aff8d2ca524c5cd4cc39e8d,db0856ad70cb86c431d02768d799f6f7f94109c1..47e854fcae24dd8c108e93a2b5a22801a68d7232
@@@ -400,8 -400,6 +400,8 @@@ void tcp_init_sock(struct sock *sk
        tcp_enable_early_retrans(tp);
        icsk->icsk_ca_ops = &tcp_init_congestion_ops;
  
 +      tp->tsoffset = 0;
 +
        sk->sk_state = TCP_CLOSE;
  
        sk->sk_write_space = sk_stream_write_space;
@@@ -897,7 -895,6 +897,7 @@@ new_segment
                        get_page(page);
                        skb_fill_page_desc(skb, i, page, offset, copy);
                }
 +              skb_shinfo(skb)->tx_flags |= SKBTX_SHARED_FRAG;
  
                skb->len += copy;
                skb->data_len += copy;
@@@ -1409,10 -1406,10 +1409,10 @@@ static void tcp_service_net_dma(struct 
                return;
  
        last_issued = tp->ucopy.dma_cookie;
-       dma_async_memcpy_issue_pending(tp->ucopy.dma_chan);
+       dma_async_issue_pending(tp->ucopy.dma_chan);
  
        do {
-               if (dma_async_memcpy_complete(tp->ucopy.dma_chan,
+               if (dma_async_is_tx_complete(tp->ucopy.dma_chan,
                                              last_issued, &done,
                                              &used) == DMA_SUCCESS) {
                        /* Safe to free early-copied skbs now */
  }
  #endif
  
 -static inline struct sk_buff *tcp_recv_skb(struct sock *sk, u32 seq, u32 *off)
 +static struct sk_buff *tcp_recv_skb(struct sock *sk, u32 seq, u32 *off)
  {
        struct sk_buff *skb;
        u32 offset;
  
 -      skb_queue_walk(&sk->sk_receive_queue, skb) {
 +      while ((skb = skb_peek(&sk->sk_receive_queue)) != NULL) {
                offset = seq - TCP_SKB_CB(skb)->seq;
                if (tcp_hdr(skb)->syn)
                        offset--;
                        *off = offset;
                        return skb;
                }
 +              /* This looks weird, but this can happen if TCP collapsing
 +               * splitted a fat GRO packet, while we released socket lock
 +               * in skb_splice_bits()
 +               */
 +              sk_eat_skb(sk, skb, false);
        }
        return NULL;
  }
@@@ -1490,7 -1482,7 +1490,7 @@@ int tcp_read_sock(struct sock *sk, read
                                        break;
                        }
                        used = recv_actor(desc, skb, offset, len);
 -                      if (used < 0) {
 +                      if (used <= 0) {
                                if (!copied)
                                        copied = used;
                                break;
        tcp_rcv_space_adjust(sk);
  
        /* Clean up data we have read: This will do ACK frames. */
 -      if (copied > 0)
 +      if (copied > 0) {
 +              tcp_recv_skb(sk, seq, &offset);
                tcp_cleanup_rbuf(sk, copied);
 +      }
        return copied;
  }
  EXPORT_SYMBOL(tcp_read_sock);
@@@ -1754,7 -1744,7 +1754,7 @@@ int tcp_recvmsg(struct kiocb *iocb, str
                                tcp_service_net_dma(sk, true);
                                tcp_cleanup_rbuf(sk, copied);
                        } else
-                               dma_async_memcpy_issue_pending(tp->ucopy.dma_chan);
+                               dma_async_issue_pending(tp->ucopy.dma_chan);
                }
  #endif
                if (copied >= target) {
@@@ -1847,7 -1837,7 +1847,7 @@@ do_prequeue
                                        break;
                                }
  
-                               dma_async_memcpy_issue_pending(tp->ucopy.dma_chan);
+                               dma_async_issue_pending(tp->ucopy.dma_chan);
  
                                if ((offset + used) == skb->len)
                                        copied_early = true;
@@@ -2290,6 -2280,7 +2290,6 @@@ int tcp_disconnect(struct sock *sk, in
        tp->packets_out = 0;
        tp->snd_ssthresh = TCP_INFINITE_SSTHRESH;
        tp->snd_cwnd_cnt = 0;
 -      tp->bytes_acked = 0;
        tp->window_clamp = 0;
        tcp_set_ca_state(sk, TCP_CA_Open);
        tcp_clear_retrans(tp);
@@@ -2713,12 -2704,6 +2713,12 @@@ static int do_tcp_setsockopt(struct soc
                else
                        err = -EINVAL;
                break;
 +      case TCP_TIMESTAMP:
 +              if (!tp->repair)
 +                      err = -EPERM;
 +              else
 +                      tp->tsoffset = val - tcp_time_stamp;
 +              break;
        default:
                err = -ENOPROTOOPT;
                break;
@@@ -2967,9 -2952,6 +2967,9 @@@ static int do_tcp_getsockopt(struct soc
        case TCP_USER_TIMEOUT:
                val = jiffies_to_msecs(icsk->icsk_user_timeout);
                break;
 +      case TCP_TIMESTAMP:
 +              val = tcp_time_stamp + tp->tsoffset;
 +              break;
        default:
                return -ENOPROTOOPT;
        }
@@@ -3043,7 -3025,6 +3043,7 @@@ struct sk_buff *tcp_tso_segment(struct 
                               SKB_GSO_DODGY |
                               SKB_GSO_TCP_ECN |
                               SKB_GSO_TCPV6 |
 +                             SKB_GSO_GRE |
                               0) ||
                             !(type & (SKB_GSO_TCPV4 | SKB_GSO_TCPV6))))
                        goto out;
@@@ -3255,7 -3236,7 +3255,7 @@@ __tcp_alloc_md5sig_pool(struct sock *sk
                struct crypto_hash *hash;
  
                hash = crypto_alloc_hash("md5", 0, CRYPTO_ALG_ASYNC);
 -              if (!hash || IS_ERR(hash))
 +              if (IS_ERR_OR_NULL(hash))
                        goto out_free;
  
                per_cpu_ptr(pool, cpu)->md5_desc.tfm = hash;