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
This commit is contained in:
@@ -24,7 +24,7 @@ Authors:
|
|||||||
Frodo Looijaard <frodol@dds.nl>,
|
Frodo Looijaard <frodol@dds.nl>,
|
||||||
Philip Edelbrock <phil@netroedge.com>,
|
Philip Edelbrock <phil@netroedge.com>,
|
||||||
Michiel Rook <michiel@grendelproject.nl>,
|
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>
|
from Jean Delvare <khali@linux-fr.org>
|
||||||
|
|
||||||
Interface
|
Interface
|
||||||
|
@@ -17,7 +17,7 @@ Thanks to Kris Chen from Fintek for answering technical questions and
|
|||||||
providing additional documentation.
|
providing additional documentation.
|
||||||
|
|
||||||
Thanks to Chris Lin from Jetway for providing wiring schematics and
|
Thanks to Chris Lin from Jetway for providing wiring schematics and
|
||||||
anwsering technical questions.
|
answering technical questions.
|
||||||
|
|
||||||
|
|
||||||
Description
|
Description
|
||||||
|
@@ -2,7 +2,7 @@ Kernel driver k8temp
|
|||||||
====================
|
====================
|
||||||
|
|
||||||
Supported chips:
|
Supported chips:
|
||||||
* AMD K8 CPU
|
* AMD Athlon64/FX or Opteron CPUs
|
||||||
Prefix: 'k8temp'
|
Prefix: 'k8temp'
|
||||||
Addresses scanned: PCI space
|
Addresses scanned: PCI space
|
||||||
Datasheet: http://www.amd.com/us-en/assets/content_type/white_papers_and_tech_docs/32559.pdf
|
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
|
Description
|
||||||
-----------
|
-----------
|
||||||
|
|
||||||
This driver permits reading temperature sensor(s) embedded inside AMD K8 CPUs.
|
This driver permits reading temperature sensor(s) embedded inside AMD K8
|
||||||
Official documentation says that it works from revision F of K8 core, but
|
family CPUs (Athlon64/FX, Opteron). Official documentation says that it works
|
||||||
in fact it seems to be implemented for all revisions of K8 except the first
|
from revision F of K8 core, but in fact it seems to be implemented for all
|
||||||
two revisions (SH-B0 and SH-B3).
|
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
|
There can be up to four temperature sensors inside single CPU. The driver
|
||||||
will auto-detect the sensors and will display only temperatures from
|
will auto-detect the sensors and will display only temperatures from
|
||||||
|
@@ -2,12 +2,14 @@ Kernel driver smsc47m1
|
|||||||
======================
|
======================
|
||||||
|
|
||||||
Supported chips:
|
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
|
Addresses scanned: none, address read from Super I/O config space
|
||||||
Prefix: 'smsc47m1'
|
Prefix: 'smsc47m1'
|
||||||
Datasheets:
|
Datasheets:
|
||||||
http://www.smsc.com/main/datasheets/47b27x.pdf
|
http://www.smsc.com/main/datasheets/47b27x.pdf
|
||||||
http://www.smsc.com/main/datasheets/47m10x.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/tools/discontinued/47m13x.pdf
|
||||||
http://www.smsc.com/main/datasheets/47m14x.pdf
|
http://www.smsc.com/main/datasheets/47m14x.pdf
|
||||||
http://www.smsc.com/main/tools/discontinued/47m15x.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
|
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
|
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
|
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
|
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
|
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:
|
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)
|
(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,
|
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.
|
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
|
L: ext2-devel@lists.sourceforge.net
|
||||||
S: Maintained
|
S: Maintained
|
||||||
|
|
||||||
|
K8TEMP HARDWARE MONITORING DRIVER
|
||||||
|
P: Rudolf Marek
|
||||||
|
M: r.marek@assembler.cz
|
||||||
|
L: lm-sensors@lm-sensors.org
|
||||||
|
S: Maintained
|
||||||
|
|
||||||
KCONFIG
|
KCONFIG
|
||||||
P: Roman Zippel
|
P: Roman Zippel
|
||||||
M: zippel@linux-m68k.org
|
M: zippel@linux-m68k.org
|
||||||
|
@@ -95,11 +95,13 @@ config SENSORS_ADM9240
|
|||||||
will be called adm9240.
|
will be called adm9240.
|
||||||
|
|
||||||
config SENSORS_K8TEMP
|
config SENSORS_K8TEMP
|
||||||
tristate "AMD K8 processor sensor"
|
tristate "AMD Athlon64/FX or Opteron temperature sensor"
|
||||||
depends on HWMON && X86 && PCI && EXPERIMENTAL
|
depends on HWMON && X86 && PCI && EXPERIMENTAL
|
||||||
help
|
help
|
||||||
If you say yes here you get support for the temperature
|
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
|
This driver can also be built as a module. If so, the module
|
||||||
will be called k8temp.
|
will be called k8temp.
|
||||||
@@ -369,8 +371,8 @@ config SENSORS_SMSC47M1
|
|||||||
help
|
help
|
||||||
If you say yes here you get support for the integrated fan
|
If you say yes here you get support for the integrated fan
|
||||||
monitoring and control capabilities of the SMSC LPC47B27x,
|
monitoring and control capabilities of the SMSC LPC47B27x,
|
||||||
LPC47M10x, LPC47M13x, LPC47M14x, LPC47M15x, LPC47M192 and
|
LPC47M10x, LPC47M112, LPC47M13x, LPC47M14x, LPC47M15x,
|
||||||
LPC47M997 chips.
|
LPC47M192 and LPC47M997 chips.
|
||||||
|
|
||||||
The temperature and voltage sensor features of the LPC47M192
|
The temperature and voltage sensor features of the LPC47M192
|
||||||
and LPC47M997 are supported by another driver, select also
|
and LPC47M997 are supported by another driver, select also
|
||||||
|
@@ -5,7 +5,7 @@
|
|||||||
* Copyright (C) 1999 Frodo Looijaard <frodol@dds.nl>
|
* Copyright (C) 1999 Frodo Looijaard <frodol@dds.nl>
|
||||||
* Philip Edelbrock <phil@netroedge.com>
|
* Philip Edelbrock <phil@netroedge.com>
|
||||||
* Copyright (C) 2003 Michiel Rook <michiel@grendelproject.nl>
|
* 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
|
* guidance from Jean Delvare
|
||||||
*
|
*
|
||||||
* Driver supports Analog Devices ADM9240
|
* Driver supports Analog Devices ADM9240
|
||||||
@@ -774,7 +774,7 @@ static void __exit sensors_adm9240_exit(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
MODULE_AUTHOR("Michiel Rook <michiel@grendelproject.nl>, "
|
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_DESCRIPTION("ADM9240/DS1780/LM81 driver");
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
|
|
||||||
|
@@ -815,17 +815,17 @@ static int __init sm_lm78_init(void)
|
|||||||
if (res)
|
if (res)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
res = i2c_isa_add_driver(&lm78_isa_driver);
|
/* Don't exit if this one fails, we still want the I2C variants
|
||||||
if (res) {
|
to work! */
|
||||||
i2c_del_driver(&lm78_driver);
|
if (i2c_isa_add_driver(&lm78_isa_driver))
|
||||||
return res;
|
isa_address = 0;
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void __exit sm_lm78_exit(void)
|
static void __exit sm_lm78_exit(void)
|
||||||
{
|
{
|
||||||
|
if (isa_address)
|
||||||
i2c_isa_del_driver(&lm78_isa_driver);
|
i2c_isa_del_driver(&lm78_isa_driver);
|
||||||
i2c_del_driver(&lm78_driver);
|
i2c_del_driver(&lm78_driver);
|
||||||
}
|
}
|
||||||
|
@@ -2,8 +2,8 @@
|
|||||||
smsc47m1.c - Part of lm_sensors, Linux kernel modules
|
smsc47m1.c - Part of lm_sensors, Linux kernel modules
|
||||||
for hardware monitoring
|
for hardware monitoring
|
||||||
|
|
||||||
Supports the SMSC LPC47B27x, LPC47M10x, LPC47M13x, LPC47M14x,
|
Supports the SMSC LPC47B27x, LPC47M10x, LPC47M112, LPC47M13x,
|
||||||
LPC47M15x, LPC47M192 and LPC47M997 Super-I/O chips.
|
LPC47M14x, LPC47M15x, LPC47M192 and LPC47M997 Super-I/O chips.
|
||||||
|
|
||||||
Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
|
Copyright (C) 2002 Mark D. Studebaker <mdsxyz123@yahoo.com>
|
||||||
Copyright (C) 2004 Jean Delvare <khali@linux-fr.org>
|
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);
|
val = superio_inb(SUPERIO_REG_DEVID);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* SMSC LPC47M10x/LPC47M13x (device id 0x59), LPC47M14x (device id
|
* SMSC LPC47M10x/LPC47M112/LPC47M13x (device id 0x59), LPC47M14x
|
||||||
* 0x5F) and LPC47B27x (device id 0x51) have fan control.
|
* (device id 0x5F) and LPC47B27x (device id 0x51) have fan control.
|
||||||
* The LPC47M15x and LPC47M192 chips "with hardware monitoring block"
|
* The LPC47M15x and LPC47M192 chips "with hardware monitoring block"
|
||||||
* can do much more besides (device id 0x60).
|
* can do much more besides (device id 0x60).
|
||||||
* The LPC47M997 is undocumented, but seems to be compatible with
|
* 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)
|
if (val == 0x51)
|
||||||
printk(KERN_INFO "smsc47m1: Found SMSC LPC47B27x\n");
|
printk(KERN_INFO "smsc47m1: Found SMSC LPC47B27x\n");
|
||||||
else if (val == 0x59)
|
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)
|
else if (val == 0x5F)
|
||||||
printk(KERN_INFO "smsc47m1: Found SMSC LPC47M14x\n");
|
printk(KERN_INFO "smsc47m1: Found SMSC LPC47M14x\n");
|
||||||
else if (val == 0x60)
|
else if (val == 0x60)
|
||||||
|
@@ -354,6 +354,8 @@ static void w83627ehf_write_fan_div(struct i2c_client *client, int nr)
|
|||||||
case 0:
|
case 0:
|
||||||
reg = (w83627ehf_read_value(client, W83627EHF_REG_FANDIV1) & 0xcf)
|
reg = (w83627ehf_read_value(client, W83627EHF_REG_FANDIV1) & 0xcf)
|
||||||
| ((data->fan_div[0] & 0x03) << 4);
|
| ((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);
|
w83627ehf_write_value(client, W83627EHF_REG_FANDIV1, reg);
|
||||||
reg = (w83627ehf_read_value(client, W83627EHF_REG_VBAT) & 0xdf)
|
reg = (w83627ehf_read_value(client, W83627EHF_REG_VBAT) & 0xdf)
|
||||||
| ((data->fan_div[0] & 0x04) << 3);
|
| ((data->fan_div[0] & 0x04) << 3);
|
||||||
@@ -362,6 +364,8 @@ static void w83627ehf_write_fan_div(struct i2c_client *client, int nr)
|
|||||||
case 1:
|
case 1:
|
||||||
reg = (w83627ehf_read_value(client, W83627EHF_REG_FANDIV1) & 0x3f)
|
reg = (w83627ehf_read_value(client, W83627EHF_REG_FANDIV1) & 0x3f)
|
||||||
| ((data->fan_div[1] & 0x03) << 6);
|
| ((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);
|
w83627ehf_write_value(client, W83627EHF_REG_FANDIV1, reg);
|
||||||
reg = (w83627ehf_read_value(client, W83627EHF_REG_VBAT) & 0xbf)
|
reg = (w83627ehf_read_value(client, W83627EHF_REG_VBAT) & 0xbf)
|
||||||
| ((data->fan_div[1] & 0x04) << 4);
|
| ((data->fan_div[1] & 0x04) << 4);
|
||||||
@@ -1216,13 +1220,16 @@ static int w83627ehf_detect(struct i2c_adapter *adapter)
|
|||||||
superio_exit();
|
superio_exit();
|
||||||
|
|
||||||
/* It looks like fan4 and fan5 pins can be alternatively used
|
/* 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 */
|
data->has_fan = 0x07; /* fan1, fan2 and fan3 */
|
||||||
i = w83627ehf_read_value(client, W83627EHF_REG_FANDIV1);
|
i = w83627ehf_read_value(client, W83627EHF_REG_FANDIV1);
|
||||||
if ((i & (1 << 2)) && (!fan4pin))
|
if ((i & (1 << 2)) && (!fan4pin))
|
||||||
data->has_fan |= (1 << 3);
|
data->has_fan |= (1 << 3);
|
||||||
if ((i & (1 << 0)) && (!fan5pin))
|
if (!(i & (1 << 1)) && (!fan5pin))
|
||||||
data->has_fan |= (1 << 4);
|
data->has_fan |= (1 << 4);
|
||||||
|
|
||||||
/* Register sysfs hooks */
|
/* Register sysfs hooks */
|
||||||
|
@@ -1099,7 +1099,8 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
|
|||||||
bank. */
|
bank. */
|
||||||
if (kind < 0) {
|
if (kind < 0) {
|
||||||
if (w83781d_read_value(client, W83781D_REG_CONFIG) & 0x80) {
|
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;
|
err = -ENODEV;
|
||||||
goto ERROR2;
|
goto ERROR2;
|
||||||
}
|
}
|
||||||
@@ -1109,7 +1110,8 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
|
|||||||
if ((!(val1 & 0x07)) &&
|
if ((!(val1 & 0x07)) &&
|
||||||
(((!(val1 & 0x80)) && (val2 != 0xa3) && (val2 != 0xc3))
|
(((!(val1 & 0x80)) && (val2 != 0xa3) && (val2 != 0xc3))
|
||||||
|| ((val1 & 0x80) && (val2 != 0x5c) && (val2 != 0x12)))) {
|
|| ((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;
|
err = -ENODEV;
|
||||||
goto ERROR2;
|
goto ERROR2;
|
||||||
}
|
}
|
||||||
@@ -1119,7 +1121,8 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
|
|||||||
((val1 & 0x80) && (val2 == 0x5c)))) {
|
((val1 & 0x80) && (val2 == 0x5c)))) {
|
||||||
if (w83781d_read_value
|
if (w83781d_read_value
|
||||||
(client, W83781D_REG_I2C_ADDR) != address) {
|
(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;
|
err = -ENODEV;
|
||||||
goto ERROR2;
|
goto ERROR2;
|
||||||
}
|
}
|
||||||
@@ -1141,8 +1144,8 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
|
|||||||
else if (val2 == 0x12)
|
else if (val2 == 0x12)
|
||||||
vendid = asus;
|
vendid = asus;
|
||||||
else {
|
else {
|
||||||
dev_dbg(dev, "Chip was made by neither "
|
dev_dbg(&adapter->dev, "w83781d chip vendor is "
|
||||||
"Winbond nor Asus?\n");
|
"neither Winbond nor Asus\n");
|
||||||
err = -ENODEV;
|
err = -ENODEV;
|
||||||
goto ERROR2;
|
goto ERROR2;
|
||||||
}
|
}
|
||||||
@@ -1161,10 +1164,9 @@ w83781d_detect(struct i2c_adapter *adapter, int address, int kind)
|
|||||||
kind = as99127f;
|
kind = as99127f;
|
||||||
else {
|
else {
|
||||||
if (kind == 0)
|
if (kind == 0)
|
||||||
dev_warn(dev, "Ignoring 'force' "
|
dev_warn(&adapter->dev, "Ignoring 'force' "
|
||||||
"parameter for unknown chip at "
|
"parameter for unknown chip at "
|
||||||
"adapter %d, address 0x%02x\n",
|
"address 0x%02x\n", address);
|
||||||
i2c_adapter_id(adapter), address);
|
|
||||||
err = -EINVAL;
|
err = -EINVAL;
|
||||||
goto ERROR2;
|
goto ERROR2;
|
||||||
}
|
}
|
||||||
@@ -1685,11 +1687,10 @@ sensors_w83781d_init(void)
|
|||||||
if (res)
|
if (res)
|
||||||
return res;
|
return res;
|
||||||
|
|
||||||
res = i2c_isa_add_driver(&w83781d_isa_driver);
|
/* Don't exit if this one fails, we still want the I2C variants
|
||||||
if (res) {
|
to work! */
|
||||||
i2c_del_driver(&w83781d_driver);
|
if (i2c_isa_add_driver(&w83781d_isa_driver))
|
||||||
return res;
|
isa_address = 0;
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1697,6 +1698,7 @@ sensors_w83781d_init(void)
|
|||||||
static void __exit
|
static void __exit
|
||||||
sensors_w83781d_exit(void)
|
sensors_w83781d_exit(void)
|
||||||
{
|
{
|
||||||
|
if (isa_address)
|
||||||
i2c_isa_del_driver(&w83781d_isa_driver);
|
i2c_isa_del_driver(&w83781d_isa_driver);
|
||||||
i2c_del_driver(&w83781d_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);
|
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:
|
/* This function is called when:
|
||||||
* w83791d_driver is inserted (when this module is loaded), for each
|
* w83791d_driver is inserted (when this module is loaded), for each
|
||||||
available adapter
|
available adapter
|
||||||
@@ -967,41 +1013,20 @@ static int w83791d_detect(struct i2c_adapter *adapter, int address, int kind)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Register sysfs hooks */
|
/* 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);
|
data->class_dev = hwmon_device_register(dev);
|
||||||
if (IS_ERR(data->class_dev)) {
|
if (IS_ERR(data->class_dev)) {
|
||||||
err = PTR_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;
|
return 0;
|
||||||
|
|
||||||
|
error4:
|
||||||
|
sysfs_remove_group(&client->dev.kobj, &w83791d_group);
|
||||||
error3:
|
error3:
|
||||||
if (data->lm75[0] != NULL) {
|
if (data->lm75[0] != NULL) {
|
||||||
i2c_detach_client(data->lm75[0]);
|
i2c_detach_client(data->lm75[0]);
|
||||||
@@ -1025,8 +1050,10 @@ static int w83791d_detach_client(struct i2c_client *client)
|
|||||||
int err;
|
int err;
|
||||||
|
|
||||||
/* main client */
|
/* main client */
|
||||||
if (data)
|
if (data) {
|
||||||
hwmon_device_unregister(data->class_dev);
|
hwmon_device_unregister(data->class_dev);
|
||||||
|
sysfs_remove_group(&client->dev.kobj, &w83791d_group);
|
||||||
|
}
|
||||||
|
|
||||||
if ((err = i2c_detach_client(client)))
|
if ((err = i2c_detach_client(client)))
|
||||||
return err;
|
return err;
|
||||||
|
@@ -91,7 +91,7 @@ int i2c_isa_add_driver(struct i2c_driver *driver)
|
|||||||
/* Now look for clients */
|
/* Now look for clients */
|
||||||
res = driver->attach_adapter(&isa_adapter);
|
res = driver->attach_adapter(&isa_adapter);
|
||||||
if (res) {
|
if (res) {
|
||||||
dev_err(&isa_adapter.dev,
|
dev_dbg(&isa_adapter.dev,
|
||||||
"Driver %s failed to attach adapter, unregistering\n",
|
"Driver %s failed to attach adapter, unregistering\n",
|
||||||
driver->driver.name);
|
driver->driver.name);
|
||||||
driver_unregister(&driver->driver);
|
driver_unregister(&driver->driver);
|
||||||
|
Reference in New Issue
Block a user