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

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: ...@@ -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 ...@@ -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 ...@@ -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> ...@@ -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 ...@@ -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). ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 ...@@ -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 @@ ...@@ -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) ...@@ -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) ...@@ -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 @@ ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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);
......
Markdown is supported
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