aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.c8
-rw-r--r--arch/arm/mach-omap2/omap_hwmod.h9
2 files changed, 17 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/omap_hwmod.c b/arch/arm/mach-omap2/omap_hwmod.c
index 4653efb87a2..6804d474a47 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -139,6 +139,8 @@
#include <linux/slab.h>
#include <linux/bootmem.h>
+#include <asm/system_misc.h>
+
#include "clock.h"
#include "omap_hwmod.h"
@@ -2134,6 +2136,8 @@ static int _enable(struct omap_hwmod *oh)
_enable_clocks(oh);
if (soc_ops.enable_module)
soc_ops.enable_module(oh);
+ if (oh->flags & HWMOD_BLOCK_WFI)
+ disable_hlt();
if (soc_ops.update_context_lost)
soc_ops.update_context_lost(oh);
@@ -2195,6 +2199,8 @@ static int _idle(struct omap_hwmod *oh)
_idle_sysc(oh);
_del_initiator_dep(oh, mpu_oh);
+ if (oh->flags & HWMOD_BLOCK_WFI)
+ enable_hlt();
if (soc_ops.disable_module)
soc_ops.disable_module(oh);
@@ -2303,6 +2309,8 @@ static int _shutdown(struct omap_hwmod *oh)
if (oh->_state == _HWMOD_STATE_ENABLED) {
_del_initiator_dep(oh, mpu_oh);
/* XXX what about the other system initiators here? dma, dsp */
+ if (oh->flags & HWMOD_BLOCK_WFI)
+ enable_hlt();
if (soc_ops.disable_module)
soc_ops.disable_module(oh);
_disable_clocks(oh);
diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h
index 3ae852a522f..80c00e706d6 100644
--- a/arch/arm/mach-omap2/omap_hwmod.h
+++ b/arch/arm/mach-omap2/omap_hwmod.h
@@ -451,6 +451,14 @@ struct omap_hwmod_omap4_prcm {
* enabled. This prevents the hwmod code from being able to
* enable and reset the IP block early. XXX Eventually it should
* be possible to query the clock framework for this information.
+ * HWMOD_BLOCK_WFI: Some OMAP peripherals apparently don't work
+ * correctly if the MPU is allowed to go idle while the
+ * peripherals are active. This is apparently true for the I2C on
+ * OMAP2420, and also the EMAC on AM3517/3505. It's unlikely that
+ * this is really true -- we're probably not configuring something
+ * correctly, or this is being abused to deal with some PM latency
+ * issues -- but we're currently suffering from a shortage of
+ * folks who are able to track these issues down properly.
*/
#define HWMOD_SWSUP_SIDLE (1 << 0)
#define HWMOD_SWSUP_MSTANDBY (1 << 1)
@@ -462,6 +470,7 @@ struct omap_hwmod_omap4_prcm {
#define HWMOD_CONTROL_OPT_CLKS_IN_RESET (1 << 7)
#define HWMOD_16BIT_REG (1 << 8)
#define HWMOD_EXT_OPT_MAIN_CLK (1 << 9)
+#define HWMOD_BLOCK_WFI (1 << 10)
/*
* omap_hwmod._int_flags definitions