summaryrefslogtreecommitdiff
path: root/drivers/hwmon
diff options
context:
space:
mode:
authorBitan Biswas <bbiswas@nvidia.com>2011-07-19 18:11:58 +0530
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:47:49 -0800
commit6e9b68133112f094d1b82b9ce854853b84480895 (patch)
treea7813dc2687a3baed69f52aaab7b5a902cd52ab8 /drivers/hwmon
parent949379b4ff8c0c060d67e0c7f89d5e134685ecca (diff)
hwmon: tegra: tsensor: lp0 save/restore configuration
tsensor configuration needs to be saved before lp0 and restored after lp0 resume else POR values are seen after lp0 resume. - Config0, Config1 and Config2 registers are saved and restored bug 851791 Original-Change-Id: I95532d995af4fa71e169209bb1788fc4152290fe Reviewed-on: http://git-master/r/41819 Reviewed-by: Bitan Biswas <bbiswas@nvidia.com> Tested-by: Bitan Biswas <bbiswas@nvidia.com> Reviewed-by: Narendra Damahe <ndamahe@nvidia.com> Reviewed-by: Laxman Dewangan <ldewangan@nvidia.com> Rebase-Id: Raceac7154fc86486f2726cdd13637d7e8d1e6828
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/tegra-tsensor.c71
1 files changed, 68 insertions, 3 deletions
diff --git a/drivers/hwmon/tegra-tsensor.c b/drivers/hwmon/tegra-tsensor.c
index 7e0f002fc4dd..ae274474e1a7 100644
--- a/drivers/hwmon/tegra-tsensor.c
+++ b/drivers/hwmon/tegra-tsensor.c
@@ -174,6 +174,10 @@ struct tegra_tsensor_data {
int sw_intr_temp;
int hysteresis;
unsigned int ts_state_saved[TSENSOR_COUNT];
+ /* save configuration before suspend and restore after resume */
+ unsigned int config0[TSENSOR_COUNT];
+ unsigned int config1[TSENSOR_COUNT];
+ unsigned int config2[TSENSOR_COUNT];
};
enum {
@@ -1623,6 +1627,59 @@ static int __devexit tegra_tsensor_remove(struct platform_device *pdev)
return 0;
}
+static void dump_a_tsensor_reg(struct tegra_tsensor_data *data,
+ unsigned int addr)
+{
+ dev_dbg(data->hwmon_dev, "\n tsensor[%d][0x%x]: 0x%x ", (addr >> 16),
+ addr & 0xFFFF, tsensor_readl(data, addr));
+}
+
+static void dump_tsensor_regs(struct tegra_tsensor_data *data)
+{
+ int i;
+ for (i = 0; i < TSENSOR_COUNT; i++) {
+ /* if STOP bit is set skip this check */
+ dump_a_tsensor_reg(data, ((i << 16) | SENSOR_CFG0));
+ dump_a_tsensor_reg(data, ((i << 16) | SENSOR_CFG1));
+ dump_a_tsensor_reg(data, ((i << 16) | SENSOR_CFG2));
+ dump_a_tsensor_reg(data, ((i << 16) | SENSOR_STATUS0));
+ dump_a_tsensor_reg(data, ((i << 16) | SENSOR_TS_STATUS1));
+ dump_a_tsensor_reg(data, ((i << 16) | SENSOR_TS_STATUS2));
+ dump_a_tsensor_reg(data, ((i << 16) | 0x0));
+ dump_a_tsensor_reg(data, ((i << 16) | 0x44));
+ dump_a_tsensor_reg(data, ((i << 16) | 0x50));
+ dump_a_tsensor_reg(data, ((i << 16) | 0x54));
+ dump_a_tsensor_reg(data, ((i << 16) | 0x64));
+ dump_a_tsensor_reg(data, ((i << 16) | 0x68));
+ }
+}
+
+static void save_tsensor_regs(struct tegra_tsensor_data *data)
+{
+ int i;
+ for (i = 0; i < TSENSOR_COUNT; i++) {
+ data->config0[i] = tsensor_readl(data,
+ ((i << 16) | SENSOR_CFG0));
+ data->config1[i] = tsensor_readl(data,
+ ((i << 16) | SENSOR_CFG1));
+ data->config2[i] = tsensor_readl(data,
+ ((i << 16) | SENSOR_CFG2));
+ }
+}
+
+static void restore_tsensor_regs(struct tegra_tsensor_data *data)
+{
+ int i;
+ for (i = 0; i < TSENSOR_COUNT; i++) {
+ tsensor_writel(data, data->config0[i],
+ ((i << 16) | SENSOR_CFG0));
+ tsensor_writel(data, data->config1[i],
+ ((i << 16) | SENSOR_CFG1));
+ tsensor_writel(data, data->config2[i],
+ ((i << 16) | SENSOR_CFG2));
+ }
+}
+
#ifdef CONFIG_PM
static int tsensor_suspend(struct platform_device *pdev,
pm_message_t state)
@@ -1630,13 +1687,16 @@ static int tsensor_suspend(struct platform_device *pdev,
struct tegra_tsensor_data *data = platform_get_drvdata(pdev);
unsigned int config0;
int i;
+ dev_dbg(data->hwmon_dev, "\n tsensor before suspend reg dump: ");
+ dump_tsensor_regs(data);
/* set STOP bit, else OVERFLOW interrupt seen in LP1 */
for (i = 0; i < TSENSOR_COUNT; i++) {
config0 = tsensor_readl(data, ((i << 16) | SENSOR_CFG0));
config0 |= (1 << SENSOR_CFG0_STOP_SHIFT);
tsensor_writel(data, config0, ((i << 16) | SENSOR_CFG0));
}
- /* TBD: check anything else that could be needed for suspend */
+ /* save current settings before suspend, when STOP bit is set */
+ save_tsensor_regs(data);
tsensor_clk_enable(data, false);
return 0;
@@ -1647,14 +1707,19 @@ static int tsensor_resume(struct platform_device *pdev)
struct tegra_tsensor_data *data = platform_get_drvdata(pdev);
unsigned int config0;
int i;
- /* TBD: check anything else that could be needed for resume */
tsensor_clk_enable(data, true);
- /* clear STOP bit */
+ /* restore current settings before suspend, no need
+ * to clear STOP bit */
+ restore_tsensor_regs(data);
+ /* clear STOP bit, after restoring regs */
for (i = 0; i < TSENSOR_COUNT; i++) {
config0 = tsensor_readl(data, ((i << 16) | SENSOR_CFG0));
config0 &= ~(1 << SENSOR_CFG0_STOP_SHIFT);
tsensor_writel(data, config0, ((i << 16) | SENSOR_CFG0));
}
+ msleep(1);
+ dev_dbg(data->hwmon_dev, "\n tsensor after resume reg dump: ");
+ dump_tsensor_regs(data);
return 0;
}