thermal: pm8xxx-tm: Use delayed_work task for temp alarm status reading

Use a delayed_work task to wait at least 40 ms in order for the
temp alarm status value to be updated after the TEMP_STAT IRQ
goes high.  Also remove IRQ enable and disable calls in the ISR
since the work item can only be enqueued once before it is run.

Change-Id: Ib5f13d0e82258b399749de96152c081d71981909
Signed-off-by: David Collins <collinsd@codeaurora.org>
(cherry picked from commit a42ed24bdc1a1ab8e2c0148430df063ee0679d18)
This commit is contained in:
David Collins
2012-09-12 14:58:54 -07:00
committed by Iliyan Malchev
parent 668fd2e679
commit bdda1c7404

View File

@@ -65,7 +65,7 @@
struct pm8xxx_tm_chip { struct pm8xxx_tm_chip {
struct pm8xxx_tm_core_data cdata; struct pm8xxx_tm_core_data cdata;
struct work_struct irq_work; struct delayed_work irq_work;
struct device *dev; struct device *dev;
struct thermal_zone_device *tz_dev; struct thermal_zone_device *tz_dev;
unsigned long temp; unsigned long temp;
@@ -83,6 +83,9 @@ enum pmic_thermal_override_mode {
SOFTWARE_OVERRIDE_ENABLED, SOFTWARE_OVERRIDE_ENABLED,
}; };
/* Delay between TEMP_STAT IRQ going high and status value changing in ms. */
#define STATUS_REGISTER_DELAY_MS 40
static inline int pm8xxx_tm_read_ctrl(struct pm8xxx_tm_chip *chip, u8 *reg) static inline int pm8xxx_tm_read_ctrl(struct pm8xxx_tm_chip *chip, u8 *reg)
{ {
int rc; int rc;
@@ -422,8 +425,10 @@ static struct thermal_zone_device_ops pm8xxx_thermal_zone_ops_pm8058_adc = {
static void pm8xxx_tm_work(struct work_struct *work) static void pm8xxx_tm_work(struct work_struct *work)
{ {
struct delayed_work *dwork
= container_of(work, struct delayed_work, work);
struct pm8xxx_tm_chip *chip struct pm8xxx_tm_chip *chip
= container_of(work, struct pm8xxx_tm_chip, irq_work); = container_of(dwork, struct pm8xxx_tm_chip, irq_work);
unsigned long temp = 0; unsigned long temp = 0;
int rc, stage, thresh; int rc, stage, thresh;
u8 reg; u8 reg;
@@ -472,17 +477,15 @@ static void pm8xxx_tm_work(struct work_struct *work)
} }
bail: bail:
enable_irq(chip->tempstat_irq); return;
enable_irq(chip->overtemp_irq);
} }
static irqreturn_t pm8xxx_tm_isr(int irq, void *data) static irqreturn_t pm8xxx_tm_isr(int irq, void *data)
{ {
struct pm8xxx_tm_chip *chip = data; struct pm8xxx_tm_chip *chip = data;
disable_irq_nosync(chip->tempstat_irq); schedule_delayed_work(&chip->irq_work,
disable_irq_nosync(chip->overtemp_irq); msecs_to_jiffies(STATUS_REGISTER_DELAY_MS) + 1);
schedule_work(&chip->irq_work);
return IRQ_HANDLED; return IRQ_HANDLED;
} }
@@ -621,7 +624,7 @@ static int __devinit pm8xxx_tm_probe(struct platform_device *pdev)
chip->mode = THERMAL_DEVICE_DISABLED; chip->mode = THERMAL_DEVICE_DISABLED;
thermal_zone_device_update(chip->tz_dev); thermal_zone_device_update(chip->tz_dev);
INIT_WORK(&chip->irq_work, pm8xxx_tm_work); INIT_DELAYED_WORK(&chip->irq_work, pm8xxx_tm_work);
rc = request_irq(chip->tempstat_irq, pm8xxx_tm_isr, IRQF_TRIGGER_RISING, rc = request_irq(chip->tempstat_irq, pm8xxx_tm_isr, IRQF_TRIGGER_RISING,
chip->cdata.irq_name_temp_stat, chip); chip->cdata.irq_name_temp_stat, chip);
@@ -646,7 +649,7 @@ static int __devinit pm8xxx_tm_probe(struct platform_device *pdev)
err_free_irq_tempstat: err_free_irq_tempstat:
free_irq(chip->tempstat_irq, chip); free_irq(chip->tempstat_irq, chip);
err_cancel_work: err_cancel_work:
cancel_work_sync(&chip->irq_work); cancel_delayed_work_sync(&chip->irq_work);
err_free_tz: err_free_tz:
thermal_zone_device_unregister(chip->tz_dev); thermal_zone_device_unregister(chip->tz_dev);
err_fail_adc: err_fail_adc:
@@ -662,7 +665,7 @@ static int __devexit pm8xxx_tm_remove(struct platform_device *pdev)
if (chip) { if (chip) {
platform_set_drvdata(pdev, NULL); platform_set_drvdata(pdev, NULL);
cancel_work_sync(&chip->irq_work); cancel_delayed_work_sync(&chip->irq_work);
free_irq(chip->overtemp_irq, chip); free_irq(chip->overtemp_irq, chip);
free_irq(chip->tempstat_irq, chip); free_irq(chip->tempstat_irq, chip);
pm8xxx_tm_shutdown_override(chip, SOFTWARE_OVERRIDE_DISABLED); pm8xxx_tm_shutdown_override(chip, SOFTWARE_OVERRIDE_DISABLED);