Merge master.kernel.org:/pub/scm/linux/kernel/git/gregkh/i2c-2.6

* master.kernel.org:/pub/scm/linux/kernel/git/gregkh/i2c-2.6: (36 commits)
  [PATCH] hwmon: add required idr locking
  [PATCH] I2C: hwmon: Rename register parameters
  [PATCH] I2C: Drop unneeded i2c-dev.h includes
  [PATCH] I2C: i2c-ixp4xx: Add hwmon class
  [PATCH] I2C: i2c-piix4: Add Broadcom HT-1000 support
  [PATCH] I2C: i2c-amd756-s4882: Improve static mutex initialization
  [PATCH] I2C: i2c-ali1535: Drop redundant mutex
  [PATCH] i2c: Cleanup isp1301_omap
  [PATCH] i2c: Fix i2c-ite name initialization
  [PATCH] i2c: Drop the i2c-frodo bus driver
  [PATCH] i2c: Optimize core_lists mutex usage
  [PATCH] w83781d: Don't reset the chip by default
  [PATCH] w83781d: Document the alarm and beep bits
  [PATCH] w83627ehf: Refactor the sysfs interface
  [PATCH] hwmon: Support the Pentium M VID code
  [PATCH] hwmon: Add support for the Winbond W83687THF
  [PATCH] hwmon: f71805f semaphore to mutex conversions
  [PATCH] hwmon: Semaphore to mutex conversions
  [PATCH] i2c: Semaphore to mutex conversions, part 3
  [PATCH] i2c: Semaphore to mutex conversions, part 2
  ...
This commit is contained in:
Linus Torvalds 2006-03-23 15:51:32 -08:00
commit b6585dedac
81 changed files with 1697 additions and 1777 deletions

View File

@ -18,6 +18,10 @@ Supported chips:
Prefix: 'w83637hf'
Addresses scanned: ISA address retrieved from Super I/O registers
Datasheet: http://www.winbond.com/PDF/sheet/w83637hf.pdf
* Winbond W83687THF
Prefix: 'w83687thf'
Addresses scanned: ISA address retrieved from Super I/O registers
Datasheet: Provided by Winbond on request
Authors:
Frodo Looijaard <frodol@dds.nl>,

View File

@ -36,6 +36,11 @@ Module parameters
Use 'init=0' to bypass initializing the chip.
Try this if your computer crashes when you load the module.
* reset int
(default 0)
The driver used to reset the chip on load, but does no more. Use
'reset=1' to restore the old behavior. Report if you need to do this.
force_subclients=bus,caddr,saddr,saddr
This is used to force the i2c addresses for subclients of
a certain chip. Typical usage is `force_subclients=0,0x2d,0x4a,0x4b'
@ -123,6 +128,25 @@ When an alarm goes off, you can be warned by a beeping signal through
your computer speaker. It is possible to enable all beeping globally,
or only the beeping for some alarms.
Individual alarm and beep bits:
0x000001: in0
0x000002: in1
0x000004: in2
0x000008: in3
0x000010: temp1
0x000020: temp2 (+temp3 on W83781D)
0x000040: fan1
0x000080: fan2
0x000100: in4
0x000200: in5
0x000400: in6
0x000800: fan3
0x001000: chassis
0x002000: temp3 (W83782D and W83627HF only)
0x010000: in7 (W83782D and W83627HF only)
0x020000: in8 (W83782D and W83627HF only)
If an alarm triggers, it will remain triggered until the hardware register
is read at least once. This means that the cause for the alarm may
already have disappeared! Note that in the current implementation, all

View File

@ -4,7 +4,7 @@ Supported adapters:
* Intel 82371AB PIIX4 and PIIX4E
* Intel 82443MX (440MX)
Datasheet: Publicly available at the Intel website
* ServerWorks OSB4, CSB5 and CSB6 southbridges
* ServerWorks OSB4, CSB5, CSB6 and HT-1000 southbridges
Datasheet: Only available via NDA from ServerWorks
* Standard Microsystems (SMSC) SLC90E66 (Victory66) southbridge
Datasheet: Publicly available at the SMSC website http://www.smsc.com

View File

@ -6,9 +6,10 @@ Module Parameters
-----------------
* base: int
Base addresses for the ACCESS.bus controllers
Base addresses for the ACCESS.bus controllers on SCx200 and SC1100 devices
Description
-----------
Enable the use of the ACCESS.bus controllers of a SCx200 processor.
Enable the use of the ACCESS.bus controller on the Geode SCx200 and
SC1100 processors and the CS5535 and CS5536 Geode companion devices.

View File

@ -406,13 +406,14 @@ config SENSORS_W83L785TS
will be called w83l785ts.
config SENSORS_W83627HF
tristate "Winbond W83627HF, W83627THF, W83637HF, W83697HF"
depends on HWMON && I2C && EXPERIMENTAL
tristate "Winbond W83627HF, W83627THF, W83637HF, W83687THF, W83697HF"
depends on HWMON && I2C
select I2C_ISA
select HWMON_VID
help
If you say yes here you get support for the Winbond W836X7 series
of sensor chips: the W83627HF, W83627THF, W83637HF, and the W83697HF
of sensor chips: the W83627HF, W83627THF, W83637HF, W83687THF and
W83697HF.
This driver can also be built as a module. If so, the module
will be called w83627hf.

View File

@ -26,6 +26,7 @@
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/err.h>
#include <linux/mutex.h>
/* Addresses to scan */
@ -92,7 +93,7 @@ struct adm1021_data {
struct class_device *class_dev;
enum chips type;
struct semaphore update_lock;
struct mutex update_lock;
char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */
@ -162,10 +163,10 @@ static ssize_t set_##value(struct device *dev, struct device_attribute *attr, co
struct adm1021_data *data = i2c_get_clientdata(client); \
int temp = simple_strtoul(buf, NULL, 10); \
\
down(&data->update_lock); \
mutex_lock(&data->update_lock); \
data->value = TEMP_TO_REG(temp); \
adm1021_write_value(client, reg, data->value); \
up(&data->update_lock); \
mutex_unlock(&data->update_lock); \
return count; \
}
set(temp_max, ADM1021_REG_TOS_W);
@ -275,7 +276,7 @@ static int adm1021_detect(struct i2c_adapter *adapter, int address, int kind)
strlcpy(new_client->name, type_name, I2C_NAME_SIZE);
data->type = kind;
data->valid = 0;
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
@ -351,7 +352,7 @@ static struct adm1021_data *adm1021_update_device(struct device *dev)
struct i2c_client *client = to_i2c_client(dev);
struct adm1021_data *data = i2c_get_clientdata(client);
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
|| !data->valid) {
@ -375,7 +376,7 @@ static struct adm1021_data *adm1021_update_device(struct device *dev)
data->valid = 1;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return data;
}

View File

@ -53,6 +53,7 @@
#include <linux/hwmon.h>
#include <linux/hwmon-vid.h>
#include <linux/err.h>
#include <linux/mutex.h>
/*
* Addresses to scan
@ -133,7 +134,7 @@ static struct i2c_driver adm1025_driver = {
struct adm1025_data {
struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock;
struct mutex update_lock;
char valid; /* zero until following fields are valid */
unsigned long last_updated; /* in jiffies */
@ -207,11 +208,11 @@ static ssize_t set_in##offset##_min(struct device *dev, struct device_attribute
struct adm1025_data *data = i2c_get_clientdata(client); \
long val = simple_strtol(buf, NULL, 10); \
\
down(&data->update_lock); \
mutex_lock(&data->update_lock); \
data->in_min[offset] = IN_TO_REG(val, in_scale[offset]); \
i2c_smbus_write_byte_data(client, ADM1025_REG_IN_MIN(offset), \
data->in_min[offset]); \
up(&data->update_lock); \
mutex_unlock(&data->update_lock); \
return count; \
} \
static ssize_t set_in##offset##_max(struct device *dev, struct device_attribute *attr, const char *buf, \
@ -221,11 +222,11 @@ static ssize_t set_in##offset##_max(struct device *dev, struct device_attribute
struct adm1025_data *data = i2c_get_clientdata(client); \
long val = simple_strtol(buf, NULL, 10); \
\
down(&data->update_lock); \
mutex_lock(&data->update_lock); \
data->in_max[offset] = IN_TO_REG(val, in_scale[offset]); \
i2c_smbus_write_byte_data(client, ADM1025_REG_IN_MAX(offset), \
data->in_max[offset]); \
up(&data->update_lock); \
mutex_unlock(&data->update_lock); \
return count; \
} \
static DEVICE_ATTR(in##offset##_min, S_IWUSR | S_IRUGO, \
@ -247,11 +248,11 @@ static ssize_t set_temp##offset##_min(struct device *dev, struct device_attribut
struct adm1025_data *data = i2c_get_clientdata(client); \
long val = simple_strtol(buf, NULL, 10); \
\
down(&data->update_lock); \
mutex_lock(&data->update_lock); \
data->temp_min[offset-1] = TEMP_TO_REG(val); \
i2c_smbus_write_byte_data(client, ADM1025_REG_TEMP_LOW(offset-1), \
data->temp_min[offset-1]); \
up(&data->update_lock); \
mutex_unlock(&data->update_lock); \
return count; \
} \
static ssize_t set_temp##offset##_max(struct device *dev, struct device_attribute *attr, const char *buf, \
@ -261,11 +262,11 @@ static ssize_t set_temp##offset##_max(struct device *dev, struct device_attribut
struct adm1025_data *data = i2c_get_clientdata(client); \
long val = simple_strtol(buf, NULL, 10); \
\
down(&data->update_lock); \
mutex_lock(&data->update_lock); \
data->temp_max[offset-1] = TEMP_TO_REG(val); \
i2c_smbus_write_byte_data(client, ADM1025_REG_TEMP_HIGH(offset-1), \
data->temp_max[offset-1]); \
up(&data->update_lock); \
mutex_unlock(&data->update_lock); \
return count; \
} \
static DEVICE_ATTR(temp##offset##_min, S_IWUSR | S_IRUGO, \
@ -404,7 +405,7 @@ static int adm1025_detect(struct i2c_adapter *adapter, int address, int kind)
/* We can fill in the remaining client fields */
strlcpy(new_client->name, name, I2C_NAME_SIZE);
data->valid = 0;
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
@ -523,7 +524,7 @@ static struct adm1025_data *adm1025_update_device(struct device *dev)
struct i2c_client *client = to_i2c_client(dev);
struct adm1025_data *data = i2c_get_clientdata(client);
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) {
int i;
@ -558,7 +559,7 @@ static struct adm1025_data *adm1025_update_device(struct device *dev)
data->valid = 1;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return data;
}

View File

@ -32,6 +32,7 @@
#include <linux/hwmon-sysfs.h>
#include <linux/hwmon-vid.h>
#include <linux/err.h>
#include <linux/mutex.h>
/* Addresses to scan */
static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
@ -260,10 +261,10 @@ struct pwm_data {
struct adm1026_data {
struct i2c_client client;
struct class_device *class_dev;
struct semaphore lock;
struct mutex lock;
enum chips type;
struct semaphore update_lock;
struct mutex update_lock;
int valid; /* !=0 if following fields are valid */
unsigned long last_reading; /* In jiffies */
unsigned long last_config; /* In jiffies */
@ -298,9 +299,8 @@ static int adm1026_attach_adapter(struct i2c_adapter *adapter);
static int adm1026_detect(struct i2c_adapter *adapter, int address,
int kind);
static int adm1026_detach_client(struct i2c_client *client);
static int adm1026_read_value(struct i2c_client *client, u8 register);
static int adm1026_write_value(struct i2c_client *client, u8 register,
int value);
static int adm1026_read_value(struct i2c_client *client, u8 reg);
static int adm1026_write_value(struct i2c_client *client, u8 reg, int value);
static void adm1026_print_gpio(struct i2c_client *client);
static void adm1026_fixup_gpio(struct i2c_client *client);
static struct adm1026_data *adm1026_update_device(struct device *dev);
@ -575,7 +575,7 @@ static struct adm1026_data *adm1026_update_device(struct device *dev)
int i;
long value, alarms, gpio;
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (!data->valid
|| time_after(jiffies, data->last_reading + ADM1026_DATA_INTERVAL)) {
/* Things that change quickly */
@ -710,7 +710,7 @@ static struct adm1026_data *adm1026_update_device(struct device *dev)
dev_dbg(&client->dev, "Setting VID from GPIO11-15.\n");
data->vid = (data->gpio >> 11) & 0x1f;
data->valid = 1;
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return data;
}
@ -739,10 +739,10 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
struct adm1026_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->in_min[nr] = INS_TO_REG(nr, val);
adm1026_write_value(client, ADM1026_REG_IN_MIN[nr], data->in_min[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t show_in_max(struct device *dev, struct device_attribute *attr,
@ -762,10 +762,10 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
struct adm1026_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->in_max[nr] = INS_TO_REG(nr, val);
adm1026_write_value(client, ADM1026_REG_IN_MAX[nr], data->in_max[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -813,10 +813,10 @@ static ssize_t set_in16_min(struct device *dev, struct device_attribute *attr, c
struct adm1026_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->in_min[16] = INS_TO_REG(16, val + NEG12_OFFSET);
adm1026_write_value(client, ADM1026_REG_IN_MIN[16], data->in_min[16]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t show_in16_max(struct device *dev, struct device_attribute *attr, char *buf)
@ -831,10 +831,10 @@ static ssize_t set_in16_max(struct device *dev, struct device_attribute *attr, c
struct adm1026_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->in_max[16] = INS_TO_REG(16, val+NEG12_OFFSET);
adm1026_write_value(client, ADM1026_REG_IN_MAX[16], data->in_max[16]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -874,11 +874,11 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
struct adm1026_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->fan_min[nr] = FAN_TO_REG(val, data->fan_div[nr]);
adm1026_write_value(client, ADM1026_REG_FAN_MIN(nr),
data->fan_min[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -939,7 +939,7 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
if (new_div == 0) {
return -EINVAL;
}
down(&data->update_lock);
mutex_lock(&data->update_lock);
orig_div = data->fan_div[nr];
data->fan_div[nr] = DIV_FROM_REG(new_div);
@ -958,7 +958,7 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
if (data->fan_div[nr] != orig_div) {
fixup_fan_min(dev,nr,orig_div);
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -1001,11 +1001,11 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
struct adm1026_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp_min[nr] = TEMP_TO_REG(val);
adm1026_write_value(client, ADM1026_REG_TEMP_MIN[nr],
data->temp_min[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t show_temp_max(struct device *dev, struct device_attribute *attr,
@ -1025,11 +1025,11 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
struct adm1026_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp_max[nr] = TEMP_TO_REG(val);
adm1026_write_value(client, ADM1026_REG_TEMP_MAX[nr],
data->temp_max[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -1064,11 +1064,11 @@ static ssize_t set_temp_offset(struct device *dev,
struct adm1026_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp_offset[nr] = TEMP_TO_REG(val);
adm1026_write_value(client, ADM1026_REG_TEMP_OFFSET[nr],
data->temp_offset[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -1115,11 +1115,11 @@ static ssize_t set_temp_auto_point1_temp(struct device *dev,
struct adm1026_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp_tmin[nr] = TEMP_TO_REG(val);
adm1026_write_value(client, ADM1026_REG_TEMP_TMIN[nr],
data->temp_tmin[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -1150,11 +1150,11 @@ static ssize_t set_temp_crit_enable(struct device *dev,
int val = simple_strtol(buf, NULL, 10);
if ((val == 1) || (val==0)) {
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->config1 = (data->config1 & ~CFG1_THERM_HOT) | (val << 4);
adm1026_write_value(client, ADM1026_REG_CONFIG1,
data->config1);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
}
return count;
}
@ -1184,11 +1184,11 @@ static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr,
struct adm1026_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp_crit[nr] = TEMP_TO_REG(val);
adm1026_write_value(client, ADM1026_REG_TEMP_THERM[nr],
data->temp_crit[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -1212,10 +1212,10 @@ static ssize_t set_analog_out_reg(struct device *dev, struct device_attribute *a
struct adm1026_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->analog_out = DAC_TO_REG(val);
adm1026_write_value(client, ADM1026_REG_DAC, data->analog_out);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -1267,7 +1267,7 @@ static ssize_t set_alarm_mask(struct device *dev, struct device_attribute *attr,
int val = simple_strtol(buf, NULL, 10);
unsigned long mask;
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->alarm_mask = val & 0x7fffffff;
mask = data->alarm_mask
| (data->gpio_mask & 0x10000 ? 0x80000000 : 0);
@ -1282,7 +1282,7 @@ static ssize_t set_alarm_mask(struct device *dev, struct device_attribute *attr,
mask >>= 8;
adm1026_write_value(client, ADM1026_REG_MASK4,
mask & 0xff);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -1303,7 +1303,7 @@ static ssize_t set_gpio(struct device *dev, struct device_attribute *attr, const
int val = simple_strtol(buf, NULL, 10);
long gpio;
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->gpio = val & 0x1ffff;
gpio = data->gpio;
adm1026_write_value(client, ADM1026_REG_GPIO_STATUS_0_7,gpio & 0xff);
@ -1311,7 +1311,7 @@ static ssize_t set_gpio(struct device *dev, struct device_attribute *attr, const
adm1026_write_value(client, ADM1026_REG_GPIO_STATUS_8_15,gpio & 0xff);
gpio = ((gpio >> 1) & 0x80) | (data->alarms >> 24 & 0x7f);
adm1026_write_value(client, ADM1026_REG_STATUS4,gpio & 0xff);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -1331,7 +1331,7 @@ static ssize_t set_gpio_mask(struct device *dev, struct device_attribute *attr,
int val = simple_strtol(buf, NULL, 10);
long mask;
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->gpio_mask = val & 0x1ffff;
mask = data->gpio_mask;
adm1026_write_value(client, ADM1026_REG_GPIO_MASK_0_7,mask & 0xff);
@ -1339,7 +1339,7 @@ static ssize_t set_gpio_mask(struct device *dev, struct device_attribute *attr,
adm1026_write_value(client, ADM1026_REG_GPIO_MASK_8_15,mask & 0xff);
mask = ((mask >> 1) & 0x80) | (data->alarm_mask >> 24 & 0x7f);
adm1026_write_value(client, ADM1026_REG_MASK1,mask & 0xff);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -1359,10 +1359,10 @@ static ssize_t set_pwm_reg(struct device *dev, struct device_attribute *attr, co
if (data->pwm1.enable == 1) {
int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->pwm1.pwm = PWM_TO_REG(val);
adm1026_write_value(client, ADM1026_REG_PWM, data->pwm1.pwm);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
}
return count;
}
@ -1378,14 +1378,14 @@ static ssize_t set_auto_pwm_min(struct device *dev, struct device_attribute *att
struct adm1026_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->pwm1.auto_pwm_min = SENSORS_LIMIT(val,0,255);
if (data->pwm1.enable == 2) { /* apply immediately */
data->pwm1.pwm = PWM_TO_REG((data->pwm1.pwm & 0x0f) |
PWM_MIN_TO_REG(data->pwm1.auto_pwm_min));
adm1026_write_value(client, ADM1026_REG_PWM, data->pwm1.pwm);
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t show_auto_pwm_max(struct device *dev, struct device_attribute *attr, char *buf)
@ -1406,7 +1406,7 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr,
int old_enable;
if ((val >= 0) && (val < 3)) {
down(&data->update_lock);
mutex_lock(&data->update_lock);
old_enable = data->pwm1.enable;
data->pwm1.enable = val;
data->config1 = (data->config1 & ~CFG1_PWM_AFC)
@ -1424,7 +1424,7 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr,
adm1026_write_value(client, ADM1026_REG_PWM,
data->pwm1.pwm);
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
}
return count;
}
@ -1541,7 +1541,7 @@ static int adm1026_detect(struct i2c_adapter *adapter, int address,
/* Fill in the remaining client fields */
data->type = kind;
data->valid = 0;
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))

View File

@ -28,6 +28,7 @@
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/err.h>
#include <linux/mutex.h>
/* Following macros takes channel parameter starting from 0 to 2 */
#define ADM1031_REG_FAN_SPEED(nr) (0x08 + (nr))
@ -70,7 +71,7 @@ typedef u8 auto_chan_table_t[8][2];
struct adm1031_data {
struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock;
struct mutex update_lock;
int chip_type;
char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */
@ -262,10 +263,10 @@ set_fan_auto_channel(struct device *dev, const char *buf, size_t count, int nr)
old_fan_mode = data->conf1;
down(&data->update_lock);
mutex_lock(&data->update_lock);
if ((ret = get_fan_auto_nearest(data, nr, val, data->conf1, &reg))) {
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return ret;
}
if (((data->conf1 = FAN_CHAN_TO_REG(reg, data->conf1)) & ADM1031_CONF1_AUTO_MODE) ^
@ -288,7 +289,7 @@ set_fan_auto_channel(struct device *dev, const char *buf, size_t count, int nr)
}
data->conf1 = FAN_CHAN_TO_REG(reg, data->conf1);
adm1031_write_value(client, ADM1031_REG_CONF1, data->conf1);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -329,11 +330,11 @@ set_auto_temp_min(struct device *dev, const char *buf, size_t count, int nr)
struct adm1031_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->auto_temp[nr] = AUTO_TEMP_MIN_TO_REG(val, data->auto_temp[nr]);
adm1031_write_value(client, ADM1031_REG_AUTO_TEMP(nr),
data->auto_temp[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t show_auto_temp_max(struct device *dev, char *buf, int nr)
@ -349,11 +350,11 @@ set_auto_temp_max(struct device *dev, const char *buf, size_t count, int nr)
struct adm1031_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp_max[nr] = AUTO_TEMP_MAX_TO_REG(val, data->auto_temp[nr], data->pwm[nr]);
adm1031_write_value(client, ADM1031_REG_AUTO_TEMP(nr),
data->temp_max[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -405,11 +406,11 @@ set_pwm(struct device *dev, const char *buf, size_t count, int nr)
int val = simple_strtol(buf, NULL, 10);
int reg;
down(&data->update_lock);
mutex_lock(&data->update_lock);
if ((data->conf1 & ADM1031_CONF1_AUTO_MODE) &&
(((val>>4) & 0xf) != 5)) {
/* In automatic mode, the only PWM accepted is 33% */
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return -EINVAL;
}
data->pwm[nr] = PWM_TO_REG(val);
@ -417,7 +418,7 @@ set_pwm(struct device *dev, const char *buf, size_t count, int nr)
adm1031_write_value(client, ADM1031_REG_PWM,
nr ? ((data->pwm[nr] << 4) & 0xf0) | (reg & 0xf)
: (data->pwm[nr] & 0xf) | (reg & 0xf0));
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -511,7 +512,7 @@ set_fan_min(struct device *dev, const char *buf, size_t count, int nr)
struct adm1031_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (val) {
data->fan_min[nr] =
FAN_TO_REG(val, FAN_DIV_FROM_REG(data->fan_div[nr]));
@ -519,7 +520,7 @@ set_fan_min(struct device *dev, const char *buf, size_t count, int nr)
data->fan_min[nr] = 0xff;
}
adm1031_write_value(client, ADM1031_REG_FAN_MIN(nr), data->fan_min[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t
@ -540,7 +541,7 @@ set_fan_div(struct device *dev, const char *buf, size_t count, int nr)
if (tmp == 0xff)
return -EINVAL;
down(&data->update_lock);
mutex_lock(&data->update_lock);
old_div = FAN_DIV_FROM_REG(data->fan_div[nr]);
data->fan_div[nr] = (tmp & 0xC0) | (0x3f & data->fan_div[nr]);
new_min = data->fan_min[nr] * old_div /
@ -553,7 +554,7 @@ set_fan_div(struct device *dev, const char *buf, size_t count, int nr)
data->fan_div[nr]);
adm1031_write_value(client, ADM1031_REG_FAN_MIN(nr),
data->fan_min[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -627,11 +628,11 @@ set_temp_min(struct device *dev, const char *buf, size_t count, int nr)
val = simple_strtol(buf, NULL, 10);
val = SENSORS_LIMIT(val, -55000, nr == 0 ? 127750 : 127875);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp_min[nr] = TEMP_TO_REG(val);
adm1031_write_value(client, ADM1031_REG_TEMP_MIN(nr),
data->temp_min[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t
@ -643,11 +644,11 @@ set_temp_max(struct device *dev, const char *buf, size_t count, int nr)
val = simple_strtol(buf, NULL, 10);
val = SENSORS_LIMIT(val, -55000, nr == 0 ? 127750 : 127875);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp_max[nr] = TEMP_TO_REG(val);
adm1031_write_value(client, ADM1031_REG_TEMP_MAX(nr),
data->temp_max[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t
@ -659,11 +660,11 @@ set_temp_crit(struct device *dev, const char *buf, size_t count, int nr)
val = simple_strtol(buf, NULL, 10);
val = SENSORS_LIMIT(val, -55000, nr == 0 ? 127750 : 127875);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp_crit[nr] = TEMP_TO_REG(val);
adm1031_write_value(client, ADM1031_REG_TEMP_CRIT(nr),
data->temp_crit[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -778,7 +779,7 @@ static int adm1031_detect(struct i2c_adapter *adapter, int address, int kind)
strlcpy(new_client->name, name, I2C_NAME_SIZE);
data->valid = 0;
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
@ -891,7 +892,7 @@ static struct adm1031_data *adm1031_update_device(struct device *dev)
struct adm1031_data *data = i2c_get_clientdata(client);
int chan;
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
|| !data->valid) {
@ -965,7 +966,7 @@ static struct adm1031_data *adm1031_update_device(struct device *dev)
data->valid = 1;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return data;
}

View File

@ -49,6 +49,7 @@
#include <linux/hwmon.h>
#include <linux/hwmon-vid.h>
#include <linux/err.h>
#include <linux/mutex.h>
/* Addresses to scan */
static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f,
@ -150,7 +151,7 @@ struct adm9240_data {
enum chips type;
struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock;
struct mutex update_lock;
char valid;
unsigned long last_updated_measure;
unsigned long last_updated_config;
@ -195,11 +196,11 @@ static ssize_t set_max(struct device *dev, struct device_attribute *devattr,
struct adm9240_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp_max[attr->index] = TEMP_TO_REG(val);
i2c_smbus_write_byte_data(client, ADM9240_REG_TEMP_MAX(attr->index),
data->temp_max[attr->index]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -246,11 +247,11 @@ static ssize_t set_in_min(struct device *dev,
struct adm9240_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->in_min[attr->index] = IN_TO_REG(val, attr->index);
i2c_smbus_write_byte_data(client, ADM9240_REG_IN_MIN(attr->index),
data->in_min[attr->index]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -263,11 +264,11 @@ static ssize_t set_in_max(struct device *dev,
struct adm9240_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->in_max[attr->index] = IN_TO_REG(val, attr->index);
i2c_smbus_write_byte_data(client, ADM9240_REG_IN_MAX(attr->index),
data->in_max[attr->index]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -350,7 +351,7 @@ static ssize_t set_fan_min(struct device *dev,
int nr = attr->index;
u8 new_div;
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (!val) {
data->fan_min[nr] = 255;
@ -390,7 +391,7 @@ static ssize_t set_fan_min(struct device *dev,
i2c_smbus_write_byte_data(client, ADM9240_REG_FAN_MIN(nr),
data->fan_min[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -439,10 +440,10 @@ static ssize_t set_aout(struct device *dev,
struct adm9240_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->aout = AOUT_TO_REG(val);
i2c_smbus_write_byte_data(client, ADM9240_REG_ANALOG_OUT, data->aout);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
static DEVICE_ATTR(aout_output, S_IRUGO | S_IWUSR, show_aout, set_aout);
@ -539,7 +540,7 @@ static int adm9240_detect(struct i2c_adapter *adapter, int address, int kind)
/* fill in the remaining client fields and attach */
strlcpy(new_client->name, name, I2C_NAME_SIZE);
data->type = kind;
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
if ((err = i2c_attach_client(new_client)))
goto exit_free;
@ -691,7 +692,7 @@ static struct adm9240_data *adm9240_update_device(struct device *dev)
struct adm9240_data *data = i2c_get_clientdata(client);
int i;
down(&data->update_lock);
mutex_lock(&data->update_lock);
/* minimum measurement cycle: 1.75 seconds */
if (time_after(jiffies, data->last_updated_measure + (HZ * 7 / 4))
@ -771,7 +772,7 @@ static struct adm9240_data *adm9240_update_device(struct device *dev)
data->last_updated_config = jiffies;
data->valid = 1;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return data;
}

View File

@ -44,6 +44,7 @@
#include <linux/err.h>
#include <linux/init.h>
#include <linux/jiffies.h>
#include <linux/mutex.h>
#include "lm75.h"
/*
@ -182,10 +183,10 @@ static u8 DIV_TO_REG(long val)
struct asb100_data {
struct i2c_client client;
struct class_device *class_dev;
struct semaphore lock;
struct mutex lock;
enum chips type;
struct semaphore update_lock;
struct mutex update_lock;
unsigned long last_updated; /* In jiffies */
/* array of 2 pointers to subclients */
@ -245,11 +246,11 @@ static ssize_t set_in_##reg(struct device *dev, const char *buf, \
struct asb100_data *data = i2c_get_clientdata(client); \
unsigned long val = simple_strtoul(buf, NULL, 10); \
\
down(&data->update_lock); \
mutex_lock(&data->update_lock); \
data->in_##reg[nr] = IN_TO_REG(val); \
asb100_write_value(client, ASB100_REG_IN_##REG(nr), \
data->in_##reg[nr]); \
up(&data->update_lock); \
mutex_unlock(&data->update_lock); \
return count; \
}
@ -331,10 +332,10 @@ static ssize_t set_fan_min(struct device *dev, const char *buf,
struct asb100_data *data = i2c_get_clientdata(client);
u32 val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
asb100_write_value(client, ASB100_REG_FAN_MIN(nr), data->fan_min[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -351,7 +352,7 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
unsigned long val = simple_strtoul(buf, NULL, 10);
int reg;
down(&data->update_lock);
mutex_lock(&data->update_lock);
min = FAN_FROM_REG(data->fan_min[nr],
DIV_FROM_REG(data->fan_div[nr]));
@ -381,7 +382,7 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
asb100_write_value(client, ASB100_REG_FAN_MIN(nr), data->fan_min[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -461,7 +462,7 @@ static ssize_t set_##reg(struct device *dev, const char *buf, \
struct asb100_data *data = i2c_get_clientdata(client); \
unsigned long val = simple_strtoul(buf, NULL, 10); \
\
down(&data->update_lock); \
mutex_lock(&data->update_lock); \
switch (nr) { \
case 1: case 2: \
data->reg[nr] = LM75_TEMP_TO_REG(val); \
@ -472,7 +473,7 @@ static ssize_t set_##reg(struct device *dev, const char *buf, \
} \
asb100_write_value(client, ASB100_REG_TEMP_##REG(nr+1), \
data->reg[nr]); \
up(&data->update_lock); \
mutex_unlock(&data->update_lock); \
return count; \
}
@ -574,11 +575,11 @@ static ssize_t set_pwm1(struct device *dev, struct device_attribute *attr, const
struct asb100_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->pwm &= 0x80; /* keep the enable bit */
data->pwm |= (0x0f & ASB100_PWM_TO_REG(val));
asb100_write_value(client, ASB100_REG_PWM1, data->pwm);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -595,11 +596,11 @@ static ssize_t set_pwm_enable1(struct device *dev, struct device_attribute *attr
struct asb100_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->pwm &= 0x0f; /* keep the duty cycle bits */
data->pwm |= (val ? 0x80 : 0x00);
asb100_write_value(client, ASB100_REG_PWM1, data->pwm);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -729,7 +730,7 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind)
}
new_client = &data->client;
init_MUTEX(&data->lock);
mutex_init(&data->lock);
i2c_set_clientdata(new_client, data);
new_client->addr = address;
new_client->adapter = adapter;
@ -789,7 +790,7 @@ static int asb100_detect(struct i2c_adapter *adapter, int address, int kind)
data->type = kind;
data->valid = 0;
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
@ -885,7 +886,7 @@ static int asb100_read_value(struct i2c_client *client, u16 reg)
struct i2c_client *cl;
int res, bank;
down(&data->lock);
mutex_lock(&data->lock);
bank = (reg >> 8) & 0x0f;
if (bank > 2)
@ -919,7 +920,7 @@ static int asb100_read_value(struct i2c_client *client, u16 reg)
if (bank > 2)
i2c_smbus_write_byte_data(client, ASB100_REG_BANK, 0);
up(&data->lock);
mutex_unlock(&data->lock);
return res;
}
@ -930,7 +931,7 @@ static void asb100_write_value(struct i2c_client *client, u16 reg, u16 value)
struct i2c_client *cl;
int bank;
down(&data->lock);
mutex_lock(&data->lock);
bank = (reg >> 8) & 0x0f;
if (bank > 2)
@ -960,7 +961,7 @@ static void asb100_write_value(struct i2c_client *client, u16 reg, u16 value)
if (bank > 2)
i2c_smbus_write_byte_data(client, ASB100_REG_BANK, 0);
up(&data->lock);
mutex_unlock(&data->lock);
}
static void asb100_init_client(struct i2c_client *client)
@ -984,7 +985,7 @@ static struct asb100_data *asb100_update_device(struct device *dev)
struct asb100_data *data = i2c_get_clientdata(client);
int i;
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
|| !data->valid) {
@ -1042,7 +1043,7 @@ static struct asb100_data *asb100_update_device(struct device *dev)
dev_dbg(&client->dev, "... device update complete\n");
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return data;
}

View File

@ -26,6 +26,7 @@
#include <linux/hwmon.h>
#include <linux/hwmon-vid.h>
#include <linux/err.h>
#include <linux/mutex.h>
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("System voltages control via Attansic ATXP1");
@ -60,7 +61,7 @@ static struct i2c_driver atxp1_driver = {
struct atxp1_data {
struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock;
struct mutex update_lock;
unsigned long last_updated;
u8 valid;
struct {
@ -80,7 +81,7 @@ static struct atxp1_data * atxp1_update_device(struct device *dev)
client = to_i2c_client(dev);
data = i2c_get_clientdata(client);
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
@ -93,7 +94,7 @@ static struct atxp1_data * atxp1_update_device(struct device *dev)
data->valid = 1;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return(data);
}
@ -309,7 +310,7 @@ static int atxp1_detect(struct i2c_adapter *adapter, int address, int kind)
data->valid = 0;
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
err = i2c_attach_client(new_client);

View File

@ -28,6 +28,7 @@
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include "lm75.h"
/* Addresses to scan */
@ -72,7 +73,7 @@ MODULE_PARM_DESC(polarity, "Output's polarity: 0 = active high, 1 = active low")
struct ds1621_data {
struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock;
struct mutex update_lock;
char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */
@ -156,10 +157,10 @@ static ssize_t set_temp_##suffix(struct device *dev, struct device_attribute *at
struct ds1621_data *data = ds1621_update_client(dev); \
u16 val = LM75_TEMP_TO_REG(simple_strtoul(buf, NULL, 10)); \
\
down(&data->update_lock); \
mutex_lock(&data->update_lock); \
data->value = val; \
ds1621_write_value(client, reg, data->value); \
up(&data->update_lock); \
mutex_unlock(&data->update_lock); \
return count; \
}
@ -242,7 +243,7 @@ static int ds1621_detect(struct i2c_adapter *adapter, int address,
/* Fill in remaining client fields and put it into the global list */
strlcpy(new_client->name, "ds1621", I2C_NAME_SIZE);
data->valid = 0;
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
@ -297,7 +298,7 @@ static struct ds1621_data *ds1621_update_client(struct device *dev)
struct ds1621_data *data = i2c_get_clientdata(client);
u8 new_conf;
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
|| !data->valid) {
@ -327,7 +328,7 @@ static struct ds1621_data *ds1621_update_client(struct device *dev)
data->valid = 1;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return data;
}

View File

@ -30,6 +30,7 @@
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <asm/io.h>
static struct platform_device *pdev;
@ -131,10 +132,10 @@ static struct resource f71805f_resource __initdata = {
struct f71805f_data {
unsigned short addr;
const char *name;
struct semaphore lock;
struct mutex lock;
struct class_device *class_dev;
struct semaphore update_lock;
struct mutex update_lock;
char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */
unsigned long last_limits; /* In jiffies */
@ -224,20 +225,20 @@ static u8 f71805f_read8(struct f71805f_data *data, u8 reg)
{
u8 val;
down(&data->lock);
mutex_lock(&data->lock);
outb(reg, data->addr + ADDR_REG_OFFSET);
val = inb(data->addr + DATA_REG_OFFSET);
up(&data->lock);
mutex_unlock(&data->lock);
return val;
}
static void f71805f_write8(struct f71805f_data *data, u8 reg, u8 val)
{
down(&data->lock);
mutex_lock(&data->lock);
outb(reg, data->addr + ADDR_REG_OFFSET);
outb(val, data->addr + DATA_REG_OFFSET);
up(&data->lock);
mutex_unlock(&data->lock);
}
/* It is important to read the MSB first, because doing so latches the
@ -246,24 +247,24 @@ static u16 f71805f_read16(struct f71805f_data *data, u8 reg)
{
u16 val;
down(&data->lock);
mutex_lock(&data->lock);
outb(reg, data->addr + ADDR_REG_OFFSET);
val = inb(data->addr + DATA_REG_OFFSET) << 8;
outb(++reg, data->addr + ADDR_REG_OFFSET);
val |= inb(data->addr + DATA_REG_OFFSET);
up(&data->lock);
mutex_unlock(&data->lock);
return val;
}
static void f71805f_write16(struct f71805f_data *data, u8 reg, u16 val)
{
down(&data->lock);
mutex_lock(&data->lock);
outb(reg, data->addr + ADDR_REG_OFFSET);
outb(val >> 8, data->addr + DATA_REG_OFFSET);
outb(++reg, data->addr + ADDR_REG_OFFSET);
outb(val & 0xff, data->addr + DATA_REG_OFFSET);
up(&data->lock);
mutex_unlock(&data->lock);
}
static struct f71805f_data *f71805f_update_device(struct device *dev)
@ -271,7 +272,7 @@ static struct f71805f_data *f71805f_update_device(struct device *dev)
struct f71805f_data *data = dev_get_drvdata(dev);
int nr;
down(&data->update_lock);
mutex_lock(&data->update_lock);
/* Limit registers cache is refreshed after 60 seconds */
if (time_after(jiffies, data->last_updated + 60 * HZ)
@ -323,7 +324,7 @@ static struct f71805f_data *f71805f_update_device(struct device *dev)
data->valid = 1;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return data;
}
@ -362,10 +363,10 @@ static ssize_t set_in0_max(struct device *dev, struct device_attribute
struct f71805f_data *data = dev_get_drvdata(dev);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->in_high[0] = in0_to_reg(val);
f71805f_write8(data, F71805F_REG_IN_HIGH(0), data->in_high[0]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -376,18 +377,14 @@ static ssize_t set_in0_min(struct device *dev, struct device_attribute
struct f71805f_data *data = dev_get_drvdata(dev);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->in_low[0] = in0_to_reg(val);
f71805f_write8(data, F71805F_REG_IN_LOW(0), data->in_low[0]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
static DEVICE_ATTR(in0_input, S_IRUGO, show_in0, NULL);
static DEVICE_ATTR(in0_max, S_IRUGO| S_IWUSR, show_in0_max, set_in0_max);
static DEVICE_ATTR(in0_min, S_IRUGO| S_IWUSR, show_in0_min, set_in0_min);
static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
char *buf)
{
@ -426,10 +423,10 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute
int nr = attr->index;
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->in_high[nr] = in_to_reg(val);
f71805f_write8(data, F71805F_REG_IN_HIGH(nr), data->in_high[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -442,31 +439,14 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute
int nr = attr->index;
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->in_low[nr] = in_to_reg(val);
f71805f_write8(data, F71805F_REG_IN_LOW(nr), data->in_low[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
#define sysfs_in(offset) \
static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \
show_in, NULL, offset); \
static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
show_in_max, set_in_max, offset); \
static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
show_in_min, set_in_min, offset)
sysfs_in(1);
sysfs_in(2);
sysfs_in(3);
sysfs_in(4);
sysfs_in(5);
sysfs_in(6);
sysfs_in(7);
sysfs_in(8);
static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
char *buf)
{
@ -495,24 +475,14 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute
int nr = attr->index;
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->fan_low[nr] = fan_to_reg(val);
f71805f_write16(data, F71805F_REG_FAN_LOW(nr), data->fan_low[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
#define sysfs_fan(offset) \
static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \
show_fan, NULL, offset - 1); \
static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
show_fan_min, set_fan_min, offset - 1)
sysfs_fan(1);
sysfs_fan(2);
sysfs_fan(3);
static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
char *buf)
{
@ -562,10 +532,10 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute
int nr = attr->index;
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp_high[nr] = temp_to_reg(val);
f71805f_write8(data, F71805F_REG_TEMP_HIGH(nr), data->temp_high[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -578,28 +548,14 @@ static ssize_t set_temp_hyst(struct device *dev, struct device_attribute
int nr = attr->index;
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp_hyst[nr] = temp_to_reg(val);
f71805f_write8(data, F71805F_REG_TEMP_HYST(nr), data->temp_hyst[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
#define sysfs_temp(offset) \
static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \
show_temp, NULL, offset - 1); \
static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO | S_IWUSR, \
show_temp_max, set_temp_max, offset - 1); \
static SENSOR_DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO | S_IWUSR, \
show_temp_hyst, set_temp_hyst, offset - 1); \
static SENSOR_DEVICE_ATTR(temp##offset##_type, S_IRUGO, \
show_temp_type, NULL, offset - 1)
sysfs_temp(1);
sysfs_temp(2);
sysfs_temp(3);
static ssize_t show_alarms_in(struct device *dev, struct device_attribute
*devattr, char *buf)
{
@ -625,10 +581,6 @@ static ssize_t show_alarms_temp(struct device *dev, struct device_attribute
return sprintf(buf, "%d\n", (data->alarms[1] >> 3) & 0x07);
}
static DEVICE_ATTR(alarms_in, S_IRUGO, show_alarms_in, NULL);
static DEVICE_ATTR(alarms_fan, S_IRUGO, show_alarms_fan, NULL);
static DEVICE_ATTR(alarms_temp, S_IRUGO, show_alarms_temp, NULL);
static ssize_t show_name(struct device *dev, struct device_attribute
*devattr, char *buf)
{
@ -637,7 +589,89 @@ static ssize_t show_name(struct device *dev, struct device_attribute
return sprintf(buf, "%s\n", data->name);
}
static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
static struct device_attribute f71805f_dev_attr[] = {
__ATTR(in0_input, S_IRUGO, show_in0, NULL),
__ATTR(in0_max, S_IRUGO| S_IWUSR, show_in0_max, set_in0_max),
__ATTR(in0_min, S_IRUGO| S_IWUSR, show_in0_min, set_in0_min),
__ATTR(alarms_in, S_IRUGO, show_alarms_in, NULL),
__ATTR(alarms_fan, S_IRUGO, show_alarms_fan, NULL),
__ATTR(alarms_temp, S_IRUGO, show_alarms_temp, NULL),
__ATTR(name, S_IRUGO, show_name, NULL),
};
static struct sensor_device_attribute f71805f_sensor_attr[] = {
SENSOR_ATTR(in1_input, S_IRUGO, show_in, NULL, 1),
SENSOR_ATTR(in1_max, S_IRUGO | S_IWUSR,
show_in_max, set_in_max, 1),
SENSOR_ATTR(in1_min, S_IRUGO | S_IWUSR,
show_in_min, set_in_min, 1),
SENSOR_ATTR(in2_input, S_IRUGO, show_in, NULL, 2),
SENSOR_ATTR(in2_max, S_IRUGO | S_IWUSR,
show_in_max, set_in_max, 2),
SENSOR_ATTR(in2_min, S_IRUGO | S_IWUSR,
show_in_min, set_in_min, 2),
SENSOR_ATTR(in3_input, S_IRUGO, show_in, NULL, 3),
SENSOR_ATTR(in3_max, S_IRUGO | S_IWUSR,
show_in_max, set_in_max, 3),
SENSOR_ATTR(in3_min, S_IRUGO | S_IWUSR,
show_in_min, set_in_min, 3),
SENSOR_ATTR(in4_input, S_IRUGO, show_in, NULL, 4),
SENSOR_ATTR(in4_max, S_IRUGO | S_IWUSR,
show_in_max, set_in_max, 4),
SENSOR_ATTR(in4_min, S_IRUGO | S_IWUSR,
show_in_min, set_in_min, 4),
SENSOR_ATTR(in5_input, S_IRUGO, show_in, NULL, 5),
SENSOR_ATTR(in5_max, S_IRUGO | S_IWUSR,
show_in_max, set_in_max, 5),
SENSOR_ATTR(in5_min, S_IRUGO | S_IWUSR,
show_in_min, set_in_min, 5),
SENSOR_ATTR(in6_input, S_IRUGO, show_in, NULL, 6),
SENSOR_ATTR(in6_max, S_IRUGO | S_IWUSR,
show_in_max, set_in_max, 6),
SENSOR_ATTR(in6_min, S_IRUGO | S_IWUSR,
show_in_min, set_in_min, 6),
SENSOR_ATTR(in7_input, S_IRUGO, show_in, NULL, 7),
SENSOR_ATTR(in7_max, S_IRUGO | S_IWUSR,
show_in_max, set_in_max, 7),
SENSOR_ATTR(in7_min, S_IRUGO | S_IWUSR,
show_in_min, set_in_min, 7),
SENSOR_ATTR(in8_input, S_IRUGO, show_in, NULL, 8),
SENSOR_ATTR(in8_max, S_IRUGO | S_IWUSR,
show_in_max, set_in_max, 8),
SENSOR_ATTR(in8_min, S_IRUGO | S_IWUSR,
show_in_min, set_in_min, 8),
SENSOR_ATTR(temp1_input, S_IRUGO, show_temp, NULL, 0),
SENSOR_ATTR(temp1_max, S_IRUGO | S_IWUSR,
show_temp_max, set_temp_max, 0),
SENSOR_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR,
show_temp_hyst, set_temp_hyst, 0),
SENSOR_ATTR(temp1_type, S_IRUGO, show_temp_type, NULL, 0),
SENSOR_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 1),
SENSOR_ATTR(temp2_max, S_IRUGO | S_IWUSR,
show_temp_max, set_temp_max, 1),
SENSOR_ATTR(temp2_max_hyst, S_IRUGO | S_IWUSR,
show_temp_hyst, set_temp_hyst, 1),
SENSOR_ATTR(temp2_type, S_IRUGO, show_temp_type, NULL, 1),
SENSOR_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 2),
SENSOR_ATTR(temp3_max, S_IRUGO | S_IWUSR,
show_temp_max, set_temp_max, 2),
SENSOR_ATTR(temp3_max_hyst, S_IRUGO | S_IWUSR,
show_temp_hyst, set_temp_hyst, 2),
SENSOR_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2),
};
static struct sensor_device_attribute f71805f_fan_attr[] = {
SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0),
SENSOR_ATTR(fan1_min, S_IRUGO | S_IWUSR,
show_fan_min, set_fan_min, 0),
SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1),
SENSOR_ATTR(fan2_min, S_IRUGO | S_IWUSR,
show_fan_min, set_fan_min, 1),
SENSOR_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2),
SENSOR_ATTR(fan3_min, S_IRUGO | S_IWUSR,
show_fan_min, set_fan_min, 2),
};
/*
* Device registration and initialization
@ -668,7 +702,7 @@ static int __devinit f71805f_probe(struct platform_device *pdev)
{
struct f71805f_data *data;
struct resource *res;
int err;
int i, err;
if (!(data = kzalloc(sizeof(struct f71805f_data), GFP_KERNEL))) {
err = -ENOMEM;
@ -678,9 +712,9 @@ static int __devinit f71805f_probe(struct platform_device *pdev)
res = platform_get_resource(pdev, IORESOURCE_IO, 0);
data->addr = res->start;
init_MUTEX(&data->lock);
mutex_init(&data->lock);
data->name = "f71805f";
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
platform_set_drvdata(pdev, data);
@ -695,76 +729,31 @@ static int __devinit f71805f_probe(struct platform_device *pdev)
f71805f_init_device(data);
/* Register sysfs interface files */
device_create_file(&pdev->dev, &dev_attr_in0_input);
device_create_file(&pdev->dev, &dev_attr_in0_max);
device_create_file(&pdev->dev, &dev_attr_in0_min);
device_create_file(&pdev->dev, &sensor_dev_attr_in1_input.dev_attr);
device_create_file(&pdev->dev, &sensor_dev_attr_in2_input.dev_attr);
device_create_file(&pdev->dev, &sensor_dev_attr_in3_input.dev_attr);
device_create_file(&pdev->dev, &sensor_dev_attr_in4_input.dev_attr);
device_create_file(&pdev->dev, &sensor_dev_attr_in5_input.dev_attr);
device_create_file(&pdev->dev, &sensor_dev_attr_in6_input.dev_attr);
device_create_file(&pdev->dev, &sensor_dev_attr_in7_input.dev_attr);
device_create_file(&pdev->dev, &sensor_dev_attr_in8_input.dev_attr);
device_create_file(&pdev->dev, &sensor_dev_attr_in1_max.dev_attr);
device_create_file(&pdev->dev, &sensor_dev_attr_in2_max.dev_attr);
device_create_file(&pdev->dev, &sensor_dev_attr_in3_max.dev_attr);
device_create_file(&pdev->dev, &sensor_dev_attr_in4_max.dev_attr);
device_create_file(&pdev->dev, &sensor_dev_attr_in5_max.dev_attr);
device_create_file(&pdev->dev, &sensor_dev_attr_in6_max.dev_attr);
device_create_file(&pdev->dev, &sensor_dev_attr_in7_max.dev_attr);
device_create_file(&pdev->dev, &sensor_dev_attr_in8_max.dev_attr);
device_create_file(&pdev->dev, &sensor_dev_attr_in1_min.dev_attr);
device_create_file(&pdev->dev, &sensor_dev_attr_in2_min.dev_attr);
device_create_file(&pdev->dev, &sensor_dev_attr_in3_min.dev_attr);
device_create_file(&pdev->dev, &sensor_dev_attr_in4_min.dev_attr);
device_create_file(&pdev->dev, &sensor_dev_attr_in5_min.dev_attr);
device_create_file(&pdev->dev, &sensor_dev_attr_in6_min.dev_attr);
device_create_file(&pdev->dev, &sensor_dev_attr_in7_min.dev_attr);
device_create_file(&pdev->dev, &sensor_dev_attr_in8_min.dev_attr);
if (data->fan_enabled & (1 << 0)) {
device_create_file(&pdev->dev,
&sensor_dev_attr_fan1_input.dev_attr);
device_create_file(&pdev->dev,
&sensor_dev_attr_fan1_min.dev_attr);
for (i = 0; i < ARRAY_SIZE(f71805f_dev_attr); i++) {
err = device_create_file(&pdev->dev, &f71805f_dev_attr[i]);
if (err)
goto exit_class;
}
if (data->fan_enabled & (1 << 1)) {
device_create_file(&pdev->dev,
&sensor_dev_attr_fan2_input.dev_attr);
device_create_file(&pdev->dev,
&sensor_dev_attr_fan2_min.dev_attr);
for (i = 0; i < ARRAY_SIZE(f71805f_sensor_attr); i++) {
err = device_create_file(&pdev->dev,
&f71805f_sensor_attr[i].dev_attr);
if (err)
goto exit_class;
}
if (data->fan_enabled & (1 << 2)) {
device_create_file(&pdev->dev,
&sensor_dev_attr_fan3_input.dev_attr);
device_create_file(&pdev->dev,
&sensor_dev_attr_fan3_min.dev_attr);
for (i = 0; i < ARRAY_SIZE(f71805f_fan_attr); i++) {
if (!(data->fan_enabled & (1 << (i / 2))))
continue;
err = device_create_file(&pdev->dev,
&f71805f_fan_attr[i].dev_attr);
if (err)
goto exit_class;
}
device_create_file(&pdev->dev,
&sensor_dev_attr_temp1_input.dev_attr);
device_create_file(&pdev->dev,
&sensor_dev_attr_temp2_input.dev_attr);
device_create_file(&pdev->dev,
&sensor_dev_attr_temp3_input.dev_attr);
device_create_file(&pdev->dev, &sensor_dev_attr_temp1_max.dev_attr);
device_create_file(&pdev->dev, &sensor_dev_attr_temp2_max.dev_attr);
device_create_file(&pdev->dev, &sensor_dev_attr_temp3_max.dev_attr);
device_create_file(&pdev->dev,
&sensor_dev_attr_temp1_max_hyst.dev_attr);
device_create_file(&pdev->dev,
&sensor_dev_attr_temp2_max_hyst.dev_attr);
device_create_file(&pdev->dev,
&sensor_dev_attr_temp3_max_hyst.dev_attr);
device_create_file(&pdev->dev, &sensor_dev_attr_temp1_type.dev_attr);
device_create_file(&pdev->dev, &sensor_dev_attr_temp2_type.dev_attr);
device_create_file(&pdev->dev, &sensor_dev_attr_temp3_type.dev_attr);
device_create_file(&pdev->dev, &dev_attr_alarms_in);
device_create_file(&pdev->dev, &dev_attr_alarms_fan);
device_create_file(&pdev->dev, &dev_attr_alarms_temp);
device_create_file(&pdev->dev, &dev_attr_name);
return 0;
exit_class:
dev_err(&pdev->dev, "Sysfs interface creation failed\n");
hwmon_device_unregister(data->class_dev);
exit_free:
kfree(data);
exit:

View File

@ -33,6 +33,7 @@
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/err.h>
#include <linux/mutex.h>
/*
* Addresses to scan
@ -133,7 +134,7 @@ static struct i2c_driver fscher_driver = {
struct fscher_data {
struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock;
struct mutex update_lock;
char valid; /* zero until following fields are valid */
unsigned long last_updated; /* in jiffies */
@ -332,7 +333,7 @@ static int fscher_detect(struct i2c_adapter *adapter, int address, int kind)
* global list */
strlcpy(new_client->name, "fscher", I2C_NAME_SIZE);
data->valid = 0;
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
@ -417,7 +418,7 @@ static struct fscher_data *fscher_update_device(struct device *dev)
struct i2c_client *client = to_i2c_client(dev);
struct fscher_data *data = i2c_get_clientdata(client);
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) {
@ -457,7 +458,7 @@ static struct fscher_data *fscher_update_device(struct device *dev)
data->valid = 1;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return data;
}
@ -472,10 +473,10 @@ static ssize_t set_fan_status(struct i2c_client *client, struct fscher_data *dat
/* bits 0..1, 3..7 reserved => mask with 0x04 */
unsigned long v = simple_strtoul(buf, NULL, 10) & 0x04;
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->fan_status[FAN_INDEX_FROM_NUM(nr)] &= ~v;
fscher_write_value(client, reg, v);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -490,10 +491,10 @@ static ssize_t set_pwm(struct i2c_client *client, struct fscher_data *data,
{
unsigned long v = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->fan_min[FAN_INDEX_FROM_NUM(nr)] = v > 0xff ? 0xff : v;
fscher_write_value(client, reg, data->fan_min[FAN_INDEX_FROM_NUM(nr)]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -518,14 +519,14 @@ static ssize_t set_fan_div(struct i2c_client *client, struct fscher_data *data,
return -EINVAL;
}
down(&data->update_lock);
mutex_lock(&data->update_lock);
/* bits 2..7 reserved => mask with 0x03 */
data->fan_ripple[FAN_INDEX_FROM_NUM(nr)] &= ~0x03;
data->fan_ripple[FAN_INDEX_FROM_NUM(nr)] |= v;
fscher_write_value(client, reg, data->fan_ripple[FAN_INDEX_FROM_NUM(nr)]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -552,10 +553,10 @@ static ssize_t set_temp_status(struct i2c_client *client, struct fscher_data *da
/* bits 2..7 reserved, 0 read only => mask with 0x02 */
unsigned long v = simple_strtoul(buf, NULL, 10) & 0x02;
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp_status[TEMP_INDEX_FROM_NUM(nr)] &= ~v;
fscher_write_value(client, reg, v);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -609,10 +610,10 @@ static ssize_t set_control(struct i2c_client *client, struct fscher_data *data,
/* bits 1..7 reserved => mask with 0x01 */
unsigned long v = simple_strtoul(buf, NULL, 10) & 0x01;
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->global_control &= ~v;
fscher_write_value(client, reg, v);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -631,11 +632,11 @@ static ssize_t set_watchdog_control(struct i2c_client *client, struct
/* bits 0..3 reserved => mask with 0xf0 */
unsigned long v = simple_strtoul(buf, NULL, 10) & 0xf0;
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->watchdog[2] &= ~0xf0;
data->watchdog[2] |= v;
fscher_write_value(client, reg, data->watchdog[2]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -651,10 +652,10 @@ static ssize_t set_watchdog_status(struct i2c_client *client, struct fscher_data
/* bits 0, 2..7 reserved => mask with 0x02 */
unsigned long v = simple_strtoul(buf, NULL, 10) & 0x02;
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->watchdog[1] &= ~v;
fscher_write_value(client, reg, v);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -669,10 +670,10 @@ static ssize_t set_watchdog_preset(struct i2c_client *client, struct fscher_data
{
unsigned long v = simple_strtoul(buf, NULL, 10) & 0xff;
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->watchdog[0] = v;
fscher_write_value(client, reg, data->watchdog[0]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}

View File

@ -37,6 +37,7 @@
#include <linux/init.h>
#include <linux/hwmon.h>
#include <linux/err.h>
#include <linux/mutex.h>
/*
* Addresses to scan
@ -89,8 +90,8 @@ static int fscpos_attach_adapter(struct i2c_adapter *adapter);
static int fscpos_detect(struct i2c_adapter *adapter, int address, int kind);
static int fscpos_detach_client(struct i2c_client *client);
static int fscpos_read_value(struct i2c_client *client, u8 register);
static int fscpos_write_value(struct i2c_client *client, u8 register, u8 value);
static int fscpos_read_value(struct i2c_client *client, u8 reg);
static int fscpos_write_value(struct i2c_client *client, u8 reg, u8 value);
static struct fscpos_data *fscpos_update_device(struct device *dev);
static void fscpos_init_client(struct i2c_client *client);
@ -114,7 +115,7 @@ static struct i2c_driver fscpos_driver = {
struct fscpos_data {
struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock;
struct mutex update_lock;
char valid; /* 0 until following fields are valid */
unsigned long last_updated; /* In jiffies */
@ -208,13 +209,13 @@ static ssize_t set_fan_ripple(struct i2c_client *client, struct fscpos_data
return -EINVAL;
}
down(&data->update_lock);
mutex_lock(&data->update_lock);
/* bits 2..7 reserved => mask with 0x03 */
data->fan_ripple[nr - 1] &= ~0x03;
data->fan_ripple[nr - 1] |= v;
fscpos_write_value(client, reg, data->fan_ripple[nr - 1]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -232,10 +233,10 @@ static ssize_t set_pwm(struct i2c_client *client, struct fscpos_data *data,
if (v < 0) v = 0;
if (v > 255) v = 255;
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->pwm[nr - 1] = v;
fscpos_write_value(client, reg, data->pwm[nr - 1]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -278,11 +279,11 @@ static ssize_t set_wdog_control(struct i2c_client *client, struct fscpos_data
/* bits 0..3 reserved => mask with 0xf0 */
unsigned long v = simple_strtoul(buf, NULL, 10) & 0xf0;
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->wdog_control &= ~0xf0;
data->wdog_control |= v;
fscpos_write_value(client, reg, data->wdog_control);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -304,10 +305,10 @@ static ssize_t set_wdog_state(struct i2c_client *client, struct fscpos_data
return -EINVAL;
}
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->wdog_state &= ~v;
fscpos_write_value(client, reg, v);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -321,10 +322,10 @@ static ssize_t set_wdog_preset(struct i2c_client *client, struct fscpos_data
{
unsigned long v = simple_strtoul(buf, NULL, 10) & 0xff;
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->wdog_preset = v;
fscpos_write_value(client, reg, data->wdog_preset);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -483,7 +484,7 @@ static int fscpos_detect(struct i2c_adapter *adapter, int address, int kind)
strlcpy(new_client->name, "fscpos", I2C_NAME_SIZE);
data->valid = 0;
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
@ -579,7 +580,7 @@ static struct fscpos_data *fscpos_update_device(struct device *dev)
struct i2c_client *client = to_i2c_client(dev);
struct fscpos_data *data = i2c_get_clientdata(client);
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) {
int i;
@ -625,7 +626,7 @@ static struct fscpos_data *fscpos_update_device(struct device *dev)
data->last_updated = jiffies;
data->valid = 1;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return data;
}

View File

@ -43,6 +43,7 @@
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/err.h>
#include <linux/mutex.h>
/* Addresses to scan */
static unsigned short normal_i2c[] = { 0x2c, 0x2d, I2C_CLIENT_END };
@ -120,7 +121,7 @@ struct gl518_data {
struct class_device *class_dev;
enum chips type;
struct semaphore update_lock;
struct mutex update_lock;
char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */
@ -212,10 +213,10 @@ static ssize_t set_##suffix(struct device *dev, struct device_attribute *attr, c
struct gl518_data *data = i2c_get_clientdata(client); \
long val = simple_strtol(buf, NULL, 10); \
\
down(&data->update_lock); \
mutex_lock(&data->update_lock); \
data->value = type##_TO_REG(val); \
gl518_write_value(client, reg, data->value); \
up(&data->update_lock); \
mutex_unlock(&data->update_lock); \
return count; \
}
@ -228,12 +229,12 @@ static ssize_t set_##suffix(struct device *dev, struct device_attribute *attr, c
int regvalue; \
unsigned long val = simple_strtoul(buf, NULL, 10); \
\
down(&data->update_lock); \
mutex_lock(&data->update_lock); \
regvalue = gl518_read_value(client, reg); \
data->value = type##_TO_REG(val); \
regvalue = (regvalue & ~mask) | (data->value << shift); \
gl518_write_value(client, reg, regvalue); \
up(&data->update_lock); \
mutex_unlock(&data->update_lock); \
return count; \
}
@ -265,7 +266,7 @@ static ssize_t set_fan_min1(struct device *dev, struct device_attribute *attr, c
int regvalue;
unsigned long val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
regvalue = gl518_read_value(client, GL518_REG_FAN_LIMIT);
data->fan_min[0] = FAN_TO_REG(val,
DIV_FROM_REG(data->fan_div[0]));
@ -280,7 +281,7 @@ static ssize_t set_fan_min1(struct device *dev, struct device_attribute *attr, c
data->beep_mask &= data->alarm_mask;
gl518_write_value(client, GL518_REG_ALARM, data->beep_mask);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -291,7 +292,7 @@ static ssize_t set_fan_min2(struct device *dev, struct device_attribute *attr, c
int regvalue;
unsigned long val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
regvalue = gl518_read_value(client, GL518_REG_FAN_LIMIT);
data->fan_min[1] = FAN_TO_REG(val,
DIV_FROM_REG(data->fan_div[1]));
@ -306,7 +307,7 @@ static ssize_t set_fan_min2(struct device *dev, struct device_attribute *attr, c
data->beep_mask &= data->alarm_mask;
gl518_write_value(client, GL518_REG_ALARM, data->beep_mask);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -407,7 +408,7 @@ static int gl518_detect(struct i2c_adapter *adapter, int address, int kind)
strlcpy(new_client->name, "gl518sm", I2C_NAME_SIZE);
data->type = kind;
data->valid = 0;
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
@ -525,7 +526,7 @@ static struct gl518_data *gl518_update_device(struct device *dev)
struct gl518_data *data = i2c_get_clientdata(client);
int val;
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
|| !data->valid) {
@ -586,7 +587,7 @@ static struct gl518_data *gl518_update_device(struct device *dev)
data->valid = 1;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return data;
}

View File

@ -29,6 +29,7 @@
#include <linux/hwmon.h>
#include <linux/hwmon-vid.h>
#include <linux/err.h>
#include <linux/mutex.h>
/* Type of the extra sensor */
static unsigned short extra_sensor_type;
@ -121,7 +122,7 @@ static struct i2c_driver gl520_driver = {
struct gl520_data {
struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock;
struct mutex update_lock;
char valid; /* zero until the following fields are valid */
unsigned long last_updated; /* in jiffies */
@ -303,7 +304,7 @@ static ssize_t set_in_min(struct i2c_client *client, struct gl520_data *data, co
long v = simple_strtol(buf, NULL, 10);
u8 r;
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (n == 0)
r = VDD_TO_REG(v);
@ -317,7 +318,7 @@ static ssize_t set_in_min(struct i2c_client *client, struct gl520_data *data, co
else
gl520_write_value(client, reg, r);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -331,7 +332,7 @@ static ssize_t set_in_max(struct i2c_client *client, struct gl520_data *data, co
else
r = IN_TO_REG(v);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->in_max[n] = r;
@ -340,7 +341,7 @@ static ssize_t set_in_max(struct i2c_client *client, struct gl520_data *data, co
else
gl520_write_value(client, reg, r);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -373,7 +374,7 @@ static ssize_t set_fan_min(struct i2c_client *client, struct gl520_data *data, c
unsigned long v = simple_strtoul(buf, NULL, 10);
u8 r;
down(&data->update_lock);
mutex_lock(&data->update_lock);
r = FAN_TO_REG(v, data->fan_div[n - 1]);
data->fan_min[n - 1] = r;
@ -390,7 +391,7 @@ static ssize_t set_fan_min(struct i2c_client *client, struct gl520_data *data, c
data->beep_mask &= data->alarm_mask;
gl520_write_value(client, GL520_REG_BEEP_MASK, data->beep_mask);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -409,7 +410,7 @@ static ssize_t set_fan_div(struct i2c_client *client, struct gl520_data *data, c
return -EINVAL;
}
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->fan_div[n - 1] = r;
if (n == 1)
@ -417,7 +418,7 @@ static ssize_t set_fan_div(struct i2c_client *client, struct gl520_data *data, c
else
gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0x30) | (r << 4));
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -425,10 +426,10 @@ static ssize_t set_fan_off(struct i2c_client *client, struct gl520_data *data, c
{
u8 r = simple_strtoul(buf, NULL, 10)?1:0;
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->fan_off = r;
gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0x0c) | (r << 2));
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -454,10 +455,10 @@ static ssize_t set_temp_max(struct i2c_client *client, struct gl520_data *data,
{
long v = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp_max[n - 1] = TEMP_TO_REG(v);;
gl520_write_value(client, reg, data->temp_max[n - 1]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -465,10 +466,10 @@ static ssize_t set_temp_max_hyst(struct i2c_client *client, struct gl520_data *d
{
long v = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp_max_hyst[n - 1] = TEMP_TO_REG(v);
gl520_write_value(client, reg, data->temp_max_hyst[n - 1]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -491,10 +492,10 @@ static ssize_t set_beep_enable(struct i2c_client *client, struct gl520_data *dat
{
u8 r = simple_strtoul(buf, NULL, 10)?0:1;
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->beep_enable = !r;
gl520_write_value(client, reg, (gl520_read_value(client, reg) & ~0x04) | (r << 2));
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -502,11 +503,11 @@ static ssize_t set_beep_mask(struct i2c_client *client, struct gl520_data *data,
{
u8 r = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
r &= data->alarm_mask;
data->beep_mask = r;
gl520_write_value(client, reg, r);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -561,7 +562,7 @@ static int gl520_detect(struct i2c_adapter *adapter, int address, int kind)
/* Fill in the remaining client fields */
strlcpy(new_client->name, "gl520sm", I2C_NAME_SIZE);
data->valid = 0;
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
@ -685,7 +686,7 @@ static struct gl520_data *gl520_update_device(struct device *dev)
struct gl520_data *data = i2c_get_clientdata(client);
int val;
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) {
@ -750,7 +751,7 @@ static struct gl520_data *gl520_update_device(struct device *dev)
data->valid = 1;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return data;
}

View File

@ -33,6 +33,7 @@
#include <linux/module.h>
#include <linux/timer.h>
#include <linux/dmi.h>
#include <linux/mutex.h>
#include <asm/io.h>
#define HDAPS_LOW_PORT 0x1600 /* first port used by hdaps */
@ -70,10 +71,10 @@ static u8 km_activity;
static int rest_x;
static int rest_y;
static DECLARE_MUTEX(hdaps_sem);
static DEFINE_MUTEX(hdaps_mutex);
/*
* __get_latch - Get the value from a given port. Callers must hold hdaps_sem.
* __get_latch - Get the value from a given port. Callers must hold hdaps_mutex.
*/
static inline u8 __get_latch(u16 port)
{
@ -82,7 +83,7 @@ static inline u8 __get_latch(u16 port)
/*
* __check_latch - Check a port latch for a given value. Returns zero if the
* port contains the given value. Callers must hold hdaps_sem.
* port contains the given value. Callers must hold hdaps_mutex.
*/
static inline int __check_latch(u16 port, u8 val)
{
@ -93,7 +94,7 @@ static inline int __check_latch(u16 port, u8 val)
/*
* __wait_latch - Wait up to 100us for a port latch to get a certain value,
* returning zero if the value is obtained. Callers must hold hdaps_sem.
* returning zero if the value is obtained. Callers must hold hdaps_mutex.
*/
static int __wait_latch(u16 port, u8 val)
{
@ -110,7 +111,7 @@ static int __wait_latch(u16 port, u8 val)
/*
* __device_refresh - request a refresh from the accelerometer. Does not wait
* for refresh to complete. Callers must hold hdaps_sem.
* for refresh to complete. Callers must hold hdaps_mutex.
*/
static void __device_refresh(void)
{
@ -124,7 +125,7 @@ static void __device_refresh(void)
/*
* __device_refresh_sync - request a synchronous refresh from the
* accelerometer. We wait for the refresh to complete. Returns zero if
* successful and nonzero on error. Callers must hold hdaps_sem.
* successful and nonzero on error. Callers must hold hdaps_mutex.
*/
static int __device_refresh_sync(void)
{
@ -134,7 +135,7 @@ static int __device_refresh_sync(void)
/*
* __device_complete - indicate to the accelerometer that we are done reading
* data, and then initiate an async refresh. Callers must hold hdaps_sem.
* data, and then initiate an async refresh. Callers must hold hdaps_mutex.
*/
static inline void __device_complete(void)
{
@ -152,7 +153,7 @@ static int hdaps_readb_one(unsigned int port, u8 *val)
{
int ret;
down(&hdaps_sem);
mutex_lock(&hdaps_mutex);
/* do a sync refresh -- we need to be sure that we read fresh data */
ret = __device_refresh_sync();
@ -163,7 +164,7 @@ static int hdaps_readb_one(unsigned int port, u8 *val)
__device_complete();
out:
up(&hdaps_sem);
mutex_unlock(&hdaps_mutex);
return ret;
}
@ -198,9 +199,9 @@ static int hdaps_read_pair(unsigned int port1, unsigned int port2,
{
int ret;
down(&hdaps_sem);
mutex_lock(&hdaps_mutex);
ret = __hdaps_read_pair(port1, port2, val1, val2);
up(&hdaps_sem);
mutex_unlock(&hdaps_mutex);
return ret;
}
@ -213,7 +214,7 @@ static int hdaps_device_init(void)
{
int total, ret = -ENXIO;
down(&hdaps_sem);
mutex_lock(&hdaps_mutex);
outb(0x13, 0x1610);
outb(0x01, 0x161f);
@ -279,7 +280,7 @@ static int hdaps_device_init(void)
}
out:
up(&hdaps_sem);
mutex_unlock(&hdaps_mutex);
return ret;
}
@ -313,7 +314,7 @@ static struct platform_driver hdaps_driver = {
};
/*
* hdaps_calibrate - Set our "resting" values. Callers must hold hdaps_sem.
* hdaps_calibrate - Set our "resting" values. Callers must hold hdaps_mutex.
*/
static void hdaps_calibrate(void)
{
@ -325,7 +326,7 @@ static void hdaps_mousedev_poll(unsigned long unused)
int x, y;
/* Cannot sleep. Try nonblockingly. If we fail, try again later. */
if (down_trylock(&hdaps_sem)) {
if (!mutex_trylock(&hdaps_mutex)) {
mod_timer(&hdaps_timer,jiffies + HDAPS_POLL_PERIOD);
return;
}
@ -340,7 +341,7 @@ static void hdaps_mousedev_poll(unsigned long unused)
mod_timer(&hdaps_timer, jiffies + HDAPS_POLL_PERIOD);
out:
up(&hdaps_sem);
mutex_unlock(&hdaps_mutex);
}
@ -420,9 +421,9 @@ static ssize_t hdaps_calibrate_store(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
{
down(&hdaps_sem);
mutex_lock(&hdaps_mutex);
hdaps_calibrate();
up(&hdaps_sem);
mutex_unlock(&hdaps_mutex);
return count;
}

View File

@ -54,6 +54,10 @@
(IMVP-II). You can find more information in the datasheet of Max1718
http://www.maxim-ic.com/quick_view2.cfm/qv_pk/2452
The 13 specification corresponds to the Intel Pentium M series. There
doesn't seem to be any named specification for these. The conversion
tables are detailed directly in the various Pentium M datasheets:
http://www.intel.com/design/intarch/pentiumm/docs_pentiumm.htm
*/
/* vrm is the VRM/VRD document version multiplied by 10.
@ -100,6 +104,8 @@ int vid_from_reg(int val, u8 vrm)
case 17: /* Intel IMVP-II */
return(val & 0x10 ? 975 - (val & 0xF) * 25 :
1750 - val * 50);
case 13:
return(1708 - (val & 0x3f) * 16);
default: /* report 0 for unknown */
printk(KERN_INFO "hwmon-vid: requested unknown VRM version\n");
return 0;
@ -129,8 +135,9 @@ struct vrm_model {
static struct vrm_model vrm_models[] = {
{X86_VENDOR_AMD, 0x6, ANY, ANY, 90}, /* Athlon Duron etc */
{X86_VENDOR_AMD, 0xF, ANY, ANY, 24}, /* Athlon 64, Opteron and above VRM 24 */
{X86_VENDOR_INTEL, 0x6, 0x9, ANY, 85}, /* 0.13um too */
{X86_VENDOR_INTEL, 0x6, 0x9, ANY, 13}, /* Pentium M (130 nm) */
{X86_VENDOR_INTEL, 0x6, 0xB, ANY, 85}, /* Tualatin */
{X86_VENDOR_INTEL, 0x6, 0xD, ANY, 13}, /* Pentium M (90 nm) */
{X86_VENDOR_INTEL, 0x6, ANY, ANY, 82}, /* any P6 */
{X86_VENDOR_INTEL, 0x7, ANY, ANY, 0}, /* Itanium */
{X86_VENDOR_INTEL, 0xF, 0x0, ANY, 90}, /* P4 */

View File

@ -17,6 +17,7 @@
#include <linux/idr.h>
#include <linux/hwmon.h>
#include <linux/gfp.h>
#include <linux/spinlock.h>
#define HWMON_ID_PREFIX "hwmon"
#define HWMON_ID_FORMAT HWMON_ID_PREFIX "%d"
@ -24,6 +25,7 @@
static struct class *hwmon_class;
static DEFINE_IDR(hwmon_idr);
static DEFINE_SPINLOCK(idr_lock);
/**
* hwmon_device_register - register w/ hwmon sysfs class
@ -37,20 +39,30 @@ static DEFINE_IDR(hwmon_idr);
struct class_device *hwmon_device_register(struct device *dev)
{
struct class_device *cdev;
int id;
int id, err;
if (idr_pre_get(&hwmon_idr, GFP_KERNEL) == 0)
again:
if (unlikely(idr_pre_get(&hwmon_idr, GFP_KERNEL) == 0))
return ERR_PTR(-ENOMEM);
if (idr_get_new(&hwmon_idr, NULL, &id) < 0)
return ERR_PTR(-ENOMEM);
spin_lock(&idr_lock);
err = idr_get_new(&hwmon_idr, NULL, &id);
spin_unlock(&idr_lock);
if (unlikely(err == -EAGAIN))
goto again;
else if (unlikely(err))
return ERR_PTR(err);
id = id & MAX_ID_MASK;
cdev = class_device_create(hwmon_class, NULL, MKDEV(0,0), dev,
HWMON_ID_FORMAT, id);
if (IS_ERR(cdev))
if (IS_ERR(cdev)) {
spin_lock(&idr_lock);
idr_remove(&hwmon_idr, id);
spin_unlock(&idr_lock);
}
return cdev;
}
@ -64,9 +76,11 @@ void hwmon_device_unregister(struct class_device *cdev)
{
int id;
if (sscanf(cdev->class_id, HWMON_ID_FORMAT, &id) == 1) {
if (likely(sscanf(cdev->class_id, HWMON_ID_FORMAT, &id) == 1)) {
class_device_unregister(cdev);
spin_lock(&idr_lock);
idr_remove(&hwmon_idr, id);
spin_unlock(&idr_lock);
} else
dev_dbg(cdev->dev,
"hwmon_device_unregister() failed: bad class ID!\n");

View File

@ -41,6 +41,7 @@
#include <linux/hwmon-sysfs.h>
#include <linux/hwmon-vid.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <asm/io.h>
@ -194,10 +195,10 @@ static int DIV_TO_REG(int val)
struct it87_data {
struct i2c_client client;
struct class_device *class_dev;
struct semaphore lock;
struct mutex lock;
enum chips type;
struct semaphore update_lock;
struct mutex update_lock;
char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */
@ -224,9 +225,8 @@ static int it87_isa_attach_adapter(struct i2c_adapter *adapter);
static int it87_detect(struct i2c_adapter *adapter, int address, int kind);
static int it87_detach_client(struct i2c_client *client);
static int it87_read_value(struct i2c_client *client, u8 register);
static int it87_write_value(struct i2c_client *client, u8 register,
u8 value);
static int it87_read_value(struct i2c_client *client, u8 reg);
static int it87_write_value(struct i2c_client *client, u8 reg, u8 value);
static struct it87_data *it87_update_device(struct device *dev);
static int it87_check_pwm(struct i2c_client *client);
static void it87_init_client(struct i2c_client *client, struct it87_data *data);
@ -290,11 +290,11 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
struct it87_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->in_min[nr] = IN_TO_REG(val);
it87_write_value(client, IT87_REG_VIN_MIN(nr),
data->in_min[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
@ -307,11 +307,11 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
struct it87_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->in_max[nr] = IN_TO_REG(val);
it87_write_value(client, IT87_REG_VIN_MAX(nr),
data->in_max[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -381,10 +381,10 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
struct it87_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp_high[nr] = TEMP_TO_REG(val);
it87_write_value(client, IT87_REG_TEMP_HIGH(nr), data->temp_high[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
@ -397,10 +397,10 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
struct it87_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp_low[nr] = TEMP_TO_REG(val);
it87_write_value(client, IT87_REG_TEMP_LOW(nr), data->temp_low[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
#define show_temp_offset(offset) \
@ -440,7 +440,7 @@ static ssize_t set_sensor(struct device *dev, struct device_attribute *attr,
struct it87_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->sensor &= ~(1 << nr);
data->sensor &= ~(8 << nr);
@ -450,11 +450,11 @@ static ssize_t set_sensor(struct device *dev, struct device_attribute *attr,
else if (val == 2)
data->sensor |= 8 << nr;
else if (val != 0) {
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return -EINVAL;
}
it87_write_value(client, IT87_REG_TEMP_ENABLE, data->sensor);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
#define show_sensor_offset(offset) \
@ -524,7 +524,7 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
int val = simple_strtol(buf, NULL, 10);
u8 reg = it87_read_value(client, IT87_REG_FAN_DIV);
down(&data->update_lock);
mutex_lock(&data->update_lock);
switch (nr) {
case 0: data->fan_div[nr] = reg & 0x07; break;
case 1: data->fan_div[nr] = (reg >> 3) & 0x07; break;
@ -533,7 +533,7 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
it87_write_value(client, IT87_REG_FAN_MIN(nr), data->fan_min[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
@ -548,7 +548,7 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
int i, min[3];
u8 old;
down(&data->update_lock);
mutex_lock(&data->update_lock);
old = it87_read_value(client, IT87_REG_FAN_DIV);
for (i = 0; i < 3; i++)
@ -576,7 +576,7 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
data->fan_min[i]=FAN_TO_REG(min[i], DIV_FROM_REG(data->fan_div[i]));
it87_write_value(client, IT87_REG_FAN_MIN(i), data->fan_min[i]);
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t set_pwm_enable(struct device *dev,
@ -589,7 +589,7 @@ static ssize_t set_pwm_enable(struct device *dev,
struct it87_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (val == 0) {
int tmp;
@ -606,11 +606,11 @@ static ssize_t set_pwm_enable(struct device *dev,
/* set saved pwm value, clear FAN_CTLX PWM mode bit */
it87_write_value(client, IT87_REG_PWM(nr), PWM_TO_REG(data->manual_pwm_ctl[nr]));
} else {
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return -EINVAL;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
@ -626,11 +626,11 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
if (val < 0 || val > 255)
return -EINVAL;
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->manual_pwm_ctl[nr] = val;
if (data->fan_main_ctrl & (1 << nr))
it87_write_value(client, IT87_REG_PWM(nr), PWM_TO_REG(data->manual_pwm_ctl[nr]));
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -776,7 +776,7 @@ static int it87_detect(struct i2c_adapter *adapter, int address, int kind)
new_client = &data->client;
if (is_isa)
init_MUTEX(&data->lock);
mutex_init(&data->lock);
i2c_set_clientdata(new_client, data);
new_client->addr = address;
new_client->adapter = adapter;
@ -823,7 +823,7 @@ static int it87_detect(struct i2c_adapter *adapter, int address, int kind)
strlcpy(new_client->name, name, I2C_NAME_SIZE);
data->type = kind;
data->valid = 0;
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
@ -950,10 +950,10 @@ static int it87_read_value(struct i2c_client *client, u8 reg)
int res;
if (i2c_is_isa_client(client)) {
down(&data->lock);
mutex_lock(&data->lock);
outb_p(reg, client->addr + IT87_ADDR_REG_OFFSET);
res = inb_p(client->addr + IT87_DATA_REG_OFFSET);
up(&data->lock);
mutex_unlock(&data->lock);
return res;
} else
return i2c_smbus_read_byte_data(client, reg);
@ -969,10 +969,10 @@ static int it87_write_value(struct i2c_client *client, u8 reg, u8 value)
struct it87_data *data = i2c_get_clientdata(client);
if (i2c_is_isa_client(client)) {
down(&data->lock);
mutex_lock(&data->lock);
outb_p(reg, client->addr + IT87_ADDR_REG_OFFSET);
outb_p(value, client->addr + IT87_DATA_REG_OFFSET);
up(&data->lock);
mutex_unlock(&data->lock);
return 0;
} else
return i2c_smbus_write_byte_data(client, reg, value);
@ -1098,7 +1098,7 @@ static struct it87_data *it87_update_device(struct device *dev)
struct it87_data *data = i2c_get_clientdata(client);
int i;
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
|| !data->valid) {
@ -1160,7 +1160,7 @@ static struct it87_data *it87_update_device(struct device *dev)
data->valid = 1;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return data;
}

View File

@ -45,6 +45,7 @@
#include <linux/hwmon-sysfs.h>
#include <linux/hwmon.h>
#include <linux/err.h>
#include <linux/mutex.h>
/*
* Addresses to scan
@ -153,7 +154,7 @@ static struct i2c_driver lm63_driver = {
struct lm63_data {
struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock;
struct mutex update_lock;
char valid; /* zero until following fields are valid */
unsigned long last_updated; /* in jiffies */
@ -192,13 +193,13 @@ static ssize_t set_fan(struct device *dev, struct device_attribute *dummy,
struct lm63_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->fan[1] = FAN_TO_REG(val);
i2c_smbus_write_byte_data(client, LM63_REG_TACH_LIMIT_LSB,
data->fan[1] & 0xFF);
i2c_smbus_write_byte_data(client, LM63_REG_TACH_LIMIT_MSB,
data->fan[1] >> 8);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -222,12 +223,12 @@ static ssize_t set_pwm1(struct device *dev, struct device_attribute *dummy,
return -EPERM;
val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->pwm1_value = val <= 0 ? 0 :
val >= 255 ? 2 * data->pwm1_freq :
(val * data->pwm1_freq * 2 + 127) / 255;
i2c_smbus_write_byte_data(client, LM63_REG_PWM_VALUE, data->pwm1_value);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -253,10 +254,10 @@ static ssize_t set_temp8(struct device *dev, struct device_attribute *dummy,
struct lm63_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp8[1] = TEMP8_TO_REG(val);
i2c_smbus_write_byte_data(client, LM63_REG_LOCAL_HIGH, data->temp8[1]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -284,13 +285,13 @@ static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr,
long val = simple_strtol(buf, NULL, 10);
int nr = attr->index;
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp11[nr] = TEMP11_TO_REG(val);
i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2],
data->temp11[nr] >> 8);
i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2 + 1],
data->temp11[nr] & 0xff);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -314,11 +315,11 @@ static ssize_t set_temp2_crit_hyst(struct device *dev, struct device_attribute *
long val = simple_strtol(buf, NULL, 10);
long hyst;
down(&data->update_lock);
mutex_lock(&data->update_lock);
hyst = TEMP8_FROM_REG(data->temp8[2]) - val;
i2c_smbus_write_byte_data(client, LM63_REG_REMOTE_TCRIT_HYST,
HYST_TO_REG(hyst));
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -427,7 +428,7 @@ static int lm63_detect(struct i2c_adapter *adapter, int address, int kind)
strlcpy(new_client->name, "lm63", I2C_NAME_SIZE);
data->valid = 0;
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
@ -530,7 +531,7 @@ static struct lm63_data *lm63_update_device(struct device *dev)
struct i2c_client *client = to_i2c_client(dev);
struct lm63_data *data = i2c_get_clientdata(client);
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
if (data->config & 0x04) { /* tachometer enabled */
@ -582,7 +583,7 @@ static struct lm63_data *lm63_update_device(struct device *dev)
data->valid = 1;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return data;
}

View File

@ -25,6 +25,7 @@
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include "lm75.h"
@ -47,7 +48,7 @@ I2C_CLIENT_INSMOD_1(lm75);
struct lm75_data {
struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock;
struct mutex update_lock;
char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */
u16 temp_input; /* Register values */
@ -91,10 +92,10 @@ static ssize_t set_##value(struct device *dev, struct device_attribute *attr, co
struct lm75_data *data = i2c_get_clientdata(client); \
int temp = simple_strtoul(buf, NULL, 10); \
\
down(&data->update_lock); \
mutex_lock(&data->update_lock); \
data->value = LM75_TEMP_TO_REG(temp); \
lm75_write_value(client, reg, data->value); \
up(&data->update_lock); \
mutex_unlock(&data->update_lock); \
return count; \
}
set(temp_max, LM75_REG_TEMP_OS);
@ -188,7 +189,7 @@ static int lm75_detect(struct i2c_adapter *adapter, int address, int kind)
/* Fill in the remaining client fields and put it into the global list */
strlcpy(new_client->name, name, I2C_NAME_SIZE);
data->valid = 0;
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
@ -264,7 +265,7 @@ static struct lm75_data *lm75_update_device(struct device *dev)
struct i2c_client *client = to_i2c_client(dev);
struct lm75_data *data = i2c_get_clientdata(client);
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
|| !data->valid) {
@ -277,7 +278,7 @@ static struct lm75_data *lm75_update_device(struct device *dev)
data->valid = 1;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return data;
}

View File

@ -32,6 +32,7 @@
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/err.h>
#include <linux/mutex.h>
/* Addresses to scan */
static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, I2C_CLIENT_END };
@ -51,7 +52,7 @@ I2C_CLIENT_INSMOD_1(lm77);
struct lm77_data {
struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock;
struct mutex update_lock;
char valid;
unsigned long last_updated; /* In jiffies */
int temp_input; /* Temperatures */
@ -139,10 +140,10 @@ static ssize_t set_##value(struct device *dev, struct device_attribute *attr, co
struct lm77_data *data = i2c_get_clientdata(client); \
long val = simple_strtoul(buf, NULL, 10); \
\
down(&data->update_lock); \
mutex_lock(&data->update_lock); \
data->value = val; \
lm77_write_value(client, reg, LM77_TEMP_TO_REG(data->value)); \
up(&data->update_lock); \
mutex_unlock(&data->update_lock); \
return count; \
}
@ -157,11 +158,11 @@ static ssize_t set_temp_crit_hyst(struct device *dev, struct device_attribute *a
struct lm77_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp_hyst = data->temp_crit - val;
lm77_write_value(client, LM77_REG_TEMP_HYST,
LM77_TEMP_TO_REG(data->temp_hyst));
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -173,7 +174,7 @@ static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr,
long val = simple_strtoul(buf, NULL, 10);
int oldcrithyst;
down(&data->update_lock);
mutex_lock(&data->update_lock);
oldcrithyst = data->temp_crit - data->temp_hyst;
data->temp_crit = val;
data->temp_hyst = data->temp_crit - oldcrithyst;
@ -181,7 +182,7 @@ static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr,
LM77_TEMP_TO_REG(data->temp_crit));
lm77_write_value(client, LM77_REG_TEMP_HYST,
LM77_TEMP_TO_REG(data->temp_hyst));
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -306,7 +307,7 @@ static int lm77_detect(struct i2c_adapter *adapter, int address, int kind)
/* Fill in the remaining client fields and put it into the global list */
strlcpy(new_client->name, name, I2C_NAME_SIZE);
data->valid = 0;
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
@ -380,7 +381,7 @@ static struct lm77_data *lm77_update_device(struct device *dev)
struct i2c_client *client = to_i2c_client(dev);
struct lm77_data *data = i2c_get_clientdata(client);
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
|| !data->valid) {
@ -406,7 +407,7 @@ static struct lm77_data *lm77_update_device(struct device *dev)
data->valid = 1;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return data;
}

View File

@ -27,6 +27,7 @@
#include <linux/hwmon.h>
#include <linux/hwmon-vid.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <asm/io.h>
/* Addresses to scan */
@ -131,10 +132,10 @@ static inline int TEMP_FROM_REG(s8 val)
struct lm78_data {
struct i2c_client client;
struct class_device *class_dev;
struct semaphore lock;
struct mutex lock;
enum chips type;
struct semaphore update_lock;
struct mutex update_lock;
char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */
@ -157,8 +158,8 @@ static int lm78_isa_attach_adapter(struct i2c_adapter *adapter);
static int lm78_detect(struct i2c_adapter *adapter, int address, int kind);
static int lm78_detach_client(struct i2c_client *client);
static int lm78_read_value(struct i2c_client *client, u8 register);
static int lm78_write_value(struct i2c_client *client, u8 register, u8 value);
static int lm78_read_value(struct i2c_client *client, u8 reg);
static int lm78_write_value(struct i2c_client *client, u8 reg, u8 value);
static struct lm78_data *lm78_update_device(struct device *dev);
static void lm78_init_client(struct i2c_client *client);
@ -207,10 +208,10 @@ static ssize_t set_in_min(struct device *dev, const char *buf,
struct lm78_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->in_min[nr] = IN_TO_REG(val);
lm78_write_value(client, LM78_REG_IN_MIN(nr), data->in_min[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -221,10 +222,10 @@ static ssize_t set_in_max(struct device *dev, const char *buf,
struct lm78_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->in_max[nr] = IN_TO_REG(val);
lm78_write_value(client, LM78_REG_IN_MAX(nr), data->in_max[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -288,10 +289,10 @@ static ssize_t set_temp_over(struct device *dev, struct device_attribute *attr,
struct lm78_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp_over = TEMP_TO_REG(val);
lm78_write_value(client, LM78_REG_TEMP_OVER, data->temp_over);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -307,10 +308,10 @@ static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *attr,
struct lm78_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp_hyst = TEMP_TO_REG(val);
lm78_write_value(client, LM78_REG_TEMP_HYST, data->temp_hyst);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -342,10 +343,10 @@ static ssize_t set_fan_min(struct device *dev, const char *buf,
struct lm78_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
lm78_write_value(client, LM78_REG_FAN_MIN(nr), data->fan_min[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -368,7 +369,7 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
unsigned long min;
u8 reg;
down(&data->update_lock);
mutex_lock(&data->update_lock);
min = FAN_FROM_REG(data->fan_min[nr],
DIV_FROM_REG(data->fan_div[nr]));
@ -380,7 +381,7 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
default:
dev_err(&client->dev, "fan_div value %ld not "
"supported. Choose one of 1, 2, 4 or 8!\n", val);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return -EINVAL;
}
@ -398,7 +399,7 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
data->fan_min[nr] =
FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
lm78_write_value(client, LM78_REG_FAN_MIN(nr), data->fan_min[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -548,7 +549,7 @@ static int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
new_client = &data->client;
if (is_isa)
init_MUTEX(&data->lock);
mutex_init(&data->lock);
i2c_set_clientdata(new_client, data);
new_client->addr = address;
new_client->adapter = adapter;
@ -598,7 +599,7 @@ static int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
data->type = kind;
data->valid = 0;
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
@ -697,10 +698,10 @@ static int lm78_read_value(struct i2c_client *client, u8 reg)
int res;
if (i2c_is_isa_client(client)) {
struct lm78_data *data = i2c_get_clientdata(client);
down(&data->lock);
mutex_lock(&data->lock);
outb_p(reg, client->addr + LM78_ADDR_REG_OFFSET);
res = inb_p(client->addr + LM78_DATA_REG_OFFSET);
up(&data->lock);
mutex_unlock(&data->lock);
return res;
} else
return i2c_smbus_read_byte_data(client, reg);
@ -717,10 +718,10 @@ static int lm78_write_value(struct i2c_client *client, u8 reg, u8 value)
{
if (i2c_is_isa_client(client)) {
struct lm78_data *data = i2c_get_clientdata(client);
down(&data->lock);
mutex_lock(&data->lock);
outb_p(reg, client->addr + LM78_ADDR_REG_OFFSET);
outb_p(value, client->addr + LM78_DATA_REG_OFFSET);
up(&data->lock);
mutex_unlock(&data->lock);
return 0;
} else
return i2c_smbus_write_byte_data(client, reg, value);
@ -742,7 +743,7 @@ static struct lm78_data *lm78_update_device(struct device *dev)
struct lm78_data *data = i2c_get_clientdata(client);
int i;
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
|| !data->valid) {
@ -786,7 +787,7 @@ static struct lm78_data *lm78_update_device(struct device *dev)
data->fan_div[2] = 1;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return data;
}

View File

@ -28,6 +28,7 @@
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/err.h>
#include <linux/mutex.h>
/* Addresses to scan */
static unsigned short normal_i2c[] = { 0x28, 0x29, 0x2a, 0x2b, 0x2c,
@ -108,7 +109,7 @@ static inline long TEMP_FROM_REG(u16 temp)
struct lm80_data {
struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock;
struct mutex update_lock;
char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */
@ -191,10 +192,10 @@ static ssize_t set_in_##suffix(struct device *dev, struct device_attribute *attr
struct lm80_data *data = i2c_get_clientdata(client); \
long val = simple_strtol(buf, NULL, 10); \
\
down(&data->update_lock);\
mutex_lock(&data->update_lock);\
data->value = IN_TO_REG(val); \
lm80_write_value(client, reg, data->value); \
up(&data->update_lock);\
mutex_unlock(&data->update_lock);\
return count; \
}
set_in(min0, in_min[0], LM80_REG_IN_MIN(0));
@ -241,10 +242,10 @@ static ssize_t set_fan_##suffix(struct device *dev, struct device_attribute *att
struct lm80_data *data = i2c_get_clientdata(client); \
long val = simple_strtoul(buf, NULL, 10); \
\
down(&data->update_lock);\
mutex_lock(&data->update_lock);\
data->value = FAN_TO_REG(val, DIV_FROM_REG(data->div)); \
lm80_write_value(client, reg, data->value); \
up(&data->update_lock);\
mutex_unlock(&data->update_lock);\
return count; \
}
set_fan(min1, fan_min[0], LM80_REG_FAN_MIN(1), fan_div[0]);
@ -263,7 +264,7 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
u8 reg;
/* Save fan_min */
down(&data->update_lock);
mutex_lock(&data->update_lock);
min = FAN_FROM_REG(data->fan_min[nr],
DIV_FROM_REG(data->fan_div[nr]));
@ -275,7 +276,7 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
default:
dev_err(&client->dev, "fan_div value %ld not "
"supported. Choose one of 1, 2, 4 or 8!\n", val);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return -EINVAL;
}
@ -286,7 +287,7 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
/* Restore fan_min */
data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
lm80_write_value(client, LM80_REG_FAN_MIN(nr + 1), data->fan_min[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -325,10 +326,10 @@ static ssize_t set_temp_##suffix(struct device *dev, struct device_attribute *at
struct lm80_data *data = i2c_get_clientdata(client); \
long val = simple_strtoul(buf, NULL, 10); \
\
down(&data->update_lock); \
mutex_lock(&data->update_lock); \
data->value = TEMP_LIMIT_TO_REG(val); \
lm80_write_value(client, reg, data->value); \
up(&data->update_lock); \
mutex_unlock(&data->update_lock); \
return count; \
}
set_temp(hot_max, temp_hot_max, LM80_REG_TEMP_HOT_MAX);
@ -437,7 +438,7 @@ static int lm80_detect(struct i2c_adapter *adapter, int address, int kind)
/* Fill in the remaining client fields and put it into the global list */
strlcpy(new_client->name, name, I2C_NAME_SIZE);
data->valid = 0;
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
@ -545,7 +546,7 @@ static struct lm80_data *lm80_update_device(struct device *dev)
struct lm80_data *data = i2c_get_clientdata(client);
int i;
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) {
dev_dbg(&client->dev, "Starting lm80 update\n");
@ -585,7 +586,7 @@ static struct lm80_data *lm80_update_device(struct device *dev)
data->valid = 1;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return data;
}

View File

@ -35,6 +35,7 @@
#include <linux/hwmon-sysfs.h>
#include <linux/hwmon.h>
#include <linux/err.h>
#include <linux/mutex.h>
/*
* Addresses to scan
@ -139,7 +140,7 @@ static struct i2c_driver lm83_driver = {
struct lm83_data {
struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock;
struct mutex update_lock;
char valid; /* zero until following fields are valid */
unsigned long last_updated; /* in jiffies */
@ -171,11 +172,11 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *devattr,
long val = simple_strtol(buf, NULL, 10);
int nr = attr->index;
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp[nr] = TEMP_TO_REG(val);
i2c_smbus_write_byte_data(client, LM83_REG_W_HIGH[nr - 4],
data->temp[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -300,7 +301,7 @@ static int lm83_detect(struct i2c_adapter *adapter, int address, int kind)
/* We can fill in the remaining client fields */
strlcpy(new_client->name, name, I2C_NAME_SIZE);
data->valid = 0;
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
@ -373,7 +374,7 @@ static struct lm83_data *lm83_update_device(struct device *dev)
struct i2c_client *client = to_i2c_client(dev);
struct lm83_data *data = i2c_get_clientdata(client);
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) {
int nr;
@ -393,7 +394,7 @@ static struct lm83_data *lm83_update_device(struct device *dev)
data->valid = 1;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return data;
}

View File

@ -31,6 +31,7 @@
#include <linux/hwmon.h>
#include <linux/hwmon-vid.h>
#include <linux/err.h>
#include <linux/mutex.h>
/* Addresses to scan */
static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, I2C_CLIENT_END };
@ -331,10 +332,10 @@ struct lm85_autofan {
struct lm85_data {
struct i2c_client client;
struct class_device *class_dev;
struct semaphore lock;
struct mutex lock;
enum chips type;
struct semaphore update_lock;
struct mutex update_lock;
int valid; /* !=0 if following fields are valid */
unsigned long last_reading; /* In jiffies */
unsigned long last_config; /* In jiffies */
@ -373,8 +374,8 @@ static int lm85_detect(struct i2c_adapter *adapter, int address,
int kind);
static int lm85_detach_client(struct i2c_client *client);
static int lm85_read_value(struct i2c_client *client, u8 register);
static int lm85_write_value(struct i2c_client *client, u8 register, int value);
static int lm85_read_value(struct i2c_client *client, u8 reg);
static int lm85_write_value(struct i2c_client *client, u8 reg, int value);
static struct lm85_data *lm85_update_device(struct device *dev);
static void lm85_init_client(struct i2c_client *client);
@ -407,10 +408,10 @@ static ssize_t set_fan_min(struct device *dev, const char *buf,
struct lm85_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->fan_min[nr] = FAN_TO_REG(val);
lm85_write_value(client, LM85_REG_FAN_MIN(nr), data->fan_min[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -499,10 +500,10 @@ static ssize_t set_pwm(struct device *dev, const char *buf,
struct lm85_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->pwm[nr] = PWM_TO_REG(val);
lm85_write_value(client, LM85_REG_PWM(nr), data->pwm[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t show_pwm_enable(struct device *dev, char *buf, int nr)
@ -559,10 +560,10 @@ static ssize_t set_in_min(struct device *dev, const char *buf,
struct lm85_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->in_min[nr] = INS_TO_REG(nr, val);
lm85_write_value(client, LM85_REG_IN_MIN(nr), data->in_min[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t show_in_max(struct device *dev, char *buf, int nr)
@ -577,10 +578,10 @@ static ssize_t set_in_max(struct device *dev, const char *buf,
struct lm85_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->in_max[nr] = INS_TO_REG(nr, val);
lm85_write_value(client, LM85_REG_IN_MAX(nr), data->in_max[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
#define show_in_reg(offset) \
@ -640,10 +641,10 @@ static ssize_t set_temp_min(struct device *dev, const char *buf,
struct lm85_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp_min[nr] = TEMP_TO_REG(val);
lm85_write_value(client, LM85_REG_TEMP_MIN(nr), data->temp_min[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t show_temp_max(struct device *dev, char *buf, int nr)
@ -658,10 +659,10 @@ static ssize_t set_temp_max(struct device *dev, const char *buf,
struct lm85_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp_max[nr] = TEMP_TO_REG(val);
lm85_write_value(client, LM85_REG_TEMP_MAX(nr), data->temp_max[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
#define show_temp_reg(offset) \
@ -713,12 +714,12 @@ static ssize_t set_pwm_auto_channels(struct device *dev, const char *buf,
struct lm85_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->autofan[nr].config = (data->autofan[nr].config & (~0xe0))
| ZONE_TO_REG(val) ;
lm85_write_value(client, LM85_REG_AFAN_CONFIG(nr),
data->autofan[nr].config);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t show_pwm_auto_pwm_min(struct device *dev, char *buf, int nr)
@ -733,11 +734,11 @@ static ssize_t set_pwm_auto_pwm_min(struct device *dev, const char *buf,
struct lm85_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->autofan[nr].min_pwm = PWM_TO_REG(val);
lm85_write_value(client, LM85_REG_AFAN_MINPWM(nr),
data->autofan[nr].min_pwm);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t show_pwm_auto_pwm_minctl(struct device *dev, char *buf, int nr)
@ -752,7 +753,7 @@ static ssize_t set_pwm_auto_pwm_minctl(struct device *dev, const char *buf,
struct lm85_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->autofan[nr].min_off = val;
lm85_write_value(client, LM85_REG_AFAN_SPIKE1, data->smooth[0]
| data->syncpwm3
@ -760,7 +761,7 @@ static ssize_t set_pwm_auto_pwm_minctl(struct device *dev, const char *buf,
| (data->autofan[1].min_off ? 0x40 : 0)
| (data->autofan[2].min_off ? 0x80 : 0)
);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t show_pwm_auto_pwm_freq(struct device *dev, char *buf, int nr)
@ -775,13 +776,13 @@ static ssize_t set_pwm_auto_pwm_freq(struct device *dev, const char *buf,
struct lm85_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->autofan[nr].freq = FREQ_TO_REG(val);
lm85_write_value(client, LM85_REG_AFAN_RANGE(nr),
(data->zone[nr].range << 4)
| data->autofan[nr].freq
);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
#define pwm_auto(offset) \
@ -857,7 +858,7 @@ static ssize_t set_temp_auto_temp_off(struct device *dev, const char *buf,
int min;
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
min = TEMP_FROM_REG(data->zone[nr].limit);
data->zone[nr].off_desired = TEMP_TO_REG(val);
data->zone[nr].hyst = HYST_TO_REG(min - val);
@ -871,7 +872,7 @@ static ssize_t set_temp_auto_temp_off(struct device *dev, const char *buf,
(data->zone[2].hyst << 4)
);
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t show_temp_auto_temp_min(struct device *dev, char *buf, int nr)
@ -886,7 +887,7 @@ static ssize_t set_temp_auto_temp_min(struct device *dev, const char *buf,
struct lm85_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->zone[nr].limit = TEMP_TO_REG(val);
lm85_write_value(client, LM85_REG_AFAN_LIMIT(nr),
data->zone[nr].limit);
@ -913,7 +914,7 @@ static ssize_t set_temp_auto_temp_min(struct device *dev, const char *buf,
(data->zone[2].hyst << 4)
);
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t show_temp_auto_temp_max(struct device *dev, char *buf, int nr)
@ -930,7 +931,7 @@ static ssize_t set_temp_auto_temp_max(struct device *dev, const char *buf,
int min;
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
min = TEMP_FROM_REG(data->zone[nr].limit);
data->zone[nr].max_desired = TEMP_TO_REG(val);
data->zone[nr].range = RANGE_TO_REG(
@ -938,7 +939,7 @@ static ssize_t set_temp_auto_temp_max(struct device *dev, const char *buf,
lm85_write_value(client, LM85_REG_AFAN_RANGE(nr),
((data->zone[nr].range & 0x0f) << 4)
| (data->autofan[nr].freq & 0x07));
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t show_temp_auto_temp_crit(struct device *dev, char *buf, int nr)
@ -953,11 +954,11 @@ static ssize_t set_temp_auto_temp_crit(struct device *dev, const char *buf,
struct lm85_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->zone[nr].critical = TEMP_TO_REG(val);
lm85_write_value(client, LM85_REG_AFAN_CRITICAL(nr),
data->zone[nr].critical);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
#define temp_auto(offset) \
@ -1149,7 +1150,7 @@ static int lm85_detect(struct i2c_adapter *adapter, int address,
/* Fill in the remaining client fields */
data->type = kind;
data->valid = 0;
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
@ -1368,7 +1369,7 @@ static struct lm85_data *lm85_update_device(struct device *dev)
struct lm85_data *data = i2c_get_clientdata(client);
int i;
down(&data->update_lock);
mutex_lock(&data->update_lock);
if ( !data->valid ||
time_after(jiffies, data->last_reading + LM85_DATA_INTERVAL) ) {
@ -1571,7 +1572,7 @@ static struct lm85_data *lm85_update_device(struct device *dev)
data->valid = 1;
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return data;
}

View File

@ -60,6 +60,7 @@
#include <linux/hwmon.h>
#include <linux/hwmon-vid.h>
#include <linux/err.h>
#include <linux/mutex.h>
/*
* Addresses to scan
@ -176,7 +177,7 @@ static struct i2c_driver lm87_driver = {
struct lm87_data {
struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock;
struct mutex update_lock;
char valid; /* zero until following fields are valid */
unsigned long last_updated; /* In jiffies */
@ -253,11 +254,11 @@ static void set_in_min(struct device *dev, const char *buf, int nr)
struct lm87_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->in_min[nr] = IN_TO_REG(val, data->in_scale[nr]);
lm87_write_value(client, nr<6 ? LM87_REG_IN_MIN(nr) :
LM87_REG_AIN_MIN(nr-6), data->in_min[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
}
static void set_in_max(struct device *dev, const char *buf, int nr)
@ -266,11 +267,11 @@ static void set_in_max(struct device *dev, const char *buf, int nr)
struct lm87_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->in_max[nr] = IN_TO_REG(val, data->in_scale[nr]);
lm87_write_value(client, nr<6 ? LM87_REG_IN_MAX(nr) :
LM87_REG_AIN_MAX(nr-6), data->in_max[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
}
#define set_in(offset) \
@ -327,10 +328,10 @@ static void set_temp_low(struct device *dev, const char *buf, int nr)
struct lm87_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp_low[nr] = TEMP_TO_REG(val);
lm87_write_value(client, LM87_REG_TEMP_LOW[nr], data->temp_low[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
}
static void set_temp_high(struct device *dev, const char *buf, int nr)
@ -339,10 +340,10 @@ static void set_temp_high(struct device *dev, const char *buf, int nr)
struct lm87_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp_high[nr] = TEMP_TO_REG(val);
lm87_write_value(client, LM87_REG_TEMP_HIGH[nr], data->temp_high[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
}
#define set_temp(offset) \
@ -411,11 +412,11 @@ static void set_fan_min(struct device *dev, const char *buf, int nr)
struct lm87_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->fan_min[nr] = FAN_TO_REG(val,
FAN_DIV_FROM_REG(data->fan_div[nr]));
lm87_write_value(client, LM87_REG_FAN_MIN(nr), data->fan_min[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
}
/* Note: we save and restore the fan minimum here, because its value is
@ -431,7 +432,7 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
unsigned long min;
u8 reg;
down(&data->update_lock);
mutex_lock(&data->update_lock);
min = FAN_FROM_REG(data->fan_min[nr],
FAN_DIV_FROM_REG(data->fan_div[nr]));
@ -441,7 +442,7 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
case 4: data->fan_div[nr] = 2; break;
case 8: data->fan_div[nr] = 3; break;
default:
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return -EINVAL;
}
@ -459,7 +460,7 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
data->fan_min[nr] = FAN_TO_REG(min, val);
lm87_write_value(client, LM87_REG_FAN_MIN(nr),
data->fan_min[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -522,10 +523,10 @@ static ssize_t set_aout(struct device *dev, struct device_attribute *attr, const
struct lm87_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->aout = AOUT_TO_REG(val);
lm87_write_value(client, LM87_REG_AOUT, data->aout);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
static DEVICE_ATTR(aout_output, S_IRUGO | S_IWUSR, show_aout, set_aout);
@ -589,7 +590,7 @@ static int lm87_detect(struct i2c_adapter *adapter, int address, int kind)
/* We can fill in the remaining client fields */
strlcpy(new_client->name, "lm87", I2C_NAME_SIZE);
data->valid = 0;
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
@ -744,7 +745,7 @@ static struct lm87_data *lm87_update_device(struct device *dev)
struct i2c_client *client = to_i2c_client(dev);
struct lm87_data *data = i2c_get_clientdata(client);
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
int i, j;
@ -813,7 +814,7 @@ static struct lm87_data *lm87_update_device(struct device *dev)
data->valid = 1;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return data;
}

View File

@ -78,6 +78,7 @@
#include <linux/hwmon-sysfs.h>
#include <linux/hwmon.h>
#include <linux/err.h>
#include <linux/mutex.h>
/*
* Addresses to scan
@ -201,7 +202,7 @@ static struct i2c_driver lm90_driver = {
struct lm90_data {
struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock;
struct mutex update_lock;
char valid; /* zero until following fields are valid */
unsigned long last_updated; /* in jiffies */
int kind;
@ -247,13 +248,13 @@ static ssize_t set_temp8(struct device *dev, struct device_attribute *devattr,
long val = simple_strtol(buf, NULL, 10);
int nr = attr->index;
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (data->kind == adt7461)
data->temp8[nr] = TEMP1_TO_REG_ADT7461(val);
else
data->temp8[nr] = TEMP1_TO_REG(val);
i2c_smbus_write_byte_data(client, reg[nr - 1], data->temp8[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -281,7 +282,7 @@ static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr,
long val = simple_strtol(buf, NULL, 10);
int nr = attr->index;
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (data->kind == adt7461)
data->temp11[nr] = TEMP2_TO_REG_ADT7461(val);
else
@ -290,7 +291,7 @@ static ssize_t set_temp11(struct device *dev, struct device_attribute *devattr,
data->temp11[nr] >> 8);
i2c_smbus_write_byte_data(client, reg[(nr - 1) * 2 + 1],
data->temp11[nr] & 0xff);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -311,11 +312,11 @@ static ssize_t set_temphyst(struct device *dev, struct device_attribute *dummy,
long val = simple_strtol(buf, NULL, 10);
long hyst;
down(&data->update_lock);
mutex_lock(&data->update_lock);
hyst = TEMP1_FROM_REG(data->temp8[3]) - val;
i2c_smbus_write_byte_data(client, LM90_REG_W_TCRIT_HYST,
HYST_TO_REG(hyst));
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -558,7 +559,7 @@ static int lm90_detect(struct i2c_adapter *adapter, int address, int kind)
strlcpy(new_client->name, name, I2C_NAME_SIZE);
data->valid = 0;
data->kind = kind;
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
@ -646,7 +647,7 @@ static struct lm90_data *lm90_update_device(struct device *dev)
struct i2c_client *client = to_i2c_client(dev);
struct lm90_data *data = i2c_get_clientdata(client);
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) {
u8 oldh, newh, l;
@ -692,7 +693,7 @@ static struct lm90_data *lm90_update_device(struct device *dev)
data->valid = 1;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return data;
}

View File

@ -46,6 +46,7 @@
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/err.h>
#include <linux/mutex.h>
/* The LM92 and MAX6635 have 2 two-state pins for address selection,
resulting in 4 possible addresses. */
@ -96,7 +97,7 @@ static struct i2c_driver lm92_driver;
struct lm92_data {
struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock;
struct mutex update_lock;
char valid; /* zero until following fields are valid */
unsigned long last_updated; /* in jiffies */
@ -114,7 +115,7 @@ static struct lm92_data *lm92_update_device(struct device *dev)
struct i2c_client *client = to_i2c_client(dev);
struct lm92_data *data = i2c_get_clientdata(client);
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ)
|| !data->valid) {
@ -134,7 +135,7 @@ static struct lm92_data *lm92_update_device(struct device *dev)
data->valid = 1;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return data;
}
@ -158,10 +159,10 @@ static ssize_t set_##value(struct device *dev, struct device_attribute *attr, co
struct lm92_data *data = i2c_get_clientdata(client); \
long val = simple_strtol(buf, NULL, 10); \
\
down(&data->update_lock); \
mutex_lock(&data->update_lock); \
data->value = TEMP_TO_REG(val); \
i2c_smbus_write_word_data(client, reg, swab16(data->value)); \
up(&data->update_lock); \
mutex_unlock(&data->update_lock); \
return count; \
}
set_temp(temp1_crit, LM92_REG_TEMP_CRIT);
@ -194,11 +195,11 @@ static ssize_t set_temp1_crit_hyst(struct device *dev, struct device_attribute *
struct lm92_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp1_hyst = TEMP_FROM_REG(data->temp1_crit) - val;
i2c_smbus_write_word_data(client, LM92_REG_TEMP_HYST,
swab16(TEMP_TO_REG(data->temp1_hyst)));
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -348,7 +349,7 @@ static int lm92_detect(struct i2c_adapter *adapter, int address, int kind)
/* Fill in the remaining client fields */
strlcpy(new_client->name, name, I2C_NAME_SIZE);
data->valid = 0;
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
/* Tell the i2c subsystem a new client has arrived */
if ((err = i2c_attach_client(new_client)))

View File

@ -33,6 +33,7 @@
#include <linux/i2c.h>
#include <linux/hwmon.h>
#include <linux/err.h>
#include <linux/mutex.h>
static unsigned short normal_i2c[] = { 0x18, 0x19, 0x1a,
0x29, 0x2a, 0x2b,
@ -104,7 +105,7 @@ static struct i2c_driver max1619_driver = {
struct max1619_data {
struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock;
struct mutex update_lock;
char valid; /* zero until following fields are valid */
unsigned long last_updated; /* in jiffies */
@ -141,10 +142,10 @@ static ssize_t set_##value(struct device *dev, struct device_attribute *attr, co
struct max1619_data *data = i2c_get_clientdata(client); \
long val = simple_strtol(buf, NULL, 10); \
\
down(&data->update_lock); \
mutex_lock(&data->update_lock); \
data->value = TEMP_TO_REG(val); \
i2c_smbus_write_byte_data(client, reg, data->value); \
up(&data->update_lock); \
mutex_unlock(&data->update_lock); \
return count; \
}
@ -262,7 +263,7 @@ static int max1619_detect(struct i2c_adapter *adapter, int address, int kind)
/* We can fill in the remaining client fields */
strlcpy(new_client->name, name, I2C_NAME_SIZE);
data->valid = 0;
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
@ -330,7 +331,7 @@ static struct max1619_data *max1619_update_device(struct device *dev)
struct i2c_client *client = to_i2c_client(dev);
struct max1619_data *data = i2c_get_clientdata(client);
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) {
dev_dbg(&client->dev, "Updating max1619 data.\n");
@ -353,7 +354,7 @@ static struct max1619_data *max1619_update_device(struct device *dev)
data->valid = 1;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return data;
}

View File

@ -43,6 +43,7 @@
#include <linux/hwmon-sysfs.h>
#include <linux/hwmon-vid.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <asm/io.h>
static u8 devid;
@ -183,8 +184,8 @@ static inline u8 PWM_TO_REG(int val, int inv)
struct pc87360_data {
struct i2c_client client;
struct class_device *class_dev;
struct semaphore lock;
struct semaphore update_lock;
struct mutex lock;
struct mutex update_lock;
char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */
@ -283,7 +284,7 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *devattr,
struct pc87360_data *data = i2c_get_clientdata(client);
long fan_min = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
fan_min = FAN_TO_REG(fan_min, FAN_DIV_FROM_REG(data->fan_status[attr->index]));
/* If it wouldn't fit, change clock divisor */
@ -300,23 +301,31 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *devattr,
/* Write new divider, preserve alarm bits */
pc87360_write_value(data, LD_FAN, NO_BANK, PC87360_REG_FAN_STATUS(attr->index),
data->fan_status[attr->index] & 0xF9);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
#define show_and_set_fan(offset) \
static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, \
show_fan_input, NULL, offset-1); \
static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IWUSR | S_IRUGO, \
show_fan_min, set_fan_min, offset-1); \
static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO, \
show_fan_div, NULL, offset-1); \
static SENSOR_DEVICE_ATTR(fan##offset##_status, S_IRUGO, \
show_fan_status, NULL, offset-1);
show_and_set_fan(1)
show_and_set_fan(2)
show_and_set_fan(3)
static struct sensor_device_attribute fan_input[] = {
SENSOR_ATTR(fan1_input, S_IRUGO, show_fan_input, NULL, 0),
SENSOR_ATTR(fan2_input, S_IRUGO, show_fan_input, NULL, 1),
SENSOR_ATTR(fan3_input, S_IRUGO, show_fan_input, NULL, 2),
};
static struct sensor_device_attribute fan_status[] = {
SENSOR_ATTR(fan1_status, S_IRUGO, show_fan_status, NULL, 0),
SENSOR_ATTR(fan2_status, S_IRUGO, show_fan_status, NULL, 1),
SENSOR_ATTR(fan3_status, S_IRUGO, show_fan_status, NULL, 2),
};
static struct sensor_device_attribute fan_div[] = {
SENSOR_ATTR(fan1_div, S_IRUGO, show_fan_div, NULL, 0),
SENSOR_ATTR(fan2_div, S_IRUGO, show_fan_div, NULL, 1),
SENSOR_ATTR(fan3_div, S_IRUGO, show_fan_div, NULL, 2),
};
static struct sensor_device_attribute fan_min[] = {
SENSOR_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min, set_fan_min, 0),
SENSOR_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min, set_fan_min, 1),
SENSOR_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min, set_fan_min, 2),
};
static ssize_t show_pwm(struct device *dev, struct device_attribute *devattr, char *buf)
{
@ -335,21 +344,20 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr, con
struct pc87360_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->pwm[attr->index] = PWM_TO_REG(val,
FAN_CONFIG_INVERT(data->fan_conf, attr->index));
pc87360_write_value(data, LD_FAN, NO_BANK, PC87360_REG_PWM(attr->index),
data->pwm[attr->index]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
#define show_and_set_pwm(offset) \
static SENSOR_DEVICE_ATTR(pwm##offset, S_IWUSR | S_IRUGO, \
show_pwm, set_pwm, offset-1);
show_and_set_pwm(1)
show_and_set_pwm(2)
show_and_set_pwm(3)
static struct sensor_device_attribute pwm[] = {
SENSOR_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 0),
SENSOR_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 1),
SENSOR_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, set_pwm, 2),
};
static ssize_t show_in_input(struct device *dev, struct device_attribute *devattr, char *buf)
{
@ -386,11 +394,11 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *devattr,
struct pc87360_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->in_min[attr->index] = IN_TO_REG(val, data->in_vref);
pc87360_write_value(data, LD_IN, attr->index, PC87365_REG_IN_MIN,
data->in_min[attr->index]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t set_in_max(struct device *dev, struct device_attribute *devattr, const char *buf,
@ -401,35 +409,67 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *devattr,
struct pc87360_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->in_max[attr->index] = IN_TO_REG(val,
data->in_vref);
pc87360_write_value(data, LD_IN, attr->index, PC87365_REG_IN_MAX,
data->in_max[attr->index]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
#define show_and_set_in(offset) \
static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, \
show_in_input, NULL, offset); \
static SENSOR_DEVICE_ATTR(in##offset##_min, S_IWUSR | S_IRUGO, \
show_in_min, set_in_min, offset); \
static SENSOR_DEVICE_ATTR(in##offset##_max, S_IWUSR | S_IRUGO, \
show_in_max, set_in_max, offset); \
static SENSOR_DEVICE_ATTR(in##offset##_status, S_IRUGO, \
show_in_status, NULL, offset);
show_and_set_in(0)
show_and_set_in(1)
show_and_set_in(2)
show_and_set_in(3)
show_and_set_in(4)
show_and_set_in(5)
show_and_set_in(6)
show_and_set_in(7)
show_and_set_in(8)
show_and_set_in(9)
show_and_set_in(10)
static struct sensor_device_attribute in_input[] = {
SENSOR_ATTR(in0_input, S_IRUGO, show_in_input, NULL, 0),
SENSOR_ATTR(in1_input, S_IRUGO, show_in_input, NULL, 1),
SENSOR_ATTR(in2_input, S_IRUGO, show_in_input, NULL, 2),
SENSOR_ATTR(in3_input, S_IRUGO, show_in_input, NULL, 3),
SENSOR_ATTR(in4_input, S_IRUGO, show_in_input, NULL, 4),
SENSOR_ATTR(in5_input, S_IRUGO, show_in_input, NULL, 5),
SENSOR_ATTR(in6_input, S_IRUGO, show_in_input, NULL, 6),
SENSOR_ATTR(in7_input, S_IRUGO, show_in_input, NULL, 7),
SENSOR_ATTR(in8_input, S_IRUGO, show_in_input, NULL, 8),
SENSOR_ATTR(in9_input, S_IRUGO, show_in_input, NULL, 9),
SENSOR_ATTR(in10_input, S_IRUGO, show_in_input, NULL, 10),
};
static struct sensor_device_attribute in_status[] = {
SENSOR_ATTR(in0_status, S_IRUGO, show_in_status, NULL, 0),
SENSOR_ATTR(in1_status, S_IRUGO, show_in_status, NULL, 1),
SENSOR_ATTR(in2_status, S_IRUGO, show_in_status, NULL, 2),
SENSOR_ATTR(in3_status, S_IRUGO, show_in_status, NULL, 3),
SENSOR_ATTR(in4_status, S_IRUGO, show_in_status, NULL, 4),
SENSOR_ATTR(in5_status, S_IRUGO, show_in_status, NULL, 5),
SENSOR_ATTR(in6_status, S_IRUGO, show_in_status, NULL, 6),
SENSOR_ATTR(in7_status, S_IRUGO, show_in_status, NULL, 7),
SENSOR_ATTR(in8_status, S_IRUGO, show_in_status, NULL, 8),
SENSOR_ATTR(in9_status, S_IRUGO, show_in_status, NULL, 9),
SENSOR_ATTR(in10_status, S_IRUGO, show_in_status, NULL, 10),
};
static struct sensor_device_attribute in_min[] = {
SENSOR_ATTR(in0_min, S_IWUSR | S_IRUGO, show_in_min, set_in_min, 0),
SENSOR_ATTR(in1_min, S_IWUSR | S_IRUGO, show_in_min, set_in_min, 1),
SENSOR_ATTR(in2_min, S_IWUSR | S_IRUGO, show_in_min, set_in_min, 2),
SENSOR_ATTR(in3_min, S_IWUSR | S_IRUGO, show_in_min, set_in_min, 3),
SENSOR_ATTR(in4_min, S_IWUSR | S_IRUGO, show_in_min, set_in_min, 4),
SENSOR_ATTR(in5_min, S_IWUSR | S_IRUGO, show_in_min, set_in_min, 5),
SENSOR_ATTR(in6_min, S_IWUSR | S_IRUGO, show_in_min, set_in_min, 6),
SENSOR_ATTR(in7_min, S_IWUSR | S_IRUGO, show_in_min, set_in_min, 7),
SENSOR_ATTR(in8_min, S_IWUSR | S_IRUGO, show_in_min, set_in_min, 8),
SENSOR_ATTR(in9_min, S_IWUSR | S_IRUGO, show_in_min, set_in_min, 9),
SENSOR_ATTR(in10_min, S_IWUSR | S_IRUGO, show_in_min, set_in_min, 10),
};
static struct sensor_device_attribute in_max[] = {
SENSOR_ATTR(in0_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 0),
SENSOR_ATTR(in1_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 1),
SENSOR_ATTR(in2_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 2),
SENSOR_ATTR(in3_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 3),
SENSOR_ATTR(in4_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 4),
SENSOR_ATTR(in5_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 5),
SENSOR_ATTR(in6_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 6),
SENSOR_ATTR(in7_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 7),
SENSOR_ATTR(in8_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 8),
SENSOR_ATTR(in9_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 9),
SENSOR_ATTR(in10_max, S_IWUSR | S_IRUGO, show_in_max, set_in_max, 10),
};
static ssize_t show_therm_input(struct device *dev, struct device_attribute *devattr, char *buf)
{
@ -473,11 +513,11 @@ static ssize_t set_therm_min(struct device *dev, struct device_attribute *devatt
struct pc87360_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->in_min[attr->index] = IN_TO_REG(val, data->in_vref);
pc87360_write_value(data, LD_IN, attr->index, PC87365_REG_TEMP_MIN,
data->in_min[attr->index]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t set_therm_max(struct device *dev, struct device_attribute *devattr, const char *buf,
@ -488,11 +528,11 @@ static ssize_t set_therm_max(struct device *dev, struct device_attribute *devatt
struct pc87360_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->in_max[attr->index] = IN_TO_REG(val, data->in_vref);
pc87360_write_value(data, LD_IN, attr->index, PC87365_REG_TEMP_MAX,
data->in_max[attr->index]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t set_therm_crit(struct device *dev, struct device_attribute *devattr, const char *buf,
@ -503,28 +543,51 @@ static ssize_t set_therm_crit(struct device *dev, struct device_attribute *devat
struct pc87360_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->in_crit[attr->index-11] = IN_TO_REG(val, data->in_vref);
pc87360_write_value(data, LD_IN, attr->index, PC87365_REG_TEMP_CRIT,
data->in_crit[attr->index-11]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
#define show_and_set_therm(offset) \
static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \
show_therm_input, NULL, 11+offset-4); \
static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IWUSR | S_IRUGO, \
show_therm_min, set_therm_min, 11+offset-4); \
static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IWUSR | S_IRUGO, \
show_therm_max, set_therm_max, 11+offset-4); \
static SENSOR_DEVICE_ATTR(temp##offset##_crit, S_IWUSR | S_IRUGO, \
show_therm_crit, set_therm_crit, 11+offset-4); \
static SENSOR_DEVICE_ATTR(temp##offset##_status, S_IRUGO, \
show_therm_status, NULL, 11+offset-4);
show_and_set_therm(4)
show_and_set_therm(5)
show_and_set_therm(6)
/* the +11 term below reflects the fact that VLM units 11,12,13 are
used in the chip to measure voltage across the thermistors
*/
static struct sensor_device_attribute therm_input[] = {
SENSOR_ATTR(temp4_input, S_IRUGO, show_therm_input, NULL, 0+11),
SENSOR_ATTR(temp5_input, S_IRUGO, show_therm_input, NULL, 1+11),
SENSOR_ATTR(temp6_input, S_IRUGO, show_therm_input, NULL, 2+11),
};
static struct sensor_device_attribute therm_status[] = {
SENSOR_ATTR(temp4_status, S_IRUGO, show_therm_status, NULL, 0+11),
SENSOR_ATTR(temp5_status, S_IRUGO, show_therm_status, NULL, 1+11),
SENSOR_ATTR(temp6_status, S_IRUGO, show_therm_status, NULL, 2+11),
};
static struct sensor_device_attribute therm_min[] = {
SENSOR_ATTR(temp4_min, S_IRUGO | S_IWUSR,
show_therm_min, set_therm_min, 0+11),
SENSOR_ATTR(temp5_min, S_IRUGO | S_IWUSR,
show_therm_min, set_therm_min, 1+11),
SENSOR_ATTR(temp6_min, S_IRUGO | S_IWUSR,
show_therm_min, set_therm_min, 2+11),
};
static struct sensor_device_attribute therm_max[] = {
SENSOR_ATTR(temp4_max, S_IRUGO | S_IWUSR,
show_therm_max, set_therm_max, 0+11),
SENSOR_ATTR(temp5_max, S_IRUGO | S_IWUSR,
show_therm_max, set_therm_max, 1+11),
SENSOR_ATTR(temp6_max, S_IRUGO | S_IWUSR,
show_therm_max, set_therm_max, 2+11),
};
static struct sensor_device_attribute therm_crit[] = {
SENSOR_ATTR(temp4_crit, S_IRUGO | S_IWUSR,
show_therm_crit, set_therm_crit, 0+11),
SENSOR_ATTR(temp5_crit, S_IRUGO | S_IWUSR,
show_therm_crit, set_therm_crit, 1+11),
SENSOR_ATTR(temp6_crit, S_IRUGO | S_IWUSR,
show_therm_crit, set_therm_crit, 2+11),
};
static ssize_t show_vid(struct device *dev, struct device_attribute *attr, char *buf)
{
@ -592,11 +655,11 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *devattr
struct pc87360_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp_min[attr->index] = TEMP_TO_REG(val);
pc87360_write_value(data, LD_TEMP, attr->index, PC87365_REG_TEMP_MIN,
data->temp_min[attr->index]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t set_temp_max(struct device *dev, struct device_attribute *devattr, const char *buf,
@ -607,11 +670,11 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *devattr
struct pc87360_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp_max[attr->index] = TEMP_TO_REG(val);
pc87360_write_value(data, LD_TEMP, attr->index, PC87365_REG_TEMP_MAX,
data->temp_max[attr->index]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t set_temp_crit(struct device *dev, struct device_attribute *devattr, const char *buf,
@ -622,28 +685,48 @@ static ssize_t set_temp_crit(struct device *dev, struct device_attribute *devatt
struct pc87360_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp_crit[attr->index] = TEMP_TO_REG(val);
pc87360_write_value(data, LD_TEMP, attr->index, PC87365_REG_TEMP_CRIT,
data->temp_crit[attr->index]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
#define show_and_set_temp(offset) \
static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \
show_temp_input, NULL, offset-1); \
static SENSOR_DEVICE_ATTR(temp##offset##_min, S_IWUSR | S_IRUGO, \
show_temp_min, set_temp_min, offset-1); \
static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IWUSR | S_IRUGO, \
show_temp_max, set_temp_max, offset-1); \
static SENSOR_DEVICE_ATTR(temp##offset##_crit, S_IWUSR | S_IRUGO, \
show_temp_crit, set_temp_crit, offset-1); \
static SENSOR_DEVICE_ATTR(temp##offset##_status, S_IRUGO, \
show_temp_status, NULL, offset-1);
show_and_set_temp(1)
show_and_set_temp(2)
show_and_set_temp(3)
static struct sensor_device_attribute temp_input[] = {
SENSOR_ATTR(temp1_input, S_IRUGO, show_temp_input, NULL, 0),
SENSOR_ATTR(temp2_input, S_IRUGO, show_temp_input, NULL, 1),
SENSOR_ATTR(temp3_input, S_IRUGO, show_temp_input, NULL, 2),
};
static struct sensor_device_attribute temp_status[] = {
SENSOR_ATTR(temp1_status, S_IRUGO, show_temp_status, NULL, 0),
SENSOR_ATTR(temp2_status, S_IRUGO, show_temp_status, NULL, 1),
SENSOR_ATTR(temp3_status, S_IRUGO, show_temp_status, NULL, 2),
};
static struct sensor_device_attribute temp_min[] = {
SENSOR_ATTR(temp1_min, S_IRUGO | S_IWUSR,
show_temp_min, set_temp_min, 0),
SENSOR_ATTR(temp2_min, S_IRUGO | S_IWUSR,
show_temp_min, set_temp_min, 1),
SENSOR_ATTR(temp3_min, S_IRUGO | S_IWUSR,
show_temp_min, set_temp_min, 2),
};
static struct sensor_device_attribute temp_max[] = {
SENSOR_ATTR(temp1_max, S_IRUGO | S_IWUSR,
show_temp_max, set_temp_max, 0),
SENSOR_ATTR(temp2_max, S_IRUGO | S_IWUSR,
show_temp_max, set_temp_max, 1),
SENSOR_ATTR(temp3_max, S_IRUGO | S_IWUSR,
show_temp_max, set_temp_max, 2),
};
static struct sensor_device_attribute temp_crit[] = {
SENSOR_ATTR(temp1_crit, S_IRUGO | S_IWUSR,
show_temp_crit, set_temp_crit, 0),
SENSOR_ATTR(temp2_crit, S_IRUGO | S_IWUSR,
show_temp_crit, set_temp_crit, 1),
SENSOR_ATTR(temp3_crit, S_IRUGO | S_IWUSR,
show_temp_crit, set_temp_crit, 2),
};
static ssize_t show_temp_alarms(struct device *dev, struct device_attribute *attr, char *buf)
{
@ -749,22 +832,24 @@ static int __init pc87360_find(int sioaddr, u8 *devid, unsigned short *addresses
static int pc87360_detect(struct i2c_adapter *adapter)
{
int i;
struct i2c_client *new_client;
struct i2c_client *client;
struct pc87360_data *data;
int err = 0;
const char *name = "pc87360";
int use_thermistors = 0;
struct device *dev;
if (!(data = kzalloc(sizeof(struct pc87360_data), GFP_KERNEL)))
return -ENOMEM;
new_client = &data->client;
i2c_set_clientdata(new_client, data);
new_client->addr = address;
init_MUTEX(&data->lock);
new_client->adapter = adapter;
new_client->driver = &pc87360_driver;
new_client->flags = 0;
client = &data->client;
dev = &client->dev;
i2c_set_clientdata(client, data);
client->addr = address;
mutex_init(&data->lock);
client->adapter = adapter;
client->driver = &pc87360_driver;
client->flags = 0;
data->fannr = 2;
data->innr = 0;
@ -792,15 +877,15 @@ static int pc87360_detect(struct i2c_adapter *adapter)
break;
}
strcpy(new_client->name, name);
strlcpy(client->name, name, sizeof(client->name));
data->valid = 0;
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
for (i = 0; i < 3; i++) {
if (((data->address[i] = extra_isa[i]))
&& !request_region(extra_isa[i], PC87360_EXTENT,
pc87360_driver.driver.name)) {
dev_err(&new_client->dev, "Region 0x%x-0x%x already "
dev_err(&client->dev, "Region 0x%x-0x%x already "
"in use!\n", extra_isa[i],
extra_isa[i]+PC87360_EXTENT-1);
for (i--; i >= 0; i--)
@ -814,7 +899,7 @@ static int pc87360_detect(struct i2c_adapter *adapter)
if (data->fannr)
data->fan_conf = confreg[0] | (confreg[1] << 8);
if ((err = i2c_attach_client(new_client)))
if ((err = i2c_attach_client(client)))
goto ERROR2;
/* Use the correct reference voltage
@ -828,7 +913,7 @@ static int pc87360_detect(struct i2c_adapter *adapter)
PC87365_REG_TEMP_CONFIG);
}
data->in_vref = (i&0x02) ? 3025 : 2966;
dev_dbg(&new_client->dev, "Using %s reference voltage\n",
dev_dbg(&client->dev, "Using %s reference voltage\n",
(i&0x02) ? "external" : "internal");
data->vid_conf = confreg[3];
@ -847,154 +932,64 @@ static int pc87360_detect(struct i2c_adapter *adapter)
if (devid == 0xe9 && data->address[1]) /* PC87366 */
use_thermistors = confreg[2] & 0x40;
pc87360_init_client(new_client, use_thermistors);
pc87360_init_client(client, use_thermistors);
}
/* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
data->class_dev = hwmon_device_register(&client->dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto ERROR3;
}
if (data->innr) {
device_create_file(&new_client->dev, &sensor_dev_attr_in0_input.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in1_input.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in2_input.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in3_input.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in4_input.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in5_input.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in6_input.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in7_input.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in8_input.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in9_input.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in10_input.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in0_min.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in1_min.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in2_min.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in3_min.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in4_min.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in5_min.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in6_min.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in7_min.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in8_min.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in9_min.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in10_min.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in0_max.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in1_max.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in2_max.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in3_max.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in4_max.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in5_max.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in6_max.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in7_max.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in8_max.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in9_max.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in10_max.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in0_status.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in1_status.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in2_status.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in3_status.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in4_status.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in5_status.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in6_status.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in7_status.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in8_status.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in9_status.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_in10_status.dev_attr);
device_create_file(&new_client->dev, &dev_attr_cpu0_vid);
device_create_file(&new_client->dev, &dev_attr_vrm);
device_create_file(&new_client->dev, &dev_attr_alarms_in);
for (i = 0; i < 11; i++) {
device_create_file(dev, &in_input[i].dev_attr);
device_create_file(dev, &in_min[i].dev_attr);
device_create_file(dev, &in_max[i].dev_attr);
device_create_file(dev, &in_status[i].dev_attr);
}
device_create_file(dev, &dev_attr_cpu0_vid);
device_create_file(dev, &dev_attr_vrm);
device_create_file(dev, &dev_attr_alarms_in);
}
if (data->tempnr) {
device_create_file(&new_client->dev, &sensor_dev_attr_temp1_input.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_temp2_input.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_temp1_min.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_temp2_min.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_temp1_max.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_temp2_max.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_temp1_crit.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_temp2_crit.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_temp1_status.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_temp2_status.dev_attr);
for (i = 0; i < data->tempnr; i++) {
device_create_file(dev, &temp_input[i].dev_attr);
device_create_file(dev, &temp_min[i].dev_attr);
device_create_file(dev, &temp_max[i].dev_attr);
device_create_file(dev, &temp_crit[i].dev_attr);
device_create_file(dev, &temp_status[i].dev_attr);
}
device_create_file(dev, &dev_attr_alarms_temp);
}
device_create_file(&new_client->dev, &dev_attr_alarms_temp);
}
if (data->tempnr == 3) {
device_create_file(&new_client->dev, &sensor_dev_attr_temp3_input.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_temp3_min.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_temp3_max.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_temp3_crit.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_temp3_status.dev_attr);
}
if (data->innr == 14) {
device_create_file(&new_client->dev, &sensor_dev_attr_temp4_input.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_temp5_input.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_temp6_input.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_temp4_min.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_temp5_min.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_temp6_min.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_temp4_max.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_temp5_max.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_temp6_max.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_temp4_crit.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_temp5_crit.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_temp6_crit.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_temp4_status.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_temp5_status.dev_attr);
device_create_file(&new_client->dev, &sensor_dev_attr_temp6_status.dev_attr);
for (i = 0; i < 3; i++) {
device_create_file(dev, &therm_input[i].dev_attr);
device_create_file(dev, &therm_min[i].dev_attr);
device_create_file(dev, &therm_max[i].dev_attr);
device_create_file(dev, &therm_crit[i].dev_attr);
device_create_file(dev, &therm_status[i].dev_attr);
}
}
if (data->fannr) {
if (FAN_CONFIG_MONITOR(data->fan_conf, 0)) {
device_create_file(&new_client->dev,
&sensor_dev_attr_fan1_input.dev_attr);
device_create_file(&new_client->dev,
&sensor_dev_attr_fan1_min.dev_attr);
device_create_file(&new_client->dev,
&sensor_dev_attr_fan1_div.dev_attr);
device_create_file(&new_client->dev,
&sensor_dev_attr_fan1_status.dev_attr);
for (i = 0; i < data->fannr; i++) {
if (FAN_CONFIG_MONITOR(data->fan_conf, i)) {
device_create_file(dev, &fan_input[i].dev_attr);
device_create_file(dev, &fan_min[i].dev_attr);
device_create_file(dev, &fan_div[i].dev_attr);
device_create_file(dev, &fan_status[i].dev_attr);
}
if (FAN_CONFIG_MONITOR(data->fan_conf, 1)) {
device_create_file(&new_client->dev,
&sensor_dev_attr_fan2_input.dev_attr);
device_create_file(&new_client->dev,
&sensor_dev_attr_fan2_min.dev_attr);
device_create_file(&new_client->dev,
&sensor_dev_attr_fan2_div.dev_attr);
device_create_file(&new_client->dev,
&sensor_dev_attr_fan2_status.dev_attr);
}
if (FAN_CONFIG_CONTROL(data->fan_conf, 0))
device_create_file(&new_client->dev, &sensor_dev_attr_pwm1.dev_attr);
if (FAN_CONFIG_CONTROL(data->fan_conf, 1))
device_create_file(&new_client->dev, &sensor_dev_attr_pwm2.dev_attr);
}
if (data->fannr == 3) {
if (FAN_CONFIG_MONITOR(data->fan_conf, 2)) {
device_create_file(&new_client->dev,
&sensor_dev_attr_fan3_input.dev_attr);
device_create_file(&new_client->dev,
&sensor_dev_attr_fan3_min.dev_attr);
device_create_file(&new_client->dev,
&sensor_dev_attr_fan3_div.dev_attr);
device_create_file(&new_client->dev,
&sensor_dev_attr_fan3_status.dev_attr);
}
if (FAN_CONFIG_CONTROL(data->fan_conf, 2))
device_create_file(&new_client->dev, &sensor_dev_attr_pwm3.dev_attr);
if (FAN_CONFIG_CONTROL(data->fan_conf, i))
device_create_file(dev, &pwm[i].dev_attr);
}
return 0;
ERROR3:
i2c_detach_client(new_client);
i2c_detach_client(client);
ERROR2:
for (i = 0; i < 3; i++) {
if (data->address[i]) {
@ -1033,11 +1028,11 @@ static int pc87360_read_value(struct pc87360_data *data, u8 ldi, u8 bank,
{
int res;
down(&(data->lock));
mutex_lock(&(data->lock));
if (bank != NO_BANK)
outb_p(bank, data->address[ldi] + PC87365_REG_BANK);
res = inb_p(data->address[ldi] + reg);
up(&(data->lock));
mutex_unlock(&(data->lock));
return res;
}
@ -1045,11 +1040,11 @@ static int pc87360_read_value(struct pc87360_data *data, u8 ldi, u8 bank,
static void pc87360_write_value(struct pc87360_data *data, u8 ldi, u8 bank,
u8 reg, u8 value)
{
down(&(data->lock));
mutex_lock(&(data->lock));
if (bank != NO_BANK)
outb_p(bank, data->address[ldi] + PC87365_REG_BANK);
outb_p(value, data->address[ldi] + reg);
up(&(data->lock));
mutex_unlock(&(data->lock));
}
static void pc87360_init_client(struct i2c_client *client, int use_thermistors)
@ -1071,7 +1066,7 @@ static void pc87360_init_client(struct i2c_client *client, int use_thermistors)
}
nr = data->innr < 11 ? data->innr : 11;
for (i=0; i<nr; i++) {
for (i = 0; i < nr; i++) {
if (init >= init_in[i]) {
/* Forcibly enable voltage channel */
reg = pc87360_read_value(data, LD_IN, i,
@ -1088,14 +1083,14 @@ static void pc87360_init_client(struct i2c_client *client, int use_thermistors)
/* We can't blindly trust the Super-I/O space configuration bit,
most BIOS won't set it properly */
for (i=11; i<data->innr; i++) {
for (i = 11; i < data->innr; i++) {
reg = pc87360_read_value(data, LD_IN, i,
PC87365_REG_TEMP_STATUS);
use_thermistors = use_thermistors || (reg & 0x01);
}
i = use_thermistors ? 2 : 0;
for (; i<data->tempnr; i++) {
for (; i < data->tempnr; i++) {
if (init >= init_temp[i]) {
/* Forcibly enable temperature channel */
reg = pc87360_read_value(data, LD_TEMP, i,
@ -1111,7 +1106,7 @@ static void pc87360_init_client(struct i2c_client *client, int use_thermistors)
}
if (use_thermistors) {
for (i=11; i<data->innr; i++) {
for (i = 11; i < data->innr; i++) {
if (init >= init_in[i]) {
/* The pin may already be used by thermal
diodes */
@ -1221,7 +1216,7 @@ static struct pc87360_data *pc87360_update_device(struct device *dev)
struct pc87360_data *data = i2c_get_clientdata(client);
u8 i;
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) {
dev_dbg(&client->dev, "Data update\n");
@ -1321,7 +1316,7 @@ static struct pc87360_data *pc87360_update_device(struct device *dev)
data->valid = 1;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return data;
}

View File

@ -60,6 +60,7 @@
#include <linux/err.h>
#include <linux/init.h>
#include <linux/jiffies.h>
#include <linux/mutex.h>
#include <asm/io.h>
@ -167,9 +168,9 @@ static inline u8 DIV_TO_REG(int val)
struct sis5595_data {
struct i2c_client client;
struct class_device *class_dev;
struct semaphore lock;
struct mutex lock;
struct semaphore update_lock;
struct mutex update_lock;
char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */
char maxins; /* == 3 if temp enabled, otherwise == 4 */
@ -192,8 +193,8 @@ static struct pci_dev *s_bridge; /* pointer to the (only) sis5595 */
static int sis5595_detect(struct i2c_adapter *adapter);
static int sis5595_detach_client(struct i2c_client *client);
static int sis5595_read_value(struct i2c_client *client, u8 register);
static int sis5595_write_value(struct i2c_client *client, u8 register, u8 value);
static int sis5595_read_value(struct i2c_client *client, u8 reg);
static int sis5595_write_value(struct i2c_client *client, u8 reg, u8 value);
static struct sis5595_data *sis5595_update_device(struct device *dev);
static void sis5595_init_client(struct i2c_client *client);
@ -231,10 +232,10 @@ static ssize_t set_in_min(struct device *dev, const char *buf,
struct sis5595_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->in_min[nr] = IN_TO_REG(val);
sis5595_write_value(client, SIS5595_REG_IN_MIN(nr), data->in_min[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -245,10 +246,10 @@ static ssize_t set_in_max(struct device *dev, const char *buf,
struct sis5595_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->in_max[nr] = IN_TO_REG(val);
sis5595_write_value(client, SIS5595_REG_IN_MAX(nr), data->in_max[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -310,10 +311,10 @@ static ssize_t set_temp_over(struct device *dev, struct device_attribute *attr,
struct sis5595_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp_over = TEMP_TO_REG(val);
sis5595_write_value(client, SIS5595_REG_TEMP_OVER, data->temp_over);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -329,10 +330,10 @@ static ssize_t set_temp_hyst(struct device *dev, struct device_attribute *attr,
struct sis5595_data *data = i2c_get_clientdata(client);
long val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp_hyst = TEMP_TO_REG(val);
sis5595_write_value(client, SIS5595_REG_TEMP_HYST, data->temp_hyst);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -364,10 +365,10 @@ static ssize_t set_fan_min(struct device *dev, const char *buf,
struct sis5595_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
sis5595_write_value(client, SIS5595_REG_FAN_MIN(nr), data->fan_min[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -390,7 +391,7 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
unsigned long val = simple_strtoul(buf, NULL, 10);
int reg;
down(&data->update_lock);
mutex_lock(&data->update_lock);
min = FAN_FROM_REG(data->fan_min[nr],
DIV_FROM_REG(data->fan_div[nr]));
reg = sis5595_read_value(client, SIS5595_REG_FANDIV);
@ -403,7 +404,7 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
default:
dev_err(&client->dev, "fan_div value %ld not "
"supported. Choose one of 1, 2, 4 or 8!\n", val);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return -EINVAL;
}
@ -419,7 +420,7 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
data->fan_min[nr] =
FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
sis5595_write_value(client, SIS5595_REG_FAN_MIN(nr), data->fan_min[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -527,7 +528,7 @@ static int sis5595_detect(struct i2c_adapter *adapter)
new_client = &data->client;
new_client->addr = address;
init_MUTEX(&data->lock);
mutex_init(&data->lock);
i2c_set_clientdata(new_client, data);
new_client->adapter = adapter;
new_client->driver = &sis5595_driver;
@ -548,7 +549,7 @@ static int sis5595_detect(struct i2c_adapter *adapter)
strlcpy(new_client->name, "sis5595", I2C_NAME_SIZE);
data->valid = 0;
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
@ -635,20 +636,20 @@ static int sis5595_read_value(struct i2c_client *client, u8 reg)
int res;
struct sis5595_data *data = i2c_get_clientdata(client);
down(&data->lock);
mutex_lock(&data->lock);
outb_p(reg, client->addr + SIS5595_ADDR_REG_OFFSET);
res = inb_p(client->addr + SIS5595_DATA_REG_OFFSET);
up(&data->lock);
mutex_unlock(&data->lock);
return res;
}
static int sis5595_write_value(struct i2c_client *client, u8 reg, u8 value)
{
struct sis5595_data *data = i2c_get_clientdata(client);
down(&data->lock);
mutex_lock(&data->lock);
outb_p(reg, client->addr + SIS5595_ADDR_REG_OFFSET);
outb_p(value, client->addr + SIS5595_DATA_REG_OFFSET);
up(&data->lock);
mutex_unlock(&data->lock);
return 0;
}
@ -667,7 +668,7 @@ static struct sis5595_data *sis5595_update_device(struct device *dev)
struct sis5595_data *data = i2c_get_clientdata(client);
int i;
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
|| !data->valid) {
@ -707,7 +708,7 @@ static struct sis5595_data *sis5595_update_device(struct device *dev)
data->valid = 1;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return data;
}

View File

@ -35,6 +35,7 @@
#include <linux/hwmon.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/mutex.h>
#include <asm/io.h>
/* Address is autodetected, there is no default value */
@ -92,9 +93,9 @@ static u8 smsc47b397_reg_temp[] = {0x25, 0x26, 0x27, 0x80};
struct smsc47b397_data {
struct i2c_client client;
struct class_device *class_dev;
struct semaphore lock;
struct mutex lock;
struct semaphore update_lock;
struct mutex update_lock;
unsigned long last_updated; /* in jiffies */
int valid;
@ -108,10 +109,10 @@ static int smsc47b397_read_value(struct i2c_client *client, u8 reg)
struct smsc47b397_data *data = i2c_get_clientdata(client);
int res;
down(&data->lock);
mutex_lock(&data->lock);
outb(reg, client->addr);
res = inb_p(client->addr + 1);
up(&data->lock);
mutex_unlock(&data->lock);
return res;
}
@ -121,7 +122,7 @@ static struct smsc47b397_data *smsc47b397_update_device(struct device *dev)
struct smsc47b397_data *data = i2c_get_clientdata(client);
int i;
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
dev_dbg(&client->dev, "starting device update...\n");
@ -144,7 +145,7 @@ static struct smsc47b397_data *smsc47b397_update_device(struct device *dev)
dev_dbg(&client->dev, "... device update complete\n");
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return data;
}
@ -254,14 +255,14 @@ static int smsc47b397_detect(struct i2c_adapter *adapter)
new_client = &data->client;
i2c_set_clientdata(new_client, data);
new_client->addr = address;
init_MUTEX(&data->lock);
mutex_init(&data->lock);
new_client->adapter = adapter;
new_client->driver = &smsc47b397_driver;
new_client->flags = 0;
strlcpy(new_client->name, "smsc47b397", I2C_NAME_SIZE);
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
if ((err = i2c_attach_client(new_client)))
goto error_free;

View File

@ -34,6 +34,7 @@
#include <linux/hwmon.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/mutex.h>
#include <asm/io.h>
/* Address is autodetected, there is no default value */
@ -102,9 +103,9 @@ superio_exit(void)
struct smsc47m1_data {
struct i2c_client client;
struct class_device *class_dev;
struct semaphore lock;
struct mutex lock;
struct semaphore update_lock;
struct mutex update_lock;
unsigned long last_updated; /* In jiffies */
u8 fan[2]; /* Register value */
@ -188,18 +189,18 @@ static ssize_t set_fan_min(struct device *dev, const char *buf,
struct smsc47m1_data *data = i2c_get_clientdata(client);
long rpmdiv, val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
rpmdiv = val * DIV_FROM_REG(data->fan_div[nr]);
if (983040 > 192 * rpmdiv || 2 * rpmdiv > 983040) {
up(&data->update_lock);
mutex_unlock(&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);
mutex_unlock(&data->update_lock);
return count;
}
@ -220,14 +221,14 @@ 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);
mutex_lock(&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:
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return -EINVAL;
}
@ -241,7 +242,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);
mutex_unlock(&data->update_lock);
return count;
}
@ -257,12 +258,12 @@ static ssize_t set_pwm(struct device *dev, const char *buf,
if (val < 0 || val > 255)
return -EINVAL;
down(&data->update_lock);
mutex_lock(&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);
mutex_unlock(&data->update_lock);
return count;
}
@ -278,12 +279,12 @@ static ssize_t set_pwm_en(struct device *dev, const char *buf,
if (val != 0 && val != 1)
return -EINVAL;
down(&data->update_lock);
mutex_lock(&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);
mutex_unlock(&data->update_lock);
return count;
}
@ -408,13 +409,13 @@ static int smsc47m1_detect(struct i2c_adapter *adapter)
new_client = &data->client;
i2c_set_clientdata(new_client, data);
new_client->addr = address;
init_MUTEX(&data->lock);
mutex_init(&data->lock);
new_client->adapter = adapter;
new_client->driver = &smsc47m1_driver;
new_client->flags = 0;
strlcpy(new_client->name, "smsc47m1", I2C_NAME_SIZE);
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
/* If no function is properly configured, there's no point in
actually registering the chip. */
@ -512,17 +513,17 @@ static int smsc47m1_read_value(struct i2c_client *client, u8 reg)
{
int res;
down(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
mutex_lock(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
res = inb_p(client->addr + reg);
up(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
mutex_unlock(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
return res;
}
static void smsc47m1_write_value(struct i2c_client *client, u8 reg, u8 value)
{
down(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
mutex_lock(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
outb_p(value, client->addr + reg);
up(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
mutex_unlock(&((struct smsc47m1_data *) i2c_get_clientdata(client))->lock);
}
static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
@ -531,7 +532,7 @@ static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
struct i2c_client *client = to_i2c_client(dev);
struct smsc47m1_data *data = i2c_get_clientdata(client);
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || init) {
int i;
@ -558,7 +559,7 @@ static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
data->last_updated = jiffies;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return data;
}

View File

@ -39,6 +39,7 @@
#include <linux/hwmon.h>
#include <linux/err.h>
#include <linux/init.h>
#include <linux/mutex.h>
#include <asm/io.h>
@ -296,7 +297,7 @@ static inline long TEMP_FROM_REG10(u16 val)
struct via686a_data {
struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock;
struct mutex update_lock;
char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */
@ -355,11 +356,11 @@ static ssize_t set_in_min(struct device *dev, const char *buf,
struct via686a_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->in_min[nr] = IN_TO_REG(val, nr);
via686a_write_value(client, VIA686A_REG_IN_MIN(nr),
data->in_min[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t set_in_max(struct device *dev, const char *buf,
@ -368,11 +369,11 @@ static ssize_t set_in_max(struct device *dev, const char *buf,
struct via686a_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->in_max[nr] = IN_TO_REG(val, nr);
via686a_write_value(client, VIA686A_REG_IN_MAX(nr),
data->in_max[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
#define show_in_offset(offset) \
@ -432,11 +433,11 @@ static ssize_t set_temp_over(struct device *dev, const char *buf,
struct via686a_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp_over[nr] = TEMP_TO_REG(val);
via686a_write_value(client, VIA686A_REG_TEMP_OVER[nr],
data->temp_over[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t set_temp_hyst(struct device *dev, const char *buf,
@ -445,11 +446,11 @@ static ssize_t set_temp_hyst(struct device *dev, const char *buf,
struct via686a_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp_hyst[nr] = TEMP_TO_REG(val);
via686a_write_value(client, VIA686A_REG_TEMP_HYST[nr],
data->temp_hyst[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
#define show_temp_offset(offset) \
@ -508,10 +509,10 @@ static ssize_t set_fan_min(struct device *dev, const char *buf,
struct via686a_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
via686a_write_value(client, VIA686A_REG_FAN_MIN(nr+1), data->fan_min[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t set_fan_div(struct device *dev, const char *buf,
@ -521,12 +522,12 @@ static ssize_t set_fan_div(struct device *dev, const char *buf,
int val = simple_strtol(buf, NULL, 10);
int old;
down(&data->update_lock);
mutex_lock(&data->update_lock);
old = via686a_read_value(client, VIA686A_REG_FANDIV);
data->fan_div[nr] = DIV_TO_REG(val);
old = (old & 0x0f) | (data->fan_div[1] << 6) | (data->fan_div[0] << 4);
via686a_write_value(client, VIA686A_REG_FANDIV, old);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -639,7 +640,7 @@ static int via686a_detect(struct i2c_adapter *adapter)
strlcpy(new_client->name, client_name, I2C_NAME_SIZE);
data->valid = 0;
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
goto exit_free;
@ -733,7 +734,7 @@ static struct via686a_data *via686a_update_device(struct device *dev)
struct via686a_data *data = i2c_get_clientdata(client);
int i;
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
|| !data->valid) {
@ -788,7 +789,7 @@ static struct via686a_data *via686a_update_device(struct device *dev)
data->valid = 1;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return data;
}

View File

@ -35,6 +35,7 @@
#include <linux/hwmon-sysfs.h>
#include <linux/hwmon-vid.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <asm/io.h>
static int force_addr;
@ -148,7 +149,7 @@ static inline u8 FAN_TO_REG(long rpm, int div)
struct vt8231_data {
struct i2c_client client;
struct semaphore update_lock;
struct mutex update_lock;
struct class_device *class_dev;
char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */
@ -223,10 +224,10 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
struct vt8231_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->in_min[nr] = SENSORS_LIMIT(((val * 958) / 10000) + 3, 0, 255);
vt8231_write_value(client, regvoltmin[nr], data->in_min[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -239,10 +240,10 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
struct vt8231_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->in_max[nr] = SENSORS_LIMIT(((val * 958) / 10000) + 3, 0, 255);
vt8231_write_value(client, regvoltmax[nr], data->in_max[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -281,11 +282,11 @@ static ssize_t set_in5_min(struct device *dev, struct device_attribute *attr,
struct vt8231_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->in_min[5] = SENSORS_LIMIT(((val * 958 * 34) / (10000 * 54)) + 3,
0, 255);
vt8231_write_value(client, regvoltmin[5], data->in_min[5]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -296,11 +297,11 @@ static ssize_t set_in5_max(struct device *dev, struct device_attribute *attr,
struct vt8231_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->in_max[5] = SENSORS_LIMIT(((val * 958 * 34) / (10000 * 54)) + 3,
0, 255);
vt8231_write_value(client, regvoltmax[5], data->in_max[5]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -351,10 +352,10 @@ static ssize_t set_temp0_max(struct device *dev, struct device_attribute *attr,
struct vt8231_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp_max[0] = SENSORS_LIMIT((val + 500) / 1000, 0, 255);
vt8231_write_value(client, regtempmax[0], data->temp_max[0]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t set_temp0_min(struct device *dev, struct device_attribute *attr,
@ -364,10 +365,10 @@ static ssize_t set_temp0_min(struct device *dev, struct device_attribute *attr,
struct vt8231_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp_min[0] = SENSORS_LIMIT((val + 500) / 1000, 0, 255);
vt8231_write_value(client, regtempmin[0], data->temp_min[0]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -407,10 +408,10 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
struct vt8231_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp_max[nr] = SENSORS_LIMIT(TEMP_MAXMIN_TO_REG(val), 0, 255);
vt8231_write_value(client, regtempmax[nr], data->temp_max[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
@ -422,10 +423,10 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
struct vt8231_data *data = i2c_get_clientdata(client);
int val = simple_strtol(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->temp_min[nr] = SENSORS_LIMIT(TEMP_MAXMIN_TO_REG(val), 0, 255);
vt8231_write_value(client, regtempmin[nr], data->temp_min[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -520,10 +521,10 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
struct vt8231_data *data = i2c_get_clientdata(client);
int val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
vt8231_write_value(client, VT8231_REG_FAN_MIN(nr), data->fan_min[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -539,7 +540,7 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
long min = FAN_FROM_REG(data->fan_min[nr],
DIV_FROM_REG(data->fan_div[nr]));
down(&data->update_lock);
mutex_lock(&data->update_lock);
switch (val) {
case 1: data->fan_div[nr] = 0; break;
case 2: data->fan_div[nr] = 1; break;
@ -548,7 +549,7 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
default:
dev_err(&client->dev, "fan_div value %ld not supported."
"Choose one of 1, 2, 4 or 8!\n", val);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return -EINVAL;
}
@ -558,7 +559,7 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
old = (old & 0x0f) | (data->fan_div[1] << 6) | (data->fan_div[0] << 4);
vt8231_write_value(client, VT8231_REG_FANDIV, old);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -660,7 +661,7 @@ int vt8231_detect(struct i2c_adapter *adapter)
/* Fill in the remaining client fields and put into the global list */
strlcpy(client->name, "vt8231", I2C_NAME_SIZE);
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(client)))
@ -745,7 +746,7 @@ static struct vt8231_data *vt8231_update_device(struct device *dev)
int i;
u16 low;
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
|| !data->valid) {
@ -804,7 +805,7 @@ static struct vt8231_data *vt8231_update_device(struct device *dev)
data->valid = 1;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return data;
}

View File

@ -42,7 +42,9 @@
#include <linux/i2c.h>
#include <linux/i2c-isa.h>
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <asm/io.h>
#include "lm75.h"
@ -177,9 +179,9 @@ temp1_to_reg(int temp)
struct w83627ehf_data {
struct i2c_client client;
struct class_device *class_dev;
struct semaphore lock;
struct mutex lock;
struct semaphore update_lock;
struct mutex update_lock;
char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */
@ -230,7 +232,7 @@ static u16 w83627ehf_read_value(struct i2c_client *client, u16 reg)
struct w83627ehf_data *data = i2c_get_clientdata(client);
int res, word_sized = is_word_sized(reg);
down(&data->lock);
mutex_lock(&data->lock);
w83627ehf_set_bank(client, reg);
outb_p(reg & 0xff, client->addr + ADDR_REG_OFFSET);
@ -242,7 +244,7 @@ static u16 w83627ehf_read_value(struct i2c_client *client, u16 reg)
}
w83627ehf_reset_bank(client, reg);
up(&data->lock);
mutex_unlock(&data->lock);
return res;
}
@ -252,7 +254,7 @@ static int w83627ehf_write_value(struct i2c_client *client, u16 reg, u16 value)
struct w83627ehf_data *data = i2c_get_clientdata(client);
int word_sized = is_word_sized(reg);
down(&data->lock);
mutex_lock(&data->lock);
w83627ehf_set_bank(client, reg);
outb_p(reg & 0xff, client->addr + ADDR_REG_OFFSET);
@ -264,7 +266,7 @@ static int w83627ehf_write_value(struct i2c_client *client, u16 reg, u16 value)
outb_p(value & 0xff, client->addr + DATA_REG_OFFSET);
w83627ehf_reset_bank(client, reg);
up(&data->lock);
mutex_unlock(&data->lock);
return 0;
}
@ -322,7 +324,7 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev)
struct w83627ehf_data *data = i2c_get_clientdata(client);
int i;
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ)
|| !data->valid) {
@ -397,7 +399,7 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev)
data->valid = 1;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return data;
}
@ -407,9 +409,12 @@ static struct w83627ehf_data *w83627ehf_update_device(struct device *dev)
#define show_fan_reg(reg) \
static ssize_t \
show_##reg(struct device *dev, char *buf, int nr) \
show_##reg(struct device *dev, struct device_attribute *attr, \
char *buf) \
{ \
struct w83627ehf_data *data = w83627ehf_update_device(dev); \
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \
int nr = sensor_attr->index; \
return sprintf(buf, "%d\n", \
fan_from_reg(data->reg[nr], \
div_from_reg(data->fan_div[nr]))); \
@ -418,23 +423,28 @@ show_fan_reg(fan);
show_fan_reg(fan_min);
static ssize_t
show_fan_div(struct device *dev, char *buf, int nr)
show_fan_div(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct w83627ehf_data *data = w83627ehf_update_device(dev);
return sprintf(buf, "%u\n",
div_from_reg(data->fan_div[nr]));
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
int nr = sensor_attr->index;
return sprintf(buf, "%u\n", div_from_reg(data->fan_div[nr]));
}
static ssize_t
store_fan_min(struct device *dev, const char *buf, size_t count, int nr)
store_fan_min(struct device *dev, struct device_attribute *attr,
const char *buf, size_t count)
{
struct i2c_client *client = to_i2c_client(dev);
struct w83627ehf_data *data = i2c_get_clientdata(client);
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
int nr = sensor_attr->index;
unsigned int val = simple_strtoul(buf, NULL, 10);
unsigned int reg;
u8 new_div;
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (!val) {
/* No min limit, alarm disabled */
data->fan_min[nr] = 255;
@ -482,63 +492,46 @@ store_fan_min(struct device *dev, const char *buf, size_t count, int nr)
}
w83627ehf_write_value(client, W83627EHF_REG_FAN_MIN[nr],
data->fan_min[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
#define sysfs_fan_offset(offset) \
static ssize_t \
show_reg_fan_##offset(struct device *dev, struct device_attribute *attr, \
char *buf) \
{ \
return show_fan(dev, buf, offset-1); \
} \
static DEVICE_ATTR(fan##offset##_input, S_IRUGO, \
show_reg_fan_##offset, NULL);
static struct sensor_device_attribute sda_fan_input[] = {
SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 0),
SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 1),
SENSOR_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 2),
SENSOR_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 3),
SENSOR_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 4),
};
#define sysfs_fan_min_offset(offset) \
static ssize_t \
show_reg_fan##offset##_min(struct device *dev, struct device_attribute *attr, \
char *buf) \
{ \
return show_fan_min(dev, buf, offset-1); \
} \
static ssize_t \
store_reg_fan##offset##_min(struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return store_fan_min(dev, buf, count, offset-1); \
} \
static DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
show_reg_fan##offset##_min, \
store_reg_fan##offset##_min);
static struct sensor_device_attribute sda_fan_min[] = {
SENSOR_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min,
store_fan_min, 0),
SENSOR_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min,
store_fan_min, 1),
SENSOR_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min,
store_fan_min, 2),
SENSOR_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min,
store_fan_min, 3),
SENSOR_ATTR(fan5_min, S_IWUSR | S_IRUGO, show_fan_min,
store_fan_min, 4),
};
#define sysfs_fan_div_offset(offset) \
static ssize_t \
show_reg_fan##offset##_div(struct device *dev, struct device_attribute *attr, \
char *buf) \
{ \
return show_fan_div(dev, buf, offset - 1); \
} \
static DEVICE_ATTR(fan##offset##_div, S_IRUGO, \
show_reg_fan##offset##_div, NULL);
static struct sensor_device_attribute sda_fan_div[] = {
SENSOR_ATTR(fan1_div, S_IRUGO, show_fan_div, NULL, 0),
SENSOR_ATTR(fan2_div, S_IRUGO, show_fan_div, NULL, 1),
SENSOR_ATTR(fan3_div, S_IRUGO, show_fan_div, NULL, 2),
SENSOR_ATTR(fan4_div, S_IRUGO, show_fan_div, NULL, 3),
SENSOR_ATTR(fan5_div, S_IRUGO, show_fan_div, NULL, 4),
};
sysfs_fan_offset(1);
sysfs_fan_min_offset(1);
sysfs_fan_div_offset(1);
sysfs_fan_offset(2);
sysfs_fan_min_offset(2);
sysfs_fan_div_offset(2);
sysfs_fan_offset(3);
sysfs_fan_min_offset(3);
sysfs_fan_div_offset(3);
sysfs_fan_offset(4);
sysfs_fan_min_offset(4);
sysfs_fan_div_offset(4);
sysfs_fan_offset(5);
sysfs_fan_min_offset(5);
sysfs_fan_div_offset(5);
static void device_create_file_fan(struct device *dev, int i)
{
device_create_file(dev, &sda_fan_input[i].dev_attr);
device_create_file(dev, &sda_fan_div[i].dev_attr);
device_create_file(dev, &sda_fan_min[i].dev_attr);
}
#define show_temp1_reg(reg) \
static ssize_t \
@ -561,27 +554,24 @@ store_temp1_##reg(struct device *dev, struct device_attribute *attr, \
struct w83627ehf_data *data = i2c_get_clientdata(client); \
u32 val = simple_strtoul(buf, NULL, 10); \
\
down(&data->update_lock); \
mutex_lock(&data->update_lock); \
data->temp1_##reg = temp1_to_reg(val); \
w83627ehf_write_value(client, W83627EHF_REG_TEMP1_##REG, \
data->temp1_##reg); \
up(&data->update_lock); \
mutex_unlock(&data->update_lock); \
return count; \
}
store_temp1_reg(OVER, max);
store_temp1_reg(HYST, max_hyst);
static DEVICE_ATTR(temp1_input, S_IRUGO, show_temp1, NULL);
static DEVICE_ATTR(temp1_max, S_IRUGO| S_IWUSR,
show_temp1_max, store_temp1_max);
static DEVICE_ATTR(temp1_max_hyst, S_IRUGO| S_IWUSR,
show_temp1_max_hyst, store_temp1_max_hyst);
#define show_temp_reg(reg) \
static ssize_t \
show_##reg (struct device *dev, char *buf, int nr) \
show_##reg(struct device *dev, struct device_attribute *attr, \
char *buf) \
{ \
struct w83627ehf_data *data = w83627ehf_update_device(dev); \
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \
int nr = sensor_attr->index; \
return sprintf(buf, "%d\n", \
LM75_TEMP_FROM_REG(data->reg[nr])); \
}
@ -591,55 +581,42 @@ show_temp_reg(temp_max_hyst);
#define store_temp_reg(REG, reg) \
static ssize_t \
store_##reg (struct device *dev, const char *buf, size_t count, int nr) \
store_##reg(struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
struct i2c_client *client = to_i2c_client(dev); \
struct w83627ehf_data *data = i2c_get_clientdata(client); \
struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr); \
int nr = sensor_attr->index; \
u32 val = simple_strtoul(buf, NULL, 10); \
\
down(&data->update_lock); \
mutex_lock(&data->update_lock); \
data->reg[nr] = LM75_TEMP_TO_REG(val); \
w83627ehf_write_value(client, W83627EHF_REG_TEMP_##REG[nr], \
data->reg[nr]); \
up(&data->update_lock); \
mutex_unlock(&data->update_lock); \
return count; \
}
store_temp_reg(OVER, temp_max);
store_temp_reg(HYST, temp_max_hyst);
#define sysfs_temp_offset(offset) \
static ssize_t \
show_reg_temp##offset (struct device *dev, struct device_attribute *attr, \
char *buf) \
{ \
return show_temp(dev, buf, offset - 2); \
} \
static DEVICE_ATTR(temp##offset##_input, S_IRUGO, \
show_reg_temp##offset, NULL);
#define sysfs_temp_reg_offset(reg, offset) \
static ssize_t \
show_reg_temp##offset##_##reg(struct device *dev, struct device_attribute *attr, \
char *buf) \
{ \
return show_temp_##reg(dev, buf, offset - 2); \
} \
static ssize_t \
store_reg_temp##offset##_##reg(struct device *dev, struct device_attribute *attr, \
const char *buf, size_t count) \
{ \
return store_temp_##reg(dev, buf, count, offset - 2); \
} \
static DEVICE_ATTR(temp##offset##_##reg, S_IRUGO| S_IWUSR, \
show_reg_temp##offset##_##reg, \
store_reg_temp##offset##_##reg);
sysfs_temp_offset(2);
sysfs_temp_reg_offset(max, 2);
sysfs_temp_reg_offset(max_hyst, 2);
sysfs_temp_offset(3);
sysfs_temp_reg_offset(max, 3);
sysfs_temp_reg_offset(max_hyst, 3);
static struct sensor_device_attribute sda_temp[] = {
SENSOR_ATTR(temp1_input, S_IRUGO, show_temp1, NULL, 0),
SENSOR_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 0),
SENSOR_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 1),
SENSOR_ATTR(temp1_max, S_IRUGO | S_IWUSR, show_temp1_max,
store_temp1_max, 0),
SENSOR_ATTR(temp2_max, S_IRUGO | S_IWUSR, show_temp_max,
store_temp_max, 0),
SENSOR_ATTR(temp3_max, S_IRUGO | S_IWUSR, show_temp_max,
store_temp_max, 1),
SENSOR_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp1_max_hyst,
store_temp1_max_hyst, 0),
SENSOR_ATTR(temp2_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst,
store_temp_max_hyst, 0),
SENSOR_ATTR(temp3_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst,
store_temp_max_hyst, 1),
};
/*
* Driver and client management
@ -673,6 +650,7 @@ static int w83627ehf_detect(struct i2c_adapter *adapter)
{
struct i2c_client *client;
struct w83627ehf_data *data;
struct device *dev;
int i, err = 0;
if (!request_region(address + REGION_OFFSET, REGION_LENGTH,
@ -689,14 +667,15 @@ static int w83627ehf_detect(struct i2c_adapter *adapter)
client = &data->client;
i2c_set_clientdata(client, data);
client->addr = address;
init_MUTEX(&data->lock);
mutex_init(&data->lock);
client->adapter = adapter;
client->driver = &w83627ehf_driver;
client->flags = 0;
dev = &client->dev;
strlcpy(client->name, "w83627ehf", I2C_NAME_SIZE);
data->valid = 0;
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
/* Tell the i2c layer a new client has arrived */
if ((err = i2c_attach_client(client)))
@ -720,42 +699,18 @@ static int w83627ehf_detect(struct i2c_adapter *adapter)
data->has_fan |= (1 << 4);
/* Register sysfs hooks */
data->class_dev = hwmon_device_register(&client->dev);
data->class_dev = hwmon_device_register(dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto exit_detach;
}
device_create_file(&client->dev, &dev_attr_fan1_input);
device_create_file(&client->dev, &dev_attr_fan1_min);
device_create_file(&client->dev, &dev_attr_fan1_div);
device_create_file(&client->dev, &dev_attr_fan2_input);
device_create_file(&client->dev, &dev_attr_fan2_min);
device_create_file(&client->dev, &dev_attr_fan2_div);
device_create_file(&client->dev, &dev_attr_fan3_input);
device_create_file(&client->dev, &dev_attr_fan3_min);
device_create_file(&client->dev, &dev_attr_fan3_div);
if (data->has_fan & (1 << 3)) {
device_create_file(&client->dev, &dev_attr_fan4_input);
device_create_file(&client->dev, &dev_attr_fan4_min);
device_create_file(&client->dev, &dev_attr_fan4_div);
for (i = 0; i < 5; i++) {
if (data->has_fan & (1 << i))
device_create_file_fan(dev, i);
}
if (data->has_fan & (1 << 4)) {
device_create_file(&client->dev, &dev_attr_fan5_input);
device_create_file(&client->dev, &dev_attr_fan5_min);
device_create_file(&client->dev, &dev_attr_fan5_div);
}
device_create_file(&client->dev, &dev_attr_temp1_input);
device_create_file(&client->dev, &dev_attr_temp1_max);
device_create_file(&client->dev, &dev_attr_temp1_max_hyst);
device_create_file(&client->dev, &dev_attr_temp2_input);
device_create_file(&client->dev, &dev_attr_temp2_max);
device_create_file(&client->dev, &dev_attr_temp2_max_hyst);
device_create_file(&client->dev, &dev_attr_temp3_input);
device_create_file(&client->dev, &dev_attr_temp3_max);
device_create_file(&client->dev, &dev_attr_temp3_max_hyst);
for (i = 0; i < ARRAY_SIZE(sda_temp); i++)
device_create_file(dev, &sda_temp[i].dev_attr);
return 0;

View File

@ -28,6 +28,7 @@
w83627hf 9 3 2 3 0x20 0x5ca3 no yes(LPC)
w83627thf 7 3 3 3 0x90 0x5ca3 no yes(LPC)
w83637hf 7 3 3 3 0x80 0x5ca3 no yes(LPC)
w83687thf 7 3 3 3 0x90 0x5ca3 no yes(LPC)
w83697hf 8 2 2 2 0x60 0x5ca3 no yes(LPC)
For other winbond chips, and for i2c support in the above chips,
@ -46,6 +47,7 @@
#include <linux/hwmon.h>
#include <linux/hwmon-vid.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <asm/io.h>
#include "lm75.h"
@ -62,7 +64,7 @@ MODULE_PARM_DESC(force_i2c,
static unsigned short address;
/* Insmod parameters */
enum chips { any_chip, w83627hf, w83627thf, w83697hf, w83637hf };
enum chips { any_chip, w83627hf, w83627thf, w83697hf, w83637hf, w83687thf };
static int reset;
module_param(reset, bool, 0);
@ -100,6 +102,10 @@ static int VAL; /* The value to read/write */
#define W83627THF_GPIO5_IOSR 0xf3 /* w83627thf only */
#define W83627THF_GPIO5_DR 0xf4 /* w83627thf only */
#define W83687THF_VID_EN 0x29 /* w83687thf only */
#define W83687THF_VID_CFG 0xF0 /* w83687thf only */
#define W83687THF_VID_DATA 0xF1 /* w83687thf only */
static inline void
superio_outb(int reg, int val)
{
@ -138,6 +144,7 @@ superio_exit(void)
#define W627THF_DEVID 0x82
#define W697_DEVID 0x60
#define W637_DEVID 0x70
#define W687THF_DEVID 0x85
#define WINB_ACT_REG 0x30
#define WINB_BASE_REG 0x60
/* Constants specified below */
@ -201,11 +208,11 @@ superio_exit(void)
#define W83627HF_REG_PWM1 0x5A
#define W83627HF_REG_PWM2 0x5B
#define W83627THF_REG_PWM1 0x01 /* 697HF and 637HF too */
#define W83627THF_REG_PWM2 0x03 /* 697HF and 637HF too */
#define W83627THF_REG_PWM3 0x11 /* 637HF too */
#define W83627THF_REG_PWM1 0x01 /* 697HF/637HF/687THF too */
#define W83627THF_REG_PWM2 0x03 /* 697HF/637HF/687THF too */
#define W83627THF_REG_PWM3 0x11 /* 637HF/687THF too */
#define W83627THF_REG_VRM_OVT_CFG 0x18 /* 637HF too */
#define W83627THF_REG_VRM_OVT_CFG 0x18 /* 637HF/687THF too */
static const u8 regpwm_627hf[] = { W83627HF_REG_PWM1, W83627HF_REG_PWM2 };
static const u8 regpwm[] = { W83627THF_REG_PWM1, W83627THF_REG_PWM2,
@ -285,10 +292,10 @@ static inline u8 DIV_TO_REG(long val)
struct w83627hf_data {
struct i2c_client client;
struct class_device *class_dev;
struct semaphore lock;
struct mutex lock;
enum chips type;
struct semaphore update_lock;
struct mutex update_lock;
char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */
@ -318,16 +325,15 @@ struct w83627hf_data {
Default = 3435.
Other Betas unimplemented */
u8 vrm;
u8 vrm_ovt; /* Register value, 627thf & 637hf only */
u8 vrm_ovt; /* Register value, 627THF/637HF/687THF only */
};
static int w83627hf_detect(struct i2c_adapter *adapter);
static int w83627hf_detach_client(struct i2c_client *client);
static int w83627hf_read_value(struct i2c_client *client, u16 register);
static int w83627hf_write_value(struct i2c_client *client, u16 register,
u16 value);
static int w83627hf_read_value(struct i2c_client *client, u16 reg);
static int w83627hf_write_value(struct i2c_client *client, u16 reg, u16 value);
static struct w83627hf_data *w83627hf_update_device(struct device *dev);
static void w83627hf_init_client(struct i2c_client *client);
@ -360,12 +366,12 @@ store_in_##reg (struct device *dev, const char *buf, size_t count, int nr) \
\
val = simple_strtoul(buf, NULL, 10); \
\
down(&data->update_lock); \
mutex_lock(&data->update_lock); \
data->in_##reg[nr] = IN_TO_REG(val); \
w83627hf_write_value(client, W83781D_REG_IN_##REG(nr), \
data->in_##reg[nr]); \
\
up(&data->update_lock); \
mutex_unlock(&data->update_lock); \
return count; \
}
store_in_reg(MIN, min)
@ -413,7 +419,8 @@ static ssize_t show_in_0(struct w83627hf_data *data, char *buf, u8 reg)
long in0;
if ((data->vrm_ovt & 0x01) &&
(w83627thf == data->type || w83637hf == data->type))
(w83627thf == data->type || w83637hf == data->type
|| w83687thf == data->type))
/* use VRM9 calculation */
in0 = (long)((reg * 488 + 70000 + 50) / 100);
@ -451,10 +458,11 @@ static ssize_t store_regs_in_min0(struct device *dev, struct device_attribute *a
val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
if ((data->vrm_ovt & 0x01) &&
(w83627thf == data->type || w83637hf == data->type))
(w83627thf == data->type || w83637hf == data->type
|| w83687thf == data->type))
/* use VRM9 calculation */
data->in_min[0] =
@ -465,7 +473,7 @@ static ssize_t store_regs_in_min0(struct device *dev, struct device_attribute *a
data->in_min[0] = IN_TO_REG(val);
w83627hf_write_value(client, W83781D_REG_IN_MIN(0), data->in_min[0]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -478,10 +486,11 @@ static ssize_t store_regs_in_max0(struct device *dev, struct device_attribute *a
val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
if ((data->vrm_ovt & 0x01) &&
(w83627thf == data->type || w83637hf == data->type))
(w83627thf == data->type || w83637hf == data->type
|| w83687thf == data->type))
/* use VRM9 calculation */
data->in_max[0] =
@ -492,7 +501,7 @@ static ssize_t store_regs_in_max0(struct device *dev, struct device_attribute *a
data->in_max[0] = IN_TO_REG(val);
w83627hf_write_value(client, W83781D_REG_IN_MAX(0), data->in_max[0]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -529,13 +538,13 @@ store_fan_min(struct device *dev, const char *buf, size_t count, int nr)
val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->fan_min[nr - 1] =
FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr - 1]));
w83627hf_write_value(client, W83781D_REG_FAN_MIN(nr),
data->fan_min[nr - 1]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -597,7 +606,7 @@ store_temp_##reg (struct device *dev, const char *buf, size_t count, int nr) \
\
val = simple_strtoul(buf, NULL, 10); \
\
down(&data->update_lock); \
mutex_lock(&data->update_lock); \
\
if (nr >= 2) { /* TEMP2 and TEMP3 */ \
data->temp_##reg##_add[nr-2] = LM75_TEMP_TO_REG(val); \
@ -609,7 +618,7 @@ store_temp_##reg (struct device *dev, const char *buf, size_t count, int nr) \
data->temp_##reg); \
} \
\
up(&data->update_lock); \
mutex_unlock(&data->update_lock); \
return count; \
}
store_temp_reg(OVER, max);
@ -718,7 +727,7 @@ store_beep_reg(struct device *dev, const char *buf, size_t count,
val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (update_mask == BEEP_MASK) { /* We are storing beep_mask */
data->beep_mask = BEEP_MASK_TO_REG(val);
@ -736,7 +745,7 @@ store_beep_reg(struct device *dev, const char *buf, size_t count,
w83627hf_write_value(client, W83781D_REG_BEEP_INTS2,
val2 | data->beep_enable << 7);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -783,7 +792,7 @@ store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr)
u8 reg;
unsigned long val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
/* Save fan_min */
min = FAN_FROM_REG(data->fan_min[nr],
@ -805,7 +814,7 @@ store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr)
data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
w83627hf_write_value(client, W83781D_REG_FAN_MIN(nr+1), data->fan_min[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -848,7 +857,7 @@ store_pwm_reg(struct device *dev, const char *buf, size_t count, int nr)
val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (data->type == w83627thf) {
/* bits 0-3 are reserved in 627THF */
@ -865,7 +874,7 @@ store_pwm_reg(struct device *dev, const char *buf, size_t count, int nr)
data->pwm[nr - 1]);
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -907,7 +916,7 @@ store_sensor_reg(struct device *dev, const char *buf, size_t count, int nr)
val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
switch (val) {
case 1: /* PII/Celeron diode */
@ -941,7 +950,7 @@ store_sensor_reg(struct device *dev, const char *buf, size_t count, int nr)
break;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -980,7 +989,8 @@ static int __init w83627hf_find(int sioaddr, unsigned short *addr)
if(val != W627_DEVID &&
val != W627THF_DEVID &&
val != W697_DEVID &&
val != W637_DEVID) {
val != W637_DEVID &&
val != W687THF_DEVID) {
superio_exit();
return -ENODEV;
}
@ -1034,6 +1044,8 @@ static int w83627hf_detect(struct i2c_adapter *adapter)
kind = w83627thf;
else if(val == W637_DEVID)
kind = w83637hf;
else if (val == W687THF_DEVID)
kind = w83687thf;
else {
dev_info(&adapter->dev,
"Unsupported chip (dev_id=0x%02X).\n", val);
@ -1057,7 +1069,7 @@ static int w83627hf_detect(struct i2c_adapter *adapter)
new_client = &data->client;
i2c_set_clientdata(new_client, data);
new_client->addr = address;
init_MUTEX(&data->lock);
mutex_init(&data->lock);
new_client->adapter = adapter;
new_client->driver = &w83627hf_driver;
new_client->flags = 0;
@ -1071,13 +1083,15 @@ static int w83627hf_detect(struct i2c_adapter *adapter)
client_name = "w83697hf";
} else if (kind == w83637hf) {
client_name = "w83637hf";
} else if (kind == w83687thf) {
client_name = "w83687thf";
}
/* Fill in the remaining client fields and put into the global list */
strlcpy(new_client->name, client_name, I2C_NAME_SIZE);
data->type = kind;
data->valid = 0;
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
@ -1106,7 +1120,7 @@ static int w83627hf_detect(struct i2c_adapter *adapter)
device_create_file_in(new_client, 2);
device_create_file_in(new_client, 3);
device_create_file_in(new_client, 4);
if (kind != w83627thf && kind != w83637hf) {
if (kind == w83627hf || kind == w83697hf) {
device_create_file_in(new_client, 5);
device_create_file_in(new_client, 6);
}
@ -1139,7 +1153,7 @@ static int w83627hf_detect(struct i2c_adapter *adapter)
device_create_file_pwm(new_client, 1);
device_create_file_pwm(new_client, 2);
if (kind == w83627thf || kind == w83637hf)
if (kind == w83627thf || kind == w83637hf || kind == w83687thf)
device_create_file_pwm(new_client, 3);
device_create_file_sensor(new_client, 1);
@ -1187,7 +1201,7 @@ static int w83627hf_read_value(struct i2c_client *client, u16 reg)
struct w83627hf_data *data = i2c_get_clientdata(client);
int res, word_sized;
down(&data->lock);
mutex_lock(&data->lock);
word_sized = (((reg & 0xff00) == 0x100)
|| ((reg & 0xff00) == 0x200))
&& (((reg & 0x00ff) == 0x50)
@ -1213,7 +1227,7 @@ static int w83627hf_read_value(struct i2c_client *client, u16 reg)
client->addr + W83781D_ADDR_REG_OFFSET);
outb_p(0, client->addr + W83781D_DATA_REG_OFFSET);
}
up(&data->lock);
mutex_unlock(&data->lock);
return res;
}
@ -1247,12 +1261,39 @@ exit:
return res;
}
static int w83687thf_read_vid(struct i2c_client *client)
{
int res = 0xff;
superio_enter();
superio_select(W83627HF_LD_HWM);
/* Make sure these GPIO pins are enabled */
if (!(superio_inb(W83687THF_VID_EN) & (1 << 2))) {
dev_dbg(&client->dev, "VID disabled, no VID function\n");
goto exit;
}
/* Make sure the pins are configured for input */
if (!(superio_inb(W83687THF_VID_CFG) & (1 << 4))) {
dev_dbg(&client->dev, "VID configured as output, "
"no VID function\n");
goto exit;
}
res = superio_inb(W83687THF_VID_DATA) & 0x3f;
exit:
superio_exit();
return res;
}
static int w83627hf_write_value(struct i2c_client *client, u16 reg, u16 value)
{
struct w83627hf_data *data = i2c_get_clientdata(client);
int word_sized;
down(&data->lock);
mutex_lock(&data->lock);
word_sized = (((reg & 0xff00) == 0x100)
|| ((reg & 0xff00) == 0x200))
&& (((reg & 0x00ff) == 0x53)
@ -1277,7 +1318,7 @@ static int w83627hf_write_value(struct i2c_client *client, u16 reg, u16 value)
client->addr + W83781D_ADDR_REG_OFFSET);
outb_p(0, client->addr + W83781D_DATA_REG_OFFSET);
}
up(&data->lock);
mutex_unlock(&data->lock);
return 0;
}
@ -1324,10 +1365,13 @@ static void w83627hf_init_client(struct i2c_client *client)
data->vid = (lo & 0x0f) | ((hi & 0x01) << 4);
} else if (w83627thf == data->type) {
data->vid = w83627thf_read_gpio5(client);
} else if (w83687thf == data->type) {
data->vid = w83687thf_read_vid(client);
}
/* Read VRM & OVT Config only once */
if (w83627thf == data->type || w83637hf == data->type) {
if (w83627thf == data->type || w83637hf == data->type
|| w83687thf == data->type) {
data->vrm_ovt =
w83627hf_read_value(client, W83627THF_REG_VRM_OVT_CFG);
}
@ -1387,14 +1431,14 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev)
struct w83627hf_data *data = i2c_get_clientdata(client);
int i;
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
|| !data->valid) {
for (i = 0; i <= 8; i++) {
/* skip missing sensors */
if (((data->type == w83697hf) && (i == 1)) ||
((data->type == w83627thf || data->type == w83637hf)
((data->type != w83627hf && data->type != w83697hf)
&& (i == 5 || i == 6)))
continue;
data->in[i] =
@ -1470,7 +1514,7 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev)
data->valid = 1;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return data;
}

View File

@ -42,6 +42,7 @@
#include <linux/hwmon.h>
#include <linux/hwmon-vid.h>
#include <linux/err.h>
#include <linux/mutex.h>
#include <asm/io.h>
#include "lm75.h"
@ -56,6 +57,10 @@ I2C_CLIENT_INSMOD_5(w83781d, w83782d, w83783s, w83627hf, as99127f);
I2C_CLIENT_MODULE_PARM(force_subclients, "List of subclient addresses: "
"{bus, clientaddr, subclientaddr1, subclientaddr2}");
static int reset;
module_param(reset, bool, 0);
MODULE_PARM_DESC(reset, "Set to one to reset chip on load");
static int init = 1;
module_param(init, bool, 0);
MODULE_PARM_DESC(init, "Set to zero to bypass chip initialization");
@ -226,10 +231,10 @@ DIV_TO_REG(long val, enum chips type)
struct w83781d_data {
struct i2c_client client;
struct class_device *class_dev;
struct semaphore lock;
struct mutex lock;
enum chips type;
struct semaphore update_lock;
struct mutex update_lock;
char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */
@ -267,9 +272,8 @@ static int w83781d_isa_attach_adapter(struct i2c_adapter *adapter);
static int w83781d_detect(struct i2c_adapter *adapter, int address, int kind);
static int w83781d_detach_client(struct i2c_client *client);
static int w83781d_read_value(struct i2c_client *client, u16 register);
static int w83781d_write_value(struct i2c_client *client, u16 register,
u16 value);
static int w83781d_read_value(struct i2c_client *client, u16 reg);
static int w83781d_write_value(struct i2c_client *client, u16 reg, u16 value);
static struct w83781d_data *w83781d_update_device(struct device *dev);
static void w83781d_init_client(struct i2c_client *client);
@ -311,11 +315,11 @@ static ssize_t store_in_##reg (struct device *dev, const char *buf, size_t count
\
val = simple_strtoul(buf, NULL, 10) / 10; \
\
down(&data->update_lock); \
mutex_lock(&data->update_lock); \
data->in_##reg[nr] = IN_TO_REG(val); \
w83781d_write_value(client, W83781D_REG_IN_##REG(nr), data->in_##reg[nr]); \
\
up(&data->update_lock); \
mutex_unlock(&data->update_lock); \
return count; \
}
store_in_reg(MIN, min);
@ -381,13 +385,13 @@ store_fan_min(struct device *dev, const char *buf, size_t count, int nr)
val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->fan_min[nr - 1] =
FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr - 1]));
w83781d_write_value(client, W83781D_REG_FAN_MIN(nr),
data->fan_min[nr - 1]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -446,7 +450,7 @@ static ssize_t store_temp_##reg (struct device *dev, const char *buf, size_t cou
\
val = simple_strtol(buf, NULL, 10); \
\
down(&data->update_lock); \
mutex_lock(&data->update_lock); \
\
if (nr >= 2) { /* TEMP2 and TEMP3 */ \
data->temp_##reg##_add[nr-2] = LM75_TEMP_TO_REG(val); \
@ -458,7 +462,7 @@ static ssize_t store_temp_##reg (struct device *dev, const char *buf, size_t cou
data->temp_##reg); \
} \
\
up(&data->update_lock); \
mutex_unlock(&data->update_lock); \
return count; \
}
store_temp_reg(OVER, max);
@ -571,7 +575,7 @@ store_beep_reg(struct device *dev, const char *buf, size_t count,
val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (update_mask == BEEP_MASK) { /* We are storing beep_mask */
data->beep_mask = BEEP_MASK_TO_REG(val, data->type);
@ -592,7 +596,7 @@ store_beep_reg(struct device *dev, const char *buf, size_t count,
w83781d_write_value(client, W83781D_REG_BEEP_INTS2,
val2 | data->beep_enable << 7);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -637,7 +641,7 @@ store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr)
u8 reg;
unsigned long val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
/* Save fan_min */
min = FAN_FROM_REG(data->fan_min[nr],
@ -662,7 +666,7 @@ store_fan_div_reg(struct device *dev, const char *buf, size_t count, int nr)
data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
w83781d_write_value(client, W83781D_REG_FAN_MIN(nr+1), data->fan_min[nr]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -709,10 +713,10 @@ store_pwm_reg(struct device *dev, const char *buf, size_t count, int nr)
val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
data->pwm[nr - 1] = PWM_TO_REG(val);
w83781d_write_value(client, W83781D_REG_PWM(nr), data->pwm[nr - 1]);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -725,7 +729,7 @@ store_pwmenable_reg(struct device *dev, const char *buf, size_t count, int nr)
val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
switch (val) {
case 0:
@ -742,11 +746,11 @@ store_pwmenable_reg(struct device *dev, const char *buf, size_t count, int nr)
break;
default:
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return -EINVAL;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -808,7 +812,7 @@ store_sensor_reg(struct device *dev, const char *buf, size_t count, int nr)
val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
switch (val) {
case 1: /* PII/Celeron diode */
@ -841,7 +845,7 @@ store_sensor_reg(struct device *dev, const char *buf, size_t count, int nr)
break;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -1073,7 +1077,7 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
new_client = &data->client;
i2c_set_clientdata(new_client, data);
new_client->addr = address;
init_MUTEX(&data->lock);
mutex_init(&data->lock);
new_client->adapter = adapter;
new_client->driver = is_isa ? &w83781d_isa_driver : &w83781d_driver;
new_client->flags = 0;
@ -1178,7 +1182,7 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
data->type = kind;
data->valid = 0;
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
@ -1325,7 +1329,7 @@ w83781d_read_value(struct i2c_client *client, u16 reg)
int res, word_sized, bank;
struct i2c_client *cl;
down(&data->lock);
mutex_lock(&data->lock);
if (i2c_is_isa_client(client)) {
word_sized = (((reg & 0xff00) == 0x100)
|| ((reg & 0xff00) == 0x200))
@ -1383,7 +1387,7 @@ w83781d_read_value(struct i2c_client *client, u16 reg)
if (bank > 2)
i2c_smbus_write_byte_data(client, W83781D_REG_BANK, 0);
}
up(&data->lock);
mutex_unlock(&data->lock);
return res;
}
@ -1394,7 +1398,7 @@ w83781d_write_value(struct i2c_client *client, u16 reg, u16 value)
int word_sized, bank;
struct i2c_client *cl;
down(&data->lock);
mutex_lock(&data->lock);
if (i2c_is_isa_client(client)) {
word_sized = (((reg & 0xff00) == 0x100)
|| ((reg & 0xff00) == 0x200))
@ -1447,7 +1451,7 @@ w83781d_write_value(struct i2c_client *client, u16 reg, u16 value)
if (bank > 2)
i2c_smbus_write_byte_data(client, W83781D_REG_BANK, 0);
}
up(&data->lock);
mutex_unlock(&data->lock);
return 0;
}
@ -1459,8 +1463,17 @@ w83781d_init_client(struct i2c_client *client)
int type = data->type;
u8 tmp;
if (init && type != as99127f) { /* this resets registers we don't have
if (reset && type != as99127f) { /* this resets registers we don't have
documentation for on the as99127f */
/* Resetting the chip has been the default for a long time,
but it causes the BIOS initializations (fan clock dividers,
thermal sensor types...) to be lost, so it is now optional.
It might even go away if nobody reports it as being useful,
as I see very little reason why this would be needed at
all. */
dev_info(&client->dev, "If reset=1 solved a problem you were "
"having, please report!\n");
/* save these registers */
i = w83781d_read_value(client, W83781D_REG_BEEP_CONFIG);
p = w83781d_read_value(client, W83781D_REG_PWMCLK12);
@ -1477,6 +1490,13 @@ w83781d_init_client(struct i2c_client *client)
w83781d_write_value(client, W83781D_REG_BEEP_INTS2, 0);
}
/* Disable power-on abnormal beep, as advised by the datasheet.
Already done if reset=1. */
if (init && !reset && type != as99127f) {
i = w83781d_read_value(client, W83781D_REG_BEEP_CONFIG);
w83781d_write_value(client, W83781D_REG_BEEP_CONFIG, i | 0x80);
}
data->vrm = vid_which_vrm();
if ((type != w83781d) && (type != as99127f)) {
@ -1533,7 +1553,7 @@ static struct w83781d_data *w83781d_update_device(struct device *dev)
struct w83781d_data *data = i2c_get_clientdata(client);
int i;
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
|| !data->valid) {
@ -1641,7 +1661,7 @@ static struct w83781d_data *w83781d_update_device(struct device *dev)
data->valid = 1;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return data;
}

View File

@ -43,6 +43,7 @@
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
/* Addresses to scan */
static unsigned short normal_i2c[] = { 0x2c, 0x2d, 0x2e, 0x2f, I2C_CLIENT_END };
@ -271,7 +272,7 @@ struct w83792d_data {
struct class_device *class_dev;
enum chips type;
struct semaphore update_lock;
struct mutex update_lock;
char valid; /* !=0 if following fields are valid */
unsigned long last_updated; /* In jiffies */
@ -382,30 +383,40 @@ static ssize_t store_in_##reg (struct device *dev, \
store_in_reg(MIN, min);
store_in_reg(MAX, max);
#define sysfs_in_reg(offset) \
static SENSOR_DEVICE_ATTR(in##offset##_input, S_IRUGO, show_in, \
NULL, offset); \
static SENSOR_DEVICE_ATTR(in##offset##_min, S_IRUGO | S_IWUSR, \
show_in_min, store_in_min, offset); \
static SENSOR_DEVICE_ATTR(in##offset##_max, S_IRUGO | S_IWUSR, \
show_in_max, store_in_max, offset);
static struct sensor_device_attribute sda_in_input[] = {
SENSOR_ATTR(in0_input, S_IRUGO, show_in, NULL, 0),
SENSOR_ATTR(in1_input, S_IRUGO, show_in, NULL, 1),
SENSOR_ATTR(in2_input, S_IRUGO, show_in, NULL, 2),
SENSOR_ATTR(in3_input, S_IRUGO, show_in, NULL, 3),
SENSOR_ATTR(in4_input, S_IRUGO, show_in, NULL, 4),
SENSOR_ATTR(in5_input, S_IRUGO, show_in, NULL, 5),
SENSOR_ATTR(in6_input, S_IRUGO, show_in, NULL, 6),
SENSOR_ATTR(in7_input, S_IRUGO, show_in, NULL, 7),
SENSOR_ATTR(in8_input, S_IRUGO, show_in, NULL, 8),
};
static struct sensor_device_attribute sda_in_min[] = {
SENSOR_ATTR(in0_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 0),
SENSOR_ATTR(in1_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 1),
SENSOR_ATTR(in2_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 2),
SENSOR_ATTR(in3_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 3),
SENSOR_ATTR(in4_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 4),
SENSOR_ATTR(in5_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 5),
SENSOR_ATTR(in6_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 6),
SENSOR_ATTR(in7_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 7),
SENSOR_ATTR(in8_min, S_IWUSR | S_IRUGO, show_in_min, store_in_min, 8),
};
static struct sensor_device_attribute sda_in_max[] = {
SENSOR_ATTR(in0_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 0),
SENSOR_ATTR(in1_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 1),
SENSOR_ATTR(in2_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 2),
SENSOR_ATTR(in3_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 3),
SENSOR_ATTR(in4_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 4),
SENSOR_ATTR(in5_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 5),
SENSOR_ATTR(in6_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 6),
SENSOR_ATTR(in7_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 7),
SENSOR_ATTR(in8_max, S_IWUSR | S_IRUGO, show_in_max, store_in_max, 8),
};
sysfs_in_reg(0);
sysfs_in_reg(1);
sysfs_in_reg(2);
sysfs_in_reg(3);
sysfs_in_reg(4);
sysfs_in_reg(5);
sysfs_in_reg(6);
sysfs_in_reg(7);
sysfs_in_reg(8);
#define device_create_file_in(client, offset) \
do { \
device_create_file(&client->dev, &sensor_dev_attr_in##offset##_input.dev_attr); \
device_create_file(&client->dev, &sensor_dev_attr_in##offset##_max.dev_attr); \
device_create_file(&client->dev, &sensor_dev_attr_in##offset##_min.dev_attr); \
} while (0)
#define show_fan_reg(reg) \
static ssize_t show_##reg (struct device *dev, struct device_attribute *attr, \
@ -486,28 +497,33 @@ store_fan_div(struct device *dev, struct device_attribute *attr,
return count;
}
#define sysfs_fan(offset) \
static SENSOR_DEVICE_ATTR(fan##offset##_input, S_IRUGO, show_fan, NULL, \
offset); \
static SENSOR_DEVICE_ATTR(fan##offset##_div, S_IRUGO | S_IWUSR, \
show_fan_div, store_fan_div, offset); \
static SENSOR_DEVICE_ATTR(fan##offset##_min, S_IRUGO | S_IWUSR, \
show_fan_min, store_fan_min, offset);
sysfs_fan(1);
sysfs_fan(2);
sysfs_fan(3);
sysfs_fan(4);
sysfs_fan(5);
sysfs_fan(6);
sysfs_fan(7);
#define device_create_file_fan(client, offset) \
do { \
device_create_file(&client->dev, &sensor_dev_attr_fan##offset##_input.dev_attr); \
device_create_file(&client->dev, &sensor_dev_attr_fan##offset##_div.dev_attr); \
device_create_file(&client->dev, &sensor_dev_attr_fan##offset##_min.dev_attr); \
} while (0)
static struct sensor_device_attribute sda_fan_input[] = {
SENSOR_ATTR(fan1_input, S_IRUGO, show_fan, NULL, 1),
SENSOR_ATTR(fan2_input, S_IRUGO, show_fan, NULL, 2),
SENSOR_ATTR(fan3_input, S_IRUGO, show_fan, NULL, 3),
SENSOR_ATTR(fan4_input, S_IRUGO, show_fan, NULL, 4),
SENSOR_ATTR(fan5_input, S_IRUGO, show_fan, NULL, 5),
SENSOR_ATTR(fan6_input, S_IRUGO, show_fan, NULL, 6),
SENSOR_ATTR(fan7_input, S_IRUGO, show_fan, NULL, 7),
};
static struct sensor_device_attribute sda_fan_min[] = {
SENSOR_ATTR(fan1_min, S_IWUSR | S_IRUGO, show_fan_min, store_fan_min, 1),
SENSOR_ATTR(fan2_min, S_IWUSR | S_IRUGO, show_fan_min, store_fan_min, 2),
SENSOR_ATTR(fan3_min, S_IWUSR | S_IRUGO, show_fan_min, store_fan_min, 3),
SENSOR_ATTR(fan4_min, S_IWUSR | S_IRUGO, show_fan_min, store_fan_min, 4),
SENSOR_ATTR(fan5_min, S_IWUSR | S_IRUGO, show_fan_min, store_fan_min, 5),
SENSOR_ATTR(fan6_min, S_IWUSR | S_IRUGO, show_fan_min, store_fan_min, 6),
SENSOR_ATTR(fan7_min, S_IWUSR | S_IRUGO, show_fan_min, store_fan_min, 7),
};
static struct sensor_device_attribute sda_fan_div[] = {
SENSOR_ATTR(fan1_div, S_IWUSR | S_IRUGO, show_fan_div, store_fan_div, 1),
SENSOR_ATTR(fan2_div, S_IWUSR | S_IRUGO, show_fan_div, store_fan_div, 2),
SENSOR_ATTR(fan3_div, S_IWUSR | S_IRUGO, show_fan_div, store_fan_div, 3),
SENSOR_ATTR(fan4_div, S_IWUSR | S_IRUGO, show_fan_div, store_fan_div, 4),
SENSOR_ATTR(fan5_div, S_IWUSR | S_IRUGO, show_fan_div, store_fan_div, 5),
SENSOR_ATTR(fan6_div, S_IWUSR | S_IRUGO, show_fan_div, store_fan_div, 6),
SENSOR_ATTR(fan7_div, S_IWUSR | S_IRUGO, show_fan_div, store_fan_div, 7),
};
/* read/write the temperature1, includes measured value and limits */
@ -539,21 +555,6 @@ static ssize_t store_temp1(struct device *dev, struct device_attribute *attr,
return count;
}
static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp1, NULL, 0);
static SENSOR_DEVICE_ATTR(temp1_max, S_IRUGO | S_IWUSR, show_temp1,
store_temp1, 1);
static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp1,
store_temp1, 2);
#define device_create_file_temp1(client) \
do { \
device_create_file(&client->dev, &sensor_dev_attr_temp1_input.dev_attr); \
device_create_file(&client->dev, &sensor_dev_attr_temp1_max.dev_attr); \
device_create_file(&client->dev, &sensor_dev_attr_temp1_max_hyst.dev_attr); \
} while (0)
/* read/write the temperature2-3, includes measured value and limits */
static ssize_t show_temp23(struct device *dev, struct device_attribute *attr,
@ -590,25 +591,23 @@ static ssize_t store_temp23(struct device *dev, struct device_attribute *attr,
return count;
}
#define sysfs_temp23(name,idx) \
static SENSOR_DEVICE_ATTR_2(name##_input, S_IRUGO, show_temp23, NULL, \
idx, 0); \
static SENSOR_DEVICE_ATTR_2(name##_max, S_IRUGO | S_IWUSR, \
show_temp23, store_temp23, idx, 2); \
static SENSOR_DEVICE_ATTR_2(name##_max_hyst, S_IRUGO | S_IWUSR, \
show_temp23, store_temp23, idx, 4);
static struct sensor_device_attribute_2 sda_temp_input[] = {
SENSOR_ATTR_2(temp1_input, S_IRUGO, show_temp1, NULL, 0, 0),
SENSOR_ATTR_2(temp2_input, S_IRUGO, show_temp23, NULL, 0, 0),
SENSOR_ATTR_2(temp3_input, S_IRUGO, show_temp23, NULL, 1, 0),
};
sysfs_temp23(temp2,0)
sysfs_temp23(temp3,1)
#define device_create_file_temp_add(client, offset) \
do { \
device_create_file(&client->dev, &sensor_dev_attr_temp##offset##_input.dev_attr); \
device_create_file(&client->dev, &sensor_dev_attr_temp##offset##_max.dev_attr); \
device_create_file(&client->dev, \
&sensor_dev_attr_temp##offset##_max_hyst.dev_attr); \
} while (0)
static struct sensor_device_attribute_2 sda_temp_max[] = {
SENSOR_ATTR_2(temp1_max, S_IRUGO | S_IWUSR, show_temp1, store_temp1, 0, 1),
SENSOR_ATTR_2(temp2_max, S_IRUGO | S_IWUSR, show_temp23, store_temp23, 0, 2),
SENSOR_ATTR_2(temp3_max, S_IRUGO | S_IWUSR, show_temp23, store_temp23, 1, 2),
};
static struct sensor_device_attribute_2 sda_temp_max_hyst[] = {
SENSOR_ATTR_2(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp1, store_temp1, 0, 2),
SENSOR_ATTR_2(temp2_max_hyst, S_IRUGO | S_IWUSR, show_temp23, store_temp23, 0, 4),
SENSOR_ATTR_2(temp3_max_hyst, S_IRUGO | S_IWUSR, show_temp23, store_temp23, 1, 4),
};
/* get reatime status of all sensors items: voltage, temp, fan */
static ssize_t
@ -620,10 +619,6 @@ show_alarms_reg(struct device *dev, struct device_attribute *attr, char *buf)
static
DEVICE_ATTR(alarms, S_IRUGO, show_alarms_reg, NULL);
#define device_create_file_alarms(client) \
device_create_file(&client->dev, &dev_attr_alarms);
static ssize_t
show_pwm(struct device *dev, struct device_attribute *attr,
@ -711,26 +706,19 @@ store_pwmenable(struct device *dev, struct device_attribute *attr,
return count;
}
#define sysfs_pwm(offset) \
static SENSOR_DEVICE_ATTR(pwm##offset, S_IRUGO | S_IWUSR, \
show_pwm, store_pwm, offset); \
static SENSOR_DEVICE_ATTR(pwm##offset##_enable, S_IRUGO | S_IWUSR, \
show_pwmenable, store_pwmenable, offset); \
sysfs_pwm(1);
sysfs_pwm(2);
sysfs_pwm(3);
#define device_create_file_pwm(client, offset) \
do { \
device_create_file(&client->dev, &sensor_dev_attr_pwm##offset.dev_attr); \
} while (0)
#define device_create_file_pwmenable(client, offset) \
do { \
device_create_file(&client->dev, &sensor_dev_attr_pwm##offset##_enable.dev_attr); \
} while (0)
static struct sensor_device_attribute sda_pwm[] = {
SENSOR_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1),
SENSOR_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2),
SENSOR_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 3),
};
static struct sensor_device_attribute sda_pwm_enable[] = {
SENSOR_ATTR(pwm1_enable, S_IWUSR | S_IRUGO,
show_pwmenable, store_pwmenable, 1),
SENSOR_ATTR(pwm2_enable, S_IWUSR | S_IRUGO,
show_pwmenable, store_pwmenable, 2),
SENSOR_ATTR(pwm3_enable, S_IWUSR | S_IRUGO,
show_pwmenable, store_pwmenable, 3),
};
static ssize_t
@ -764,18 +752,14 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr,
return count;
}
#define sysfs_pwm_mode(offset) \
static SENSOR_DEVICE_ATTR(pwm##offset##_mode, S_IRUGO | S_IWUSR, \
show_pwm_mode, store_pwm_mode, offset);
sysfs_pwm_mode(1);
sysfs_pwm_mode(2);
sysfs_pwm_mode(3);
#define device_create_file_pwm_mode(client, offset) \
do { \
device_create_file(&client->dev, &sensor_dev_attr_pwm##offset##_mode.dev_attr); \
} while (0)
static struct sensor_device_attribute sda_pwm_mode[] = {
SENSOR_ATTR(pwm1_mode, S_IWUSR | S_IRUGO,
show_pwm_mode, store_pwm_mode, 1),
SENSOR_ATTR(pwm2_mode, S_IWUSR | S_IRUGO,
show_pwm_mode, store_pwm_mode, 2),
SENSOR_ATTR(pwm3_mode, S_IWUSR | S_IRUGO,
show_pwm_mode, store_pwm_mode, 3),
};
static ssize_t
@ -788,12 +772,6 @@ show_regs_chassis(struct device *dev, struct device_attribute *attr,
static DEVICE_ATTR(chassis, S_IRUGO, show_regs_chassis, NULL);
#define device_create_file_chassis(client) \
do { \
device_create_file(&client->dev, &dev_attr_chassis); \
} while (0)
static ssize_t
show_chassis_clear(struct device *dev, struct device_attribute *attr, char *buf)
{
@ -824,13 +802,6 @@ store_chassis_clear(struct device *dev, struct device_attribute *attr,
static DEVICE_ATTR(chassis_clear, S_IRUGO | S_IWUSR,
show_chassis_clear, store_chassis_clear);
#define device_create_file_chassis_clear(client) \
do { \
device_create_file(&client->dev, &dev_attr_chassis_clear); \
} while (0)
/* For Smart Fan I / Thermal Cruise */
static ssize_t
show_thermal_cruise(struct device *dev, struct device_attribute *attr,
@ -864,20 +835,14 @@ store_thermal_cruise(struct device *dev, struct device_attribute *attr,
return count;
}
#define sysfs_thermal_cruise(offset) \
static SENSOR_DEVICE_ATTR(thermal_cruise##offset, S_IRUGO | S_IWUSR, \
show_thermal_cruise, store_thermal_cruise, offset);
sysfs_thermal_cruise(1);
sysfs_thermal_cruise(2);
sysfs_thermal_cruise(3);
#define device_create_file_thermal_cruise(client, offset) \
do { \
device_create_file(&client->dev, \
&sensor_dev_attr_thermal_cruise##offset.dev_attr); \
} while (0)
static struct sensor_device_attribute sda_thermal_cruise[] = {
SENSOR_ATTR(thermal_cruise1, S_IWUSR | S_IRUGO,
show_thermal_cruise, store_thermal_cruise, 1),
SENSOR_ATTR(thermal_cruise2, S_IWUSR | S_IRUGO,
show_thermal_cruise, store_thermal_cruise, 2),
SENSOR_ATTR(thermal_cruise3, S_IWUSR | S_IRUGO,
show_thermal_cruise, store_thermal_cruise, 3),
};
/* For Smart Fan I/Thermal Cruise and Smart Fan II */
static ssize_t
@ -916,19 +881,14 @@ store_tolerance(struct device *dev, struct device_attribute *attr,
return count;
}
#define sysfs_tolerance(offset) \
static SENSOR_DEVICE_ATTR(tolerance##offset, S_IRUGO | S_IWUSR, \
show_tolerance, store_tolerance, offset);
sysfs_tolerance(1);
sysfs_tolerance(2);
sysfs_tolerance(3);
#define device_create_file_tolerance(client, offset) \
do { \
device_create_file(&client->dev, &sensor_dev_attr_tolerance##offset.dev_attr); \
} while (0)
static struct sensor_device_attribute sda_tolerance[] = {
SENSOR_ATTR(tolerance1, S_IWUSR | S_IRUGO,
show_tolerance, store_tolerance, 1),
SENSOR_ATTR(tolerance2, S_IWUSR | S_IRUGO,
show_tolerance, store_tolerance, 2),
SENSOR_ATTR(tolerance3, S_IWUSR | S_IRUGO,
show_tolerance, store_tolerance, 3),
};
/* For Smart Fan II */
static ssize_t
@ -964,28 +924,34 @@ store_sf2_point(struct device *dev, struct device_attribute *attr,
return count;
}
#define sysfs_sf2_point(offset, index) \
static SENSOR_DEVICE_ATTR_2(sf2_point##offset##_fan##index, S_IRUGO | S_IWUSR, \
show_sf2_point, store_sf2_point, offset, index);
static struct sensor_device_attribute_2 sda_sf2_point[] = {
SENSOR_ATTR_2(sf2_point1_fan1, S_IRUGO | S_IWUSR,
show_sf2_point, store_sf2_point, 1, 1),
SENSOR_ATTR_2(sf2_point2_fan1, S_IRUGO | S_IWUSR,
show_sf2_point, store_sf2_point, 2, 1),
SENSOR_ATTR_2(sf2_point3_fan1, S_IRUGO | S_IWUSR,
show_sf2_point, store_sf2_point, 3, 1),
SENSOR_ATTR_2(sf2_point4_fan1, S_IRUGO | S_IWUSR,
show_sf2_point, store_sf2_point, 4, 1),
sysfs_sf2_point(1, 1); /* Fan1 */
sysfs_sf2_point(2, 1); /* Fan1 */
sysfs_sf2_point(3, 1); /* Fan1 */
sysfs_sf2_point(4, 1); /* Fan1 */
sysfs_sf2_point(1, 2); /* Fan2 */
sysfs_sf2_point(2, 2); /* Fan2 */
sysfs_sf2_point(3, 2); /* Fan2 */
sysfs_sf2_point(4, 2); /* Fan2 */
sysfs_sf2_point(1, 3); /* Fan3 */
sysfs_sf2_point(2, 3); /* Fan3 */
sysfs_sf2_point(3, 3); /* Fan3 */
sysfs_sf2_point(4, 3); /* Fan3 */
SENSOR_ATTR_2(sf2_point1_fan2, S_IRUGO | S_IWUSR,
show_sf2_point, store_sf2_point, 1, 2),
SENSOR_ATTR_2(sf2_point2_fan2, S_IRUGO | S_IWUSR,
show_sf2_point, store_sf2_point, 2, 2),
SENSOR_ATTR_2(sf2_point3_fan2, S_IRUGO | S_IWUSR,
show_sf2_point, store_sf2_point, 3, 2),
SENSOR_ATTR_2(sf2_point4_fan2, S_IRUGO | S_IWUSR,
show_sf2_point, store_sf2_point, 4, 2),
#define device_create_file_sf2_point(client, offset, index) \
do { \
device_create_file(&client->dev, \
&sensor_dev_attr_sf2_point##offset##_fan##index.dev_attr); \
} while (0)
SENSOR_ATTR_2(sf2_point1_fan3, S_IRUGO | S_IWUSR,
show_sf2_point, store_sf2_point, 1, 3),
SENSOR_ATTR_2(sf2_point2_fan3, S_IRUGO | S_IWUSR,
show_sf2_point, store_sf2_point, 2, 3),
SENSOR_ATTR_2(sf2_point3_fan3, S_IRUGO | S_IWUSR,
show_sf2_point, store_sf2_point, 3, 3),
SENSOR_ATTR_2(sf2_point4_fan3, S_IRUGO | S_IWUSR,
show_sf2_point, store_sf2_point, 4, 3),
};
static ssize_t
@ -1026,26 +992,28 @@ store_sf2_level(struct device *dev, struct device_attribute *attr,
return count;
}
#define sysfs_sf2_level(offset, index) \
static SENSOR_DEVICE_ATTR_2(sf2_level##offset##_fan##index, S_IRUGO | S_IWUSR, \
show_sf2_level, store_sf2_level, offset, index);
static struct sensor_device_attribute_2 sda_sf2_level[] = {
SENSOR_ATTR_2(sf2_level1_fan1, S_IRUGO | S_IWUSR,
show_sf2_level, store_sf2_level, 1, 1),
SENSOR_ATTR_2(sf2_level2_fan1, S_IRUGO | S_IWUSR,
show_sf2_level, store_sf2_level, 2, 1),
SENSOR_ATTR_2(sf2_level3_fan1, S_IRUGO | S_IWUSR,
show_sf2_level, store_sf2_level, 3, 1),
sysfs_sf2_level(1, 1); /* Fan1 */
sysfs_sf2_level(2, 1); /* Fan1 */
sysfs_sf2_level(3, 1); /* Fan1 */
sysfs_sf2_level(1, 2); /* Fan2 */
sysfs_sf2_level(2, 2); /* Fan2 */
sysfs_sf2_level(3, 2); /* Fan2 */
sysfs_sf2_level(1, 3); /* Fan3 */
sysfs_sf2_level(2, 3); /* Fan3 */
sysfs_sf2_level(3, 3); /* Fan3 */
#define device_create_file_sf2_level(client, offset, index) \
do { \
device_create_file(&client->dev, \
&sensor_dev_attr_sf2_level##offset##_fan##index.dev_attr); \
} while (0)
SENSOR_ATTR_2(sf2_level1_fan2, S_IRUGO | S_IWUSR,
show_sf2_level, store_sf2_level, 1, 2),
SENSOR_ATTR_2(sf2_level2_fan2, S_IRUGO | S_IWUSR,
show_sf2_level, store_sf2_level, 2, 2),
SENSOR_ATTR_2(sf2_level3_fan2, S_IRUGO | S_IWUSR,
show_sf2_level, store_sf2_level, 3, 2),
SENSOR_ATTR_2(sf2_level1_fan3, S_IRUGO | S_IWUSR,
show_sf2_level, store_sf2_level, 1, 3),
SENSOR_ATTR_2(sf2_level2_fan3, S_IRUGO | S_IWUSR,
show_sf2_level, store_sf2_level, 2, 3),
SENSOR_ATTR_2(sf2_level3_fan3, S_IRUGO | S_IWUSR,
show_sf2_level, store_sf2_level, 3, 3),
};
/* This function is called when:
* w83792d_driver is inserted (when this module is loaded), for each
@ -1147,12 +1115,19 @@ ERROR_SC_0:
return err;
}
static void device_create_file_fan(struct device *dev, int i)
{
device_create_file(dev, &sda_fan_input[i].dev_attr);
device_create_file(dev, &sda_fan_div[i].dev_attr);
device_create_file(dev, &sda_fan_min[i].dev_attr);
}
static int
w83792d_detect(struct i2c_adapter *adapter, int address, int kind)
{
int i = 0, val1 = 0, val2;
struct i2c_client *new_client;
struct i2c_client *client;
struct device *dev;
struct w83792d_data *data;
int err = 0;
const char *client_name = "";
@ -1170,12 +1145,13 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind)
goto ERROR0;
}
new_client = &data->client;
i2c_set_clientdata(new_client, data);
new_client->addr = address;
new_client->adapter = adapter;
new_client->driver = &w83792d_driver;
new_client->flags = 0;
client = &data->client;
dev = &client->dev;
i2c_set_clientdata(client, data);
client->addr = address;
client->adapter = adapter;
client->driver = &w83792d_driver;
client->flags = 0;
/* Now, we do the remaining detection. */
@ -1184,13 +1160,12 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind)
force_*=... parameter, and the Winbond will be reset to the right
bank. */
if (kind < 0) {
if (w83792d_read_value(new_client, W83792D_REG_CONFIG) & 0x80) {
dev_warn(&new_client->dev, "Detection failed at step "
"3\n");
if (w83792d_read_value(client, W83792D_REG_CONFIG) & 0x80) {
dev_warn(dev, "Detection failed at step 3\n");
goto ERROR1;
}
val1 = w83792d_read_value(new_client, W83792D_REG_BANK);
val2 = w83792d_read_value(new_client, W83792D_REG_CHIPMAN);
val1 = w83792d_read_value(client, W83792D_REG_BANK);
val2 = w83792d_read_value(client, W83792D_REG_CHIPMAN);
/* Check for Winbond ID if in bank 0 */
if (!(val1 & 0x07)) { /* is Bank0 */
if (((!(val1 & 0x80)) && (val2 != 0xa3)) ||
@ -1200,34 +1175,33 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind)
}
/* If Winbond chip, address of chip and W83792D_REG_I2C_ADDR
should match */
if (w83792d_read_value(new_client,
if (w83792d_read_value(client,
W83792D_REG_I2C_ADDR) != address) {
dev_warn(&new_client->dev, "Detection failed "
"at step 5\n");
dev_warn(dev, "Detection failed at step 5\n");
goto ERROR1;
}
}
/* We have either had a force parameter, or we have already detected the
Winbond. Put it now into bank 0 and Vendor ID High Byte */
w83792d_write_value(new_client,
w83792d_write_value(client,
W83792D_REG_BANK,
(w83792d_read_value(new_client,
(w83792d_read_value(client,
W83792D_REG_BANK) & 0x78) | 0x80);
/* Determine the chip type. */
if (kind <= 0) {
/* get vendor ID */
val2 = w83792d_read_value(new_client, W83792D_REG_CHIPMAN);
val2 = w83792d_read_value(client, W83792D_REG_CHIPMAN);
if (val2 != 0x5c) { /* the vendor is NOT Winbond */
goto ERROR1;
}
val1 = w83792d_read_value(new_client, W83792D_REG_WCHIPID);
val1 = w83792d_read_value(client, W83792D_REG_WCHIPID);
if (val1 == 0x7a) {
kind = w83792d;
} else {
if (kind == 0)
dev_warn(&new_client->dev,
dev_warn(dev,
"w83792d: Ignoring 'force' parameter for"
" unknown chip at adapter %d, address"
" 0x%02x\n", i2c_adapter_id(adapter),
@ -1239,120 +1213,86 @@ w83792d_detect(struct i2c_adapter *adapter, int address, int kind)
if (kind == w83792d) {
client_name = "w83792d";
} else {
dev_err(&new_client->dev, "w83792d: Internal error: unknown"
dev_err(dev, "w83792d: Internal error: unknown"
" kind (%d)?!?", kind);
goto ERROR1;
}
/* Fill in the remaining client fields and put into the global list */
strlcpy(new_client->name, client_name, I2C_NAME_SIZE);
strlcpy(client->name, client_name, I2C_NAME_SIZE);
data->type = kind;
data->valid = 0;
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
if ((err = i2c_attach_client(client)))
goto ERROR1;
if ((err = w83792d_detect_subclients(adapter, address,
kind, new_client)))
kind, client)))
goto ERROR2;
/* Initialize the chip */
w83792d_init_client(new_client);
w83792d_init_client(client);
/* A few vars need to be filled upon startup */
for (i = 0; i < 7; i++) {
data->fan_min[i] = w83792d_read_value(new_client,
data->fan_min[i] = w83792d_read_value(client,
W83792D_REG_FAN_MIN[i]);
}
/* Register sysfs hooks */
data->class_dev = hwmon_device_register(&new_client->dev);
data->class_dev = hwmon_device_register(dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto ERROR3;
}
device_create_file_in(new_client, 0);
device_create_file_in(new_client, 1);
device_create_file_in(new_client, 2);
device_create_file_in(new_client, 3);
device_create_file_in(new_client, 4);
device_create_file_in(new_client, 5);
device_create_file_in(new_client, 6);
device_create_file_in(new_client, 7);
device_create_file_in(new_client, 8);
device_create_file_fan(new_client, 1);
device_create_file_fan(new_client, 2);
device_create_file_fan(new_client, 3);
for (i = 0; i < 9; i++) {
device_create_file(dev, &sda_in_input[i].dev_attr);
device_create_file(dev, &sda_in_max[i].dev_attr);
device_create_file(dev, &sda_in_min[i].dev_attr);
}
for (i = 0; i < 3; i++)
device_create_file_fan(dev, i);
/* Read GPIO enable register to check if pins for fan 4,5 are used as
GPIO */
val1 = w83792d_read_value(new_client, W83792D_REG_GPIO_EN);
val1 = w83792d_read_value(client, W83792D_REG_GPIO_EN);
if (!(val1 & 0x40))
device_create_file_fan(new_client, 4);
device_create_file_fan(dev, 3);
if (!(val1 & 0x20))
device_create_file_fan(new_client, 5);
device_create_file_fan(dev, 4);
val1 = w83792d_read_value(new_client, W83792D_REG_PIN);
val1 = w83792d_read_value(client, W83792D_REG_PIN);
if (val1 & 0x40)
device_create_file_fan(new_client, 6);
device_create_file_fan(dev, 5);
if (val1 & 0x04)
device_create_file_fan(new_client, 7);
device_create_file_fan(dev, 6);
device_create_file_temp1(new_client); /* Temp1 */
device_create_file_temp_add(new_client, 2); /* Temp2 */
device_create_file_temp_add(new_client, 3); /* Temp3 */
for (i = 0; i < 3; i++) {
device_create_file(dev, &sda_temp_input[i].dev_attr);
device_create_file(dev, &sda_temp_max[i].dev_attr);
device_create_file(dev, &sda_temp_max_hyst[i].dev_attr);
device_create_file(dev, &sda_thermal_cruise[i].dev_attr);
device_create_file(dev, &sda_tolerance[i].dev_attr);
}
device_create_file_alarms(new_client);
for (i = 0; i < ARRAY_SIZE(sda_pwm); i++) {
device_create_file(dev, &sda_pwm[i].dev_attr);
device_create_file(dev, &sda_pwm_enable[i].dev_attr);
device_create_file(dev, &sda_pwm_mode[i].dev_attr);
}
device_create_file_pwm(new_client, 1);
device_create_file_pwm(new_client, 2);
device_create_file_pwm(new_client, 3);
device_create_file(dev, &dev_attr_alarms);
device_create_file(dev, &dev_attr_chassis);
device_create_file(dev, &dev_attr_chassis_clear);
device_create_file_pwmenable(new_client, 1);
device_create_file_pwmenable(new_client, 2);
device_create_file_pwmenable(new_client, 3);
for (i = 0; i < ARRAY_SIZE(sda_sf2_point); i++)
device_create_file(dev, &sda_sf2_point[i].dev_attr);
device_create_file_pwm_mode(new_client, 1);
device_create_file_pwm_mode(new_client, 2);
device_create_file_pwm_mode(new_client, 3);
device_create_file_chassis(new_client);
device_create_file_chassis_clear(new_client);
device_create_file_thermal_cruise(new_client, 1);
device_create_file_thermal_cruise(new_client, 2);
device_create_file_thermal_cruise(new_client, 3);
device_create_file_tolerance(new_client, 1);
device_create_file_tolerance(new_client, 2);
device_create_file_tolerance(new_client, 3);
device_create_file_sf2_point(new_client, 1, 1); /* Fan1 */
device_create_file_sf2_point(new_client, 2, 1); /* Fan1 */
device_create_file_sf2_point(new_client, 3, 1); /* Fan1 */
device_create_file_sf2_point(new_client, 4, 1); /* Fan1 */
device_create_file_sf2_point(new_client, 1, 2); /* Fan2 */
device_create_file_sf2_point(new_client, 2, 2); /* Fan2 */
device_create_file_sf2_point(new_client, 3, 2); /* Fan2 */
device_create_file_sf2_point(new_client, 4, 2); /* Fan2 */
device_create_file_sf2_point(new_client, 1, 3); /* Fan3 */
device_create_file_sf2_point(new_client, 2, 3); /* Fan3 */
device_create_file_sf2_point(new_client, 3, 3); /* Fan3 */
device_create_file_sf2_point(new_client, 4, 3); /* Fan3 */
device_create_file_sf2_level(new_client, 1, 1); /* Fan1 */
device_create_file_sf2_level(new_client, 2, 1); /* Fan1 */
device_create_file_sf2_level(new_client, 3, 1); /* Fan1 */
device_create_file_sf2_level(new_client, 1, 2); /* Fan2 */
device_create_file_sf2_level(new_client, 2, 2); /* Fan2 */
device_create_file_sf2_level(new_client, 3, 2); /* Fan2 */
device_create_file_sf2_level(new_client, 1, 3); /* Fan3 */
device_create_file_sf2_level(new_client, 2, 3); /* Fan3 */
device_create_file_sf2_level(new_client, 3, 3); /* Fan3 */
for (i = 0; i < ARRAY_SIZE(sda_sf2_level); i++)
device_create_file(dev, &sda_sf2_level[i].dev_attr);
return 0;
@ -1366,7 +1306,7 @@ ERROR3:
kfree(data->lm75[1]);
}
ERROR2:
i2c_detach_client(new_client);
i2c_detach_client(client);
ERROR1:
kfree(data);
ERROR0:
@ -1434,7 +1374,7 @@ static struct w83792d_data *w83792d_update_device(struct device *dev)
int i, j;
u8 reg_array_tmp[4], pwm_array_tmp[7], reg_tmp;
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (time_after
(jiffies - data->last_updated, (unsigned long) (HZ * 3))
@ -1545,7 +1485,7 @@ static struct w83792d_data *w83792d_update_device(struct device *dev)
data->valid = 1;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
#ifdef DEBUG
w83792d_print_debug(data, dev);

View File

@ -39,6 +39,7 @@
#include <linux/hwmon.h>
#include <linux/hwmon-sysfs.h>
#include <linux/err.h>
#include <linux/mutex.h>
/* How many retries on register read error */
#define MAX_RETRIES 5
@ -107,7 +108,7 @@ static struct i2c_driver w83l785ts_driver = {
struct w83l785ts_data {
struct i2c_client client;
struct class_device *class_dev;
struct semaphore update_lock;
struct mutex update_lock;
char valid; /* zero until following fields are valid */
unsigned long last_updated; /* in jiffies */
@ -221,7 +222,7 @@ static int w83l785ts_detect(struct i2c_adapter *adapter, int address, int kind)
/* We can fill in the remaining client fields. */
strlcpy(new_client->name, "w83l785ts", I2C_NAME_SIZE);
data->valid = 0;
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
/* Default values in case the first read fails (unlikely). */
data->temp[1] = data->temp[0] = 0;
@ -299,7 +300,7 @@ static struct w83l785ts_data *w83l785ts_update_device(struct device *dev)
struct i2c_client *client = to_i2c_client(dev);
struct w83l785ts_data *data = i2c_get_clientdata(client);
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (!data->valid || time_after(jiffies, data->last_updated + HZ * 2)) {
dev_dbg(&client->dev, "Updating w83l785ts data.\n");
@ -312,7 +313,7 @@ static struct w83l785ts_data *w83l785ts_update_device(struct device *dev)
data->valid = 1;
}
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return data;
}

View File

@ -168,12 +168,14 @@ config I2C_PIIX4
help
If you say yes to this option, support will be included for the Intel
PIIX4 family of mainboard I2C interfaces. Specifically, the following
versions of the chipset are supported:
versions of the chipset are supported (note that Serverworks is part
of Broadcom):
Intel PIIX4
Intel 440MX
Serverworks OSB4
Serverworks CSB5
Serverworks CSB6
Serverworks HT-1000
SMSC Victory66
This driver can also be built as a module. If so, the module
@ -389,10 +391,11 @@ config SCx200_I2C_SDA
also be specified with a module parameter.
config SCx200_ACB
tristate "NatSemi SCx200 ACCESS.bus"
depends on I2C && PCI
tristate "Geode ACCESS.bus support"
depends on X86_32 && I2C && PCI
help
Enable the use of the ACCESS.bus controllers of a SCx200 processor.
Enable the use of the ACCESS.bus controllers on the Geode SCx200 and
SC1100 processors and the CS5535 and CS5536 Geode companion devices.
If you don't know what to do here, say N.

View File

@ -63,7 +63,6 @@
#include <linux/i2c.h>
#include <linux/init.h>
#include <asm/io.h>
#include <asm/semaphore.h>
/* ALI1535 SMBus address offsets */
@ -136,7 +135,6 @@
static struct pci_driver ali1535_driver;
static unsigned short ali1535_smba;
static DECLARE_MUTEX(i2c_ali1535_sem);
/* Detect whether a ALI1535 can be found, and initialize it, where necessary.
Note the differences between kernels with the old PCI BIOS interface and
@ -345,7 +343,6 @@ static s32 ali1535_access(struct i2c_adapter *adap, u16 addr,
int timeout;
s32 result = 0;
down(&i2c_ali1535_sem);
/* make sure SMBus is idle */
temp = inb_p(SMBHSTSTS);
for (timeout = 0;
@ -460,7 +457,6 @@ static s32 ali1535_access(struct i2c_adapter *adap, u16 addr,
break;
}
EXIT:
up(&i2c_ali1535_sem);
return result;
}

View File

@ -38,6 +38,7 @@
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/mutex.h>
extern struct i2c_adapter amd756_smbus;
@ -45,7 +46,7 @@ static struct i2c_adapter *s4882_adapter;
static struct i2c_algorithm *s4882_algo;
/* Wrapper access functions for multiplexed SMBus */
static struct semaphore amd756_lock;
static DEFINE_MUTEX(amd756_lock);
static s32 amd756_access_virt0(struct i2c_adapter * adap, u16 addr,
unsigned short flags, char read_write,
@ -59,12 +60,12 @@ static s32 amd756_access_virt0(struct i2c_adapter * adap, u16 addr,
|| addr == 0x18)
return -1;
down(&amd756_lock);
mutex_lock(&amd756_lock);
error = amd756_smbus.algo->smbus_xfer(adap, addr, flags, read_write,
command, size, data);
up(&amd756_lock);
mutex_unlock(&amd756_lock);
return error;
}
@ -87,7 +88,7 @@ static inline s32 amd756_access_channel(struct i2c_adapter * adap, u16 addr,
if (addr != 0x4c && (addr & 0xfc) != 0x50 && (addr & 0xfc) != 0x30)
return -1;
down(&amd756_lock);
mutex_lock(&amd756_lock);
if (last_channels != channels) {
union i2c_smbus_data mplxdata;
@ -105,7 +106,7 @@ static inline s32 amd756_access_channel(struct i2c_adapter * adap, u16 addr,
command, size, data);
UNLOCK:
up(&amd756_lock);
mutex_unlock(&amd756_lock);
return error;
}
@ -166,8 +167,6 @@ static int __init amd756_s4882_init(void)
}
printk(KERN_INFO "Enabling SMBus multiplexing for Tyan S4882\n");
init_MUTEX(&amd756_lock);
/* Define the 5 virtual adapters and algorithms structures */
if (!(s4882_adapter = kzalloc(5 * sizeof(struct i2c_adapter),
GFP_KERNEL))) {

View File

@ -1,85 +0,0 @@
/*
* linux/drivers/i2c/i2c-frodo.c
*
* Author: Abraham van der Merwe <abraham@2d3d.co.za>
*
* An I2C adapter driver for the 2d3D, Inc. StrongARM SA-1110
* Development board (Frodo).
*
* This source code is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* version 2 as published by the Free Software Foundation.
*/
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/i2c-algo-bit.h>
#include <asm/hardware.h>
static void frodo_setsda (void *data,int state)
{
if (state)
FRODO_CPLD_I2C |= FRODO_I2C_SDA_OUT;
else
FRODO_CPLD_I2C &= ~FRODO_I2C_SDA_OUT;
}
static void frodo_setscl (void *data,int state)
{
if (state)
FRODO_CPLD_I2C |= FRODO_I2C_SCL_OUT;
else
FRODO_CPLD_I2C &= ~FRODO_I2C_SCL_OUT;
}
static int frodo_getsda (void *data)
{
return ((FRODO_CPLD_I2C & FRODO_I2C_SDA_IN) != 0);
}
static int frodo_getscl (void *data)
{
return ((FRODO_CPLD_I2C & FRODO_I2C_SCL_IN) != 0);
}
static struct i2c_algo_bit_data bit_frodo_data = {
.setsda = frodo_setsda,
.setscl = frodo_setscl,
.getsda = frodo_getsda,
.getscl = frodo_getscl,
.udelay = 80,
.mdelay = 80,
.timeout = HZ
};
static struct i2c_adapter frodo_ops = {
.owner = THIS_MODULE,
.id = I2C_HW_B_FRODO,
.algo_data = &bit_frodo_data,
.dev = {
.name = "Frodo adapter driver",
},
};
static int __init i2c_frodo_init (void)
{
return i2c_bit_add_bus(&frodo_ops);
}
static void __exit i2c_frodo_exit (void)
{
i2c_bit_del_bus(&frodo_ops);
}
MODULE_AUTHOR ("Abraham van der Merwe <abraham@2d3d.co.za>");
MODULE_DESCRIPTION ("I2C-Bus adapter routines for Frodo");
MODULE_LICENSE ("GPL");
module_init (i2c_frodo_init);
module_exit (i2c_frodo_exit);

View File

@ -125,7 +125,7 @@ int i2c_isa_del_driver(struct i2c_driver *driver)
static int __init i2c_isa_init(void)
{
init_MUTEX(&isa_adapter.clist_lock);
mutex_init(&isa_adapter.clist_lock);
INIT_LIST_HEAD(&isa_adapter.clients);
isa_adapter.nr = ANY_I2C_ISA_BUS;

View File

@ -200,9 +200,7 @@ static struct i2c_adapter iic_ite_ops = {
.owner = THIS_MODULE,
.id = I2C_HW_I_IIC,
.algo_data = &iic_ite_data,
.dev = {
.name = "ITE IIC adapter",
},
.name = "ITE IIC adapter",
};
/* Called when the module is loaded. This function starts the

View File

@ -126,6 +126,7 @@ static int ixp4xx_i2c_probe(struct platform_device *plat_dev)
drv_data->algo_data.timeout = 100;
drv_data->adapter.id = I2C_HW_B_IXP4XX;
drv_data->adapter.class = I2C_CLASS_HWMON;
strlcpy(drv_data->adapter.name, plat_dev->dev.driver->name,
I2C_NAME_SIZE);
drv_data->adapter.algo_data = &drv_data->algo_data;

View File

@ -22,7 +22,7 @@
/*
Supports:
Intel PIIX4, 440MX
Serverworks OSB4, CSB5, CSB6
Serverworks OSB4, CSB5, CSB6, HT-1000
SMSC Victory66
Note: we assume there can only be one device, with one SMBus interface.
@ -419,6 +419,8 @@ static struct pci_device_id piix4_ids[] = {
.driver_data = 0 },
{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6),
.driver_data = 0 },
{ PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000SB),
.driver_data = 0 },
{ PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_82443MX_3),
.driver_data = 3 },
{ PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_3),

View File

@ -647,7 +647,7 @@ static inline void i2c_pxa_start_message(struct pxa_i2c *i2c)
}
/*
* We are protected by the adapter bus semaphore.
* We are protected by the adapter bus mutex.
*/
static int i2c_pxa_do_xfer(struct pxa_i2c *i2c, struct i2c_msg *msg, int num)
{

View File

@ -1,27 +1,26 @@
/* linux/drivers/i2c/scx200_acb.c
/*
Copyright (c) 2001,2002 Christer Weinigel <wingel@nano-system.com>
National Semiconductor SCx200 ACCESS.bus support
Also supports the AMD CS5535 and AMD CS5536
Based on i2c-keywest.c which is:
Copyright (c) 2001 Benjamin Herrenschmidt <benh@kernel.crashing.org>
Copyright (c) 2000 Philip Edelbrock <phil@stimpy.netroedge.com>
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the
License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
#include <linux/module.h>
@ -32,7 +31,9 @@
#include <linux/smp_lock.h>
#include <linux/pci.h>
#include <linux/delay.h>
#include <linux/mutex.h>
#include <asm/io.h>
#include <asm/msr.h>
#include <linux/scx200.h>
@ -47,16 +48,7 @@ static int base[MAX_DEVICES] = { 0x820, 0x840 };
module_param_array(base, int, NULL, 0);
MODULE_PARM_DESC(base, "Base addresses for the ACCESS.bus controllers");
#ifdef DEBUG
#define DBG(x...) printk(KERN_DEBUG NAME ": " x)
#else
#define DBG(x...)
#endif
/* The hardware supports interrupt driven mode too, but I haven't
implemented that. */
#define POLLED_MODE 1
#define POLL_TIMEOUT (HZ)
#define POLL_TIMEOUT (HZ/5)
enum scx200_acb_state {
state_idle,
@ -79,12 +71,11 @@ static const char *scx200_acb_state_name[] = {
};
/* Physical interface */
struct scx200_acb_iface
{
struct scx200_acb_iface {
struct scx200_acb_iface *next;
struct i2c_adapter adapter;
unsigned base;
struct semaphore sem;
struct mutex mutex;
/* State machine data */
enum scx200_acb_state state;
@ -100,7 +91,7 @@ struct scx200_acb_iface
#define ACBSDA (iface->base + 0)
#define ACBST (iface->base + 1)
#define ACBST_SDAST 0x40 /* SDA Status */
#define ACBST_BER 0x20
#define ACBST_BER 0x20
#define ACBST_NEGACK 0x10 /* Negative Acknowledge */
#define ACBST_STASTR 0x08 /* Stall After Start */
#define ACBST_MASTER 0x02
@ -109,9 +100,9 @@ struct scx200_acb_iface
#define ACBCTL1 (iface->base + 3)
#define ACBCTL1_STASTRE 0x80
#define ACBCTL1_NMINTE 0x40
#define ACBCTL1_ACK 0x10
#define ACBCTL1_STOP 0x02
#define ACBCTL1_START 0x01
#define ACBCTL1_ACK 0x10
#define ACBCTL1_STOP 0x02
#define ACBCTL1_START 0x01
#define ACBADDR (iface->base + 4)
#define ACBCTL2 (iface->base + 5)
#define ACBCTL2_ENABLE 0x01
@ -122,8 +113,8 @@ static void scx200_acb_machine(struct scx200_acb_iface *iface, u8 status)
{
const char *errmsg;
DBG("state %s, status = 0x%02x\n",
scx200_acb_state_name[iface->state], status);
dev_dbg(&iface->adapter.dev, "state %s, status = 0x%02x\n",
scx200_acb_state_name[iface->state], status);
if (status & ACBST_BER) {
errmsg = "bus error";
@ -133,8 +124,17 @@ static void scx200_acb_machine(struct scx200_acb_iface *iface, u8 status)
errmsg = "not master";
goto error;
}
if (status & ACBST_NEGACK)
goto negack;
if (status & ACBST_NEGACK) {
dev_dbg(&iface->adapter.dev, "negative ack in state %s\n",
scx200_acb_state_name[iface->state]);
iface->state = state_idle;
iface->result = -ENXIO;
outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
outb(ACBST_STASTR | ACBST_NEGACK, ACBST);
return;
}
switch (iface->state) {
case state_idle:
@ -160,10 +160,10 @@ static void scx200_acb_machine(struct scx200_acb_iface *iface, u8 status)
case state_repeat_start:
outb(inb(ACBCTL1) | ACBCTL1_START, ACBCTL1);
/* fallthrough */
case state_quick:
if (iface->address_byte & 1) {
if (iface->len == 1)
if (iface->len == 1)
outb(inb(ACBCTL1) | ACBCTL1_ACK, ACBCTL1);
else
outb(inb(ACBCTL1) & ~ACBCTL1_ACK, ACBCTL1);
@ -202,26 +202,15 @@ static void scx200_acb_machine(struct scx200_acb_iface *iface, u8 status)
outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
break;
}
outb(*iface->ptr++, ACBSDA);
--iface->len;
break;
}
return;
negack:
DBG("negative acknowledge in state %s\n",
scx200_acb_state_name[iface->state]);
iface->state = state_idle;
iface->result = -ENXIO;
outb(inb(ACBCTL1) | ACBCTL1_STOP, ACBCTL1);
outb(ACBST_STASTR | ACBST_NEGACK, ACBST);
return;
error:
dev_err(&iface->adapter.dev, "%s in state %s\n", errmsg,
scx200_acb_state_name[iface->state]);
@ -231,20 +220,9 @@ static void scx200_acb_machine(struct scx200_acb_iface *iface, u8 status)
iface->needs_reset = 1;
}
static void scx200_acb_timeout(struct scx200_acb_iface *iface)
{
dev_err(&iface->adapter.dev, "timeout in state %s\n",
scx200_acb_state_name[iface->state]);
iface->state = state_idle;
iface->result = -EIO;
iface->needs_reset = 1;
}
#ifdef POLLED_MODE
static void scx200_acb_poll(struct scx200_acb_iface *iface)
{
u8 status = 0;
u8 status;
unsigned long timeout;
timeout = jiffies + POLL_TIMEOUT;
@ -254,17 +232,21 @@ static void scx200_acb_poll(struct scx200_acb_iface *iface)
scx200_acb_machine(iface, status);
return;
}
msleep(10);
yield();
}
scx200_acb_timeout(iface);
dev_err(&iface->adapter.dev, "timeout in state %s\n",
scx200_acb_state_name[iface->state]);
iface->state = state_idle;
iface->result = -EIO;
iface->needs_reset = 1;
}
#endif /* POLLED_MODE */
static void scx200_acb_reset(struct scx200_acb_iface *iface)
{
/* Disable the ACCESS.bus device and Configure the SCL
frequency: 16 clock cycles */
frequency: 16 clock cycles */
outb(0x70, ACBCTL2);
/* Polling mode */
outb(0, ACBCTL1);
@ -283,9 +265,9 @@ static void scx200_acb_reset(struct scx200_acb_iface *iface)
}
static s32 scx200_acb_smbus_xfer(struct i2c_adapter *adapter,
u16 address, unsigned short flags,
char rw, u8 command, int size,
union i2c_smbus_data *data)
u16 address, unsigned short flags,
char rw, u8 command, int size,
union i2c_smbus_data *data)
{
struct scx200_acb_iface *iface = i2c_get_adapdata(adapter);
int len;
@ -295,53 +277,47 @@ static s32 scx200_acb_smbus_xfer(struct i2c_adapter *adapter,
switch (size) {
case I2C_SMBUS_QUICK:
len = 0;
buffer = NULL;
break;
len = 0;
buffer = NULL;
break;
case I2C_SMBUS_BYTE:
if (rw == I2C_SMBUS_READ) {
len = 1;
buffer = &data->byte;
} else {
len = 1;
buffer = &command;
}
break;
len = 1;
buffer = rw ? &data->byte : &command;
break;
case I2C_SMBUS_BYTE_DATA:
len = 1;
buffer = &data->byte;
break;
len = 1;
buffer = &data->byte;
break;
case I2C_SMBUS_WORD_DATA:
len = 2;
cur_word = cpu_to_le16(data->word);
buffer = (u8 *)&cur_word;
cur_word = cpu_to_le16(data->word);
buffer = (u8 *)&cur_word;
break;
case I2C_SMBUS_BLOCK_DATA:
len = data->block[0];
buffer = &data->block[1];
len = data->block[0];
buffer = &data->block[1];
break;
default:
return -EINVAL;
}
DBG("size=%d, address=0x%x, command=0x%x, len=%d, read=%d\n",
size, address, command, len, rw == I2C_SMBUS_READ);
if (!len && rw == I2C_SMBUS_READ) {
dev_warn(&adapter->dev, "zero length read\n");
return -EINVAL;
}
if (len && !buffer) {
dev_warn(&adapter->dev, "nonzero length but no buffer\n");
return -EFAULT;
dev_dbg(&adapter->dev,
"size=%d, address=0x%x, command=0x%x, len=%d, read=%d\n",
size, address, command, len, rw);
if (!len && rw == I2C_SMBUS_READ) {
dev_dbg(&adapter->dev, "zero length read\n");
return -EINVAL;
}
down(&iface->sem);
mutex_lock(&iface->mutex);
iface->address_byte = address<<1;
if (rw == I2C_SMBUS_READ)
iface->address_byte |= 1;
iface->address_byte = (address << 1) | rw;
iface->command = command;
iface->ptr = buffer;
iface->len = len;
@ -355,25 +331,21 @@ static s32 scx200_acb_smbus_xfer(struct i2c_adapter *adapter,
else
iface->state = state_address;
#ifdef POLLED_MODE
while (iface->state != state_idle)
scx200_acb_poll(iface);
#else /* POLLED_MODE */
#error Interrupt driven mode not implemented
#endif /* POLLED_MODE */
if (iface->needs_reset)
scx200_acb_reset(iface);
rc = iface->result;
up(&iface->sem);
mutex_unlock(&iface->mutex);
if (rc == 0 && size == I2C_SMBUS_WORD_DATA && rw == I2C_SMBUS_READ)
data->word = le16_to_cpu(cur_word);
data->word = le16_to_cpu(cur_word);
#ifdef DEBUG
DBG(": transfer done, result: %d", rc);
dev_dbg(&adapter->dev, "transfer done, result: %d", rc);
if (buffer) {
int i;
printk(" data:");
@ -400,17 +372,18 @@ static struct i2c_algorithm scx200_acb_algorithm = {
};
static struct scx200_acb_iface *scx200_acb_list;
static DECLARE_MUTEX(scx200_acb_list_mutex);
static int scx200_acb_probe(struct scx200_acb_iface *iface)
{
u8 val;
/* Disable the ACCESS.bus device and Configure the SCL
frequency: 16 clock cycles */
frequency: 16 clock cycles */
outb(0x70, ACBCTL2);
if (inb(ACBCTL2) != 0x70) {
DBG("ACBCTL2 readback failed\n");
pr_debug(NAME ": ACBCTL2 readback failed\n");
return -ENXIO;
}
@ -418,7 +391,8 @@ static int scx200_acb_probe(struct scx200_acb_iface *iface)
val = inb(ACBCTL1);
if (val) {
DBG("disabled, but ACBCTL1=0x%02x\n", val);
pr_debug(NAME ": disabled, but ACBCTL1=0x%02x\n",
val);
return -ENXIO;
}
@ -428,18 +402,19 @@ static int scx200_acb_probe(struct scx200_acb_iface *iface)
val = inb(ACBCTL1);
if ((val & ACBCTL1_NMINTE) != ACBCTL1_NMINTE) {
DBG("enabled, but NMINTE won't be set, ACBCTL1=0x%02x\n", val);
pr_debug(NAME ": enabled, but NMINTE won't be set, "
"ACBCTL1=0x%02x\n", val);
return -ENXIO;
}
return 0;
}
static int __init scx200_acb_create(int base, int index)
static int __init scx200_acb_create(const char *text, int base, int index)
{
struct scx200_acb_iface *iface;
struct i2c_adapter *adapter;
int rc = 0;
int rc;
char description[64];
iface = kzalloc(sizeof(*iface), GFP_KERNEL);
@ -451,50 +426,51 @@ static int __init scx200_acb_create(int base, int index)
adapter = &iface->adapter;
i2c_set_adapdata(adapter, iface);
snprintf(adapter->name, I2C_NAME_SIZE, "SCx200 ACB%d", index);
snprintf(adapter->name, I2C_NAME_SIZE, "%s ACB%d", text, index);
adapter->owner = THIS_MODULE;
adapter->id = I2C_HW_SMBUS_SCX200;
adapter->algo = &scx200_acb_algorithm;
adapter->class = I2C_CLASS_HWMON;
init_MUTEX(&iface->sem);
mutex_init(&iface->mutex);
snprintf(description, sizeof(description), "%s ACCESS.bus [%s]",
text, adapter->name);
snprintf(description, sizeof(description), "NatSemi SCx200 ACCESS.bus [%s]", adapter->name);
if (request_region(base, 8, description) == 0) {
dev_err(&adapter->dev, "can't allocate io 0x%x-0x%x\n",
printk(KERN_ERR NAME ": can't allocate io 0x%x-0x%x\n",
base, base + 8-1);
rc = -EBUSY;
goto errout;
goto errout_free;
}
iface->base = base;
rc = scx200_acb_probe(iface);
if (rc) {
dev_warn(&adapter->dev, "probe failed\n");
goto errout;
printk(KERN_WARNING NAME ": probe failed\n");
goto errout_release;
}
scx200_acb_reset(iface);
if (i2c_add_adapter(adapter) < 0) {
dev_err(&adapter->dev, "failed to register\n");
printk(KERN_ERR NAME ": failed to register\n");
rc = -ENODEV;
goto errout;
goto errout_release;
}
lock_kernel();
down(&scx200_acb_list_mutex);
iface->next = scx200_acb_list;
scx200_acb_list = iface;
unlock_kernel();
up(&scx200_acb_list_mutex);
return 0;
errout_release:
release_region(iface->base, 8);
errout_free:
kfree(iface);
errout:
if (iface) {
if (iface->base)
release_region(iface->base, 8);
kfree(iface);
}
return rc;
}
@ -504,50 +480,69 @@ static struct pci_device_id scx200[] = {
{ },
};
static struct pci_device_id divil_pci[] = {
{ PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_CS5535_ISA) },
{ PCI_DEVICE(PCI_VENDOR_ID_AMD, PCI_DEVICE_ID_AMD_CS5536_ISA) },
{ } /* NULL entry */
};
#define MSR_LBAR_SMB 0x5140000B
static int scx200_add_cs553x(void)
{
u32 low, hi;
u32 smb_base;
/* Grab & reserve the SMB I/O range */
rdmsr(MSR_LBAR_SMB, low, hi);
/* Check the IO mask and whether SMB is enabled */
if (hi != 0x0000F001) {
printk(KERN_WARNING NAME ": SMBus not enabled\n");
return -ENODEV;
}
/* SMBus IO size is 8 bytes */
smb_base = low & 0x0000FFF8;
return scx200_acb_create("CS5535", smb_base, 0);
}
static int __init scx200_acb_init(void)
{
int i;
int rc;
int rc = -ENODEV;
pr_debug(NAME ": NatSemi SCx200 ACCESS.bus Driver\n");
/* Verify that this really is a SCx200 processor */
if (pci_dev_present(scx200) == 0)
return -ENODEV;
if (pci_dev_present(scx200)) {
for (i = 0; i < MAX_DEVICES; ++i) {
if (base[i] > 0)
rc = scx200_acb_create("SCx200", base[i], i);
}
} else if (pci_dev_present(divil_pci))
rc = scx200_add_cs553x();
rc = -ENXIO;
for (i = 0; i < MAX_DEVICES; ++i) {
if (base[i] > 0)
rc = scx200_acb_create(base[i], i);
}
if (scx200_acb_list)
return 0;
return rc;
}
static void __exit scx200_acb_cleanup(void)
{
struct scx200_acb_iface *iface;
lock_kernel();
down(&scx200_acb_list_mutex);
while ((iface = scx200_acb_list) != NULL) {
scx200_acb_list = iface->next;
unlock_kernel();
up(&scx200_acb_list_mutex);
i2c_del_adapter(&iface->adapter);
release_region(iface->base, 8);
kfree(iface);
lock_kernel();
down(&scx200_acb_list_mutex);
}
unlock_kernel();
up(&scx200_acb_list_mutex);
}
module_init(scx200_acb_init);
module_exit(scx200_acb_cleanup);
/*
Local variables:
compile-command: "make -k -C ../.. SUBDIRS=drivers/i2c modules"
c-basic-offset: 8
End:
*/

View File

@ -26,6 +26,7 @@
#include <linux/i2c.h>
#include <linux/rtc.h>
#include <linux/bcd.h>
#include <linux/mutex.h>
#define DS1374_REG_TOD0 0x00
#define DS1374_REG_TOD1 0x01
@ -41,7 +42,7 @@
#define DS1374_DRV_NAME "ds1374"
static DECLARE_MUTEX(ds1374_mutex);
static DEFINE_MUTEX(ds1374_mutex);
static struct i2c_driver ds1374_driver;
static struct i2c_client *save_client;
@ -114,7 +115,7 @@ ulong ds1374_get_rtc_time(void)
ulong t1, t2;
int limit = 10; /* arbitrary retry limit */
down(&ds1374_mutex);
mutex_lock(&ds1374_mutex);
/*
* Since the reads are being performed one byte at a time using
@ -127,7 +128,7 @@ ulong ds1374_get_rtc_time(void)
t2 = ds1374_read_rtc();
} while (t1 != t2 && limit--);
up(&ds1374_mutex);
mutex_unlock(&ds1374_mutex);
if (t1 != t2) {
dev_warn(&save_client->dev,
@ -145,7 +146,7 @@ static void ds1374_set_tlet(ulong arg)
t1 = *(ulong *) arg;
down(&ds1374_mutex);
mutex_lock(&ds1374_mutex);
/*
* Since the writes are being performed one byte at a time using
@ -158,7 +159,7 @@ static void ds1374_set_tlet(ulong arg)
t2 = ds1374_read_rtc();
} while (t1 != t2 && limit--);
up(&ds1374_mutex);
mutex_unlock(&ds1374_mutex);
if (t1 != t2)
dev_warn(&save_client->dev,

View File

@ -33,6 +33,7 @@
#include <linux/sched.h>
#include <linux/jiffies.h>
#include <linux/i2c.h>
#include <linux/mutex.h>
/* Addresses to scan */
static unsigned short normal_i2c[] = { 0x50, 0x51, 0x52, 0x53, 0x54,
@ -54,7 +55,7 @@ enum eeprom_nature {
/* Each client has this additional data */
struct eeprom_data {
struct i2c_client client;
struct semaphore update_lock;
struct mutex update_lock;
u8 valid; /* bitfield, bit!=0 if slice is valid */
unsigned long last_updated[8]; /* In jiffies, 8 slices */
u8 data[EEPROM_SIZE]; /* Register values */
@ -81,7 +82,7 @@ static void eeprom_update_client(struct i2c_client *client, u8 slice)
struct eeprom_data *data = i2c_get_clientdata(client);
int i, j;
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (!(data->valid & (1 << slice)) ||
time_after(jiffies, data->last_updated[slice] + 300 * HZ)) {
@ -107,7 +108,7 @@ static void eeprom_update_client(struct i2c_client *client, u8 slice)
data->valid |= (1 << slice);
}
exit:
up(&data->update_lock);
mutex_unlock(&data->update_lock);
}
static ssize_t eeprom_read(struct kobject *kobj, char *buf, loff_t off, size_t count)
@ -187,7 +188,7 @@ static int eeprom_detect(struct i2c_adapter *adapter, int address, int kind)
/* Fill in the remaining client fields */
strlcpy(new_client->name, "eeprom", I2C_NAME_SIZE);
data->valid = 0;
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
data->nature = UNKNOWN;
/* Tell the I2C layer a new client has arrived */

View File

@ -1635,8 +1635,6 @@ static struct i2c_driver isp1301_driver = {
.driver = {
.name = "isp1301_omap",
},
.id = 1301, /* FIXME "official", i2c-ids.h */
.class = I2C_CLASS_HWMON,
.attach_adapter = isp1301_scan_bus,
.detach_client = isp1301_detach_client,
};

View File

@ -24,13 +24,14 @@
#include <linux/i2c.h>
#include <linux/rtc.h>
#include <linux/bcd.h>
#include <linux/mutex.h>
#include <asm/time.h>
#include <asm/rtc.h>
#define M41T00_DRV_NAME "m41t00"
static DECLARE_MUTEX(m41t00_mutex);
static DEFINE_MUTEX(m41t00_mutex);
static struct i2c_driver m41t00_driver;
static struct i2c_client *save_client;
@ -54,7 +55,7 @@ m41t00_get_rtc_time(void)
sec = min = hour = day = mon = year = 0;
sec1 = min1 = hour1 = day1 = mon1 = year1 = 0;
down(&m41t00_mutex);
mutex_lock(&m41t00_mutex);
do {
if (((sec = i2c_smbus_read_byte_data(save_client, 0)) >= 0)
&& ((min = i2c_smbus_read_byte_data(save_client, 1))
@ -80,7 +81,7 @@ m41t00_get_rtc_time(void)
mon1 = mon;
year1 = year;
} while (--limit > 0);
up(&m41t00_mutex);
mutex_unlock(&m41t00_mutex);
if (limit == 0) {
dev_warn(&save_client->dev,
@ -125,7 +126,7 @@ m41t00_set_tlet(ulong arg)
BIN_TO_BCD(tm.tm_mday);
BIN_TO_BCD(tm.tm_year);
down(&m41t00_mutex);
mutex_lock(&m41t00_mutex);
if ((i2c_smbus_write_byte_data(save_client, 0, tm.tm_sec & 0x7f) < 0)
|| (i2c_smbus_write_byte_data(save_client, 1, tm.tm_min & 0x7f)
< 0)
@ -140,7 +141,7 @@ m41t00_set_tlet(ulong arg)
dev_warn(&save_client->dev,"m41t00: can't write to rtc chip\n");
up(&m41t00_mutex);
mutex_unlock(&m41t00_mutex);
return;
}

View File

@ -31,7 +31,7 @@
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <asm/semaphore.h>
#include <linux/mutex.h>
/* Do not scan - the MAX6875 access method will write to some EEPROM chips */
static unsigned short normal_i2c[] = {I2C_CLIENT_END};
@ -54,7 +54,7 @@ I2C_CLIENT_INSMOD_1(max6875);
/* Each client has this additional data */
struct max6875_data {
struct i2c_client client;
struct semaphore update_lock;
struct mutex update_lock;
u32 valid;
u8 data[USER_EEPROM_SIZE];
@ -83,7 +83,7 @@ static void max6875_update_slice(struct i2c_client *client, int slice)
if (slice >= USER_EEPROM_SLICES)
return;
down(&data->update_lock);
mutex_lock(&data->update_lock);
buf = &data->data[slice << SLICE_BITS];
@ -122,7 +122,7 @@ static void max6875_update_slice(struct i2c_client *client, int slice)
data->valid |= (1 << slice);
}
exit_up:
up(&data->update_lock);
mutex_unlock(&data->update_lock);
}
static ssize_t max6875_read(struct kobject *kobj, char *buf, loff_t off,
@ -196,7 +196,7 @@ static int max6875_detect(struct i2c_adapter *adapter, int address, int kind)
real_client->driver = &max6875_driver;
real_client->flags = 0;
strlcpy(real_client->name, "max6875", I2C_NAME_SIZE);
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
/* Init fake client data */
/* set the client data to the i2c_client so that it will get freed */

View File

@ -24,6 +24,7 @@
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/mutex.h>
/* Addresses to scan */
static unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b, 0x4c,
@ -74,7 +75,7 @@ MODULE_PARM_DESC(input_mode,
struct pcf8591_data {
struct i2c_client client;
struct semaphore update_lock;
struct mutex update_lock;
u8 control;
u8 aout;
@ -144,13 +145,13 @@ static ssize_t set_out0_enable(struct device *dev, struct device_attribute *attr
struct pcf8591_data *data = i2c_get_clientdata(client);
unsigned long val = simple_strtoul(buf, NULL, 10);
down(&data->update_lock);
mutex_lock(&data->update_lock);
if (val)
data->control |= PCF8591_CONTROL_AOEF;
else
data->control &= ~PCF8591_CONTROL_AOEF;
i2c_smbus_write_byte(client, data->control);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
return count;
}
@ -200,7 +201,7 @@ static int pcf8591_detect(struct i2c_adapter *adapter, int address, int kind)
/* Fill in the remaining client fields and put it into the global
list */
strlcpy(new_client->name, "pcf8591", I2C_NAME_SIZE);
init_MUTEX(&data->update_lock);
mutex_init(&data->update_lock);
/* Tell the I2C layer a new client has arrived */
if ((err = i2c_attach_client(new_client)))
@ -265,7 +266,7 @@ static int pcf8591_read_channel(struct device *dev, int channel)
struct i2c_client *client = to_i2c_client(dev);
struct pcf8591_data *data = i2c_get_clientdata(client);
down(&data->update_lock);
mutex_lock(&data->update_lock);
if ((data->control & PCF8591_CONTROL_AICH_MASK) != channel) {
data->control = (data->control & ~PCF8591_CONTROL_AICH_MASK)
@ -278,7 +279,7 @@ static int pcf8591_read_channel(struct device *dev, int channel)
}
value = i2c_smbus_read_byte(client);
up(&data->update_lock);
mutex_unlock(&data->update_lock);
if ((channel == 2 && input_mode == 2) ||
(channel != 3 && (input_mode == 1 || input_mode == 3)))

View File

@ -32,6 +32,7 @@
#include <linux/suspend.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/mutex.h>
#include <asm/irq.h>
#include <asm/mach-types.h>
@ -81,7 +82,7 @@ enum tps_model {
struct tps65010 {
struct i2c_client client;
struct semaphore lock;
struct mutex lock;
int irq;
struct work_struct work;
struct dentry *file;
@ -218,7 +219,7 @@ static int dbg_show(struct seq_file *s, void *_)
seq_printf(s, "driver %s\nversion %s\nchip %s\n\n",
DRIVER_NAME, DRIVER_VERSION, chip);
down(&tps->lock);
mutex_lock(&tps->lock);
/* FIXME how can we tell whether a battery is present?
* likely involves a charge gauging chip (like BQ26501).
@ -300,7 +301,7 @@ static int dbg_show(struct seq_file *s, void *_)
(v2 & (1 << (4 + i))) ? "rising" : "falling");
}
up(&tps->lock);
mutex_unlock(&tps->lock);
return 0;
}
@ -416,7 +417,7 @@ static void tps65010_work(void *_tps)
{
struct tps65010 *tps = _tps;
down(&tps->lock);
mutex_lock(&tps->lock);
tps65010_interrupt(tps);
@ -444,7 +445,7 @@ static void tps65010_work(void *_tps)
if (test_and_clear_bit(FLAG_IRQ_ENABLE, &tps->flags))
enable_irq(tps->irq);
up(&tps->lock);
mutex_unlock(&tps->lock);
}
static irqreturn_t tps65010_irq(int irq, void *_tps, struct pt_regs *regs)
@ -505,7 +506,7 @@ tps65010_probe(struct i2c_adapter *bus, int address, int kind)
if (!tps)
return 0;
init_MUTEX(&tps->lock);
mutex_init(&tps->lock);
INIT_WORK(&tps->work, tps65010_work, tps);
tps->irq = -1;
tps->client.addr = address;
@ -695,7 +696,7 @@ int tps65010_set_gpio_out_value(unsigned gpio, unsigned value)
if ((gpio < GPIO1) || (gpio > GPIO4))
return -EINVAL;
down(&the_tps->lock);
mutex_lock(&the_tps->lock);
defgpio = i2c_smbus_read_byte_data(&the_tps->client, TPS_DEFGPIO);
@ -720,7 +721,7 @@ int tps65010_set_gpio_out_value(unsigned gpio, unsigned value)
gpio, value ? "high" : "low",
i2c_smbus_read_byte_data(&the_tps->client, TPS_DEFGPIO));
up(&the_tps->lock);
mutex_unlock(&the_tps->lock);
return status;
}
EXPORT_SYMBOL(tps65010_set_gpio_out_value);
@ -745,7 +746,7 @@ int tps65010_set_led(unsigned led, unsigned mode)
led = LED2;
}
down(&the_tps->lock);
mutex_lock(&the_tps->lock);
pr_debug("%s: led%i_on 0x%02x\n", DRIVER_NAME, led,
i2c_smbus_read_byte_data(&the_tps->client,
@ -771,7 +772,7 @@ int tps65010_set_led(unsigned led, unsigned mode)
default:
printk(KERN_ERR "%s: Wrong mode parameter for set_led()\n",
DRIVER_NAME);
up(&the_tps->lock);
mutex_unlock(&the_tps->lock);
return -EINVAL;
}
@ -781,7 +782,7 @@ int tps65010_set_led(unsigned led, unsigned mode)
if (status != 0) {
printk(KERN_ERR "%s: Failed to write led%i_on register\n",
DRIVER_NAME, led);
up(&the_tps->lock);
mutex_unlock(&the_tps->lock);
return status;
}
@ -794,7 +795,7 @@ int tps65010_set_led(unsigned led, unsigned mode)
if (status != 0) {
printk(KERN_ERR "%s: Failed to write led%i_per register\n",
DRIVER_NAME, led);
up(&the_tps->lock);
mutex_unlock(&the_tps->lock);
return status;
}
@ -802,7 +803,7 @@ int tps65010_set_led(unsigned led, unsigned mode)
i2c_smbus_read_byte_data(&the_tps->client,
TPS_LED1_PER + offs));
up(&the_tps->lock);
mutex_unlock(&the_tps->lock);
return status;
}
@ -820,7 +821,7 @@ int tps65010_set_vib(unsigned value)
if (!the_tps)
return -ENODEV;
down(&the_tps->lock);
mutex_lock(&the_tps->lock);
vdcdc2 = i2c_smbus_read_byte_data(&the_tps->client, TPS_VDCDC2);
vdcdc2 &= ~(1 << 1);
@ -831,7 +832,7 @@ int tps65010_set_vib(unsigned value)
pr_debug("%s: vibrator %s\n", DRIVER_NAME, value ? "on" : "off");
up(&the_tps->lock);
mutex_unlock(&the_tps->lock);
return status;
}
EXPORT_SYMBOL(tps65010_set_vib);
@ -848,7 +849,7 @@ int tps65010_set_low_pwr(unsigned mode)
if (!the_tps)
return -ENODEV;
down(&the_tps->lock);
mutex_lock(&the_tps->lock);
pr_debug("%s: %s low_pwr, vdcdc1 0x%02x\n", DRIVER_NAME,
mode ? "enable" : "disable",
@ -876,7 +877,7 @@ int tps65010_set_low_pwr(unsigned mode)
pr_debug("%s: vdcdc1 0x%02x\n", DRIVER_NAME,
i2c_smbus_read_byte_data(&the_tps->client, TPS_VDCDC1));
up(&the_tps->lock);
mutex_unlock(&the_tps->lock);
return status;
}
@ -894,7 +895,7 @@ int tps65010_config_vregs1(unsigned value)
if (!the_tps)
return -ENODEV;
down(&the_tps->lock);
mutex_lock(&the_tps->lock);
pr_debug("%s: vregs1 0x%02x\n", DRIVER_NAME,
i2c_smbus_read_byte_data(&the_tps->client, TPS_VREGS1));
@ -909,7 +910,7 @@ int tps65010_config_vregs1(unsigned value)
pr_debug("%s: vregs1 0x%02x\n", DRIVER_NAME,
i2c_smbus_read_byte_data(&the_tps->client, TPS_VREGS1));
up(&the_tps->lock);
mutex_unlock(&the_tps->lock);
return status;
}
@ -931,7 +932,7 @@ int tps65013_set_low_pwr(unsigned mode)
if (!the_tps || the_tps->por)
return -ENODEV;
down(&the_tps->lock);
mutex_lock(&the_tps->lock);
pr_debug("%s: %s low_pwr, chgconfig 0x%02x vdcdc1 0x%02x\n",
DRIVER_NAME,
@ -959,7 +960,7 @@ int tps65013_set_low_pwr(unsigned mode)
if (status != 0) {
printk(KERN_ERR "%s: Failed to write chconfig register\n",
DRIVER_NAME);
up(&the_tps->lock);
mutex_unlock(&the_tps->lock);
return status;
}
@ -977,7 +978,7 @@ int tps65013_set_low_pwr(unsigned mode)
pr_debug("%s: vdcdc1 0x%02x\n", DRIVER_NAME,
i2c_smbus_read_byte_data(&the_tps->client, TPS_VDCDC1));
up(&the_tps->lock);
mutex_unlock(&the_tps->lock);
return status;
}

View File

@ -31,12 +31,13 @@
#include <linux/idr.h>
#include <linux/seq_file.h>
#include <linux/platform_device.h>
#include <linux/mutex.h>
#include <asm/uaccess.h>
static LIST_HEAD(adapters);
static LIST_HEAD(drivers);
static DECLARE_MUTEX(core_lists);
static DEFINE_MUTEX(core_lists);
static DEFINE_IDR(i2c_adapter_idr);
/* match always succeeds, as we want the probe() to tell if we really accept this match */
@ -153,7 +154,7 @@ int i2c_add_adapter(struct i2c_adapter *adap)
struct list_head *item;
struct i2c_driver *driver;
down(&core_lists);
mutex_lock(&core_lists);
if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0) {
res = -ENOMEM;
@ -168,8 +169,8 @@ int i2c_add_adapter(struct i2c_adapter *adap)
}
adap->nr = id & MAX_ID_MASK;
init_MUTEX(&adap->bus_lock);
init_MUTEX(&adap->clist_lock);
mutex_init(&adap->bus_lock);
mutex_init(&adap->clist_lock);
list_add_tail(&adap->list,&adapters);
INIT_LIST_HEAD(&adap->clients);
@ -203,7 +204,7 @@ int i2c_add_adapter(struct i2c_adapter *adap)
}
out_unlock:
up(&core_lists);
mutex_unlock(&core_lists);
return res;
}
@ -216,7 +217,7 @@ int i2c_del_adapter(struct i2c_adapter *adap)
struct i2c_client *client;
int res = 0;
down(&core_lists);
mutex_lock(&core_lists);
/* First make sure that this adapter was ever added */
list_for_each_entry(adap_from_list, &adapters, list) {
@ -272,7 +273,7 @@ int i2c_del_adapter(struct i2c_adapter *adap)
dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name);
out_unlock:
up(&core_lists);
mutex_unlock(&core_lists);
return res;
}
@ -287,9 +288,7 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
{
struct list_head *item;
struct i2c_adapter *adapter;
int res = 0;
down(&core_lists);
int res;
/* add the driver to the list of i2c drivers in the driver core */
driver->driver.owner = owner;
@ -297,8 +296,10 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
res = driver_register(&driver->driver);
if (res)
goto out_unlock;
return res;
mutex_lock(&core_lists);
list_add_tail(&driver->list,&drivers);
pr_debug("i2c-core: driver [%s] registered\n", driver->driver.name);
@ -310,9 +311,8 @@ int i2c_register_driver(struct module *owner, struct i2c_driver *driver)
}
}
out_unlock:
up(&core_lists);
return res;
mutex_unlock(&core_lists);
return 0;
}
EXPORT_SYMBOL(i2c_register_driver);
@ -324,7 +324,7 @@ int i2c_del_driver(struct i2c_driver *driver)
int res = 0;
down(&core_lists);
mutex_lock(&core_lists);
/* Have a look at each adapter, if clients of this driver are still
* attached. If so, detach them to be able to kill the driver
@ -363,7 +363,7 @@ int i2c_del_driver(struct i2c_driver *driver)
pr_debug("i2c-core: driver [%s] unregistered\n", driver->driver.name);
out_unlock:
up(&core_lists);
mutex_unlock(&core_lists);
return 0;
}
@ -384,9 +384,9 @@ int i2c_check_addr(struct i2c_adapter *adapter, int addr)
{
int rval;
down(&adapter->clist_lock);
mutex_lock(&adapter->clist_lock);
rval = __i2c_check_addr(adapter, addr);
up(&adapter->clist_lock);
mutex_unlock(&adapter->clist_lock);
return rval;
}
@ -395,13 +395,13 @@ int i2c_attach_client(struct i2c_client *client)
{
struct i2c_adapter *adapter = client->adapter;
down(&adapter->clist_lock);
mutex_lock(&adapter->clist_lock);
if (__i2c_check_addr(client->adapter, client->addr)) {
up(&adapter->clist_lock);
mutex_unlock(&adapter->clist_lock);
return -EBUSY;
}
list_add_tail(&client->list,&adapter->clients);
up(&adapter->clist_lock);
mutex_unlock(&adapter->clist_lock);
if (adapter->client_register) {
if (adapter->client_register(client)) {
@ -450,12 +450,12 @@ int i2c_detach_client(struct i2c_client *client)
}
}
down(&adapter->clist_lock);
mutex_lock(&adapter->clist_lock);
list_del(&client->list);
init_completion(&client->released);
device_remove_file(&client->dev, &dev_attr_client_name);
device_unregister(&client->dev);
up(&adapter->clist_lock);
mutex_unlock(&adapter->clist_lock);
wait_for_completion(&client->released);
out:
@ -513,19 +513,19 @@ void i2c_clients_command(struct i2c_adapter *adap, unsigned int cmd, void *arg)
struct list_head *item;
struct i2c_client *client;
down(&adap->clist_lock);
mutex_lock(&adap->clist_lock);
list_for_each(item,&adap->clients) {
client = list_entry(item, struct i2c_client, list);
if (!try_module_get(client->driver->driver.owner))
continue;
if (NULL != client->driver->command) {
up(&adap->clist_lock);
mutex_unlock(&adap->clist_lock);
client->driver->command(client,cmd,arg);
down(&adap->clist_lock);
mutex_lock(&adap->clist_lock);
}
module_put(client->driver->driver.owner);
}
up(&adap->clist_lock);
mutex_unlock(&adap->clist_lock);
}
static int __init i2c_init(void)
@ -569,9 +569,9 @@ int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num)
}
#endif
down(&adap->bus_lock);
mutex_lock(&adap->bus_lock);
ret = adap->algo->master_xfer(adap,msgs,num);
up(&adap->bus_lock);
mutex_unlock(&adap->bus_lock);
return ret;
} else {
@ -779,12 +779,12 @@ struct i2c_adapter* i2c_get_adapter(int id)
{
struct i2c_adapter *adapter;
down(&core_lists);
mutex_lock(&core_lists);
adapter = (struct i2c_adapter *)idr_find(&i2c_adapter_idr, id);
if (adapter && !try_module_get(adapter->owner))
adapter = NULL;
up(&core_lists);
mutex_unlock(&core_lists);
return adapter;
}
@ -919,12 +919,11 @@ s32 i2c_smbus_write_block_data(struct i2c_client *client, u8 command,
u8 length, u8 *values)
{
union i2c_smbus_data data;
int i;
if (length > I2C_SMBUS_BLOCK_MAX)
length = I2C_SMBUS_BLOCK_MAX;
for (i = 1; i <= length; i++)
data.block[i] = values[i-1];
data.block[0] = length;
memcpy(&data.block[1], values, length);
return i2c_smbus_xfer(client->adapter,client->addr,client->flags,
I2C_SMBUS_WRITE,command,
I2C_SMBUS_BLOCK_DATA,&data);
@ -934,16 +933,14 @@ s32 i2c_smbus_write_block_data(struct i2c_client *client, u8 command,
s32 i2c_smbus_read_i2c_block_data(struct i2c_client *client, u8 command, u8 *values)
{
union i2c_smbus_data data;
int i;
if (i2c_smbus_xfer(client->adapter,client->addr,client->flags,
I2C_SMBUS_READ,command,
I2C_SMBUS_I2C_BLOCK_DATA,&data))
return -1;
else {
for (i = 1; i <= data.block[0]; i++)
values[i-1] = data.block[i];
return data.block[0];
}
memcpy(values, &data.block[1], data.block[0]);
return data.block[0];
}
s32 i2c_smbus_write_i2c_block_data(struct i2c_client *client, u8 command,
@ -1118,10 +1115,10 @@ s32 i2c_smbus_xfer(struct i2c_adapter * adapter, u16 addr, unsigned short flags,
flags &= I2C_M_TEN | I2C_CLIENT_PEC;
if (adapter->algo->smbus_xfer) {
down(&adapter->bus_lock);
mutex_lock(&adapter->bus_lock);
res = adapter->algo->smbus_xfer(adapter,addr,flags,read_write,
command,size,data);
up(&adapter->bus_lock);
mutex_unlock(&adapter->bus_lock);
} else
res = i2c_smbus_xfer_emulated(adapter,addr,flags,read_write,
command,size,data);

View File

@ -53,7 +53,6 @@ MODULE_AUTHOR("Maxim Yevtyushkin");
MODULE_LICENSE("GPL");
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#define I2C_NAME(x) (x)->name

View File

@ -49,7 +49,6 @@ MODULE_AUTHOR("Dave Perks");
MODULE_LICENSE("GPL");
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#define I2C_NAME(s) (s)->name

View File

@ -53,7 +53,6 @@ MODULE_AUTHOR("Mike Bernson & Dave Perks");
MODULE_LICENSE("GPL");
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#define I2C_NAME(s) (s)->name

View File

@ -53,7 +53,6 @@ MODULE_AUTHOR("Mike Bernson & Dave Perks");
MODULE_LICENSE("GPL");
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#define I2C_NAME(s) (s)->name

View File

@ -39,7 +39,6 @@ MODULE_AUTHOR("Pauline Middelink");
MODULE_LICENSE("GPL");
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#define I2C_NAME(s) (s)->name

View File

@ -52,7 +52,6 @@ MODULE_AUTHOR("Dave Perks");
MODULE_LICENSE("GPL");
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#define I2C_NAME(s) (s)->name

View File

@ -55,7 +55,6 @@ MODULE_AUTHOR("Maxim Yevtyushkin");
MODULE_LICENSE("GPL");
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#define I2C_NAME(x) (x)->name

View File

@ -45,7 +45,6 @@ MODULE_AUTHOR("Dave Perks, Jose Ignacio Gijon, Joerg Heckenbach, Mark McClelland
MODULE_LICENSE("GPL");
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#define I2C_NAME(s) (s)->name

View File

@ -49,7 +49,6 @@ MODULE_AUTHOR("Dave Perks");
MODULE_LICENSE("GPL");
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#define I2C_NAME(s) (s)->name

View File

@ -30,7 +30,6 @@
#include <asm/uaccess.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#define I2C_NAME(x) (x)->name

View File

@ -27,11 +27,13 @@ struct sensor_device_attribute{
#define to_sensor_dev_attr(_dev_attr) \
container_of(_dev_attr, struct sensor_device_attribute, dev_attr)
#define SENSOR_DEVICE_ATTR(_name,_mode,_show,_store,_index) \
struct sensor_device_attribute sensor_dev_attr_##_name = { \
.dev_attr = __ATTR(_name,_mode,_show,_store), \
.index = _index, \
}
#define SENSOR_ATTR(_name, _mode, _show, _store, _index) \
{ .dev_attr = __ATTR(_name, _mode, _show, _store), \
.index = _index }
#define SENSOR_DEVICE_ATTR(_name, _mode, _show, _store, _index) \
struct sensor_device_attribute sensor_dev_attr_##_name \
= SENSOR_ATTR(_name, _mode, _show, _store, _index)
struct sensor_device_attribute_2 {
struct device_attribute dev_attr;
@ -41,11 +43,13 @@ struct sensor_device_attribute_2 {
#define to_sensor_dev_attr_2(_dev_attr) \
container_of(_dev_attr, struct sensor_device_attribute_2, dev_attr)
#define SENSOR_ATTR_2(_name, _mode, _show, _store, _nr, _index) \
{ .dev_attr = __ATTR(_name, _mode, _show, _store), \
.index = _index, \
.nr = _nr }
#define SENSOR_DEVICE_ATTR_2(_name,_mode,_show,_store,_nr,_index) \
struct sensor_device_attribute_2 sensor_dev_attr_##_name = { \
.dev_attr = __ATTR(_name,_mode,_show,_store), \
.index = _index, \
.nr = _nr, \
}
struct sensor_device_attribute_2 sensor_dev_attr_##_name \
= SENSOR_ATTR_2(_name, _mode, _show, _store, _nr, _index)
#endif /* _LINUX_HWMON_SYSFS_H */

View File

@ -172,7 +172,6 @@
#define I2C_HW_B_RIVA 0x010010 /* Riva based graphics cards */
#define I2C_HW_B_IOC 0x010011 /* IOC bit-wiggling */
#define I2C_HW_B_TSUNA 0x010012 /* DEC Tsunami chipset */
#define I2C_HW_B_FRODO 0x010013 /* 2d3D SA-1110 Development Board */
#define I2C_HW_B_OMAHA 0x010014 /* Omaha I2C interface (ARM) */
#define I2C_HW_B_GUIDE 0x010015 /* Guide bit-basher */
#define I2C_HW_B_IXP2000 0x010016 /* GPIO on IXP2000 systems */

View File

@ -32,7 +32,7 @@
#include <linux/mod_devicetable.h>
#include <linux/device.h> /* for struct device */
#include <linux/sched.h> /* for completion */
#include <asm/semaphore.h>
#include <linux/mutex.h>
/* --- For i2c-isa ---------------------------------------------------- */
@ -225,8 +225,8 @@ struct i2c_adapter {
int (*client_unregister)(struct i2c_client *);
/* data fields that are valid for all devices */
struct semaphore bus_lock;
struct semaphore clist_lock;
struct mutex bus_lock;
struct mutex clist_lock;
int timeout;
int retries;

View File

@ -1371,6 +1371,7 @@
#define PCI_DEVICE_ID_SERVERWORKS_OSB4 0x0200
#define PCI_DEVICE_ID_SERVERWORKS_CSB5 0x0201
#define PCI_DEVICE_ID_SERVERWORKS_CSB6 0x0203
#define PCI_DEVICE_ID_SERVERWORKS_HT1000SB 0x0205
#define PCI_DEVICE_ID_SERVERWORKS_OSB4IDE 0x0211
#define PCI_DEVICE_ID_SERVERWORKS_CSB5IDE 0x0212
#define PCI_DEVICE_ID_SERVERWORKS_CSB6IDE 0x0213

View File

@ -88,8 +88,6 @@
#include <linux/pmu.h>
#endif
#include <linux/i2c-dev.h>
#include <asm/uaccess.h>
#include <asm/prom.h>
#include <asm/machdep.h>

View File

@ -22,7 +22,6 @@
#include <sound/driver.h>
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <linux/kmod.h>
#include <linux/slab.h>
#include <sound/core.h>

View File

@ -23,7 +23,6 @@
#include <linux/init.h>
#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/i2c-dev.h>
#include <linux/slab.h>
#include <sound/core.h>
#include "pmac.h"

View File

@ -22,7 +22,6 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <linux/kmod.h>
#include <linux/slab.h>
#include <linux/interrupt.h>

View File

@ -28,7 +28,6 @@
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/i2c-dev.h>
#include <linux/kmod.h>
#include <linux/slab.h>
#include <linux/interrupt.h>