[PATCH 13/16] OMAP3: PM: Correcting accessing of ERRCONFIG register in smartreflex.c

Thara Gopinath
2010-02-24T09:29:35Z

Smartreflex error config register is special as it contains
certain status bits which if written a 1 into means a clear
of those bits. This patch takes special care during modify of
this register that no status bits in this register are accidently
set to 1.

This issue was first reported by Nishanth Menon.

Signed-off-by: Thara Gopinath <thara@ti.com>
---
arch/arm/mach-omap2/smartreflex.c | 12 +++++++++++-
arch/arm/mach-omap2/smartreflex.h | 6 ++++++
2 files changed, 17 insertions(+), 1 deletions(-)

diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
index 085dd05..8a4c48b 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -68,8 +68,18 @@ static inline void sr_modify_reg(struct omap_sr *sr, unsigned offset, u32 mask,

reg_val = __raw_readl(SR_REGADDR(offset));
reg_val &= ~mask;
- reg_val |= value;
+ /*
+ * Smartreflex error config register is special as it contains
+ * certain status bits which if written a 1 into means a clear
+ * of those bits. So in order to make sure no accidental write of
+ * 1 happens to those status bits, do a clear of them in the read
+ * value. Now if there is an actual reguest to write to these bits
+ * they will be set in the nex step.
+ */
+ if (offset == ERRCONFIG)
+ reg_val &= ~ERRCONFIG_STATUS_MASK;

+ reg_val |= value;
__raw_writel(reg_val, SR_REGADDR(offset));
}

diff --git a/arch/arm/mach-omap2/smartreflex.h b/arch/arm/mach-omap2/smartreflex.h
index f8fc8a4..fbb6bf4 100644
--- a/arch/arm/mach-omap2/smartreflex.h
+++ b/arch/arm/mach-omap2/smartreflex.h
@@ -84,6 +84,12 @@ extern struct dentry *pm_dbg_main_dir;
#define ERRCONFIG_MCUDISACKINTEN BIT(23)
#define ERRCONFIG_MCUDISACKINTST BIT(22)

+#define ERRCONFIG_STATUS_MASK (ERRCONFIG_VPBOUNDINTST | \
+ ERRCONFIG_MCUACCUMINTST | \
+ ERRCONFIG_MCUVALIDINTST | \
+ ERRCONFIG_MCUBOUNDINTST | \
+ ERRCONFIG_MCUDISACKINTST)
+
/* Common Bit values */

#define SRCLKLENGTH_12MHZ_SYSCLK 0x3C
--
1.7.0.rc1.33.g07cf0f