aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/smsc47m1.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon/smsc47m1.c')
-rw-r--r--drivers/hwmon/smsc47m1.c41
1 files changed, 21 insertions, 20 deletions
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c
index d1e3ec0fe4df..7732aec54594 100644
--- a/drivers/hwmon/smsc47m1.c
+++ b/drivers/hwmon/smsc47m1.c
@@ -34,6 +34,7 @@
34#include <linux/hwmon.h> 34#include <linux/hwmon.h>
35#include <linux/err.h> 35#include <linux/err.h>
36#include <linux/init.h> 36#include <linux/init.h>
37#include <linux/mutex.h>
37#include <asm/io.h> 38#include <asm/io.h>
38 39
39/* Address is autodetected, there is no default value */ 40/* Address is autodetected, there is no default value */
@@ -102,9 +103,9 @@ superio_exit(void)
102struct smsc47m1_data { 103struct smsc47m1_data {
103 struct i2c_client client; 104 struct i2c_client client;
104 struct class_device *class_dev; 105 struct class_device *class_dev;
105 struct semaphore lock; 106 struct mutex lock;
106 107
107 struct semaphore update_lock; 108 struct mutex update_lock;
108 unsigned long last_updated; /* In jiffies */ 109 unsigned long last_updated; /* In jiffies */
109 110
110 u8 fan[2]; /* Register value */ 111 u8 fan[2]; /* Register value */
@@ -188,18 +189,18 @@ static ssize_t set_fan_min(struct device *dev, const char *buf,
188 struct smsc47m1_data *data = i2c_get_clientdata(client); 189 struct smsc47m1_data *data = i2c_get_clientdata(client);
189 long rpmdiv, val = simple_strtol(buf, NULL, 10); 190 long rpmdiv, val = simple_strtol(buf, NULL, 10);
190 191
191 down(&data->update_lock); 192 mutex_lock(&data->update_lock);
192 rpmdiv = val * DIV_FROM_REG(data->fan_div[nr]); 193 rpmdiv = val * DIV_FROM_REG(data->fan_div[nr]);
193 194
194 if (983040 > 192 * rpmdiv || 2 * rpmdiv > 983040) { 195 if (983040 > 192 * rpmdiv || 2 * rpmdiv > 983040) {
195 up(&data->update_lock); 196 mutex_unlock(&data->update_lock);
196 return -EINVAL; 197 return -EINVAL;
197 } 198 }
198 199
199 data->fan_preload[nr] = 192 - ((983040 + rpmdiv / 2) / rpmdiv); 200 data->fan_preload[nr] = 192 - ((983040 + rpmdiv / 2) / rpmdiv);
200 smsc47m1_write_value(client, SMSC47M1_REG_FAN_PRELOAD(nr), 201 smsc47m1_write_value(client, SMSC47M1_REG_FAN_PRELOAD(nr),
201 data->fan_preload[nr]); 202 data->fan_preload[nr]);
202 up(&data->update_lock); 203 mutex_unlock(&data->update_lock);
203 204
204 return count; 205 return count;
205} 206}
@@ -220,14 +221,14 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
220 if (new_div == old_div) /* No change */ 221 if (new_div == old_div) /* No change */
221 return count; 222 return count;
222 223
223 down(&data->update_lock); 224 mutex_lock(&data->update_lock);
224 switch (new_div) { 225 switch (new_div) {
225 case 1: data->fan_div[nr] = 0; break; 226 case 1: data->fan_div[nr] = 0; break;
226 case 2: data->fan_div[nr] = 1; break; 227 case 2: data->fan_div[nr] = 1; break;
227 case 4: data->fan_div[nr] = 2; break; 228 case 4: data->fan_div[nr] = 2; break;
228 case 8: data->fan_div[nr] = 3; break; 229 case 8: data->fan_div[nr] = 3; break;
229 default: 230 default:
230 up(&data->update_lock); 231 mutex_unlock(&data->update_lock);
231 return -EINVAL; 232 return -EINVAL;
232 } 233 }
233 234
@@ -241,7 +242,7 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
241 data->fan_preload[nr] = SENSORS_LIMIT(tmp, 0, 191); 242 data->fan_preload[nr] = SENSORS_LIMIT(tmp, 0, 191);
242 smsc47m1_write_value(client, SMSC47M1_REG_FAN_PRELOAD(nr), 243 smsc47m1_write_value(client, SMSC47M1_REG_FAN_PRELOAD(nr),
243 data->fan_preload[nr]); 244 data->fan_preload[nr]);
244 up(&data->update_lock); 245 mutex_unlock(&data->update_lock);
245 246
246 return count; 247 return count;
247} 248}
@@ -257,12 +258,12 @@ static ssize_t set_pwm(struct device *dev, const char *buf,
257 if (val < 0 || val > 255) 258 if (val < 0 || val > 255)
258 return -EINVAL; 259 return -EINVAL;
259 260
260 down(&data->update_lock); 261 mutex_lock(&data->update_lock);
261 data->pwm[nr] &= 0x81; /* Preserve additional bits */ 262 data->pwm[nr] &= 0x81; /* Preserve additional bits */
262 data->pwm[nr] |= PWM_TO_REG(val); 263 data->pwm[nr] |= PWM_TO_REG(val);
263 smsc47m1_write_value(client, SMSC47M1_REG_PWM(nr), 264 smsc47m1_write_value(client, SMSC47M1_REG_PWM(nr),
264 data->pwm[nr]); 265 data->pwm[nr]);
265 up(&data->update_lock); 266 mutex_unlock(&data->update_lock);
266 267
267 return count; 268 return count;
268} 269}
@@ -278,12 +279,12 @@ static ssize_t set_pwm_en(struct device *dev, const char *buf,
278 if (val != 0 && val != 1) 279 if (val != 0 && val != 1)
279 return -EINVAL; 280 return -EINVAL;
280 281
281 down(&data->update_lock); 282 mutex_lock(&data->update_lock);
282 data->pwm[nr] &= 0xFE; /* preserve the other bits */ 283 data->pwm[nr] &= 0xFE; /* preserve the other bits */
283 data->pwm[nr] |= !val; 284 data->pwm[nr] |= !val;
284 smsc47m1_write_value(client, SMSC47M1_REG_PWM(nr), 285 smsc47m1_write_value(client, SMSC47M1_REG_PWM(nr),
285 data->pwm[nr]); 286 data->pwm[nr]);
286 up(&data->update_lock); 287 mutex_unlock(&data->update_lock);
287 288
288 return count; 289 return count;
289} 290}
@@ -408,13 +409,13 @@ static int smsc47m1_detect(struct i2c_adapter *adapter)
408 new_client = &data->client; 409 new_client = &data->client;
409 i2c_set_clientdata(new_client, data); 410 i2c_set_clientdata(new_client, data);
410 new_client->addr = address; 411 new_client->addr = address;
411 init_MUTEX(&data->lock); 412 mutex_init(&data->lock);
412 new_client->adapter = adapter; 413 new_client->adapter = adapter;
413 new_client->driver = &smsc47m1_driver; 414 new_client->driver = &smsc47m1_driver;
414 new_client->flags = 0; 415 new_client->flags = 0;
415 416
416 strlcpy(new_client->name, "smsc47m1", I2C_NAME_SIZE); 417 strlcpy(new_client->name, "smsc47m1", I2C_NAME_SIZE);
417 init_MUTEX(&data->update_lock); 418 mutex_init(&data->update_lock);
418 419
419 /* If no function is properly configured, there's no point in 420 /* If no function is properly configured, there's no point in
420 actually registering the chip. */ 421 actually registering the chip. */
@@ -512,17 +513,17 @@ static int smsc47m1_read_value(struct i2c_client *client, u8 reg)
512{ 513{
513 int res; 514 int res;
514 515
515 down(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock); 516 mutex_lock(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
516 res = inb_p(client->addr + reg); 517 res = inb_p(client->addr + reg);
517 up(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock); 518 mutex_unlock(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
518 return res; 519 return res;
519} 520}
520 521
521static void smsc47m1_write_value(struct i2c_client *client, u8 reg, u8 value) 522static void smsc47m1_write_value(struct i2c_client *client, u8 reg, u8 value)
522{ 523{
523 down(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock); 524 mutex_lock(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
524 outb_p(value, client->addr + reg); 525 outb_p(value, client->addr + reg);
525 up(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock); 526 mutex_unlock(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
526} 527}
527 528
528static struct smsc47m1_data *smsc47m1_update_device(struct device *dev, 529static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
@@ -531,7 +532,7 @@ static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
531 struct i2c_client *client = to_i2c_client(dev); 532 struct i2c_client *client = to_i2c_client(dev);
532 struct smsc47m1_data *data = i2c_get_clientdata(client); 533 struct smsc47m1_data *data = i2c_get_clientdata(client);
533 534
534 down(&data->update_lock); 535 mutex_lock(&data->update_lock);
535 536
536 if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || init) { 537 if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || init) {
537 int i; 538 int i;
@@ -558,7 +559,7 @@ static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
558 data->last_updated = jiffies; 559 data->last_updated = jiffies;
559 } 560 }
560 561
561 up(&data->update_lock); 562 mutex_unlock(&data->update_lock);
562 return data; 563 return data;
563} 564}
564 565