summaryrefslogtreecommitdiff
path: root/drivers/hwmon
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/hwmon')
-rw-r--r--drivers/hwmon/Kconfig2
-rw-r--r--drivers/hwmon/adm1275.c26
-rw-r--r--drivers/hwmon/asus_atk0110.c6
-rw-r--r--drivers/hwmon/coretemp.c27
-rw-r--r--drivers/hwmon/emc6w201.c58
-rw-r--r--drivers/hwmon/f71882fg.c19
-rw-r--r--drivers/hwmon/hwmon-vid.c2
-rw-r--r--drivers/hwmon/ibmaem.c2
-rw-r--r--drivers/hwmon/ibmpex.c1
-rw-r--r--drivers/hwmon/it87.c2
-rw-r--r--drivers/hwmon/lm95241.c22
-rw-r--r--drivers/hwmon/max1111.c11
-rw-r--r--drivers/hwmon/max6642.c22
-rw-r--r--drivers/hwmon/pmbus.c19
-rw-r--r--drivers/hwmon/pmbus_core.c31
-rw-r--r--drivers/hwmon/s3c-hwmon.c2
-rw-r--r--drivers/hwmon/sch5627.c2
17 files changed, 163 insertions, 91 deletions
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 16db83c83c8b..5f888f7e7dcb 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -333,7 +333,7 @@ config SENSORS_F71882FG
F71858FG
F71862FG
F71863FG
- F71869F/E
+ F71869F/E/A
F71882FG
F71883FG
F71889FG/ED/A
diff --git a/drivers/hwmon/adm1275.c b/drivers/hwmon/adm1275.c
index c2ee2048ab91..8bc1bd663721 100644
--- a/drivers/hwmon/adm1275.c
+++ b/drivers/hwmon/adm1275.c
@@ -32,6 +32,7 @@ static int adm1275_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
int config;
+ int ret;
struct pmbus_driver_info *info;
if (!i2c_check_functionality(client->adapter,
@@ -43,30 +44,32 @@ static int adm1275_probe(struct i2c_client *client,
return -ENOMEM;
config = i2c_smbus_read_byte_data(client, ADM1275_PMON_CONFIG);
- if (config < 0)
- return config;
+ if (config < 0) {
+ ret = config;
+ goto err_mem;
+ }
info->pages = 1;
info->direct[PSC_VOLTAGE_IN] = true;
info->direct[PSC_VOLTAGE_OUT] = true;
info->direct[PSC_CURRENT_OUT] = true;
- info->m[PSC_CURRENT_OUT] = 800;
+ info->m[PSC_CURRENT_OUT] = 807;
info->b[PSC_CURRENT_OUT] = 20475;
info->R[PSC_CURRENT_OUT] = -1;
info->func[0] = PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT;
if (config & ADM1275_VRANGE) {
- info->m[PSC_VOLTAGE_IN] = 19045;
+ info->m[PSC_VOLTAGE_IN] = 19199;
info->b[PSC_VOLTAGE_IN] = 0;
info->R[PSC_VOLTAGE_IN] = -2;
- info->m[PSC_VOLTAGE_OUT] = 19045;
+ info->m[PSC_VOLTAGE_OUT] = 19199;
info->b[PSC_VOLTAGE_OUT] = 0;
info->R[PSC_VOLTAGE_OUT] = -2;
} else {
- info->m[PSC_VOLTAGE_IN] = 6666;
+ info->m[PSC_VOLTAGE_IN] = 6720;
info->b[PSC_VOLTAGE_IN] = 0;
info->R[PSC_VOLTAGE_IN] = -1;
- info->m[PSC_VOLTAGE_OUT] = 6666;
+ info->m[PSC_VOLTAGE_OUT] = 6720;
info->b[PSC_VOLTAGE_OUT] = 0;
info->R[PSC_VOLTAGE_OUT] = -1;
}
@@ -76,7 +79,14 @@ static int adm1275_probe(struct i2c_client *client,
else
info->func[0] |= PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT;
- return pmbus_do_probe(client, id, info);
+ ret = pmbus_do_probe(client, id, info);
+ if (ret)
+ goto err_mem;
+ return 0;
+
+err_mem:
+ kfree(info);
+ return ret;
}
static int adm1275_remove(struct i2c_client *client)
diff --git a/drivers/hwmon/asus_atk0110.c b/drivers/hwmon/asus_atk0110.c
index b5e892017e0c..00e98517f94c 100644
--- a/drivers/hwmon/asus_atk0110.c
+++ b/drivers/hwmon/asus_atk0110.c
@@ -268,6 +268,7 @@ static struct device_attribute atk_name_attr =
static void atk_init_attribute(struct device_attribute *attr, char *name,
sysfs_show_func show)
{
+ sysfs_attr_init(&attr->attr);
attr->attr.name = name;
attr->attr.mode = 0444;
attr->show = show;
@@ -673,6 +674,7 @@ static int atk_debugfs_gitm_get(void *p, u64 *val)
else
err = -EIO;
+ ACPI_FREE(ret);
return err;
}
@@ -1188,19 +1190,15 @@ static int atk_create_files(struct atk_data *data)
int err;
list_for_each_entry(s, &data->sensor_list, list) {
- sysfs_attr_init(&s->input_attr.attr);
err = device_create_file(data->hwmon_dev, &s->input_attr);
if (err)
return err;
- sysfs_attr_init(&s->label_attr.attr);
err = device_create_file(data->hwmon_dev, &s->label_attr);
if (err)
return err;
- sysfs_attr_init(&s->limit1_attr.attr);
err = device_create_file(data->hwmon_dev, &s->limit1_attr);
if (err)
return err;
- sysfs_attr_init(&s->limit2_attr.attr);
err = device_create_file(data->hwmon_dev, &s->limit2_attr);
if (err)
return err;
diff --git a/drivers/hwmon/coretemp.c b/drivers/hwmon/coretemp.c
index de3d2465fe24..0070d5476dd0 100644
--- a/drivers/hwmon/coretemp.c
+++ b/drivers/hwmon/coretemp.c
@@ -97,9 +97,7 @@ struct platform_data {
struct pdev_entry {
struct list_head list;
struct platform_device *pdev;
- unsigned int cpu;
u16 phys_proc_id;
- u16 cpu_core_id;
};
static LIST_HEAD(pdev_list);
@@ -296,7 +294,7 @@ static int get_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev)
* If the TjMax is not plausible, an assumption
* will be used
*/
- if (val > 80 && val < 120) {
+ if (val) {
dev_info(dev, "TjMax is %d C.\n", val);
return val * 1000;
}
@@ -304,24 +302,9 @@ static int get_tjmax(struct cpuinfo_x86 *c, u32 id, struct device *dev)
/*
* An assumption is made for early CPUs and unreadable MSR.
- * NOTE: the given value may not be correct.
+ * NOTE: the calculated value may not be correct.
*/
-
- switch (c->x86_model) {
- case 0xe:
- case 0xf:
- case 0x16:
- case 0x1a:
- dev_warn(dev, "TjMax is assumed as 100 C!\n");
- return 100000;
- case 0x17:
- case 0x1c: /* Atom CPUs */
- return adjust_tjmax(c, id, dev);
- default:
- dev_warn(dev, "CPU (model=0x%x) is not supported yet,"
- " using default TjMax of 100C.\n", c->x86_model);
- return 100000;
- }
+ return adjust_tjmax(c, id, dev);
}
static void __devinit get_ucode_rev_on_cpu(void *edx)
@@ -341,7 +324,7 @@ static int get_pkg_tjmax(unsigned int cpu, struct device *dev)
err = rdmsr_safe_on_cpu(cpu, MSR_IA32_TEMPERATURE_TARGET, &eax, &edx);
if (!err) {
val = (eax >> 16) & 0xff;
- if (val > 80 && val < 120)
+ if (val)
return val * 1000;
}
dev_warn(dev, "Unable to read Pkg-TjMax from CPU:%u\n", cpu);
@@ -668,9 +651,7 @@ static int __cpuinit coretemp_device_add(unsigned int cpu)
}
pdev_entry->pdev = pdev;
- pdev_entry->cpu = cpu;
pdev_entry->phys_proc_id = TO_PHYS_ID(cpu);
- pdev_entry->cpu_core_id = TO_CORE_ID(cpu);
list_add_tail(&pdev_entry->list, &pdev_list);
mutex_unlock(&pdev_list_mutex);
diff --git a/drivers/hwmon/emc6w201.c b/drivers/hwmon/emc6w201.c
index e0ef32378ac6..0064432f361f 100644
--- a/drivers/hwmon/emc6w201.c
+++ b/drivers/hwmon/emc6w201.c
@@ -78,8 +78,9 @@ static u16 emc6w201_read16(struct i2c_client *client, u8 reg)
lsb = i2c_smbus_read_byte_data(client, reg);
msb = i2c_smbus_read_byte_data(client, reg + 1);
- if (lsb < 0 || msb < 0) {
- dev_err(&client->dev, "16-bit read failed at 0x%02x\n", reg);
+ if (unlikely(lsb < 0 || msb < 0)) {
+ dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n",
+ 16, "read", reg);
return 0xFFFF; /* Arbitrary value */
}
@@ -95,10 +96,39 @@ static int emc6w201_write16(struct i2c_client *client, u8 reg, u16 val)
int err;
err = i2c_smbus_write_byte_data(client, reg, val & 0xff);
- if (!err)
+ if (likely(!err))
err = i2c_smbus_write_byte_data(client, reg + 1, val >> 8);
- if (err < 0)
- dev_err(&client->dev, "16-bit write failed at 0x%02x\n", reg);
+ if (unlikely(err < 0))
+ dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n",
+ 16, "write", reg);
+
+ return err;
+}
+
+/* Read 8-bit value from register */
+static u8 emc6w201_read8(struct i2c_client *client, u8 reg)
+{
+ int val;
+
+ val = i2c_smbus_read_byte_data(client, reg);
+ if (unlikely(val < 0)) {
+ dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n",
+ 8, "read", reg);
+ return 0x00; /* Arbitrary value */
+ }
+
+ return val;
+}
+
+/* Write 8-bit value to register */
+static int emc6w201_write8(struct i2c_client *client, u8 reg, u8 val)
+{
+ int err;
+
+ err = i2c_smbus_write_byte_data(client, reg, val);
+ if (unlikely(err < 0))
+ dev_err(&client->dev, "%d-bit %s failed at 0x%02x\n",
+ 8, "write", reg);
return err;
}
@@ -114,25 +144,25 @@ static struct emc6w201_data *emc6w201_update_device(struct device *dev)
if (time_after(jiffies, data->last_updated + HZ) || !data->valid) {
for (nr = 0; nr < 6; nr++) {
data->in[input][nr] =
- i2c_smbus_read_byte_data(client,
+ emc6w201_read8(client,
EMC6W201_REG_IN(nr));
data->in[min][nr] =
- i2c_smbus_read_byte_data(client,
+ emc6w201_read8(client,
EMC6W201_REG_IN_LOW(nr));
data->in[max][nr] =
- i2c_smbus_read_byte_data(client,
+ emc6w201_read8(client,
EMC6W201_REG_IN_HIGH(nr));
}
for (nr = 0; nr < 6; nr++) {
data->temp[input][nr] =
- i2c_smbus_read_byte_data(client,
+ emc6w201_read8(client,
EMC6W201_REG_TEMP(nr));
data->temp[min][nr] =
- i2c_smbus_read_byte_data(client,
+ emc6w201_read8(client,
EMC6W201_REG_TEMP_LOW(nr));
data->temp[max][nr] =
- i2c_smbus_read_byte_data(client,
+ emc6w201_read8(client,
EMC6W201_REG_TEMP_HIGH(nr));
}
@@ -192,7 +222,7 @@ static ssize_t set_in(struct device *dev, struct device_attribute *devattr,
mutex_lock(&data->update_lock);
data->in[sf][nr] = SENSORS_LIMIT(val, 0, 255);
- err = i2c_smbus_write_byte_data(client, reg, data->in[sf][nr]);
+ err = emc6w201_write8(client, reg, data->in[sf][nr]);
mutex_unlock(&data->update_lock);
return err < 0 ? err : count;
@@ -229,7 +259,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *devattr,
mutex_lock(&data->update_lock);
data->temp[sf][nr] = SENSORS_LIMIT(val, -127, 128);
- err = i2c_smbus_write_byte_data(client, reg, data->temp[sf][nr]);
+ err = emc6w201_write8(client, reg, data->temp[sf][nr]);
mutex_unlock(&data->update_lock);
return err < 0 ? err : count;
@@ -444,7 +474,7 @@ static int emc6w201_detect(struct i2c_client *client,
/* Check configuration */
config = i2c_smbus_read_byte_data(client, EMC6W201_REG_CONFIG);
- if ((config & 0xF4) != 0x04)
+ if (config < 0 || (config & 0xF4) != 0x04)
return -ENODEV;
if (!(config & 0x01)) {
dev_err(&client->dev, "Monitoring not enabled\n");
diff --git a/drivers/hwmon/f71882fg.c b/drivers/hwmon/f71882fg.c
index a4a94a096c90..2d96ed2bf8ed 100644
--- a/drivers/hwmon/f71882fg.c
+++ b/drivers/hwmon/f71882fg.c
@@ -52,6 +52,7 @@
#define SIO_F71858_ID 0x0507 /* Chipset ID */
#define SIO_F71862_ID 0x0601 /* Chipset ID */
#define SIO_F71869_ID 0x0814 /* Chipset ID */
+#define SIO_F71869A_ID 0x1007 /* Chipset ID */
#define SIO_F71882_ID 0x0541 /* Chipset ID */
#define SIO_F71889_ID 0x0723 /* Chipset ID */
#define SIO_F71889E_ID 0x0909 /* Chipset ID */
@@ -108,8 +109,8 @@ static unsigned short force_id;
module_param(force_id, ushort, 0);
MODULE_PARM_DESC(force_id, "Override the detected device ID");
-enum chips { f71808e, f71808a, f71858fg, f71862fg, f71869, f71882fg, f71889fg,
- f71889ed, f71889a, f8000, f81865f };
+enum chips { f71808e, f71808a, f71858fg, f71862fg, f71869, f71869a, f71882fg,
+ f71889fg, f71889ed, f71889a, f8000, f81865f };
static const char *f71882fg_names[] = {
"f71808e",
@@ -117,6 +118,7 @@ static const char *f71882fg_names[] = {
"f71858fg",
"f71862fg",
"f71869", /* Both f71869f and f71869e, reg. compatible and same id */
+ "f71869a",
"f71882fg",
"f71889fg", /* f81801u too, same id */
"f71889ed",
@@ -131,6 +133,7 @@ static const char f71882fg_has_in[][F71882FG_MAX_INS] = {
[f71858fg] = { 1, 1, 1, 0, 0, 0, 0, 0, 0 },
[f71862fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
[f71869] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
+ [f71869a] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
[f71882fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
[f71889fg] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
[f71889ed] = { 1, 1, 1, 1, 1, 1, 1, 1, 1 },
@@ -145,6 +148,7 @@ static const char f71882fg_has_in1_alarm[] = {
[f71858fg] = 0,
[f71862fg] = 0,
[f71869] = 0,
+ [f71869a] = 0,
[f71882fg] = 1,
[f71889fg] = 1,
[f71889ed] = 1,
@@ -159,6 +163,7 @@ static const char f71882fg_fan_has_beep[] = {
[f71858fg] = 0,
[f71862fg] = 1,
[f71869] = 1,
+ [f71869a] = 1,
[f71882fg] = 1,
[f71889fg] = 1,
[f71889ed] = 1,
@@ -173,6 +178,7 @@ static const char f71882fg_nr_fans[] = {
[f71858fg] = 3,
[f71862fg] = 3,
[f71869] = 3,
+ [f71869a] = 3,
[f71882fg] = 4,
[f71889fg] = 3,
[f71889ed] = 3,
@@ -187,6 +193,7 @@ static const char f71882fg_temp_has_beep[] = {
[f71858fg] = 0,
[f71862fg] = 1,
[f71869] = 1,
+ [f71869a] = 1,
[f71882fg] = 1,
[f71889fg] = 1,
[f71889ed] = 1,
@@ -201,6 +208,7 @@ static const char f71882fg_nr_temps[] = {
[f71858fg] = 3,
[f71862fg] = 3,
[f71869] = 3,
+ [f71869a] = 3,
[f71882fg] = 3,
[f71889fg] = 3,
[f71889ed] = 3,
@@ -2243,6 +2251,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
case f71808e:
case f71808a:
case f71869:
+ case f71869a:
/* These always have signed auto point temps */
data->auto_point_temp_signed = 1;
/* Fall through to select correct fan/pwm reg bank! */
@@ -2305,6 +2314,7 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
case f71808e:
case f71808a:
case f71869:
+ case f71869a:
case f71889fg:
case f71889ed:
case f71889a:
@@ -2528,6 +2538,9 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
case SIO_F71869_ID:
sio_data->type = f71869;
break;
+ case SIO_F71869A_ID:
+ sio_data->type = f71869a;
+ break;
case SIO_F71882_ID:
sio_data->type = f71882fg;
break;
@@ -2662,7 +2675,7 @@ static void __exit f71882fg_exit(void)
}
MODULE_DESCRIPTION("F71882FG Hardware Monitoring Driver");
-MODULE_AUTHOR("Hans Edgington, Hans de Goede (hdegoede@redhat.com)");
+MODULE_AUTHOR("Hans Edgington, Hans de Goede <hdegoede@redhat.com>");
MODULE_LICENSE("GPL");
module_init(f71882fg_init);
diff --git a/drivers/hwmon/hwmon-vid.c b/drivers/hwmon/hwmon-vid.c
index 2582bfef6ccb..c8195a077da3 100644
--- a/drivers/hwmon/hwmon-vid.c
+++ b/drivers/hwmon/hwmon-vid.c
@@ -202,7 +202,7 @@ static struct vrm_model vrm_models[] = {
{X86_VENDOR_CENTAUR, 0x6, 0x7, ANY, 85}, /* Eden ESP/Ezra */
{X86_VENDOR_CENTAUR, 0x6, 0x8, 0x7, 85}, /* Ezra T */
- {X86_VENDOR_CENTAUR, 0x6, 0x9, 0x7, 85}, /* Nemiah */
+ {X86_VENDOR_CENTAUR, 0x6, 0x9, 0x7, 85}, /* Nehemiah */
{X86_VENDOR_CENTAUR, 0x6, 0x9, ANY, 17}, /* C3-M, Eden-N */
{X86_VENDOR_CENTAUR, 0x6, 0xA, 0x7, 0}, /* No information */
{X86_VENDOR_CENTAUR, 0x6, 0xA, ANY, 13}, /* C7, Esther */
diff --git a/drivers/hwmon/ibmaem.c b/drivers/hwmon/ibmaem.c
index 537409d07ee7..1a409c5bc9bc 100644
--- a/drivers/hwmon/ibmaem.c
+++ b/drivers/hwmon/ibmaem.c
@@ -947,6 +947,7 @@ static int aem_register_sensors(struct aem_data *data,
/* Set up read-only sensors */
while (ro->label) {
+ sysfs_attr_init(&sensors->dev_attr.attr);
sensors->dev_attr.attr.name = ro->label;
sensors->dev_attr.attr.mode = S_IRUGO;
sensors->dev_attr.show = ro->show;
@@ -963,6 +964,7 @@ static int aem_register_sensors(struct aem_data *data,
/* Set up read-write sensors */
while (rw->label) {
+ sysfs_attr_init(&sensors->dev_attr.attr);
sensors->dev_attr.attr.name = rw->label;
sensors->dev_attr.attr.mode = S_IRUGO | S_IWUSR;
sensors->dev_attr.show = rw->show;
diff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c
index 06d4eafcf76b..41dbf8161ed7 100644
--- a/drivers/hwmon/ibmpex.c
+++ b/drivers/hwmon/ibmpex.c
@@ -358,6 +358,7 @@ static int create_sensor(struct ibmpex_bmc_data *data, int type,
else if (type == POWER_SENSOR)
sprintf(n, power_sensor_name_templates[func], "power", counter);
+ sysfs_attr_init(&data->sensors[sensor].attr[func].dev_attr.attr);
data->sensors[sensor].attr[func].dev_attr.attr.name = n;
data->sensors[sensor].attr[func].dev_attr.attr.mode = S_IRUGO;
data->sensors[sensor].attr[func].dev_attr.show = ibmpex_show_sensor;
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index bb6405b92007..5f5247750430 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -1538,7 +1538,7 @@ static struct attribute *it87_attributes_label[] = {
};
static const struct attribute_group it87_group_label = {
- .attrs = it87_attributes_vid,
+ .attrs = it87_attributes_label,
};
/* SuperIO detection - will change isa_address if a chip is found */
diff --git a/drivers/hwmon/lm95241.c b/drivers/hwmon/lm95241.c
index 1a6dfb6df1e7..d3b464b74ced 100644
--- a/drivers/hwmon/lm95241.c
+++ b/drivers/hwmon/lm95241.c
@@ -98,11 +98,16 @@ struct lm95241_data {
};
/* Conversions */
-static int TempFromReg(u8 val_h, u8 val_l)
+static int temp_from_reg_signed(u8 val_h, u8 val_l)
{
- if (val_h & 0x80)
- return val_h - 0x100;
- return val_h * 1000 + val_l * 1000 / 256;
+ s16 val_hl = (val_h << 8) | val_l;
+ return val_hl * 1000 / 256;
+}
+
+static int temp_from_reg_unsigned(u8 val_h, u8 val_l)
+{
+ u16 val_hl = (val_h << 8) | val_l;
+ return val_hl * 1000 / 256;
}
static struct lm95241_data *lm95241_update_device(struct device *dev)
@@ -135,10 +140,13 @@ static ssize_t show_input(struct device *dev, struct device_attribute *attr,
char *buf)
{
struct lm95241_data *data = lm95241_update_device(dev);
+ int index = to_sensor_dev_attr(attr)->index;
return snprintf(buf, PAGE_SIZE - 1, "%d\n",
- TempFromReg(data->temp[to_sensor_dev_attr(attr)->index],
- data->temp[to_sensor_dev_attr(attr)->index + 1]));
+ index == 0 || (data->config & (1 << (index / 2))) ?
+ temp_from_reg_signed(data->temp[index], data->temp[index + 1]) :
+ temp_from_reg_unsigned(data->temp[index],
+ data->temp[index + 1]));
}
static ssize_t show_type(struct device *dev, struct device_attribute *attr,
@@ -339,7 +347,7 @@ static int lm95241_detect(struct i2c_client *new_client,
if ((i2c_smbus_read_byte_data(new_client, LM95241_REG_R_MAN_ID)
== MANUFACTURER_ID)
&& (i2c_smbus_read_byte_data(new_client, LM95241_REG_R_CHIP_ID)
- >= DEFAULT_REVISION)) {
+ == DEFAULT_REVISION)) {
name = DEVNAME;
} else {
dev_dbg(&adapter->dev, "LM95241 detection failed at 0x%02x\n",
diff --git a/drivers/hwmon/max1111.c b/drivers/hwmon/max1111.c
index 12a54aa29776..14335bbc9bdc 100644
--- a/drivers/hwmon/max1111.c
+++ b/drivers/hwmon/max1111.c
@@ -40,6 +40,8 @@ struct max1111_data {
struct spi_transfer xfer[2];
uint8_t *tx_buf;
uint8_t *rx_buf;
+ struct mutex drvdata_lock;
+ /* protect msg, xfer and buffers from multiple access */
};
static int max1111_read(struct device *dev, int channel)
@@ -48,6 +50,9 @@ static int max1111_read(struct device *dev, int channel)
uint8_t v1, v2;
int err;
+ /* writing to drvdata struct is not thread safe, wait on mutex */
+ mutex_lock(&data->drvdata_lock);
+
data->tx_buf[0] = (channel << MAX1111_CTRL_SEL_SH) |
MAX1111_CTRL_PD0 | MAX1111_CTRL_PD1 |
MAX1111_CTRL_SGL | MAX1111_CTRL_UNI | MAX1111_CTRL_STR;
@@ -55,12 +60,15 @@ static int max1111_read(struct device *dev, int channel)
err = spi_sync(data->spi, &data->msg);
if (err < 0) {
dev_err(dev, "spi_sync failed with %d\n", err);
+ mutex_unlock(&data->drvdata_lock);
return err;
}
v1 = data->rx_buf[0];
v2 = data->rx_buf[1];
+ mutex_unlock(&data->drvdata_lock);
+
if ((v1 & 0xc0) || (v2 & 0x3f))
return -EINVAL;
@@ -176,6 +184,8 @@ static int __devinit max1111_probe(struct spi_device *spi)
if (err)
goto err_free_data;
+ mutex_init(&data->drvdata_lock);
+
data->spi = spi;
spi_set_drvdata(spi, data);
@@ -213,6 +223,7 @@ static int __devexit max1111_remove(struct spi_device *spi)
hwmon_device_unregister(data->hwmon_dev);
sysfs_remove_group(&spi->dev.kobj, &max1111_attr_group);
+ mutex_destroy(&data->drvdata_lock);
kfree(data->rx_buf);
kfree(data->tx_buf);
kfree(data);
diff --git a/drivers/hwmon/max6642.c b/drivers/hwmon/max6642.c
index 0f9fc40379cd..e855d3b0bd1f 100644
--- a/drivers/hwmon/max6642.c
+++ b/drivers/hwmon/max6642.c
@@ -136,15 +136,29 @@ static int max6642_detect(struct i2c_client *client,
if (man_id != 0x4D)
return -ENODEV;
+ /* sanity check */
+ if (i2c_smbus_read_byte_data(client, 0x04) != 0x4D
+ || i2c_smbus_read_byte_data(client, 0x06) != 0x4D
+ || i2c_smbus_read_byte_data(client, 0xff) != 0x4D)
+ return -ENODEV;
+
/*
* We read the config and status register, the 4 lower bits in the
* config register should be zero and bit 5, 3, 1 and 0 should be
* zero in the status register.
*/
reg_config = i2c_smbus_read_byte_data(client, MAX6642_REG_R_CONFIG);
+ if ((reg_config & 0x0f) != 0x00)
+ return -ENODEV;
+
+ /* in between, another round of sanity checks */
+ if (i2c_smbus_read_byte_data(client, 0x04) != reg_config
+ || i2c_smbus_read_byte_data(client, 0x06) != reg_config
+ || i2c_smbus_read_byte_data(client, 0xff) != reg_config)
+ return -ENODEV;
+
reg_status = i2c_smbus_read_byte_data(client, MAX6642_REG_R_STATUS);
- if (((reg_config & 0x0f) != 0x00) ||
- ((reg_status & 0x2b) != 0x00))
+ if ((reg_status & 0x2b) != 0x00)
return -ENODEV;
strlcpy(info->type, "max6642", I2C_NAME_SIZE);
@@ -246,7 +260,7 @@ static SENSOR_DEVICE_ATTR_2(temp1_max, S_IWUSR | S_IRUGO, show_temp_max,
set_temp_max, 0, MAX6642_REG_W_LOCAL_HIGH);
static SENSOR_DEVICE_ATTR_2(temp2_max, S_IWUSR | S_IRUGO, show_temp_max,
set_temp_max, 1, MAX6642_REG_W_REMOTE_HIGH);
-static SENSOR_DEVICE_ATTR(temp_fault, S_IRUGO, show_alarm, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_alarm, NULL, 2);
static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 6);
static SENSOR_DEVICE_ATTR(temp2_max_alarm, S_IRUGO, show_alarm, NULL, 4);
@@ -256,7 +270,7 @@ static struct attribute *max6642_attributes[] = {
&sensor_dev_attr_temp1_max.dev_attr.attr,
&sensor_dev_attr_temp2_max.dev_attr.attr,
- &sensor_dev_attr_temp_fault.dev_attr.attr,
+ &sensor_dev_attr_temp2_fault.dev_attr.attr,
&sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
&sensor_dev_attr_temp2_max_alarm.dev_attr.attr,
NULL
diff --git a/drivers/hwmon/pmbus.c b/drivers/hwmon/pmbus.c
index 98e2e28899e2..9b1f0c37ef77 100644
--- a/drivers/hwmon/pmbus.c
+++ b/drivers/hwmon/pmbus.c
@@ -47,22 +47,29 @@ static void pmbus_find_sensor_groups(struct i2c_client *client,
if (info->func[0]
&& pmbus_check_byte_register(client, 0, PMBUS_STATUS_INPUT))
info->func[0] |= PMBUS_HAVE_STATUS_INPUT;
- if (pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_1)) {
+ if (pmbus_check_byte_register(client, 0, PMBUS_FAN_CONFIG_12) &&
+ pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_1)) {
info->func[0] |= PMBUS_HAVE_FAN12;
if (pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_12))
info->func[0] |= PMBUS_HAVE_STATUS_FAN12;
}
- if (pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_3)) {
+ if (pmbus_check_byte_register(client, 0, PMBUS_FAN_CONFIG_34) &&
+ pmbus_check_word_register(client, 0, PMBUS_READ_FAN_SPEED_3)) {
info->func[0] |= PMBUS_HAVE_FAN34;
if (pmbus_check_byte_register(client, 0, PMBUS_STATUS_FAN_34))
info->func[0] |= PMBUS_HAVE_STATUS_FAN34;
}
- if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_1)) {
+ if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_1))
info->func[0] |= PMBUS_HAVE_TEMP;
- if (pmbus_check_byte_register(client, 0,
- PMBUS_STATUS_TEMPERATURE))
+ if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_2))
+ info->func[0] |= PMBUS_HAVE_TEMP2;
+ if (pmbus_check_word_register(client, 0, PMBUS_READ_TEMPERATURE_3))
+ info->func[0] |= PMBUS_HAVE_TEMP3;
+ if (info->func[0] & (PMBUS_HAVE_TEMP | PMBUS_HAVE_TEMP2
+ | PMBUS_HAVE_TEMP3)
+ && pmbus_check_byte_register(client, 0,
+ PMBUS_STATUS_TEMPERATURE))
info->func[0] |= PMBUS_HAVE_STATUS_TEMP;
- }
/* Sensors detected on all pages */
for (page = 0; page < info->pages; page++) {
diff --git a/drivers/hwmon/pmbus_core.c b/drivers/hwmon/pmbus_core.c
index 354770ed3186..8e31a8e2c746 100644
--- a/drivers/hwmon/pmbus_core.c
+++ b/drivers/hwmon/pmbus_core.c
@@ -362,8 +362,8 @@ static struct pmbus_data *pmbus_update_device(struct device *dev)
* Convert linear sensor values to milli- or micro-units
* depending on sensor type.
*/
-static int pmbus_reg2data_linear(struct pmbus_data *data,
- struct pmbus_sensor *sensor)
+static long pmbus_reg2data_linear(struct pmbus_data *data,
+ struct pmbus_sensor *sensor)
{
s16 exponent;
s32 mantissa;
@@ -397,15 +397,15 @@ static int pmbus_reg2data_linear(struct pmbus_data *data,
else
val >>= -exponent;
- return (int)val;
+ return val;
}
/*
* Convert direct sensor values to milli- or micro-units
* depending on sensor type.
*/
-static int pmbus_reg2data_direct(struct pmbus_data *data,
- struct pmbus_sensor *sensor)
+static long pmbus_reg2data_direct(struct pmbus_data *data,
+ struct pmbus_sensor *sensor)
{
long val = (s16) sensor->data;
long m, b, R;
@@ -440,12 +440,12 @@ static int pmbus_reg2data_direct(struct pmbus_data *data,
R++;
}
- return (int)((val - b) / m);
+ return (val - b) / m;
}
-static int pmbus_reg2data(struct pmbus_data *data, struct pmbus_sensor *sensor)
+static long pmbus_reg2data(struct pmbus_data *data, struct pmbus_sensor *sensor)
{
- int val;
+ long val;
if (data->info->direct[sensor->class])
val = pmbus_reg2data_direct(data, sensor);
@@ -619,7 +619,7 @@ static int pmbus_get_boolean(struct pmbus_data *data, int index, int *val)
if (!s1 && !s2)
*val = !!regval;
else {
- int v1, v2;
+ long v1, v2;
struct pmbus_sensor *sensor1, *sensor2;
sensor1 = &data->sensors[s1];
@@ -661,7 +661,7 @@ static ssize_t pmbus_show_sensor(struct device *dev,
if (sensor->data < 0)
return sensor->data;
- return snprintf(buf, PAGE_SIZE, "%d\n", pmbus_reg2data(data, sensor));
+ return snprintf(buf, PAGE_SIZE, "%ld\n", pmbus_reg2data(data, sensor));
}
static ssize_t pmbus_set_sensor(struct device *dev,
@@ -1430,14 +1430,9 @@ int pmbus_do_probe(struct i2c_client *client, const struct i2c_device_id *id,
i2c_set_clientdata(client, data);
mutex_init(&data->update_lock);
- /*
- * Bail out if status register or PMBus revision register
- * does not exist.
- */
- if (i2c_smbus_read_byte_data(client, PMBUS_STATUS_BYTE) < 0
- || i2c_smbus_read_byte_data(client, PMBUS_REVISION) < 0) {
- dev_err(&client->dev,
- "Status or revision register not found\n");
+ /* Bail out if PMBus status register does not exist. */
+ if (i2c_smbus_read_byte_data(client, PMBUS_STATUS_BYTE) < 0) {
+ dev_err(&client->dev, "PMBus status register not found\n");
ret = -ENODEV;
goto out_data;
}
diff --git a/drivers/hwmon/s3c-hwmon.c b/drivers/hwmon/s3c-hwmon.c
index 92b42db43bcf..b39f52e2752a 100644
--- a/drivers/hwmon/s3c-hwmon.c
+++ b/drivers/hwmon/s3c-hwmon.c
@@ -232,6 +232,7 @@ static int s3c_hwmon_create_attr(struct device *dev,
attr = &attrs->in;
attr->index = channel;
+ sysfs_attr_init(&attr->dev_attr.attr);
attr->dev_attr.attr.name = attrs->in_name;
attr->dev_attr.attr.mode = S_IRUGO;
attr->dev_attr.show = s3c_hwmon_ch_show;
@@ -249,6 +250,7 @@ static int s3c_hwmon_create_attr(struct device *dev,
attr = &attrs->label;
attr->index = channel;
+ sysfs_attr_init(&attr->dev_attr.attr);
attr->dev_attr.attr.name = attrs->label_name;
attr->dev_attr.attr.mode = S_IRUGO;
attr->dev_attr.show = s3c_hwmon_label_show;
diff --git a/drivers/hwmon/sch5627.c b/drivers/hwmon/sch5627.c
index 020c87273ea1..3494a4cce414 100644
--- a/drivers/hwmon/sch5627.c
+++ b/drivers/hwmon/sch5627.c
@@ -887,7 +887,7 @@ static void __exit sch5627_exit(void)
}
MODULE_DESCRIPTION("SMSC SCH5627 Hardware Monitoring Driver");
-MODULE_AUTHOR("Hans de Goede (hdegoede@redhat.com)");
+MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
MODULE_LICENSE("GPL");
module_init(sch5627_init);