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 <smohanad@codeaurora.org>
Signed-off-by: David Brown <davidb@codeaurora.org>
This commit is contained in:
Siddartha Mohanadoss 2011-09-29 13:50:24 -07:00 committed by Stephen Boyd
parent 74c1658ff9
commit 8968ae08cd

View file

@ -29,6 +29,7 @@
#include <linux/io.h>
#include <mach/msm_iomap.h>
#include <linux/pm.h>
/* 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
},
};