wish to say no.  Selecting yes without understanding what is
          going on could result in system crashes;
 
+config OMAP4_ERRATA_I688
+       bool "OMAP4 errata: Async Bridge Corruption"
+       depends on ARCH_OMAP4
+       select ARCH_HAS_BARRIERS
+       help
+         If a data is stalled inside asynchronous bridge because of back
+         pressure, it may be accepted multiple times, creating pointer
+         misalignment that will corrupt next transfers on that data path
+         until next reset of the system (No recovery procedure once the
+         issue is hit, the path remains consistently broken). Async bridge
+         can be found on path between MPU to EMIF and MPU to L3 interconnect.
+         This situation can happen only when the idle is initiated by a
+         Master Request Disconnection (which is trigged by software when
+         executing WFI on CPU).
+         The work-around for this errata needs all the initiators connected
+         through async bridge must ensure that data path is properly drained
+         before issuing WFI. This condition will be met if one Strongly ordered
+         access is performed to the target right before executing the WFI.
+         In MPU case, L3 T2ASYNC FIFO and DDR T2ASYNC FIFO needs to be drained.
+         IO barrier ensure that there is no synchronisation loss on initiators
+         operating on both interconnect port simultaneously.
 endmenu
 
 endif
 
--- /dev/null
+/*
+ * OMAP memory barrier header.
+ *
+ * Copyright (C) 2011 Texas Instruments, Inc.
+ *  Santosh Shilimkar <santosh.shilimkar@ti.com>
+ *  Richard Woodruff <r-woodruff2@ti.com>
+ *
+ * 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.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __MACH_BARRIERS_H
+#define __MACH_BARRIERS_H
+
+extern void omap_bus_sync(void);
+
+#define rmb()          dsb()
+#define wmb()          do { dsb(); outer_sync(); omap_bus_sync(); } while (0)
+#define mb()           wmb()
+
+#endif /* __MACH_BARRIERS_H */
 
                .length         = L4_EMU_44XX_SIZE,
                .type           = MT_DEVICE,
        },
+#ifdef CONFIG_OMAP4_ERRATA_I688
+       {
+               .virtual        = OMAP4_SRAM_VA,
+               .pfn            = __phys_to_pfn(OMAP4_SRAM_PA),
+               .length         = PAGE_SIZE,
+               .type           = MT_MEMORY_SO,
+       },
+#endif
+
 };
 #endif
 
 
 #include <linux/init.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
+#include <linux/memblock.h>
 
 #include <asm/hardware/gic.h>
 #include <asm/hardware/cache-l2x0.h>
+#include <asm/mach/map.h>
 
 #include <plat/irqs.h>
+#include <plat/sram.h>
 
 #include <mach/hardware.h>
 #include <mach/omap-wakeupgen.h>
 
 static void __iomem *sar_ram_base;
 
+#ifdef CONFIG_OMAP4_ERRATA_I688
+/* Used to implement memory barrier on DRAM path */
+#define OMAP4_DRAM_BARRIER_VA                  0xfe600000
+
+void __iomem *dram_sync, *sram_sync;
+
+void omap_bus_sync(void)
+{
+       if (dram_sync && sram_sync) {
+               writel_relaxed(readl_relaxed(dram_sync), dram_sync);
+               writel_relaxed(readl_relaxed(sram_sync), sram_sync);
+               isb();
+       }
+}
+
+static int __init omap_barriers_init(void)
+{
+       struct map_desc dram_io_desc[1];
+       phys_addr_t paddr;
+       u32 size;
+
+       if (!cpu_is_omap44xx())
+               return -ENODEV;
+
+       size = ALIGN(PAGE_SIZE, SZ_1M);
+       paddr = memblock_alloc(size, SZ_1M);
+       if (!paddr) {
+               pr_err("%s: failed to reserve 4 Kbytes\n", __func__);
+               return -ENOMEM;
+       }
+       memblock_free(paddr, size);
+       memblock_remove(paddr, size);
+       dram_io_desc[0].virtual = OMAP4_DRAM_BARRIER_VA;
+       dram_io_desc[0].pfn = __phys_to_pfn(paddr);
+       dram_io_desc[0].length = size;
+       dram_io_desc[0].type = MT_MEMORY_SO;
+       iotable_init(dram_io_desc, ARRAY_SIZE(dram_io_desc));
+       dram_sync = (void __iomem *) dram_io_desc[0].virtual;
+       sram_sync = (void __iomem *) OMAP4_SRAM_VA;
+
+       pr_info("OMAP4: Map 0x%08llx to 0x%08lx for dram barrier\n",
+               (long long) paddr, dram_io_desc[0].virtual);
+
+       return 0;
+}
+core_initcall(omap_barriers_init);
+#endif
+
 void __init gic_init_irq(void)
 {
        void __iomem *omap_irq_base;
 
 ENDPROC(omap4_cpu_resume)
 #endif
 
+#ifndef CONFIG_OMAP4_ERRATA_I688
+ENTRY(omap_bus_sync)
+       mov     pc, lr
+ENDPROC(omap_bus_sync)
+#endif
+
 ENTRY(omap_do_wfi)
        stmfd   sp!, {lr}
+       /* Drain interconnect write buffers. */
+       bl omap_bus_sync
 
        /*
         * Execute an ISB instruction to ensure that all of the
 
  */
 #define OMAP2_SRAM_PA          0x40200000
 #define OMAP3_SRAM_PA           0x40200000
+#ifdef CONFIG_OMAP4_ERRATA_I688
+#define OMAP4_SRAM_PA          0x40304000
+#define OMAP4_SRAM_VA          0xfe404000
+#else
 #define OMAP4_SRAM_PA          0x40300000
-
+#endif
 #endif
 
 #define OMAP1_SRAM_PA          0x20000000
 #define OMAP2_SRAM_PUB_PA      (OMAP2_SRAM_PA + 0xf800)
 #define OMAP3_SRAM_PUB_PA       (OMAP3_SRAM_PA + 0x8000)
+#ifdef CONFIG_OMAP4_ERRATA_I688
+#define OMAP4_SRAM_PUB_PA      OMAP4_SRAM_PA
+#else
 #define OMAP4_SRAM_PUB_PA      (OMAP4_SRAM_PA + 0x4000)
+#endif
 
 #if defined(CONFIG_ARCH_OMAP2PLUS)
 #define SRAM_BOOTLOADER_SZ     0x00
        if (omap_sram_size == 0)
                return;
 
+#ifdef CONFIG_OMAP4_ERRATA_I688
+               omap_sram_start += PAGE_SIZE;
+               omap_sram_size -= SZ_16K;
+#endif
        if (cpu_is_omap34xx()) {
                /*
                 * SRAM must be marked as non-cached on OMAP3 since the