diff options
author | Jean Delvare <khali@linux-fr.org> | 2007-02-14 15:15:03 -0500 |
---|---|---|
committer | Jean Delvare <khali@arrakis.delvare> | 2007-02-14 15:15:03 -0500 |
commit | 7f999aa726ded3fd10d7619945e8b7d7e39833b3 (patch) | |
tree | cb99dfde0b69cf076810eb3c0d46aac54449e5e1 /drivers/hwmon | |
parent | 6a0b1013c61396e588540713c8389038e7d0fead (diff) |
hwmon: Simplify the locking model of two drivers
Many hardware monitoring drivers use two different mutexes, one to
protect their per-device data structure, and one to protect the
access to the device registers. These mutexes are essentially
redundant, as the drivers are transfering values between the device
registers and the data cache, so they almost always end up holding
both mutexes at the same time. Using a single mutex will make the
code more simple and faster.
I am changing only two of the affected drivers here, the authors
of the other affected drivers are welcome to submit similar patches
if they want.
Signed-off-by: Jean Delvare <khali@linux-fr.org>
Diffstat (limited to 'drivers/hwmon')
-rw-r--r-- | drivers/hwmon/f71805f.c | 22 | ||||
-rw-r--r-- | drivers/hwmon/it87.c | 22 |
2 files changed, 11 insertions, 33 deletions
diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c index a272cae8f60e..2fc537819388 100644 --- a/drivers/hwmon/f71805f.c +++ b/drivers/hwmon/f71805f.c | |||
@@ -146,7 +146,6 @@ superio_exit(int base) | |||
146 | struct f71805f_data { | 146 | struct f71805f_data { |
147 | unsigned short addr; | 147 | unsigned short addr; |
148 | const char *name; | 148 | const char *name; |
149 | struct mutex lock; | ||
150 | struct class_device *class_dev; | 149 | struct class_device *class_dev; |
151 | 150 | ||
152 | struct mutex update_lock; | 151 | struct mutex update_lock; |
@@ -271,50 +270,42 @@ static inline u8 temp_to_reg(long val) | |||
271 | * Device I/O access | 270 | * Device I/O access |
272 | */ | 271 | */ |
273 | 272 | ||
273 | /* Must be called with data->update_lock held, except during initialization */ | ||
274 | static u8 f71805f_read8(struct f71805f_data *data, u8 reg) | 274 | static u8 f71805f_read8(struct f71805f_data *data, u8 reg) |
275 | { | 275 | { |
276 | u8 val; | ||
277 | |||
278 | mutex_lock(&data->lock); | ||
279 | outb(reg, data->addr + ADDR_REG_OFFSET); | 276 | outb(reg, data->addr + ADDR_REG_OFFSET); |
280 | val = inb(data->addr + DATA_REG_OFFSET); | 277 | return inb(data->addr + DATA_REG_OFFSET); |
281 | mutex_unlock(&data->lock); | ||
282 | |||
283 | return val; | ||
284 | } | 278 | } |
285 | 279 | ||
280 | /* Must be called with data->update_lock held, except during initialization */ | ||
286 | static void f71805f_write8(struct f71805f_data *data, u8 reg, u8 val) | 281 | static void f71805f_write8(struct f71805f_data *data, u8 reg, u8 val) |
287 | { | 282 | { |
288 | mutex_lock(&data->lock); | ||
289 | outb(reg, data->addr + ADDR_REG_OFFSET); | 283 | outb(reg, data->addr + ADDR_REG_OFFSET); |
290 | outb(val, data->addr + DATA_REG_OFFSET); | 284 | outb(val, data->addr + DATA_REG_OFFSET); |
291 | mutex_unlock(&data->lock); | ||
292 | } | 285 | } |
293 | 286 | ||
294 | /* It is important to read the MSB first, because doing so latches the | 287 | /* It is important to read the MSB first, because doing so latches the |
295 | value of the LSB, so we are sure both bytes belong to the same value. */ | 288 | value of the LSB, so we are sure both bytes belong to the same value. |
289 | Must be called with data->update_lock held, except during initialization */ | ||
296 | static u16 f71805f_read16(struct f71805f_data *data, u8 reg) | 290 | static u16 f71805f_read16(struct f71805f_data *data, u8 reg) |
297 | { | 291 | { |
298 | u16 val; | 292 | u16 val; |
299 | 293 | ||
300 | mutex_lock(&data->lock); | ||
301 | outb(reg, data->addr + ADDR_REG_OFFSET); | 294 | outb(reg, data->addr + ADDR_REG_OFFSET); |
302 | val = inb(data->addr + DATA_REG_OFFSET) << 8; | 295 | val = inb(data->addr + DATA_REG_OFFSET) << 8; |
303 | outb(++reg, data->addr + ADDR_REG_OFFSET); | 296 | outb(++reg, data->addr + ADDR_REG_OFFSET); |
304 | val |= inb(data->addr + DATA_REG_OFFSET); | 297 | val |= inb(data->addr + DATA_REG_OFFSET); |
305 | mutex_unlock(&data->lock); | ||
306 | 298 | ||
307 | return val; | 299 | return val; |
308 | } | 300 | } |
309 | 301 | ||
302 | /* Must be called with data->update_lock held, except during initialization */ | ||
310 | static void f71805f_write16(struct f71805f_data *data, u8 reg, u16 val) | 303 | static void f71805f_write16(struct f71805f_data *data, u8 reg, u16 val) |
311 | { | 304 | { |
312 | mutex_lock(&data->lock); | ||
313 | outb(reg, data->addr + ADDR_REG_OFFSET); | 305 | outb(reg, data->addr + ADDR_REG_OFFSET); |
314 | outb(val >> 8, data->addr + DATA_REG_OFFSET); | 306 | outb(val >> 8, data->addr + DATA_REG_OFFSET); |
315 | outb(++reg, data->addr + ADDR_REG_OFFSET); | 307 | outb(++reg, data->addr + ADDR_REG_OFFSET); |
316 | outb(val & 0xff, data->addr + DATA_REG_OFFSET); | 308 | outb(val & 0xff, data->addr + DATA_REG_OFFSET); |
317 | mutex_unlock(&data->lock); | ||
318 | } | 309 | } |
319 | 310 | ||
320 | static struct f71805f_data *f71805f_update_device(struct device *dev) | 311 | static struct f71805f_data *f71805f_update_device(struct device *dev) |
@@ -1150,7 +1141,6 @@ static int __devinit f71805f_probe(struct platform_device *pdev) | |||
1150 | 1141 | ||
1151 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); | 1142 | res = platform_get_resource(pdev, IORESOURCE_IO, 0); |
1152 | data->addr = res->start; | 1143 | data->addr = res->start; |
1153 | mutex_init(&data->lock); | ||
1154 | data->name = names[sio_data->kind]; | 1144 | data->name = names[sio_data->kind]; |
1155 | mutex_init(&data->update_lock); | 1145 | mutex_init(&data->update_lock); |
1156 | 1146 | ||
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c index bb16668ad2bd..18bb44d18e89 100644 --- a/drivers/hwmon/it87.c +++ b/drivers/hwmon/it87.c | |||
@@ -221,7 +221,6 @@ static const unsigned int pwm_freq[8] = { | |||
221 | struct it87_data { | 221 | struct it87_data { |
222 | struct i2c_client client; | 222 | struct i2c_client client; |
223 | struct class_device *class_dev; | 223 | struct class_device *class_dev; |
224 | struct mutex lock; | ||
225 | enum chips type; | 224 | enum chips type; |
226 | 225 | ||
227 | struct mutex update_lock; | 226 | struct mutex update_lock; |
@@ -548,9 +547,10 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr, | |||
548 | struct i2c_client *client = to_i2c_client(dev); | 547 | struct i2c_client *client = to_i2c_client(dev); |
549 | struct it87_data *data = i2c_get_clientdata(client); | 548 | struct it87_data *data = i2c_get_clientdata(client); |
550 | int val = simple_strtol(buf, NULL, 10); | 549 | int val = simple_strtol(buf, NULL, 10); |
551 | u8 reg = it87_read_value(client, IT87_REG_FAN_DIV); | 550 | u8 reg; |
552 | 551 | ||
553 | mutex_lock(&data->update_lock); | 552 | mutex_lock(&data->update_lock); |
553 | reg = it87_read_value(client, IT87_REG_FAN_DIV); | ||
554 | switch (nr) { | 554 | switch (nr) { |
555 | case 0: data->fan_div[nr] = reg & 0x07; break; | 555 | case 0: data->fan_div[nr] = reg & 0x07; break; |
556 | case 1: data->fan_div[nr] = (reg >> 3) & 0x07; break; | 556 | case 1: data->fan_div[nr] = (reg >> 3) & 0x07; break; |
@@ -949,7 +949,6 @@ static int it87_detect(struct i2c_adapter *adapter) | |||
949 | } | 949 | } |
950 | 950 | ||
951 | new_client = &data->client; | 951 | new_client = &data->client; |
952 | mutex_init(&data->lock); | ||
953 | i2c_set_clientdata(new_client, data); | 952 | i2c_set_clientdata(new_client, data); |
954 | new_client->addr = isa_address; | 953 | new_client->addr = isa_address; |
955 | new_client->adapter = adapter; | 954 | new_client->adapter = adapter; |
@@ -1127,33 +1126,22 @@ static int it87_detach_client(struct i2c_client *client) | |||
1127 | return 0; | 1126 | return 0; |
1128 | } | 1127 | } |
1129 | 1128 | ||
1130 | /* ISA access must be locked explicitly! | 1129 | /* Must be called with data->update_lock held, except during initialization. |
1131 | We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks, | 1130 | We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks, |
1132 | would slow down the IT87 access and should not be necessary. */ | 1131 | would slow down the IT87 access and should not be necessary. */ |
1133 | static int it87_read_value(struct i2c_client *client, u8 reg) | 1132 | static int it87_read_value(struct i2c_client *client, u8 reg) |
1134 | { | 1133 | { |
1135 | struct it87_data *data = i2c_get_clientdata(client); | ||
1136 | int res; | ||
1137 | |||
1138 | mutex_lock(&data->lock); | ||
1139 | outb_p(reg, client->addr + IT87_ADDR_REG_OFFSET); | 1134 | outb_p(reg, client->addr + IT87_ADDR_REG_OFFSET); |
1140 | res = inb_p(client->addr + IT87_DATA_REG_OFFSET); | 1135 | return inb_p(client->addr + IT87_DATA_REG_OFFSET); |
1141 | mutex_unlock(&data->lock); | ||
1142 | |||
1143 | return res; | ||
1144 | } | 1136 | } |
1145 | 1137 | ||
1146 | /* ISA access must be locked explicitly! | 1138 | /* Must be called with data->update_lock held, except during initialization. |
1147 | We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks, | 1139 | We ignore the IT87 BUSY flag at this moment - it could lead to deadlocks, |
1148 | would slow down the IT87 access and should not be necessary. */ | 1140 | would slow down the IT87 access and should not be necessary. */ |
1149 | static void it87_write_value(struct i2c_client *client, u8 reg, u8 value) | 1141 | static void it87_write_value(struct i2c_client *client, u8 reg, u8 value) |
1150 | { | 1142 | { |
1151 | struct it87_data *data = i2c_get_clientdata(client); | ||
1152 | |||
1153 | mutex_lock(&data->lock); | ||
1154 | outb_p(reg, client->addr + IT87_ADDR_REG_OFFSET); | 1143 | outb_p(reg, client->addr + IT87_ADDR_REG_OFFSET); |
1155 | outb_p(value, client->addr + IT87_DATA_REG_OFFSET); | 1144 | outb_p(value, client->addr + IT87_DATA_REG_OFFSET); |
1156 | mutex_unlock(&data->lock); | ||
1157 | } | 1145 | } |
1158 | 1146 | ||
1159 | /* Return 1 if and only if the PWM interface is safe to use */ | 1147 | /* Return 1 if and only if the PWM interface is safe to use */ |