From: Lars-Peter Clausen <lars@metafoo.de> To: Jean Delvare <khali@linux-fr.org>, Guenter Roeck <linux@roeck-us.net> Cc: Hartmut Knaack <knaack.h@gmx.de>, Jonathan Cameron <jic23@cam.ac.uk>, lm-sensors@lm-sensors.org, linux-iio@vger.kernel.org, Lars-Peter Clausen <lars@metafoo.de> Subject: [PATCH v2 1/4] hwmon: (adt7410) Don't re-read non-volatile registers Date: Mon, 18 Feb 2013 14:38:56 +0100 [thread overview] Message-ID: <1361194739-16525-1-git-send-email-lars@metafoo.de> (raw) Currently each time the temperature register is read the driver also reads the threshold and hysteresis registers. This increases the amount of I2C traffic and time needed to read the temperature by a factor of ~5. Neither the threshold nor the hysteresis change on their own, so once we've read them, we should be able to just use the cached value of the registers. This patch modifies the code accordingly and only reads the threshold and hysteresis registers once during probe. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> --- Changes since v1: * Fix error checking for i2c reads --- drivers/hwmon/adt7410.c | 91 +++++++++++++++++++++++++++++++------------------ 1 file changed, 58 insertions(+), 33 deletions(-) diff --git a/drivers/hwmon/adt7410.c b/drivers/hwmon/adt7410.c index 99a7290..b6acfa4 100644 --- a/drivers/hwmon/adt7410.c +++ b/drivers/hwmon/adt7410.c @@ -119,45 +119,33 @@ static int adt7410_temp_ready(struct i2c_client *client) return -ETIMEDOUT; } -static struct adt7410_data *adt7410_update_device(struct device *dev) +static int adt7410_update_temp(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct adt7410_data *data = i2c_get_clientdata(client); - struct adt7410_data *ret = data; + int ret = 0; + mutex_lock(&data->update_lock); if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || !data->valid) { - int i, status; + int temp; dev_dbg(&client->dev, "Starting update\n"); - status = adt7410_temp_ready(client); /* check for new value */ - if (unlikely(status)) { - ret = ERR_PTR(status); + ret = adt7410_temp_ready(client); /* check for new value */ + if (ret) goto abort; - } - for (i = 0; i < ARRAY_SIZE(data->temp); i++) { - status = i2c_smbus_read_word_swapped(client, - ADT7410_REG_TEMP[i]); - if (unlikely(status < 0)) { - dev_dbg(dev, - "Failed to read value: reg %d, error %d\n", - ADT7410_REG_TEMP[i], status); - ret = ERR_PTR(status); - goto abort; - } - data->temp[i] = status; - } - status = i2c_smbus_read_byte_data(client, ADT7410_T_HYST); - if (unlikely(status < 0)) { - dev_dbg(dev, - "Failed to read value: reg %d, error %d\n", - ADT7410_T_HYST, status); - ret = ERR_PTR(status); + + temp = i2c_smbus_read_word_swapped(client, ADT7410_REG_TEMP[0]); + if (temp < 0) { + ret = temp; + dev_dbg(dev, "Failed to read value: reg %d, error %d\n", + ADT7410_REG_TEMP[0], ret); goto abort; } - data->hyst = status; + data->temp[0] = temp; + data->last_updated = jiffies; data->valid = true; } @@ -167,6 +155,35 @@ abort: return ret; } +static int adt7410_fill_cache(struct i2c_client *client) +{ + struct adt7410_data *data = i2c_get_clientdata(client); + int ret; + int i; + + for (i = 1; i < ARRAY_SIZE(ADT7410_REG_TEMP); i++) { + ret = i2c_smbus_read_word_swapped(client, ADT7410_REG_TEMP[i]); + if (ret < 0) { + dev_dbg(&client->dev, + "Failed to read value: reg %d, error %d\n", + ADT7410_REG_TEMP[0], ret); + return ret; + } + data->temp[i] = ret; + } + + ret = i2c_smbus_read_byte_data(client, ADT7410_T_HYST); + if (ret < 0) { + dev_dbg(&client->dev, + "Failed to read value: hyst reg, error %d\n", + ret); + return ret; + } + data->hyst = ret; + + return 0; +} + static s16 ADT7410_TEMP_TO_REG(long temp) { return DIV_ROUND_CLOSEST(clamp_val(temp, ADT7410_TEMP_MIN, @@ -193,10 +210,16 @@ static ssize_t adt7410_show_temp(struct device *dev, struct device_attribute *da, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct adt7410_data *data = adt7410_update_device(dev); + struct i2c_client *client = to_i2c_client(dev); + struct adt7410_data *data = i2c_get_clientdata(client); - if (IS_ERR(data)) - return PTR_ERR(data); + if (attr->index == 0) { + int ret; + + ret = adt7410_update_temp(dev); + if (ret) + return ret; + } return sprintf(buf, "%d\n", ADT7410_REG_TO_TEMP(data, data->temp[attr->index])); @@ -232,13 +255,11 @@ static ssize_t adt7410_show_t_hyst(struct device *dev, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct adt7410_data *data; + struct i2c_client *client = to_i2c_client(dev); + struct adt7410_data *data = i2c_get_clientdata(client); int nr = attr->index; int hyst; - data = adt7410_update_device(dev); - if (IS_ERR(data)) - return PTR_ERR(data); hyst = (data->hyst & ADT7410_T_HYST_MASK) * 1000; /* @@ -371,6 +392,10 @@ static int adt7410_probe(struct i2c_client *client, } dev_dbg(&client->dev, "Config %02x\n", data->config); + ret = adt7410_fill_cache(client); + if (ret) + goto exit_restore; + /* Register sysfs hooks */ ret = sysfs_create_group(&client->dev.kobj, &adt7410_group); if (ret) -- 1.8.0
WARNING: multiple messages have this Message-ID (diff)
From: Lars-Peter Clausen <lars@metafoo.de> To: Jean Delvare <khali@linux-fr.org>, Guenter Roeck <linux@roeck-us.net> Cc: Hartmut Knaack <knaack.h@gmx.de>, Jonathan Cameron <jic23@cam.ac.uk>, lm-sensors@lm-sensors.org, linux-iio@vger.kernel.org, Lars-Peter Clausen <lars@metafoo.de> Subject: [lm-sensors] [PATCH v2 1/4] hwmon: (adt7410) Don't re-read non-volatile registers Date: Mon, 18 Feb 2013 13:38:56 +0000 [thread overview] Message-ID: <1361194739-16525-1-git-send-email-lars@metafoo.de> (raw) Currently each time the temperature register is read the driver also reads the threshold and hysteresis registers. This increases the amount of I2C traffic and time needed to read the temperature by a factor of ~5. Neither the threshold nor the hysteresis change on their own, so once we've read them, we should be able to just use the cached value of the registers. This patch modifies the code accordingly and only reads the threshold and hysteresis registers once during probe. Signed-off-by: Lars-Peter Clausen <lars@metafoo.de> --- Changes since v1: * Fix error checking for i2c reads --- drivers/hwmon/adt7410.c | 91 +++++++++++++++++++++++++++++++------------------ 1 file changed, 58 insertions(+), 33 deletions(-) diff --git a/drivers/hwmon/adt7410.c b/drivers/hwmon/adt7410.c index 99a7290..b6acfa4 100644 --- a/drivers/hwmon/adt7410.c +++ b/drivers/hwmon/adt7410.c @@ -119,45 +119,33 @@ static int adt7410_temp_ready(struct i2c_client *client) return -ETIMEDOUT; } -static struct adt7410_data *adt7410_update_device(struct device *dev) +static int adt7410_update_temp(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); struct adt7410_data *data = i2c_get_clientdata(client); - struct adt7410_data *ret = data; + int ret = 0; + mutex_lock(&data->update_lock); if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || !data->valid) { - int i, status; + int temp; dev_dbg(&client->dev, "Starting update\n"); - status = adt7410_temp_ready(client); /* check for new value */ - if (unlikely(status)) { - ret = ERR_PTR(status); + ret = adt7410_temp_ready(client); /* check for new value */ + if (ret) goto abort; - } - for (i = 0; i < ARRAY_SIZE(data->temp); i++) { - status = i2c_smbus_read_word_swapped(client, - ADT7410_REG_TEMP[i]); - if (unlikely(status < 0)) { - dev_dbg(dev, - "Failed to read value: reg %d, error %d\n", - ADT7410_REG_TEMP[i], status); - ret = ERR_PTR(status); - goto abort; - } - data->temp[i] = status; - } - status = i2c_smbus_read_byte_data(client, ADT7410_T_HYST); - if (unlikely(status < 0)) { - dev_dbg(dev, - "Failed to read value: reg %d, error %d\n", - ADT7410_T_HYST, status); - ret = ERR_PTR(status); + + temp = i2c_smbus_read_word_swapped(client, ADT7410_REG_TEMP[0]); + if (temp < 0) { + ret = temp; + dev_dbg(dev, "Failed to read value: reg %d, error %d\n", + ADT7410_REG_TEMP[0], ret); goto abort; } - data->hyst = status; + data->temp[0] = temp; + data->last_updated = jiffies; data->valid = true; } @@ -167,6 +155,35 @@ abort: return ret; } +static int adt7410_fill_cache(struct i2c_client *client) +{ + struct adt7410_data *data = i2c_get_clientdata(client); + int ret; + int i; + + for (i = 1; i < ARRAY_SIZE(ADT7410_REG_TEMP); i++) { + ret = i2c_smbus_read_word_swapped(client, ADT7410_REG_TEMP[i]); + if (ret < 0) { + dev_dbg(&client->dev, + "Failed to read value: reg %d, error %d\n", + ADT7410_REG_TEMP[0], ret); + return ret; + } + data->temp[i] = ret; + } + + ret = i2c_smbus_read_byte_data(client, ADT7410_T_HYST); + if (ret < 0) { + dev_dbg(&client->dev, + "Failed to read value: hyst reg, error %d\n", + ret); + return ret; + } + data->hyst = ret; + + return 0; +} + static s16 ADT7410_TEMP_TO_REG(long temp) { return DIV_ROUND_CLOSEST(clamp_val(temp, ADT7410_TEMP_MIN, @@ -193,10 +210,16 @@ static ssize_t adt7410_show_temp(struct device *dev, struct device_attribute *da, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct adt7410_data *data = adt7410_update_device(dev); + struct i2c_client *client = to_i2c_client(dev); + struct adt7410_data *data = i2c_get_clientdata(client); - if (IS_ERR(data)) - return PTR_ERR(data); + if (attr->index = 0) { + int ret; + + ret = adt7410_update_temp(dev); + if (ret) + return ret; + } return sprintf(buf, "%d\n", ADT7410_REG_TO_TEMP(data, data->temp[attr->index])); @@ -232,13 +255,11 @@ static ssize_t adt7410_show_t_hyst(struct device *dev, char *buf) { struct sensor_device_attribute *attr = to_sensor_dev_attr(da); - struct adt7410_data *data; + struct i2c_client *client = to_i2c_client(dev); + struct adt7410_data *data = i2c_get_clientdata(client); int nr = attr->index; int hyst; - data = adt7410_update_device(dev); - if (IS_ERR(data)) - return PTR_ERR(data); hyst = (data->hyst & ADT7410_T_HYST_MASK) * 1000; /* @@ -371,6 +392,10 @@ static int adt7410_probe(struct i2c_client *client, } dev_dbg(&client->dev, "Config %02x\n", data->config); + ret = adt7410_fill_cache(client); + if (ret) + goto exit_restore; + /* Register sysfs hooks */ ret = sysfs_create_group(&client->dev.kobj, &adt7410_group); if (ret) -- 1.8.0 _______________________________________________ lm-sensors mailing list lm-sensors@lm-sensors.org http://lists.lm-sensors.org/mailman/listinfo/lm-sensors
next reply other threads:[~2013-02-18 13:37 UTC|newest] Thread overview: 47+ messages / expand[flat|nested] mbox.gz Atom feed top 2013-02-18 13:38 Lars-Peter Clausen [this message] 2013-02-18 13:38 ` [lm-sensors] [PATCH v2 1/4] hwmon: (adt7410) Don't re-read non-volatile registers Lars-Peter Clausen 2013-02-18 13:38 ` [PATCH v2 2/4] hwmon: (adt7410) Add support for the adt7310/adt7320 Lars-Peter Clausen 2013-02-18 13:38 ` [lm-sensors] [PATCH v2 2/4] hwmon: (adt7410) =?utf-8?q?Add_support_for_the_ad Lars-Peter Clausen 2013-02-19 1:30 ` [PATCH v2 2/4] hwmon: (adt7410) Add support for the adt7310/adt7320 Guenter Roeck 2013-02-19 1:30 ` [lm-sensors] " Guenter Roeck 2013-02-19 11:57 ` Lars-Peter Clausen 2013-02-19 11:57 ` [lm-sensors] " Lars-Peter Clausen 2013-02-19 16:52 ` Guenter Roeck 2013-02-19 16:52 ` [lm-sensors] " Guenter Roeck 2013-02-18 13:38 ` [PATCH v2 3/4] hwmon: (adt7x10) Add alarm interrupt support Lars-Peter Clausen 2013-02-18 13:38 ` [lm-sensors] " Lars-Peter Clausen 2013-02-19 1:39 ` Guenter Roeck 2013-02-19 1:39 ` [lm-sensors] " Guenter Roeck 2013-02-19 12:05 ` Lars-Peter Clausen 2013-02-19 12:05 ` [lm-sensors] " Lars-Peter Clausen 2013-02-19 17:10 ` Guenter Roeck 2013-02-19 17:10 ` [lm-sensors] " Guenter Roeck 2013-02-18 13:38 ` [PATCH v2 4/4] staging:iio: Remove adt7410 driver Lars-Peter Clausen 2013-02-18 13:38 ` [lm-sensors] " Lars-Peter Clausen 2013-03-02 16:45 ` Jonathan Cameron 2013-03-02 16:45 ` [lm-sensors] " Jonathan Cameron 2013-03-02 17:10 ` Guenter Roeck 2013-03-02 17:10 ` [lm-sensors] " Guenter Roeck 2013-02-18 20:22 ` [PATCH v2 1/4] hwmon: (adt7410) Don't re-read non-volatile registers Hartmut Knaack 2013-02-18 20:22 ` [lm-sensors] " Hartmut Knaack 2013-02-19 1:02 ` Guenter Roeck 2013-02-19 1:02 ` [lm-sensors] " Guenter Roeck 2013-02-19 19:39 ` Hartmut Knaack 2013-02-19 19:39 ` [lm-sensors] " Hartmut Knaack 2013-02-20 1:22 ` Guenter Roeck 2013-02-20 1:22 ` [lm-sensors] " Guenter Roeck 2013-02-19 1:32 ` Guenter Roeck 2013-02-19 1:32 ` [lm-sensors] " Guenter Roeck 2013-02-23 0:45 ` Hartmut Knaack 2013-02-23 20:18 ` Guenter Roeck 2013-02-23 20:18 ` [lm-sensors] " Guenter Roeck 2013-02-25 22:03 ` Hartmut Knaack 2013-02-25 22:03 ` [lm-sensors] " Hartmut Knaack 2013-02-26 1:40 ` Guenter Roeck 2013-02-26 1:40 ` [lm-sensors] " Guenter Roeck 2013-02-25 9:54 ` Lars-Peter Clausen 2013-02-25 9:54 ` [lm-sensors] " Lars-Peter Clausen 2013-02-25 21:30 ` Hartmut Knaack 2013-02-25 21:30 ` [lm-sensors] " Hartmut Knaack 2013-02-26 1:39 ` Guenter Roeck 2013-02-26 1:39 ` [lm-sensors] " Guenter Roeck
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=1361194739-16525-1-git-send-email-lars@metafoo.de \ --to=lars@metafoo.de \ --cc=jic23@cam.ac.uk \ --cc=khali@linux-fr.org \ --cc=knaack.h@gmx.de \ --cc=linux-iio@vger.kernel.org \ --cc=linux@roeck-us.net \ --cc=lm-sensors@lm-sensors.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.