Skip to content

Commit c55dc91

Browse files
larsclausengroeck
authored andcommitted
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>
1 parent f40fb63 commit c55dc91

File tree

1 file changed

+58
-33
lines changed

1 file changed

+58
-33
lines changed

drivers/hwmon/adt7410.c

Lines changed: 58 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -119,45 +119,33 @@ static int adt7410_temp_ready(struct i2c_client *client)
119119
return -ETIMEDOUT;
120120
}
121121

122-
static struct adt7410_data *adt7410_update_device(struct device *dev)
122+
static int adt7410_update_temp(struct device *dev)
123123
{
124124
struct i2c_client *client = to_i2c_client(dev);
125125
struct adt7410_data *data = i2c_get_clientdata(client);
126-
struct adt7410_data *ret = data;
126+
int ret = 0;
127+
127128
mutex_lock(&data->update_lock);
128129

129130
if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
130131
|| !data->valid) {
131-
int i, status;
132+
int temp;
132133

133134
dev_dbg(&client->dev, "Starting update\n");
134135

135-
status = adt7410_temp_ready(client); /* check for new value */
136-
if (unlikely(status)) {
137-
ret = ERR_PTR(status);
136+
ret = adt7410_temp_ready(client); /* check for new value */
137+
if (ret)
138138
goto abort;
139-
}
140-
for (i = 0; i < ARRAY_SIZE(data->temp); i++) {
141-
status = i2c_smbus_read_word_swapped(client,
142-
ADT7410_REG_TEMP[i]);
143-
if (unlikely(status < 0)) {
144-
dev_dbg(dev,
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);
139+
140+
temp = i2c_smbus_read_word_swapped(client, ADT7410_REG_TEMP[0]);
141+
if (temp < 0) {
142+
ret = temp;
143+
dev_dbg(dev, "Failed to read value: reg %d, error %d\n",
144+
ADT7410_REG_TEMP[0], ret);
158145
goto abort;
159146
}
160-
data->hyst = status;
147+
data->temp[0] = temp;
148+
161149
data->last_updated = jiffies;
162150
data->valid = true;
163151
}
@@ -167,6 +155,35 @@ static struct adt7410_data *adt7410_update_device(struct device *dev)
167155
return ret;
168156
}
169157

158+
static 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+
170187
static s16 ADT7410_TEMP_TO_REG(long temp)
171188
{
172189
return DIV_ROUND_CLOSEST(clamp_val(temp, ADT7410_TEMP_MIN,
@@ -193,10 +210,16 @@ static ssize_t adt7410_show_temp(struct device *dev,
193210
struct device_attribute *da, char *buf)
194211
{
195212
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);
197215

198-
if (IS_ERR(data))
199-
return PTR_ERR(data);
216+
if (attr->index == 0) {
217+
int ret;
218+
219+
ret = adt7410_update_temp(dev);
220+
if (ret)
221+
return ret;
222+
}
200223

201224
return sprintf(buf, "%d\n", ADT7410_REG_TO_TEMP(data,
202225
data->temp[attr->index]));
@@ -232,13 +255,11 @@ static ssize_t adt7410_show_t_hyst(struct device *dev,
232255
char *buf)
233256
{
234257
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);
236260
int nr = attr->index;
237261
int hyst;
238262

239-
data = adt7410_update_device(dev);
240-
if (IS_ERR(data))
241-
return PTR_ERR(data);
242263
hyst = (data->hyst & ADT7410_T_HYST_MASK) * 1000;
243264

244265
/*
@@ -371,6 +392,10 @@ static int adt7410_probe(struct i2c_client *client,
371392
}
372393
dev_dbg(&client->dev, "Config %02x\n", data->config);
373394

395+
ret = adt7410_fill_cache(client);
396+
if (ret)
397+
goto exit_restore;
398+
374399
/* Register sysfs hooks */
375400
ret = sysfs_create_group(&client->dev.kobj, &adt7410_group);
376401
if (ret)

0 commit comments

Comments
 (0)