vserver 2.0 rc7
[linux-2.6.git] / drivers / i2c / chips / smsc47m1.c
index c9f0d2b..0e12ca3 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/module.h>
 #include <linux/slab.h>
 #include <linux/ioport.h>
+#include <linux/jiffies.h>
 #include <linux/i2c.h>
 #include <linux/i2c-sensor.h>
 #include <linux/init.h>
@@ -108,7 +109,6 @@ superio_exit(void)
 struct smsc47m1_data {
        struct i2c_client client;
        struct semaphore lock;
-       int sysctl_id;
 
        struct semaphore update_lock;
        unsigned long last_updated;     /* In jiffies */
@@ -133,8 +133,6 @@ static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
                int init);
 
 
-static int smsc47m1_id;
-
 static struct i2c_driver smsc47m1_driver = {
        .owner          = THIS_MODULE,
        .name           = "smsc47m1",
@@ -197,16 +195,20 @@ static ssize_t set_fan_min(struct device *dev, const char *buf,
 {
        struct i2c_client *client = to_i2c_client(dev);
        struct smsc47m1_data *data = i2c_get_clientdata(client);
+       long rpmdiv, val = simple_strtol(buf, NULL, 10);
 
-       long rpmdiv = simple_strtol(buf, NULL, 10)
-                   * DIV_FROM_REG(data->fan_div[nr]);
+       down(&data->update_lock);
+       rpmdiv = val * DIV_FROM_REG(data->fan_div[nr]);
 
-       if (983040 > 192 * rpmdiv || 2 * rpmdiv > 983040)
+       if (983040 > 192 * rpmdiv || 2 * rpmdiv > 983040) {
+               up(&data->update_lock);
                return -EINVAL;
+       }
 
        data->fan_preload[nr] = 192 - ((983040 + rpmdiv / 2) / rpmdiv);
        smsc47m1_write_value(client, SMSC47M1_REG_FAN_PRELOAD(nr),
                             data->fan_preload[nr]);
+       up(&data->update_lock);
 
        return count;
 }
@@ -226,12 +228,16 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
 
        if (new_div == old_div) /* No change */
                return count;
+
+       down(&data->update_lock);
        switch (new_div) {
        case 1: data->fan_div[nr] = 0; break;
        case 2: data->fan_div[nr] = 1; break;
        case 4: data->fan_div[nr] = 2; break;
        case 8: data->fan_div[nr] = 3; break;
-       default: return -EINVAL;
+       default:
+               up(&data->update_lock);
+               return -EINVAL;
        }
 
        tmp = smsc47m1_read_value(client, SMSC47M1_REG_FANDIV) & 0x0F;
@@ -244,6 +250,7 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
        data->fan_preload[nr] = SENSORS_LIMIT(tmp, 0, 191);
        smsc47m1_write_value(client, SMSC47M1_REG_FAN_PRELOAD(nr),
                             data->fan_preload[nr]);
+       up(&data->update_lock);
 
        return count;
 }
@@ -259,11 +266,13 @@ static ssize_t set_pwm(struct device *dev, const char *buf,
        if (val < 0 || val > 255)
                return -EINVAL;
 
+       down(&data->update_lock);
        data->pwm[nr] &= 0x81; /* Preserve additional bits */
        data->pwm[nr] |= PWM_TO_REG(val);
-
        smsc47m1_write_value(client, SMSC47M1_REG_PWM(nr),
                             data->pwm[nr]);
+       up(&data->update_lock);
+
        return count;
 }
 
@@ -278,11 +287,12 @@ static ssize_t set_pwm_en(struct device *dev, const char *buf,
        if (val != 0 && val != 1)
                return -EINVAL;
 
+       down(&data->update_lock);
        data->pwm[nr] &= 0xFE; /* preserve the other bits */
        data->pwm[nr] |= !val;
-
        smsc47m1_write_value(client, SMSC47M1_REG_PWM(nr),
                             data->pwm[nr]);
+       up(&data->update_lock);
 
        return count;
 }
@@ -420,8 +430,6 @@ static int smsc47m1_detect(struct i2c_adapter *adapter, int address, int kind)
        new_client->flags = 0;
 
        strlcpy(new_client->name, "smsc47m1", I2C_NAME_SIZE);
-
-       new_client->id = smsc47m1_id++;
        init_MUTEX(&data->update_lock);
 
        /* If no function is properly configured, there's no point in
@@ -532,8 +540,7 @@ static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
 
        down(&data->update_lock);
 
-       if ((jiffies - data->last_updated > HZ + HZ / 2) ||
-           (jiffies < data->last_updated) || init) {
+       if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || init) {
                int i;
 
                for (i = 0; i < 2; i++) {