Commit 64d9a39e authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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

* git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/hwmon-2.6:
  hwmon: Fix debug messages in w83781d
  hwmon: Let w83781d and lm78 load again
  w83627ehf: Fix the detection of fan5
  k8temp: Documentation update
  smsc47m1: List the SMSC LPC47M112 as supported
  hwmon: Fix documentation typos
  adm9240: Update Grant Coady's email address
  w83791d: Fix unchecked return status
parents 17e6c600 bd452e6f
......@@ -24,7 +24,7 @@ Authors:
Frodo Looijaard <frodol@dds.nl>,
Philip Edelbrock <phil@netroedge.com>,
Michiel Rook <michiel@grendelproject.nl>,
Grant Coady <gcoady@gmail.com> with guidance
Grant Coady <gcoady.lk@gmail.com> with guidance
from Jean Delvare <khali@linux-fr.org>
Interface
......
......@@ -17,7 +17,7 @@ Thanks to Kris Chen from Fintek for answering technical questions and
providing additional documentation.
Thanks to Chris Lin from Jetway for providing wiring schematics and
anwsering technical questions.
answering technical questions.
Description
......
......@@ -2,7 +2,7 @@ Kernel driver k8temp
====================
Supported chips:
* AMD K8 CPU
* AMD Athlon64/FX or Opteron CPUs
Prefix: 'k8temp'
Addresses scanned: PCI space
Datasheet: http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/32559.pdf
......@@ -13,10 +13,13 @@ Contact: Rudolf Marek <r.marek@sh.cvut.cz>
Description
-----------
This driver permits reading temperature sensor(s) embedded inside AMD K8 CPUs.
Official documentation says that it works from revision F of K8 core, but
in fact it seems to be implemented for all revisions of K8 except the first
two revisions (SH-B0 and SH-B3).
This driver permits reading temperature sensor(s) embedded inside AMD K8
family CPUs (Athlon64/FX, Opteron). Official documentation says that it works
from revision F of K8 core, but in fact it seems to be implemented for all
revisions of K8 except the first two revisions (SH-B0 and SH-B3).
Please note that you will need at least lm-sensors 2.10.1 for proper userspace
support.
There can be up to four temperature sensors inside single CPU. The driver
will auto-detect the sensors and will display only temperatures from
......
......@@ -2,12 +2,14 @@ Kernel driver smsc47m1
======================
Supported chips:
* SMSC LPC47B27x, LPC47M10x, LPC47M13x, LPC47M14x, LPC47M15x and LPC47M192
* SMSC LPC47B27x, LPC47M112, LPC47M10x, LPC47M13x, LPC47M14x,
LPC47M15x and LPC47M192
Addresses scanned: none, address read from Super I/O config space
Prefix: 'smsc47m1'
Datasheets:
http://www.smsc.com/main/datasheets/47b27x.pdf
http://www.smsc.com/main/datasheets/47m10x.pdf
http://www.smsc.com/main/datasheets/47m112.pdf
http://www.smsc.com/main/tools/discontinued/47m13x.pdf
http://www.smsc.com/main/datasheets/47m14x.pdf
http://www.smsc.com/main/tools/discontinued/47m15x.pdf
......
......@@ -26,7 +26,7 @@ fan control mode).
Temperatures are measured in degrees Celsius and measurement resolution is 1
degC for temp1 and 0.5 degC for temp2 and temp3. An alarm is triggered when
the temperature gets higher than high limit; it stays on until the temperature
falls below the Hysteresis value.
falls below the hysteresis value.
Fan rotation speeds are reported in RPM (rotations per minute). An alarm is
triggered if the rotation speed has dropped below a programmable limit. Fan
......@@ -67,9 +67,9 @@ Thermal Cruise mode
If the temperature is in the range defined by:
pwm[1-4]_target - set target temperature, unit millidegree Celcius
pwm[1-4]_target - set target temperature, unit millidegree Celsius
(range 0 - 127000)
pwm[1-4]_tolerance - tolerance, unit millidegree Celcius (range 0 - 15000)
pwm[1-4]_tolerance - tolerance, unit millidegree Celsius (range 0 - 15000)
there are no changes to fan speed. Once the temperature leaves the interval,
fan speed increases (temp is higher) or decreases if lower than desired.
......
......@@ -1668,6 +1668,12 @@ M: sct@redhat.com, akpm@osdl.org
L: ext2-devel@lists.sourceforge.net
S: Maintained
K8TEMP HARDWARE MONITORING DRIVER
P: Rudolf Marek
M: r.marek@assembler.cz
L: lm-sensors@lm-sensors.org
S: Maintained
KCONFIG
P: Roman Zippel
M: zippel@linux-m68k.org
......
......@@ -95,11 +95,13 @@ config SENSORS_ADM9240
will be called adm9240.
config SENSORS_K8TEMP
tristate "AMD K8 processor sensor"
tristate "AMD Athlon64/FX or Opteron temperature sensor"
depends on HWMON && X86 && PCI && EXPERIMENTAL
help
If you say yes here you get support for the temperature
sensor(s) inside your AMD K8 CPU.
sensor(s) inside your CPU. Supported is whole AMD K8
microarchitecture. Please note that you will need at least
lm-sensors 2.10.1 for proper userspace support.
This driver can also be built as a module. If so, the module
will be called k8temp.
......@@ -369,8 +371,8 @@ config SENSORS_SMSC47M1
help
If you say yes here you get support for the integrated fan
monitoring and control capabilities of the SMSC LPC47B27x,
LPC47M10x, LPC47M13x, LPC47M14x, LPC47M15x, LPC47M192 and
LPC47M997 chips.
LPC47M10x, LPC47M112, LPC47M13x, LPC47M14x, LPC47M15x,
LPC47M192 and LPC47M997 chips.
The temperature and voltage sensor features of the LPC47M192
and LPC47M997 are supported by another driver, select also
......
......@@ -5,7 +5,7 @@
* Copyright (C) 1999 Frodo Looijaard <frodol@dds.nl>
* Philip Edelbrock <phil@netroedge.com>
* Copyright (C) 2003 Michiel Rook <michiel@grendelproject.nl>
* Copyright (C) 2005 Grant Coady <gcoady@gmail.com> with valuable
* Copyright (C) 2005 Grant Coady <gcoady.lk@gmail.com> with valuable
* guidance from Jean Delvare
*
* Driver supports Analog Devices ADM9240
......@@ -774,7 +774,7 @@ static void __exit sensors_adm9240_exit(void)
}
MODULE_AUTHOR("Michiel Rook <michiel@grendelproject.nl>, "
"Grant Coady <gcoady@gmail.com> and others");
"Grant Coady <gcoady.lk@gmail.com> and others");
MODULE_DESCRIPTION("ADM9240/DS1780/LM81 driver");
MODULE_LICENSE("GPL");
......
......@@ -815,18 +815,18 @@ static int __init sm_lm78_init(void)
if (res)
return res;
res = i2c_isa_add_driver(&lm78_isa_driver);
if (res) {
i2c_del_driver(&lm78_driver);
return res;
}
/* Don't exit if this one fails, we still want the I2C variants
to work! */
if (i2c_isa_add_driver(&lm78_isa_driver))
isa_address = 0;
return 0;
}
static void __exit sm_lm78_exit(void)
{
i2c_isa_del_driver(&lm78_isa_driver);
if (isa_address)
i2c_isa_del_driver(&lm78_isa_driver);
i2c_del_driver(&lm78_driver);
}
......
......@@ -2,8 +2,8 @@
smsc47m1.c - Part of lm_sensors, Linux kernel modules
for hardware monitoring
Supports the SMSC LPC47B27x, LPC47M10x, LPC47M13x, LPC47M14x,
LPC47M15x, LPC47M192 and LPC47M997 Super-I/O chips.
Supports the SMSC LPC47B27x, LPC47M10x, LPC47M112, LPC47M13x,
LPC47M14x, LPC47M15x, LPC47M192 and LPC47M997 Super-I/O chips.
Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
Copyright (C) 2004 Jean Delvare <khali@linux-fr.org>
......@@ -380,8 +380,8 @@ static int __init smsc47m1_find(unsigned short *addr)
val = superio_inb(SUPERIO_REG_DEVID);
/*
* SMSC LPC47M10x/LPC47M13x (device id 0x59), LPC47M14x (device id
* 0x5F) and LPC47B27x (device id 0x51) have fan control.
* SMSC LPC47M10x/LPC47M112/LPC47M13x (device id 0x59), LPC47M14x
* (device id 0x5F) and LPC47B27x (device id 0x51) have fan control.
* The LPC47M15x and LPC47M192 chips "with hardware monitoring block"
* can do much more besides (device id 0x60).
* The LPC47M997 is undocumented, but seems to be compatible with
......@@ -390,7 +390,8 @@ static int __init smsc47m1_find(unsigned short *addr)
if (val == 0x51)
printk(KERN_INFO "smsc47m1: Found SMSC LPC47B27x\n");
else if (val == 0x59)
printk(KERN_INFO "smsc47m1: Found SMSC LPC47M10x/LPC47M13x\n");
printk(KERN_INFO "smsc47m1: Found SMSC "
"LPC47M10x/LPC47M112/LPC47M13x\n");
else if (val == 0x5F)
printk(KERN_INFO "smsc47m1: Found SMSC LPC47M14x\n");
else if (val == 0x60)
......
......@@ -354,6 +354,8 @@ static void w83627ehf_write_fan_div(struct i2c_client *client, int nr)
case 0:
reg = (w83627ehf_read_value(client, W83627EHF_REG_FANDIV1) & 0xcf)
| ((data->fan_div[0] & 0x03) << 4);
/* fan5 input control bit is write only, compute the value */
reg |= (data->has_fan & (1 << 4)) ? 1 : 0;
w83627ehf_write_value(client, W83627EHF_REG_FANDIV1, reg);
reg = (w83627ehf_read_value(client, W83627EHF_REG_VBAT) & 0xdf)
| ((data->fan_div[0] & 0x04) << 3);
......@@ -362,6 +364,8 @@ static void w83627ehf_write_fan_div(struct i2c_client *client, int nr)
case 1:
reg = (w83627ehf_read_value(client, W83627EHF_REG_FANDIV1) & 0x3f)
| ((data->fan_div[1] & 0x03) << 6);
/* fan5 input control bit is write only, compute the value */
reg |= (data->has_fan & (1 << 4)) ? 1 : 0;
w83627ehf_write_value(client, W83627EHF_REG_FANDIV1, reg);
reg = (w83627ehf_read_value(client, W83627EHF_REG_VBAT) & 0xbf)
| ((data->fan_div[1] & 0x04) << 4);
......@@ -1216,13 +1220,16 @@ static int w83627ehf_detect(struct i2c_adapter *adapter)
superio_exit();
/* It looks like fan4 and fan5 pins can be alternatively used
as fan on/off switches */
as fan on/off switches, but fan5 control is write only :/
We assume that if the serial interface is disabled, designers
connected fan5 as input unless they are emitting log 1, which
is not the default. */
data->has_fan = 0x07; /* fan1, fan2 and fan3 */
i = w83627ehf_read_value(client, W83627EHF_REG_FANDIV1);
if ((i & (1 << 2)) && (!fan4pin))
data->has_fan |= (1 << 3);
if ((i & (1 << 0)) && (!fan5pin))
if (!(i & (1 << 1)) && (!fan5pin))
data->has_fan |= (1 << 4);
/* Register sysfs hooks */
......
......@@ -1099,7 +1099,8 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
bank. */
if (kind < 0) {
if (w83781d_read_value(client, W83781D_REG_CONFIG) & 0x80) {
dev_dbg(dev, "Detection failed at step 3\n");
dev_dbg(&adapter->dev, "Detection of w83781d chip "
"failed at step 3\n");
err = -ENODEV;
goto ERROR2;
}
......@@ -1109,7 +1110,8 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
if ((!(val1 & 0x07)) &&
(((!(val1 & 0x80)) && (val2 != 0xa3) && (val2 != 0xc3))
|| ((val1 & 0x80) && (val2 != 0x5c) && (val2 != 0x12)))) {
dev_dbg(dev, "Detection failed at step 4\n");
dev_dbg(&adapter->dev, "Detection of w83781d chip "
"failed at step 4\n");
err = -ENODEV;
goto ERROR2;
}
......@@ -1119,7 +1121,8 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
((val1 & 0x80) && (val2 == 0x5c)))) {
if (w83781d_read_value
(client, W83781D_REG_I2C_ADDR) != address) {
dev_dbg(dev, "Detection failed at step 5\n");
dev_dbg(&adapter->dev, "Detection of w83781d "
"chip failed at step 5\n");
err = -ENODEV;
goto ERROR2;
}
......@@ -1141,8 +1144,8 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
else if (val2 == 0x12)
vendid = asus;
else {
dev_dbg(dev, "Chip was made by neither "
"Winbond nor Asus?\n");
dev_dbg(&adapter->dev, "w83781d chip vendor is "
"neither Winbond nor Asus\n");
err = -ENODEV;
goto ERROR2;
}
......@@ -1161,10 +1164,9 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
kind = as99127f;
else {
if (kind == 0)
dev_warn(dev, "Ignoring 'force' "
dev_warn(&adapter->dev, "Ignoring 'force' "
"parameter for unknown chip at "
"adapter %d, address 0x%02x\n",
i2c_adapter_id(adapter), address);
"address 0x%02x\n", address);
err = -EINVAL;
goto ERROR2;
}
......@@ -1685,11 +1687,10 @@ sensors_w83781d_init(void)
if (res)
return res;
res = i2c_isa_add_driver(&w83781d_isa_driver);
if (res) {
i2c_del_driver(&w83781d_driver);
return res;
}
/* Don't exit if this one fails, we still want the I2C variants
to work! */
if (i2c_isa_add_driver(&w83781d_isa_driver))
isa_address = 0;
return 0;
}
......@@ -1697,7 +1698,8 @@ sensors_w83781d_init(void)
static void __exit
sensors_w83781d_exit(void)
{
i2c_isa_del_driver(&w83781d_isa_driver);
if (isa_address)
i2c_isa_del_driver(&w83781d_isa_driver);
i2c_del_driver(&w83781d_driver);
}
......
......@@ -746,6 +746,52 @@ static ssize_t store_vrm_reg(struct device *dev,
static DEVICE_ATTR(vrm, S_IRUGO | S_IWUSR, show_vrm_reg, store_vrm_reg);
#define IN_UNIT_ATTRS(X) \
&sda_in_input[X].dev_attr.attr, \
&sda_in_min[X].dev_attr.attr, \
&sda_in_max[X].dev_attr.attr
#define FAN_UNIT_ATTRS(X) \
&sda_fan_input[X].dev_attr.attr, \
&sda_fan_min[X].dev_attr.attr, \
&sda_fan_div[X].dev_attr.attr
#define TEMP_UNIT_ATTRS(X) \
&sda_temp_input[X].dev_attr.attr, \
&sda_temp_max[X].dev_attr.attr, \
&sda_temp_max_hyst[X].dev_attr.attr
static struct attribute *w83791d_attributes[] = {
IN_UNIT_ATTRS(0),
IN_UNIT_ATTRS(1),
IN_UNIT_ATTRS(2),
IN_UNIT_ATTRS(3),
IN_UNIT_ATTRS(4),
IN_UNIT_ATTRS(5),
IN_UNIT_ATTRS(6),
IN_UNIT_ATTRS(7),
IN_UNIT_ATTRS(8),
IN_UNIT_ATTRS(9),
FAN_UNIT_ATTRS(0),
FAN_UNIT_ATTRS(1),
FAN_UNIT_ATTRS(2),
FAN_UNIT_ATTRS(3),
FAN_UNIT_ATTRS(4),
TEMP_UNIT_ATTRS(0),
TEMP_UNIT_ATTRS(1),
TEMP_UNIT_ATTRS(2),
&dev_attr_alarms.attr,
&sda_beep_ctrl[0].dev_attr.attr,
&sda_beep_ctrl[1].dev_attr.attr,
&dev_attr_cpu0_vid.attr,
&dev_attr_vrm.attr,
NULL
};
static const struct attribute_group w83791d_group = {
.attrs = w83791d_attributes,
};
/* This function is called when:
* w83791d_driver is inserted (when this module is loaded), for each
available adapter
......@@ -967,41 +1013,20 @@ static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind)
}
/* Register sysfs hooks */
if ((err = sysfs_create_group(&client->dev.kobj, &w83791d_group)))
goto error3;
/* Everything is ready, now register the working device */
data->class_dev = hwmon_device_register(dev);
if (IS_ERR(data->class_dev)) {
err = PTR_ERR(data->class_dev);
goto error3;
goto error4;
}
for (i = 0; i < NUMBER_OF_VIN; i++) {
device_create_file(dev, &sda_in_input[i].dev_attr);
device_create_file(dev, &sda_in_min[i].dev_attr);
device_create_file(dev, &sda_in_max[i].dev_attr);
}
for (i = 0; i < NUMBER_OF_FANIN; 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);
}
for (i = 0; i < NUMBER_OF_TEMPIN; 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, &dev_attr_alarms);
for (i = 0; i < ARRAY_SIZE(sda_beep_ctrl); i++) {
device_create_file(dev, &sda_beep_ctrl[i].dev_attr);
}
device_create_file(dev, &dev_attr_cpu0_vid);
device_create_file(dev, &dev_attr_vrm);
return 0;
error4:
sysfs_remove_group(&client->dev.kobj, &w83791d_group);
error3:
if (data->lm75[0] != NULL) {
i2c_detach_client(data->lm75[0]);
......@@ -1025,8 +1050,10 @@ static int w83791d_detach_client(struct i2c_client *client)
int err;
/* main client */
if (data)
if (data) {
hwmon_device_unregister(data->class_dev);
sysfs_remove_group(&client->dev.kobj, &w83791d_group);
}
if ((err = i2c_detach_client(client)))
return err;
......
......@@ -91,7 +91,7 @@ int i2c_isa_add_driver(struct i2c_driver *driver)
/* Now look for clients */
res = driver->attach_adapter(&isa_adapter);
if (res) {
dev_err(&isa_adapter.dev,
dev_dbg(&isa_adapter.dev,
"Driver %s failed to attach adapter, unregistering\n",
driver->driver.name);
driver_unregister(&driver->driver);
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment