msm: footswitch-8x60: Detect footswitch state at boot
If a footswitch is already enabled according to its register,
a call to enable it should return early and not touch the clocks
or resets associated with the core. Otherwise, the first call to
enable the footswitch at boot will reset the core's state.
This modification allows for smooth hand-offs of core control
from the bootloaders to Linux so that, for example, an image
displayed by the MDP core can be made to persist across the
kernel display driver's call to enable the footswitch.
Signed-off-by: Matt Wagantall <mattw@codeaurora.org>
diff --git a/arch/arm/mach-msm/footswitch-8x60.c b/arch/arm/mach-msm/footswitch-8x60.c
index 6ba3962..8bb2576 100644
--- a/arch/arm/mach-msm/footswitch-8x60.c
+++ b/arch/arm/mach-msm/footswitch-8x60.c
@@ -145,6 +145,11 @@
fs->is_claimed = true;
mutex_unlock(&claim_lock);
+ /* Return early if already enabled. */
+ regval = readl_relaxed(fs->gfs_ctl_reg);
+ if ((regval & (ENABLE_BIT | CLAMP_BIT)) == ENABLE_BIT)
+ return 0;
+
/* Make sure required clocks are on at the correct rates. */
rc = setup_clocks(fs);
if (rc)
@@ -179,7 +184,6 @@
udelay(RESET_DELAY_US);
/* Enable the power rail at the footswitch. */
- regval = readl_relaxed(fs->gfs_ctl_reg);
regval |= ENABLE_BIT;
writel_relaxed(regval, fs->gfs_ctl_reg);
/* Wait for the rail to fully charge. */
@@ -216,6 +220,11 @@
struct footswitch *fs = rdev_get_drvdata(rdev);
uint32_t regval, rc = 0;
+ /* Return early if already disabled. */
+ regval = readl_relaxed(fs->gfs_ctl_reg);
+ if ((regval & ENABLE_BIT) == 0)
+ return 0;
+
/* Make sure required clocks are on at the correct rates. */
rc = setup_clocks(fs);
if (rc)
@@ -252,7 +261,6 @@
* Clamp the I/O ports of the core to ensure the values
* remain fixed while the core is collapsed.
*/
- regval = readl_relaxed(fs->gfs_ctl_reg);
regval |= CLAMP_BIT;
writel_relaxed(regval, fs->gfs_ctl_reg);
@@ -282,6 +290,11 @@
fs->is_claimed = true;
mutex_unlock(&claim_lock);
+ /* Return early if already enabled. */
+ regval = readl_relaxed(fs->gfs_ctl_reg);
+ if ((regval & (ENABLE_BIT | CLAMP_BIT)) == ENABLE_BIT)
+ return 0;
+
/* Make sure required clocks are on at the correct rates. */
rc = setup_clocks(fs);
if (rc)
@@ -312,7 +325,6 @@
udelay(20);
/* Enable the power rail at the footswitch. */
- regval = readl_relaxed(fs->gfs_ctl_reg);
regval |= ENABLE_BIT;
writel_relaxed(regval, fs->gfs_ctl_reg);
mb();
@@ -345,6 +357,11 @@
struct footswitch *fs = rdev_get_drvdata(rdev);
uint32_t regval, rc = 0;
+ /* Return early if already disabled. */
+ regval = readl_relaxed(fs->gfs_ctl_reg);
+ if ((regval & ENABLE_BIT) == 0)
+ return 0;
+
/* Make sure required clocks are on at the correct rates. */
rc = setup_clocks(fs);
if (rc)
@@ -377,7 +394,6 @@
* Clamp the I/O ports of the core to ensure the values
* remain fixed while the core is collapsed.
*/
- regval = readl_relaxed(fs->gfs_ctl_reg);
regval |= CLAMP_BIT;
writel_relaxed(regval, fs->gfs_ctl_reg);