aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPaul Walmsley <paul@pwsan.com>2013-01-26 02:48:56 -0500
committerPaul Walmsley <paul@pwsan.com>2013-01-26 03:42:33 -0500
commitfa2002223e12c6b1bc96381b70c376afe4e01d80 (patch)
tree5daf5c6c001d616157c19b559ca62d9fcb4727ab
parentdd1e4223544412c0f0a39da70462f9f8374ef98d (diff)
ARM: OMAP2+: hwmod: add support for blocking WFI when a device is active
Apparently, on some OMAPs, the MPU can't be allowed to enter WFI while certain peripherals are active. It's not clear why, and it's likely that there is simply some other bug in the driver or integration code. But since the likelihood that anyone will have the time to track these problems down in the future seems quite small, we'll provide a flag, HWMOD_BLOCK_WFI, to mark these issues in the hwmod data. Signed-off-by: Paul Walmsley <paul@pwsan.com>
-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 4653efb87a27..6804d474a47d 100644
--- a/arch/arm/mach-omap2/omap_hwmod.c
+++ b/arch/arm/mach-omap2/omap_hwmod.c
@@ -139,6 +139,8 @@
139#include <linux/slab.h> 139#include <linux/slab.h>
140#include <linux/bootmem.h> 140#include <linux/bootmem.h>
141 141
142#include <asm/system_misc.h>
143
142#include "clock.h" 144#include "clock.h"
143#include "omap_hwmod.h" 145#include "omap_hwmod.h"
144 146
@@ -2134,6 +2136,8 @@ static int _enable(struct omap_hwmod *oh)
2134 _enable_clocks(oh); 2136 _enable_clocks(oh);
2135 if (soc_ops.enable_module) 2137 if (soc_ops.enable_module)
2136 soc_ops.enable_module(oh); 2138 soc_ops.enable_module(oh);
2139 if (oh->flags & HWMOD_BLOCK_WFI)
2140 disable_hlt();
2137 2141
2138 if (soc_ops.update_context_lost) 2142 if (soc_ops.update_context_lost)
2139 soc_ops.update_context_lost(oh); 2143 soc_ops.update_context_lost(oh);
@@ -2195,6 +2199,8 @@ static int _idle(struct omap_hwmod *oh)
2195 _idle_sysc(oh); 2199 _idle_sysc(oh);
2196 _del_initiator_dep(oh, mpu_oh); 2200 _del_initiator_dep(oh, mpu_oh);
2197 2201
2202 if (oh->flags & HWMOD_BLOCK_WFI)
2203 enable_hlt();
2198 if (soc_ops.disable_module) 2204 if (soc_ops.disable_module)
2199 soc_ops.disable_module(oh); 2205 soc_ops.disable_module(oh);
2200 2206
@@ -2303,6 +2309,8 @@ static int _shutdown(struct omap_hwmod *oh)
2303 if (oh->_state == _HWMOD_STATE_ENABLED) { 2309 if (oh->_state == _HWMOD_STATE_ENABLED) {
2304 _del_initiator_dep(oh, mpu_oh); 2310 _del_initiator_dep(oh, mpu_oh);
2305 /* XXX what about the other system initiators here? dma, dsp */ 2311 /* XXX what about the other system initiators here? dma, dsp */
2312 if (oh->flags & HWMOD_BLOCK_WFI)
2313 enable_hlt();
2306 if (soc_ops.disable_module) 2314 if (soc_ops.disable_module)
2307 soc_ops.disable_module(oh); 2315 soc_ops.disable_module(oh);
2308 _disable_clocks(oh); 2316 _disable_clocks(oh);
diff --git a/arch/arm/mach-omap2/omap_hwmod.h b/arch/arm/mach-omap2/omap_hwmod.h
index 3ae852a522f9..80c00e706d69 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 {
451 * enabled. This prevents the hwmod code from being able to 451 * enabled. This prevents the hwmod code from being able to
452 * enable and reset the IP block early. XXX Eventually it should 452 * enable and reset the IP block early. XXX Eventually it should
453 * be possible to query the clock framework for this information. 453 * be possible to query the clock framework for this information.
454 * HWMOD_BLOCK_WFI: Some OMAP peripherals apparently don't work
455 * correctly if the MPU is allowed to go idle while the
456 * peripherals are active. This is apparently true for the I2C on
457 * OMAP2420, and also the EMAC on AM3517/3505. It's unlikely that
458 * this is really true -- we're probably not configuring something
459 * correctly, or this is being abused to deal with some PM latency
460 * issues -- but we're currently suffering from a shortage of
461 * folks who are able to track these issues down properly.
454 */ 462 */
455#define HWMOD_SWSUP_SIDLE (1 << 0) 463#define HWMOD_SWSUP_SIDLE (1 << 0)
456#define HWMOD_SWSUP_MSTANDBY (1 << 1) 464#define HWMOD_SWSUP_MSTANDBY (1 << 1)
@@ -462,6 +470,7 @@ struct omap_hwmod_omap4_prcm {
462#define HWMOD_CONTROL_OPT_CLKS_IN_RESET (1 << 7) 470#define HWMOD_CONTROL_OPT_CLKS_IN_RESET (1 << 7)
463#define HWMOD_16BIT_REG (1 << 8) 471#define HWMOD_16BIT_REG (1 << 8)
464#define HWMOD_EXT_OPT_MAIN_CLK (1 << 9) 472#define HWMOD_EXT_OPT_MAIN_CLK (1 << 9)
473#define HWMOD_BLOCK_WFI (1 << 10)
465 474
466/* 475/*
467 * omap_hwmod._int_flags definitions 476 * omap_hwmod._int_flags definitions