[4/4] ARM: omap2: restore OMAP4 barrier behaviour
diff mbox

Message ID E1ZFQmM-0006GN-5Y@rmk-PC.arm.linux.org.uk
State New
Headers show

Commit Message

Russell King July 15, 2015, 5:47 p.m. UTC
Restore the OMAP4 barrier behaviour using the new implementation which
allows multiplatform systems to hook into the mb() and wmb() ARM
implementations to perform any necessary additional barrier maintanence.

Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
---
 arch/arm/mach-omap2/Kconfig                 | 28 +++------
 arch/arm/mach-omap2/common.h                | 12 +++-
 arch/arm/mach-omap2/include/mach/barriers.h | 33 -----------
 arch/arm/mach-omap2/omap-secure.h           |  7 ---
 arch/arm/mach-omap2/omap4-common.c          | 90 +++++++++++++++++++++++------
 arch/arm/mach-omap2/sleep44xx.S             | 10 +---
 6 files changed, 90 insertions(+), 90 deletions(-)
 delete mode 100644 arch/arm/mach-omap2/include/mach/barriers.h

Comments

Tony Lindgren July 16, 2015, 6:48 a.m. UTC | #1
Hi,

* Russell King <rmk+kernel@arm.linux.org.uk> [150715 10:50]:
> Restore the OMAP4 barrier behaviour using the new implementation which
> allows multiplatform systems to hook into the mb() and wmb() ARM
> implementations to perform any necessary additional barrier maintanence.

I'm getthing this with omap2plus_defconfig with the last patch
applied:

arch/arm/mach-omap2/omap4-common.c: In function ‘omap4_sram_init’:
arch/arm/mach-omap2/omap4-common.c:138:14: error: implicit declaration of function ‘of_get_named_gen_pool’ [-Werror=implicit-function-declaration]
  sram_pool = of_get_named_gen_pool(np, "sram", 0);
              ^
arch/arm/mach-omap2/omap4-common.c:138:12: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
  sram_pool = of_get_named_gen_pool(np, "sram", 0);
            ^
Regards,

Tony
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Russell King - ARM Linux July 16, 2015, 1:54 p.m. UTC | #2
On Wed, Jul 15, 2015 at 11:48:54PM -0700, Tony Lindgren wrote:
> Hi,
> 
> * Russell King <rmk+kernel@arm.linux.org.uk> [150715 10:50]:
> > Restore the OMAP4 barrier behaviour using the new implementation which
> > allows multiplatform systems to hook into the mb() and wmb() ARM
> > implementations to perform any necessary additional barrier maintanence.
> 
> I'm getthing this with omap2plus_defconfig with the last patch
> applied:
> 
> arch/arm/mach-omap2/omap4-common.c: In function ‘omap4_sram_init’:
> arch/arm/mach-omap2/omap4-common.c:138:14: error: implicit declaration of function ‘of_get_named_gen_pool’ [-Werror=implicit-function-declaration]
>   sram_pool = of_get_named_gen_pool(np, "sram", 0);
>               ^
> arch/arm/mach-omap2/omap4-common.c:138:12: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
>   sram_pool = of_get_named_gen_pool(np, "sram", 0);
>             ^

I'd forgotten to merge in the merge window fixes for this... which have now
been lost.  This needs to become of_gen_pool_get() in 4.2-rc1 and later.
Tony Lindgren July 17, 2015, 5:48 a.m. UTC | #3
* Russell King - ARM Linux <linux@arm.linux.org.uk> [150716 06:56]:
> On Wed, Jul 15, 2015 at 11:48:54PM -0700, Tony Lindgren wrote:
> > Hi,
> > 
> > * Russell King <rmk+kernel@arm.linux.org.uk> [150715 10:50]:
> > > Restore the OMAP4 barrier behaviour using the new implementation which
> > > allows multiplatform systems to hook into the mb() and wmb() ARM
> > > implementations to perform any necessary additional barrier maintanence.
> > 
> > I'm getthing this with omap2plus_defconfig with the last patch
> > applied:
> > 
> > arch/arm/mach-omap2/omap4-common.c: In function ‘omap4_sram_init’:
> > arch/arm/mach-omap2/omap4-common.c:138:14: error: implicit declaration of function ‘of_get_named_gen_pool’ [-Werror=implicit-function-declaration]
> >   sram_pool = of_get_named_gen_pool(np, "sram", 0);
> >               ^
> > arch/arm/mach-omap2/omap4-common.c:138:12: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
> >   sram_pool = of_get_named_gen_pool(np, "sram", 0);
> >             ^
> 
> I'd forgotten to merge in the merge window fixes for this... which have now
> been lost.  This needs to become of_gen_pool_get() in 4.2-rc1 and later.

OK with that change looks good to me, so please feel free to
add for the whole series:

Acked-by: Tony Lindgren <tony@atomide.com>
--
To unsubscribe from this list: send the line "unsubscribe linux-omap" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Dan Murphy July 27, 2015, 9:23 p.m. UTC | #4
Russell

On 07/15/2015 12:47 PM, Russell King wrote:
> Restore the OMAP4 barrier behaviour using the new implementation which
> allows multiplatform systems to hook into the mb() and wmb() ARM
> implementations to perform any necessary additional barrier maintanence.
>
> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
> ---
>  arch/arm/mach-omap2/Kconfig                 | 28 +++------
>  arch/arm/mach-omap2/common.h                | 12 +++-
>  arch/arm/mach-omap2/include/mach/barriers.h | 33 -----------
>  arch/arm/mach-omap2/omap-secure.h           |  7 ---
>  arch/arm/mach-omap2/omap4-common.c          | 90 +++++++++++++++++++++++------
>  arch/arm/mach-omap2/sleep44xx.S             | 10 +---
>  6 files changed, 90 insertions(+), 90 deletions(-)
>  delete mode 100644 arch/arm/mach-omap2/include/mach/barriers.h
>
> diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
> index 2128441430ad..8427997e09c4 100644
> --- a/arch/arm/mach-omap2/Kconfig
> +++ b/arch/arm/mach-omap2/Kconfig
> @@ -29,6 +29,7 @@ config ARCH_OMAP4
>  	select HAVE_ARM_SCU if SMP
>  	select HAVE_ARM_TWD if SMP
>  	select OMAP_INTERCONNECT
> +	select OMAP_INTERCONNECT_BARRIER
>  	select PL310_ERRATA_588369 if CACHE_L2X0
>  	select PL310_ERRATA_727915 if CACHE_L2X0
>  	select PM_OPP if PM
> @@ -46,6 +47,7 @@ config SOC_OMAP5
>  	select HAVE_ARM_TWD if SMP
>  	select HAVE_ARM_ARCH_TIMER
>  	select ARM_ERRATA_798181 if SMP
> +	select OMAP_INTERCONNECT_BARRIER
>  
>  config SOC_AM33XX
>  	bool "TI AM33XX"
> @@ -70,6 +72,7 @@ config SOC_DRA7XX
>  	select HAVE_ARM_ARCH_TIMER
>  	select IRQ_CROSSBAR
>  	select ARM_ERRATA_798181 if SMP
> +	select OMAP_INTERCONNECT_BARRIER
>  
>  config ARCH_OMAP2PLUS
>  	bool
> @@ -91,6 +94,10 @@ config ARCH_OMAP2PLUS
>  	help
>  	  Systems based on OMAP2, OMAP3, OMAP4 or OMAP5
>  
> +config OMAP_INTERCONNECT_BARRIER
> +	bool
> +	select ARM_HEAVY_MB
> +	
>  
>  if ARCH_OMAP2PLUS
>  
> @@ -240,27 +247,6 @@ config OMAP3_SDRC_AC_TIMING
>  	  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 || SOC_OMAP5) && !ARCH_MULTIPLATFORM
> -	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
> diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
> index 46e24581d624..82f88b4ec15f 100644
> --- a/arch/arm/mach-omap2/common.h
> +++ b/arch/arm/mach-omap2/common.h
> @@ -189,6 +189,15 @@ static inline void omap44xx_restart(enum reboot_mode mode, const char *cmd)
>  }
>  #endif
>  
> +#ifdef CONFIG_OMAP_INTERCONNECT_BARRIER
> +void omap_barrier_reserve_memblock(void);
> +void omap_barriers_init(void);
> +#else
> +static inline void omap_barrier_reserve_memblock(void)
> +{
> +}
> +#endif
> +
>  /* This gets called from mach-omap2/io.c, do not call this */
>  void __init omap2_set_globals_tap(u32 class, void __iomem *tap);
>  
> @@ -200,9 +209,6 @@ void __init omap4_map_io(void);
>  void __init omap5_map_io(void);
>  void __init ti81xx_map_io(void);
>  
> -/* omap_barriers_init() is OMAP4 only */
> -void omap_barriers_init(void);
> -
>  /**
>   * omap_test_timeout - busy-loop, testing a condition
>   * @cond: condition to test until it evaluates to true
> diff --git a/arch/arm/mach-omap2/include/mach/barriers.h b/arch/arm/mach-omap2/include/mach/barriers.h
> deleted file mode 100644
> index 1c582a8592b9..000000000000
> --- a/arch/arm/mach-omap2/include/mach/barriers.h
> +++ /dev/null
> @@ -1,33 +0,0 @@
> -/*
> - * 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
> -
> -#include <asm/outercache.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 */
> diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h
> index dec2b05d184b..af2851fbcdf0 100644
> --- a/arch/arm/mach-omap2/omap-secure.h
> +++ b/arch/arm/mach-omap2/omap-secure.h
> @@ -70,13 +70,6 @@ extern u32 rx51_secure_dispatcher(u32 idx, u32 process, u32 flag, u32 nargs,
>  extern u32 rx51_secure_update_aux_cr(u32 set_bits, u32 clear_bits);
>  extern u32 rx51_secure_rng_call(u32 ptr, u32 count, u32 flag);
>  
> -#ifdef CONFIG_OMAP4_ERRATA_I688
> -extern int omap_barrier_reserve_memblock(void);
> -#else
> -static inline void omap_barrier_reserve_memblock(void)
> -{ }
> -#endif
> -
>  #ifdef CONFIG_SOC_HAS_REALTIME_COUNTER
>  void set_cntfreq(void);
>  #else
> diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c
> index 7bb116a6f86f..9c7aac616938 100644
> --- a/arch/arm/mach-omap2/omap4-common.c
> +++ b/arch/arm/mach-omap2/omap4-common.c
> @@ -51,16 +51,73 @@ static void __iomem *twd_base;
>  
>  #define IRQ_LOCALTIMER		29
>  
> -#ifdef CONFIG_OMAP4_ERRATA_I688
> +#ifdef CONFIG_OMAP_INTERCONNECT_BARRIER
> +
>  /* Used to implement memory barrier on DRAM path */
>  #define OMAP4_DRAM_BARRIER_VA			0xfe600000
>  
> -void __iomem *dram_sync, *sram_sync;
> +static void __iomem *dram_sync, *sram_sync;
> +static phys_addr_t dram_sync_paddr;
> +static u32 dram_sync_size;
> +
> +/*
> + * The OMAP4 bus structure contains asynchrnous bridges which can buffer
> + * data writes from the MPU. These asynchronous bridges can be found on
> + * paths between the MPU to EMIF, and the MPU to L3 interconnects.
> + *
> + * We need to be careful about re-ordering which can happen as a result
> + * of different accesses being performed via different paths, and
> + * therefore different asynchronous bridges.
> + */
>  
> -static phys_addr_t paddr;
> -static u32 size;
> +/*
> + * OMAP4 interconnect barrier which is called for each mb() and wmb().
> + * This is to ensure that normal paths to DRAM (normal memory, cacheable
> + * accesses) are properly synchronised with writes to DMA coherent memory
> + * (normal memory, uncacheable) and device writes.
> + *
> + * The mb() and wmb() barriers only operate only on the MPU->MA->EMIF
> + * path, as we need to ensure that data is visible to other system
> + * masters prior to writes to those system masters being seen.
> + *
> + * Note: the SRAM path is not synchronised via mb() and wmb().
> + */
> +static void omap4_mb(void)

Sorry for the late response but this throws a warning when CONFIG_ARCH_OMAP4
is not configured.

arch/arm/mach-omap2/omap4-common.c:85:13: warning: 'omap4_mb' defined but not used [-Wunused-function]

If this was already taken I can just throw a patch up against what ever tree it is on.

<snip>
Russell King - ARM Linux July 28, 2015, 12:55 p.m. UTC | #5
On Mon, Jul 27, 2015 at 04:23:45PM -0500, Dan Murphy wrote:
> Russell
> 
> On 07/15/2015 12:47 PM, Russell King wrote:
> > +#ifdef CONFIG_OMAP_INTERCONNECT_BARRIER
> > +
> >  /* Used to implement memory barrier on DRAM path */
> >  #define OMAP4_DRAM_BARRIER_VA			0xfe600000
> >  
> > -void __iomem *dram_sync, *sram_sync;
> > +static void __iomem *dram_sync, *sram_sync;
> > +static phys_addr_t dram_sync_paddr;
> > +static u32 dram_sync_size;
> > +
> > +/*
> > + * The OMAP4 bus structure contains asynchrnous bridges which can buffer
> > + * data writes from the MPU. These asynchronous bridges can be found on
> > + * paths between the MPU to EMIF, and the MPU to L3 interconnects.
> > + *
> > + * We need to be careful about re-ordering which can happen as a result
> > + * of different accesses being performed via different paths, and
> > + * therefore different asynchronous bridges.
> > + */
> >  
> > -static phys_addr_t paddr;
> > -static u32 size;
> > +/*
> > + * OMAP4 interconnect barrier which is called for each mb() and wmb().
> > + * This is to ensure that normal paths to DRAM (normal memory, cacheable
> > + * accesses) are properly synchronised with writes to DMA coherent memory
> > + * (normal memory, uncacheable) and device writes.
> > + *
> > + * The mb() and wmb() barriers only operate only on the MPU->MA->EMIF
> > + * path, as we need to ensure that data is visible to other system
> > + * masters prior to writes to those system masters being seen.
> > + *
> > + * Note: the SRAM path is not synchronised via mb() and wmb().
> > + */
> > +static void omap4_mb(void)
> 
> Sorry for the late response but this throws a warning when CONFIG_ARCH_OMAP4
> is not configured.
> 
> arch/arm/mach-omap2/omap4-common.c:85:13: warning: 'omap4_mb' defined but not used [-Wunused-function]

Sorry, I'm going to have to disagree with you and your compiler on this.
This is how the code is structured:

#ifdef CONFIG_OMAP_INTERCONNECT_BARRIER
...
static void omap4_mb(void)
{
        if (dram_sync)
                writel_relaxed(0, dram_sync);
}
...
void __init omap_barriers_init(void)
{
...
        soc_mb = omap4_mb;
}

#endif

So, the definition of omap4_mb(), and the use of the same are both
under the same ifdef.  You can't build omap4_mb() without also building
omap_barriers_init() as well.

So, there's no way that omap4_mb() would be "defined but not used".

I think you have some changes in your kernel which, maybe, place an
ifdef around omap_barriers_init() which _would_ cause the warning you're
seeing if they aren't set.

Also, please trim context before the relevant part to which you're
replying. I almost gave up paging down to see whether there was actually
anything worth replying to.  If there's nothing in the first 50 lines of
the message, it's a waste of space.

Patch
diff mbox

diff --git a/arch/arm/mach-omap2/Kconfig b/arch/arm/mach-omap2/Kconfig
index 2128441430ad..8427997e09c4 100644
--- a/arch/arm/mach-omap2/Kconfig
+++ b/arch/arm/mach-omap2/Kconfig
@@ -29,6 +29,7 @@  config ARCH_OMAP4
 	select HAVE_ARM_SCU if SMP
 	select HAVE_ARM_TWD if SMP
 	select OMAP_INTERCONNECT
+	select OMAP_INTERCONNECT_BARRIER
 	select PL310_ERRATA_588369 if CACHE_L2X0
 	select PL310_ERRATA_727915 if CACHE_L2X0
 	select PM_OPP if PM
@@ -46,6 +47,7 @@  config SOC_OMAP5
 	select HAVE_ARM_TWD if SMP
 	select HAVE_ARM_ARCH_TIMER
 	select ARM_ERRATA_798181 if SMP
+	select OMAP_INTERCONNECT_BARRIER
 
 config SOC_AM33XX
 	bool "TI AM33XX"
@@ -70,6 +72,7 @@  config SOC_DRA7XX
 	select HAVE_ARM_ARCH_TIMER
 	select IRQ_CROSSBAR
 	select ARM_ERRATA_798181 if SMP
+	select OMAP_INTERCONNECT_BARRIER
 
 config ARCH_OMAP2PLUS
 	bool
@@ -91,6 +94,10 @@  config ARCH_OMAP2PLUS
 	help
 	  Systems based on OMAP2, OMAP3, OMAP4 or OMAP5
 
+config OMAP_INTERCONNECT_BARRIER
+	bool
+	select ARM_HEAVY_MB
+	
 
 if ARCH_OMAP2PLUS
 
@@ -240,27 +247,6 @@  config OMAP3_SDRC_AC_TIMING
 	  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 || SOC_OMAP5) && !ARCH_MULTIPLATFORM
-	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
diff --git a/arch/arm/mach-omap2/common.h b/arch/arm/mach-omap2/common.h
index 46e24581d624..82f88b4ec15f 100644
--- a/arch/arm/mach-omap2/common.h
+++ b/arch/arm/mach-omap2/common.h
@@ -189,6 +189,15 @@  static inline void omap44xx_restart(enum reboot_mode mode, const char *cmd)
 }
 #endif
 
+#ifdef CONFIG_OMAP_INTERCONNECT_BARRIER
+void omap_barrier_reserve_memblock(void);
+void omap_barriers_init(void);
+#else
+static inline void omap_barrier_reserve_memblock(void)
+{
+}
+#endif
+
 /* This gets called from mach-omap2/io.c, do not call this */
 void __init omap2_set_globals_tap(u32 class, void __iomem *tap);
 
@@ -200,9 +209,6 @@  void __init omap4_map_io(void);
 void __init omap5_map_io(void);
 void __init ti81xx_map_io(void);
 
-/* omap_barriers_init() is OMAP4 only */
-void omap_barriers_init(void);
-
 /**
  * omap_test_timeout - busy-loop, testing a condition
  * @cond: condition to test until it evaluates to true
diff --git a/arch/arm/mach-omap2/include/mach/barriers.h b/arch/arm/mach-omap2/include/mach/barriers.h
deleted file mode 100644
index 1c582a8592b9..000000000000
--- a/arch/arm/mach-omap2/include/mach/barriers.h
+++ /dev/null
@@ -1,33 +0,0 @@ 
-/*
- * 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
-
-#include <asm/outercache.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 */
diff --git a/arch/arm/mach-omap2/omap-secure.h b/arch/arm/mach-omap2/omap-secure.h
index dec2b05d184b..af2851fbcdf0 100644
--- a/arch/arm/mach-omap2/omap-secure.h
+++ b/arch/arm/mach-omap2/omap-secure.h
@@ -70,13 +70,6 @@  extern u32 rx51_secure_dispatcher(u32 idx, u32 process, u32 flag, u32 nargs,
 extern u32 rx51_secure_update_aux_cr(u32 set_bits, u32 clear_bits);
 extern u32 rx51_secure_rng_call(u32 ptr, u32 count, u32 flag);
 
-#ifdef CONFIG_OMAP4_ERRATA_I688
-extern int omap_barrier_reserve_memblock(void);
-#else
-static inline void omap_barrier_reserve_memblock(void)
-{ }
-#endif
-
 #ifdef CONFIG_SOC_HAS_REALTIME_COUNTER
 void set_cntfreq(void);
 #else
diff --git a/arch/arm/mach-omap2/omap4-common.c b/arch/arm/mach-omap2/omap4-common.c
index 7bb116a6f86f..9c7aac616938 100644
--- a/arch/arm/mach-omap2/omap4-common.c
+++ b/arch/arm/mach-omap2/omap4-common.c
@@ -51,16 +51,73 @@  static void __iomem *twd_base;
 
 #define IRQ_LOCALTIMER		29
 
-#ifdef CONFIG_OMAP4_ERRATA_I688
+#ifdef CONFIG_OMAP_INTERCONNECT_BARRIER
+
 /* Used to implement memory barrier on DRAM path */
 #define OMAP4_DRAM_BARRIER_VA			0xfe600000
 
-void __iomem *dram_sync, *sram_sync;
+static void __iomem *dram_sync, *sram_sync;
+static phys_addr_t dram_sync_paddr;
+static u32 dram_sync_size;
+
+/*
+ * The OMAP4 bus structure contains asynchrnous bridges which can buffer
+ * data writes from the MPU. These asynchronous bridges can be found on
+ * paths between the MPU to EMIF, and the MPU to L3 interconnects.
+ *
+ * We need to be careful about re-ordering which can happen as a result
+ * of different accesses being performed via different paths, and
+ * therefore different asynchronous bridges.
+ */
 
-static phys_addr_t paddr;
-static u32 size;
+/*
+ * OMAP4 interconnect barrier which is called for each mb() and wmb().
+ * This is to ensure that normal paths to DRAM (normal memory, cacheable
+ * accesses) are properly synchronised with writes to DMA coherent memory
+ * (normal memory, uncacheable) and device writes.
+ *
+ * The mb() and wmb() barriers only operate only on the MPU->MA->EMIF
+ * path, as we need to ensure that data is visible to other system
+ * masters prior to writes to those system masters being seen.
+ *
+ * Note: the SRAM path is not synchronised via mb() and wmb().
+ */
+static void omap4_mb(void)
+{
+	if (dram_sync)
+		writel_relaxed(0, dram_sync);
+}
 
-void omap_bus_sync(void)
+/*
+ * OMAP4 Errata i688 - asynchronous bridge corruption when entering WFI.
+ *
+ * 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 bridges can be found on paths between MPU to EMIF and MPU to L3
+ * interconnects.
+ *
+ * This situation can happen only when the idle is initiated by a Master
+ * Request Disconnection (which is trigged by software when executing WFI
+ * on the CPU).
+ *
+ * The work-around for this errata needs all the initiators connected
+ * through an async bridge to 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.
+ *
+ * This is a stronger version of the OMAP4 memory barrier below, and
+ * operates on both the MPU->MA->EMIF path but also the MPU->OCP path
+ * as well, and is necessary prior to executing a WFI.
+ */
+void omap_interconnect_sync(void)
 {
 	if (dram_sync && sram_sync) {
 		writel_relaxed(readl_relaxed(dram_sync), dram_sync);
@@ -68,7 +125,6 @@  void omap_bus_sync(void)
 		isb();
 	}
 }
-EXPORT_SYMBOL(omap_bus_sync);
 
 static int __init omap4_sram_init(void)
 {
@@ -91,13 +147,10 @@  static int __init omap4_sram_init(void)
 omap_arch_initcall(omap4_sram_init);
 
 /* Steal one page physical memory for barrier implementation */
-int __init omap_barrier_reserve_memblock(void)
+void __init omap_barrier_reserve_memblock(void)
 {
-
-	size = ALIGN(PAGE_SIZE, SZ_1M);
-	paddr = arm_memblock_steal(size, SZ_1M);
-
-	return 0;
+	dram_sync_size = ALIGN(PAGE_SIZE, SZ_1M);
+	dram_sync_paddr = arm_memblock_steal(dram_sync_size, SZ_1M);
 }
 
 void __init omap_barriers_init(void)
@@ -105,19 +158,18 @@  void __init omap_barriers_init(void)
 	struct map_desc dram_io_desc[1];
 
 	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].pfn = __phys_to_pfn(dram_sync_paddr);
+	dram_io_desc[0].length = dram_sync_size;
 	dram_io_desc[0].type = MT_MEMORY_RW_SO;
 	iotable_init(dram_io_desc, ARRAY_SIZE(dram_io_desc));
 	dram_sync = (void __iomem *) dram_io_desc[0].virtual;
 
-	pr_info("OMAP4: Map 0x%08llx to 0x%08lx for dram barrier\n",
-		(long long) paddr, dram_io_desc[0].virtual);
+	pr_info("OMAP4: Map %pa to %p for dram barrier\n",
+		&dram_sync_paddr, dram_sync);
 
+	soc_mb = omap4_mb;
 }
-#else
-void __init omap_barriers_init(void)
-{}
+
 #endif
 
 void gic_dist_disable(void)
diff --git a/arch/arm/mach-omap2/sleep44xx.S b/arch/arm/mach-omap2/sleep44xx.S
index b84a0122d823..9b09d85d811a 100644
--- a/arch/arm/mach-omap2/sleep44xx.S
+++ b/arch/arm/mach-omap2/sleep44xx.S
@@ -333,16 +333,12 @@  ENDPROC(omap4_cpu_resume)
 
 #endif	/* defined(CONFIG_SMP) && defined(CONFIG_PM) */
 
-#ifndef CONFIG_OMAP4_ERRATA_I688
-ENTRY(omap_bus_sync)
-	ret	lr
-ENDPROC(omap_bus_sync)
-#endif
-
 ENTRY(omap_do_wfi)
 	stmfd	sp!, {lr}
+#ifdef CONFIG_OMAP_INTERCONNECT_BARRIER
 	/* Drain interconnect write buffers. */
-	bl omap_bus_sync
+	bl	omap_interconnect_sync
+#endif
 
 	/*
 	 * Execute an ISB instruction to ensure that all of the