aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNishanth Menon <nm@ti.com>2012-02-29 17:33:42 -0500
committerKevin Hilman <khilman@ti.com>2012-03-05 14:29:26 -0500
commitcfec9c54f99ce6aa3e31c39ef6df749550ab49c1 (patch)
tree4590035e3cd9b3bc962cadd0b5e3c6710146d218
parentade6ec056fd4acdf4826178eeb305ed263844532 (diff)
ARM: OMAP3+: SmartReflex: clear ERRCONFIG_VPBOUNDINTST only on a need
The VPBOUNDINTST field of the ERRCONFIG register has an additional functional meaning of force clearing the SR internal signal with VP (sr_interruptz). This can result in scenarios where the VP->SR protocol is violated because the SR internal signal with VP is already high and VP will never clear the vpirqclr signal. Therefore during the next force update to reset to nominal voltage, VP cannot pulse vpirqclr, so the PRCM HW cannot generate the tranxdone IRQ and the situation is not recoverable until a cold reset is invoked. To prevent this situation, check if status is set before clearing it as this needs to be done only on a need basis. Reported-by: Vincent Bour <v-bour@ti.com> Signed-off-by: Nishanth Menon <nm@ti.com> Signed-off-by: Jean Pihet <j-pihet@ti.com> Reviewed-by: Kevin Hilman <khilman@ti.com> Signed-off-by: Kevin Hilman <khilman@ti.com>
-rw-r--r--arch/arm/mach-omap2/smartreflex.c22
1 files changed, 16 insertions, 6 deletions
diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
index f2f2f2af7ba2..64d3ca72f0c9 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -289,6 +289,8 @@ error:
289static void sr_v1_disable(struct omap_sr *sr) 289static void sr_v1_disable(struct omap_sr *sr)
290{ 290{
291 int timeout = 0; 291 int timeout = 0;
292 int errconf_val = ERRCONFIG_MCUACCUMINTST | ERRCONFIG_MCUVALIDINTST |
293 ERRCONFIG_MCUBOUNDINTST;
292 294
293 /* Enable MCUDisableAcknowledge interrupt */ 295 /* Enable MCUDisableAcknowledge interrupt */
294 sr_modify_reg(sr, ERRCONFIG_V1, 296 sr_modify_reg(sr, ERRCONFIG_V1,
@@ -297,13 +299,13 @@ static void sr_v1_disable(struct omap_sr *sr)
297 /* SRCONFIG - disable SR */ 299 /* SRCONFIG - disable SR */
298 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0); 300 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0);
299 301
300 /* Disable all other SR interrupts and clear the status */ 302 /* Disable all other SR interrupts and clear the status as needed */
303 if (sr_read_reg(sr, ERRCONFIG_V1) & ERRCONFIG_VPBOUNDINTST_V1)
304 errconf_val |= ERRCONFIG_VPBOUNDINTST_V1;
301 sr_modify_reg(sr, ERRCONFIG_V1, 305 sr_modify_reg(sr, ERRCONFIG_V1,
302 (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN | 306 (ERRCONFIG_MCUACCUMINTEN | ERRCONFIG_MCUVALIDINTEN |
303 ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_VPBOUNDINTEN_V1), 307 ERRCONFIG_MCUBOUNDINTEN | ERRCONFIG_VPBOUNDINTEN_V1),
304 (ERRCONFIG_MCUACCUMINTST | ERRCONFIG_MCUVALIDINTST | 308 errconf_val);
305 ERRCONFIG_MCUBOUNDINTST |
306 ERRCONFIG_VPBOUNDINTST_V1));
307 309
308 /* 310 /*
309 * Wait for SR to be disabled. 311 * Wait for SR to be disabled.
@@ -332,9 +334,17 @@ static void sr_v2_disable(struct omap_sr *sr)
332 /* SRCONFIG - disable SR */ 334 /* SRCONFIG - disable SR */
333 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0); 335 sr_modify_reg(sr, SRCONFIG, SRCONFIG_SRENABLE, 0x0);
334 336
335 /* Disable all other SR interrupts and clear the status */ 337 /*
336 sr_modify_reg(sr, ERRCONFIG_V2, ERRCONFIG_VPBOUNDINTEN_V2, 338 * Disable all other SR interrupts and clear the status
339 * write to status register ONLY on need basis - only if status
340 * is set.
341 */
342 if (sr_read_reg(sr, ERRCONFIG_V2) & ERRCONFIG_VPBOUNDINTST_V2)
343 sr_modify_reg(sr, ERRCONFIG_V2, ERRCONFIG_VPBOUNDINTEN_V2,
337 ERRCONFIG_VPBOUNDINTST_V2); 344 ERRCONFIG_VPBOUNDINTST_V2);
345 else
346 sr_modify_reg(sr, ERRCONFIG_V2, ERRCONFIG_VPBOUNDINTEN_V2,
347 0x0);
338 sr_write_reg(sr, IRQENABLE_CLR, (IRQENABLE_MCUACCUMINT | 348 sr_write_reg(sr, IRQENABLE_CLR, (IRQENABLE_MCUACCUMINT |
339 IRQENABLE_MCUVALIDINT | 349 IRQENABLE_MCUVALIDINT |
340 IRQENABLE_MCUBOUNDSINT)); 350 IRQENABLE_MCUBOUNDSINT));