Merge branch 'for-rmk' of git://source.mvista.com/git/linux-davinci-2.6.git
authorRussell King <rmk@dyn-67.arm.linux.org.uk>
Thu, 9 Oct 2008 20:33:05 +0000 (21:33 +0100)
committerRussell King <rmk+kernel@arm.linux.org.uk>
Thu, 9 Oct 2008 20:33:05 +0000 (21:33 +0100)
Merge branch 'davinci' into devel

1  2 
MAINTAINERS
arch/arm/Kconfig
arch/arm/mach-davinci/board-evm.c
arch/arm/mach-davinci/gpio.c
arch/arm/mach-mx3/pcm037.c
arch/arm/plat-omap/devices.c
drivers/video/atmel_lcdfb.c

diff --combined MAINTAINERS
@@@ -466,12 -466,6 +466,12 @@@ M:       kernel@wantstofly.or
  L:    linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
  S:    Maintained
  
 +ARM/AFEB9260 MACHINE SUPPORT
 +P:    Sergey Lapin
 +M:    slapin@ossfans.org
 +L:    linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
 +S:    Maintained
 +
  ARM/AJECO 1ARM MACHINE SUPPORT
  P:    Lennert Buytenhek
  M:    kernel@wantstofly.org
@@@ -497,7 -491,7 +497,7 @@@ M: kernel@wantstofly.or
  L:    linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
  S:    Maintained
  
 -ARM/COMPULAB CM-X270/EM-X270 MACHINE SUPPORT
 +ARM/COMPULAB CM-X270/EM-X270 and CM-X300 MACHINE SUPPORT
  P:    Mike Rapoport
  M:    mike@compulab.co.il
  L:    linux-arm-kernel@lists.arm.linux.org.uk (subscribers-only)
@@@ -629,12 -623,6 +629,12 @@@ M:       marek.vasut@gmail.co
  W:    http://hackndev.com
  S:    Maintained
  
 +ARM/PALMZ72 SUPPORT
 +P:     Sergey Lapin
 +M:     slapin@ossfans.org
 +W:     http://hackndev.com
 +S:     Maintained
 +
  ARM/PLEB SUPPORT
  P:    Peter Chubb
  M:    pleb@gelato.unsw.edu.au
@@@ -4377,7 -4365,7 +4377,7 @@@ S:      Maintaine
  USB VIDEO CLASS
  P:    Laurent Pinchart
  M:    laurent.pinchart@skynet.be
- L:    linx-uvc-devel@berlios.de
+ L:    linux-uvc-devel@lists.berlios.de
  L:    video4linux-list@redhat.com
  W:    http://linux-uvc.berlios.de
  S:    Maintained
diff --combined arch/arm/Kconfig
@@@ -148,6 -148,7 +148,6 @@@ config ARCH_MAY_HAVE_PC_FD
  
  config ZONE_DMA
        bool
 -      default y
  
  config GENERIC_ISA_DMA
        bool
@@@ -177,11 -178,6 +177,11 @@@ config OPROFILE_MPCOR
  config OPROFILE_ARM11_CORE
        bool
  
 +config OPROFILE_ARMV7
 +      def_bool y
 +      depends on CPU_V7 && !SMP
 +      bool
 +
  endif
  
  config VECTORS_BASE
@@@ -249,7 -245,6 +249,7 @@@ config ARCH_CLPS750
        select TIMER_ACORN
        select ISA
        select NO_IOPORT
 +      select ARCH_SPARSEMEM_ENABLE
        help
          Support for the Cirrus Logic PS7500FE system-on-a-chip.
  
@@@ -311,7 -306,6 +311,7 @@@ config ARCH_IOP13X
        select PLAT_IOP
        select PCI
        select ARCH_SUPPORTS_MSI
 +      select VMSPLIT_1G
        help
          Support for Intel's IOP13XX (XScale) family of processors.
  
@@@ -356,7 -350,6 +356,7 @@@ config ARCH_IXP4X
        select GENERIC_GPIO
        select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
 +      select ZONE_DMA if PCI
        help
          Support for Intel's IXP4XX (XScale) family of processors.
  
@@@ -471,7 -464,6 +471,7 @@@ config ARCH_RP
        select HAVE_PATA_PLATFORM
        select ISA_DMA_API
        select NO_IOPORT
 +      select ARCH_SPARSEMEM_ENABLE
        help
          On the Acorn Risc-PC, Linux can support the internal IDE disk and
          CD-ROM interface, serial and parallel port, and the floppy drive.
  config ARCH_SA1100
        bool "SA1100-based"
        select ISA
 -      select ARCH_DISCONTIGMEM_ENABLE
        select ARCH_SPARSEMEM_ENABLE
 -      select ARCH_SELECT_MEMORY_MODEL
        select ARCH_MTD_XIP
        select GENERIC_GPIO
        select GENERIC_TIME
@@@ -503,7 -497,6 +503,7 @@@ config ARCH_SHAR
        bool "Shark"
        select ISA
        select ISA_DMA
 +      select ZONE_DMA
        select PCI
        help
          Support for the StrongARM based Digital DNARD machine, also known
  
  config ARCH_LH7A40X
        bool "Sharp LH7A40X"
 +      select ARCH_DISCONTIGMEM_ENABLE if !LH7A40X_CONTIGMEM
 +      select ARCH_SPARSEMEM_ENABLE if !LH7A40X_CONTIGMEM
        help
          Say Y here for systems based on one of the Sharp LH7A40X
          System on a Chip processors.  These CPUs include an ARM922T
@@@ -524,8 -515,8 +524,9 @@@ config ARCH_DAVINC
        select GENERIC_TIME
        select GENERIC_CLOCKEVENTS
        select GENERIC_GPIO
+       select ARCH_REQUIRE_GPIOLIB
        select HAVE_CLK
 +      select ZONE_DMA
        help
          Support for TI's DaVinci platform.
  
@@@ -744,29 -735,6 +745,29 @@@ config SM
  
          If you don't know what to do here, say N.
  
 +choice
 +      prompt "Memory split"
 +      default VMSPLIT_3G
 +      help
 +        Select the desired split between kernel and user memory.
 +
 +        If you are not absolutely sure what you are doing, leave this
 +        option alone!
 +
 +      config VMSPLIT_3G
 +              bool "3G/1G user/kernel split"
 +      config VMSPLIT_2G
 +              bool "2G/2G user/kernel split"
 +      config VMSPLIT_1G
 +              bool "1G/3G user/kernel split"
 +endchoice
 +
 +config PAGE_OFFSET
 +      hex
 +      default 0x40000000 if VMSPLIT_1G
 +      default 0x80000000 if VMSPLIT_2G
 +      default 0xC0000000
 +
  config NR_CPUS
        int "Maximum number of CPUs (2-32)"
        range 2 32
@@@ -848,18 -816,20 +849,18 @@@ config ARCH_FLATMEM_HAS_HOLE
        default y
        depends on FLATMEM
  
 +# Discontigmem is deprecated
  config ARCH_DISCONTIGMEM_ENABLE
        bool
 -      default (ARCH_LH7A40X && !LH7A40X_CONTIGMEM)
 -      help
 -        Say Y to support efficient handling of discontiguous physical memory,
 -        for architectures which are either NUMA (Non-Uniform Memory Access)
 -        or have huge holes in the physical address space for other reasons.
 -        See <file:Documentation/vm/numa> for more.
  
  config ARCH_SPARSEMEM_ENABLE
        bool
  
 +config ARCH_SPARSEMEM_DEFAULT
 +      def_bool ARCH_SPARSEMEM_ENABLE
 +
  config ARCH_SELECT_MEMORY_MODEL
 -      bool
 +      def_bool ARCH_DISCONTIGMEM_ENABLE && ARCH_SPARSEMEM_ENABLE
  
  config NODES_SHIFT
        int
@@@ -876,7 -846,7 +877,7 @@@ config LED
                   ARCH_LUBBOCK || MACH_MAINSTONE || ARCH_NETWINDER || \
                   ARCH_OMAP || ARCH_P720T || ARCH_PXA_IDP || \
                   ARCH_SA1100 || ARCH_SHARK || ARCH_VERSATILE || \
 -                 ARCH_AT91 || MACH_TRIZEPS4 || ARCH_DAVINCI || \
 +                 ARCH_AT91 || ARCH_DAVINCI || \
                   ARCH_KS8695 || MACH_RD88F5182
        help
          If you say Y here, the LEDs on your machine will be used
@@@ -1036,9 -1006,9 +1037,9 @@@ config ATAGS_PRO
  
  endmenu
  
 -if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX || ARCH_PXA)
 +menu "CPU Power Management"
  
 -menu "CPU Frequency scaling"
 +if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX || ARCH_PXA)
  
  source "drivers/cpufreq/Kconfig"
  
@@@ -1078,12 -1048,10 +1079,12 @@@ config CPU_FREQ_PX
        default y
        select CPU_FREQ_DEFAULT_GOV_USERSPACE
  
 -endmenu
 -
  endif
  
 +source "drivers/cpuidle/Kconfig"
 +
 +endmenu
 +
  menu "Floating point emulation"
  
  comment "At least one emulation must be selected"
@@@ -1235,8 -1203,6 +1236,8 @@@ source "drivers/power/Kconfig
  
  source "drivers/hwmon/Kconfig"
  
 +source "drivers/thermal/Kconfig"
 +
  source "drivers/watchdog/Kconfig"
  
  source "drivers/ssb/Kconfig"
@@@ -1257,10 -1223,6 +1258,10 @@@ source "drivers/usb/Kconfig
  
  source "drivers/mmc/Kconfig"
  
 +source "drivers/memstick/Kconfig"
 +
 +source "drivers/accessibility/Kconfig"
 +
  source "drivers/leds/Kconfig"
  
  source "drivers/rtc/Kconfig"
@@@ -1269,8 -1231,6 +1270,8 @@@ source "drivers/dma/Kconfig
  
  source "drivers/dca/Kconfig"
  
 +source "drivers/auxdisplay/Kconfig"
 +
  source "drivers/regulator/Kconfig"
  
  source "drivers/uio/Kconfig"
  #include <linux/init.h>
  #include <linux/dma-mapping.h>
  #include <linux/platform_device.h>
+ #include <linux/gpio.h>
+ #include <linux/leds.h>
+ #include <linux/i2c.h>
+ #include <linux/i2c/pcf857x.h>
+ #include <linux/i2c/at24.h>
  #include <linux/mtd/mtd.h>
  #include <linux/mtd/partitions.h>
  #include <linux/mtd/physmap.h>
 +#include <linux/io.h>
  
  #include <asm/setup.h>
 -#include <asm/io.h>
  #include <asm/mach-types.h>
- #include <mach/hardware.h>
  
  #include <asm/mach/arch.h>
  #include <asm/mach/map.h>
  #include <asm/mach/flash.h>
  
+ #include <mach/hardware.h>
  #include <mach/common.h>
+ #include <mach/i2c.h>
  
  /* other misc. init functions */
  void __init davinci_psc_init(void);
@@@ -34,10 -42,10 +42,10 @@@ void __init davinci_irq_init(void)
  void __init davinci_map_common_io(void);
  void __init davinci_init_common_hw(void);
  
- /* NOR Flash base address set to CS0 by default */
- #define NOR_FLASH_PHYS 0x02000000
+ #if defined(CONFIG_MTD_PHYSMAP) || \
+     defined(CONFIG_MTD_PHYSMAP_MODULE)
  
- static struct mtd_partition davinci_evm_partitions[] = {
+ static struct mtd_partition davinci_evm_norflash_partitions[] = {
        /* bootloader (U-Boot, etc) in first 4 sectors */
        {
                .name           = "bootloader",
        }
  };
  
- static struct physmap_flash_data davinci_evm_flash_data = {
+ static struct physmap_flash_data davinci_evm_norflash_data = {
        .width          = 2,
-       .parts          = davinci_evm_partitions,
-       .nr_parts       = ARRAY_SIZE(davinci_evm_partitions),
+       .parts          = davinci_evm_norflash_partitions,
+       .nr_parts       = ARRAY_SIZE(davinci_evm_norflash_partitions),
  };
  
  /* NOTE: CFI probe will correctly detect flash part as 32M, but EMIF
   * limits addresses to 16M, so using addresses past 16M will wrap */
- static struct resource davinci_evm_flash_resource = {
-       .start          = NOR_FLASH_PHYS,
-       .end            = NOR_FLASH_PHYS + SZ_16M - 1,
+ static struct resource davinci_evm_norflash_resource = {
+       .start          = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE,
+       .end            = DAVINCI_ASYNC_EMIF_DATA_CE0_BASE + SZ_16M - 1,
        .flags          = IORESOURCE_MEM,
  };
  
- static struct platform_device davinci_evm_flash_device = {
+ static struct platform_device davinci_evm_norflash_device = {
        .name           = "physmap-flash",
        .id             = 0,
        .dev            = {
-               .platform_data  = &davinci_evm_flash_data,
+               .platform_data  = &davinci_evm_norflash_data,
        },
        .num_resources  = 1,
-       .resource       = &davinci_evm_flash_resource,
+       .resource       = &davinci_evm_norflash_resource,
+ };
+ #endif
+ #if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
+     defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
+ static struct resource ide_resources[] = {
+       {
+               .start          = DAVINCI_CFC_ATA_BASE,
+               .end            = DAVINCI_CFC_ATA_BASE + 0x7ff,
+               .flags          = IORESOURCE_MEM,
+       },
+       {
+               .start          = IRQ_IDE,
+               .end            = IRQ_IDE,
+               .flags          = IORESOURCE_IRQ,
+       },
+ };
+ static u64 ide_dma_mask = DMA_32BIT_MASK;
+ static struct platform_device ide_dev = {
+       .name           = "palm_bk3710",
+       .id             = -1,
+       .resource       = ide_resources,
+       .num_resources  = ARRAY_SIZE(ide_resources),
+       .dev = {
+               .dma_mask               = &ide_dma_mask,
+               .coherent_dma_mask      = DMA_32BIT_MASK,
+       },
+ };
+ #endif
+ /*----------------------------------------------------------------------*/
+ /*
+  * I2C GPIO expanders
+  */
+ #define PCF_Uxx_BASE(x)       (DAVINCI_N_GPIO + ((x) * 8))
+ /* U2 -- LEDs */
+ static struct gpio_led evm_leds[] = {
+       { .name = "DS8", .active_low = 1,
+               .default_trigger = "heartbeat", },
+       { .name = "DS7", .active_low = 1, },
+       { .name = "DS6", .active_low = 1, },
+       { .name = "DS5", .active_low = 1, },
+       { .name = "DS4", .active_low = 1, },
+       { .name = "DS3", .active_low = 1, },
+       { .name = "DS2", .active_low = 1,
+               .default_trigger = "mmc0", },
+       { .name = "DS1", .active_low = 1,
+               .default_trigger = "ide-disk", },
+ };
+ static const struct gpio_led_platform_data evm_led_data = {
+       .num_leds       = ARRAY_SIZE(evm_leds),
+       .leds           = evm_leds,
+ };
+ static struct platform_device *evm_led_dev;
+ static int
+ evm_led_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
+ {
+       struct gpio_led *leds = evm_leds;
+       int status;
+       while (ngpio--) {
+               leds->gpio = gpio++;
+               leds++;
+       }
+       /* what an extremely annoying way to be forced to handle
+        * device unregistration ...
+        */
+       evm_led_dev = platform_device_alloc("leds-gpio", 0);
+       platform_device_add_data(evm_led_dev,
+                       &evm_led_data, sizeof evm_led_data);
+       evm_led_dev->dev.parent = &client->dev;
+       status = platform_device_add(evm_led_dev);
+       if (status < 0) {
+               platform_device_put(evm_led_dev);
+               evm_led_dev = NULL;
+       }
+       return status;
+ }
+ static int
+ evm_led_teardown(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
+ {
+       if (evm_led_dev) {
+               platform_device_unregister(evm_led_dev);
+               evm_led_dev = NULL;
+       }
+       return 0;
+ }
+ static struct pcf857x_platform_data pcf_data_u2 = {
+       .gpio_base      = PCF_Uxx_BASE(0),
+       .setup          = evm_led_setup,
+       .teardown       = evm_led_teardown,
+ };
+ /* U18 - A/V clock generator and user switch */
+ static int sw_gpio;
+ static ssize_t
+ sw_show(struct device *d, struct device_attribute *a, char *buf)
+ {
+       char *s = gpio_get_value_cansleep(sw_gpio) ? "on\n" : "off\n";
+       strcpy(buf, s);
+       return strlen(s);
+ }
+ static DEVICE_ATTR(user_sw, S_IRUGO, sw_show, NULL);
+ static int
+ evm_u18_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
+ {
+       int     status;
+       /* export dip switch option */
+       sw_gpio = gpio + 7;
+       status = gpio_request(sw_gpio, "user_sw");
+       if (status == 0)
+               status = gpio_direction_input(sw_gpio);
+       if (status == 0)
+               status = device_create_file(&client->dev, &dev_attr_user_sw);
+       else
+               gpio_free(sw_gpio);
+       if (status != 0)
+               sw_gpio = -EINVAL;
+       /* audio PLL:  48 kHz (vs 44.1 or 32), single rate (vs double) */
+       gpio_request(gpio + 3, "pll_fs2");
+       gpio_direction_output(gpio + 3, 0);
+       gpio_request(gpio + 2, "pll_fs1");
+       gpio_direction_output(gpio + 2, 0);
+       gpio_request(gpio + 1, "pll_sr");
+       gpio_direction_output(gpio + 1, 0);
+       return 0;
+ }
+ static int
+ evm_u18_teardown(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
+ {
+       gpio_free(gpio + 1);
+       gpio_free(gpio + 2);
+       gpio_free(gpio + 3);
+       if (sw_gpio > 0) {
+               device_remove_file(&client->dev, &dev_attr_user_sw);
+               gpio_free(sw_gpio);
+       }
+       return 0;
+ }
+ static struct pcf857x_platform_data pcf_data_u18 = {
+       .gpio_base      = PCF_Uxx_BASE(1),
+       .n_latch        = (1 << 3) | (1 << 2) | (1 << 1),
+       .setup          = evm_u18_setup,
+       .teardown       = evm_u18_teardown,
  };
  
+ /* U35 - various I/O signals used to manage USB, CF, ATA, etc */
+ static int
+ evm_u35_setup(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
+ {
+       /* p0 = nDRV_VBUS (initial:  don't supply it) */
+       gpio_request(gpio + 0, "nDRV_VBUS");
+       gpio_direction_output(gpio + 0, 1);
+       /* p1 = VDDIMX_EN */
+       gpio_request(gpio + 1, "VDDIMX_EN");
+       gpio_direction_output(gpio + 1, 1);
+       /* p2 = VLYNQ_EN */
+       gpio_request(gpio + 2, "VLYNQ_EN");
+       gpio_direction_output(gpio + 2, 1);
+       /* p3 = n3V3_CF_RESET (initial: stay in reset) */
+       gpio_request(gpio + 3, "nCF_RESET");
+       gpio_direction_output(gpio + 3, 0);
+       /* (p4 unused) */
+       /* p5 = 1V8_WLAN_RESET (initial: stay in reset) */
+       gpio_request(gpio + 5, "WLAN_RESET");
+       gpio_direction_output(gpio + 5, 1);
+       /* p6 = nATA_SEL (initial: select) */
+       gpio_request(gpio + 6, "nATA_SEL");
+       gpio_direction_output(gpio + 6, 0);
+       /* p7 = nCF_SEL (initial: deselect) */
+       gpio_request(gpio + 7, "nCF_SEL");
+       gpio_direction_output(gpio + 7, 1);
+       return 0;
+ }
+ static int
+ evm_u35_teardown(struct i2c_client *client, int gpio, unsigned ngpio, void *c)
+ {
+       gpio_free(gpio + 7);
+       gpio_free(gpio + 6);
+       gpio_free(gpio + 5);
+       gpio_free(gpio + 3);
+       gpio_free(gpio + 2);
+       gpio_free(gpio + 1);
+       gpio_free(gpio + 0);
+       return 0;
+ }
+ static struct pcf857x_platform_data pcf_data_u35 = {
+       .gpio_base      = PCF_Uxx_BASE(2),
+       .setup          = evm_u35_setup,
+       .teardown       = evm_u35_teardown,
+ };
+ /*----------------------------------------------------------------------*/
+ /* Most of this EEPROM is unused, but U-Boot uses some data:
+  *  - 0x7f00, 6 bytes Ethernet Address
+  *  - 0x0039, 1 byte NTSC vs PAL (bit 0x80 == PAL)
+  *  - ... newer boards may have more
+  */
+ static struct at24_platform_data eeprom_info = {
+       .byte_len       = (256*1024) / 8,
+       .page_size      = 64,
+       .flags          = AT24_FLAG_ADDR16,
+ };
+ static struct i2c_board_info __initdata i2c_info[] =  {
+       {
+               I2C_BOARD_INFO("pcf8574", 0x38),
+               .platform_data  = &pcf_data_u2,
+       },
+       {
+               I2C_BOARD_INFO("pcf8574", 0x39),
+               .platform_data  = &pcf_data_u18,
+       },
+       {
+               I2C_BOARD_INFO("pcf8574", 0x3a),
+               .platform_data  = &pcf_data_u35,
+       },
+       {
+               I2C_BOARD_INFO("24c256", 0x50),
+               .platform_data  = &eeprom_info,
+       },
+       /* ALSO:
+        * - tvl320aic33 audio codec (0x1b)
+        * - msp430 microcontroller (0x23)
+        * - tvp5146 video decoder (0x5d)
+        */
+ };
+ /* The msp430 uses a slow bitbanged I2C implementation (ergo 20 KHz),
+  * which requires 100 usec of idle bus after i2c writes sent to it.
+  */
+ static struct davinci_i2c_platform_data i2c_pdata = {
+       .bus_freq       = 20 /* kHz */,
+       .bus_delay      = 100 /* usec */,
+ };
+ static void __init evm_init_i2c(void)
+ {
+       davinci_init_i2c(&i2c_pdata);
+       i2c_register_board_info(1, i2c_info, ARRAY_SIZE(i2c_info));
+ }
  static struct platform_device *davinci_evm_devices[] __initdata = {
-       &davinci_evm_flash_device,
+ #if defined(CONFIG_MTD_PHYSMAP) || \
+     defined(CONFIG_MTD_PHYSMAP_MODULE)
+       &davinci_evm_norflash_device,
+ #endif
+ #if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
+     defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
+       &ide_dev,
+ #endif
  };
  
  static void __init
@@@ -106,13 -405,21 +405,21 @@@ static __init void davinci_evm_init(voi
  {
        davinci_psc_init();
  
- #if defined(CONFIG_BLK_DEV_DAVINCI) || defined(CONFIG_BLK_DEV_DAVINCI_MODULE)
+ #if defined(CONFIG_BLK_DEV_PALMCHIP_BK3710) || \
+     defined(CONFIG_BLK_DEV_PALMCHIP_BK3710_MODULE)
+ #if defined(CONFIG_MTD_PHYSMAP) || \
+     defined(CONFIG_MTD_PHYSMAP_MODULE)
        printk(KERN_WARNING "WARNING: both IDE and NOR flash are enabled, "
               "but share pins.\n\t Disable IDE for NOR support.\n");
+ #endif
  #endif
  
        platform_add_devices(davinci_evm_devices,
                             ARRAY_SIZE(davinci_evm_devices));
+       evm_init_i2c();
+       /* irlml6401 sustains over 3A, switches 5V in under 8 msec */
+       setup_usb(500, 8);
  }
  
  static __init void davinci_evm_irq_init(void)
  MACHINE_START(DAVINCI_EVM, "DaVinci EVM")
        /* Maintainer: MontaVista Software <source@mvista.com> */
        .phys_io      = IO_PHYS,
-       .io_pg_offst  = (io_p2v(IO_PHYS) >> 18) & 0xfffc,
+       .io_pg_offst  = (__IO_ADDRESS(IO_PHYS) >> 18) & 0xfffc,
        .boot_params  = (DAVINCI_DDR_BASE + 0x100),
        .map_io       = davinci_evm_map_io,
        .init_irq     = davinci_evm_irq_init,
@@@ -1,7 -1,7 +1,7 @@@
  /*
   * TI DaVinci GPIO Support
   *
-  * Copyright (c) 2006 David Brownell
+  * Copyright (c) 2006-2007 David Brownell
   * Copyright (c) 2007, MontaVista Software, Inc. <source@mvista.com>
   *
   * This program is free software; you can redistribute it and/or modify
  
  #include <asm/mach/irq.h>
  
- static DEFINE_SPINLOCK(gpio_lock);
- static DECLARE_BITMAP(gpio_in_use, DAVINCI_N_GPIO);
  
- int gpio_request(unsigned gpio, const char *tag)
- {
-       if (gpio >= DAVINCI_N_GPIO)
-               return -EINVAL;
+ static DEFINE_SPINLOCK(gpio_lock);
  
-       if (test_and_set_bit(gpio, gpio_in_use))
-               return -EBUSY;
+ struct davinci_gpio {
+       struct gpio_chip        chip;
+       struct gpio_controller  *__iomem regs;
+ };
  
-       return 0;
- }
- EXPORT_SYMBOL(gpio_request);
- void gpio_free(unsigned gpio)
- {
-       if (gpio >= DAVINCI_N_GPIO)
-               return;
+ static struct davinci_gpio chips[DIV_ROUND_UP(DAVINCI_N_GPIO, 32)];
  
-       clear_bit(gpio, gpio_in_use);
- }
- EXPORT_SYMBOL(gpio_free);
  
  /* create a non-inlined version */
- static struct gpio_controller *__iomem gpio2controller(unsigned gpio)
+ static struct gpio_controller *__iomem __init gpio2controller(unsigned gpio)
  {
        return __gpio_to_controller(gpio);
  }
  
+ /*--------------------------------------------------------------------------*/
  /*
-  * Assuming the pin is muxed as a gpio output, set its output value.
+  * board setup code *MUST* set PINMUX0 and PINMUX1 as
+  * needed, and enable the GPIO clock.
   */
- void __gpio_set(unsigned gpio, int value)
+ static int davinci_direction_in(struct gpio_chip *chip, unsigned offset)
  {
-       struct gpio_controller *__iomem g = gpio2controller(gpio);
+       struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip);
+       struct gpio_controller *__iomem g = d->regs;
+       u32 temp;
  
-       __raw_writel(__gpio_mask(gpio), value ? &g->set_data : &g->clr_data);
- }
- EXPORT_SYMBOL(__gpio_set);
+       spin_lock(&gpio_lock);
+       temp = __raw_readl(&g->dir);
+       temp |= (1 << offset);
+       __raw_writel(temp, &g->dir);
+       spin_unlock(&gpio_lock);
  
+       return 0;
+ }
  
  /*
   * Read the pin's value (works even if it's set up as output);
   * Note that changes are synched to the GPIO clock, so reading values back
   * right after you've set them may give old values.
   */
int __gpio_get(unsigned gpio)
static int davinci_gpio_get(struct gpio_chip *chip, unsigned offset)
  {
-       struct gpio_controller *__iomem g = gpio2controller(gpio);
+       struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip);
+       struct gpio_controller *__iomem g = d->regs;
  
-       return !!(__gpio_mask(gpio) & __raw_readl(&g->in_data));
+       return (1 << offset) & __raw_readl(&g->in_data);
  }
- EXPORT_SYMBOL(__gpio_get);
  
- /*--------------------------------------------------------------------------*/
- /*
-  * board setup code *MUST* set PINMUX0 and PINMUX1 as
-  * needed, and enable the GPIO clock.
-  */
- int gpio_direction_input(unsigned gpio)
+ static int
+ davinci_direction_out(struct gpio_chip *chip, unsigned offset, int value)
  {
-       struct gpio_controller *__iomem g = gpio2controller(gpio);
+       struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip);
+       struct gpio_controller *__iomem g = d->regs;
        u32 temp;
-       u32 mask;
-       if (!g)
-               return -EINVAL;
+       u32 mask = 1 << offset;
  
        spin_lock(&gpio_lock);
-       mask = __gpio_mask(gpio);
        temp = __raw_readl(&g->dir);
-       temp |= mask;
+       temp &= ~mask;
+       __raw_writel(mask, value ? &g->set_data : &g->clr_data);
        __raw_writel(temp, &g->dir);
        spin_unlock(&gpio_lock);
        return 0;
  }
- EXPORT_SYMBOL(gpio_direction_input);
  
- int gpio_direction_output(unsigned gpio, int value)
+ /*
+  * Assuming the pin is muxed as a gpio output, set its output value.
+  */
+ static void
+ davinci_gpio_set(struct gpio_chip *chip, unsigned offset, int value)
  {
-       struct gpio_controller *__iomem g = gpio2controller(gpio);
-       u32 temp;
-       u32 mask;
+       struct davinci_gpio *d = container_of(chip, struct davinci_gpio, chip);
+       struct gpio_controller *__iomem g = d->regs;
  
-       if (!g)
-               return -EINVAL;
+       __raw_writel((1 << offset), value ? &g->set_data : &g->clr_data);
+ }
+ static int __init davinci_gpio_setup(void)
+ {
+       int i, base;
+       for (i = 0, base = 0;
+                       i < ARRAY_SIZE(chips);
+                       i++, base += 32) {
+               chips[i].chip.label = "DaVinci";
+               chips[i].chip.direction_input = davinci_direction_in;
+               chips[i].chip.get = davinci_gpio_get;
+               chips[i].chip.direction_output = davinci_direction_out;
+               chips[i].chip.set = davinci_gpio_set;
+               chips[i].chip.base = base;
+               chips[i].chip.ngpio = DAVINCI_N_GPIO - base;
+               if (chips[i].chip.ngpio > 32)
+                       chips[i].chip.ngpio = 32;
+               chips[i].regs = gpio2controller(base);
+               gpiochip_add(&chips[i].chip);
+       }
  
-       spin_lock(&gpio_lock);
-       mask = __gpio_mask(gpio);
-       temp = __raw_readl(&g->dir);
-       temp &= ~mask;
-       __raw_writel(mask, value ? &g->set_data : &g->clr_data);
-       __raw_writel(temp, &g->dir);
-       spin_unlock(&gpio_lock);
        return 0;
  }
EXPORT_SYMBOL(gpio_direction_output);
pure_initcall(davinci_gpio_setup);
  
+ /*--------------------------------------------------------------------------*/
  /*
   * We expect irqs will normally be set up as input pins, but they can also be
   * used as output pins ... which is convenient for testing.
@@@ -201,6 -210,7 +210,6 @@@ gpio_irq_handler(unsigned irq, struct i
        desc->chip->ack(irq);
        while (1) {
                u32             status;
 -              struct irq_desc *gpio;
                int             n;
                int             res;
  
  
                /* now demux them to the right lowlevel handler */
                n = (int)get_irq_data(irq);
 -              gpio = &irq_desc[n];
                while (status) {
                        res = ffs(status);
                        n += res;
 -                      gpio += res;
 -                      desc_handle_irq(n - 1, gpio - 1);
 +                      generic_handle_irq(n - 1);
                        status >>= res;
                }
        }
@@@ -33,8 -33,6 +33,8 @@@
  #include <mach/iomux-mx3.h>
  #include <mach/board-pcm037.h>
  
 +#include "devices.h"
 +
  static struct physmap_flash_data pcm037_flash_data = {
        .width  = 2,
  };
@@@ -56,7 -54,7 +56,7 @@@ static struct platform_device pcm037_fl
  };
  
  static struct imxuart_platform_data uart_pdata = {
-       .flags = 0,
+       .flags = IMXUART_HAVE_RTSCTS,
  };
  
  static struct platform_device *devices[] __initdata = {
@@@ -75,12 -73,12 +75,12 @@@ static void __init mxc_board_init(void
        mxc_iomux_mode(MX31_PIN_TXD1__TXD1);
        mxc_iomux_mode(MX31_PIN_RXD1__RXD1);
  
 -      imx_init_uart(0, &uart_pdata);
 +      mxc_register_device(&mxc_uart_device0, &uart_pdata);
  
        mxc_iomux_mode(MX31_PIN_CSPI3_MOSI__RXD3);
        mxc_iomux_mode(MX31_PIN_CSPI3_MISO__TXD3);
  
 -      imx_init_uart(2, &uart_pdata);
 +      mxc_register_device(&mxc_uart_device2, &uart_pdata);
  }
  
  /*
  #include <linux/kernel.h>
  #include <linux/init.h>
  #include <linux/platform_device.h>
 +#include <linux/io.h>
  
  #include <mach/hardware.h>
 -#include <asm/io.h>
  #include <asm/mach-types.h>
  #include <asm/mach/map.h>
  
  #include <mach/tc.h>
  #include <mach/board.h>
+ #include <mach/mmc.h>
  #include <mach/mux.h>
  #include <mach/gpio.h>
  #include <mach/menelaus.h>
@@@ -194,25 -195,38 +195,38 @@@ void omap_mcbsp_register_board_cfg(stru
  
  /*-------------------------------------------------------------------------*/
  
- #if   defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE)
+ #if   defined(CONFIG_MMC_OMAP) || defined(CONFIG_MMC_OMAP_MODULE) || \
+       defined(CONFIG_MMC_OMAP_HS) || defined(CONFIG_MMC_OMAP_HS_MODULE)
  
- #ifdef CONFIG_ARCH_OMAP24XX
+ #if defined(CONFIG_ARCH_OMAP24XX) || defined(CONFIG_ARCH_OMAP34XX)
  #define       OMAP_MMC1_BASE          0x4809c000
- #define OMAP_MMC1_INT         INT_24XX_MMC_IRQ
+ #define       OMAP_MMC1_END           (OMAP_MMC1_BASE + 0x1fc)
+ #define       OMAP_MMC1_INT           INT_24XX_MMC_IRQ
+ #define       OMAP_MMC2_BASE          0x480b4000
+ #define       OMAP_MMC2_END           (OMAP_MMC2_BASE + 0x1fc)
+ #define       OMAP_MMC2_INT           INT_24XX_MMC2_IRQ
  #else
  #define       OMAP_MMC1_BASE          0xfffb7800
+ #define       OMAP_MMC1_END           (OMAP_MMC1_BASE + 0x7f)
  #define OMAP_MMC1_INT         INT_MMC
- #endif
  #define       OMAP_MMC2_BASE          0xfffb7c00      /* omap16xx only */
+ #define       OMAP_MMC2_END           (OMAP_MMC2_BASE + 0x7f)
+ #define       OMAP_MMC2_INT           INT_1610_MMC2
  
- static struct omap_mmc_conf mmc1_conf;
+ #endif
+ static struct omap_mmc_platform_data mmc1_data;
  
  static u64 mmc1_dmamask = 0xffffffff;
  
  static struct resource mmc1_resources[] = {
        {
                .start          = OMAP_MMC1_BASE,
-               .end            = OMAP_MMC1_BASE + 0x7f,
+               .end            = OMAP_MMC1_END,
                .flags          = IORESOURCE_MEM,
        },
        {
@@@ -226,26 -240,27 +240,27 @@@ static struct platform_device mmc_omap_
        .id             = 1,
        .dev = {
                .dma_mask       = &mmc1_dmamask,
-               .platform_data  = &mmc1_conf,
+               .platform_data  = &mmc1_data,
        },
        .num_resources  = ARRAY_SIZE(mmc1_resources),
        .resource       = mmc1_resources,
  };
  
- #ifdef        CONFIG_ARCH_OMAP16XX
+ #if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2430) || \
+       defined(CONFIG_ARCH_OMAP34XX)
  
- static struct omap_mmc_conf mmc2_conf;
+ static struct omap_mmc_platform_data mmc2_data;
  
  static u64 mmc2_dmamask = 0xffffffff;
  
  static struct resource mmc2_resources[] = {
        {
                .start          = OMAP_MMC2_BASE,
-               .end            = OMAP_MMC2_BASE + 0x7f,
+               .end            = OMAP_MMC2_END,
                .flags          = IORESOURCE_MEM,
        },
        {
-               .start          = INT_1610_MMC2,
+               .start          = OMAP_MMC2_INT,
                .flags          = IORESOURCE_IRQ,
        },
  };
@@@ -255,26 -270,19 +270,19 @@@ static struct platform_device mmc_omap_
        .id             = 2,
        .dev = {
                .dma_mask       = &mmc2_dmamask,
-               .platform_data  = &mmc2_conf,
+               .platform_data  = &mmc2_data,
        },
        .num_resources  = ARRAY_SIZE(mmc2_resources),
        .resource       = mmc2_resources,
  };
  #endif
  
- static void __init omap_init_mmc(void)
+ static inline void omap_init_mmc_conf(const struct omap_mmc_config *mmc_conf)
  {
-       const struct omap_mmc_config    *mmc_conf;
-       const struct omap_mmc_conf      *mmc;
-       /* NOTE:  assumes MMC was never (wrongly) enabled */
-       mmc_conf = omap_get_config(OMAP_TAG_MMC, struct omap_mmc_config);
-       if (!mmc_conf)
+       if (cpu_is_omap2430() || cpu_is_omap34xx())
                return;
  
-       /* block 1 is always available and has just one pinout option */
-       mmc = &mmc_conf->mmc[0];
-       if (mmc->enabled) {
+       if (mmc_conf->mmc[0].enabled) {
                if (cpu_is_omap24xx()) {
                        omap_cfg_reg(H18_24XX_MMC_CMD);
                        omap_cfg_reg(H15_24XX_MMC_CLKI);
                                omap_cfg_reg(P20_1710_MMC_DATDIR0);
                        }
                }
-               if (mmc->wire4) {
+               if (mmc_conf->mmc[0].wire4) {
                        if (cpu_is_omap24xx()) {
                                omap_cfg_reg(H14_24XX_MMC_DAT1);
                                omap_cfg_reg(E19_24XX_MMC_DAT2);
                        } else {
                                omap_cfg_reg(MMC_DAT1);
                                /* NOTE:  DAT2 can be on W10 (here) or M15 */
-                               if (!mmc->nomux)
+                               if (!mmc_conf->mmc[0].nomux)
                                        omap_cfg_reg(MMC_DAT2);
                                omap_cfg_reg(MMC_DAT3);
                        }
                }
-               mmc1_conf = *mmc;
-               (void) platform_device_register(&mmc_omap_device1);
+ #if defined(CONFIG_ARCH_OMAP2420)
+               if (mmc_conf->mmc[0].internal_clock) {
+                       /*
+                        * Use internal loop-back in MMC/SDIO
+                        * Module Input Clock selection
+                        */
+                       if (cpu_is_omap24xx()) {
+                               u32 v = omap_ctrl_readl(OMAP2_CONTROL_DEVCONF0);
+                               v |= (1 << 24); /* not used in 243x */
+                               omap_ctrl_writel(v, OMAP2_CONTROL_DEVCONF0);
+                       }
+               }
+ #endif
        }
  
  #ifdef        CONFIG_ARCH_OMAP16XX
        /* block 2 is on newer chips, and has many pinout options */
-       mmc = &mmc_conf->mmc[1];
-       if (mmc->enabled) {
-               if (!mmc->nomux) {
+       if (mmc_conf->mmc[1].enabled) {
+               if (!mmc_conf->mmc[1].nomux) {
                        omap_cfg_reg(Y8_1610_MMC2_CMD);
                        omap_cfg_reg(Y10_1610_MMC2_CLK);
                        omap_cfg_reg(R18_1610_MMC2_CLKIN);
                        omap_cfg_reg(W8_1610_MMC2_DAT0);
-                       if (mmc->wire4) {
+                       if (mmc_conf->mmc[1].wire4) {
                                omap_cfg_reg(V8_1610_MMC2_DAT1);
                                omap_cfg_reg(W15_1610_MMC2_DAT2);
                                omap_cfg_reg(R10_1610_MMC2_DAT3);
                if (cpu_is_omap1710())
                        omap_writel(omap_readl(MOD_CONF_CTRL_1) | (1 << 24),
                                     MOD_CONF_CTRL_1);
-               mmc2_conf = *mmc;
+       }
+ #endif
+ }
+ static void __init omap_init_mmc(void)
+ {
+       const struct omap_mmc_config    *mmc_conf;
+       /* NOTE:  assumes MMC was never (wrongly) enabled */
+       mmc_conf = omap_get_config(OMAP_TAG_MMC, struct omap_mmc_config);
+       if (!mmc_conf)
+               return;
+       omap_init_mmc_conf(mmc_conf);
+       if (mmc_conf->mmc[0].enabled) {
+               mmc1_data.conf = mmc_conf->mmc[0];
+               (void) platform_device_register(&mmc_omap_device1);
+       }
+ #if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2430) || \
+       defined(CONFIG_ARCH_OMAP34XX)
+       if (mmc_conf->mmc[1].enabled) {
+               mmc2_data.conf = mmc_conf->mmc[1];
                (void) platform_device_register(&mmc_omap_device2);
        }
  #endif
-       return;
  }
+ void omap_set_mmc_info(int host, const struct omap_mmc_platform_data *info)
+ {
+       switch (host) {
+       case 1:
+               mmc1_data = *info;
+               break;
+ #if defined(CONFIG_ARCH_OMAP16XX) || defined(CONFIG_ARCH_OMAP2430) || \
+       defined(CONFIG_ARCH_OMAP34XX)
+       case 2:
+               mmc2_data = *info;
+               break;
+ #endif
+       default:
+               BUG();
+       }
+ }
  #else
  static inline void omap_init_mmc(void) {}
+ void omap_set_mmc_info(int host, const struct omap_mmc_platform_data *info) {}
  #endif
  
  /*-------------------------------------------------------------------------*/
@@@ -208,6 -208,36 +208,36 @@@ static unsigned long compute_hozval(uns
        return value;
  }
  
+ static void atmel_lcdfb_stop_nowait(struct atmel_lcdfb_info *sinfo)
+ {
+       /* Turn off the LCD controller and the DMA controller */
+       lcdc_writel(sinfo, ATMEL_LCDC_PWRCON,
+                       sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET);
+       /* Wait for the LCDC core to become idle */
+       while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY)
+               msleep(10);
+       lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0);
+ }
+ static void atmel_lcdfb_stop(struct atmel_lcdfb_info *sinfo)
+ {
+       atmel_lcdfb_stop_nowait(sinfo);
+       /* Wait for DMA engine to become idle... */
+       while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY)
+               msleep(10);
+ }
+ static void atmel_lcdfb_start(struct atmel_lcdfb_info *sinfo)
+ {
+       lcdc_writel(sinfo, ATMEL_LCDC_DMACON, sinfo->default_dmacon);
+       lcdc_writel(sinfo, ATMEL_LCDC_PWRCON,
+               (sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET)
+               | ATMEL_LCDC_PWR);
+ }
  static void atmel_lcdfb_update_dma(struct fb_info *info,
                               struct fb_var_screeninfo *var)
  {
@@@ -378,10 -408,6 +408,10 @@@ static int atmel_lcdfb_check_var(struc
                        var->red.offset = 11;
                        var->blue.offset = 0;
                        var->green.length = 6;
 +              } else if (sinfo->lcd_wiring_mode == ATMEL_LCDC_WIRING_RGB555) {
 +                      var->red.offset = 10;
 +                      var->blue.offset = 0;
 +                      var->green.length = 5;
                } else {
                        /* BGR:555 mode */
                        var->red.offset = 0;
@@@ -424,26 -450,8 +454,8 @@@ static void atmel_lcdfb_reset(struct at
  {
        might_sleep();
  
-       /* LCD power off */
-       lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET);
-       /* wait for the LCDC core to become idle */
-       while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY)
-               msleep(10);
-       /* DMA disable */
-       lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0);
-       /* wait for DMA engine to become idle */
-       while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY)
-               msleep(10);
-       /* LCD power on */
-       lcdc_writel(sinfo, ATMEL_LCDC_PWRCON,
-               (sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET) | ATMEL_LCDC_PWR);
-       /* DMA enable */
-       lcdc_writel(sinfo, ATMEL_LCDC_DMACON, sinfo->default_dmacon);
+       atmel_lcdfb_stop(sinfo);
+       atmel_lcdfb_start(sinfo);
  }
  
  /**
@@@ -475,14 -483,7 +487,7 @@@ static int atmel_lcdfb_set_par(struct f
                 info->var.xres, info->var.yres,
                 info->var.xres_virtual, info->var.yres_virtual);
  
-       /* Turn off the LCD controller and the DMA controller */
-       lcdc_writel(sinfo, ATMEL_LCDC_PWRCON, sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET);
-       /* Wait for the LCDC core to become idle */
-       while (lcdc_readl(sinfo, ATMEL_LCDC_PWRCON) & ATMEL_LCDC_BUSY)
-               msleep(10);
-       lcdc_writel(sinfo, ATMEL_LCDC_DMACON, 0);
+       atmel_lcdfb_stop_nowait(sinfo);
  
        if (info->var.bits_per_pixel == 1)
                info->fix.visual = FB_VISUAL_MONO01;
        while (lcdc_readl(sinfo, ATMEL_LCDC_DMACON) & ATMEL_LCDC_DMABUSY)
                msleep(10);
  
-       dev_dbg(info->device, "  * re-enable DMA engine\n");
-       /* ...and enable it with updated configuration */
-       lcdc_writel(sinfo, ATMEL_LCDC_DMACON, sinfo->default_dmacon);
-       dev_dbg(info->device, "  * re-enable LCDC core\n");
-       lcdc_writel(sinfo, ATMEL_LCDC_PWRCON,
-               (sinfo->guard_time << ATMEL_LCDC_GUARDT_OFFSET) | ATMEL_LCDC_PWR);
+       atmel_lcdfb_start(sinfo);
  
        dev_dbg(info->device, "  * DONE\n");
  
@@@ -1036,11 -1031,20 +1035,20 @@@ static int atmel_lcdfb_suspend(struct p
        struct fb_info *info = platform_get_drvdata(pdev);
        struct atmel_lcdfb_info *sinfo = info->par;
  
+       /*
+        * We don't want to handle interrupts while the clock is
+        * stopped. It may take forever.
+        */
+       lcdc_writel(sinfo, ATMEL_LCDC_IDR, ~0UL);
        sinfo->saved_lcdcon = lcdc_readl(sinfo, ATMEL_LCDC_CONTRAST_VAL);
        lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, 0);
        if (sinfo->atmel_lcdfb_power_control)
                sinfo->atmel_lcdfb_power_control(0);
+       atmel_lcdfb_stop(sinfo);
        atmel_lcdfb_stop_clock(sinfo);
        return 0;
  }
  
@@@ -1050,9 -1054,15 +1058,15 @@@ static int atmel_lcdfb_resume(struct pl
        struct atmel_lcdfb_info *sinfo = info->par;
  
        atmel_lcdfb_start_clock(sinfo);
+       atmel_lcdfb_start(sinfo);
        if (sinfo->atmel_lcdfb_power_control)
                sinfo->atmel_lcdfb_power_control(1);
        lcdc_writel(sinfo, ATMEL_LCDC_CONTRAST_CTR, sinfo->saved_lcdcon);
+       /* Enable FIFO & DMA errors */
+       lcdc_writel(sinfo, ATMEL_LCDC_IER, ATMEL_LCDC_UFLWI
+                       | ATMEL_LCDC_OWRI | ATMEL_LCDC_MERI);
        return 0;
  }