Merge branch 'dmaengine' of git://git.linaro.org/people/rmk/linux-arm
authorLinus Torvalds <torvalds@linux-foundation.org>
Wed, 1 Aug 2012 23:41:07 +0000 (16:41 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Wed, 1 Aug 2012 23:41:07 +0000 (16:41 -0700)
Pull ARM DMA engine updates from Russell King:
 "This looks scary at first glance, but what it is is:
   - a rework of the sa11x0 DMA engine driver merged during the previous
     cycle, to extract a common set of helper functions for DMA engine
     implementations.
   - conversion of amba-pl08x.c to use these helper functions.
   - addition of OMAP DMA engine driver (using these helper functions),
     and conversion of some of the OMAP DMA users to use DMA engine.

  Nothing in the helper functions is ARM specific, so I hope that other
  implementations can consolidate some of their code by making use of
  these helpers.

  This has been sitting in linux-next most of the merge cycle, and has
  been tested by several OMAP folk.  I've tested it on sa11x0 platforms,
  and given it my best shot on my broken platforms which have the
  amba-pl08x controller.

  The last point is the addition to feature-removal-schedule.txt, which
  will have a merge conflict.  Between myself and TI, we're planning to
  remove the old TI DMA implementation next year."

Fix up trivial add/add conflicts in Documentation/feature-removal-schedule.txt
and drivers/dma/{Kconfig,Makefile}

* 'dmaengine' of git://git.linaro.org/people/rmk/linux-arm: (53 commits)
  ARM: 7481/1: OMAP2+: omap2plus_defconfig: enable OMAP DMA engine
  ARM: 7464/1: mmc: omap_hsmmc: ensure probe returns error if DMA channel request fails
  Add feature removal of old OMAP private DMA implementation
  mtd: omap2: remove private DMA API implementation
  mtd: omap2: add DMA engine support
  spi: omap2-mcspi: remove private DMA API implementation
  spi: omap2-mcspi: add DMA engine support
  ARM: omap: remove mmc platform data dma_mask and initialization
  mmc: omap: remove private DMA API implementation
  mmc: omap: add DMA engine support
  mmc: omap_hsmmc: remove private DMA API implementation
  mmc: omap_hsmmc: add DMA engine support
  dmaengine: omap: add support for cyclic DMA
  dmaengine: omap: add support for setting fi
  dmaengine: omap: add support for returning residue in tx_state method
  dmaengine: add OMAP DMA engine driver
  dmaengine: sa11x0-dma: add cyclic DMA support
  dmaengine: sa11x0-dma: fix DMA residue support
  dmaengine: PL08x: ensure all descriptors are freed when channel is released
  dmaengine: PL08x: get rid of write only pool_ctr and free_txd locking
  ...

1  2 
Documentation/feature-removal-schedule.txt
arch/arm/configs/omap2plus_defconfig
arch/arm/mach-omap1/board-nokia770.c
arch/arm/mach-spear3xx/spear3xx.c
arch/arm/mach-spear6xx/spear6xx.c
drivers/dma/Kconfig
drivers/dma/Makefile
drivers/mmc/host/omap_hsmmc.c
drivers/spi/spi-omap2-mcspi.c

index 72ed15075f79d8de0eed70971adbe2345aa252fa,1f7ba3537a8557d2f61fe91a73862b5cb8b077f9..afaff312bf415acb59449aeb9bee4c848c197ff2
@@@ -13,14 -13,6 +13,14 @@@ Who:        Jim Cromie <jim.cromie@gmail.com>
  
  ---------------------------
  
 +What: /proc/sys/vm/nr_pdflush_threads
 +When: 2012
 +Why: Since pdflush is deprecated, the interface exported in /proc/sys/vm/
 +     should be removed.
 +Who: Wanpeng Li <liwp@linux.vnet.ibm.com>
 +
 +---------------------------
 +
  What: CONFIG_APM_CPU_IDLE, and its ability to call APM BIOS in idle
  When: 2012
  Why:  This optional sub-feature of APM is of dubious reliability,
@@@ -78,6 -70,20 +78,6 @@@ Who: Luis R. Rodriguez <lrodriguez@athe
  
  ---------------------------
  
 -What: IRQF_SAMPLE_RANDOM
 -Check:        IRQF_SAMPLE_RANDOM
 -When: July 2009
 -
 -Why:  Many of IRQF_SAMPLE_RANDOM users are technically bogus as entropy
 -      sources in the kernel's current entropy model. To resolve this, every
 -      input point to the kernel's entropy pool needs to better document the
 -      type of entropy source it actually is. This will be replaced with
 -      additional add_*_randomness functions in drivers/char/random.c
 -
 -Who:  Robin Getz <rgetz@blackfin.uclinux.org> & Matt Mackall <mpm@selenic.com>
 -
 ----------------------------
 -
  What: The ieee80211_regdom module parameter
  When: March 2010 / desktop catchup
  
@@@ -243,6 -249,15 +243,6 @@@ Who:      Ravikiran Thirumalai <kiran@scalex
  
  ---------------------------
  
 -What: Code that is now under CONFIG_WIRELESS_EXT_SYSFS
 -      (in net/core/net-sysfs.c)
 -When: 3.5
 -Why:  Over 1K .text/.data size reduction, data is available in other
 -      ways (ioctls)
 -Who:  Johannes Berg <johannes@sipsolutions.net>
 -
 ----------------------------
 -
  What: sysfs ui for changing p4-clockmod parameters
  When: September 2009
  Why:  See commits 129f8ae9b1b5be94517da76009ea956e89104ce8 and
@@@ -399,6 -414,21 +399,6 @@@ Who:      Jean Delvare <khali@linux-fr.org
  
  ----------------------------
  
 -What: xt_connlimit rev 0
 -When: 2012
 -Who:  Jan Engelhardt <jengelh@medozas.de>
 -Files:        net/netfilter/xt_connlimit.c
 -
 -----------------------------
 -
 -What: ipt_addrtype match include file
 -When: 2012
 -Why:  superseded by xt_addrtype
 -Who:  Florian Westphal <fw@strlen.de>
 -Files:        include/linux/netfilter_ipv4/ipt_addrtype.h
 -
 -----------------------------
 -
  What: i2c_driver.attach_adapter
        i2c_driver.detach_adapter
  When: September 2011
@@@ -419,19 -449,6 +419,19 @@@ Who:     Hans Verkuil <hans.verkuil@cisco.c
  
  ----------------------------
  
 +What: CONFIG_CFG80211_WEXT
 +When: as soon as distributions ship new wireless tools, ie. wpa_supplicant 1.0
 +      and NetworkManager/connman/etc. that are able to use nl80211
 +Why:  Wireless extensions are deprecated, and userland tools are moving to
 +      using nl80211. New drivers are no longer using wireless extensions,
 +      and while there might still be old drivers, both new drivers and new
 +      userland no longer needs them and they can't be used for an feature
 +      developed in the past couple of years. As such, compatibility with
 +      wireless extensions in new drivers will be removed.
 +Who:  Johannes Berg <johannes@sipsolutions.net>
 +
 +----------------------------
 +
  What: g_file_storage driver
  When: 3.8
  Why:  This driver has been superseded by g_mass_storage.
@@@ -506,6 -523,14 +506,6 @@@ Who:      Sebastian Andrzej Siewior <sebasti
  
  ----------------------------
  
 -What: kmap_atomic(page, km_type)
 -When: 3.5
 -Why:  The old kmap_atomic() with two arguments is deprecated, we only
 -      keep it for backward compatibility for few cycles and then drop it.
 -Who:  Cong Wang <amwang@redhat.com>
 -
 -----------------------------
 -
  What: get_robust_list syscall
  When: 2013
  Why:  There appear to be no production users of the get_robust_list syscall,
@@@ -564,13 -589,6 +564,13 @@@ Why:     Remount currently allows changing 
  
  ----------------------------
  
 +What:  xt_recent rev 0
 +When:  2013
 +Who:   Pablo Neira Ayuso <pablo@netfilter.org>
 +Files: net/netfilter/xt_recent.c
 +
 +----------------------------
 +
  What: KVM debugfs statistics
  When: 2013
  Why:  KVM tracepoints provide mostly equivalent information in a much more
@@@ -595,34 -613,13 +595,45 @@@ Why:    Unsupported/unmaintained/unused si
  
  ----------------------------
  
 +What: V4L2 selections API target rectangle and flags unification, the
 +      following definitions will be removed: V4L2_SEL_TGT_CROP_ACTIVE,
 +      V4L2_SEL_TGT_COMPOSE_ACTIVE, V4L2_SUBDEV_SEL_*, V4L2_SUBDEV_SEL_FLAG_*
 +      in favor of common V4L2_SEL_TGT_* and V4L2_SEL_FLAG_* definitions.
 +      For more details see include/linux/v4l2-common.h.
 +When: 3.8
 +Why:  The regular V4L2 selections and the subdev selection API originally
 +      defined distinct names for the target rectangles and flags - V4L2_SEL_*
 +      and V4L2_SUBDEV_SEL_*. Although, it turned out that the meaning of these
 +      target rectangles is virtually identical and the APIs were consolidated
 +      to use single set of names - V4L2_SEL_*. This didn't involve any ABI
 +      changes. Alias definitions were created for the original ones to avoid
 +      any instabilities in the user space interface. After few cycles these
 +      backward compatibility definitions will be removed.
 +Who:  Sylwester Nawrocki <sylvester.nawrocki@gmail.com>
 +
 +----------------------------
 +
 +What: Using V4L2_CAP_VIDEO_CAPTURE and V4L2_CAP_VIDEO_OUTPUT flags
 +      to indicate a V4L2 memory-to-memory device capability
 +When: 3.8
 +Why:  New drivers should use new V4L2_CAP_VIDEO_M2M capability flag
 +      to indicate a V4L2 video memory-to-memory (M2M) device and
 +      applications can now identify a M2M video device by checking
 +      for V4L2_CAP_VIDEO_M2M, with VIDIOC_QUERYCAP ioctl. Using ORed
 +      V4L2_CAP_VIDEO_CAPTURE and V4L2_CAP_VIDEO_OUTPUT flags for M2M
 +      devices is ambiguous and may lead, for example, to identifying
 +      a M2M device as a video capture or output device.
 +Who:  Sylwester Nawrocki <s.nawrocki@samsung.com>
 +
 +----------------------------
++
+ What: OMAP private DMA implementation
+ When: 2013
+ Why:  We have a DMA engine implementation; all users should be updated
+       to use this rather than persisting with the old APIs.  The old APIs
+       block merging the old DMA engine implementation into the DMA
+       engine driver.
+ Who:  Russell King <linux@arm.linux.org.uk>,
+       Santosh Shilimkar <santosh.shilimkar@ti.com>
+ ----------------------------
index b152de79fd95373e2f6fd8e34e66a4c360463c3b,3b391b23bddafec043d7d21118301466f9b4ab40..e58edc36b4066bdba9dcdd4112d5ae29c15c8f5e
@@@ -176,6 -176,7 +176,6 @@@ CONFIG_USB_ANNOUNCE_NEW_DEVICES=
  CONFIG_USB_DEVICEFS=y
  CONFIG_USB_SUSPEND=y
  CONFIG_USB_MON=y
 -CONFIG_USB_EHCI_HCD=y
  CONFIG_USB_WDM=y
  CONFIG_USB_STORAGE=y
  CONFIG_USB_LIBUSUAL=y
@@@ -193,10 -194,11 +193,12 @@@ CONFIG_MMC_OMAP_HS=
  CONFIG_RTC_CLASS=y
  CONFIG_RTC_DRV_TWL92330=y
  CONFIG_RTC_DRV_TWL4030=y
+ CONFIG_DMADEVICES=y
+ CONFIG_DMA_OMAP=y
  CONFIG_EXT2_FS=y
  CONFIG_EXT3_FS=y
  # CONFIG_EXT3_FS_XATTR is not set
 +CONFIG_EXT4_FS=y
  CONFIG_QUOTA=y
  CONFIG_QFMT_V2=y
  CONFIG_MSDOS_FS=y
@@@ -236,4 -238,3 +238,4 @@@ CONFIG_CRC_T10DIF=
  CONFIG_CRC_ITU_T=y
  CONFIG_CRC7=y
  CONFIG_LIBCRC32C=y
 +CONFIG_SOC_OMAP5=y
index 4007a372481b9a9bfac27c9fa8d55d2ed672fa27,c54b45f32638bf02f2c57f72fcbc573682be403f..2c0ca8fc3380092380b6e2e683dfa9a17460fadf
@@@ -26,6 -26,7 +26,6 @@@
  #include <asm/mach/map.h>
  
  #include <plat/mux.h>
 -#include <plat/usb.h>
  #include <plat/board.h>
  #include <plat/keypad.h>
  #include <plat/lcd_mipid.h>
@@@ -33,7 -34,6 +33,7 @@@
  #include <plat/clock.h>
  
  #include <mach/hardware.h>
 +#include <mach/usb.h>
  
  #include "common.h"
  
@@@ -185,7 -185,6 +185,6 @@@ static int nokia770_mmc_get_cover_state
  
  static struct omap_mmc_platform_data nokia770_mmc2_data = {
        .nr_slots                       = 1,
-       .dma_mask                       = 0xffffffff,
        .max_freq                       = 12000000,
        .slots[0]       = {
                .set_power              = nokia770_mmc_set_power,
index 66db5f13af844360b1b5845d1b06c13a6d51445a,d6cd8403fe668e8f9f18df371f6263ab0366d230..98144baf88838243d8a45c5bded0f606bd7d99d7
@@@ -46,7 -46,8 +46,8 @@@ struct pl022_ssp_controller pl022_plat_
  struct pl08x_platform_data pl080_plat_data = {
        .memcpy_channel = {
                .bus_id = "memcpy",
-               .cctl = (PL080_BSIZE_16 << PL080_CONTROL_SB_SIZE_SHIFT | \
+               .cctl_memcpy =
+                       (PL080_BSIZE_16 << PL080_CONTROL_SB_SIZE_SHIFT | \
                        PL080_BSIZE_16 << PL080_CONTROL_DB_SIZE_SHIFT | \
                        PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | \
                        PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT | \
@@@ -87,7 -88,7 +88,7 @@@ void __init spear3xx_map_io(void
  
  static void __init spear3xx_timer_init(void)
  {
 -      char pclk_name[] = "pll3_48m_clk";
 +      char pclk_name[] = "pll3_clk";
        struct clk *gpt_clk, *pclk;
  
        spear3xx_clk_init();
index 9af67d003c62ce6f167307020fcd2f52fa181e8a,b59ae5369e7bb3900c9f4a6dcbdd267d48a9a38c..5a5a52db252bf79d6d776c4a2cbdbbf330ba9e43
@@@ -36,336 -36,288 +36,288 @@@ static struct pl08x_channel_data spear6
                .min_signal = 0,
                .max_signal = 0,
                .muxval = 0,
-               .cctl = 0,
                .periph_buses = PL08X_AHB1,
        }, {
                .bus_id = "ssp1_tx",
                .min_signal = 1,
                .max_signal = 1,
                .muxval = 0,
-               .cctl = 0,
                .periph_buses = PL08X_AHB1,
        }, {
                .bus_id = "uart0_rx",
                .min_signal = 2,
                .max_signal = 2,
                .muxval = 0,
-               .cctl = 0,
                .periph_buses = PL08X_AHB1,
        }, {
                .bus_id = "uart0_tx",
                .min_signal = 3,
                .max_signal = 3,
                .muxval = 0,
-               .cctl = 0,
                .periph_buses = PL08X_AHB1,
        }, {
                .bus_id = "uart1_rx",
                .min_signal = 4,
                .max_signal = 4,
                .muxval = 0,
-               .cctl = 0,
                .periph_buses = PL08X_AHB1,
        }, {
                .bus_id = "uart1_tx",
                .min_signal = 5,
                .max_signal = 5,
                .muxval = 0,
-               .cctl = 0,
                .periph_buses = PL08X_AHB1,
        }, {
                .bus_id = "ssp2_rx",
                .min_signal = 6,
                .max_signal = 6,
                .muxval = 0,
-               .cctl = 0,
                .periph_buses = PL08X_AHB2,
        }, {
                .bus_id = "ssp2_tx",
                .min_signal = 7,
                .max_signal = 7,
                .muxval = 0,
-               .cctl = 0,
                .periph_buses = PL08X_AHB2,
        }, {
                .bus_id = "ssp0_rx",
                .min_signal = 8,
                .max_signal = 8,
                .muxval = 0,
-               .cctl = 0,
                .periph_buses = PL08X_AHB1,
        }, {
                .bus_id = "ssp0_tx",
                .min_signal = 9,
                .max_signal = 9,
                .muxval = 0,
-               .cctl = 0,
                .periph_buses = PL08X_AHB1,
        }, {
                .bus_id = "i2c_rx",
                .min_signal = 10,
                .max_signal = 10,
                .muxval = 0,
-               .cctl = 0,
                .periph_buses = PL08X_AHB1,
        }, {
                .bus_id = "i2c_tx",
                .min_signal = 11,
                .max_signal = 11,
                .muxval = 0,
-               .cctl = 0,
                .periph_buses = PL08X_AHB1,
        }, {
                .bus_id = "irda",
                .min_signal = 12,
                .max_signal = 12,
                .muxval = 0,
-               .cctl = 0,
                .periph_buses = PL08X_AHB1,
        }, {
                .bus_id = "adc",
                .min_signal = 13,
                .max_signal = 13,
                .muxval = 0,
-               .cctl = 0,
                .periph_buses = PL08X_AHB2,
        }, {
                .bus_id = "to_jpeg",
                .min_signal = 14,
                .max_signal = 14,
                .muxval = 0,
-               .cctl = 0,
                .periph_buses = PL08X_AHB1,
        }, {
                .bus_id = "from_jpeg",
                .min_signal = 15,
                .max_signal = 15,
                .muxval = 0,
-               .cctl = 0,
                .periph_buses = PL08X_AHB1,
        }, {
                .bus_id = "ras0_rx",
                .min_signal = 0,
                .max_signal = 0,
                .muxval = 1,
-               .cctl = 0,
                .periph_buses = PL08X_AHB1,
        }, {
                .bus_id = "ras0_tx",
                .min_signal = 1,
                .max_signal = 1,
                .muxval = 1,
-               .cctl = 0,
                .periph_buses = PL08X_AHB1,
        }, {
                .bus_id = "ras1_rx",
                .min_signal = 2,
                .max_signal = 2,
                .muxval = 1,
-               .cctl = 0,
                .periph_buses = PL08X_AHB1,
        }, {
                .bus_id = "ras1_tx",
                .min_signal = 3,
                .max_signal = 3,
                .muxval = 1,
-               .cctl = 0,
                .periph_buses = PL08X_AHB1,
        }, {
                .bus_id = "ras2_rx",
                .min_signal = 4,
                .max_signal = 4,
                .muxval = 1,
-               .cctl = 0,
                .periph_buses = PL08X_AHB1,
        }, {
                .bus_id = "ras2_tx",
                .min_signal = 5,
                .max_signal = 5,
                .muxval = 1,
-               .cctl = 0,
                .periph_buses = PL08X_AHB1,
        }, {
                .bus_id = "ras3_rx",
                .min_signal = 6,
                .max_signal = 6,
                .muxval = 1,
-               .cctl = 0,
                .periph_buses = PL08X_AHB1,
        }, {
                .bus_id = "ras3_tx",
                .min_signal = 7,
                .max_signal = 7,
                .muxval = 1,
-               .cctl = 0,
                .periph_buses = PL08X_AHB1,
        }, {
                .bus_id = "ras4_rx",
                .min_signal = 8,
                .max_signal = 8,
                .muxval = 1,
-               .cctl = 0,
                .periph_buses = PL08X_AHB1,
        }, {
                .bus_id = "ras4_tx",
                .min_signal = 9,
                .max_signal = 9,
                .muxval = 1,
-               .cctl = 0,
                .periph_buses = PL08X_AHB1,
        }, {
                .bus_id = "ras5_rx",
                .min_signal = 10,
                .max_signal = 10,
                .muxval = 1,
-               .cctl = 0,
                .periph_buses = PL08X_AHB1,
        }, {
                .bus_id = "ras5_tx",
                .min_signal = 11,
                .max_signal = 11,
                .muxval = 1,
-               .cctl = 0,
                .periph_buses = PL08X_AHB1,
        }, {
                .bus_id = "ras6_rx",
                .min_signal = 12,
                .max_signal = 12,
                .muxval = 1,
-               .cctl = 0,
                .periph_buses = PL08X_AHB1,
        }, {
                .bus_id = "ras6_tx",
                .min_signal = 13,
                .max_signal = 13,
                .muxval = 1,
-               .cctl = 0,
                .periph_buses = PL08X_AHB1,
        }, {
                .bus_id = "ras7_rx",
                .min_signal = 14,
                .max_signal = 14,
                .muxval = 1,
-               .cctl = 0,
                .periph_buses = PL08X_AHB1,
        }, {
                .bus_id = "ras7_tx",
                .min_signal = 15,
                .max_signal = 15,
                .muxval = 1,
-               .cctl = 0,
                .periph_buses = PL08X_AHB1,
        }, {
                .bus_id = "ext0_rx",
                .min_signal = 0,
                .max_signal = 0,
                .muxval = 2,
-               .cctl = 0,
                .periph_buses = PL08X_AHB2,
        }, {
                .bus_id = "ext0_tx",
                .min_signal = 1,
                .max_signal = 1,
                .muxval = 2,
-               .cctl = 0,
                .periph_buses = PL08X_AHB2,
        }, {
                .bus_id = "ext1_rx",
                .min_signal = 2,
                .max_signal = 2,
                .muxval = 2,
-               .cctl = 0,
                .periph_buses = PL08X_AHB2,
        }, {
                .bus_id = "ext1_tx",
                .min_signal = 3,
                .max_signal = 3,
                .muxval = 2,
-               .cctl = 0,
                .periph_buses = PL08X_AHB2,
        }, {
                .bus_id = "ext2_rx",
                .min_signal = 4,
                .max_signal = 4,
                .muxval = 2,
-               .cctl = 0,
                .periph_buses = PL08X_AHB2,
        }, {
                .bus_id = "ext2_tx",
                .min_signal = 5,
                .max_signal = 5,
                .muxval = 2,
-               .cctl = 0,
                .periph_buses = PL08X_AHB2,
        }, {
                .bus_id = "ext3_rx",
                .min_signal = 6,
                .max_signal = 6,
                .muxval = 2,
-               .cctl = 0,
                .periph_buses = PL08X_AHB2,
        }, {
                .bus_id = "ext3_tx",
                .min_signal = 7,
                .max_signal = 7,
                .muxval = 2,
-               .cctl = 0,
                .periph_buses = PL08X_AHB2,
        }, {
                .bus_id = "ext4_rx",
                .min_signal = 8,
                .max_signal = 8,
                .muxval = 2,
-               .cctl = 0,
                .periph_buses = PL08X_AHB2,
        }, {
                .bus_id = "ext4_tx",
                .min_signal = 9,
                .max_signal = 9,
                .muxval = 2,
-               .cctl = 0,
                .periph_buses = PL08X_AHB2,
        }, {
                .bus_id = "ext5_rx",
                .min_signal = 10,
                .max_signal = 10,
                .muxval = 2,
-               .cctl = 0,
                .periph_buses = PL08X_AHB2,
        }, {
                .bus_id = "ext5_tx",
                .min_signal = 11,
                .max_signal = 11,
                .muxval = 2,
-               .cctl = 0,
                .periph_buses = PL08X_AHB2,
        }, {
                .bus_id = "ext6_rx",
                .min_signal = 12,
                .max_signal = 12,
                .muxval = 2,
-               .cctl = 0,
                .periph_buses = PL08X_AHB2,
        }, {
                .bus_id = "ext6_tx",
                .min_signal = 13,
                .max_signal = 13,
                .muxval = 2,
-               .cctl = 0,
                .periph_buses = PL08X_AHB2,
        }, {
                .bus_id = "ext7_rx",
                .min_signal = 14,
                .max_signal = 14,
                .muxval = 2,
-               .cctl = 0,
                .periph_buses = PL08X_AHB2,
        }, {
                .bus_id = "ext7_tx",
                .min_signal = 15,
                .max_signal = 15,
                .muxval = 2,
-               .cctl = 0,
                .periph_buses = PL08X_AHB2,
        },
  };
  struct pl08x_platform_data pl080_plat_data = {
        .memcpy_channel = {
                .bus_id = "memcpy",
-               .cctl = (PL080_BSIZE_16 << PL080_CONTROL_SB_SIZE_SHIFT | \
+               .cctl_memcpy =
+                       (PL080_BSIZE_16 << PL080_CONTROL_SB_SIZE_SHIFT | \
                        PL080_BSIZE_16 << PL080_CONTROL_DB_SIZE_SHIFT | \
                        PL080_WIDTH_32BIT << PL080_CONTROL_SWIDTH_SHIFT | \
                        PL080_WIDTH_32BIT << PL080_CONTROL_DWIDTH_SHIFT | \
@@@ -423,7 -376,7 +376,7 @@@ void __init spear6xx_map_io(void
  
  static void __init spear6xx_timer_init(void)
  {
 -      char pclk_name[] = "pll3_48m_clk";
 +      char pclk_name[] = "pll3_clk";
        struct clk *gpt_clk, *pclk;
  
        spear6xx_clk_init();
diff --combined drivers/dma/Kconfig
index d45cf1bcbde5f6b096d5cf38bf13b9c9ddf23a86,6f93365d9d04727f33c80109058ed892b3ead51c..d06ea2950dd9ffb9ad266bcedbb2db934e020376
@@@ -53,6 -53,7 +53,7 @@@ config AMBA_PL08
        bool "ARM PrimeCell PL080 or PL081 support"
        depends on ARM_AMBA && EXPERIMENTAL
        select DMA_ENGINE
+       select DMA_VIRTUAL_CHANNELS
        help
          Platform has a PL08x DMAC device
          which can provide DMA engine support
@@@ -148,20 -149,6 +149,20 @@@ config TXX9_DMA
          Support the TXx9 SoC internal DMA controller.  This can be
          integrated in chips such as the Toshiba TX4927/38/39.
  
 +config TEGRA20_APB_DMA
 +      bool "NVIDIA Tegra20 APB DMA support"
 +      depends on ARCH_TEGRA
 +      select DMA_ENGINE
 +      help
 +        Support for the NVIDIA Tegra20 APB DMA controller driver. The
 +        DMA controller is having multiple DMA channel which can be
 +        configured for different peripherals like audio, UART, SPI,
 +        I2C etc which is in APB bus.
 +        This DMA controller transfers data from memory to peripheral fifo
 +        or vice versa. It does not support memory to memory data transfer.
 +
 +
 +
  config SH_DMAE
        tristate "Renesas SuperH DMAC support"
        depends on (SUPERH && SH_DMA) || (ARM && ARCH_SHMOBILE)
@@@ -251,7 -238,7 +252,7 @@@ config IMX_DM
  
  config MXS_DMA
        bool "MXS DMA support"
 -      depends on SOC_IMX23 || SOC_IMX28
 +      depends on SOC_IMX23 || SOC_IMX28 || SOC_IMX6Q
        select STMP_DEVICE
        select DMA_ENGINE
        help
@@@ -269,24 -256,24 +270,34 @@@ config DMA_SA11X
        tristate "SA-11x0 DMA support"
        depends on ARCH_SA1100
        select DMA_ENGINE
+       select DMA_VIRTUAL_CHANNELS
        help
          Support the DMA engine found on Intel StrongARM SA-1100 and
          SA-1110 SoCs.  This DMA engine can only be used with on-chip
          devices.
  
 +config MMP_TDMA
 +      bool "MMP Two-Channel DMA support"
 +      depends on ARCH_MMP
 +      select DMA_ENGINE
 +      help
 +        Support the MMP Two-Channel DMA engine.
 +        This engine used for MMP Audio DMA and pxa910 SQU.
 +
 +        Say Y here if you enabled MMP ADMA, otherwise say N.
 +
+ config DMA_OMAP
+       tristate "OMAP DMA support"
+       depends on ARCH_OMAP
+       select DMA_ENGINE
+       select DMA_VIRTUAL_CHANNELS
  config DMA_ENGINE
        bool
  
+ config DMA_VIRTUAL_CHANNELS
+       tristate
  comment "DMA Clients"
        depends on DMA_ENGINE
  
diff --combined drivers/dma/Makefile
index 640356add0a31f0bea96cc0568a2f290e41b0494,ddc291a2116a575fbfc29844d19dac6ab6580d2d..4cf6b128ab9a466b8f4c2c5237064f0f8e80846f
@@@ -2,6 -2,7 +2,7 @@@ ccflags-$(CONFIG_DMADEVICES_DEBUG)  := 
  ccflags-$(CONFIG_DMADEVICES_VDEBUG) += -DVERBOSE_DEBUG
  
  obj-$(CONFIG_DMA_ENGINE) += dmaengine.o
+ obj-$(CONFIG_DMA_VIRTUAL_CHANNELS) += virt-dma.o
  obj-$(CONFIG_NET_DMA) += iovlock.o
  obj-$(CONFIG_INTEL_MID_DMAC) += intel_mid_dma.o
  obj-$(CONFIG_DMATEST) += dmatest.o
@@@ -14,7 -15,7 +15,7 @@@ obj-$(CONFIG_DW_DMAC) += dw_dmac.
  obj-$(CONFIG_AT_HDMAC) += at_hdmac.o
  obj-$(CONFIG_MX3_IPU) += ipu/
  obj-$(CONFIG_TXX9_DMAC) += txx9dmac.o
 -obj-$(CONFIG_SH_DMAE) += shdma.o
 +obj-$(CONFIG_SH_DMAE) += sh/
  obj-$(CONFIG_COH901318) += coh901318.o coh901318_lli.o
  obj-$(CONFIG_AMCC_PPC440SPE_ADMA) += ppc4xx/
  obj-$(CONFIG_IMX_SDMA) += imx-sdma.o
@@@ -23,10 -24,9 +24,11 @@@ obj-$(CONFIG_MXS_DMA) += mxs-dma.
  obj-$(CONFIG_TIMB_DMA) += timb_dma.o
  obj-$(CONFIG_SIRF_DMA) += sirf-dma.o
  obj-$(CONFIG_STE_DMA40) += ste_dma40.o ste_dma40_ll.o
 +obj-$(CONFIG_TEGRA20_APB_DMA) += tegra20-apb-dma.o
  obj-$(CONFIG_PL330_DMA) += pl330.o
  obj-$(CONFIG_PCH_DMA) += pch_dma.o
  obj-$(CONFIG_AMBA_PL08X) += amba-pl08x.o
  obj-$(CONFIG_EP93XX_DMA) += ep93xx_dma.o
  obj-$(CONFIG_DMA_SA11X0) += sa11x0-dma.o
 +obj-$(CONFIG_MMP_TDMA) += mmp_tdma.o
+ obj-$(CONFIG_DMA_OMAP) += omap-dma.o
index bc28627af66b961372f0f38cc0bbe61d621cc99a,823d21cb87c01cf9673d90f682479fd234470cb3..3a09f93cc3b6f846a2b4cd327a7fd2a4524e31bc
@@@ -19,6 -19,7 +19,7 @@@
  #include <linux/init.h>
  #include <linux/kernel.h>
  #include <linux/debugfs.h>
+ #include <linux/dmaengine.h>
  #include <linux/seq_file.h>
  #include <linux/interrupt.h>
  #include <linux/delay.h>
@@@ -29,6 -30,7 +30,7 @@@
  #include <linux/of.h>
  #include <linux/of_gpio.h>
  #include <linux/of_device.h>
+ #include <linux/omap-dma.h>
  #include <linux/mmc/host.h>
  #include <linux/mmc/core.h>
  #include <linux/mmc/mmc.h>
@@@ -37,7 -39,6 +39,6 @@@
  #include <linux/gpio.h>
  #include <linux/regulator/consumer.h>
  #include <linux/pm_runtime.h>
- #include <plat/dma.h>
  #include <mach/hardware.h>
  #include <plat/board.h>
  #include <plat/mmc.h>
@@@ -166,7 -167,8 +167,8 @@@ struct omap_hsmmc_host 
        int                     suspended;
        int                     irq;
        int                     use_dma, dma_ch;
-       int                     dma_line_tx, dma_line_rx;
+       struct dma_chan         *tx_chan;
+       struct dma_chan         *rx_chan;
        int                     slot_id;
        int                     response_busy;
        int                     context_loss;
@@@ -797,6 -799,12 +799,12 @@@ omap_hsmmc_get_dma_dir(struct omap_hsmm
                return DMA_FROM_DEVICE;
  }
  
+ static struct dma_chan *omap_hsmmc_get_dma_chan(struct omap_hsmmc_host *host,
+       struct mmc_data *data)
+ {
+       return data->flags & MMC_DATA_WRITE ? host->tx_chan : host->rx_chan;
+ }
  static void omap_hsmmc_request_done(struct omap_hsmmc_host *host, struct mmc_request *mrq)
  {
        int dma_ch;
@@@ -889,10 -897,13 +897,13 @@@ static void omap_hsmmc_dma_cleanup(stru
        spin_unlock_irqrestore(&host->irq_lock, flags);
  
        if (host->use_dma && dma_ch != -1) {
-               dma_unmap_sg(mmc_dev(host->mmc), host->data->sg,
-                       host->data->sg_len,
+               struct dma_chan *chan = omap_hsmmc_get_dma_chan(host, host->data);
+               dmaengine_terminate_all(chan);
+               dma_unmap_sg(chan->device->dev,
+                       host->data->sg, host->data->sg_len,
                        omap_hsmmc_get_dma_dir(host, host->data));
-               omap_free_dma(dma_ch);
                host->data->host_cookie = 0;
        }
        host->data = NULL;
@@@ -1089,7 -1100,7 +1100,7 @@@ static int omap_hsmmc_switch_opcond(str
        /* Disable the clocks */
        pm_runtime_put_sync(host->dev);
        if (host->dbclk)
 -              clk_disable(host->dbclk);
 +              clk_disable_unprepare(host->dbclk);
  
        /* Turn the power off */
        ret = mmc_slot(host).set_power(host->dev, host->slot_id, 0, 0);
                                               vdd);
        pm_runtime_get_sync(host->dev);
        if (host->dbclk)
 -              clk_enable(host->dbclk);
 +              clk_prepare_enable(host->dbclk);
  
        if (ret != 0)
                goto err;
@@@ -1190,90 -1201,29 +1201,29 @@@ static irqreturn_t omap_hsmmc_detect(in
        return IRQ_HANDLED;
  }
  
- static int omap_hsmmc_get_dma_sync_dev(struct omap_hsmmc_host *host,
-                                    struct mmc_data *data)
- {
-       int sync_dev;
-       if (data->flags & MMC_DATA_WRITE)
-               sync_dev = host->dma_line_tx;
-       else
-               sync_dev = host->dma_line_rx;
-       return sync_dev;
- }
- static void omap_hsmmc_config_dma_params(struct omap_hsmmc_host *host,
-                                      struct mmc_data *data,
-                                      struct scatterlist *sgl)
- {
-       int blksz, nblk, dma_ch;
-       dma_ch = host->dma_ch;
-       if (data->flags & MMC_DATA_WRITE) {
-               omap_set_dma_dest_params(dma_ch, 0, OMAP_DMA_AMODE_CONSTANT,
-                       (host->mapbase + OMAP_HSMMC_DATA), 0, 0);
-               omap_set_dma_src_params(dma_ch, 0, OMAP_DMA_AMODE_POST_INC,
-                       sg_dma_address(sgl), 0, 0);
-       } else {
-               omap_set_dma_src_params(dma_ch, 0, OMAP_DMA_AMODE_CONSTANT,
-                       (host->mapbase + OMAP_HSMMC_DATA), 0, 0);
-               omap_set_dma_dest_params(dma_ch, 0, OMAP_DMA_AMODE_POST_INC,
-                       sg_dma_address(sgl), 0, 0);
-       }
-       blksz = host->data->blksz;
-       nblk = sg_dma_len(sgl) / blksz;
-       omap_set_dma_transfer_params(dma_ch, OMAP_DMA_DATA_TYPE_S32,
-                       blksz / 4, nblk, OMAP_DMA_SYNC_FRAME,
-                       omap_hsmmc_get_dma_sync_dev(host, data),
-                       !(data->flags & MMC_DATA_WRITE));
-       omap_start_dma(dma_ch);
- }
- /*
-  * DMA call back function
-  */
- static void omap_hsmmc_dma_cb(int lch, u16 ch_status, void *cb_data)
+ static void omap_hsmmc_dma_callback(void *param)
  {
-       struct omap_hsmmc_host *host = cb_data;
+       struct omap_hsmmc_host *host = param;
+       struct dma_chan *chan;
        struct mmc_data *data;
-       int dma_ch, req_in_progress;
-       unsigned long flags;
-       if (!(ch_status & OMAP_DMA_BLOCK_IRQ)) {
-               dev_warn(mmc_dev(host->mmc), "unexpected dma status %x\n",
-                       ch_status);
-               return;
-       }
+       int req_in_progress;
  
-       spin_lock_irqsave(&host->irq_lock, flags);
+       spin_lock_irq(&host->irq_lock);
        if (host->dma_ch < 0) {
-               spin_unlock_irqrestore(&host->irq_lock, flags);
+               spin_unlock_irq(&host->irq_lock);
                return;
        }
  
        data = host->mrq->data;
-       host->dma_sg_idx++;
-       if (host->dma_sg_idx < host->dma_len) {
-               /* Fire up the next transfer. */
-               omap_hsmmc_config_dma_params(host, data,
-                                          data->sg + host->dma_sg_idx);
-               spin_unlock_irqrestore(&host->irq_lock, flags);
-               return;
-       }
+       chan = omap_hsmmc_get_dma_chan(host, data);
        if (!data->host_cookie)
-               dma_unmap_sg(mmc_dev(host->mmc), data->sg, data->sg_len,
+               dma_unmap_sg(chan->device->dev,
+                            data->sg, data->sg_len,
                             omap_hsmmc_get_dma_dir(host, data));
  
        req_in_progress = host->req_in_progress;
-       dma_ch = host->dma_ch;
        host->dma_ch = -1;
-       spin_unlock_irqrestore(&host->irq_lock, flags);
-       omap_free_dma(dma_ch);
+       spin_unlock_irq(&host->irq_lock);
  
        /* If DMA has finished after TC, complete the request */
        if (!req_in_progress) {
  
  static int omap_hsmmc_pre_dma_transfer(struct omap_hsmmc_host *host,
                                       struct mmc_data *data,
-                                      struct omap_hsmmc_next *next)
+                                      struct omap_hsmmc_next *next,
+                                      struct dma_chan *chan)
  {
        int dma_len;
  
        /* Check if next job is already prepared */
        if (next ||
            (!next && data->host_cookie != host->next_data.cookie)) {
-               dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg,
-                                    data->sg_len,
+               dma_len = dma_map_sg(chan->device->dev, data->sg, data->sg_len,
                                     omap_hsmmc_get_dma_dir(host, data));
  
        } else {
  static int omap_hsmmc_start_dma_transfer(struct omap_hsmmc_host *host,
                                        struct mmc_request *req)
  {
-       int dma_ch = 0, ret = 0, i;
+       struct dma_slave_config cfg;
+       struct dma_async_tx_descriptor *tx;
+       int ret = 0, i;
        struct mmc_data *data = req->data;
+       struct dma_chan *chan;
  
        /* Sanity check: all the SG entries must be aligned by block size. */
        for (i = 0; i < data->sg_len; i++) {
  
        BUG_ON(host->dma_ch != -1);
  
-       ret = omap_request_dma(omap_hsmmc_get_dma_sync_dev(host, data),
-                              "MMC/SD", omap_hsmmc_dma_cb, host, &dma_ch);
-       if (ret != 0) {
-               dev_err(mmc_dev(host->mmc),
-                       "%s: omap_request_dma() failed with %d\n",
-                       mmc_hostname(host->mmc), ret);
+       chan = omap_hsmmc_get_dma_chan(host, data);
+       cfg.src_addr = host->mapbase + OMAP_HSMMC_DATA;
+       cfg.dst_addr = host->mapbase + OMAP_HSMMC_DATA;
+       cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+       cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+       cfg.src_maxburst = data->blksz / 4;
+       cfg.dst_maxburst = data->blksz / 4;
+       ret = dmaengine_slave_config(chan, &cfg);
+       if (ret)
                return ret;
-       }
-       ret = omap_hsmmc_pre_dma_transfer(host, data, NULL);
+       ret = omap_hsmmc_pre_dma_transfer(host, data, NULL, chan);
        if (ret)
                return ret;
  
-       host->dma_ch = dma_ch;
-       host->dma_sg_idx = 0;
+       tx = dmaengine_prep_slave_sg(chan, data->sg, data->sg_len,
+               data->flags & MMC_DATA_WRITE ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM,
+               DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+       if (!tx) {
+               dev_err(mmc_dev(host->mmc), "prep_slave_sg() failed\n");
+               /* FIXME: cleanup */
+               return -1;
+       }
+       tx->callback = omap_hsmmc_dma_callback;
+       tx->callback_param = host;
  
-       omap_hsmmc_config_dma_params(host, data, data->sg);
+       /* Does not fail */
+       dmaengine_submit(tx);
+       host->dma_ch = 1;
+       dma_async_issue_pending(chan);
  
        return 0;
  }
@@@ -1445,11 -1417,11 +1417,11 @@@ static void omap_hsmmc_post_req(struct 
        struct omap_hsmmc_host *host = mmc_priv(mmc);
        struct mmc_data *data = mrq->data;
  
-       if (host->use_dma) {
-               if (data->host_cookie)
-                       dma_unmap_sg(mmc_dev(host->mmc), data->sg,
-                                    data->sg_len,
-                                    omap_hsmmc_get_dma_dir(host, data));
+       if (host->use_dma && data->host_cookie) {
+               struct dma_chan *c = omap_hsmmc_get_dma_chan(host, data);
+               dma_unmap_sg(c->device->dev, data->sg, data->sg_len,
+                            omap_hsmmc_get_dma_dir(host, data));
                data->host_cookie = 0;
        }
  }
@@@ -1464,10 -1436,13 +1436,13 @@@ static void omap_hsmmc_pre_req(struct m
                return ;
        }
  
-       if (host->use_dma)
+       if (host->use_dma) {
+               struct dma_chan *c = omap_hsmmc_get_dma_chan(host, mrq->data);
                if (omap_hsmmc_pre_dma_transfer(host, mrq->data,
-                                               &host->next_data))
+                                               &host->next_data, c))
                        mrq->data->host_cookie = 0;
+       }
  }
  
  /*
@@@ -1800,6 -1775,8 +1775,8 @@@ static int __devinit omap_hsmmc_probe(s
        struct resource *res;
        int ret, irq;
        const struct of_device_id *match;
+       dma_cap_mask_t mask;
+       unsigned tx_req, rx_req;
  
        match = of_match_device(of_match_ptr(omap_mmc_of_match), &pdev->dev);
        if (match) {
        host->pdata     = pdata;
        host->dev       = &pdev->dev;
        host->use_dma   = 1;
-       host->dev->dma_mask = &pdata->dma_mask;
        host->dma_ch    = -1;
        host->irq       = irq;
        host->slot_id   = 0;
        if (IS_ERR(host->dbclk)) {
                dev_warn(mmc_dev(host->mmc), "Failed to get debounce clk\n");
                host->dbclk = NULL;
 -      } else if (clk_enable(host->dbclk) != 0) {
 +      } else if (clk_prepare_enable(host->dbclk) != 0) {
                dev_warn(mmc_dev(host->mmc), "Failed to enable debounce clk\n");
                clk_put(host->dbclk);
                host->dbclk = NULL;
        res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "tx");
        if (!res) {
                dev_err(mmc_dev(host->mmc), "cannot get DMA TX channel\n");
 +              ret = -ENXIO;
                goto err_irq;
        }
-       host->dma_line_tx = res->start;
+       tx_req = res->start;
  
        res = platform_get_resource_byname(pdev, IORESOURCE_DMA, "rx");
        if (!res) {
                dev_err(mmc_dev(host->mmc), "cannot get DMA RX channel\n");
 +              ret = -ENXIO;
                goto err_irq;
        }
-       host->dma_line_rx = res->start;
+       rx_req = res->start;
+       dma_cap_zero(mask);
+       dma_cap_set(DMA_SLAVE, mask);
+       host->rx_chan = dma_request_channel(mask, omap_dma_filter_fn, &rx_req);
+       if (!host->rx_chan) {
+               dev_err(mmc_dev(host->mmc), "unable to obtain RX DMA engine channel %u\n", rx_req);
+               ret = -ENXIO;
+               goto err_irq;
+       }
+       host->tx_chan = dma_request_channel(mask, omap_dma_filter_fn, &tx_req);
+       if (!host->tx_chan) {
+               dev_err(mmc_dev(host->mmc), "unable to obtain TX DMA engine channel %u\n", tx_req);
+               ret = -ENXIO;
+               goto err_irq;
+       }
  
        /* Request IRQ for MMC operations */
        ret = request_irq(host->irq, omap_hsmmc_irq, 0,
@@@ -2021,11 -2012,15 +2014,15 @@@ err_reg
  err_irq_cd_init:
        free_irq(host->irq, host);
  err_irq:
+       if (host->tx_chan)
+               dma_release_channel(host->tx_chan);
+       if (host->rx_chan)
+               dma_release_channel(host->rx_chan);
        pm_runtime_put_sync(host->dev);
        pm_runtime_disable(host->dev);
        clk_put(host->fclk);
        if (host->dbclk) {
 -              clk_disable(host->dbclk);
 +              clk_disable_unprepare(host->dbclk);
                clk_put(host->dbclk);
        }
  err1:
@@@ -2056,11 -2051,16 +2053,16 @@@ static int __devexit omap_hsmmc_remove(
        if (mmc_slot(host).card_detect_irq)
                free_irq(mmc_slot(host).card_detect_irq, host);
  
+       if (host->tx_chan)
+               dma_release_channel(host->tx_chan);
+       if (host->rx_chan)
+               dma_release_channel(host->rx_chan);
        pm_runtime_put_sync(host->dev);
        pm_runtime_disable(host->dev);
        clk_put(host->fclk);
        if (host->dbclk) {
 -              clk_disable(host->dbclk);
 +              clk_disable_unprepare(host->dbclk);
                clk_put(host->dbclk);
        }
  
@@@ -2118,7 -2118,7 +2120,7 @@@ static int omap_hsmmc_suspend(struct de
        }
  
        if (host->dbclk)
 -              clk_disable(host->dbclk);
 +              clk_disable_unprepare(host->dbclk);
  err:
        pm_runtime_put_sync(host->dev);
        return ret;
@@@ -2139,7 -2139,7 +2141,7 @@@ static int omap_hsmmc_resume(struct dev
        pm_runtime_get_sync(host->dev);
  
        if (host->dbclk)
 -              clk_enable(host->dbclk);
 +              clk_prepare_enable(host->dbclk);
  
        if (!(host->mmc->pm_flags & MMC_PM_KEEP_POWER))
                omap_hsmmc_conf_bus_power(host);
index 7d46b15e1520d0613b02cca28a5206f5123db4db,26a99ae9a599e7befaba86cde359c2eb997d731b..bc4778175e343c6a9ebeceac09b0cc543c935bc2
@@@ -28,6 -28,8 +28,8 @@@
  #include <linux/device.h>
  #include <linux/delay.h>
  #include <linux/dma-mapping.h>
+ #include <linux/dmaengine.h>
+ #include <linux/omap-dma.h>
  #include <linux/platform_device.h>
  #include <linux/err.h>
  #include <linux/clk.h>
@@@ -39,7 -41,6 +41,6 @@@
  
  #include <linux/spi/spi.h>
  
- #include <plat/dma.h>
  #include <plat/clock.h>
  #include <plat/mcspi.h>
  
@@@ -93,8 -94,8 +94,8 @@@
  
  /* We have 2 DMA channels per CS, one for RX and one for TX */
  struct omap2_mcspi_dma {
-       int dma_tx_channel;
-       int dma_rx_channel;
+       struct dma_chan *dma_tx;
+       struct dma_chan *dma_rx;
  
        int dma_tx_sync_dev;
        int dma_rx_sync_dev;
@@@ -300,20 -301,46 +301,46 @@@ static int mcspi_wait_for_reg_bit(void 
        return 0;
  }
  
+ static void omap2_mcspi_rx_callback(void *data)
+ {
+       struct spi_device *spi = data;
+       struct omap2_mcspi *mcspi = spi_master_get_devdata(spi->master);
+       struct omap2_mcspi_dma *mcspi_dma = &mcspi->dma_channels[spi->chip_select];
+       complete(&mcspi_dma->dma_rx_completion);
+       /* We must disable the DMA RX request */
+       omap2_mcspi_set_dma_req(spi, 1, 0);
+ }
+ static void omap2_mcspi_tx_callback(void *data)
+ {
+       struct spi_device *spi = data;
+       struct omap2_mcspi *mcspi = spi_master_get_devdata(spi->master);
+       struct omap2_mcspi_dma *mcspi_dma = &mcspi->dma_channels[spi->chip_select];
+       complete(&mcspi_dma->dma_tx_completion);
+       /* We must disable the DMA TX request */
+       omap2_mcspi_set_dma_req(spi, 0, 0);
+ }
  static unsigned
  omap2_mcspi_txrx_dma(struct spi_device *spi, struct spi_transfer *xfer)
  {
        struct omap2_mcspi      *mcspi;
        struct omap2_mcspi_cs   *cs = spi->controller_state;
        struct omap2_mcspi_dma  *mcspi_dma;
-       unsigned int            count, c;
-       unsigned long           base, tx_reg, rx_reg;
-       int                     word_len, data_type, element_count;
+       unsigned int            count;
+       int                     word_len, element_count;
        int                     elements = 0;
        u32                     l;
        u8                      * rx;
        const u8                * tx;
        void __iomem            *chstat_reg;
+       struct dma_slave_config cfg;
+       enum dma_slave_buswidth width;
+       unsigned es;
  
        mcspi = spi_master_get_devdata(spi->master);
        mcspi_dma = &mcspi->dma_channels[spi->chip_select];
  
        chstat_reg = cs->base + OMAP2_MCSPI_CHSTAT0;
  
+       if (cs->word_len <= 8) {
+               width = DMA_SLAVE_BUSWIDTH_1_BYTE;
+               es = 1;
+       } else if (cs->word_len <= 16) {
+               width = DMA_SLAVE_BUSWIDTH_2_BYTES;
+               es = 2;
+       } else {
+               width = DMA_SLAVE_BUSWIDTH_4_BYTES;
+               es = 4;
+       }
+       memset(&cfg, 0, sizeof(cfg));
+       cfg.src_addr = cs->phys + OMAP2_MCSPI_RX0;
+       cfg.dst_addr = cs->phys + OMAP2_MCSPI_TX0;
+       cfg.src_addr_width = width;
+       cfg.dst_addr_width = width;
+       cfg.src_maxburst = 1;
+       cfg.dst_maxburst = 1;
+       if (xfer->tx_buf && mcspi_dma->dma_tx) {
+               struct dma_async_tx_descriptor *tx;
+               struct scatterlist sg;
+               dmaengine_slave_config(mcspi_dma->dma_tx, &cfg);
+               sg_init_table(&sg, 1);
+               sg_dma_address(&sg) = xfer->tx_dma;
+               sg_dma_len(&sg) = xfer->len;
+               tx = dmaengine_prep_slave_sg(mcspi_dma->dma_tx, &sg, 1,
+                       DMA_MEM_TO_DEV, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+               if (tx) {
+                       tx->callback = omap2_mcspi_tx_callback;
+                       tx->callback_param = spi;
+                       dmaengine_submit(tx);
+               } else {
+                       /* FIXME: fall back to PIO? */
+               }
+       }
+       if (xfer->rx_buf && mcspi_dma->dma_rx) {
+               struct dma_async_tx_descriptor *tx;
+               struct scatterlist sg;
+               size_t len = xfer->len - es;
+               dmaengine_slave_config(mcspi_dma->dma_rx, &cfg);
+               if (l & OMAP2_MCSPI_CHCONF_TURBO)
+                       len -= es;
+               sg_init_table(&sg, 1);
+               sg_dma_address(&sg) = xfer->rx_dma;
+               sg_dma_len(&sg) = len;
+               tx = dmaengine_prep_slave_sg(mcspi_dma->dma_rx, &sg, 1,
+                       DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+               if (tx) {
+                       tx->callback = omap2_mcspi_rx_callback;
+                       tx->callback_param = spi;
+                       dmaengine_submit(tx);
+               } else {
+                       /* FIXME: fall back to PIO? */
+               }
+       }
        count = xfer->len;
-       c = count;
        word_len = cs->word_len;
  
-       base = cs->phys;
-       tx_reg = base + OMAP2_MCSPI_TX0;
-       rx_reg = base + OMAP2_MCSPI_RX0;
        rx = xfer->rx_buf;
        tx = xfer->tx_buf;
  
        if (word_len <= 8) {
-               data_type = OMAP_DMA_DATA_TYPE_S8;
                element_count = count;
        } else if (word_len <= 16) {
-               data_type = OMAP_DMA_DATA_TYPE_S16;
                element_count = count >> 1;
        } else /* word_len <= 32 */ {
-               data_type = OMAP_DMA_DATA_TYPE_S32;
                element_count = count >> 2;
        }
  
        if (tx != NULL) {
-               omap_set_dma_transfer_params(mcspi_dma->dma_tx_channel,
-                               data_type, element_count, 1,
-                               OMAP_DMA_SYNC_ELEMENT,
-                               mcspi_dma->dma_tx_sync_dev, 0);
-               omap_set_dma_dest_params(mcspi_dma->dma_tx_channel, 0,
-                               OMAP_DMA_AMODE_CONSTANT,
-                               tx_reg, 0, 0);
-               omap_set_dma_src_params(mcspi_dma->dma_tx_channel, 0,
-                               OMAP_DMA_AMODE_POST_INC,
-                               xfer->tx_dma, 0, 0);
-       }
-       if (rx != NULL) {
-               elements = element_count - 1;
-               if (l & OMAP2_MCSPI_CHCONF_TURBO)
-                       elements--;
-               omap_set_dma_transfer_params(mcspi_dma->dma_rx_channel,
-                               data_type, elements, 1,
-                               OMAP_DMA_SYNC_ELEMENT,
-                               mcspi_dma->dma_rx_sync_dev, 1);
-               omap_set_dma_src_params(mcspi_dma->dma_rx_channel, 0,
-                               OMAP_DMA_AMODE_CONSTANT,
-                               rx_reg, 0, 0);
-               omap_set_dma_dest_params(mcspi_dma->dma_rx_channel, 0,
-                               OMAP_DMA_AMODE_POST_INC,
-                               xfer->rx_dma, 0, 0);
-       }
-       if (tx != NULL) {
-               omap_start_dma(mcspi_dma->dma_tx_channel);
+               dma_async_issue_pending(mcspi_dma->dma_tx);
                omap2_mcspi_set_dma_req(spi, 0, 1);
        }
  
        if (rx != NULL) {
-               omap_start_dma(mcspi_dma->dma_rx_channel);
+               dma_async_issue_pending(mcspi_dma->dma_rx);
                omap2_mcspi_set_dma_req(spi, 1, 1);
        }
  
        if (tx != NULL) {
                wait_for_completion(&mcspi_dma->dma_tx_completion);
 -              dma_unmap_single(&spi->dev, xfer->tx_dma, count, DMA_TO_DEVICE);
 +              dma_unmap_single(mcspi->dev, xfer->tx_dma, count,
 +                               DMA_TO_DEVICE);
  
                /* for TX_ONLY mode, be sure all words have shifted out */
                if (rx == NULL) {
  
        if (rx != NULL) {
                wait_for_completion(&mcspi_dma->dma_rx_completion);
 -              dma_unmap_single(&spi->dev, xfer->rx_dma, count, DMA_FROM_DEVICE);
 +              dma_unmap_single(mcspi->dev, xfer->rx_dma, count,
 +                               DMA_FROM_DEVICE);
                omap2_mcspi_set_enable(spi, 0);
  
+               elements = element_count - 1;
                if (l & OMAP2_MCSPI_CHCONF_TURBO) {
+                       elements--;
  
                        if (likely(mcspi_read_cs_reg(spi, OMAP2_MCSPI_CHSTAT0)
                                   & OMAP2_MCSPI_CHSTAT_RXS)) {
@@@ -725,64 -777,38 +779,38 @@@ static int omap2_mcspi_setup_transfer(s
        return 0;
  }
  
- static void omap2_mcspi_dma_rx_callback(int lch, u16 ch_status, void *data)
- {
-       struct spi_device       *spi = data;
-       struct omap2_mcspi      *mcspi;
-       struct omap2_mcspi_dma  *mcspi_dma;
-       mcspi = spi_master_get_devdata(spi->master);
-       mcspi_dma = &(mcspi->dma_channels[spi->chip_select]);
-       complete(&mcspi_dma->dma_rx_completion);
-       /* We must disable the DMA RX request */
-       omap2_mcspi_set_dma_req(spi, 1, 0);
- }
- static void omap2_mcspi_dma_tx_callback(int lch, u16 ch_status, void *data)
- {
-       struct spi_device       *spi = data;
-       struct omap2_mcspi      *mcspi;
-       struct omap2_mcspi_dma  *mcspi_dma;
-       mcspi = spi_master_get_devdata(spi->master);
-       mcspi_dma = &(mcspi->dma_channels[spi->chip_select]);
-       complete(&mcspi_dma->dma_tx_completion);
-       /* We must disable the DMA TX request */
-       omap2_mcspi_set_dma_req(spi, 0, 0);
- }
  static int omap2_mcspi_request_dma(struct spi_device *spi)
  {
        struct spi_master       *master = spi->master;
        struct omap2_mcspi      *mcspi;
        struct omap2_mcspi_dma  *mcspi_dma;
+       dma_cap_mask_t mask;
+       unsigned sig;
  
        mcspi = spi_master_get_devdata(master);
        mcspi_dma = mcspi->dma_channels + spi->chip_select;
  
-       if (omap_request_dma(mcspi_dma->dma_rx_sync_dev, "McSPI RX",
-                       omap2_mcspi_dma_rx_callback, spi,
-                       &mcspi_dma->dma_rx_channel)) {
-               dev_err(&spi->dev, "no RX DMA channel for McSPI\n");
+       init_completion(&mcspi_dma->dma_rx_completion);
+       init_completion(&mcspi_dma->dma_tx_completion);
+       dma_cap_zero(mask);
+       dma_cap_set(DMA_SLAVE, mask);
+       sig = mcspi_dma->dma_rx_sync_dev;
+       mcspi_dma->dma_rx = dma_request_channel(mask, omap_dma_filter_fn, &sig);
+       if (!mcspi_dma->dma_rx) {
+               dev_err(&spi->dev, "no RX DMA engine channel for McSPI\n");
                return -EAGAIN;
        }
  
-       if (omap_request_dma(mcspi_dma->dma_tx_sync_dev, "McSPI TX",
-                       omap2_mcspi_dma_tx_callback, spi,
-                       &mcspi_dma->dma_tx_channel)) {
-               omap_free_dma(mcspi_dma->dma_rx_channel);
-               mcspi_dma->dma_rx_channel = -1;
-               dev_err(&spi->dev, "no TX DMA channel for McSPI\n");
+       sig = mcspi_dma->dma_tx_sync_dev;
+       mcspi_dma->dma_tx = dma_request_channel(mask, omap_dma_filter_fn, &sig);
+       if (!mcspi_dma->dma_tx) {
+               dev_err(&spi->dev, "no TX DMA engine channel for McSPI\n");
+               dma_release_channel(mcspi_dma->dma_rx);
+               mcspi_dma->dma_rx = NULL;
                return -EAGAIN;
        }
  
-       init_completion(&mcspi_dma->dma_rx_completion);
-       init_completion(&mcspi_dma->dma_tx_completion);
        return 0;
  }
  
@@@ -814,8 -840,7 +842,7 @@@ static int omap2_mcspi_setup(struct spi
                list_add_tail(&cs->node, &ctx->cs);
        }
  
-       if (mcspi_dma->dma_rx_channel == -1
-                       || mcspi_dma->dma_tx_channel == -1) {
+       if (!mcspi_dma->dma_rx || !mcspi_dma->dma_tx) {
                ret = omap2_mcspi_request_dma(spi);
                if (ret < 0)
                        return ret;
@@@ -850,13 -875,13 +877,13 @@@ static void omap2_mcspi_cleanup(struct 
        if (spi->chip_select < spi->master->num_chipselect) {
                mcspi_dma = &mcspi->dma_channels[spi->chip_select];
  
-               if (mcspi_dma->dma_rx_channel != -1) {
-                       omap_free_dma(mcspi_dma->dma_rx_channel);
-                       mcspi_dma->dma_rx_channel = -1;
+               if (mcspi_dma->dma_rx) {
+                       dma_release_channel(mcspi_dma->dma_rx);
+                       mcspi_dma->dma_rx = NULL;
                }
-               if (mcspi_dma->dma_tx_channel != -1) {
-                       omap_free_dma(mcspi_dma->dma_tx_channel);
-                       mcspi_dma->dma_tx_channel = -1;
+               if (mcspi_dma->dma_tx) {
+                       dma_release_channel(mcspi_dma->dma_tx);
+                       mcspi_dma->dma_tx = NULL;
                }
        }
  }
@@@ -1034,7 -1059,7 +1061,7 @@@ static int omap2_mcspi_transfer_one_mes
        return 0;
  }
  
 -static int __init omap2_mcspi_master_setup(struct omap2_mcspi *mcspi)
 +static int __devinit omap2_mcspi_master_setup(struct omap2_mcspi *mcspi)
  {
        struct spi_master       *master = mcspi->master;
        struct omap2_mcspi_regs *ctx = &mcspi->ctx;
@@@ -1176,7 -1201,6 +1203,6 @@@ static int __devinit omap2_mcspi_probe(
                        break;
                }
  
-               mcspi->dma_channels[i].dma_rx_channel = -1;
                mcspi->dma_channels[i].dma_rx_sync_dev = dma_res->start;
                sprintf(dma_ch_name, "tx%d", i);
                dma_res = platform_get_resource_byname(pdev, IORESOURCE_DMA,
                        break;
                }
  
-               mcspi->dma_channels[i].dma_tx_channel = -1;
                mcspi->dma_channels[i].dma_tx_sync_dev = dma_res->start;
        }