msm: spm-v2: Support to reinitalize SPM registers
On certain devices SPM hardware block doesn't retain its state through
certain low power modes. This commit allows for reinitialization of
control and sequence entry registers on resume.
Change-Id: Ib70ab1e090dc69fa2901d183b9a25416ad433ba0
Signed-off-by: Maheshkumar Sivasubramanian <msivasub@codeaurora.org>
diff --git a/arch/arm/mach-msm/spm-v2.c b/arch/arm/mach-msm/spm-v2.c
index 4a7cf91..378bcf2 100644
--- a/arch/arm/mach-msm/spm-v2.c
+++ b/arch/arm/mach-msm/spm-v2.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -271,6 +271,17 @@
return -EIO;
}
+void msm_spm_drv_reinit(struct msm_spm_driver_data *dev)
+{
+ int i;
+
+ for (i = 0; i < MSM_SPM_REG_NR_INITIALIZE; i++)
+ msm_spm_drv_flush_shadow(dev, i);
+
+ msm_spm_drv_flush_seq_entry(dev);
+ mb();
+}
+
int __init msm_spm_drv_init(struct msm_spm_driver_data *dev,
struct msm_spm_platform_data *data)
{
diff --git a/arch/arm/mach-msm/spm.h b/arch/arm/mach-msm/spm.h
index b155781..21c7dca 100644
--- a/arch/arm/mach-msm/spm.h
+++ b/arch/arm/mach-msm/spm.h
@@ -115,6 +115,7 @@
#if defined(CONFIG_MSM_L2_SPM)
int msm_spm_l2_set_low_power_mode(unsigned int mode, bool notify_rpm);
int msm_spm_l2_init(struct msm_spm_platform_data *data);
+void msm_spm_l2_reinit(void);
#else
static inline int msm_spm_l2_set_low_power_mode(unsigned int mode,
bool notify_rpm)
@@ -125,6 +126,10 @@
{
return -ENOSYS;
}
+static inline void msm_spm_l2_reinit(void)
+{
+ /* empty */
+}
#endif /* defined(CONFIG_MSM_L2_SPM) */
#else /* defined(CONFIG_MSM_SPM_V1) || defined(CONFIG_MSM_SPM_V2) */
diff --git a/arch/arm/mach-msm/spm_devices.c b/arch/arm/mach-msm/spm_devices.c
index 1f85194..2b17fa3 100644
--- a/arch/arm/mach-msm/spm_devices.c
+++ b/arch/arm/mach-msm/spm_devices.c
@@ -126,6 +126,13 @@
return ret;
}
+void msm_spm_reinit(void)
+{
+ unsigned int cpu;
+ for_each_possible_cpu(cpu)
+ msm_spm_drv_reinit(&per_cpu(msm_cpu_spm_device.reg_data, cpu));
+}
+
int msm_spm_set_low_power_mode(unsigned int mode, bool notify_rpm)
{
struct msm_spm_device *dev = &__get_cpu_var(msm_cpu_spm_device);
@@ -198,4 +205,9 @@
{
return msm_spm_dev_init(&msm_spm_l2_device, data);
}
+
+void msm_spm_l2_reinit(void)
+{
+ msm_spm_drv_reinit(&msm_spm_l2_device.reg_data);
+}
#endif
diff --git a/arch/arm/mach-msm/spm_driver.h b/arch/arm/mach-msm/spm_driver.h
index f8d3cfc..712f051 100644
--- a/arch/arm/mach-msm/spm_driver.h
+++ b/arch/arm/mach-msm/spm_driver.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 and
@@ -23,6 +23,7 @@
int msm_spm_drv_init(struct msm_spm_driver_data *dev,
struct msm_spm_platform_data *data);
+void msm_spm_drv_reinit(struct msm_spm_driver_data *dev);
int msm_spm_drv_set_low_power_mode(struct msm_spm_driver_data *dev,
uint32_t addr);
int msm_spm_drv_set_vdd(struct msm_spm_driver_data *dev,