From 8968ae08cddf69dcd4d297129623fe63e97b8818 Mon Sep 17 00:00:00 2001 From: Siddartha Mohanadoss Date: Thu, 29 Sep 2011 13:50:24 -0700 Subject: [PATCH] thermal: tsens: Add suspend/resume for TSENS TSENS does not operate reliably during VDD_CX minimization. Incorrect temperature readings are reported on some instances when Apps processor comes out of suspend. This leads the TSENS interrupt being triggered in critical temperature zone. Thermal sys takes drastic action of shutting down the phone which is not desired. Hence remove updating the thermal sys on temperature changes as its not required. CRs-Fixed: 309855 Change-Id: Id6186b2a6032150273bc0d74d91c72db5a077ac7 Signed-off-by: Siddartha Mohanadoss Signed-off-by: David Brown --- drivers/thermal/msm_tsens.c | 56 ++++++++++++++++++++++++++++++++++--- 1 file changed, 52 insertions(+), 4 deletions(-) diff --git a/drivers/thermal/msm_tsens.c b/drivers/thermal/msm_tsens.c index 40c685093917..3a7f9fb785cb 100644 --- a/drivers/thermal/msm_tsens.c +++ b/drivers/thermal/msm_tsens.c @@ -29,6 +29,7 @@ #include #include +#include /* Trips: from very hot to very cold */ enum tsens_trip_type { @@ -93,6 +94,7 @@ struct tsens_tm_device { bool prev_reading_avail; int offset; struct work_struct work; + uint32_t pm_tsens_thr_data; }; struct tsens_tm_device *tmdev; @@ -476,9 +478,6 @@ static irqreturn_t tsens_isr_thread(int irq, void *data) if (lower_th_x) mask |= TSENS_LOWER_STATUS_CLR; if (upper_th_x || lower_th_x) { - thermal_zone_device_update( - tm->sensor[i].tz_dev); - /* Notify user space */ schedule_work(&tm->work); adc_code = readl(TSENS_S0_STATUS_ADDR @@ -495,6 +494,53 @@ static irqreturn_t tsens_isr_thread(int irq, void *data) return IRQ_HANDLED; } +#ifdef CONFIG_PM +static int tsens_suspend(struct device *dev) +{ + unsigned int reg; + + tmdev->pm_tsens_thr_data = readl_relaxed(TSENS_THRESHOLD_ADDR); + reg = readl_relaxed(TSENS_CNTL_ADDR); + writel_relaxed(reg & ~(TSENS_SLP_CLK_ENA | TSENS_EN), TSENS_CNTL_ADDR); + tmdev->prev_reading_avail = 0; + + disable_irq_nosync(TSENS_UPPER_LOWER_INT); + mb(); + return 0; +} + +static int tsens_resume(struct device *dev) +{ + unsigned int reg; + + reg = readl_relaxed(TSENS_CNTL_ADDR); + writel_relaxed(reg | TSENS_SW_RST, TSENS_CNTL_ADDR); + reg |= TSENS_SLP_CLK_ENA | TSENS_EN | (TSENS_MEASURE_PERIOD << 16) | + TSENS_LOWER_STATUS_CLR | TSENS_UPPER_STATUS_CLR | + TSENS_MIN_STATUS_MASK | TSENS_MAX_STATUS_MASK | + (((1 << TSENS_NUM_SENSORS) - 1) << 3); + + reg = (reg & ~TSENS_CONFIG_MASK) | (TSENS_CONFIG << TSENS_CONFIG_SHIFT); + writel_relaxed(reg, TSENS_CNTL_ADDR); + + if (tmdev->sensor->mode == THERMAL_DEVICE_DISABLED) { + writel_relaxed(reg & ~((((1 << TSENS_NUM_SENSORS) - 1) << 3) + | TSENS_SLP_CLK_ENA | TSENS_EN), TSENS_CNTL_ADDR); + } + + writel_relaxed(tmdev->pm_tsens_thr_data, TSENS_THRESHOLD_ADDR); + + enable_irq(TSENS_UPPER_LOWER_INT); + mb(); + return 0; +} + +static const struct dev_pm_ops tsens_pm_ops = { + .suspend = tsens_suspend, + .resume = tsens_resume, +}; +#endif + static int __devinit tsens_tm_probe(struct platform_device *pdev) { unsigned int reg, i, calib_data, calib_data_backup; @@ -560,7 +606,6 @@ static int __devinit tsens_tm_probe(struct platform_device *pdev) return -ENODEV; } tmdev->sensor[i].sensor_num = i; - thermal_zone_device_update(tmdev->sensor[i].tz_dev); tmdev->sensor[i].mode = THERMAL_DEVICE_DISABLED; } @@ -601,6 +646,9 @@ static struct platform_driver tsens_tm_driver = { .driver = { .name = "tsens-tm", .owner = THIS_MODULE, +#ifdef CONFIG_PM + .pm = &tsens_pm_ops, +#endif }, };