diff options
author | Joshua Primero <jprimero@nvidia.com> | 2012-01-19 16:42:10 -0800 |
---|---|---|
committer | Simone Willett <swillett@nvidia.com> | 2012-02-27 20:46:14 -0800 |
commit | 2b382eec86290b09660a9499598a4d9c55abe556 (patch) | |
tree | 3f65d2c3887285443a218ff500834d386f0bfacc /drivers/misc | |
parent | 566594ce3b1dbfc8397a62826992a0794612f51a (diff) |
drivers: misc: nct: Fixed nct interrupt handler
Fixed nct bug where interrupts would go missing because
thermal_alert would not correctly set the state of
the thermal device.
Change-Id: I09f4e7816fe606e576b257281acd498428f0d941
Signed-off-by: Joshua Primero <jprimero@nvidia.com>
Reviewed-on: http://git-master/r/84674
(cherry picked from commit 5bba6f1b63225ce9ab0ab45a8513541d4435ace5)
Reviewed-on: http://git-master/r/85945
Reviewed-by: Diwakar Tundlam <dtundlam@nvidia.com>
Diffstat (limited to 'drivers/misc')
-rw-r--r-- | drivers/misc/nct1008.c | 91 |
1 files changed, 11 insertions, 80 deletions
diff --git a/drivers/misc/nct1008.c b/drivers/misc/nct1008.c index a9a0891f5c75..643f91d69b4d 100644 --- a/drivers/misc/nct1008.c +++ b/drivers/misc/nct1008.c @@ -488,99 +488,34 @@ static int nct1008_disable(struct i2c_client *client) return err; } -static int nct1008_disable_alert(struct nct1008_data *data) +static int nct1008_within_limits(struct nct1008_data *data) { - struct i2c_client *client = data->client; - int ret = 0; - int val; - - /* - * Disable ALERT# output, because these chips don't implement - * SMBus alert correctly; they should only hold the alert line - * low briefly. - */ - val = i2c_smbus_read_byte_data(data->client, CONFIG_RD); - if (val < 0) { - dev_err(&client->dev, "%s, line=%d, disable alert failed ... " - "i2c read error=%d\n", __func__, __LINE__, val); - return val; - } - data->config = val | ALERT_BIT; - ret = i2c_smbus_write_byte_data(client, CONFIG_WR, data->config); - if (ret) - dev_err(&client->dev, "%s: fail to disable alert, i2c " - "write error=%d#\n", __func__, ret); - - return ret; -} - -static int nct1008_enable_alert(struct nct1008_data *data) -{ - int val; - int ret; + int intr_status; - val = i2c_smbus_read_byte_data(data->client, CONFIG_RD); - if (val < 0) { - dev_err(&data->client->dev, "%s, line=%d, enable alert " - "failed ... i2c read error=%d\n", __func__, - __LINE__, val); - return val; - } - val &= ~(ALERT_BIT | THERM2_BIT); - ret = i2c_smbus_write_byte_data(data->client, CONFIG_WR, val); - if (ret) { - dev_err(&data->client->dev, "%s: fail to enable alert, i2c " - "write error=%d\n", __func__, ret); - return ret; - } + intr_status = i2c_smbus_read_byte_data(data->client, STATUS_RD); - return ret; + return !(intr_status & (BIT(3) | BIT(4))); } static void nct1008_work_func(struct work_struct *work) { struct nct1008_data *data = container_of(work, struct nct1008_data, work); - int err = 0; - int intr_status = i2c_smbus_read_byte_data(data->client, STATUS_RD); - - if (intr_status < 0) { - dev_err(&data->client->dev, "%s, line=%d, i2c read error=%d\n", - __func__, __LINE__, intr_status); - return; - } - intr_status &= (BIT(3) | BIT(4)); - if (!intr_status) - return; + if (data->alert_func) + if (!nct1008_within_limits(data)) + data->alert_func(data->alert_data); - if (data->alert_func) { - err = nct1008_disable_alert(data); - if (err) { - dev_err(&data->client->dev, - "%s: disable alert fail(error=%d)\n", - __func__, err); - return; - } - - data->alert_func(data->alert_data); - - nct1008_enable_alert(data); - } - - - if (err) - dev_err(&data->client->dev, "%s: fail(error=%d)\n", __func__, - err); - else - pr_debug("%s: done\n", __func__); + enable_irq(data->client->irq); } static irqreturn_t nct1008_irq(int irq, void *dev_id) { struct nct1008_data *data = dev_id; + disable_irq_nosync(irq); schedule_work(&data->work); + return IRQ_HANDLED; } @@ -737,7 +672,7 @@ static int __devinit nct1008_configure_irq(struct nct1008_data *data) return 0; else return request_irq(data->client->irq, nct1008_irq, - IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, + IRQF_TRIGGER_LOW, DRIVER_NAME, data); } @@ -794,10 +729,6 @@ int nct1008_thermal_set_limits(struct nct1008_data *data, if (lo_limit >= hi_limit) return -EINVAL; - if (data->current_lo_limit == lo_limit && - data->current_hi_limit == hi_limit) - return 0; - if (data->current_lo_limit != lo_limit) { value = temperature_to_value(extended_range, lo_limit); pr_debug("%s: set lo_limit %ld\n", __func__, lo_limit); |