summary refs log tree commit diff
path: root/arch/arm/mach-ep93xx/core.c
diff options
context:
space:
mode:
authorHartley Sweeten <hartleys@visionengravers.com>2009-07-08 02:00:49 +0100
committerRussell King <rmk+kernel@arm.linux.org.uk>2009-07-09 16:10:51 +0100
commit02239f0a4264608686cc0015d906c7b2dead89df (patch)
tree85e23dd5af1b1d9a00466af408827e384049c239 /arch/arm/mach-ep93xx/core.c
parentf04989bbf4a40077dc7ddcc3dccde11a5f3e91f2 (diff)
downloadlinux-02239f0a4264608686cc0015d906c7b2dead89df.tar.gz
[ARM] 5577/2: ep93xx: syscon locked register functions
Add core functions to handle writes to the ep93xx software locked
registers.

There are a number of registers in the EP93xx System Controller
that require a write to the software lock register before they
can be updated. This patch adds a number of exported functions
to the ep93xx core that handle this access.

The software locked clock divider registers, VidClkDiv, MIRClkDiv,
I2SClkDiv and KeyTchClkDiv would typically involve writing a
specific value to the register. To support this the
ep93xx_syscon_swlocked_write() function is provided.

For the DeviceCfg register it's more typical to only need to
set or clear a single bit. A generic ep93xx_devcfg_set_clear()
function is provided to handle both operations. Two inline
functions, ep93xx_devcfg_set_bits() and ep93xx_devcfg_clear_bits()
are also provided to improve code readability.

In addition, the remaining bits in the System Controller Device
Config Register have been documented and the previously defined
names shortened.

All code paths that use this functionality have been updated
except for arch/arm/kernel/crunch.c. That code is in a context
switch path, which is not reentrant, so it is safe against itself.

Cc: Lennert Buytenhek <buytenh@wantstofly.org>
Cc: Matthias Kaehlcke <matthias@kaehlcke.net>
Signed-off-by: H Hartley Sweeten <hsweeten@visionengravers.com>
Acked-by: Ryan Mallon <ryan@bluewatersys.com>
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-ep93xx/core.c')
-rw-r--r--arch/arm/mach-ep93xx/core.c52
1 files changed, 43 insertions, 9 deletions
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 204dc5cbd0b8..9399d3af9906 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -385,6 +385,47 @@ void __init ep93xx_init_irq(void)
 
 
 /*************************************************************************
+ * EP93xx System Controller Software Locked register handling
+ *************************************************************************/
+
+/*
+ * syscon_swlock prevents anything else from writing to the syscon
+ * block while a software locked register is being written.
+ */
+static DEFINE_SPINLOCK(syscon_swlock);
+
+void ep93xx_syscon_swlocked_write(unsigned int val, unsigned int reg)
+{
+	unsigned long flags;
+
+	spin_lock_irqsave(&syscon_swlock, flags);
+
+	__raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
+	__raw_writel(val, reg);
+
+	spin_unlock_irqrestore(&syscon_swlock, flags);
+}
+EXPORT_SYMBOL(ep93xx_syscon_swlocked_write);
+
+void ep93xx_devcfg_set_clear(unsigned int set_bits, unsigned int clear_bits)
+{
+	unsigned long flags;
+	unsigned int val;
+
+	spin_lock_irqsave(&syscon_swlock, flags);
+
+	val = __raw_readl(EP93XX_SYSCON_DEVCFG);
+	val |= set_bits;
+	val &= ~clear_bits;
+	__raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
+	__raw_writel(val, EP93XX_SYSCON_DEVCFG);
+
+	spin_unlock_irqrestore(&syscon_swlock, flags);
+}
+EXPORT_SYMBOL(ep93xx_devcfg_set_clear);
+
+
+/*************************************************************************
  * EP93xx peripheral handling
  *************************************************************************/
 #define EP93XX_UART_MCR_OFFSET		(0x0100)
@@ -550,15 +591,8 @@ extern void ep93xx_gpio_init(void);
 
 void __init ep93xx_init_devices(void)
 {
-	unsigned int v;
-
-	/*
-	 * Disallow access to MaverickCrunch initially.
-	 */
-	v = __raw_readl(EP93XX_SYSCON_DEVICE_CONFIG);
-	v &= ~EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE;
-	__raw_writel(0xaa, EP93XX_SYSCON_SWLOCK);
-	__raw_writel(v, EP93XX_SYSCON_DEVICE_CONFIG);
+	/* Disallow access to MaverickCrunch initially */
+	ep93xx_devcfg_clear_bits(EP93XX_SYSCON_DEVCFG_CPENA);
 
 	ep93xx_gpio_init();