]> git.proxmox.com Git - mirror_ubuntu-artful-kernel.git/commitdiff
Merge tag 'for-linus-3.4' of git://git.infradead.org/mtd-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Sat, 31 Mar 2012 00:31:56 +0000 (17:31 -0700)
committerLinus Torvalds <torvalds@linux-foundation.org>
Sat, 31 Mar 2012 00:31:56 +0000 (17:31 -0700)
Pull MTD changes from David Woodhouse:
 - Artem's cleanup of the MTD API continues apace.
 - Fixes and improvements for ST FSMC and SuperH FLCTL NAND, amongst
   others.
 - More work on DiskOnChip G3, new driver for DiskOnChip G4.
 - Clean up debug/warning printks in JFFS2 to use pr_<level>.

Fix up various trivial conflicts, largely due to changes in calling
conventions for things like dmaengine_prep_slave_sg() (new inline
wrapper to hide new parameter, clashing with rewrite of previously last
parameter that used to be an 'append' flag, and is now a bitmap of
'unsigned long flags').

(Also some header file fallout - like so many merges this merge window -
and silly conflicts with sparse fixes)

* tag 'for-linus-3.4' of git://git.infradead.org/mtd-2.6: (120 commits)
  mtd: docg3 add protection against concurrency
  mtd: docg3 refactor cascade floors structure
  mtd: docg3 increase write/erase timeout
  mtd: docg3 fix inbound calculations
  mtd: nand: gpmi: fix function annotations
  mtd: phram: fix section mismatch for phram_setup
  mtd: unify initialization of erase_info->fail_addr
  mtd: support ONFI multi lun NAND
  mtd: sm_ftl: fix typo in major number.
  mtd: add device-tree support to spear_smi
  mtd: spear_smi: Remove default partition information from driver
  mtd: Add device-tree support to fsmc_nand
  mtd: fix section mismatch for doc_probe_device
  mtd: nand/fsmc: Remove sparse warnings and errors
  mtd: nand/fsmc: Add DMA support
  mtd: nand/fsmc: Access the NAND device word by word whenever possible
  mtd: nand/fsmc: Use dev_err to report error scenario
  mtd: nand/fsmc: Use devm routines
  mtd: nand/fsmc: Modify fsmc driver to accept nand timing parameters via platform
  mtd: fsmc_nand: add pm callbacks to support hibernation
  ...

24 files changed:
1  2 
arch/arm/mach-omap1/flash.c
arch/arm/mach-s3c24xx/simtec-nor.c
arch/arm/mach-shmobile/board-mackerel.c
arch/arm/mach-shmobile/clock-sh7372.c
arch/arm/mach-u300/core.c
arch/arm/mach-u300/include/mach/u300-regs.h
drivers/dma/mxs-dma.c
drivers/mmc/host/mxs-mmc.c
drivers/mtd/Kconfig
drivers/mtd/chips/cfi_cmdset_0001.c
drivers/mtd/devices/Kconfig
drivers/mtd/devices/pmc551.c
drivers/mtd/devices/slram.c
drivers/mtd/maps/pcmciamtd.c
drivers/mtd/mtdchar.c
drivers/mtd/nand/Kconfig
drivers/mtd/nand/Makefile
drivers/mtd/nand/atmel_nand.c
drivers/mtd/nand/bcm_umi_nand.c
drivers/mtd/nand/gpmi-nand/gpmi-lib.c
drivers/net/ethernet/sfc/mtd.c
fs/jffs2/fs.c
sound/soc/mxs/mxs-pcm.c
sound/soc/mxs/mxs-saif.c

index f9bf78d4fdfb9681dd38f534477335f0617b9206,4665bfcd2ce973fcdb35d64a3c6375df110a56d2..401eb3c080c2f325de709d805aac2fc9f260c9f2
@@@ -6,31 -6,21 +6,23 @@@
   * published by the Free Software Foundation.
   */
  
 +#include <linux/io.h>
  #include <linux/mtd/mtd.h>
  #include <linux/mtd/map.h>
  
 -#include <plat/io.h>
  #include <plat/tc.h>
  #include <plat/flash.h>
  
 +#include <mach/hardware.h>
 +
  void omap1_set_vpp(struct platform_device *pdev, int enable)
  {
-       static int count;
        u32 l;
  
-       if (enable) {
-               if (count++ == 0) {
-                       l = omap_readl(EMIFS_CONFIG);
-                       l |= OMAP_EMIFS_CONFIG_WP;
-                       omap_writel(l, EMIFS_CONFIG);
-               }
-       } else {
-               if (count && (--count == 0)) {
-                       l = omap_readl(EMIFS_CONFIG);
-                       l &= ~OMAP_EMIFS_CONFIG_WP;
-                       omap_writel(l, EMIFS_CONFIG);
-               }
-       }
+       l = omap_readl(EMIFS_CONFIG);
+       if (enable)
+               l |= OMAP_EMIFS_CONFIG_WP;
+       else
+               l &= ~OMAP_EMIFS_CONFIG_WP;
+       omap_writel(l, EMIFS_CONFIG);
  }
index 2119ca6a73bc9c5f0c43fd52796a3ad662ba4cd6,0000000000000000000000000000000000000000..b9d6d4f92c034c461ee04af9f3632c6342feeb54
mode 100644,000000..100644
--- /dev/null
@@@ -1,87 -1,0 +1,84 @@@
-       unsigned long flags;
 +/* linux/arch/arm/mach-s3c2410/nor-simtec.c
 + *
 + * Copyright (c) 2008 Simtec Electronics
 + *    http://armlinux.simtec.co.uk/
 + *    Ben Dooks <ben@simtec.co.uk>
 + *
 + * Simtec NOR mapping
 + *
 + * This program is free software; you can redistribute it and/or modify
 + * it under the terms of the GNU General Public License version 2 as
 + * published by the Free Software Foundation.
 +*/
 +
 +#include <linux/module.h>
 +#include <linux/types.h>
 +#include <linux/init.h>
 +#include <linux/kernel.h>
 +#include <linux/platform_device.h>
 +
 +#include <linux/mtd/mtd.h>
 +#include <linux/mtd/map.h>
 +#include <linux/mtd/physmap.h>
 +#include <linux/mtd/partitions.h>
 +
 +#include <asm/mach/arch.h>
 +#include <asm/mach/map.h>
 +#include <asm/mach/irq.h>
 +
 +#include <mach/map.h>
 +#include <mach/bast-map.h>
 +#include <mach/bast-cpld.h>
 +
 +#include "simtec.h"
 +
 +static void simtec_nor_vpp(struct platform_device *pdev, int vpp)
 +{
 +      unsigned int val;
-       local_irq_save(flags);
 +
-       local_irq_restore(flags);
 +      val = __raw_readb(BAST_VA_CTRL3);
 +
 +      printk(KERN_DEBUG "%s(%d)\n", __func__, vpp);
 +
 +      if (vpp)
 +              val |= BAST_CPLD_CTRL3_ROMWEN;
 +      else
 +              val &= ~BAST_CPLD_CTRL3_ROMWEN;
 +
 +      __raw_writeb(val, BAST_VA_CTRL3);
 +}
 +
 +static struct physmap_flash_data simtec_nor_pdata = {
 +      .width          = 2,
 +      .set_vpp        = simtec_nor_vpp,
 +      .nr_parts       = 0,
 +};
 +
 +static struct resource simtec_nor_resource[] = {
 +      [0] = {
 +              .start = S3C2410_CS1 + 0x4000000,
 +              .end   = S3C2410_CS1 + 0x4000000 + SZ_8M - 1,
 +              .flags = IORESOURCE_MEM,
 +      }
 +};
 +
 +static struct platform_device simtec_device_nor = {
 +      .name           = "physmap-flash",
 +      .id             = -1,
 +      .num_resources  = ARRAY_SIZE(simtec_nor_resource),
 +      .resource       = simtec_nor_resource,
 +      .dev            = {
 +              .platform_data = &simtec_nor_pdata,
 +      },
 +};
 +
 +void __init nor_simtec_init(void)
 +{
 +      int ret;
 +
 +      ret = platform_device_register(&simtec_device_nor);
 +      if (ret < 0)
 +              printk(KERN_ERR "failed to register physmap-flash device\n");
 +      else
 +              simtec_nor_vpp(NULL, 1);
 +}
index a125d4e114ec53db0500632fa7d8addaa5d99bee,8758f9453fdd6ff0a9a04b9fbaf789723a1b7c3b..f49e28abe0abe59d987aec558d357dd78e2ec7f3
@@@ -39,6 -39,7 +39,7 @@@
  #include <linux/mtd/mtd.h>
  #include <linux/mtd/partitions.h>
  #include <linux/mtd/physmap.h>
+ #include <linux/mtd/sh_flctl.h>
  #include <linux/pm_clock.h>
  #include <linux/smsc911x.h>
  #include <linux/sh_intc.h>
  #include <sound/sh_fsi.h>
  
  #include <mach/common.h>
 +#include <mach/irqs.h>
  #include <mach/sh7372.h>
  
  #include <asm/mach/arch.h>
 -#include <asm/mach/time.h>
 -#include <asm/mach/map.h>
  #include <asm/mach-types.h>
  
  /*
@@@ -317,14 -319,8 +318,14 @@@ static struct sh_mobile_meram_info mack
  
  static struct resource meram_resources[] = {
        [0] = {
 -              .name   = "MERAM",
 +              .name   = "regs",
                .start  = 0xe8000000,
 +              .end    = 0xe807ffff,
 +              .flags  = IORESOURCE_MEM,
 +      },
 +      [1] = {
 +              .name   = "meram",
 +              .start  = 0xe8080000,
                .end    = 0xe81fffff,
                .flags  = IORESOURCE_MEM,
        },
@@@ -356,23 -352,29 +357,23 @@@ static struct fb_videomode mackerel_lcd
        },
  };
  
 -static int mackerel_set_brightness(void *board_data, int brightness)
 +static int mackerel_set_brightness(int brightness)
  {
        gpio_set_value(GPIO_PORT31, brightness);
  
        return 0;
  }
  
 -static int mackerel_get_brightness(void *board_data)
 +static int mackerel_get_brightness(void)
  {
        return gpio_get_value(GPIO_PORT31);
  }
  
 -static struct sh_mobile_meram_cfg lcd_meram_cfg = {
 +static const struct sh_mobile_meram_cfg lcd_meram_cfg = {
        .icb[0] = {
 -              .marker_icb     = 28,
 -              .cache_icb      = 24,
 -              .meram_offset   = 0x0,
                .meram_size     = 0x40,
        },
        .icb[1] = {
 -              .marker_icb     = 29,
 -              .cache_icb      = 25,
 -              .meram_offset   = 0x40,
                .meram_size     = 0x40,
        },
  };
@@@ -383,20 -385,20 +384,20 @@@ static struct sh_mobile_lcdc_info lcdc_
        .ch[0] = {
                .chan = LCDC_CHAN_MAINLCD,
                .fourcc = V4L2_PIX_FMT_RGB565,
 -              .lcd_cfg = mackerel_lcdc_modes,
 -              .num_cfg = ARRAY_SIZE(mackerel_lcdc_modes),
 +              .lcd_modes = mackerel_lcdc_modes,
 +              .num_modes = ARRAY_SIZE(mackerel_lcdc_modes),
                .interface_type         = RGB24,
                .clock_divider          = 3,
                .flags                  = 0,
 -              .lcd_size_cfg.width     = 152,
 -              .lcd_size_cfg.height    = 91,
 -              .board_cfg = {
 -                      .set_brightness = mackerel_set_brightness,
 -                      .get_brightness = mackerel_get_brightness,
 +              .panel_cfg = {
 +                      .width          = 152,
 +                      .height         = 91,
                },
                .bl_info = {
                        .name = "sh_mobile_lcdc_bl",
                        .max_brightness = 1,
 +                      .set_brightness = mackerel_set_brightness,
 +                      .get_brightness = mackerel_get_brightness,
                },
                .meram_cfg = &lcd_meram_cfg,
        }
@@@ -425,44 -427,21 +426,44 @@@ static struct platform_device lcdc_devi
        },
  };
  
 -static struct sh_mobile_meram_cfg hdmi_meram_cfg = {
 +/* HDMI */
 +static struct sh_mobile_hdmi_info hdmi_info = {
 +      .flags          = HDMI_SND_SRC_SPDIF,
 +};
 +
 +static struct resource hdmi_resources[] = {
 +      [0] = {
 +              .name   = "HDMI",
 +              .start  = 0xe6be0000,
 +              .end    = 0xe6be00ff,
 +              .flags  = IORESOURCE_MEM,
 +      },
 +      [1] = {
 +              /* There's also an HDMI interrupt on INTCS @ 0x18e0 */
 +              .start  = evt2irq(0x17e0),
 +              .flags  = IORESOURCE_IRQ,
 +      },
 +};
 +
 +static struct platform_device hdmi_device = {
 +      .name           = "sh-mobile-hdmi",
 +      .num_resources  = ARRAY_SIZE(hdmi_resources),
 +      .resource       = hdmi_resources,
 +      .id             = -1,
 +      .dev    = {
 +              .platform_data  = &hdmi_info,
 +      },
 +};
 +
 +static const struct sh_mobile_meram_cfg hdmi_meram_cfg = {
        .icb[0] = {
 -              .marker_icb     = 30,
 -              .cache_icb      = 26,
 -              .meram_offset   = 0x80,
                .meram_size     = 0x100,
        },
        .icb[1] = {
 -              .marker_icb     = 31,
 -              .cache_icb      = 27,
 -              .meram_offset   = 0x180,
                .meram_size     = 0x100,
        },
  };
 -/* HDMI */
 +
  static struct sh_mobile_lcdc_info hdmi_lcdc_info = {
        .meram_dev = &mackerel_meram_info,
        .clock_source = LCDC_CLK_EXTERNAL,
                .clock_divider = 1,
                .flags = LCDC_FLAGS_DWPOL,
                .meram_cfg = &hdmi_meram_cfg,
 +              .tx_dev = &hdmi_device,
        }
  };
  
@@@ -501,6 -479,36 +502,6 @@@ static struct platform_device hdmi_lcdc
        },
  };
  
 -static struct sh_mobile_hdmi_info hdmi_info = {
 -      .lcd_chan       = &hdmi_lcdc_info.ch[0],
 -      .lcd_dev        = &hdmi_lcdc_device.dev,
 -      .flags          = HDMI_SND_SRC_SPDIF,
 -};
 -
 -static struct resource hdmi_resources[] = {
 -      [0] = {
 -              .name   = "HDMI",
 -              .start  = 0xe6be0000,
 -              .end    = 0xe6be00ff,
 -              .flags  = IORESOURCE_MEM,
 -      },
 -      [1] = {
 -              /* There's also an HDMI interrupt on INTCS @ 0x18e0 */
 -              .start  = evt2irq(0x17e0),
 -              .flags  = IORESOURCE_IRQ,
 -      },
 -};
 -
 -static struct platform_device hdmi_device = {
 -      .name           = "sh-mobile-hdmi",
 -      .num_resources  = ARRAY_SIZE(hdmi_resources),
 -      .resource       = hdmi_resources,
 -      .id             = -1,
 -      .dev    = {
 -              .platform_data  = &hdmi_info,
 -      },
 -};
 -
  static struct platform_device fsi_hdmi_device = {
        .name           = "sh_fsi2_b_hdmi",
  };
@@@ -853,7 -861,7 +854,7 @@@ static int __fsi_set_round_rate(struct 
        return clk_enable(clk);
  }
  
 -static int fsi_set_rate(struct device *dev, int is_porta, int rate, int enable)
 +static int fsi_b_set_rate(struct device *dev, int rate, int enable)
  {
        struct clk *fsib_clk;
        struct clk *fdiv_clk = &sh7372_fsidivb_clk;
        int ackmd_bpfmd;
        int ret;
  
 -      /* FSIA is slave mode. nothing to do here */
 -      if (is_porta)
 -              return 0;
 -
        /* clock start */
        switch (rate) {
        case 44100:
@@@ -905,16 -917,14 +906,16 @@@ fsi_set_rate_end
  }
  
  static struct sh_fsi_platform_info fsi_info = {
 -      .porta_flags =  SH_FSI_BRS_INV,
 -
 -      .portb_flags =  SH_FSI_BRS_INV  |
 +      .port_a = {
 +              .flags = SH_FSI_BRS_INV,
 +      },
 +      .port_b = {
 +              .flags = SH_FSI_BRS_INV |
                        SH_FSI_BRM_INV  |
                        SH_FSI_LRS_INV  |
                        SH_FSI_FMT_SPDIF,
 -
 -      .set_rate = fsi_set_rate,
 +              .set_rate = fsi_b_set_rate,
 +      }
  };
  
  static struct resource fsi_resources[] = {
@@@ -956,6 -966,50 +957,50 @@@ static struct platform_device fsi_ak464
        },
  };
  
+ /* FLCTL */
+ static struct mtd_partition nand_partition_info[] = {
+       {
+               .name   = "system",
+               .offset = 0,
+               .size   = 128 * 1024 * 1024,
+       },
+       {
+               .name   = "userdata",
+               .offset = MTDPART_OFS_APPEND,
+               .size   = 256 * 1024 * 1024,
+       },
+       {
+               .name   = "cache",
+               .offset = MTDPART_OFS_APPEND,
+               .size   = 128 * 1024 * 1024,
+       },
+ };
+ static struct resource nand_flash_resources[] = {
+       [0] = {
+               .start  = 0xe6a30000,
+               .end    = 0xe6a3009b,
+               .flags  = IORESOURCE_MEM,
+       }
+ };
+ static struct sh_flctl_platform_data nand_flash_data = {
+       .parts          = nand_partition_info,
+       .nr_parts       = ARRAY_SIZE(nand_partition_info),
+       .flcmncr_val    = CLK_16B_12L_4H | TYPESEL_SET
+                       | SHBUSSEL | SEL_16BIT | SNAND_E,
+       .use_holden     = 1,
+ };
+ static struct platform_device nand_flash_device = {
+       .name           = "sh_flctl",
+       .resource       = nand_flash_resources,
+       .num_resources  = ARRAY_SIZE(nand_flash_resources),
+       .dev            = {
+               .platform_data = &nand_flash_data,
+       },
+ };
  /*
   * The card detect pin of the top SD/MMC slot (CN7) is active low and is
   * connected to GPIO A22 of SH7372 (GPIO_PORT41).
@@@ -1259,6 -1313,7 +1304,7 @@@ static struct platform_device *mackerel
        &fsi_device,
        &fsi_ak4643_device,
        &fsi_hdmi_device,
+       &nand_flash_device,
        &sdhi0_device,
  #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
        &sdhi1_device,
        &sh_mmcif_device,
        &ceu_device,
        &mackerel_camera,
 -      &hdmi_lcdc_device,
        &hdmi_device,
 +      &hdmi_lcdc_device,
        &meram_device,
  };
  
@@@ -1328,6 -1383,27 +1374,6 @@@ static struct i2c_board_info i2c1_devic
        },
  };
  
 -static struct map_desc mackerel_io_desc[] __initdata = {
 -      /* create a 1:1 entity map for 0xe6xxxxxx
 -       * used by CPGA, INTC and PFC.
 -       */
 -      {
 -              .virtual        = 0xe6000000,
 -              .pfn            = __phys_to_pfn(0xe6000000),
 -              .length         = 256 << 20,
 -              .type           = MT_DEVICE_NONSHARED
 -      },
 -};
 -
 -static void __init mackerel_map_io(void)
 -{
 -      iotable_init(mackerel_io_desc, ARRAY_SIZE(mackerel_io_desc));
 -
 -      /* setup early devices and console here as well */
 -      sh7372_add_early_devices();
 -      shmobile_setup_console();
 -}
 -
  #define GPIO_PORT9CR  0xE6051009
  #define GPIO_PORT10CR 0xE605100A
  #define GPIO_PORT167CR        0xE60520A7
@@@ -1340,9 -1416,6 +1386,9 @@@ static void __init mackerel_init(void
        struct clk *clk;
        int ret;
  
 +      /* External clock source */
 +      clk_set_rate(&sh7372_dv_clki_clk, 27000000);
 +
        sh7372_pinmux_init();
  
        /* enable SCIFA0 */
        gpio_request(GPIO_FN_MMCCMD0, NULL);
        gpio_request(GPIO_FN_MMCCLK0, NULL);
  
+       /* FLCTL */
+       gpio_request(GPIO_FN_D0_NAF0, NULL);
+       gpio_request(GPIO_FN_D1_NAF1, NULL);
+       gpio_request(GPIO_FN_D2_NAF2, NULL);
+       gpio_request(GPIO_FN_D3_NAF3, NULL);
+       gpio_request(GPIO_FN_D4_NAF4, NULL);
+       gpio_request(GPIO_FN_D5_NAF5, NULL);
+       gpio_request(GPIO_FN_D6_NAF6, NULL);
+       gpio_request(GPIO_FN_D7_NAF7, NULL);
+       gpio_request(GPIO_FN_D8_NAF8, NULL);
+       gpio_request(GPIO_FN_D9_NAF9, NULL);
+       gpio_request(GPIO_FN_D10_NAF10, NULL);
+       gpio_request(GPIO_FN_D11_NAF11, NULL);
+       gpio_request(GPIO_FN_D12_NAF12, NULL);
+       gpio_request(GPIO_FN_D13_NAF13, NULL);
+       gpio_request(GPIO_FN_D14_NAF14, NULL);
+       gpio_request(GPIO_FN_D15_NAF15, NULL);
+       gpio_request(GPIO_FN_FCE0, NULL);
+       gpio_request(GPIO_FN_WE0_FWE, NULL);
+       gpio_request(GPIO_FN_FRB, NULL);
+       gpio_request(GPIO_FN_A4_FOE, NULL);
+       gpio_request(GPIO_FN_A5_FCDE, NULL);
+       gpio_request(GPIO_FN_RD_FSC, NULL);
        /* enable GPS module (GT-720F) */
        gpio_request(GPIO_FN_SCIFA2_TXD1, NULL);
        gpio_request(GPIO_FN_SCIFA2_RXD1, NULL);
        sh7372_add_device_to_domain(&sh7372_a4mp, &fsi_device);
        sh7372_add_device_to_domain(&sh7372_a3sp, &usbhs0_device);
        sh7372_add_device_to_domain(&sh7372_a3sp, &usbhs1_device);
+       sh7372_add_device_to_domain(&sh7372_a3sp, &nand_flash_device);
        sh7372_add_device_to_domain(&sh7372_a3sp, &sh_mmcif_device);
        sh7372_add_device_to_domain(&sh7372_a3sp, &sdhi0_device);
  #if !defined(CONFIG_MMC_SH_MMCIF) && !defined(CONFIG_MMC_SH_MMCIF_MODULE)
        pm_clk_add(&hdmi_lcdc_device.dev, "hdmi");
  }
  
 -static void __init mackerel_timer_init(void)
 -{
 -      sh7372_clock_init();
 -      shmobile_timer.init();
 -
 -      /* External clock source */
 -      clk_set_rate(&sh7372_dv_clki_clk, 27000000);
 -}
 -
 -static struct sys_timer mackerel_timer = {
 -      .init           = mackerel_timer_init,
 -};
 -
  MACHINE_START(MACKEREL, "mackerel")
 -      .map_io         = mackerel_map_io,
 +      .map_io         = sh7372_map_io,
 +      .init_early     = sh7372_add_early_devices,
        .init_irq       = sh7372_init_irq,
        .handle_irq     = shmobile_handle_irq_intc,
        .init_machine   = mackerel_init,
 -      .timer          = &mackerel_timer,
 +      .timer          = &shmobile_timer,
  MACHINE_END
index de243e3c83929311753e47f0dc1dc1d495e88761,b692ad3d13a577b361abda3453f5ed7e54792100..94d1f88246d3fc780267ad698b9d43e73c339eaa
@@@ -89,7 -89,7 +89,7 @@@ static unsigned long div2_recalc(struc
        return clk->parent->rate / 2;
  }
  
 -static struct clk_ops div2_clk_ops = {
 +static struct sh_clk_ops div2_clk_ops = {
        .recalc         = div2_recalc,
  };
  
@@@ -128,7 -128,7 +128,7 @@@ static unsigned long pllc01_recalc(stru
        return clk->parent->rate * mult;
  }
  
 -static struct clk_ops pllc01_clk_ops = {
 +static struct sh_clk_ops pllc01_clk_ops = {
        .recalc         = pllc01_recalc,
  };
  
@@@ -276,7 -276,7 +276,7 @@@ static int pllc2_set_parent(struct clk 
        return 0;
  }
  
 -static struct clk_ops pllc2_clk_ops = {
 +static struct sh_clk_ops pllc2_clk_ops = {
        .recalc         = pllc2_recalc,
        .round_rate     = pllc2_round_rate,
        .set_rate       = pllc2_set_rate,
@@@ -468,7 -468,7 +468,7 @@@ static int fsidiv_set_rate(struct clk *
        return 0;
  }
  
 -static struct clk_ops fsidiv_clk_ops = {
 +static struct sh_clk_ops fsidiv_clk_ops = {
        .recalc         = fsidiv_recalc,
        .round_rate     = fsidiv_round_rate,
        .set_rate       = fsidiv_set_rate,
@@@ -511,7 -511,7 +511,7 @@@ enum { MSTP001, MSTP000
         MSTP223,
         MSTP218, MSTP217, MSTP216, MSTP214, MSTP208, MSTP207,
         MSTP206, MSTP205, MSTP204, MSTP203, MSTP202, MSTP201, MSTP200,
-        MSTP328, MSTP323, MSTP322, MSTP314, MSTP313, MSTP312,
+       MSTP328, MSTP323, MSTP322, MSTP315, MSTP314, MSTP313, MSTP312,
         MSTP423, MSTP415, MSTP413, MSTP411, MSTP410, MSTP407, MSTP406,
         MSTP405, MSTP404, MSTP403, MSTP400,
         MSTP_NR };
@@@ -553,6 -553,7 +553,7 @@@ static struct clk mstp_clks[MSTP_NR] = 
        [MSTP328] = MSTP(&div6_clks[DIV6_SPU], SMSTPCR3, 28, 0), /* FSI2 */
        [MSTP323] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 23, 0), /* IIC1 */
        [MSTP322] = MSTP(&div6_clks[DIV6_SUB], SMSTPCR3, 22, 0), /* USB0 */
+       [MSTP315] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 15, 0), /* FLCTL*/
        [MSTP314] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 14, 0), /* SDHI0 */
        [MSTP313] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 13, 0), /* SDHI1 */
        [MSTP312] = MSTP(&div4_clks[DIV4_HP], SMSTPCR3, 12, 0), /* MMC */
@@@ -653,6 -654,7 +654,7 @@@ static struct clk_lookup lookups[] = 
        CLKDEV_DEV_ID("r8a66597_hcd.0", &mstp_clks[MSTP322]), /* USB0 */
        CLKDEV_DEV_ID("r8a66597_udc.0", &mstp_clks[MSTP322]), /* USB0 */
        CLKDEV_DEV_ID("renesas_usbhs.0", &mstp_clks[MSTP322]), /* USB0 */
+       CLKDEV_DEV_ID("sh_flctl.0", &mstp_clks[MSTP315]), /* FLCTL */
        CLKDEV_DEV_ID("sh_mobile_sdhi.0", &mstp_clks[MSTP314]), /* SDHI0 */
        CLKDEV_DEV_ID("sh_mobile_sdhi.1", &mstp_clks[MSTP313]), /* SDHI1 */
        CLKDEV_DEV_ID("sh_mmcif.0", &mstp_clks[MSTP312]), /* MMC */
@@@ -710,7 -712,7 +712,7 @@@ void __init sh7372_clock_init(void
        clkdev_add_table(lookups, ARRAY_SIZE(lookups));
  
        if (!ret)
 -              clk_init();
 +              shmobile_clk_init();
        else
                panic("failed to setup sh7372 clocks\n");
  
index 8b90c44d237f92d2afcb261cf698500979842fea,9c3bafd48cda2fb1b76c35ed62bbc51c78dd7ebf..1621ad07d284fea97626fea99a3e5535844c8417
@@@ -18,7 -18,6 +18,7 @@@
  #include <linux/termios.h>
  #include <linux/dmaengine.h>
  #include <linux/amba/bus.h>
 +#include <linux/amba/mmci.h>
  #include <linux/amba/serial.h>
  #include <linux/platform_device.h>
  #include <linux/gpio.h>
@@@ -27,8 -26,7 +27,8 @@@
  #include <linux/mtd/nand.h>
  #include <linux/mtd/fsmc.h>
  #include <linux/pinctrl/machine.h>
 -#include <linux/pinctrl/pinmux.h>
 +#include <linux/pinctrl/consumer.h>
 +#include <linux/pinctrl/pinconf-generic.h>
  #include <linux/dma-mapping.h>
  
  #include <asm/types.h>
@@@ -45,9 -43,9 +45,9 @@@
  #include <mach/gpio-u300.h>
  
  #include "clock.h"
 -#include "mmc.h"
  #include "spi.h"
  #include "i2c.h"
 +#include "u300-gpio.h"
  
  /*
   * Static I/O mappings that are needed for booting the U300 platforms. The
@@@ -96,9 -94,19 +96,9 @@@ static struct amba_pl011_data uart0_pla
  #endif
  };
  
 -static struct amba_device uart0_device = {
 -      .dev = {
 -              .coherent_dma_mask = ~0,
 -              .init_name = "uart0", /* Slow device at 0x3000 offset */
 -              .platform_data = &uart0_plat_data,
 -      },
 -      .res = {
 -              .start = U300_UART0_BASE,
 -              .end   = U300_UART0_BASE + SZ_4K - 1,
 -              .flags = IORESOURCE_MEM,
 -      },
 -      .irq = { IRQ_U300_UART0, NO_IRQ },
 -};
 +/* Slow device at 0x3000 offset */
 +static AMBA_APB_DEVICE(uart0, "uart0", 0, U300_UART0_BASE,
 +      { IRQ_U300_UART0 }, &uart0_plat_data);
  
  /* The U335 have an additional UART1 on the APP CPU */
  #ifdef CONFIG_MACH_U300_BS335
@@@ -110,42 -118,72 +110,42 @@@ static struct amba_pl011_data uart1_pla
  #endif
  };
  
 -static struct amba_device uart1_device = {
 -      .dev = {
 -              .coherent_dma_mask = ~0,
 -              .init_name = "uart1", /* Fast device at 0x7000 offset */
 -              .platform_data = &uart1_plat_data,
 -      },
 -      .res = {
 -              .start = U300_UART1_BASE,
 -              .end   = U300_UART1_BASE + SZ_4K - 1,
 -              .flags = IORESOURCE_MEM,
 -      },
 -      .irq = { IRQ_U300_UART1, NO_IRQ },
 -};
 +/* Fast device at 0x7000 offset */
 +static AMBA_APB_DEVICE(uart1, "uart1", 0, U300_UART1_BASE,
 +      { IRQ_U300_UART1 }, &uart1_plat_data);
  #endif
  
 -static struct amba_device pl172_device = {
 -      .dev = {
 -              .init_name = "pl172", /* AHB device at 0x4000 offset */
 -              .platform_data = NULL,
 -      },
 -      .res = {
 -              .start = U300_EMIF_CFG_BASE,
 -              .end   = U300_EMIF_CFG_BASE + SZ_4K - 1,
 -              .flags = IORESOURCE_MEM,
 -      },
 -};
 +/* AHB device at 0x4000 offset */
 +static AMBA_APB_DEVICE(pl172, "pl172", 0, U300_EMIF_CFG_BASE, { }, NULL);
  
 +/* Fast device at 0x6000 offset */
 +static AMBA_APB_DEVICE(pl022, "pl022", 0, U300_SPI_BASE,
 +      { IRQ_U300_SPI }, NULL);
  
 -/*
 - * Everything within this next ifdef deals with external devices connected to
 - * the APP SPI bus.
 - */
 -static struct amba_device pl022_device = {
 -      .dev = {
 -              .coherent_dma_mask = ~0,
 -              .init_name = "pl022", /* Fast device at 0x6000 offset */
 -      },
 -      .res = {
 -              .start = U300_SPI_BASE,
 -              .end   = U300_SPI_BASE + SZ_4K - 1,
 -              .flags = IORESOURCE_MEM,
 -      },
 -      .irq = {IRQ_U300_SPI, NO_IRQ },
 -      /*
 -       * This device has a DMA channel but the Linux driver does not use
 -       * it currently.
 -       */
 -};
 +/* Fast device at 0x1000 offset */
 +#define U300_MMCSD_IRQS       { IRQ_U300_MMCSD_MCIINTR0, IRQ_U300_MMCSD_MCIINTR1 }
  
 -static struct amba_device mmcsd_device = {
 -      .dev = {
 -              .init_name = "mmci", /* Fast device at 0x1000 offset */
 -              .platform_data = NULL, /* Added later */
 -      },
 -      .res = {
 -              .start = U300_MMCSD_BASE,
 -              .end   = U300_MMCSD_BASE + SZ_4K - 1,
 -              .flags = IORESOURCE_MEM,
 -      },
 -      .irq = {IRQ_U300_MMCSD_MCIINTR0, IRQ_U300_MMCSD_MCIINTR1 },
 +static struct mmci_platform_data mmcsd_platform_data = {
        /*
 -       * This device has a DMA channel but the Linux driver does not use
 -       * it currently.
 +       * Do not set ocr_mask or voltage translation function,
 +       * we have a regulator we can control instead.
         */
 +      .f_max = 24000000,
 +      .gpio_wp = -1,
 +      .gpio_cd = U300_GPIO_PIN_MMC_CD,
 +      .cd_invert = true,
 +      .capabilities = MMC_CAP_MMC_HIGHSPEED |
 +      MMC_CAP_SD_HIGHSPEED | MMC_CAP_4_BIT_DATA | MMC_CAP_8_BIT_DATA,
 +#ifdef CONFIG_COH901318
 +      .dma_filter = coh901318_filter_id,
 +      .dma_rx_param = (void *) U300_DMA_MMCSD_RX_TX,
 +      /* Don't specify a TX channel, this RX channel is bidirectional */
 +#endif
  };
  
 +static AMBA_APB_DEVICE(mmcsd, "mmci", 0, U300_MMCSD_BASE,
 +      U300_MMCSD_IRQS, &mmcsd_platform_data);
 +
  /*
   * The order of device declaration may be important, since some devices
   * have dependencies on other devices being initialized first.
@@@ -1439,7 -1477,7 +1439,7 @@@ static struct coh901318_platform coh901
        .max_channels = U300_DMA_CHANNELS,
  };
  
 -static struct resource pinmux_resources[] = {
 +static struct resource pinctrl_resources[] = {
        {
                .start = U300_SYSCON_BASE,
                .end   = U300_SYSCON_BASE + SZ_4K - 1,
@@@ -1468,13 -1506,6 +1468,13 @@@ static struct platform_device i2c1_devi
        .resource = i2c1_resources,
  };
  
 +static struct platform_device pinctrl_device = {
 +      .name = "pinctrl-u300",
 +      .id = -1,
 +      .num_resources = ARRAY_SIZE(pinctrl_resources),
 +      .resource = pinctrl_resources,
 +};
 +
  /*
   * The different variants have a few different versions of the
   * GPIO block, with different number of ports.
@@@ -1494,7 -1525,6 +1494,7 @@@ static struct u300_gpio_platform u300_g
  #endif
        .gpio_base = 0,
        .gpio_irq_base = IRQ_U300_GPIO_BASE,
 +      .pinctrl_device = &pinctrl_device,
  };
  
  static struct platform_device gpio_device = {
@@@ -1544,6 -1574,8 +1544,8 @@@ static struct fsmc_nand_platform_data n
        .nr_partitions = ARRAY_SIZE(u300_partitions),
        .options = NAND_SKIP_BBTSCAN,
        .width = FSMC_NAND_BW8,
+       .ale_off = PLAT_NAND_ALE,
+       .cle_off = PLAT_NAND_CLE,
  };
  
  static struct platform_device nand_device = {
@@@ -1567,67 -1599,71 +1569,67 @@@ static struct platform_device dma_devic
        },
  };
  
 -static struct platform_device pinmux_device = {
 -      .name = "pinmux-u300",
 -      .id = -1,
 -      .num_resources = ARRAY_SIZE(pinmux_resources),
 -      .resource = pinmux_resources,
 +static unsigned long pin_pullup_conf[] = {
 +      PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_UP, 1),
 +};
 +
 +static unsigned long pin_highz_conf[] = {
 +      PIN_CONF_PACKED(PIN_CONFIG_BIAS_HIGH_IMPEDANCE, 0),
  };
  
 -/* Pinmux settings */
 -static struct pinmux_map __initdata u300_pinmux_map[] = {
 +/* Pin control settings */
 +static struct pinctrl_map __initdata u300_pinmux_map[] = {
        /* anonymous maps for chip power and EMIFs */
 -      PINMUX_MAP_SYS_HOG("POWER", "pinmux-u300", "power"),
 -      PINMUX_MAP_SYS_HOG("EMIF0", "pinmux-u300", "emif0"),
 -      PINMUX_MAP_SYS_HOG("EMIF1", "pinmux-u300", "emif1"),
 +      PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "power"),
 +      PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "emif0"),
 +      PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "emif1"),
        /* per-device maps for MMC/SD, SPI and UART */
 -      PINMUX_MAP("MMCSD", "pinmux-u300", "mmc0", "mmci"),
 -      PINMUX_MAP("SPI", "pinmux-u300", "spi0", "pl022"),
 -      PINMUX_MAP("UART0", "pinmux-u300", "uart0", "uart0"),
 +      PIN_MAP_MUX_GROUP_DEFAULT("mmci",  "pinctrl-u300", NULL, "mmc0"),
 +      PIN_MAP_MUX_GROUP_DEFAULT("pl022", "pinctrl-u300", NULL, "spi0"),
 +      PIN_MAP_MUX_GROUP_DEFAULT("uart0", "pinctrl-u300", NULL, "uart0"),
 +      /* This pin is used for clock return rather than GPIO */
 +      PIN_MAP_CONFIGS_PIN_DEFAULT("mmci", "pinctrl-u300", "PIO APP GPIO 11",
 +                                  pin_pullup_conf),
 +      /* This pin is used for card detect */
 +      PIN_MAP_CONFIGS_PIN_DEFAULT("mmci", "pinctrl-u300", "PIO MS INS",
 +                                  pin_highz_conf),
  };
  
  struct u300_mux_hog {
 -      const char *name;
        struct device *dev;
 -      struct pinmux *pmx;
 +      struct pinctrl *p;
  };
  
  static struct u300_mux_hog u300_mux_hogs[] = {
        {
 -              .name = "uart0",
                .dev = &uart0_device.dev,
        },
        {
 -              .name = "spi0",
                .dev = &pl022_device.dev,
        },
        {
 -              .name = "mmc0",
                .dev = &mmcsd_device.dev,
        },
  };
  
 -static int __init u300_pinmux_fetch(void)
 +static int __init u300_pinctrl_fetch(void)
  {
        int i;
  
        for (i = 0; i < ARRAY_SIZE(u300_mux_hogs); i++) {
 -              struct pinmux *pmx;
 -              int ret;
 +              struct pinctrl *p;
  
 -              pmx = pinmux_get(u300_mux_hogs[i].dev, NULL);
 -              if (IS_ERR(pmx)) {
 -                      pr_err("u300: could not get pinmux hog %s\n",
 -                             u300_mux_hogs[i].name);
 -                      continue;
 -              }
 -              ret = pinmux_enable(pmx);
 -              if (ret) {
 -                      pr_err("u300: could enable pinmux hog %s\n",
 -                             u300_mux_hogs[i].name);
 +              p = pinctrl_get_select_default(u300_mux_hogs[i].dev);
 +              if (IS_ERR(p)) {
 +                      pr_err("u300: could not get pinmux hog for dev %s\n",
 +                             dev_name(u300_mux_hogs[i].dev));
                        continue;
                }
 -              u300_mux_hogs[i].pmx = pmx;
 +              u300_mux_hogs[i].p = p;
        }
        return 0;
  }
 -subsys_initcall(u300_pinmux_fetch);
 +subsys_initcall(u300_pinctrl_fetch);
  
  /*
   * Notice that AMBA devices are initialized before platform devices.
@@@ -1642,6 -1678,7 +1644,6 @@@ static struct platform_device *platform
        &gpio_device,
        &nand_device,
        &wdog_device,
 -      &pinmux_device,
  };
  
  /*
@@@ -1826,8 -1863,8 +1828,8 @@@ void __init u300_init_devices(void
        u300_assign_physmem();
  
        /* Initialize pinmuxing */
 -      pinmux_register_mappings(u300_pinmux_map,
 -                               ARRAY_SIZE(u300_pinmux_map));
 +      pinctrl_register_mappings(u300_pinmux_map,
 +                                ARRAY_SIZE(u300_pinmux_map));
  
        /* Register subdevices on the I2C buses */
        u300_i2c_register_board_devices();
        writew(val, U300_SYSCON_VBASE + U300_SYSCON_SMCR);
  }
  
 -static int core_module_init(void)
 -{
 -      /*
 -       * This needs to be initialized later: it needs the input framework
 -       * to be initialized first.
 -       */
 -      return mmc_init(&mmcsd_device);
 -}
 -module_init(core_module_init);
 -
  /* Forward declare this function from the watchdog */
  void coh901327_watchdog_reset(void);
  
index 7b7cba960b690945fbd9830e893eb3c27ade58c8,b9701fb86db62caa18113993147a4327ecd21008..65f87c523892e0826ea65d4928cb14cb10b30349
   * the defines are used for setting up the I/O memory mapping.
   */
  
 -#ifdef __ASSEMBLER__
 -#define IOMEM(a) (a)
 -#else
 -#define IOMEM(a) (void __iomem *) a
 -#endif
 -
  /* NAND Flash CS0 */
  #define U300_NAND_CS0_PHYS_BASE               0x80000000
  
  /* NFIF */
  #define U300_NAND_IF_PHYS_BASE                0x9f800000
  
+ /* ALE, CLE offset for FSMC NAND */
+ #define PLAT_NAND_CLE                 (1 << 16)
+ #define PLAT_NAND_ALE                 (1 << 17)
  /* AHB Peripherals */
  #define U300_AHB_PER_PHYS_BASE                0xa0000000
  #define U300_AHB_PER_VIRT_BASE                0xff010000
diff --combined drivers/dma/mxs-dma.c
index 65334c49b71e92bb3c73c01306a98c86eb90b732,0ddfd30b56ad21e3ba5d8a127c89d401baf5e84b..c81ef7e10e08283ce8eaf4fadf6166b5d3ddc19c
  #include <linux/platform_device.h>
  #include <linux/dmaengine.h>
  #include <linux/delay.h>
+ #include <linux/fsl/mxs-dma.h>
  
  #include <asm/irq.h>
  #include <mach/mxs.h>
- #include <mach/dma.h>
  #include <mach/common.h>
  
 +#include "dmaengine.h"
 +
  /*
   * NOTE: The term "PIO" throughout the mxs-dma implementation means
   * PIO mode of mxs apbh-dma and apbx-dma.  With this working mode,
@@@ -113,6 -111,7 +113,6 @@@ struct mxs_dma_chan 
        struct mxs_dma_ccw              *ccw;
        dma_addr_t                      ccw_phys;
        int                             desc_count;
 -      dma_cookie_t                    last_completed;
        enum dma_status                 status;
        unsigned int                    flags;
  #define MXS_DMA_SG_LOOP                       (1 << 0)
@@@ -194,6 -193,19 +194,6 @@@ static void mxs_dma_resume_chan(struct 
        mxs_chan->status = DMA_IN_PROGRESS;
  }
  
 -static dma_cookie_t mxs_dma_assign_cookie(struct mxs_dma_chan *mxs_chan)
 -{
 -      dma_cookie_t cookie = mxs_chan->chan.cookie;
 -
 -      if (++cookie < 0)
 -              cookie = 1;
 -
 -      mxs_chan->chan.cookie = cookie;
 -      mxs_chan->desc.cookie = cookie;
 -
 -      return cookie;
 -}
 -
  static struct mxs_dma_chan *to_mxs_dma_chan(struct dma_chan *chan)
  {
        return container_of(chan, struct mxs_dma_chan, chan);
@@@ -205,7 -217,7 +205,7 @@@ static dma_cookie_t mxs_dma_tx_submit(s
  
        mxs_dma_enable_chan(mxs_chan);
  
 -      return mxs_dma_assign_cookie(mxs_chan);
 +      return dma_cookie_assign(tx);
  }
  
  static void mxs_dma_tasklet(unsigned long data)
@@@ -262,7 -274,7 +262,7 @@@ static irqreturn_t mxs_dma_int_handler(
                stat1 &= ~(1 << channel);
  
                if (mxs_chan->status == DMA_SUCCESS)
 -                      mxs_chan->last_completed = mxs_chan->desc.cookie;
 +                      dma_cookie_complete(&mxs_chan->desc);
  
                /* schedule tasklet on this channel */
                tasklet_schedule(&mxs_chan->tasklet);
@@@ -337,10 -349,32 +337,32 @@@ static void mxs_dma_free_chan_resources
        clk_disable_unprepare(mxs_dma->clk);
  }
  
+ /*
+  * How to use the flags for ->device_prep_slave_sg() :
+  *    [1] If there is only one DMA command in the DMA chain, the code should be:
+  *            ......
+  *            ->device_prep_slave_sg(DMA_CTRL_ACK);
+  *            ......
+  *    [2] If there are two DMA commands in the DMA chain, the code should be
+  *            ......
+  *            ->device_prep_slave_sg(0);
+  *            ......
+  *            ->device_prep_slave_sg(DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
+  *            ......
+  *    [3] If there are more than two DMA commands in the DMA chain, the code
+  *        should be:
+  *            ......
+  *            ->device_prep_slave_sg(0);                                // First
+  *            ......
+  *            ->device_prep_slave_sg(DMA_PREP_INTERRUPT [| DMA_CTRL_ACK]);
+  *            ......
+  *            ->device_prep_slave_sg(DMA_PREP_INTERRUPT | DMA_CTRL_ACK); // Last
+  *            ......
+  */
  static struct dma_async_tx_descriptor *mxs_dma_prep_slave_sg(
                struct dma_chan *chan, struct scatterlist *sgl,
                unsigned int sg_len, enum dma_transfer_direction direction,
-               unsigned long append, void *context)
 -              unsigned long flags)
++              unsigned long flags, void *context)
  {
        struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan);
        struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
        struct scatterlist *sg;
        int i, j;
        u32 *pio;
+       bool append = flags & DMA_PREP_INTERRUPT;
        int idx = append ? mxs_chan->desc_count : 0;
  
        if (mxs_chan->status == DMA_IN_PROGRESS && !append)
                ccw->bits |= CCW_CHAIN;
                ccw->bits &= ~CCW_IRQ;
                ccw->bits &= ~CCW_DEC_SEM;
-               ccw->bits &= ~CCW_WAIT4END;
        } else {
                idx = 0;
        }
                ccw->bits = 0;
                ccw->bits |= CCW_IRQ;
                ccw->bits |= CCW_DEC_SEM;
-               ccw->bits |= CCW_WAIT4END;
+               if (flags & DMA_CTRL_ACK)
+                       ccw->bits |= CCW_WAIT4END;
                ccw->bits |= CCW_HALT_ON_TERM;
                ccw->bits |= CCW_TERM_FLUSH;
                ccw->bits |= BF_CCW(sg_len, PIO_NUM);
                                ccw->bits &= ~CCW_CHAIN;
                                ccw->bits |= CCW_IRQ;
                                ccw->bits |= CCW_DEC_SEM;
-                               ccw->bits |= CCW_WAIT4END;
+                               if (flags & DMA_CTRL_ACK)
+                                       ccw->bits |= CCW_WAIT4END;
                        }
                }
        }
@@@ -435,8 -471,7 +459,8 @@@ err_out
  
  static struct dma_async_tx_descriptor *mxs_dma_prep_dma_cyclic(
                struct dma_chan *chan, dma_addr_t dma_addr, size_t buf_len,
 -              size_t period_len, enum dma_transfer_direction direction)
 +              size_t period_len, enum dma_transfer_direction direction,
 +              void *context)
  {
        struct mxs_dma_chan *mxs_chan = to_mxs_dma_chan(chan);
        struct mxs_dma_engine *mxs_dma = mxs_chan->mxs_dma;
@@@ -527,7 -562,7 +551,7 @@@ static enum dma_status mxs_dma_tx_statu
        dma_cookie_t last_used;
  
        last_used = chan->cookie;
 -      dma_set_tx_state(txstate, mxs_chan->last_completed, last_used, 0);
 +      dma_set_tx_state(txstate, chan->completed_cookie, last_used, 0);
  
        return mxs_chan->status;
  }
@@@ -619,7 -654,6 +643,7 @@@ static int __init mxs_dma_probe(struct 
  
                mxs_chan->mxs_dma = mxs_dma;
                mxs_chan->chan.device = &mxs_dma->dma_device;
 +              dma_cookie_init(&mxs_chan->chan);
  
                tasklet_init(&mxs_chan->tasklet, mxs_dma_tasklet,
                             (unsigned long) mxs_chan);
index 65f36cf2ff334bf0059ddd57401e5b70c19566e5,4062812136ef66b215666c3d5715a65c42ed2b26..b0f2ef9881883df42f5513eb3f1f0479e6c83653
  #include <linux/gpio.h>
  #include <linux/regulator/consumer.h>
  #include <linux/module.h>
+ #include <linux/fsl/mxs-dma.h>
  
  #include <mach/mxs.h>
  #include <mach/common.h>
- #include <mach/dma.h>
  #include <mach/mmc.h>
  
  #define DRIVER_NAME   "mxs-mmc"
@@@ -305,7 -305,7 +305,7 @@@ static irqreturn_t mxs_mmc_irq_handler(
  }
  
  static struct dma_async_tx_descriptor *mxs_mmc_prep_dma(
-       struct mxs_mmc_host *host, unsigned int append)
+       struct mxs_mmc_host *host, unsigned long flags)
  {
        struct dma_async_tx_descriptor *desc;
        struct mmc_data *data = host->data;
                sg_len = SSP_PIO_NUM;
        }
  
 -      desc = host->dmach->device->device_prep_slave_sg(host->dmach,
 +      desc = dmaengine_prep_slave_sg(host->dmach,
-                               sgl, sg_len, host->slave_dirn, append);
+                               sgl, sg_len, host->slave_dirn, flags);
        if (desc) {
                desc->callback = mxs_mmc_dma_irq_callback;
                desc->callback_param = host;
@@@ -358,7 -358,7 +358,7 @@@ static void mxs_mmc_bc(struct mxs_mmc_h
        host->ssp_pio_words[2] = cmd1;
        host->dma_dir = DMA_NONE;
        host->slave_dirn = DMA_TRANS_NONE;
-       desc = mxs_mmc_prep_dma(host, 0);
+       desc = mxs_mmc_prep_dma(host, DMA_CTRL_ACK);
        if (!desc)
                goto out;
  
@@@ -398,7 -398,7 +398,7 @@@ static void mxs_mmc_ac(struct mxs_mmc_h
        host->ssp_pio_words[2] = cmd1;
        host->dma_dir = DMA_NONE;
        host->slave_dirn = DMA_TRANS_NONE;
-       desc = mxs_mmc_prep_dma(host, 0);
+       desc = mxs_mmc_prep_dma(host, DMA_CTRL_ACK);
        if (!desc)
                goto out;
  
@@@ -526,7 -526,7 +526,7 @@@ static void mxs_mmc_adtc(struct mxs_mmc
        host->data = data;
        host->dma_dir = dma_data_dir;
        host->slave_dirn = slave_dirn;
-       desc = mxs_mmc_prep_dma(host, 1);
+       desc = mxs_mmc_prep_dma(host, DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
        if (!desc)
                goto out;
  
diff --combined drivers/mtd/Kconfig
index 284cf3433720fe07233ce5c380e3668999d4b94e,58c6020d41821dc49a7afa36e3784d4a9f457180..5760c1a4b3f66ea3125b71d28ab4f62ceb4ee925
@@@ -1,6 -1,6 +1,6 @@@
  menuconfig MTD
        tristate "Memory Technology Device (MTD) support"
 -      depends on HAS_IOMEM
 +      depends on GENERIC_IO
        help
          Memory Technology Devices are flash, RAM and similar chips, often
          used for solid state file systems on embedded devices. This option
@@@ -304,9 -304,6 +304,6 @@@ config MTD_OOP
          buffer in a flash partition where it can be read back at some
          later point.
  
-         To use, add console=ttyMTDx to the kernel command line,
-         where x is the MTD device number to use.
  config MTD_SWAP
        tristate "Swap on MTD device support"
        depends on MTD && SWAP
index 9bcd1f415f43f137631793e8371ffb6899b5d92c,bfee5b3a9217cc18c3bfc0be82e8679d6d2b0d63..dbbd2edfb812805e96c95ea7530aa229c821d78c
@@@ -87,7 -87,7 +87,7 @@@ static int cfi_intelext_partition_fixup
  
  static int cfi_intelext_point (struct mtd_info *mtd, loff_t from, size_t len,
                     size_t *retlen, void **virt, resource_size_t *phys);
- static void cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len);
+ static int cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len);
  
  static int chip_ready (struct map_info *map, struct flchip *chip, unsigned long adr, int mode);
  static int get_chip(struct map_info *map, struct flchip *chip, unsigned long adr, int mode);
@@@ -262,9 -262,9 +262,9 @@@ static void fixup_st_m28w320cb(struct m
  static void fixup_use_point(struct mtd_info *mtd)
  {
        struct map_info *map = mtd->priv;
-       if (!mtd->point && map_is_linear(map)) {
-               mtd->point   = cfi_intelext_point;
-               mtd->unpoint = cfi_intelext_unpoint;
+       if (!mtd->_point && map_is_linear(map)) {
+               mtd->_point   = cfi_intelext_point;
+               mtd->_unpoint = cfi_intelext_unpoint;
        }
  }
  
@@@ -274,8 -274,8 +274,8 @@@ static void fixup_use_write_buffers(str
        struct cfi_private *cfi = map->fldrv_priv;
        if (cfi->cfiq->BufWriteTimeoutTyp) {
                printk(KERN_INFO "Using buffer write method\n" );
-               mtd->write = cfi_intelext_write_buffers;
-               mtd->writev = cfi_intelext_writev;
+               mtd->_write = cfi_intelext_write_buffers;
+               mtd->_writev = cfi_intelext_writev;
        }
  }
  
@@@ -443,15 -443,15 +443,15 @@@ struct mtd_info *cfi_cmdset_0001(struc
        mtd->type = MTD_NORFLASH;
  
        /* Fill in the default mtd operations */
-       mtd->erase   = cfi_intelext_erase_varsize;
-       mtd->read    = cfi_intelext_read;
-       mtd->write   = cfi_intelext_write_words;
-       mtd->sync    = cfi_intelext_sync;
-       mtd->lock    = cfi_intelext_lock;
-       mtd->unlock  = cfi_intelext_unlock;
-       mtd->is_locked = cfi_intelext_is_locked;
-       mtd->suspend = cfi_intelext_suspend;
-       mtd->resume  = cfi_intelext_resume;
+       mtd->_erase   = cfi_intelext_erase_varsize;
+       mtd->_read    = cfi_intelext_read;
+       mtd->_write   = cfi_intelext_write_words;
+       mtd->_sync    = cfi_intelext_sync;
+       mtd->_lock    = cfi_intelext_lock;
+       mtd->_unlock  = cfi_intelext_unlock;
+       mtd->_is_locked = cfi_intelext_is_locked;
+       mtd->_suspend = cfi_intelext_suspend;
+       mtd->_resume  = cfi_intelext_resume;
        mtd->flags   = MTD_CAP_NORFLASH;
        mtd->name    = map->name;
        mtd->writesize = 1;
@@@ -600,12 -600,12 +600,12 @@@ static struct mtd_info *cfi_intelext_se
        }
  
  #ifdef CONFIG_MTD_OTP
-       mtd->read_fact_prot_reg = cfi_intelext_read_fact_prot_reg;
-       mtd->read_user_prot_reg = cfi_intelext_read_user_prot_reg;
-       mtd->write_user_prot_reg = cfi_intelext_write_user_prot_reg;
-       mtd->lock_user_prot_reg = cfi_intelext_lock_user_prot_reg;
-       mtd->get_fact_prot_info = cfi_intelext_get_fact_prot_info;
-       mtd->get_user_prot_info = cfi_intelext_get_user_prot_info;
+       mtd->_read_fact_prot_reg = cfi_intelext_read_fact_prot_reg;
+       mtd->_read_user_prot_reg = cfi_intelext_read_user_prot_reg;
+       mtd->_write_user_prot_reg = cfi_intelext_write_user_prot_reg;
+       mtd->_lock_user_prot_reg = cfi_intelext_lock_user_prot_reg;
+       mtd->_get_fact_prot_info = cfi_intelext_get_fact_prot_info;
+       mtd->_get_user_prot_info = cfi_intelext_get_user_prot_info;
  #endif
  
        /* This function has the potential to distort the reality
@@@ -1017,8 -1017,6 +1017,6 @@@ static void put_chip(struct map_info *m
        case FL_READY:
        case FL_STATUS:
        case FL_JEDEC_QUERY:
-               /* We should really make set_vpp() count, rather than doing this */
-               DISABLE_VPP(map);
                break;
        default:
                printk(KERN_ERR "%s: put_chip() called with oldstate %d!!\n", map->name, chip->oldstate);
@@@ -1324,7 -1322,7 +1322,7 @@@ static int cfi_intelext_point(struct mt
        int chipnum;
        int ret = 0;
  
-       if (!map->virt || (from + len > mtd->size))
+       if (!map->virt)
                return -EINVAL;
  
        /* Now lock the chip(s) to POINT state */
        ofs = from - (chipnum << cfi->chipshift);
  
        *virt = map->virt + cfi->chips[chipnum].start + ofs;
-       *retlen = 0;
        if (phys)
                *phys = map->phys + cfi->chips[chipnum].start + ofs;
  
        return 0;
  }
  
- static void cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
+ static int cfi_intelext_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
  {
        struct map_info *map = mtd->priv;
        struct cfi_private *cfi = map->fldrv_priv;
        unsigned long ofs;
-       int chipnum;
+       int chipnum, err = 0;
  
        /* Now unlock the chip(s) POINT state */
  
        chipnum = (from >> cfi->chipshift);
        ofs = from - (chipnum <<  cfi->chipshift);
  
-       while (len) {
+       while (len && !err) {
                unsigned long thislen;
                struct flchip *chip;
  
                        chip->ref_point_counter--;
                        if(chip->ref_point_counter == 0)
                                chip->state = FL_READY;
-               } else
-                       printk(KERN_ERR "%s: Warning: unpoint called on non pointed region\n", map->name); /* Should this give an error? */
+               } else {
+                       printk(KERN_ERR "%s: Error: unpoint called on non pointed region\n", map->name);
+                       err = -EINVAL;
+               }
  
                put_chip(map, chip, chip->start);
                mutex_unlock(&chip->mutex);
                ofs = 0;
                chipnum++;
        }
+       return err;
  }
  
  static inline int do_read_onechip(struct map_info *map, struct flchip *chip, loff_t adr, size_t len, u_char *buf)
@@@ -1456,8 -1457,6 +1457,6 @@@ static int cfi_intelext_read (struct mt
        chipnum = (from >> cfi->chipshift);
        ofs = from - (chipnum <<  cfi->chipshift);
  
-       *retlen = 0;
        while (len) {
                unsigned long thislen;
  
@@@ -1551,7 -1550,8 +1550,8 @@@ static int __xipram do_write_oneword(st
        }
  
        xip_enable(map, chip, adr);
-  out: put_chip(map, chip, adr);
+  out: DISABLE_VPP(map);
+       put_chip(map, chip, adr);
        mutex_unlock(&chip->mutex);
        return ret;
  }
@@@ -1565,10 -1565,6 +1565,6 @@@ static int cfi_intelext_write_words (st
        int chipnum;
        unsigned long ofs;
  
-       *retlen = 0;
-       if (!len)
-               return 0;
        chipnum = to >> cfi->chipshift;
        ofs = to  - (chipnum << cfi->chipshift);
  
@@@ -1794,7 -1790,8 +1790,8 @@@ static int __xipram do_write_buffer(str
        }
  
        xip_enable(map, chip, cmd_adr);
-  out: put_chip(map, chip, cmd_adr);
+  out: DISABLE_VPP(map);
+       put_chip(map, chip, cmd_adr);
        mutex_unlock(&chip->mutex);
        return ret;
  }
@@@ -1813,7 -1810,6 +1810,6 @@@ static int cfi_intelext_writev (struct 
        for (i = 0; i < count; i++)
                len += vecs[i].iov_len;
  
-       *retlen = 0;
        if (!len)
                return 0;
  
@@@ -1932,6 -1928,7 +1928,7 @@@ static int __xipram do_erase_oneblock(s
                        ret = -EIO;
                } else if (chipstatus & 0x20 && retries--) {
                        printk(KERN_DEBUG "block erase failed at 0x%08lx: status 0x%lx. Retrying...\n", adr, chipstatus);
+                       DISABLE_VPP(map);
                        put_chip(map, chip, adr);
                        mutex_unlock(&chip->mutex);
                        goto retry;
        }
  
        xip_enable(map, chip, adr);
-  out: put_chip(map, chip, adr);
+  out: DISABLE_VPP(map);
+       put_chip(map, chip, adr);
        mutex_unlock(&chip->mutex);
        return ret;
  }
@@@ -2086,7 -2084,8 +2084,8 @@@ static int __xipram do_xxlock_oneblock(
        }
  
        xip_enable(map, chip, adr);
- out:  put_chip(map, chip, adr);
+  out: DISABLE_VPP(map);
+       put_chip(map, chip, adr);
        mutex_unlock(&chip->mutex);
        return ret;
  }
@@@ -2483,7 -2482,7 +2482,7 @@@ static int cfi_intelext_suspend(struct 
                           allowed to. Or should we return -EAGAIN, because the upper layers
                           ought to have already shut down anything which was using the device
                           anyway? The latter for now. */
-                       printk(KERN_NOTICE "Flash device refused suspend due to active operation (state %d)\n", chip->oldstate);
+                       printk(KERN_NOTICE "Flash device refused suspend due to active operation (state %d)\n", chip->state);
                        ret = -EAGAIN;
                case FL_PM_SUSPENDED:
                        break;
@@@ -2526,10 -2525,12 +2525,10 @@@ static void cfi_intelext_restore_locks(
                if (!region->lockmap)
                        continue;
  
 -              for (block = 0; block < region->numblocks; block++) {
 +              for_each_clear_bit(block, region->lockmap, region->numblocks) {
                        len = region->erasesize;
                        adr = region->offset + block * len;
 -
 -                      if (!test_bit(block, region->lockmap))
 -                              cfi_intelext_unlock(mtd, adr, len);
 +                      cfi_intelext_unlock(mtd, adr, len);
                }
        }
  }
index 8d3dac40d7e6e17411936a34a6e50b226ad78667,98206b034c01fbd0d0f2d5f2391f6f82126cb030..4cdb2af7bf44e74dbb72bab223d39beabd7c265a
@@@ -1,6 -1,5 +1,6 @@@
  menu "Self-contained MTD device drivers"
        depends on MTD!=n
 +      depends on HAS_IOMEM
  
  config MTD_PMC551
        tristate "Ramix PMC551 PCI Mezzanine RAM card support"
@@@ -103,6 -102,13 +103,13 @@@ config M25PXX_USE_FAST_REA
        help
          This option enables FAST_READ access supported by ST M25Pxx.
  
+ config MTD_SPEAR_SMI
+       tristate "SPEAR MTD NOR Support through SMI controller"
+       depends on PLAT_SPEAR
+       default y
+       help
+         This enable SNOR support on SPEAR platforms using SMI controller
  config MTD_SST25L
        tristate "Support SST25L (non JEDEC) SPI Flash chips"
        depends on SPI_MASTER
index 5d53c5760a6cfa71adc20fe92d862497acb33aff,c4368ec39d5cd8ca4c323ffa675b8be2d0a6ab55..0c51b988e1f8880af884995540cee3c5ac91dfca
  #include <linux/fs.h>
  #include <linux/ioctl.h>
  #include <asm/io.h>
 -#include <asm/system.h>
  #include <linux/pci.h>
  #include <linux/mtd/mtd.h>
- #include <linux/mtd/pmc551.h>
+ #define PMC551_VERSION \
+       "Ramix PMC551 PCI Mezzanine Ram Driver. (C) 1999,2000 Nortel Networks.\n"
+ #define PCI_VENDOR_ID_V3_SEMI 0x11b0
+ #define PCI_DEVICE_ID_V3_SEMI_V370PDC 0x0200
+ #define PMC551_PCI_MEM_MAP0 0x50
+ #define PMC551_PCI_MEM_MAP1 0x54
+ #define PMC551_PCI_MEM_MAP_MAP_ADDR_MASK 0x3ff00000
+ #define PMC551_PCI_MEM_MAP_APERTURE_MASK 0x000000f0
+ #define PMC551_PCI_MEM_MAP_REG_EN 0x00000002
+ #define PMC551_PCI_MEM_MAP_ENABLE 0x00000001
+ #define PMC551_SDRAM_MA  0x60
+ #define PMC551_SDRAM_CMD 0x62
+ #define PMC551_DRAM_CFG  0x64
+ #define PMC551_SYS_CTRL_REG 0x78
+ #define PMC551_DRAM_BLK0 0x68
+ #define PMC551_DRAM_BLK1 0x6c
+ #define PMC551_DRAM_BLK2 0x70
+ #define PMC551_DRAM_BLK3 0x74
+ #define PMC551_DRAM_BLK_GET_SIZE(x) (524288 << ((x >> 4) & 0x0f))
+ #define PMC551_DRAM_BLK_SET_COL_MUX(x, v) (((x) & ~0x00007000) | (((v) & 0x7) << 12))
+ #define PMC551_DRAM_BLK_SET_ROW_MUX(x, v) (((x) & ~0x00000f00) | (((v) & 0xf) << 8))
+ struct mypriv {
+       struct pci_dev *dev;
+       u_char *start;
+       u32 base_map0;
+       u32 curr_map0;
+       u32 asize;
+       struct mtd_info *nextpmc551;
+ };
  
  static struct mtd_info *pmc551list;
  
+ static int pmc551_point(struct mtd_info *mtd, loff_t from, size_t len,
+                       size_t *retlen, void **virt, resource_size_t *phys);
  static int pmc551_erase(struct mtd_info *mtd, struct erase_info *instr)
  {
        struct mypriv *priv = mtd->priv;
  #endif
  
        end = instr->addr + instr->len - 1;
-       /* Is it past the end? */
-       if (end > mtd->size) {
- #ifdef CONFIG_MTD_PMC551_DEBUG
-               printk(KERN_DEBUG "pmc551_erase() out of bounds (%ld > %ld)\n",
-                       (long)end, (long)mtd->size);
- #endif
-               return -EINVAL;
-       }
        eoff_hi = end & ~(priv->asize - 1);
        soff_hi = instr->addr & ~(priv->asize - 1);
        eoff_lo = end & (priv->asize - 1);
@@@ -178,18 -205,6 +204,6 @@@ static int pmc551_point(struct mtd_inf
        printk(KERN_DEBUG "pmc551_point(%ld, %ld)\n", (long)from, (long)len);
  #endif
  
-       if (from + len > mtd->size) {
- #ifdef CONFIG_MTD_PMC551_DEBUG
-               printk(KERN_DEBUG "pmc551_point() out of bounds (%ld > %ld)\n",
-                       (long)from + len, (long)mtd->size);
- #endif
-               return -EINVAL;
-       }
-       /* can we return a physical address with this driver? */
-       if (phys)
-               return -EINVAL;
        soff_hi = from & ~(priv->asize - 1);
        soff_lo = from & (priv->asize - 1);
  
        return 0;
  }
  
- static void pmc551_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
+ static int pmc551_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
  {
  #ifdef CONFIG_MTD_PMC551_DEBUG
        printk(KERN_DEBUG "pmc551_unpoint()\n");
  #endif
+       return 0;
  }
  
  static int pmc551_read(struct mtd_info *mtd, loff_t from, size_t len,
  #endif
  
        end = from + len - 1;
-       /* Is it past the end? */
-       if (end > mtd->size) {
- #ifdef CONFIG_MTD_PMC551_DEBUG
-               printk(KERN_DEBUG "pmc551_read() out of bounds (%ld > %ld)\n",
-                       (long)end, (long)mtd->size);
- #endif
-               return -EINVAL;
-       }
        soff_hi = from & ~(priv->asize - 1);
        eoff_hi = end & ~(priv->asize - 1);
        soff_lo = from & (priv->asize - 1);
@@@ -295,16 -301,6 +300,6 @@@ static int pmc551_write(struct mtd_inf
  #endif
  
        end = to + len - 1;
-       /* Is it past the end?  or did the u32 wrap? */
-       if (end > mtd->size) {
- #ifdef CONFIG_MTD_PMC551_DEBUG
-               printk(KERN_DEBUG "pmc551_write() out of bounds (end: %ld, "
-                       "size: %ld, to: %ld)\n", (long)end, (long)mtd->size,
-                       (long)to);
- #endif
-               return -EINVAL;
-       }
        soff_hi = to & ~(priv->asize - 1);
        eoff_hi = end & ~(priv->asize - 1);
        soff_lo = to & (priv->asize - 1);
   * mechanism
   * returns the size of the memory region found.
   */
- static u32 fixup_pmc551(struct pci_dev *dev)
+ static int fixup_pmc551(struct pci_dev *dev)
  {
  #ifdef CONFIG_MTD_PMC551_BUGFIX
        u32 dram_data;
@@@ -668,7 -664,7 +663,7 @@@ static int __init init_pmc551(void
        struct mypriv *priv;
        int found = 0;
        struct mtd_info *mtd;
-       u32 length = 0;
+       int length = 0;
  
        if (msize) {
                msize = (1 << (ffs(msize) - 1)) << 20;
  
                mtd->size = msize;
                mtd->flags = MTD_CAP_RAM;
-               mtd->erase = pmc551_erase;
-               mtd->read = pmc551_read;
-               mtd->write = pmc551_write;
-               mtd->point = pmc551_point;
-               mtd->unpoint = pmc551_unpoint;
+               mtd->_erase = pmc551_erase;
+               mtd->_read = pmc551_read;
+               mtd->_write = pmc551_write;
+               mtd->_point = pmc551_point;
+               mtd->_unpoint = pmc551_unpoint;
                mtd->type = MTD_RAM;
                mtd->name = "PMC551 RAM board";
                mtd->erasesize = 0x10000;
index 288594163c22da60e4c932ea16e78c3b9bf1f6bf,ccd39ff509b168895e34d4b0235eb79544f69ae1..8f52fc858e48bec08f900963996c0d37bd4601cb
@@@ -42,6 -42,7 +42,6 @@@
  #include <linux/ioctl.h>
  #include <linux/init.h>
  #include <asm/io.h>
 -#include <asm/system.h>
  
  #include <linux/mtd/mtd.h>
  
@@@ -75,7 -76,7 +75,7 @@@ static slram_mtd_list_t *slram_mtdlist 
  static int slram_erase(struct mtd_info *, struct erase_info *);
  static int slram_point(struct mtd_info *, loff_t, size_t, size_t *, void **,
                resource_size_t *);
- static void slram_unpoint(struct mtd_info *, loff_t, size_t);
+ static int slram_unpoint(struct mtd_info *, loff_t, size_t);
  static int slram_read(struct mtd_info *, loff_t, size_t, size_t *, u_char *);
  static int slram_write(struct mtd_info *, loff_t, size_t, size_t *, const u_char *);
  
@@@ -83,21 -84,13 +83,13 @@@ static int slram_erase(struct mtd_info 
  {
        slram_priv_t *priv = mtd->priv;
  
-       if (instr->addr + instr->len > mtd->size) {
-               return(-EINVAL);
-       }
        memset(priv->start + instr->addr, 0xff, instr->len);
        /* This'll catch a few races. Free the thing before returning :)
         * I don't feel at all ashamed. This kind of thing is possible anyway
         * with flash, but unlikely.
         */
        instr->state = MTD_ERASE_DONE;
        mtd_erase_callback(instr);
        return(0);
  }
  
@@@ -106,20 -99,14 +98,14 @@@ static int slram_point(struct mtd_info 
  {
        slram_priv_t *priv = mtd->priv;
  
-       /* can we return a physical address with this driver? */
-       if (phys)
-               return -EINVAL;
-       if (from + len > mtd->size)
-               return -EINVAL;
        *virt = priv->start + from;
        *retlen = len;
        return(0);
  }
  
- static void slram_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
+ static int slram_unpoint(struct mtd_info *mtd, loff_t from, size_t len)
  {
+       return 0;
  }
  
  static int slram_read(struct mtd_info *mtd, loff_t from, size_t len,
  {
        slram_priv_t *priv = mtd->priv;
  
-       if (from > mtd->size)
-               return -EINVAL;
-       if (from + len > mtd->size)
-               len = mtd->size - from;
        memcpy(buf, priv->start + from, len);
        *retlen = len;
        return(0);
  }
@@@ -144,11 -124,7 +123,7 @@@ static int slram_write(struct mtd_info 
  {
        slram_priv_t *priv = mtd->priv;
  
-       if (to + len > mtd->size)
-               return -EINVAL;
        memcpy(priv->start + to, buf, len);
        *retlen = len;
        return(0);
  }
@@@ -199,11 -175,11 +174,11 @@@ static int register_device(char *name, 
        (*curmtd)->mtdinfo->name = name;
        (*curmtd)->mtdinfo->size = length;
        (*curmtd)->mtdinfo->flags = MTD_CAP_RAM;
-         (*curmtd)->mtdinfo->erase = slram_erase;
-       (*curmtd)->mtdinfo->point = slram_point;
-       (*curmtd)->mtdinfo->unpoint = slram_unpoint;
-       (*curmtd)->mtdinfo->read = slram_read;
-       (*curmtd)->mtdinfo->write = slram_write;
+       (*curmtd)->mtdinfo->_erase = slram_erase;
+       (*curmtd)->mtdinfo->_point = slram_point;
+       (*curmtd)->mtdinfo->_unpoint = slram_unpoint;
+       (*curmtd)->mtdinfo->_read = slram_read;
+       (*curmtd)->mtdinfo->_write = slram_write;
        (*curmtd)->mtdinfo->owner = THIS_MODULE;
        (*curmtd)->mtdinfo->type = MTD_RAM;
        (*curmtd)->mtdinfo->erasesize = SLRAM_BLK_SZ;
index 0259cf5830222e4c2da75f921be90c8517bd8c15,7d5cf369f0ad747c05c81409441849a972421992..a3cfad392ed653c1543a5318ddfc40f007b72233
@@@ -14,6 -14,7 +14,6 @@@
  #include <linux/timer.h>
  #include <linux/init.h>
  #include <asm/io.h>
 -#include <asm/system.h>
  
  #include <pcmcia/cistpl.h>
  #include <pcmcia/ds.h>
@@@ -294,13 -295,24 +294,24 @@@ static void pcmcia_copy_to(struct map_i
  }
  
  
+ static DEFINE_SPINLOCK(pcmcia_vpp_lock);
+ static int pcmcia_vpp_refcnt;
  static void pcmciamtd_set_vpp(struct map_info *map, int on)
  {
        struct pcmciamtd_dev *dev = (struct pcmciamtd_dev *)map->map_priv_1;
        struct pcmcia_device *link = dev->p_dev;
+       unsigned long flags;
  
        pr_debug("dev = %p on = %d vpp = %d\n\n", dev, on, dev->vpp);
-       pcmcia_fixup_vpp(link, on ? dev->vpp : 0);
+       spin_lock_irqsave(&pcmcia_vpp_lock, flags);
+       if (on) {
+               if (++pcmcia_vpp_refcnt == 1)   /* first nested 'on' */
+                       pcmcia_fixup_vpp(link, dev->vpp);
+       } else {
+               if (--pcmcia_vpp_refcnt == 0)   /* last nested 'off' */
+                       pcmcia_fixup_vpp(link, 0);
+       }
+       spin_unlock_irqrestore(&pcmcia_vpp_lock, flags);
  }
  
  
diff --combined drivers/mtd/mtdchar.c
index c57ae92ebda4d8654bc6bc8328ac004e60754fa1,426640eaf81823ebe06825a98090de76ca340ab6..55d82321d307de4db3fa0158f9282f66d03bd4f6
  #include <linux/compat.h>
  #include <linux/mount.h>
  #include <linux/blkpg.h>
 +#include <linux/magic.h>
  #include <linux/mtd/mtd.h>
  #include <linux/mtd/partitions.h>
  #include <linux/mtd/map.h>
  
  #include <asm/uaccess.h>
  
 -#define MTD_INODE_FS_MAGIC 0x11307854
  static DEFINE_MUTEX(mtd_mutex);
  static struct vfsmount *mtd_inode_mnt __read_mostly;
  
@@@ -405,7 -405,7 +405,7 @@@ static int mtdchar_writeoob(struct fil
        if (length > 4096)
                return -EINVAL;
  
-       if (!mtd->write_oob)
+       if (!mtd->_write_oob)
                ret = -EOPNOTSUPP;
        else
                ret = access_ok(VERIFY_READ, ptr, length) ? 0 : -EFAULT;
@@@ -576,7 -576,7 +576,7 @@@ static int mtdchar_write_ioctl(struct m
                        !access_ok(VERIFY_READ, req.usr_data, req.len) ||
                        !access_ok(VERIFY_READ, req.usr_oob, req.ooblen))
                return -EFAULT;
-       if (!mtd->write_oob)
+       if (!mtd->_write_oob)
                return -EOPNOTSUPP;
  
        ops.mode = req.mode;
diff --combined drivers/mtd/nand/Kconfig
index a3c4de551ebee12239c07738f9d9896a3b26060f,0ea7084eabdcb5d1dc7f7164ef2159282e769ca9..7d17cecad69d8fccc1467eaa210c6fe2915197dd
@@@ -187,7 -187,7 +187,7 @@@ config MTD_NAND_PPCHAMELEONEV
  
  config MTD_NAND_S3C2410
        tristate "NAND Flash support for Samsung S3C SoCs"
 -      depends on ARCH_S3C2410 || ARCH_S3C64XX
 +      depends on ARCH_S3C24XX || ARCH_S3C64XX
        help
          This enables the NAND flash controller on the S3C24xx and S3C64xx
          SoCs
@@@ -246,7 -246,6 +246,7 @@@ config MTD_NAND_BCM_UMI_HWC
  config MTD_NAND_DISKONCHIP
        tristate "DiskOnChip 2000, Millennium and Millennium Plus (NAND reimplementation) (EXPERIMENTAL)"
        depends on EXPERIMENTAL
 +      depends on HAS_IOMEM
        select REED_SOLOMON
        select REED_SOLOMON_DEC16
        help
@@@ -314,6 -313,26 +314,26 @@@ config MTD_NAND_DISKONCHIP_BBTWRIT
          load time (assuming you build diskonchip as a module) with the module
          parameter "inftl_bbt_write=1".
  
+ config MTD_NAND_DOCG4
+       tristate "Support for DiskOnChip G4 (EXPERIMENTAL)"
+       depends on EXPERIMENTAL
+       select BCH
+       select BITREVERSE
+       help
+         Support for diskonchip G4 nand flash, found in various smartphones and
+         PDAs, among them the Palm Treo680, HTC Prophet and Wizard, Toshiba
+         Portege G900, Asus P526, and O2 XDA Zinc.
+         With this driver you will be able to use UBI and create a ubifs on the
+         device, so you may wish to consider enabling UBI and UBIFS as well.
+         These devices ship with the Mys/Sandisk SAFTL formatting, for which
+         there is currently no mtd parser, so you may want to use command line
+         partitioning to segregate write-protected blocks. On the Treo680, the
+         first five erase blocks (256KiB each) are write-protected, followed
+         by the block containing the saftl partition table.  This is probably
+         typical.
  config MTD_NAND_SHARPSL
        tristate "Support for NAND Flash on Sharp SL Series (C7xx + others)"
        depends on ARCH_PXA
@@@ -421,7 -440,6 +441,6 @@@ config MTD_NAND_NANDSI
  config MTD_NAND_GPMI_NAND
          bool "GPMI NAND Flash Controller driver"
          depends on MTD_NAND && (SOC_IMX23 || SOC_IMX28)
-       select MTD_CMDLINE_PARTS
          help
         Enables NAND Flash support for IMX23 or IMX28.
         The GPMI controller is very powerful, with the help of BCH
  
  config MTD_NAND_PLATFORM
        tristate "Support for generic platform NAND driver"
 +      depends on HAS_IOMEM
        help
          This implements a generic NAND driver for on-SOC platform
          devices. You will need to provide platform-specific functions
@@@ -464,16 -481,6 +483,16 @@@ config MTD_NAND_FSL_ELB
          Enabling this option will enable you to use this to control
          external NAND devices.
  
 +config MTD_NAND_FSL_IFC
 +      tristate "NAND support for Freescale IFC controller"
 +      depends on MTD_NAND && FSL_SOC
 +      select FSL_IFC
 +      help
 +        Various Freescale chips e.g P1010, include a NAND Flash machine
 +        with built-in hardware ECC capabilities.
 +        Enabling this option will enable you to use this to control
 +        external NAND devices.
 +
  config MTD_NAND_FSL_UPM
        tristate "Support for NAND on Freescale UPM"
        depends on PPC_83xx || PPC_85xx
index 19bc8cb1d1874bf3b64fbd6234258d5142171554,36c26ab2ae16384e041d109316af6095c8642222..d4b4d8739bd8e88584e4b8f425d7cc9234b3e304
@@@ -19,6 -19,7 +19,7 @@@ obj-$(CONFIG_MTD_NAND_PPCHAMELEONEVB) +
  obj-$(CONFIG_MTD_NAND_S3C2410)                += s3c2410.o
  obj-$(CONFIG_MTD_NAND_DAVINCI)                += davinci_nand.o
  obj-$(CONFIG_MTD_NAND_DISKONCHIP)     += diskonchip.o
+ obj-$(CONFIG_MTD_NAND_DOCG4)          += docg4.o
  obj-$(CONFIG_MTD_NAND_FSMC)           += fsmc_nand.o
  obj-$(CONFIG_MTD_NAND_H1900)          += h1910.o
  obj-$(CONFIG_MTD_NAND_RTC_FROM4)      += rtc_from4.o
@@@ -37,7 -38,6 +38,7 @@@ obj-$(CONFIG_MTD_ALAUDA)              += alauda.
  obj-$(CONFIG_MTD_NAND_PASEMI)         += pasemi_nand.o
  obj-$(CONFIG_MTD_NAND_ORION)          += orion_nand.o
  obj-$(CONFIG_MTD_NAND_FSL_ELBC)               += fsl_elbc_nand.o
 +obj-$(CONFIG_MTD_NAND_FSL_IFC)                += fsl_ifc_nand.o
  obj-$(CONFIG_MTD_NAND_FSL_UPM)                += fsl_upm.o
  obj-$(CONFIG_MTD_NAND_SH_FLCTL)               += sh_flctl.o
  obj-$(CONFIG_MTD_NAND_MXC)            += mxc_nand.o
index ae7e37d9ac172fa411d99aacbb4c3b196cdc5991,662abf08061af34e712261b8207e2e08d6fa35f5..2165576a1c67df0e623752970fdfdd141f3ea931
  #include <linux/module.h>
  #include <linux/moduleparam.h>
  #include <linux/platform_device.h>
 +#include <linux/of.h>
 +#include <linux/of_device.h>
 +#include <linux/of_gpio.h>
 +#include <linux/of_mtd.h>
  #include <linux/mtd/mtd.h>
  #include <linux/mtd/nand.h>
  #include <linux/mtd/partitions.h>
  #include <linux/dmaengine.h>
  #include <linux/gpio.h>
  #include <linux/io.h>
 +#include <linux/platform_data/atmel.h>
  
 -#include <mach/board.h>
  #include <mach/cpu.h>
  
 -#ifdef CONFIG_MTD_NAND_ATMEL_ECC_HW
 -#define hard_ecc      1
 -#else
 -#define hard_ecc      0
 -#endif
 -
 -#ifdef CONFIG_MTD_NAND_ATMEL_ECC_NONE
 -#define no_ecc                1
 -#else
 -#define no_ecc                0
 -#endif
 -
  static int use_dma = 1;
  module_param(use_dma, int, 0);
  
@@@ -87,7 -95,7 +87,7 @@@ struct atmel_nand_host 
        struct mtd_info         mtd;
        void __iomem            *io_base;
        dma_addr_t              io_phys;
 -      struct atmel_nand_data  *board;
 +      struct atmel_nand_data  board;
        struct device           *dev;
        void __iomem            *ecc;
  
@@@ -105,8 -113,8 +105,8 @@@ static int cpu_has_dma(void
   */
  static void atmel_nand_enable(struct atmel_nand_host *host)
  {
 -      if (gpio_is_valid(host->board->enable_pin))
 -              gpio_set_value(host->board->enable_pin, 0);
 +      if (gpio_is_valid(host->board.enable_pin))
 +              gpio_set_value(host->board.enable_pin, 0);
  }
  
  /*
   */
  static void atmel_nand_disable(struct atmel_nand_host *host)
  {
 -      if (gpio_is_valid(host->board->enable_pin))
 -              gpio_set_value(host->board->enable_pin, 1);
 +      if (gpio_is_valid(host->board.enable_pin))
 +              gpio_set_value(host->board.enable_pin, 1);
  }
  
  /*
@@@ -136,9 -144,9 +136,9 @@@ static void atmel_nand_cmd_ctrl(struct 
                return;
  
        if (ctrl & NAND_CLE)
 -              writeb(cmd, host->io_base + (1 << host->board->cle));
 +              writeb(cmd, host->io_base + (1 << host->board.cle));
        else
 -              writeb(cmd, host->io_base + (1 << host->board->ale));
 +              writeb(cmd, host->io_base + (1 << host->board.ale));
  }
  
  /*
@@@ -149,8 -157,8 +149,8 @@@ static int atmel_nand_device_ready(stru
        struct nand_chip *nand_chip = mtd->priv;
        struct atmel_nand_host *host = nand_chip->priv;
  
 -      return gpio_get_value(host->board->rdy_pin) ^
 -                !!host->board->rdy_pin_active_low;
 +      return gpio_get_value(host->board.rdy_pin) ^
 +                !!host->board.rdy_pin_active_low;
  }
  
  /*
@@@ -265,7 -273,7 +265,7 @@@ static void atmel_read_buf(struct mtd_i
                if (atmel_nand_dma_op(mtd, buf, len, 1) == 0)
                        return;
  
 -      if (host->board->bus_width_16)
 +      if (host->board.bus_width_16)
                atmel_read_buf16(mtd, buf, len);
        else
                atmel_read_buf8(mtd, buf, len);
@@@ -281,7 -289,7 +281,7 @@@ static void atmel_write_buf(struct mtd_
                if (atmel_nand_dma_op(mtd, (void *)buf, len, 0) == 0)
                        return;
  
 -      if (host->board->bus_width_16)
 +      if (host->board.bus_width_16)
                atmel_write_buf16(mtd, buf, len);
        else
                atmel_write_buf8(mtd, buf, len);
@@@ -473,56 -481,6 +473,56 @@@ static void atmel_nand_hwctl(struct mtd
        }
  }
  
 +#if defined(CONFIG_OF)
 +static int __devinit atmel_of_init_port(struct atmel_nand_host *host,
 +                                       struct device_node *np)
 +{
 +      u32 val;
 +      int ecc_mode;
 +      struct atmel_nand_data *board = &host->board;
 +      enum of_gpio_flags flags;
 +
 +      if (of_property_read_u32(np, "atmel,nand-addr-offset", &val) == 0) {
 +              if (val >= 32) {
 +                      dev_err(host->dev, "invalid addr-offset %u\n", val);
 +                      return -EINVAL;
 +              }
 +              board->ale = val;
 +      }
 +
 +      if (of_property_read_u32(np, "atmel,nand-cmd-offset", &val) == 0) {
 +              if (val >= 32) {
 +                      dev_err(host->dev, "invalid cmd-offset %u\n", val);
 +                      return -EINVAL;
 +              }
 +              board->cle = val;
 +      }
 +
 +      ecc_mode = of_get_nand_ecc_mode(np);
 +
 +      board->ecc_mode = ecc_mode < 0 ? NAND_ECC_SOFT : ecc_mode;
 +
 +      board->on_flash_bbt = of_get_nand_on_flash_bbt(np);
 +
 +      if (of_get_nand_bus_width(np) == 16)
 +              board->bus_width_16 = 1;
 +
 +      board->rdy_pin = of_get_gpio_flags(np, 0, &flags);
 +      board->rdy_pin_active_low = (flags == OF_GPIO_ACTIVE_LOW);
 +
 +      board->enable_pin = of_get_gpio(np, 1);
 +      board->det_pin = of_get_gpio(np, 2);
 +
 +      return 0;
 +}
 +#else
 +static int __devinit atmel_of_init_port(struct atmel_nand_host *host,
 +                                       struct device_node *np)
 +{
 +      return -EINVAL;
 +}
 +#endif
 +
  /*
   * Probe for the NAND device.
   */
@@@ -533,7 -491,6 +533,7 @@@ static int __init atmel_nand_probe(stru
        struct nand_chip *nand_chip;
        struct resource *regs;
        struct resource *mem;
 +      struct mtd_part_parser_data ppdata = {};
        int res;
  
        mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
  
        mtd = &host->mtd;
        nand_chip = &host->nand_chip;
 -      host->board = pdev->dev.platform_data;
        host->dev = &pdev->dev;
 +      if (pdev->dev.of_node) {
 +              res = atmel_of_init_port(host, pdev->dev.of_node);
 +              if (res)
 +                      goto err_nand_ioremap;
 +      } else {
 +              memcpy(&host->board, pdev->dev.platform_data,
 +                     sizeof(struct atmel_nand_data));
 +      }
  
        nand_chip->priv = host;         /* link the private data structures */
        mtd->priv = nand_chip;
        nand_chip->IO_ADDR_W = host->io_base;
        nand_chip->cmd_ctrl = atmel_nand_cmd_ctrl;
  
 -      if (gpio_is_valid(host->board->rdy_pin))
 +      if (gpio_is_valid(host->board.rdy_pin))
                nand_chip->dev_ready = atmel_nand_device_ready;
  
 +      nand_chip->ecc.mode = host->board.ecc_mode;
 +
        regs = platform_get_resource(pdev, IORESOURCE_MEM, 1);
 -      if (!regs && hard_ecc) {
 +      if (!regs && nand_chip->ecc.mode == NAND_ECC_HW) {
                printk(KERN_ERR "atmel_nand: can't get I/O resource "
                                "regs\nFalling back on software ECC\n");
 +              nand_chip->ecc.mode = NAND_ECC_SOFT;
        }
  
 -      nand_chip->ecc.mode = NAND_ECC_SOFT;    /* enable ECC */
 -      if (no_ecc)
 -              nand_chip->ecc.mode = NAND_ECC_NONE;
 -      if (hard_ecc && regs) {
 +      if (nand_chip->ecc.mode == NAND_ECC_HW) {
                host->ecc = ioremap(regs->start, resource_size(regs));
                if (host->ecc == NULL) {
                        printk(KERN_ERR "atmel_nand: ioremap failed\n");
                        res = -EIO;
                        goto err_ecc_ioremap;
                }
 -              nand_chip->ecc.mode = NAND_ECC_HW;
                nand_chip->ecc.calculate = atmel_nand_calculate;
                nand_chip->ecc.correct = atmel_nand_correct;
                nand_chip->ecc.hwctl = atmel_nand_hwctl;
                nand_chip->ecc.read_page = atmel_nand_read_page;
                nand_chip->ecc.bytes = 4;
+               nand_chip->ecc.strength = 1;
        }
  
        nand_chip->chip_delay = 20;             /* 20us command delay time */
  
 -      if (host->board->bus_width_16)  /* 16-bit bus width */
 +      if (host->board.bus_width_16)   /* 16-bit bus width */
                nand_chip->options |= NAND_BUSWIDTH_16;
  
        nand_chip->read_buf = atmel_read_buf;
        platform_set_drvdata(pdev, host);
        atmel_nand_enable(host);
  
 -      if (gpio_is_valid(host->board->det_pin)) {
 -              if (gpio_get_value(host->board->det_pin)) {
 +      if (gpio_is_valid(host->board.det_pin)) {
 +              if (gpio_get_value(host->board.det_pin)) {
                        printk(KERN_INFO "No SmartMedia card inserted.\n");
                        res = -ENXIO;
                        goto err_no_card;
                }
        }
  
 -      if (on_flash_bbt) {
 +      if (host->board.on_flash_bbt || on_flash_bbt) {
                printk(KERN_INFO "atmel_nand: Use On Flash BBT\n");
                nand_chip->bbt_options |= NAND_BBT_USE_FLASH;
        }
        }
  
        mtd->name = "atmel_nand";
 -      res = mtd_device_parse_register(mtd, NULL, NULL, host->board->parts,
 -                                      host->board->num_parts);
 +      ppdata.of_node = pdev->dev.of_node;
 +      res = mtd_device_parse_register(mtd, NULL, &ppdata,
 +                      host->board.parts, host->board.num_parts);
        if (!res)
                return res;
  
@@@ -745,21 -696,11 +746,21 @@@ static int __exit atmel_nand_remove(str
        return 0;
  }
  
 +#if defined(CONFIG_OF)
 +static const struct of_device_id atmel_nand_dt_ids[] = {
 +      { .compatible = "atmel,at91rm9200-nand" },
 +      { /* sentinel */ }
 +};
 +
 +MODULE_DEVICE_TABLE(of, atmel_nand_dt_ids);
 +#endif
 +
  static struct platform_driver atmel_nand_driver = {
        .remove         = __exit_p(atmel_nand_remove),
        .driver         = {
                .name   = "atmel_nand",
                .owner  = THIS_MODULE,
 +              .of_match_table = of_match_ptr(atmel_nand_dt_ids),
        },
  };
  
index 64c9cbaf86a1905abdb8b8663740af687b883db3,fc600431f519416f5eb44b021b8ad055e0f3706e..6908cdde3065e73b24509e8c9d32865f5befb1d9
@@@ -31,6 -31,7 +31,6 @@@
  #include <linux/mtd/partitions.h>
  
  #include <asm/mach-types.h>
 -#include <asm/system.h>
  
  #include <mach/reg_nand.h>
  #include <mach/reg_umi.h>
@@@ -475,6 -476,14 +475,14 @@@ static int __devinit bcm_umi_nand_probe
                        largepage_bbt.options = NAND_BBT_SCAN2NDPAGE;
                this->badblock_pattern = &largepage_bbt;
        }
+       /*
+        * FIXME: ecc strength value of 6 bits per 512 bytes of data is a
+        * conservative guess, given 13 ecc bytes and using bch alg.
+        * (Assume Galois field order m=15 to allow a margin of error.)
+        */
+       this->ecc.strength = 6;
  #endif
  
        /* Now finish off the scan, now that ecc.layout has been initialized. */
  
        /* Register the partitions */
        board_mtd->name = "bcm_umi-nand";
-       mtd_device_parse_register(board_mtd, NULL, 0, NULL, 0);
+       mtd_device_parse_register(board_mtd, NULL, NULL, NULL, 0);
  
        /* Return happy */
        return 0;
index 590dd5cceed66164ff93686f9f355818883ac0b3,c34dab17682e1b41c4800b202ca3c1b2cc9a3970..e8ea7107932e9a9f784007da5be11cf01e32d5dd
@@@ -835,7 -835,7 +835,7 @@@ int gpmi_send_command(struct gpmi_nand_
                | BM_GPMI_CTRL0_ADDRESS_INCREMENT
                | BF_GPMI_CTRL0_XFER_COUNT(this->command_length);
        pio[1] = pio[2] = 0;
 -      desc = channel->device->device_prep_slave_sg(channel,
 +      desc = dmaengine_prep_slave_sg(channel,
                                        (struct scatterlist *)pio,
                                        ARRAY_SIZE(pio), DMA_TRANS_NONE, 0);
        if (!desc) {
  
        sg_init_one(sgl, this->cmd_buffer, this->command_length);
        dma_map_sg(this->dev, sgl, 1, DMA_TO_DEVICE);
-       desc = dmaengine_prep_slave_sg(channel, sgl, 1, DMA_MEM_TO_DEV, 1);
 -      desc = channel->device->device_prep_slave_sg(channel,
++      desc = dmaengine_prep_slave_sg(channel,
+                               sgl, 1, DMA_MEM_TO_DEV,
+                               DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
        if (!desc) {
                pr_err("step 2 error\n");
                return -1;
@@@ -879,7 -882,8 +882,7 @@@ int gpmi_send_data(struct gpmi_nand_dat
                | BF_GPMI_CTRL0_ADDRESS(address)
                | BF_GPMI_CTRL0_XFER_COUNT(this->upper_len);
        pio[1] = 0;
 -      desc = channel->device->device_prep_slave_sg(channel,
 -                                      (struct scatterlist *)pio,
 +      desc = dmaengine_prep_slave_sg(channel, (struct scatterlist *)pio,
                                        ARRAY_SIZE(pio), DMA_TRANS_NONE, 0);
        if (!desc) {
                pr_err("step 1 error\n");
  
        /* [2] send DMA request */
        prepare_data_dma(this, DMA_TO_DEVICE);
 -      desc = channel->device->device_prep_slave_sg(channel, &this->data_sgl,
 +      desc = dmaengine_prep_slave_sg(channel, &this->data_sgl,
-                                               1, DMA_MEM_TO_DEV, 1);
+                                       1, DMA_MEM_TO_DEV,
+                                       DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
        if (!desc) {
                pr_err("step 2 error\n");
                return -1;
@@@ -914,7 -919,7 +918,7 @@@ int gpmi_read_data(struct gpmi_nand_dat
                | BF_GPMI_CTRL0_ADDRESS(BV_GPMI_CTRL0_ADDRESS__NAND_DATA)
                | BF_GPMI_CTRL0_XFER_COUNT(this->upper_len);
        pio[1] = 0;
 -      desc = channel->device->device_prep_slave_sg(channel,
 +      desc = dmaengine_prep_slave_sg(channel,
                                        (struct scatterlist *)pio,
                                        ARRAY_SIZE(pio), DMA_TRANS_NONE, 0);
        if (!desc) {
  
        /* [2] : send DMA request */
        prepare_data_dma(this, DMA_FROM_DEVICE);
 -      desc = channel->device->device_prep_slave_sg(channel, &this->data_sgl,
 +      desc = dmaengine_prep_slave_sg(channel, &this->data_sgl,
-                                       1, DMA_DEV_TO_MEM, 1);
+                                       1, DMA_DEV_TO_MEM,
+                                       DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
        if (!desc) {
                pr_err("step 2 error\n");
                return -1;
@@@ -970,8 -976,10 +975,10 @@@ int gpmi_send_page(struct gpmi_nand_dat
        pio[4] = payload;
        pio[5] = auxiliary;
  
-       desc = dmaengine_prep_slave_sg(channel, (struct scatterlist *)pio,
-                                       ARRAY_SIZE(pio), DMA_TRANS_NONE, 0);
 -      desc = channel->device->device_prep_slave_sg(channel,
++      desc = dmaengine_prep_slave_sg(channel,
+                                       (struct scatterlist *)pio,
+                                       ARRAY_SIZE(pio), DMA_TRANS_NONE,
+                                       DMA_CTRL_ACK);
        if (!desc) {
                pr_err("step 2 error\n");
                return -1;
@@@ -1004,7 -1012,7 +1011,7 @@@ int gpmi_read_page(struct gpmi_nand_dat
                | BF_GPMI_CTRL0_ADDRESS(address)
                | BF_GPMI_CTRL0_XFER_COUNT(0);
        pio[1] = 0;
 -      desc = channel->device->device_prep_slave_sg(channel,
 +      desc = dmaengine_prep_slave_sg(channel,
                                (struct scatterlist *)pio, 2,
                                DMA_TRANS_NONE, 0);
        if (!desc) {
        pio[3] = geo->page_size;
        pio[4] = payload;
        pio[5] = auxiliary;
 -      desc = channel->device->device_prep_slave_sg(channel,
 +      desc = dmaengine_prep_slave_sg(channel,
                                        (struct scatterlist *)pio,
-                                       ARRAY_SIZE(pio), DMA_TRANS_NONE, 1);
+                                       ARRAY_SIZE(pio), DMA_TRANS_NONE,
+                                       DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
        if (!desc) {
                pr_err("step 2 error\n");
                return -1;
                | BF_GPMI_CTRL0_ADDRESS(address)
                | BF_GPMI_CTRL0_XFER_COUNT(geo->page_size);
        pio[1] = 0;
 -      desc = channel->device->device_prep_slave_sg(channel,
+       pio[2] = 0; /* clear GPMI_HW_GPMI_ECCCTRL, disable the BCH. */
-                               (struct scatterlist *)pio, 2,
-                               DMA_TRANS_NONE, 1);
 +      desc = dmaengine_prep_slave_sg(channel,
+                               (struct scatterlist *)pio, 3,
+                               DMA_TRANS_NONE,
+                               DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
        if (!desc) {
                pr_err("step 3 error\n");
                return -1;
index 26b3c23b0b6f263a72678675eadb8ff673be5f2c,c44a03ee2b5f1977b498d92a564513f6f9474ef5..758148379b0e19d34e0e413884649060efa9090f
@@@ -193,7 -193,7 +193,7 @@@ static int efx_mtd_erase(struct mtd_inf
                erase->state = MTD_ERASE_DONE;
        } else {
                erase->state = MTD_ERASE_FAILED;
-               erase->fail_addr = 0xffffffff;
+               erase->fail_addr = MTD_FAIL_ADDR_UNKNOWN;
        }
        mtd_erase_callback(erase);
        return rc;
@@@ -263,10 -263,10 +263,10 @@@ static int efx_mtd_probe_device(struct 
                part->mtd.owner = THIS_MODULE;
                part->mtd.priv = efx_mtd;
                part->mtd.name = part->name;
-               part->mtd.erase = efx_mtd_erase;
-               part->mtd.read = efx_mtd->ops->read;
-               part->mtd.write = efx_mtd->ops->write;
-               part->mtd.sync = efx_mtd_sync;
+               part->mtd._erase = efx_mtd_erase;
+               part->mtd._read = efx_mtd->ops->read;
+               part->mtd._write = efx_mtd->ops->write;
+               part->mtd._sync = efx_mtd_sync;
  
                if (mtd_device_register(&part->mtd, NULL, 0))
                        goto fail;
@@@ -280,7 -280,7 +280,7 @@@ fail
                --part;
                efx_mtd_remove_partition(part);
        }
 -      /* mtd_device_register() returns 1 if the MTD table is full */
 +      /* Failure is unlikely here, but probably means we're out of memory */
        return -ENOMEM;
  }
  
@@@ -382,7 -382,7 +382,7 @@@ static int falcon_mtd_sync(struct mtd_i
        return rc;
  }
  
 -static struct efx_mtd_ops falcon_mtd_ops = {
 +static const struct efx_mtd_ops falcon_mtd_ops = {
        .read   = falcon_mtd_read,
        .erase  = falcon_mtd_erase,
        .write  = falcon_mtd_write,
@@@ -560,7 -560,7 +560,7 @@@ static int siena_mtd_sync(struct mtd_in
        return rc;
  }
  
 -static struct efx_mtd_ops siena_mtd_ops = {
 +static const struct efx_mtd_ops siena_mtd_ops = {
        .read   = siena_mtd_read,
        .erase  = siena_mtd_erase,
        .write  = siena_mtd_write,
@@@ -572,7 -572,7 +572,7 @@@ struct siena_nvram_type_info 
        const char *name;
  };
  
 -static struct siena_nvram_type_info siena_nvram_types[] = {
 +static const struct siena_nvram_type_info siena_nvram_types[] = {
        [MC_CMD_NVRAM_TYPE_DISABLED_CALLISTO]   = { 0, "sfc_dummy_phy" },
        [MC_CMD_NVRAM_TYPE_MC_FW]               = { 0, "sfc_mcfw" },
        [MC_CMD_NVRAM_TYPE_MC_FW_BACKUP]        = { 0, "sfc_mcfw_backup" },
@@@ -593,7 -593,7 +593,7 @@@ static int siena_mtd_probe_partition(st
                                     unsigned int type)
  {
        struct efx_mtd_partition *part = &efx_mtd->part[part_id];
 -      struct siena_nvram_type_info *info;
 +      const struct siena_nvram_type_info *info;
        size_t size, erase_size;
        bool protected;
        int rc;
@@@ -627,10 -627,11 +627,10 @@@ static int siena_mtd_get_fw_subtypes(st
                                     struct efx_mtd *efx_mtd)
  {
        struct efx_mtd_partition *part;
 -      uint16_t fw_subtype_list[MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_LEN /
 -                               sizeof(uint16_t)];
 +      uint16_t fw_subtype_list[MC_CMD_GET_BOARD_CFG_OUT_FW_SUBTYPE_LIST_MINNUM];
        int rc;
  
 -      rc = efx_mcdi_get_board_cfg(efx, NULL, fw_subtype_list);
 +      rc = efx_mcdi_get_board_cfg(efx, NULL, fw_subtype_list, NULL);
        if (rc)
                return rc;
  
diff --combined fs/jffs2/fs.c
index c0d5c9d770dadc8df1afbaaeaa5136813aa746ac,43052faa94e18d349874055034226a048001c57e..bb6f993ebca924dd39471163b586ded206096f62
@@@ -10,6 -10,8 +10,8 @@@
   *
   */
  
+ #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  #include <linux/capability.h>
  #include <linux/kernel.h>
  #include <linux/sched.h>
@@@ -39,7 -41,7 +41,7 @@@ int jffs2_do_setattr (struct inode *ino
        int ret;
        int alloc_type = ALLOC_NORMAL;
  
-       D1(printk(KERN_DEBUG "jffs2_setattr(): ino #%lu\n", inode->i_ino));
+       jffs2_dbg(1, "%s(): ino #%lu\n", __func__, inode->i_ino);
  
        /* Special cases - we don't want more than one data node
           for these types on the medium at any time. So setattr
@@@ -50,7 -52,8 +52,8 @@@
                /* For these, we don't actually need to read the old node */
                mdatalen = jffs2_encode_dev(&dev, inode->i_rdev);
                mdata = (char *)&dev;
-               D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of kdev_t\n", mdatalen));
+               jffs2_dbg(1, "%s(): Writing %d bytes of kdev_t\n",
+                         __func__, mdatalen);
        } else if (S_ISLNK(inode->i_mode)) {
                mutex_lock(&f->sem);
                mdatalen = f->metadata->size;
@@@ -66,7 -69,8 +69,8 @@@
                        return ret;
                }
                mutex_unlock(&f->sem);
-               D1(printk(KERN_DEBUG "jffs2_setattr(): Writing %d bytes of symlink target\n", mdatalen));
+               jffs2_dbg(1, "%s(): Writing %d bytes of symlink target\n",
+                         __func__, mdatalen);
        }
  
        ri = jffs2_alloc_raw_inode();
@@@ -233,7 -237,8 +237,8 @@@ void jffs2_evict_inode (struct inode *i
        struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
        struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
  
-       D1(printk(KERN_DEBUG "jffs2_evict_inode(): ino #%lu mode %o\n", inode->i_ino, inode->i_mode));
+       jffs2_dbg(1, "%s(): ino #%lu mode %o\n",
+                 __func__, inode->i_ino, inode->i_mode);
        truncate_inode_pages(&inode->i_data, 0);
        end_writeback(inode);
        jffs2_do_clear_inode(c, f);
@@@ -249,7 -254,7 +254,7 @@@ struct inode *jffs2_iget(struct super_b
        dev_t rdev = 0;
        int ret;
  
-       D1(printk(KERN_DEBUG "jffs2_iget(): ino == %lu\n", ino));
+       jffs2_dbg(1, "%s(): ino == %lu\n", __func__, ino);
  
        inode = iget_locked(sb, ino);
        if (!inode)
                /* Read the device numbers from the media */
                if (f->metadata->size != sizeof(jdev.old_id) &&
                    f->metadata->size != sizeof(jdev.new_id)) {
-                       printk(KERN_NOTICE "Device node has strange size %d\n", f->metadata->size);
+                       pr_notice("Device node has strange size %d\n",
+                                 f->metadata->size);
                        goto error_io;
                }
-               D1(printk(KERN_DEBUG "Reading device numbers from flash\n"));
+               jffs2_dbg(1, "Reading device numbers from flash\n");
                ret = jffs2_read_dnode(c, f, f->metadata, (char *)&jdev, 0, f->metadata->size);
                if (ret < 0) {
                        /* Eep */
-                       printk(KERN_NOTICE "Read device numbers for inode %lu failed\n", (unsigned long)inode->i_ino);
+                       pr_notice("Read device numbers for inode %lu failed\n",
+                                 (unsigned long)inode->i_ino);
                        goto error;
                }
                if (f->metadata->size == sizeof(jdev.old_id))
                break;
  
        default:
-               printk(KERN_WARNING "jffs2_read_inode(): Bogus imode %o for ino %lu\n", inode->i_mode, (unsigned long)inode->i_ino);
+               pr_warn("%s(): Bogus i_mode %o for ino %lu\n",
+                       __func__, inode->i_mode, (unsigned long)inode->i_ino);
        }
  
        mutex_unlock(&f->sem);
  
-       D1(printk(KERN_DEBUG "jffs2_read_inode() returning\n"));
+       jffs2_dbg(1, "jffs2_read_inode() returning\n");
        unlock_new_inode(inode);
        return inode;
  
@@@ -362,11 -370,13 +370,13 @@@ void jffs2_dirty_inode(struct inode *in
        struct iattr iattr;
  
        if (!(inode->i_state & I_DIRTY_DATASYNC)) {
-               D2(printk(KERN_DEBUG "jffs2_dirty_inode() not calling setattr() for ino #%lu\n", inode->i_ino));
+               jffs2_dbg(2, "%s(): not calling setattr() for ino #%lu\n",
+                         __func__, inode->i_ino);
                return;
        }
  
-       D1(printk(KERN_DEBUG "jffs2_dirty_inode() calling setattr() for ino #%lu\n", inode->i_ino));
+       jffs2_dbg(1, "%s(): calling setattr() for ino #%lu\n",
+                 __func__, inode->i_ino);
  
        iattr.ia_valid = ATTR_MODE|ATTR_UID|ATTR_GID|ATTR_ATIME|ATTR_MTIME|ATTR_CTIME;
        iattr.ia_mode = inode->i_mode;
@@@ -414,7 -424,8 +424,8 @@@ struct inode *jffs2_new_inode (struct i
        struct jffs2_inode_info *f;
        int ret;
  
-       D1(printk(KERN_DEBUG "jffs2_new_inode(): dir_i %ld, mode 0x%x\n", dir_i->i_ino, mode));
+       jffs2_dbg(1, "%s(): dir_i %ld, mode 0x%x\n",
+                 __func__, dir_i->i_ino, mode);
  
        c = JFFS2_SB_INFO(sb);
  
@@@ -504,11 -515,11 +515,11 @@@ int jffs2_do_fill_super(struct super_bl
  
  #ifndef CONFIG_JFFS2_FS_WRITEBUFFER
        if (c->mtd->type == MTD_NANDFLASH) {
-               printk(KERN_ERR "jffs2: Cannot operate on NAND flash unless jffs2 NAND support is compiled in.\n");
+               pr_err("Cannot operate on NAND flash unless jffs2 NAND support is compiled in\n");
                return -EINVAL;
        }
        if (c->mtd->type == MTD_DATAFLASH) {
-               printk(KERN_ERR "jffs2: Cannot operate on DataFlash unless jffs2 DataFlash support is compiled in.\n");
+               pr_err("Cannot operate on DataFlash unless jffs2 DataFlash support is compiled in\n");
                return -EINVAL;
        }
  #endif
         */
        if ((c->sector_size * blocks) != c->flash_size) {
                c->flash_size = c->sector_size * blocks;
-               printk(KERN_INFO "jffs2: Flash size not aligned to erasesize, reducing to %dKiB\n",
+               pr_info("Flash size not aligned to erasesize, reducing to %dKiB\n",
                        c->flash_size / 1024);
        }
  
        if (c->flash_size < 5*c->sector_size) {
-               printk(KERN_ERR "jffs2: Too few erase blocks (%d)\n", c->flash_size / c->sector_size);
+               pr_err("Too few erase blocks (%d)\n",
+                      c->flash_size / c->sector_size);
                return -EINVAL;
        }
  
        if ((ret = jffs2_do_mount_fs(c)))
                goto out_inohash;
  
-       D1(printk(KERN_DEBUG "jffs2_do_fill_super(): Getting root inode\n"));
+       jffs2_dbg(1, "%s(): Getting root inode\n", __func__);
        root_i = jffs2_iget(sb, 1);
        if (IS_ERR(root_i)) {
-               D1(printk(KERN_WARNING "get root inode failed\n"));
+               jffs2_dbg(1, "get root inode failed\n");
                ret = PTR_ERR(root_i);
                goto out_root;
        }
  
        ret = -ENOMEM;
  
-       D1(printk(KERN_DEBUG "jffs2_do_fill_super(): d_alloc_root()\n"));
 -      jffs2_dbg(1, "%s(): d_alloc_root()\n", __func__);
 -      sb->s_root = d_alloc_root(root_i);
++      jffs2_dbg(1, "%s(): d_make_root()\n", __func__);
 +      sb->s_root = d_make_root(root_i);
        if (!sb->s_root)
 -              goto out_root_i;
 +              goto out_root;
  
        sb->s_maxbytes = 0xFFFFFFFF;
        sb->s_blocksize = PAGE_CACHE_SIZE;
                jffs2_start_garbage_collect_thread(c);
        return 0;
  
 - out_root_i:
 -      iput(root_i);
  out_root:
        jffs2_free_ino_caches(c);
        jffs2_free_raw_node_refs(c);
@@@ -618,20 -632,21 +630,21 @@@ struct jffs2_inode_info *jffs2_gc_fetch
                */
                inode = ilookup(OFNI_BS_2SFFJ(c), inum);
                if (!inode) {
-                       D1(printk(KERN_DEBUG "ilookup() failed for ino #%u; inode is probably deleted.\n",
-                                 inum));
+                       jffs2_dbg(1, "ilookup() failed for ino #%u; inode is probably deleted.\n",
+                                 inum);
  
                        spin_lock(&c->inocache_lock);
                        ic = jffs2_get_ino_cache(c, inum);
                        if (!ic) {
-                               D1(printk(KERN_DEBUG "Inode cache for ino #%u is gone.\n", inum));
+                               jffs2_dbg(1, "Inode cache for ino #%u is gone\n",
+                                         inum);
                                spin_unlock(&c->inocache_lock);
                                return NULL;
                        }
                        if (ic->state != INO_STATE_CHECKEDABSENT) {
                                /* Wait for progress. Don't just loop */
-                               D1(printk(KERN_DEBUG "Waiting for ino #%u in state %d\n",
-                                         ic->ino, ic->state));
+                               jffs2_dbg(1, "Waiting for ino #%u in state %d\n",
+                                         ic->ino, ic->state);
                                sleep_on_spinunlock(&c->inocache_wq, &c->inocache_lock);
                        } else {
                                spin_unlock(&c->inocache_lock);
                        return ERR_CAST(inode);
        }
        if (is_bad_inode(inode)) {
-               printk(KERN_NOTICE "Eep. read_inode() failed for ino #%u. unlinked %d\n",
-                      inum, unlinked);
+               pr_notice("Eep. read_inode() failed for ino #%u. unlinked %d\n",
+                         inum, unlinked);
                /* NB. This will happen again. We need to do something appropriate here. */
                iput(inode);
                return ERR_PTR(-EIO);
diff --combined sound/soc/mxs/mxs-pcm.c
index 6ca1f46d84a49cc5d0cd5ab2b886975ec63879b9,420715eb6a1d61e1e44bb51db5de8882a98267f9..e373fbbc97a0eb7edeb06bb99dfee274a129249c
  #include <linux/platform_device.h>
  #include <linux/slab.h>
  #include <linux/dmaengine.h>
+ #include <linux/fsl/mxs-dma.h>
  
  #include <sound/core.h>
  #include <sound/initval.h>
  #include <sound/pcm.h>
  #include <sound/pcm_params.h>
  #include <sound/soc.h>
 +#include <sound/dmaengine_pcm.h>
  
- #include <mach/dma.h>
  #include "mxs-pcm.h"
  
 +struct mxs_pcm_dma_data {
 +      struct mxs_dma_data dma_data;
 +      struct mxs_pcm_dma_params *dma_params;
 +};
 +
  static struct snd_pcm_hardware snd_mxs_hardware = {
        .info                   = SNDRV_PCM_INFO_MMAP |
                                  SNDRV_PCM_INFO_MMAP_VALID |
  
  };
  
 -static void audio_dma_irq(void *data)
 -{
 -      struct snd_pcm_substream *substream = (struct snd_pcm_substream *)data;
 -      struct snd_pcm_runtime *runtime = substream->runtime;
 -      struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
 -
 -      iprtd->offset += iprtd->period_bytes;
 -      iprtd->offset %= iprtd->period_bytes * iprtd->periods;
 -      snd_pcm_period_elapsed(substream);
 -}
 -
  static bool filter(struct dma_chan *chan, void *param)
  {
 -      struct mxs_pcm_runtime_data *iprtd = param;
 -      struct mxs_pcm_dma_params *dma_params = iprtd->dma_params;
 +      struct mxs_pcm_dma_data *pcm_dma_data = param;
 +      struct mxs_pcm_dma_params *dma_params = pcm_dma_data->dma_params;
  
        if (!mxs_dma_is_apbx(chan))
                return false;
        if (chan->chan_id != dma_params->chan_num)
                return false;
  
 -      chan->private = &iprtd->dma_data;
 +      chan->private = &pcm_dma_data->dma_data;
  
        return true;
  }
  
 -static int mxs_dma_alloc(struct snd_pcm_substream *substream,
 -                              struct snd_pcm_hw_params *params)
 -{
 -      struct snd_soc_pcm_runtime *rtd = substream->private_data;
 -      struct snd_pcm_runtime *runtime = substream->runtime;
 -      struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
 -      dma_cap_mask_t mask;
 -
 -      iprtd->dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
 -
 -      dma_cap_zero(mask);
 -      dma_cap_set(DMA_SLAVE, mask);
 -      iprtd->dma_data.chan_irq = iprtd->dma_params->chan_irq;
 -      iprtd->dma_chan = dma_request_channel(mask, filter, iprtd);
 -      if (!iprtd->dma_chan)
 -              return -EINVAL;
 -
 -      return 0;
 -}
 -
  static int snd_mxs_pcm_hw_params(struct snd_pcm_substream *substream,
                                struct snd_pcm_hw_params *params)
  {
 -      struct snd_pcm_runtime *runtime = substream->runtime;
 -      struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
 -      unsigned long dma_addr;
 -      struct dma_chan *chan;
 -      int ret;
 -
 -      ret = mxs_dma_alloc(substream, params);
 -      if (ret)
 -              return ret;
 -      chan = iprtd->dma_chan;
 -
 -      iprtd->size = params_buffer_bytes(params);
 -      iprtd->periods = params_periods(params);
 -      iprtd->period_bytes = params_period_bytes(params);
 -      iprtd->offset = 0;
 -      iprtd->period_time = HZ / (params_rate(params) /
 -                      params_period_size(params));
 -
        snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer);
  
 -      dma_addr = runtime->dma_addr;
 -
 -      iprtd->buf = substream->dma_buffer.area;
 -
 -      iprtd->desc = chan->device->device_prep_dma_cyclic(chan, dma_addr,
 -                      iprtd->period_bytes * iprtd->periods,
 -                      iprtd->period_bytes,
 -                      substream->stream == SNDRV_PCM_STREAM_PLAYBACK ?
 -                      DMA_MEM_TO_DEV : DMA_DEV_TO_MEM);
 -      if (!iprtd->desc) {
 -              dev_err(&chan->dev->device, "cannot prepare slave dma\n");
 -              return -EINVAL;
 -      }
 -
 -      iprtd->desc->callback = audio_dma_irq;
 -      iprtd->desc->callback_param = substream;
 -
        return 0;
  }
  
 -static int snd_mxs_pcm_hw_free(struct snd_pcm_substream *substream)
 -{
 -      struct snd_pcm_runtime *runtime = substream->runtime;
 -      struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
 -
 -      if (iprtd->dma_chan) {
 -              dma_release_channel(iprtd->dma_chan);
 -              iprtd->dma_chan = NULL;
 -      }
 -
 -      return 0;
 -}
 -
 -static int snd_mxs_pcm_trigger(struct snd_pcm_substream *substream, int cmd)
 -{
 -      struct snd_pcm_runtime *runtime = substream->runtime;
 -      struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
 -
 -      switch (cmd) {
 -      case SNDRV_PCM_TRIGGER_START:
 -      case SNDRV_PCM_TRIGGER_RESUME:
 -      case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 -              dmaengine_submit(iprtd->desc);
 -
 -              break;
 -      case SNDRV_PCM_TRIGGER_STOP:
 -      case SNDRV_PCM_TRIGGER_SUSPEND:
 -      case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 -              dmaengine_terminate_all(iprtd->dma_chan);
 -
 -              break;
 -      default:
 -              return -EINVAL;
 -      }
 -
 -      return 0;
 -}
 -
 -static snd_pcm_uframes_t snd_mxs_pcm_pointer(
 -              struct snd_pcm_substream *substream)
 -{
 -      struct snd_pcm_runtime *runtime = substream->runtime;
 -      struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
 -
 -      return bytes_to_frames(substream->runtime, iprtd->offset);
 -}
 -
  static int snd_mxs_open(struct snd_pcm_substream *substream)
  {
 -      struct snd_pcm_runtime *runtime = substream->runtime;
 -      struct mxs_pcm_runtime_data *iprtd;
 +      struct snd_soc_pcm_runtime *rtd = substream->private_data;
 +      struct mxs_pcm_dma_data *pcm_dma_data;
        int ret;
  
 -      iprtd = kzalloc(sizeof(*iprtd), GFP_KERNEL);
 -      if (iprtd == NULL)
 +      pcm_dma_data = kzalloc(sizeof(*pcm_dma_data), GFP_KERNEL);
 +      if (pcm_dma_data == NULL)
                return -ENOMEM;
 -      runtime->private_data = iprtd;
  
 -      ret = snd_pcm_hw_constraint_integer(substream->runtime,
 -                      SNDRV_PCM_HW_PARAM_PERIODS);
 -      if (ret < 0) {
 -              kfree(iprtd);
 +      pcm_dma_data->dma_params = snd_soc_dai_get_dma_data(rtd->cpu_dai, substream);
 +      pcm_dma_data->dma_data.chan_irq = pcm_dma_data->dma_params->chan_irq;
 +
 +      ret = snd_dmaengine_pcm_open(substream, filter, pcm_dma_data);
 +      if (ret) {
 +              kfree(pcm_dma_data);
                return ret;
        }
  
        snd_soc_set_runtime_hwparams(substream, &snd_mxs_hardware);
  
 +      snd_dmaengine_pcm_set_data(substream, pcm_dma_data);
 +
        return 0;
  }
  
  static int snd_mxs_close(struct snd_pcm_substream *substream)
  {
 -      struct snd_pcm_runtime *runtime = substream->runtime;
 -      struct mxs_pcm_runtime_data *iprtd = runtime->private_data;
 +      struct mxs_pcm_dma_data *pcm_dma_data = snd_dmaengine_pcm_get_data(substream);
  
 -      kfree(iprtd);
 +      snd_dmaengine_pcm_close(substream);
 +      kfree(pcm_dma_data);
  
        return 0;
  }
@@@ -140,8 -244,9 +140,8 @@@ static struct snd_pcm_ops mxs_pcm_ops 
        .close          = snd_mxs_close,
        .ioctl          = snd_pcm_lib_ioctl,
        .hw_params      = snd_mxs_pcm_hw_params,
 -      .hw_free        = snd_mxs_pcm_hw_free,
 -      .trigger        = snd_mxs_pcm_trigger,
 -      .pointer        = snd_mxs_pcm_pointer,
 +      .trigger        = snd_dmaengine_pcm_trigger,
 +      .pointer        = snd_dmaengine_pcm_pointer,
        .mmap           = snd_mxs_pcm_mmap,
  };
  
diff --combined sound/soc/mxs/mxs-saif.c
index 12be05b16880aacc05d896d15564fd548686bb55,ce591123d994f504a44c6d0a7811b31f1b113fa7..53f4fd8fecedc81d418e38730b7b3d1040967ad4
  #include <linux/clk.h>
  #include <linux/delay.h>
  #include <linux/time.h>
+ #include <linux/fsl/mxs-dma.h>
  #include <sound/core.h>
  #include <sound/pcm.h>
  #include <sound/pcm_params.h>
  #include <sound/soc.h>
  #include <sound/saif.h>
- #include <mach/dma.h>
  #include <asm/mach-types.h>
  #include <mach/hardware.h>
  #include <mach/mxs.h>
@@@ -630,7 -630,7 +630,7 @@@ static int mxs_saif_probe(struct platfo
        if (pdev->id >= ARRAY_SIZE(mxs_saif))
                return -EINVAL;
  
 -      saif = kzalloc(sizeof(*saif), GFP_KERNEL);
 +      saif = devm_kzalloc(&pdev->dev, sizeof(*saif), GFP_KERNEL);
        if (!saif)
                return -ENOMEM;
  
                ret = PTR_ERR(saif->clk);
                dev_err(&pdev->dev, "Cannot get the clock: %d\n",
                        ret);
 -              goto failed_clk;
 +              return ret;
        }
  
        iores = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 -      if (!iores) {
 -              ret = -ENODEV;
 -              dev_err(&pdev->dev, "failed to get io resource: %d\n",
 -                      ret);
 -              goto failed_get_resource;
 -      }
  
 -      if (!request_mem_region(iores->start, resource_size(iores),
 -                              "mxs-saif")) {
 -              dev_err(&pdev->dev, "request_mem_region failed\n");
 -              ret = -EBUSY;
 -              goto failed_get_resource;
 -      }
 -
 -      saif->base = ioremap(iores->start, resource_size(iores));
 +      saif->base = devm_request_and_ioremap(&pdev->dev, iores);
        if (!saif->base) {
                dev_err(&pdev->dev, "ioremap failed\n");
                ret = -ENODEV;
 -              goto failed_ioremap;
 +              goto failed_get_resource;
        }
  
        dmares = platform_get_resource(pdev, IORESOURCE_DMA, 0);
                ret = -ENODEV;
                dev_err(&pdev->dev, "failed to get dma resource: %d\n",
                        ret);
 -              goto failed_ioremap;
 +              goto failed_get_resource;
        }
        saif->dma_param.chan_num = dmares->start;
  
                ret = saif->irq;
                dev_err(&pdev->dev, "failed to get irq resource: %d\n",
                        ret);
 -              goto failed_get_irq1;
 +              goto failed_get_resource;
        }
  
        saif->dev = &pdev->dev;
 -      ret = request_irq(saif->irq, mxs_saif_irq, 0, "mxs-saif", saif);
 +      ret = devm_request_irq(&pdev->dev, saif->irq, mxs_saif_irq, 0,
 +                             "mxs-saif", saif);
        if (ret) {
                dev_err(&pdev->dev, "failed to request irq\n");
 -              goto failed_get_irq1;
 +              goto failed_get_resource;
        }
  
        saif->dma_param.chan_irq = platform_get_irq(pdev, 1);
                ret = saif->dma_param.chan_irq;
                dev_err(&pdev->dev, "failed to get dma irq resource: %d\n",
                        ret);
 -              goto failed_get_irq2;
 +              goto failed_get_resource;
        }
  
        platform_set_drvdata(pdev, saif);
        ret = snd_soc_register_dai(&pdev->dev, &mxs_saif_dai);
        if (ret) {
                dev_err(&pdev->dev, "register DAI failed\n");
 -              goto failed_register;
 +              goto failed_get_resource;
        }
  
        saif->soc_platform_pdev = platform_device_alloc(
@@@ -728,19 -740,36 +728,19 @@@ failed_pdev_add
        platform_device_put(saif->soc_platform_pdev);
  failed_pdev_alloc:
        snd_soc_unregister_dai(&pdev->dev);
 -failed_register:
 -failed_get_irq2:
 -      free_irq(saif->irq, saif);
 -failed_get_irq1:
 -      iounmap(saif->base);
 -failed_ioremap:
 -      release_mem_region(iores->start, resource_size(iores));
  failed_get_resource:
        clk_put(saif->clk);
 -failed_clk:
 -      kfree(saif);
  
        return ret;
  }
  
  static int __devexit mxs_saif_remove(struct platform_device *pdev)
  {
 -      struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        struct mxs_saif *saif = platform_get_drvdata(pdev);
  
        platform_device_unregister(saif->soc_platform_pdev);
 -
        snd_soc_unregister_dai(&pdev->dev);
 -
 -      iounmap(saif->base);
 -      release_mem_region(res->start, resource_size(res));
 -      free_irq(saif->irq, saif);
 -
        clk_put(saif->clk);
 -      kfree(saif);
  
        return 0;
  }