aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon
diff options
context:
space:
mode:
authorLars-Peter Clausen <lars@metafoo.de>2013-03-12 06:38:45 -0400
committerGuenter Roeck <linux@roeck-us.net>2013-04-08 00:16:38 -0400
commitc55dc91e92bdf21427dd8f5ad779ed9d63caacbd (patch)
treeadcf4aa5fbd1a7cb8d3655ad0a37f4dd161c3035 /drivers/hwmon
parentf40fb63e923ccc8c280f8451d4909bb8607a1a8f (diff)
hwmon: (adt7410) Don't re-read non-volatile registers
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 have 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> Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/adt7410.c91
1 files changed, 58 insertions, 33 deletions
diff --git a/drivers/hwmon/adt7410.c b/drivers/hwmon/adt7410.c
index 99a7290da0a3..894ff71499b3 100644
--- a/drivers/hwmon/adt7410.c
+++ b/drivers/hwmon/adt7410.c
@@ -119,45 +119,33 @@ static int adt7410_temp_ready(struct i2c_client *client)
119 return -ETIMEDOUT; 119 return -ETIMEDOUT;
120} 120}
121 121
122static struct adt7410_data *adt7410_update_device(struct device *dev) 122static int adt7410_update_temp(struct device *dev)
123{ 123{
124 struct i2c_client *client = to_i2c_client(dev); 124 struct i2c_client *client = to_i2c_client(dev);
125 struct adt7410_data *data = i2c_get_clientdata(client); 125 struct adt7410_data *data = i2c_get_clientdata(client);
126 struct adt7410_data *ret = data; 126 int ret = 0;
127
127 mutex_lock(&data->update_lock); 128 mutex_lock(&data->update_lock);
128 129
129 if (time_after(jiffies, data->last_updated + HZ + HZ / 2) 130 if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
130 || !data->valid) { 131 || !data->valid) {
131 int i, status; 132 int temp;
132 133
133 dev_dbg(&client->dev, "Starting update\n"); 134 dev_dbg(&client->dev, "Starting update\n");
134 135
135 status = adt7410_temp_ready(client); /* check for new value */ 136 ret = adt7410_temp_ready(client); /* check for new value */
136 if (unlikely(status)) { 137 if (ret)
137 ret = ERR_PTR(status);
138 goto abort; 138 goto abort;
139 } 139
140 for (i = 0; i < ARRAY_SIZE(data->temp); i++) { 140 temp = i2c_smbus_read_word_swapped(client, ADT7410_REG_TEMP[0]);
141 status = i2c_smbus_read_word_swapped(client, 141 if (temp < 0) {
142 ADT7410_REG_TEMP[i]); 142 ret = temp;
143 if (unlikely(status < 0)) { 143 dev_dbg(dev, "Failed to read value: reg %d, error %d\n",
144 dev_dbg(dev, 144 ADT7410_REG_TEMP[0], ret);
145 "Failed to read value: reg %d, error %d\n",
146 ADT7410_REG_TEMP[i], status);
147 ret = ERR_PTR(status);
148 goto abort;
149 }
150 data->temp[i] = status;
151 }
152 status = i2c_smbus_read_byte_data(client, ADT7410_T_HYST);
153 if (unlikely(status < 0)) {
154 dev_dbg(dev,
155 "Failed to read value: reg %d, error %d\n",
156 ADT7410_T_HYST, status);
157 ret = ERR_PTR(status);
158 goto abort; 145 goto abort;
159 } 146 }
160 data->hyst = status; 147 data->temp[0] = temp;
148
161 data->last_updated = jiffies; 149 data->last_updated = jiffies;
162 data->valid = true; 150 data->valid = true;
163 } 151 }
@@ -167,6 +155,35 @@ abort:
167 return ret; 155 return ret;
168} 156}
169 157
158static int adt7410_fill_cache(struct i2c_client *client)
159{
160 struct adt7410_data *data = i2c_get_clientdata(client);
161 int ret;
162 int i;
163
164 for (i = 1; i < ARRAY_SIZE(ADT7410_REG_TEMP); i++) {
165 ret = i2c_smbus_read_word_swapped(client, ADT7410_REG_TEMP[i]);
166 if (ret < 0) {
167 dev_dbg(&client->dev,
168 "Failed to read value: reg %d, error %d\n",
169 ADT7410_REG_TEMP[i], ret);
170 return ret;
171 }
172 data->temp[i] = ret;
173 }
174
175 ret = i2c_smbus_read_byte_data(client, ADT7410_T_HYST);
176 if (ret < 0) {
177 dev_dbg(&client->dev,
178 "Failed to read value: hyst reg, error %d\n",
179 ret);
180 return ret;
181 }
182 data->hyst = ret;
183
184 return 0;
185}
186
170static s16 ADT7410_TEMP_TO_REG(long temp) 187static s16 ADT7410_TEMP_TO_REG(long temp)
171{ 188{
172 return DIV_ROUND_CLOSEST(clamp_val(temp, ADT7410_TEMP_MIN, 189 return DIV_ROUND_CLOSEST(clamp_val(temp, ADT7410_TEMP_MIN,
@@ -193,10 +210,16 @@ static ssize_t adt7410_show_temp(struct device *dev,
193 struct device_attribute *da, char *buf) 210 struct device_attribute *da, char *buf)
194{ 211{
195 struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 212 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
196 struct adt7410_data *data = adt7410_update_device(dev); 213 struct i2c_client *client = to_i2c_client(dev);
214 struct adt7410_data *data = i2c_get_clientdata(client);
197 215
198 if (IS_ERR(data)) 216 if (attr->index == 0) {
199 return PTR_ERR(data); 217 int ret;
218
219 ret = adt7410_update_temp(dev);
220 if (ret)
221 return ret;
222 }
200 223
201 return sprintf(buf, "%d\n", ADT7410_REG_TO_TEMP(data, 224 return sprintf(buf, "%d\n", ADT7410_REG_TO_TEMP(data,
202 data->temp[attr->index])); 225 data->temp[attr->index]));
@@ -232,13 +255,11 @@ static ssize_t adt7410_show_t_hyst(struct device *dev,
232 char *buf) 255 char *buf)
233{ 256{
234 struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 257 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
235 struct adt7410_data *data; 258 struct i2c_client *client = to_i2c_client(dev);
259 struct adt7410_data *data = i2c_get_clientdata(client);
236 int nr = attr->index; 260 int nr = attr->index;
237 int hyst; 261 int hyst;
238 262
239 data = adt7410_update_device(dev);
240 if (IS_ERR(data))
241 return PTR_ERR(data);
242 hyst = (data->hyst & ADT7410_T_HYST_MASK) * 1000; 263 hyst = (data->hyst & ADT7410_T_HYST_MASK) * 1000;
243 264
244 /* 265 /*
@@ -371,6 +392,10 @@ static int adt7410_probe(struct i2c_client *client,
371 } 392 }
372 dev_dbg(&client->dev, "Config %02x\n", data->config); 393 dev_dbg(&client->dev, "Config %02x\n", data->config);
373 394
395 ret = adt7410_fill_cache(client);
396 if (ret)
397 goto exit_restore;
398
374 /* Register sysfs hooks */ 399 /* Register sysfs hooks */
375 ret = sysfs_create_group(&client->dev.kobj, &adt7410_group); 400 ret = sysfs_create_group(&client->dev.kobj, &adt7410_group);
376 if (ret) 401 if (ret)