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:
committed by
Iliyan Malchev
parent
668fd2e679
commit
bdda1c7404
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user