aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-03-30 20:54:32 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2009-03-30 20:54:32 -0400
commit3c6fae67d026d57f64eb3da9c0d0e76983e39ae3 (patch)
treea11f2ff6d99b382fff02a643f6b6b204efb9c40e
parentc4e1aa67ed9e4e542a064bc271ddbf152b677e91 (diff)
parentde15f093e666ccd542f6f7a0e3e917166a07ab44 (diff)
Merge branch 'hwmon-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6
* 'hwmon-for-linus' of git://jdelvare.pck.nerim.net/jdelvare-2.6: hwmon: (fschmd) Add support for the FSC Hades IC hwmon: (fschmd) Add support for the FSC Syleus IC i2c-i801: Instantiate FSC hardware montioring chips dmi: Let dmi_walk() users pass private data hwmon: Define a standard interface for chassis intrusion detection Move the pcf8591 driver to hwmon hwmon: (w83627ehf) Only expose in6 or temp3 on the W83667HG hwmon: (w83627ehf) Add support for W83667HG hwmon: (w83627ehf) Invert fan pin variables logic hwmon: (hdaps) Fix Thinkpad X41 axis inversion hwmon: (hdaps) Allow inversion of separate axis hwmon: (ds1621) Clean up documentation hwmon: (ds1621) Avoid unneeded register access hwmon: (ds1621) Clean up register access hwmon: (ds1621) Reorder code statements
-rw-r--r--Documentation/hwmon/ds162151
-rw-r--r--Documentation/hwmon/pcf8591 (renamed from Documentation/i2c/chips/pcf8591)0
-rw-r--r--Documentation/hwmon/sysfs-interface22
-rw-r--r--Documentation/hwmon/w83627ehf29
-rw-r--r--drivers/firmware/dmi_scan.c18
-rw-r--r--drivers/hwmon/Kconfig27
-rw-r--r--drivers/hwmon/Makefile1
-rw-r--r--drivers/hwmon/ds1621.c172
-rw-r--r--drivers/hwmon/fschmd.c229
-rw-r--r--drivers/hwmon/hdaps.c66
-rw-r--r--drivers/hwmon/pcf8591.c (renamed from drivers/i2c/chips/pcf8591.c)24
-rw-r--r--drivers/hwmon/w83627ehf.c170
-rw-r--r--drivers/i2c/busses/i2c-i801.c77
-rw-r--r--drivers/i2c/chips/Kconfig13
-rw-r--r--drivers/i2c/chips/Makefile1
-rw-r--r--drivers/platform/x86/dell-laptop.c4
-rw-r--r--drivers/watchdog/hpwdt.c4
-rw-r--r--include/linux/dmi.h7
18 files changed, 588 insertions, 327 deletions
diff --git a/Documentation/hwmon/ds1621 b/Documentation/hwmon/ds1621
index 1fee6f1e6bc5..5e97f333c4df 100644
--- a/Documentation/hwmon/ds1621
+++ b/Documentation/hwmon/ds1621
@@ -49,12 +49,9 @@ of up to +/- 0.5 degrees even when compared against precise temperature
49readings. Be sure to have a high vs. low temperature limit gap of al least 49readings. Be sure to have a high vs. low temperature limit gap of al least
501.0 degree Celsius to avoid Tout "bouncing", though! 501.0 degree Celsius to avoid Tout "bouncing", though!
51 51
52As for alarms, you can read the alarm status of the DS1621 via the 'alarms' 52The alarm bits are set when the high or low limits are met or exceeded and
53/sys file interface. The result consists mainly of bit 6 and 5 of the 53are reset by the module as soon as the respective temperature ranges are
54configuration register of the chip; bit 6 (0x40 or 64) is the high alarm 54left.
55bit and bit 5 (0x20 or 32) the low one. These bits are set when the high or
56low limits are met or exceeded and are reset by the module as soon as the
57respective temperature ranges are left.
58 55
59The alarm registers are in no way suitable to find out about the actual 56The alarm registers are in no way suitable to find out about the actual
60status of Tout. They will only tell you about its history, whether or not 57status of Tout. They will only tell you about its history, whether or not
@@ -64,45 +61,3 @@ with neither of the alarms set.
64 61
65Temperature conversion of the DS1621 takes up to 1000ms; internal access to 62Temperature conversion of the DS1621 takes up to 1000ms; internal access to
66non-volatile registers may last for 10ms or below. 63non-volatile registers may last for 10ms or below.
67
68High Accuracy Temperature Reading
69---------------------------------
70
71As said before, the temperature issued via the 9-bit i2c-bus data is
72somewhat arbitrary. Internally, the temperature conversion is of a
73different kind that is explained (not so...) well in the DS1621 data sheet.
74To cut the long story short: Inside the DS1621 there are two oscillators,
75both of them biassed by a temperature coefficient.
76
77Higher resolution of the temperature reading can be achieved using the
78internal projection, which means taking account of REG_COUNT and REG_SLOPE
79(the driver manages them):
80
81Taken from Dallas Semiconductors App Note 068: 'Increasing Temperature
82Resolution on the DS1620' and App Note 105: 'High Resolution Temperature
83Measurement with Dallas Direct-to-Digital Temperature Sensors'
84
85- Read the 9-bit temperature and strip the LSB (Truncate the .5 degs)
86- The resulting value is TEMP_READ.
87- Then, read REG_COUNT.
88- And then, REG_SLOPE.
89
90 TEMP = TEMP_READ - 0.25 + ((REG_SLOPE - REG_COUNT) / REG_SLOPE)
91
92Note that this is what the DONE bit in the DS1621 configuration register is
93good for: Internally, one temperature conversion takes up to 1000ms. Before
94that conversion is complete you will not be able to read valid things out
95of REG_COUNT and REG_SLOPE. The DONE bit, as you may have guessed by now,
96tells you whether the conversion is complete ("done", in plain English) and
97thus, whether the values you read are good or not.
98
99The DS1621 has two modes of operation: "Continuous" conversion, which can
100be understood as the default stand-alone mode where the chip gets the
101temperature and controls external devices via its Tout pin or tells other
102i2c's about it if they care. The other mode is called "1SHOT", that means
103that it only figures out about the temperature when it is explicitly told
104to do so; this can be seen as power saving mode.
105
106Now if you want to read REG_COUNT and REG_SLOPE, you have to either stop
107the continuous conversions until the contents of these registers are valid,
108or, in 1SHOT mode, you have to have one conversion made.
diff --git a/Documentation/i2c/chips/pcf8591 b/Documentation/hwmon/pcf8591
index 5628fcf4207f..5628fcf4207f 100644
--- a/Documentation/i2c/chips/pcf8591
+++ b/Documentation/hwmon/pcf8591
diff --git a/Documentation/hwmon/sysfs-interface b/Documentation/hwmon/sysfs-interface
index 6dbfd5efd991..2f10ce6a879f 100644
--- a/Documentation/hwmon/sysfs-interface
+++ b/Documentation/hwmon/sysfs-interface
@@ -365,6 +365,7 @@ energy[1-*]_input Cumulative energy use
365 Unit: microJoule 365 Unit: microJoule
366 RO 366 RO
367 367
368
368********** 369**********
369* Alarms * 370* Alarms *
370********** 371**********
@@ -453,6 +454,27 @@ beep_mask Bitmask for beep.
453 RW 454 RW
454 455
455 456
457***********************
458* Intrusion detection *
459***********************
460
461intrusion[0-*]_alarm
462 Chassis intrusion detection
463 0: OK
464 1: intrusion detected
465 RW
466 Contrary to regular alarm flags which clear themselves
467 automatically when read, this one sticks until cleared by
468 the user. This is done by writing 0 to the file. Writing
469 other values is unsupported.
470
471intrusion[0-*]_beep
472 Chassis intrusion beep
473 0: disable
474 1: enable
475 RW
476
477
456sysfs attribute writes interpretation 478sysfs attribute writes interpretation
457------------------------------------- 479-------------------------------------
458 480
diff --git a/Documentation/hwmon/w83627ehf b/Documentation/hwmon/w83627ehf
index d6e1ae30fa6e..b6eb59384bb3 100644
--- a/Documentation/hwmon/w83627ehf
+++ b/Documentation/hwmon/w83627ehf
@@ -2,30 +2,40 @@ Kernel driver w83627ehf
2======================= 2=======================
3 3
4Supported chips: 4Supported chips:
5 * Winbond W83627EHF/EHG/DHG (ISA access ONLY) 5 * Winbond W83627EHF/EHG (ISA access ONLY)
6 Prefix: 'w83627ehf' 6 Prefix: 'w83627ehf'
7 Addresses scanned: ISA address retrieved from Super I/O registers 7 Addresses scanned: ISA address retrieved from Super I/O registers
8 Datasheet: 8 Datasheet:
9 http://www.winbond-usa.com/products/winbond_products/pdfs/PCIC/W83627EHF_%20W83627EHGb.pdf 9 http://www.nuvoton.com.tw/NR/rdonlyres/A6A258F0-F0C9-4F97-81C0-C4D29E7E943E/0/W83627EHF.pdf
10 DHG datasheet confidential. 10 * Winbond W83627DHG
11 Prefix: 'w83627dhg'
12 Addresses scanned: ISA address retrieved from Super I/O registers
13 Datasheet:
14 http://www.nuvoton.com.tw/NR/rdonlyres/7885623D-A487-4CF9-A47F-30C5F73D6FE6/0/W83627DHG.pdf
15 * Winbond W83667HG
16 Prefix: 'w83667hg'
17 Addresses scanned: ISA address retrieved from Super I/O registers
18 Datasheet: not available
11 19
12Authors: 20Authors:
13 Jean Delvare <khali@linux-fr.org> 21 Jean Delvare <khali@linux-fr.org>
14 Yuan Mu (Winbond) 22 Yuan Mu (Winbond)
15 Rudolf Marek <r.marek@assembler.cz> 23 Rudolf Marek <r.marek@assembler.cz>
16 David Hubbard <david.c.hubbard@gmail.com> 24 David Hubbard <david.c.hubbard@gmail.com>
25 Gong Jun <JGong@nuvoton.com>
17 26
18Description 27Description
19----------- 28-----------
20 29
21This driver implements support for the Winbond W83627EHF, W83627EHG, and 30This driver implements support for the Winbond W83627EHF, W83627EHG,
22W83627DHG super I/O chips. We will refer to them collectively as Winbond chips. 31W83627DHG and W83667HG super I/O chips. We will refer to them collectively
32as Winbond chips.
23 33
24The chips implement three temperature sensors, five fan rotation 34The chips implement three temperature sensors, five fan rotation
25speed sensors, ten analog voltage sensors (only nine for the 627DHG), one 35speed sensors, ten analog voltage sensors (only nine for the 627DHG), one
26VID (6 pins for the 627EHF/EHG, 8 pins for the 627DHG), alarms with beep 36VID (6 pins for the 627EHF/EHG, 8 pins for the 627DHG and 667HG), alarms
27warnings (control unimplemented), and some automatic fan regulation 37with beep warnings (control unimplemented), and some automatic fan
28strategies (plus manual fan control mode). 38regulation strategies (plus manual fan control mode).
29 39
30Temperatures are measured in degrees Celsius and measurement resolution is 1 40Temperatures are measured in degrees Celsius and measurement resolution is 1
31degC for temp1 and 0.5 degC for temp2 and temp3. An alarm is triggered when 41degC for temp1 and 0.5 degC for temp2 and temp3. An alarm is triggered when
@@ -54,7 +64,8 @@ follows:
54temp1 -> pwm1 64temp1 -> pwm1
55temp2 -> pwm2 65temp2 -> pwm2
56temp3 -> pwm3 66temp3 -> pwm3
57prog -> pwm4 (the programmable setting is not supported by the driver) 67prog -> pwm4 (not on 667HG; the programmable setting is not supported by
68 the driver)
58 69
59/sys files 70/sys files
60---------- 71----------
diff --git a/drivers/firmware/dmi_scan.c b/drivers/firmware/dmi_scan.c
index 8f0f7c449305..5f1b5400d96a 100644
--- a/drivers/firmware/dmi_scan.c
+++ b/drivers/firmware/dmi_scan.c
@@ -68,7 +68,8 @@ static char * __init dmi_string(const struct dmi_header *dm, u8 s)
68 * pointing to completely the wrong place for example 68 * pointing to completely the wrong place for example
69 */ 69 */
70static void dmi_table(u8 *buf, int len, int num, 70static void dmi_table(u8 *buf, int len, int num,
71 void (*decode)(const struct dmi_header *)) 71 void (*decode)(const struct dmi_header *, void *),
72 void *private_data)
72{ 73{
73 u8 *data = buf; 74 u8 *data = buf;
74 int i = 0; 75 int i = 0;
@@ -89,7 +90,7 @@ static void dmi_table(u8 *buf, int len, int num,
89 while ((data - buf < len - 1) && (data[0] || data[1])) 90 while ((data - buf < len - 1) && (data[0] || data[1]))
90 data++; 91 data++;
91 if (data - buf < len - 1) 92 if (data - buf < len - 1)
92 decode(dm); 93 decode(dm, private_data);
93 data += 2; 94 data += 2;
94 i++; 95 i++;
95 } 96 }
@@ -99,7 +100,8 @@ static u32 dmi_base;
99static u16 dmi_len; 100static u16 dmi_len;
100static u16 dmi_num; 101static u16 dmi_num;
101 102
102static int __init dmi_walk_early(void (*decode)(const struct dmi_header *)) 103static int __init dmi_walk_early(void (*decode)(const struct dmi_header *,
104 void *))
103{ 105{
104 u8 *buf; 106 u8 *buf;
105 107
@@ -107,7 +109,7 @@ static int __init dmi_walk_early(void (*decode)(const struct dmi_header *))
107 if (buf == NULL) 109 if (buf == NULL)
108 return -1; 110 return -1;
109 111
110 dmi_table(buf, dmi_len, dmi_num, decode); 112 dmi_table(buf, dmi_len, dmi_num, decode, NULL);
111 113
112 dmi_iounmap(buf, dmi_len); 114 dmi_iounmap(buf, dmi_len);
113 return 0; 115 return 0;
@@ -295,7 +297,7 @@ static void __init dmi_save_extended_devices(const struct dmi_header *dm)
295 * and machine entries. For 2.5 we should pull the smbus controller info 297 * and machine entries. For 2.5 we should pull the smbus controller info
296 * out of here. 298 * out of here.
297 */ 299 */
298static void __init dmi_decode(const struct dmi_header *dm) 300static void __init dmi_decode(const struct dmi_header *dm, void *dummy)
299{ 301{
300 switch(dm->type) { 302 switch(dm->type) {
301 case 0: /* BIOS Information */ 303 case 0: /* BIOS Information */
@@ -598,10 +600,12 @@ int dmi_get_year(int field)
598/** 600/**
599 * dmi_walk - Walk the DMI table and get called back for every record 601 * dmi_walk - Walk the DMI table and get called back for every record
600 * @decode: Callback function 602 * @decode: Callback function
603 * @private_data: Private data to be passed to the callback function
601 * 604 *
602 * Returns -1 when the DMI table can't be reached, 0 on success. 605 * Returns -1 when the DMI table can't be reached, 0 on success.
603 */ 606 */
604int dmi_walk(void (*decode)(const struct dmi_header *)) 607int dmi_walk(void (*decode)(const struct dmi_header *, void *),
608 void *private_data)
605{ 609{
606 u8 *buf; 610 u8 *buf;
607 611
@@ -612,7 +616,7 @@ int dmi_walk(void (*decode)(const struct dmi_header *))
612 if (buf == NULL) 616 if (buf == NULL)
613 return -1; 617 return -1;
614 618
615 dmi_table(buf, dmi_len, dmi_num, decode); 619 dmi_table(buf, dmi_len, dmi_num, decode, private_data);
616 620
617 iounmap(buf); 621 iounmap(buf);
618 return 0; 622 return 0;
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index b4eea0292c1a..51ff9b3d7ea2 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -343,12 +343,13 @@ config SENSORS_FSCPOS
343 will be called fscpos. 343 will be called fscpos.
344 344
345config SENSORS_FSCHMD 345config SENSORS_FSCHMD
346 tristate "FSC Poseidon, Scylla, Hermes, Heimdall and Heracles" 346 tristate "Fujitsu Siemens Computers sensor chips"
347 depends on X86 && I2C 347 depends on X86 && I2C
348 help 348 help
349 If you say yes here you get support for various Fujitsu Siemens 349 If you say yes here you get support for the following Fujitsu
350 Computers sensor chips, including support for the integrated 350 Siemens Computers (FSC) sensor chips: Poseidon, Scylla, Hermes,
351 watchdog. 351 Heimdall, Heracles, Hades and Syleus including support for the
352 integrated watchdog.
352 353
353 This is a merged driver for FSC sensor chips replacing the fscpos, 354 This is a merged driver for FSC sensor chips replacing the fscpos,
354 fscscy and fscher drivers and adding support for several other FSC 355 fscscy and fscher drivers and adding support for several other FSC
@@ -635,6 +636,20 @@ config SENSORS_PC87427
635 This driver can also be built as a module. If so, the module 636 This driver can also be built as a module. If so, the module
636 will be called pc87427. 637 will be called pc87427.
637 638
639config SENSORS_PCF8591
640 tristate "Philips PCF8591 ADC/DAC"
641 depends on I2C
642 default n
643 help
644 If you say yes here you get support for Philips PCF8591 4-channel
645 ADC, 1-channel DAC chips.
646
647 This driver can also be built as a module. If so, the module
648 will be called pcf8591.
649
650 These devices are hard to detect and rarely found on mainstream
651 hardware. If unsure, say N.
652
638config SENSORS_SIS5595 653config SENSORS_SIS5595
639 tristate "Silicon Integrated Systems Corp. SiS5595" 654 tristate "Silicon Integrated Systems Corp. SiS5595"
640 depends on PCI 655 depends on PCI
@@ -827,7 +842,7 @@ config SENSORS_W83627HF
827 will be called w83627hf. 842 will be called w83627hf.
828 843
829config SENSORS_W83627EHF 844config SENSORS_W83627EHF
830 tristate "Winbond W83627EHF/DHG" 845 tristate "Winbond W83627EHF/EHG/DHG, W83667HG"
831 select HWMON_VID 846 select HWMON_VID
832 help 847 help
833 If you say yes here you get support for the hardware 848 If you say yes here you get support for the hardware
@@ -838,6 +853,8 @@ config SENSORS_W83627EHF
838 chip suited for specific Intel processors that use PECI such as 853 chip suited for specific Intel processors that use PECI such as
839 the Core 2 Duo. 854 the Core 2 Duo.
840 855
856 This driver also supports the W83667HG chip.
857
841 This driver can also be built as a module. If so, the module 858 This driver can also be built as a module. If so, the module
842 will be called w83627ehf. 859 will be called w83627ehf.
843 860
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 2e80f37f39eb..e332d6267920 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -70,6 +70,7 @@ obj-$(CONFIG_SENSORS_MAX1619) += max1619.o
70obj-$(CONFIG_SENSORS_MAX6650) += max6650.o 70obj-$(CONFIG_SENSORS_MAX6650) += max6650.o
71obj-$(CONFIG_SENSORS_PC87360) += pc87360.o 71obj-$(CONFIG_SENSORS_PC87360) += pc87360.o
72obj-$(CONFIG_SENSORS_PC87427) += pc87427.o 72obj-$(CONFIG_SENSORS_PC87427) += pc87427.o
73obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o
73obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o 74obj-$(CONFIG_SENSORS_SIS5595) += sis5595.o
74obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o 75obj-$(CONFIG_SENSORS_SMSC47B397)+= smsc47b397.o
75obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o 76obj-$(CONFIG_SENSORS_SMSC47M1) += smsc47m1.o
diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c
index 7415381601c3..53f88f511816 100644
--- a/drivers/hwmon/ds1621.c
+++ b/drivers/hwmon/ds1621.c
@@ -81,71 +81,84 @@ struct ds1621_data {
81 u8 conf; /* Register encoding, combined */ 81 u8 conf; /* Register encoding, combined */
82}; 82};
83 83
84static int ds1621_probe(struct i2c_client *client, 84/* Temperature registers are word-sized.
85 const struct i2c_device_id *id);
86static int ds1621_detect(struct i2c_client *client, int kind,
87 struct i2c_board_info *info);
88static void ds1621_init_client(struct i2c_client *client);
89static int ds1621_remove(struct i2c_client *client);
90static struct ds1621_data *ds1621_update_client(struct device *dev);
91
92static const struct i2c_device_id ds1621_id[] = {
93 { "ds1621", ds1621 },
94 { "ds1625", ds1621 },
95 { }
96};
97MODULE_DEVICE_TABLE(i2c, ds1621_id);
98
99/* This is the driver that will be inserted */
100static struct i2c_driver ds1621_driver = {
101 .class = I2C_CLASS_HWMON,
102 .driver = {
103 .name = "ds1621",
104 },
105 .probe = ds1621_probe,
106 .remove = ds1621_remove,
107 .id_table = ds1621_id,
108 .detect = ds1621_detect,
109 .address_data = &addr_data,
110};
111
112/* All registers are word-sized, except for the configuration register.
113 DS1621 uses a high-byte first convention, which is exactly opposite to 85 DS1621 uses a high-byte first convention, which is exactly opposite to
114 the SMBus standard. */ 86 the SMBus standard. */
115static int ds1621_read_value(struct i2c_client *client, u8 reg) 87static int ds1621_read_temp(struct i2c_client *client, u8 reg)
116{ 88{
117 if (reg == DS1621_REG_CONF) 89 int ret;
118 return i2c_smbus_read_byte_data(client, reg); 90
119 else 91 ret = i2c_smbus_read_word_data(client, reg);
120 return swab16(i2c_smbus_read_word_data(client, reg)); 92 if (ret < 0)
93 return ret;
94 return swab16(ret);
121} 95}
122 96
123static int ds1621_write_value(struct i2c_client *client, u8 reg, u16 value) 97static int ds1621_write_temp(struct i2c_client *client, u8 reg, u16 value)
124{ 98{
125 if (reg == DS1621_REG_CONF) 99 return i2c_smbus_write_word_data(client, reg, swab16(value));
126 return i2c_smbus_write_byte_data(client, reg, value);
127 else
128 return i2c_smbus_write_word_data(client, reg, swab16(value));
129} 100}
130 101
131static void ds1621_init_client(struct i2c_client *client) 102static void ds1621_init_client(struct i2c_client *client)
132{ 103{
133 int reg = ds1621_read_value(client, DS1621_REG_CONF); 104 u8 conf, new_conf;
105
106 new_conf = conf = i2c_smbus_read_byte_data(client, DS1621_REG_CONF);
134 /* switch to continuous conversion mode */ 107 /* switch to continuous conversion mode */
135 reg &= ~ DS1621_REG_CONFIG_1SHOT; 108 new_conf &= ~DS1621_REG_CONFIG_1SHOT;
136 109
137 /* setup output polarity */ 110 /* setup output polarity */
138 if (polarity == 0) 111 if (polarity == 0)
139 reg &= ~DS1621_REG_CONFIG_POLARITY; 112 new_conf &= ~DS1621_REG_CONFIG_POLARITY;
140 else if (polarity == 1) 113 else if (polarity == 1)
141 reg |= DS1621_REG_CONFIG_POLARITY; 114 new_conf |= DS1621_REG_CONFIG_POLARITY;
142 115
143 ds1621_write_value(client, DS1621_REG_CONF, reg); 116 if (conf != new_conf)
117 i2c_smbus_write_byte_data(client, DS1621_REG_CONF, new_conf);
144 118
145 /* start conversion */ 119 /* start conversion */
146 i2c_smbus_write_byte(client, DS1621_COM_START); 120 i2c_smbus_write_byte(client, DS1621_COM_START);
147} 121}
148 122
123static struct ds1621_data *ds1621_update_client(struct device *dev)
124{
125 struct i2c_client *client = to_i2c_client(dev);
126 struct ds1621_data *data = i2c_get_clientdata(client);
127 u8 new_conf;
128
129 mutex_lock(&data->update_lock);
130
131 if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
132 || !data->valid) {
133 int i;
134
135 dev_dbg(&client->dev, "Starting ds1621 update\n");
136
137 data->conf = i2c_smbus_read_byte_data(client, DS1621_REG_CONF);
138
139 for (i = 0; i < ARRAY_SIZE(data->temp); i++)
140 data->temp[i] = ds1621_read_temp(client,
141 DS1621_REG_TEMP[i]);
142
143 /* reset alarms if necessary */
144 new_conf = data->conf;
145 if (data->temp[0] > data->temp[1]) /* input > min */
146 new_conf &= ~DS1621_ALARM_TEMP_LOW;
147 if (data->temp[0] < data->temp[2]) /* input < max */
148 new_conf &= ~DS1621_ALARM_TEMP_HIGH;
149 if (data->conf != new_conf)
150 i2c_smbus_write_byte_data(client, DS1621_REG_CONF,
151 new_conf);
152
153 data->last_updated = jiffies;
154 data->valid = 1;
155 }
156
157 mutex_unlock(&data->update_lock);
158
159 return data;
160}
161
149static ssize_t show_temp(struct device *dev, struct device_attribute *da, 162static ssize_t show_temp(struct device *dev, struct device_attribute *da,
150 char *buf) 163 char *buf)
151{ 164{
@@ -160,13 +173,13 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da,
160{ 173{
161 struct sensor_device_attribute *attr = to_sensor_dev_attr(da); 174 struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
162 struct i2c_client *client = to_i2c_client(dev); 175 struct i2c_client *client = to_i2c_client(dev);
163 struct ds1621_data *data = ds1621_update_client(dev); 176 struct ds1621_data *data = i2c_get_clientdata(client);
164 u16 val = LM75_TEMP_TO_REG(simple_strtol(buf, NULL, 10)); 177 u16 val = LM75_TEMP_TO_REG(simple_strtol(buf, NULL, 10));
165 178
166 mutex_lock(&data->update_lock); 179 mutex_lock(&data->update_lock);
167 data->temp[attr->index] = val; 180 data->temp[attr->index] = val;
168 ds1621_write_value(client, DS1621_REG_TEMP[attr->index], 181 ds1621_write_temp(client, DS1621_REG_TEMP[attr->index],
169 data->temp[attr->index]); 182 data->temp[attr->index]);
170 mutex_unlock(&data->update_lock); 183 mutex_unlock(&data->update_lock);
171 return count; 184 return count;
172} 185}
@@ -228,13 +241,14 @@ static int ds1621_detect(struct i2c_client *client, int kind,
228 /* The NVB bit should be low if no EEPROM write has been 241 /* The NVB bit should be low if no EEPROM write has been
229 requested during the latest 10ms, which is highly 242 requested during the latest 10ms, which is highly
230 improbable in our case. */ 243 improbable in our case. */
231 conf = ds1621_read_value(client, DS1621_REG_CONF); 244 conf = i2c_smbus_read_byte_data(client, DS1621_REG_CONF);
232 if (conf & DS1621_REG_CONFIG_NVB) 245 if (conf < 0 || conf & DS1621_REG_CONFIG_NVB)
233 return -ENODEV; 246 return -ENODEV;
234 /* The 7 lowest bits of a temperature should always be 0. */ 247 /* The 7 lowest bits of a temperature should always be 0. */
235 for (i = 0; i < ARRAY_SIZE(DS1621_REG_TEMP); i++) { 248 for (i = 0; i < ARRAY_SIZE(DS1621_REG_TEMP); i++) {
236 temp = ds1621_read_value(client, DS1621_REG_TEMP[i]); 249 temp = i2c_smbus_read_word_data(client,
237 if (temp & 0x007f) 250 DS1621_REG_TEMP[i]);
251 if (temp < 0 || (temp & 0x7f00))
238 return -ENODEV; 252 return -ENODEV;
239 } 253 }
240 } 254 }
@@ -294,45 +308,25 @@ static int ds1621_remove(struct i2c_client *client)
294 return 0; 308 return 0;
295} 309}
296 310
311static const struct i2c_device_id ds1621_id[] = {
312 { "ds1621", ds1621 },
313 { "ds1625", ds1621 },
314 { }
315};
316MODULE_DEVICE_TABLE(i2c, ds1621_id);
297 317
298static struct ds1621_data *ds1621_update_client(struct device *dev) 318/* This is the driver that will be inserted */
299{ 319static struct i2c_driver ds1621_driver = {
300 struct i2c_client *client = to_i2c_client(dev); 320 .class = I2C_CLASS_HWMON,
301 struct ds1621_data *data = i2c_get_clientdata(client); 321 .driver = {
302 u8 new_conf; 322 .name = "ds1621",
303 323 },
304 mutex_lock(&data->update_lock); 324 .probe = ds1621_probe,
305 325 .remove = ds1621_remove,
306 if (time_after(jiffies, data->last_updated + HZ + HZ / 2) 326 .id_table = ds1621_id,
307 || !data->valid) { 327 .detect = ds1621_detect,
308 int i; 328 .address_data = &addr_data,
309 329};
310 dev_dbg(&client->dev, "Starting ds1621 update\n");
311
312 data->conf = ds1621_read_value(client, DS1621_REG_CONF);
313
314 for (i = 0; i < ARRAY_SIZE(data->temp); i++)
315 data->temp[i] = ds1621_read_value(client,
316 DS1621_REG_TEMP[i]);
317
318 /* reset alarms if necessary */
319 new_conf = data->conf;
320 if (data->temp[0] > data->temp[1]) /* input > min */
321 new_conf &= ~DS1621_ALARM_TEMP_LOW;
322 if (data->temp[0] < data->temp[2]) /* input < max */
323 new_conf &= ~DS1621_ALARM_TEMP_HIGH;
324 if (data->conf != new_conf)
325 ds1621_write_value(client, DS1621_REG_CONF,
326 new_conf);
327
328 data->last_updated = jiffies;
329 data->valid = 1;
330 }
331
332 mutex_unlock(&data->update_lock);
333
334 return data;
335}
336 330
337static int __init ds1621_init(void) 331static int __init ds1621_init(void)
338{ 332{
diff --git a/drivers/hwmon/fschmd.c b/drivers/hwmon/fschmd.c
index d07f4ef75092..ea955edde87e 100644
--- a/drivers/hwmon/fschmd.c
+++ b/drivers/hwmon/fschmd.c
@@ -1,6 +1,6 @@
1/* fschmd.c 1/* fschmd.c
2 * 2 *
3 * Copyright (C) 2007,2008 Hans de Goede <hdegoede@redhat.com> 3 * Copyright (C) 2007 - 2009 Hans de Goede <hdegoede@redhat.com>
4 * 4 *
5 * This program is free software; you can redistribute it and/or modify 5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by 6 * it under the terms of the GNU General Public License as published by
@@ -19,7 +19,7 @@
19 19
20/* 20/*
21 * Merged Fujitsu Siemens hwmon driver, supporting the Poseidon, Hermes, 21 * Merged Fujitsu Siemens hwmon driver, supporting the Poseidon, Hermes,
22 * Scylla, Heracles and Heimdall chips 22 * Scylla, Heracles, Heimdall, Hades and Syleus chips
23 * 23 *
24 * Based on the original 2.4 fscscy, 2.6 fscpos, 2.6 fscher and 2.6 24 * Based on the original 2.4 fscscy, 2.6 fscpos, 2.6 fscher and 2.6
25 * (candidate) fschmd drivers: 25 * (candidate) fschmd drivers:
@@ -56,7 +56,7 @@ static int nowayout = WATCHDOG_NOWAYOUT;
56module_param(nowayout, int, 0); 56module_param(nowayout, int, 0);
57MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" 57MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default="
58 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); 58 __MODULE_STRING(WATCHDOG_NOWAYOUT) ")");
59I2C_CLIENT_INSMOD_5(fscpos, fscher, fscscy, fschrc, fschmd); 59I2C_CLIENT_INSMOD_7(fscpos, fscher, fscscy, fschrc, fschmd, fschds, fscsyl);
60 60
61/* 61/*
62 * The FSCHMD registers and other defines 62 * The FSCHMD registers and other defines
@@ -75,9 +75,12 @@ I2C_CLIENT_INSMOD_5(fscpos, fscher, fscscy, fschrc, fschmd);
75#define FSCHMD_CONTROL_ALERT_LED 0x01 75#define FSCHMD_CONTROL_ALERT_LED 0x01
76 76
77/* watchdog */ 77/* watchdog */
78#define FSCHMD_REG_WDOG_PRESET 0x28 78static const u8 FSCHMD_REG_WDOG_CONTROL[7] =
79#define FSCHMD_REG_WDOG_STATE 0x23 79 { 0x21, 0x21, 0x21, 0x21, 0x21, 0x28, 0x28 };
80#define FSCHMD_REG_WDOG_CONTROL 0x21 80static const u8 FSCHMD_REG_WDOG_STATE[7] =
81 { 0x23, 0x23, 0x23, 0x23, 0x23, 0x29, 0x29 };
82static const u8 FSCHMD_REG_WDOG_PRESET[7] =
83 { 0x28, 0x28, 0x28, 0x28, 0x28, 0x2a, 0x2a };
81 84
82#define FSCHMD_WDOG_CONTROL_TRIGGER 0x10 85#define FSCHMD_WDOG_CONTROL_TRIGGER 0x10
83#define FSCHMD_WDOG_CONTROL_STARTED 0x10 /* the same as trigger */ 86#define FSCHMD_WDOG_CONTROL_STARTED 0x10 /* the same as trigger */
@@ -87,70 +90,95 @@ I2C_CLIENT_INSMOD_5(fscpos, fscher, fscscy, fschrc, fschmd);
87#define FSCHMD_WDOG_STATE_CARDRESET 0x02 90#define FSCHMD_WDOG_STATE_CARDRESET 0x02
88 91
89/* voltages, weird order is to keep the same order as the old drivers */ 92/* voltages, weird order is to keep the same order as the old drivers */
90static const u8 FSCHMD_REG_VOLT[3] = { 0x45, 0x42, 0x48 }; 93static const u8 FSCHMD_REG_VOLT[7][6] = {
94 { 0x45, 0x42, 0x48 }, /* pos */
95 { 0x45, 0x42, 0x48 }, /* her */
96 { 0x45, 0x42, 0x48 }, /* scy */
97 { 0x45, 0x42, 0x48 }, /* hrc */
98 { 0x45, 0x42, 0x48 }, /* hmd */
99 { 0x21, 0x20, 0x22 }, /* hds */
100 { 0x21, 0x20, 0x22, 0x23, 0x24, 0x25 }, /* syl */
101};
102
103static const int FSCHMD_NO_VOLT_SENSORS[7] = { 3, 3, 3, 3, 3, 3, 6 };
91 104
92/* minimum pwm at which the fan is driven (pwm can by increased depending on 105/* minimum pwm at which the fan is driven (pwm can by increased depending on
93 the temp. Notice that for the scy some fans share there minimum speed. 106 the temp. Notice that for the scy some fans share there minimum speed.
94 Also notice that with the scy the sensor order is different than with the 107 Also notice that with the scy the sensor order is different than with the
95 other chips, this order was in the 2.4 driver and kept for consistency. */ 108 other chips, this order was in the 2.4 driver and kept for consistency. */
96static const u8 FSCHMD_REG_FAN_MIN[5][6] = { 109static const u8 FSCHMD_REG_FAN_MIN[7][7] = {
97 { 0x55, 0x65 }, /* pos */ 110 { 0x55, 0x65 }, /* pos */
98 { 0x55, 0x65, 0xb5 }, /* her */ 111 { 0x55, 0x65, 0xb5 }, /* her */
99 { 0x65, 0x65, 0x55, 0xa5, 0x55, 0xa5 }, /* scy */ 112 { 0x65, 0x65, 0x55, 0xa5, 0x55, 0xa5 }, /* scy */
100 { 0x55, 0x65, 0xa5, 0xb5 }, /* hrc */ 113 { 0x55, 0x65, 0xa5, 0xb5 }, /* hrc */
101 { 0x55, 0x65, 0xa5, 0xb5, 0xc5 }, /* hmd */ 114 { 0x55, 0x65, 0xa5, 0xb5, 0xc5 }, /* hmd */
115 { 0x55, 0x65, 0xa5, 0xb5, 0xc5 }, /* hds */
116 { 0x54, 0x64, 0x74, 0x84, 0x94, 0xa4, 0xb4 }, /* syl */
102}; 117};
103 118
104/* actual fan speed */ 119/* actual fan speed */
105static const u8 FSCHMD_REG_FAN_ACT[5][6] = { 120static const u8 FSCHMD_REG_FAN_ACT[7][7] = {
106 { 0x0e, 0x6b, 0xab }, /* pos */ 121 { 0x0e, 0x6b, 0xab }, /* pos */
107 { 0x0e, 0x6b, 0xbb }, /* her */ 122 { 0x0e, 0x6b, 0xbb }, /* her */
108 { 0x6b, 0x6c, 0x0e, 0xab, 0x5c, 0xbb }, /* scy */ 123 { 0x6b, 0x6c, 0x0e, 0xab, 0x5c, 0xbb }, /* scy */
109 { 0x0e, 0x6b, 0xab, 0xbb }, /* hrc */ 124 { 0x0e, 0x6b, 0xab, 0xbb }, /* hrc */
110 { 0x5b, 0x6b, 0xab, 0xbb, 0xcb }, /* hmd */ 125 { 0x5b, 0x6b, 0xab, 0xbb, 0xcb }, /* hmd */
126 { 0x5b, 0x6b, 0xab, 0xbb, 0xcb }, /* hds */
127 { 0x57, 0x67, 0x77, 0x87, 0x97, 0xa7, 0xb7 }, /* syl */
111}; 128};
112 129
113/* fan status registers */ 130/* fan status registers */
114static const u8 FSCHMD_REG_FAN_STATE[5][6] = { 131static const u8 FSCHMD_REG_FAN_STATE[7][7] = {
115 { 0x0d, 0x62, 0xa2 }, /* pos */ 132 { 0x0d, 0x62, 0xa2 }, /* pos */
116 { 0x0d, 0x62, 0xb2 }, /* her */ 133 { 0x0d, 0x62, 0xb2 }, /* her */
117 { 0x62, 0x61, 0x0d, 0xa2, 0x52, 0xb2 }, /* scy */ 134 { 0x62, 0x61, 0x0d, 0xa2, 0x52, 0xb2 }, /* scy */
118 { 0x0d, 0x62, 0xa2, 0xb2 }, /* hrc */ 135 { 0x0d, 0x62, 0xa2, 0xb2 }, /* hrc */
119 { 0x52, 0x62, 0xa2, 0xb2, 0xc2 }, /* hmd */ 136 { 0x52, 0x62, 0xa2, 0xb2, 0xc2 }, /* hmd */
137 { 0x52, 0x62, 0xa2, 0xb2, 0xc2 }, /* hds */
138 { 0x50, 0x60, 0x70, 0x80, 0x90, 0xa0, 0xb0 }, /* syl */
120}; 139};
121 140
122/* fan ripple / divider registers */ 141/* fan ripple / divider registers */
123static const u8 FSCHMD_REG_FAN_RIPPLE[5][6] = { 142static const u8 FSCHMD_REG_FAN_RIPPLE[7][7] = {
124 { 0x0f, 0x6f, 0xaf }, /* pos */ 143 { 0x0f, 0x6f, 0xaf }, /* pos */
125 { 0x0f, 0x6f, 0xbf }, /* her */ 144 { 0x0f, 0x6f, 0xbf }, /* her */
126 { 0x6f, 0x6f, 0x0f, 0xaf, 0x0f, 0xbf }, /* scy */ 145 { 0x6f, 0x6f, 0x0f, 0xaf, 0x0f, 0xbf }, /* scy */
127 { 0x0f, 0x6f, 0xaf, 0xbf }, /* hrc */ 146 { 0x0f, 0x6f, 0xaf, 0xbf }, /* hrc */
128 { 0x5f, 0x6f, 0xaf, 0xbf, 0xcf }, /* hmd */ 147 { 0x5f, 0x6f, 0xaf, 0xbf, 0xcf }, /* hmd */
148 { 0x5f, 0x6f, 0xaf, 0xbf, 0xcf }, /* hds */
149 { 0x56, 0x66, 0x76, 0x86, 0x96, 0xa6, 0xb6 }, /* syl */
129}; 150};
130 151
131static const int FSCHMD_NO_FAN_SENSORS[5] = { 3, 3, 6, 4, 5 }; 152static const int FSCHMD_NO_FAN_SENSORS[7] = { 3, 3, 6, 4, 5, 5, 7 };
132 153
133/* Fan status register bitmasks */ 154/* Fan status register bitmasks */
134#define FSCHMD_FAN_ALARM 0x04 /* called fault by FSC! */ 155#define FSCHMD_FAN_ALARM 0x04 /* called fault by FSC! */
135#define FSCHMD_FAN_NOT_PRESENT 0x08 /* not documented */ 156#define FSCHMD_FAN_NOT_PRESENT 0x08
157#define FSCHMD_FAN_DISABLED 0x80
136 158
137 159
138/* actual temperature registers */ 160/* actual temperature registers */
139static const u8 FSCHMD_REG_TEMP_ACT[5][5] = { 161static const u8 FSCHMD_REG_TEMP_ACT[7][11] = {
140 { 0x64, 0x32, 0x35 }, /* pos */ 162 { 0x64, 0x32, 0x35 }, /* pos */
141 { 0x64, 0x32, 0x35 }, /* her */ 163 { 0x64, 0x32, 0x35 }, /* her */
142 { 0x64, 0xD0, 0x32, 0x35 }, /* scy */ 164 { 0x64, 0xD0, 0x32, 0x35 }, /* scy */
143 { 0x64, 0x32, 0x35 }, /* hrc */ 165 { 0x64, 0x32, 0x35 }, /* hrc */
144 { 0x70, 0x80, 0x90, 0xd0, 0xe0 }, /* hmd */ 166 { 0x70, 0x80, 0x90, 0xd0, 0xe0 }, /* hmd */
167 { 0x70, 0x80, 0x90, 0xd0, 0xe0 }, /* hds */
168 { 0x58, 0x68, 0x78, 0x88, 0x98, 0xa8, /* syl */
169 0xb8, 0xc8, 0xd8, 0xe8, 0xf8 },
145}; 170};
146 171
147/* temperature state registers */ 172/* temperature state registers */
148static const u8 FSCHMD_REG_TEMP_STATE[5][5] = { 173static const u8 FSCHMD_REG_TEMP_STATE[7][11] = {
149 { 0x71, 0x81, 0x91 }, /* pos */ 174 { 0x71, 0x81, 0x91 }, /* pos */
150 { 0x71, 0x81, 0x91 }, /* her */ 175 { 0x71, 0x81, 0x91 }, /* her */
151 { 0x71, 0xd1, 0x81, 0x91 }, /* scy */ 176 { 0x71, 0xd1, 0x81, 0x91 }, /* scy */
152 { 0x71, 0x81, 0x91 }, /* hrc */ 177 { 0x71, 0x81, 0x91 }, /* hrc */
153 { 0x71, 0x81, 0x91, 0xd1, 0xe1 }, /* hmd */ 178 { 0x71, 0x81, 0x91, 0xd1, 0xe1 }, /* hmd */
179 { 0x71, 0x81, 0x91, 0xd1, 0xe1 }, /* hds */
180 { 0x59, 0x69, 0x79, 0x89, 0x99, 0xa9, /* syl */
181 0xb9, 0xc9, 0xd9, 0xe9, 0xf9 },
154}; 182};
155 183
156/* temperature high limit registers, FSC does not document these. Proven to be 184/* temperature high limit registers, FSC does not document these. Proven to be
@@ -158,24 +186,31 @@ static const u8 FSCHMD_REG_TEMP_STATE[5][5] = {
158 in the fscscy 2.4 driver. FSC has confirmed that the fschmd has registers 186 in the fscscy 2.4 driver. FSC has confirmed that the fschmd has registers
159 at these addresses, but doesn't want to confirm they are the same as with 187 at these addresses, but doesn't want to confirm they are the same as with
160 the fscher?? */ 188 the fscher?? */
161static const u8 FSCHMD_REG_TEMP_LIMIT[5][5] = { 189static const u8 FSCHMD_REG_TEMP_LIMIT[7][11] = {
162 { 0, 0, 0 }, /* pos */ 190 { 0, 0, 0 }, /* pos */
163 { 0x76, 0x86, 0x96 }, /* her */ 191 { 0x76, 0x86, 0x96 }, /* her */
164 { 0x76, 0xd6, 0x86, 0x96 }, /* scy */ 192 { 0x76, 0xd6, 0x86, 0x96 }, /* scy */
165 { 0x76, 0x86, 0x96 }, /* hrc */ 193 { 0x76, 0x86, 0x96 }, /* hrc */
166 { 0x76, 0x86, 0x96, 0xd6, 0xe6 }, /* hmd */ 194 { 0x76, 0x86, 0x96, 0xd6, 0xe6 }, /* hmd */
195 { 0x76, 0x86, 0x96, 0xd6, 0xe6 }, /* hds */
196 { 0x5a, 0x6a, 0x7a, 0x8a, 0x9a, 0xaa, /* syl */
197 0xba, 0xca, 0xda, 0xea, 0xfa },
167}; 198};
168 199
169/* These were found through experimenting with an fscher, currently they are 200/* These were found through experimenting with an fscher, currently they are
170 not used, but we keep them around for future reference. 201 not used, but we keep them around for future reference.
202 On the fscsyl AUTOP1 lives at 0x#c (so 0x5c for fan1, 0x6c for fan2, etc),
203 AUTOP2 lives at 0x#e, and 0x#1 is a bitmask defining which temps influence
204 the fan speed.
171static const u8 FSCHER_REG_TEMP_AUTOP1[] = { 0x73, 0x83, 0x93 }; 205static const u8 FSCHER_REG_TEMP_AUTOP1[] = { 0x73, 0x83, 0x93 };
172static const u8 FSCHER_REG_TEMP_AUTOP2[] = { 0x75, 0x85, 0x95 }; */ 206static const u8 FSCHER_REG_TEMP_AUTOP2[] = { 0x75, 0x85, 0x95 }; */
173 207
174static const int FSCHMD_NO_TEMP_SENSORS[5] = { 3, 3, 4, 3, 5 }; 208static const int FSCHMD_NO_TEMP_SENSORS[7] = { 3, 3, 4, 3, 5, 5, 11 };
175 209
176/* temp status register bitmasks */ 210/* temp status register bitmasks */
177#define FSCHMD_TEMP_WORKING 0x01 211#define FSCHMD_TEMP_WORKING 0x01
178#define FSCHMD_TEMP_ALERT 0x02 212#define FSCHMD_TEMP_ALERT 0x02
213#define FSCHMD_TEMP_DISABLED 0x80
179/* there only really is an alarm if the sensor is working and alert == 1 */ 214/* there only really is an alarm if the sensor is working and alert == 1 */
180#define FSCHMD_TEMP_ALARM_MASK \ 215#define FSCHMD_TEMP_ALARM_MASK \
181 (FSCHMD_TEMP_WORKING | FSCHMD_TEMP_ALERT) 216 (FSCHMD_TEMP_WORKING | FSCHMD_TEMP_ALERT)
@@ -201,6 +236,8 @@ static const struct i2c_device_id fschmd_id[] = {
201 { "fscscy", fscscy }, 236 { "fscscy", fscscy },
202 { "fschrc", fschrc }, 237 { "fschrc", fschrc },
203 { "fschmd", fschmd }, 238 { "fschmd", fschmd },
239 { "fschds", fschds },
240 { "fscsyl", fscsyl },
204 { } 241 { }
205}; 242};
206MODULE_DEVICE_TABLE(i2c, fschmd_id); 243MODULE_DEVICE_TABLE(i2c, fschmd_id);
@@ -242,14 +279,14 @@ struct fschmd_data {
242 u8 watchdog_control; /* watchdog control register */ 279 u8 watchdog_control; /* watchdog control register */
243 u8 watchdog_state; /* watchdog status register */ 280 u8 watchdog_state; /* watchdog status register */
244 u8 watchdog_preset; /* watchdog counter preset on trigger val */ 281 u8 watchdog_preset; /* watchdog counter preset on trigger val */
245 u8 volt[3]; /* 12, 5, battery voltage */ 282 u8 volt[6]; /* voltage */
246 u8 temp_act[5]; /* temperature */ 283 u8 temp_act[11]; /* temperature */
247 u8 temp_status[5]; /* status of sensor */ 284 u8 temp_status[11]; /* status of sensor */
248 u8 temp_max[5]; /* high temp limit, notice: undocumented! */ 285 u8 temp_max[11]; /* high temp limit, notice: undocumented! */
249 u8 fan_act[6]; /* fans revolutions per second */ 286 u8 fan_act[7]; /* fans revolutions per second */
250 u8 fan_status[6]; /* fan status */ 287 u8 fan_status[7]; /* fan status */
251 u8 fan_min[6]; /* fan min value for rps */ 288 u8 fan_min[7]; /* fan min value for rps */
252 u8 fan_ripple[6]; /* divider for rps */ 289 u8 fan_ripple[7]; /* divider for rps */
253}; 290};
254 291
255/* Global variables to hold information read from special DMI tables, which are 292/* Global variables to hold information read from special DMI tables, which are
@@ -257,8 +294,8 @@ struct fschmd_data {
257 protect these with a lock as they are only modified from our attach function 294 protect these with a lock as they are only modified from our attach function
258 which always gets called with the i2c-core lock held and never accessed 295 which always gets called with the i2c-core lock held and never accessed
259 before the attach function is done with them. */ 296 before the attach function is done with them. */
260static int dmi_mult[3] = { 490, 200, 100 }; 297static int dmi_mult[6] = { 490, 200, 100, 100, 200, 100 };
261static int dmi_offset[3] = { 0, 0, 0 }; 298static int dmi_offset[6] = { 0, 0, 0, 0, 0, 0 };
262static int dmi_vref = -1; 299static int dmi_vref = -1;
263 300
264/* Somewhat ugly :( global data pointer list with all fschmd devices, so that 301/* Somewhat ugly :( global data pointer list with all fschmd devices, so that
@@ -450,10 +487,11 @@ static ssize_t show_pwm_auto_point1_pwm(struct device *dev,
450 struct device_attribute *devattr, char *buf) 487 struct device_attribute *devattr, char *buf)
451{ 488{
452 int index = to_sensor_dev_attr(devattr)->index; 489 int index = to_sensor_dev_attr(devattr)->index;
453 int val = fschmd_update_device(dev)->fan_min[index]; 490 struct fschmd_data *data = fschmd_update_device(dev);
491 int val = data->fan_min[index];
454 492
455 /* 0 = allow turning off, 1-255 = 50-100% */ 493 /* 0 = allow turning off (except on the syl), 1-255 = 50-100% */
456 if (val) 494 if (val || data->kind == fscsyl - 1)
457 val = val / 2 + 128; 495 val = val / 2 + 128;
458 496
459 return sprintf(buf, "%d\n", val); 497 return sprintf(buf, "%d\n", val);
@@ -466,8 +504,8 @@ static ssize_t store_pwm_auto_point1_pwm(struct device *dev,
466 struct fschmd_data *data = dev_get_drvdata(dev); 504 struct fschmd_data *data = dev_get_drvdata(dev);
467 unsigned long v = simple_strtoul(buf, NULL, 10); 505 unsigned long v = simple_strtoul(buf, NULL, 10);
468 506
469 /* register: 0 = allow turning off, 1-255 = 50-100% */ 507 /* reg: 0 = allow turning off (except on the syl), 1-255 = 50-100% */
470 if (v) { 508 if (v || data->kind == fscsyl - 1) {
471 v = SENSORS_LIMIT(v, 128, 255); 509 v = SENSORS_LIMIT(v, 128, 255);
472 v = (v - 128) * 2 + 1; 510 v = (v - 128) * 2 + 1;
473 } 511 }
@@ -522,11 +560,15 @@ static ssize_t store_alert_led(struct device *dev,
522 return count; 560 return count;
523} 561}
524 562
563static DEVICE_ATTR(alert_led, 0644, show_alert_led, store_alert_led);
564
525static struct sensor_device_attribute fschmd_attr[] = { 565static struct sensor_device_attribute fschmd_attr[] = {
526 SENSOR_ATTR(in0_input, 0444, show_in_value, NULL, 0), 566 SENSOR_ATTR(in0_input, 0444, show_in_value, NULL, 0),
527 SENSOR_ATTR(in1_input, 0444, show_in_value, NULL, 1), 567 SENSOR_ATTR(in1_input, 0444, show_in_value, NULL, 1),
528 SENSOR_ATTR(in2_input, 0444, show_in_value, NULL, 2), 568 SENSOR_ATTR(in2_input, 0444, show_in_value, NULL, 2),
529 SENSOR_ATTR(alert_led, 0644, show_alert_led, store_alert_led, 0), 569 SENSOR_ATTR(in3_input, 0444, show_in_value, NULL, 3),
570 SENSOR_ATTR(in4_input, 0444, show_in_value, NULL, 4),
571 SENSOR_ATTR(in5_input, 0444, show_in_value, NULL, 5),
530}; 572};
531 573
532static struct sensor_device_attribute fschmd_temp_attr[] = { 574static struct sensor_device_attribute fschmd_temp_attr[] = {
@@ -550,6 +592,30 @@ static struct sensor_device_attribute fschmd_temp_attr[] = {
550 SENSOR_ATTR(temp5_max, 0644, show_temp_max, store_temp_max, 4), 592 SENSOR_ATTR(temp5_max, 0644, show_temp_max, store_temp_max, 4),
551 SENSOR_ATTR(temp5_fault, 0444, show_temp_fault, NULL, 4), 593 SENSOR_ATTR(temp5_fault, 0444, show_temp_fault, NULL, 4),
552 SENSOR_ATTR(temp5_alarm, 0444, show_temp_alarm, NULL, 4), 594 SENSOR_ATTR(temp5_alarm, 0444, show_temp_alarm, NULL, 4),
595 SENSOR_ATTR(temp6_input, 0444, show_temp_value, NULL, 5),
596 SENSOR_ATTR(temp6_max, 0644, show_temp_max, store_temp_max, 5),
597 SENSOR_ATTR(temp6_fault, 0444, show_temp_fault, NULL, 5),
598 SENSOR_ATTR(temp6_alarm, 0444, show_temp_alarm, NULL, 5),
599 SENSOR_ATTR(temp7_input, 0444, show_temp_value, NULL, 6),
600 SENSOR_ATTR(temp7_max, 0644, show_temp_max, store_temp_max, 6),
601 SENSOR_ATTR(temp7_fault, 0444, show_temp_fault, NULL, 6),
602 SENSOR_ATTR(temp7_alarm, 0444, show_temp_alarm, NULL, 6),
603 SENSOR_ATTR(temp8_input, 0444, show_temp_value, NULL, 7),
604 SENSOR_ATTR(temp8_max, 0644, show_temp_max, store_temp_max, 7),
605 SENSOR_ATTR(temp8_fault, 0444, show_temp_fault, NULL, 7),
606 SENSOR_ATTR(temp8_alarm, 0444, show_temp_alarm, NULL, 7),
607 SENSOR_ATTR(temp9_input, 0444, show_temp_value, NULL, 8),
608 SENSOR_ATTR(temp9_max, 0644, show_temp_max, store_temp_max, 8),
609 SENSOR_ATTR(temp9_fault, 0444, show_temp_fault, NULL, 8),
610 SENSOR_ATTR(temp9_alarm, 0444, show_temp_alarm, NULL, 8),
611 SENSOR_ATTR(temp10_input, 0444, show_temp_value, NULL, 9),
612 SENSOR_ATTR(temp10_max, 0644, show_temp_max, store_temp_max, 9),
613 SENSOR_ATTR(temp10_fault, 0444, show_temp_fault, NULL, 9),
614 SENSOR_ATTR(temp10_alarm, 0444, show_temp_alarm, NULL, 9),
615 SENSOR_ATTR(temp11_input, 0444, show_temp_value, NULL, 10),
616 SENSOR_ATTR(temp11_max, 0644, show_temp_max, store_temp_max, 10),
617 SENSOR_ATTR(temp11_fault, 0444, show_temp_fault, NULL, 10),
618 SENSOR_ATTR(temp11_alarm, 0444, show_temp_alarm, NULL, 10),
553}; 619};
554 620
555static struct sensor_device_attribute fschmd_fan_attr[] = { 621static struct sensor_device_attribute fschmd_fan_attr[] = {
@@ -589,6 +655,12 @@ static struct sensor_device_attribute fschmd_fan_attr[] = {
589 SENSOR_ATTR(fan6_fault, 0444, show_fan_fault, NULL, 5), 655 SENSOR_ATTR(fan6_fault, 0444, show_fan_fault, NULL, 5),
590 SENSOR_ATTR(pwm6_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm, 656 SENSOR_ATTR(pwm6_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm,
591 store_pwm_auto_point1_pwm, 5), 657 store_pwm_auto_point1_pwm, 5),
658 SENSOR_ATTR(fan7_input, 0444, show_fan_value, NULL, 6),
659 SENSOR_ATTR(fan7_div, 0644, show_fan_div, store_fan_div, 6),
660 SENSOR_ATTR(fan7_alarm, 0444, show_fan_alarm, NULL, 6),
661 SENSOR_ATTR(fan7_fault, 0444, show_fan_fault, NULL, 6),
662 SENSOR_ATTR(pwm7_auto_point1_pwm, 0644, show_pwm_auto_point1_pwm,
663 store_pwm_auto_point1_pwm, 6),
592}; 664};
593 665
594 666
@@ -624,10 +696,11 @@ static int watchdog_set_timeout(struct fschmd_data *data, int timeout)
624 data->watchdog_preset = DIV_ROUND_UP(timeout, resolution); 696 data->watchdog_preset = DIV_ROUND_UP(timeout, resolution);
625 697
626 /* Write new timeout value */ 698 /* Write new timeout value */
627 i2c_smbus_write_byte_data(data->client, FSCHMD_REG_WDOG_PRESET, 699 i2c_smbus_write_byte_data(data->client,
628 data->watchdog_preset); 700 FSCHMD_REG_WDOG_PRESET[data->kind], data->watchdog_preset);
629 /* Write new control register, do not trigger! */ 701 /* Write new control register, do not trigger! */
630 i2c_smbus_write_byte_data(data->client, FSCHMD_REG_WDOG_CONTROL, 702 i2c_smbus_write_byte_data(data->client,
703 FSCHMD_REG_WDOG_CONTROL[data->kind],
631 data->watchdog_control & ~FSCHMD_WDOG_CONTROL_TRIGGER); 704 data->watchdog_control & ~FSCHMD_WDOG_CONTROL_TRIGGER);
632 705
633 ret = data->watchdog_preset * resolution; 706 ret = data->watchdog_preset * resolution;
@@ -662,8 +735,9 @@ static int watchdog_trigger(struct fschmd_data *data)
662 } 735 }
663 736
664 data->watchdog_control |= FSCHMD_WDOG_CONTROL_TRIGGER; 737 data->watchdog_control |= FSCHMD_WDOG_CONTROL_TRIGGER;
665 i2c_smbus_write_byte_data(data->client, FSCHMD_REG_WDOG_CONTROL, 738 i2c_smbus_write_byte_data(data->client,
666 data->watchdog_control); 739 FSCHMD_REG_WDOG_CONTROL[data->kind],
740 data->watchdog_control);
667leave: 741leave:
668 mutex_unlock(&data->watchdog_lock); 742 mutex_unlock(&data->watchdog_lock);
669 return ret; 743 return ret;
@@ -682,7 +756,8 @@ static int watchdog_stop(struct fschmd_data *data)
682 data->watchdog_control &= ~FSCHMD_WDOG_CONTROL_STARTED; 756 data->watchdog_control &= ~FSCHMD_WDOG_CONTROL_STARTED;
683 /* Don't store the stop flag in our watchdog control register copy, as 757 /* Don't store the stop flag in our watchdog control register copy, as
684 its a write only bit (read always returns 0) */ 758 its a write only bit (read always returns 0) */
685 i2c_smbus_write_byte_data(data->client, FSCHMD_REG_WDOG_CONTROL, 759 i2c_smbus_write_byte_data(data->client,
760 FSCHMD_REG_WDOG_CONTROL[data->kind],
686 data->watchdog_control | FSCHMD_WDOG_CONTROL_STOP); 761 data->watchdog_control | FSCHMD_WDOG_CONTROL_STOP);
687leave: 762leave:
688 mutex_unlock(&data->watchdog_lock); 763 mutex_unlock(&data->watchdog_lock);
@@ -856,7 +931,7 @@ static struct file_operations watchdog_fops = {
856 931
857/* DMI decode routine to read voltage scaling factors from special DMI tables, 932/* DMI decode routine to read voltage scaling factors from special DMI tables,
858 which are available on FSC machines with an fscher or later chip. */ 933 which are available on FSC machines with an fscher or later chip. */
859static void fschmd_dmi_decode(const struct dmi_header *header) 934static void fschmd_dmi_decode(const struct dmi_header *header, void *dummy)
860{ 935{
861 int i, mult[3] = { 0 }, offset[3] = { 0 }, vref = 0, found = 0; 936 int i, mult[3] = { 0 }, offset[3] = { 0 }, vref = 0, found = 0;
862 937
@@ -912,6 +987,15 @@ static void fschmd_dmi_decode(const struct dmi_header *header)
912 dmi_mult[i] = mult[i] * 10; 987 dmi_mult[i] = mult[i] * 10;
913 dmi_offset[i] = offset[i] * 10; 988 dmi_offset[i] = offset[i] * 10;
914 } 989 }
990 /* According to the docs there should be separate dmi entries
991 for the mult's and offsets of in3-5 of the syl, but on
992 my test machine these are not present */
993 dmi_mult[3] = dmi_mult[2];
994 dmi_mult[4] = dmi_mult[1];
995 dmi_mult[5] = dmi_mult[2];
996 dmi_offset[3] = dmi_offset[2];
997 dmi_offset[4] = dmi_offset[1];
998 dmi_offset[5] = dmi_offset[2];
915 dmi_vref = vref; 999 dmi_vref = vref;
916 } 1000 }
917} 1001}
@@ -920,8 +1004,6 @@ static int fschmd_detect(struct i2c_client *client, int kind,
920 struct i2c_board_info *info) 1004 struct i2c_board_info *info)
921{ 1005{
922 struct i2c_adapter *adapter = client->adapter; 1006 struct i2c_adapter *adapter = client->adapter;
923 const char * const client_names[5] = { "fscpos", "fscher", "fscscy",
924 "fschrc", "fschmd" };
925 1007
926 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) 1008 if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
927 return -ENODEV; 1009 return -ENODEV;
@@ -948,11 +1030,15 @@ static int fschmd_detect(struct i2c_client *client, int kind,
948 kind = fschrc; 1030 kind = fschrc;
949 else if (!strcmp(id, "HMD")) 1031 else if (!strcmp(id, "HMD"))
950 kind = fschmd; 1032 kind = fschmd;
1033 else if (!strcmp(id, "HDS"))
1034 kind = fschds;
1035 else if (!strcmp(id, "SYL"))
1036 kind = fscsyl;
951 else 1037 else
952 return -ENODEV; 1038 return -ENODEV;
953 } 1039 }
954 1040
955 strlcpy(info->type, client_names[kind - 1], I2C_NAME_SIZE); 1041 strlcpy(info->type, fschmd_id[kind - 1].name, I2C_NAME_SIZE);
956 1042
957 return 0; 1043 return 0;
958} 1044}
@@ -961,8 +1047,8 @@ static int fschmd_probe(struct i2c_client *client,
961 const struct i2c_device_id *id) 1047 const struct i2c_device_id *id)
962{ 1048{
963 struct fschmd_data *data; 1049 struct fschmd_data *data;
964 const char * const names[5] = { "Poseidon", "Hermes", "Scylla", 1050 const char * const names[7] = { "Poseidon", "Hermes", "Scylla",
965 "Heracles", "Heimdall" }; 1051 "Heracles", "Heimdall", "Hades", "Syleus" };
966 const int watchdog_minors[] = { WATCHDOG_MINOR, 212, 213, 214, 215 }; 1052 const int watchdog_minors[] = { WATCHDOG_MINOR, 212, 213, 214, 215 };
967 int i, err; 1053 int i, err;
968 enum chips kind = id->driver_data; 1054 enum chips kind = id->driver_data;
@@ -991,7 +1077,7 @@ static int fschmd_probe(struct i2c_client *client,
991 1077
992 /* Read the special DMI table for fscher and newer chips */ 1078 /* Read the special DMI table for fscher and newer chips */
993 if ((kind == fscher || kind >= fschrc) && dmi_vref == -1) { 1079 if ((kind == fscher || kind >= fschrc) && dmi_vref == -1) {
994 dmi_walk(fschmd_dmi_decode); 1080 dmi_walk(fschmd_dmi_decode, NULL);
995 if (dmi_vref == -1) { 1081 if (dmi_vref == -1) {
996 dev_warn(&client->dev, 1082 dev_warn(&client->dev,
997 "Couldn't get voltage scaling factors from " 1083 "Couldn't get voltage scaling factors from "
@@ -1000,21 +1086,25 @@ static int fschmd_probe(struct i2c_client *client,
1000 } 1086 }
1001 } 1087 }
1002 1088
1089 /* i2c kind goes from 1-6, we want from 0-5 to address arrays */
1090 data->kind = kind - 1;
1091
1003 /* Read in some never changing registers */ 1092 /* Read in some never changing registers */
1004 data->revision = i2c_smbus_read_byte_data(client, FSCHMD_REG_REVISION); 1093 data->revision = i2c_smbus_read_byte_data(client, FSCHMD_REG_REVISION);
1005 data->global_control = i2c_smbus_read_byte_data(client, 1094 data->global_control = i2c_smbus_read_byte_data(client,
1006 FSCHMD_REG_CONTROL); 1095 FSCHMD_REG_CONTROL);
1007 data->watchdog_control = i2c_smbus_read_byte_data(client, 1096 data->watchdog_control = i2c_smbus_read_byte_data(client,
1008 FSCHMD_REG_WDOG_CONTROL); 1097 FSCHMD_REG_WDOG_CONTROL[data->kind]);
1009 data->watchdog_state = i2c_smbus_read_byte_data(client, 1098 data->watchdog_state = i2c_smbus_read_byte_data(client,
1010 FSCHMD_REG_WDOG_STATE); 1099 FSCHMD_REG_WDOG_STATE[data->kind]);
1011 data->watchdog_preset = i2c_smbus_read_byte_data(client, 1100 data->watchdog_preset = i2c_smbus_read_byte_data(client,
1012 FSCHMD_REG_WDOG_PRESET); 1101 FSCHMD_REG_WDOG_PRESET[data->kind]);
1013 1102
1014 /* i2c kind goes from 1-5, we want from 0-4 to address arrays */ 1103 err = device_create_file(&client->dev, &dev_attr_alert_led);
1015 data->kind = kind - 1; 1104 if (err)
1105 goto exit_detach;
1016 1106
1017 for (i = 0; i < ARRAY_SIZE(fschmd_attr); i++) { 1107 for (i = 0; i < FSCHMD_NO_VOLT_SENSORS[data->kind]; i++) {
1018 err = device_create_file(&client->dev, 1108 err = device_create_file(&client->dev,
1019 &fschmd_attr[i].dev_attr); 1109 &fschmd_attr[i].dev_attr);
1020 if (err) 1110 if (err)
@@ -1027,6 +1117,16 @@ static int fschmd_probe(struct i2c_client *client,
1027 show_temp_max) 1117 show_temp_max)
1028 continue; 1118 continue;
1029 1119
1120 if (kind == fscsyl) {
1121 if (i % 4 == 0)
1122 data->temp_status[i / 4] =
1123 i2c_smbus_read_byte_data(client,
1124 FSCHMD_REG_TEMP_STATE
1125 [data->kind][i / 4]);
1126 if (data->temp_status[i / 4] & FSCHMD_TEMP_DISABLED)
1127 continue;
1128 }
1129
1030 err = device_create_file(&client->dev, 1130 err = device_create_file(&client->dev,
1031 &fschmd_temp_attr[i].dev_attr); 1131 &fschmd_temp_attr[i].dev_attr);
1032 if (err) 1132 if (err)
@@ -1040,6 +1140,16 @@ static int fschmd_probe(struct i2c_client *client,
1040 "pwm3_auto_point1_pwm")) 1140 "pwm3_auto_point1_pwm"))
1041 continue; 1141 continue;
1042 1142
1143 if (kind == fscsyl) {
1144 if (i % 5 == 0)
1145 data->fan_status[i / 5] =
1146 i2c_smbus_read_byte_data(client,
1147 FSCHMD_REG_FAN_STATE
1148 [data->kind][i / 5]);
1149 if (data->fan_status[i / 5] & FSCHMD_FAN_DISABLED)
1150 continue;
1151 }
1152
1043 err = device_create_file(&client->dev, 1153 err = device_create_file(&client->dev,
1044 &fschmd_fan_attr[i].dev_attr); 1154 &fschmd_fan_attr[i].dev_attr);
1045 if (err) 1155 if (err)
@@ -1126,7 +1236,8 @@ static int fschmd_remove(struct i2c_client *client)
1126 if (data->hwmon_dev) 1236 if (data->hwmon_dev)
1127 hwmon_device_unregister(data->hwmon_dev); 1237 hwmon_device_unregister(data->hwmon_dev);
1128 1238
1129 for (i = 0; i < ARRAY_SIZE(fschmd_attr); i++) 1239 device_remove_file(&client->dev, &dev_attr_alert_led);
1240 for (i = 0; i < (FSCHMD_NO_VOLT_SENSORS[data->kind]); i++)
1130 device_remove_file(&client->dev, &fschmd_attr[i].dev_attr); 1241 device_remove_file(&client->dev, &fschmd_attr[i].dev_attr);
1131 for (i = 0; i < (FSCHMD_NO_TEMP_SENSORS[data->kind] * 4); i++) 1242 for (i = 0; i < (FSCHMD_NO_TEMP_SENSORS[data->kind] * 4); i++)
1132 device_remove_file(&client->dev, 1243 device_remove_file(&client->dev,
@@ -1171,7 +1282,7 @@ static struct fschmd_data *fschmd_update_device(struct device *dev)
1171 data->temp_act[i] < data->temp_max[i]) 1282 data->temp_act[i] < data->temp_max[i])
1172 i2c_smbus_write_byte_data(client, 1283 i2c_smbus_write_byte_data(client,
1173 FSCHMD_REG_TEMP_STATE[data->kind][i], 1284 FSCHMD_REG_TEMP_STATE[data->kind][i],
1174 FSCHMD_TEMP_ALERT); 1285 data->temp_status[i]);
1175 } 1286 }
1176 1287
1177 for (i = 0; i < FSCHMD_NO_FAN_SENSORS[data->kind]; i++) { 1288 for (i = 0; i < FSCHMD_NO_FAN_SENSORS[data->kind]; i++) {
@@ -1193,12 +1304,12 @@ static struct fschmd_data *fschmd_update_device(struct device *dev)
1193 data->fan_act[i]) 1304 data->fan_act[i])
1194 i2c_smbus_write_byte_data(client, 1305 i2c_smbus_write_byte_data(client,
1195 FSCHMD_REG_FAN_STATE[data->kind][i], 1306 FSCHMD_REG_FAN_STATE[data->kind][i],
1196 FSCHMD_FAN_ALARM); 1307 data->fan_status[i]);
1197 } 1308 }
1198 1309
1199 for (i = 0; i < 3; i++) 1310 for (i = 0; i < FSCHMD_NO_VOLT_SENSORS[data->kind]; i++)
1200 data->volt[i] = i2c_smbus_read_byte_data(client, 1311 data->volt[i] = i2c_smbus_read_byte_data(client,
1201 FSCHMD_REG_VOLT[i]); 1312 FSCHMD_REG_VOLT[data->kind][i]);
1202 1313
1203 data->last_updated = jiffies; 1314 data->last_updated = jiffies;
1204 data->valid = 1; 1315 data->valid = 1;
@@ -1220,8 +1331,8 @@ static void __exit fschmd_exit(void)
1220} 1331}
1221 1332
1222MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>"); 1333MODULE_AUTHOR("Hans de Goede <hdegoede@redhat.com>");
1223MODULE_DESCRIPTION("FSC Poseidon, Hermes, Scylla, Heracles and " 1334MODULE_DESCRIPTION("FSC Poseidon, Hermes, Scylla, Heracles, Heimdall, Hades "
1224 "Heimdall driver"); 1335 "and Syleus driver");
1225MODULE_LICENSE("GPL"); 1336MODULE_LICENSE("GPL");
1226 1337
1227module_init(fschmd_init); 1338module_init(fschmd_init);
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c
index a4d92d246d52..d3612a1f1981 100644
--- a/drivers/hwmon/hdaps.c
+++ b/drivers/hwmon/hdaps.c
@@ -65,6 +65,10 @@
65#define HDAPS_INPUT_FUZZ 4 /* input event threshold */ 65#define HDAPS_INPUT_FUZZ 4 /* input event threshold */
66#define HDAPS_INPUT_FLAT 4 66#define HDAPS_INPUT_FLAT 4
67 67
68#define HDAPS_X_AXIS (1 << 0)
69#define HDAPS_Y_AXIS (1 << 1)
70#define HDAPS_BOTH_AXES (HDAPS_X_AXIS | HDAPS_Y_AXIS)
71
68static struct platform_device *pdev; 72static struct platform_device *pdev;
69static struct input_polled_dev *hdaps_idev; 73static struct input_polled_dev *hdaps_idev;
70static unsigned int hdaps_invert; 74static unsigned int hdaps_invert;
@@ -182,11 +186,11 @@ static int __hdaps_read_pair(unsigned int port1, unsigned int port2,
182 km_activity = inb(HDAPS_PORT_KMACT); 186 km_activity = inb(HDAPS_PORT_KMACT);
183 __device_complete(); 187 __device_complete();
184 188
185 /* if hdaps_invert is set, negate the two values */ 189 /* hdaps_invert is a bitvector to negate the axes */
186 if (hdaps_invert) { 190 if (hdaps_invert & HDAPS_X_AXIS)
187 *x = -*x; 191 *x = -*x;
192 if (hdaps_invert & HDAPS_Y_AXIS)
188 *y = -*y; 193 *y = -*y;
189 }
190 194
191 return 0; 195 return 0;
192} 196}
@@ -436,7 +440,8 @@ static ssize_t hdaps_invert_store(struct device *dev,
436{ 440{
437 int invert; 441 int invert;
438 442
439 if (sscanf(buf, "%d", &invert) != 1 || (invert != 1 && invert != 0)) 443 if (sscanf(buf, "%d", &invert) != 1 ||
444 invert < 0 || invert > HDAPS_BOTH_AXES)
440 return -EINVAL; 445 return -EINVAL;
441 446
442 hdaps_invert = invert; 447 hdaps_invert = invert;
@@ -483,56 +488,52 @@ static int __init hdaps_dmi_match(const struct dmi_system_id *id)
483/* hdaps_dmi_match_invert - found an inverted match. */ 488/* hdaps_dmi_match_invert - found an inverted match. */
484static int __init hdaps_dmi_match_invert(const struct dmi_system_id *id) 489static int __init hdaps_dmi_match_invert(const struct dmi_system_id *id)
485{ 490{
486 hdaps_invert = 1; 491 hdaps_invert = (unsigned long)id->driver_data;
487 printk(KERN_INFO "hdaps: inverting axis readings.\n"); 492 printk(KERN_INFO "hdaps: inverting axis (%u) readings.\n",
493 hdaps_invert);
488 return hdaps_dmi_match(id); 494 return hdaps_dmi_match(id);
489} 495}
490 496
491#define HDAPS_DMI_MATCH_NORMAL(vendor, model) { \ 497#define HDAPS_DMI_MATCH_INVERT(vendor, model, axes) { \
492 .ident = vendor " " model, \
493 .callback = hdaps_dmi_match, \
494 .matches = { \
495 DMI_MATCH(DMI_BOARD_VENDOR, vendor), \
496 DMI_MATCH(DMI_PRODUCT_VERSION, model) \
497 } \
498}
499
500#define HDAPS_DMI_MATCH_INVERT(vendor, model) { \
501 .ident = vendor " " model, \ 498 .ident = vendor " " model, \
502 .callback = hdaps_dmi_match_invert, \ 499 .callback = hdaps_dmi_match_invert, \
500 .driver_data = (void *)axes, \
503 .matches = { \ 501 .matches = { \
504 DMI_MATCH(DMI_BOARD_VENDOR, vendor), \ 502 DMI_MATCH(DMI_BOARD_VENDOR, vendor), \
505 DMI_MATCH(DMI_PRODUCT_VERSION, model) \ 503 DMI_MATCH(DMI_PRODUCT_VERSION, model) \
506 } \ 504 } \
507} 505}
508 506
507#define HDAPS_DMI_MATCH_NORMAL(vendor, model) \
508 HDAPS_DMI_MATCH_INVERT(vendor, model, 0)
509
509/* Note that HDAPS_DMI_MATCH_NORMAL("ThinkPad T42") would match 510/* Note that HDAPS_DMI_MATCH_NORMAL("ThinkPad T42") would match
510 "ThinkPad T42p", so the order of the entries matters. 511 "ThinkPad T42p", so the order of the entries matters.
511 If your ThinkPad is not recognized, please update to latest 512 If your ThinkPad is not recognized, please update to latest
512 BIOS. This is especially the case for some R52 ThinkPads. */ 513 BIOS. This is especially the case for some R52 ThinkPads. */
513static struct dmi_system_id __initdata hdaps_whitelist[] = { 514static struct dmi_system_id __initdata hdaps_whitelist[] = {
514 HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad R50p"), 515 HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad R50p", HDAPS_BOTH_AXES),
515 HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R50"), 516 HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R50"),
516 HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R51"), 517 HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R51"),
517 HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R52"), 518 HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad R52"),
518 HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R61i"), 519 HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R61i", HDAPS_BOTH_AXES),
519 HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R61"), 520 HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad R61", HDAPS_BOTH_AXES),
520 HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T41p"), 521 HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T41p", HDAPS_BOTH_AXES),
521 HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T41"), 522 HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T41"),
522 HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T42p"), 523 HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad T42p", HDAPS_BOTH_AXES),
523 HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T42"), 524 HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T42"),
524 HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T43"), 525 HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad T43"),
525 HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T60"), 526 HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T60", HDAPS_BOTH_AXES),
526 HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61p"), 527 HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61p", HDAPS_BOTH_AXES),
527 HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61"), 528 HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad T61", HDAPS_BOTH_AXES),
528 HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X40"), 529 HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X40"),
529 HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad X41"), 530 HDAPS_DMI_MATCH_INVERT("IBM", "ThinkPad X41", HDAPS_Y_AXIS),
530 HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X60"), 531 HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X60", HDAPS_BOTH_AXES),
531 HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X61s"), 532 HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X61s", HDAPS_BOTH_AXES),
532 HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X61"), 533 HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad X61", HDAPS_BOTH_AXES),
533 HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad Z60m"), 534 HDAPS_DMI_MATCH_NORMAL("IBM", "ThinkPad Z60m"),
534 HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61m"), 535 HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61m", HDAPS_BOTH_AXES),
535 HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61p"), 536 HDAPS_DMI_MATCH_INVERT("LENOVO", "ThinkPad Z61p", HDAPS_BOTH_AXES),
536 { .ident = NULL } 537 { .ident = NULL }
537}; 538};
538 539
@@ -627,8 +628,9 @@ static void __exit hdaps_exit(void)
627module_init(hdaps_init); 628module_init(hdaps_init);
628module_exit(hdaps_exit); 629module_exit(hdaps_exit);
629 630
630module_param_named(invert, hdaps_invert, bool, 0); 631module_param_named(invert, hdaps_invert, int, 0);
631MODULE_PARM_DESC(invert, "invert data along each axis"); 632MODULE_PARM_DESC(invert, "invert data along each axis. 1 invert x-axis, "
633 "2 invert y-axis, 3 invert both axes.");
632 634
633MODULE_AUTHOR("Robert Love"); 635MODULE_AUTHOR("Robert Love");
634MODULE_DESCRIPTION("IBM Hard Drive Active Protection System (HDAPS) driver"); 636MODULE_DESCRIPTION("IBM Hard Drive Active Protection System (HDAPS) driver");
diff --git a/drivers/i2c/chips/pcf8591.c b/drivers/hwmon/pcf8591.c
index 16ce3e193776..1d7ffebd679d 100644
--- a/drivers/i2c/chips/pcf8591.c
+++ b/drivers/hwmon/pcf8591.c
@@ -1,6 +1,6 @@
1/* 1/*
2 Copyright (C) 2001-2004 Aurelien Jarno <aurelien@aurel32.net> 2 Copyright (C) 2001-2004 Aurelien Jarno <aurelien@aurel32.net>
3 Ported to Linux 2.6 by Aurelien Jarno <aurelien@aurel32.net> with 3 Ported to Linux 2.6 by Aurelien Jarno <aurelien@aurel32.net> with
4 the help of Jean Delvare <khali@linux-fr.org> 4 the help of Jean Delvare <khali@linux-fr.org>
5 5
6 This program is free software; you can redistribute it and/or modify 6 This program is free software; you can redistribute it and/or modify
@@ -41,13 +41,13 @@ MODULE_PARM_DESC(input_mode,
41 " 3 = two differential inputs\n"); 41 " 3 = two differential inputs\n");
42 42
43/* The PCF8591 control byte 43/* The PCF8591 control byte
44 7 6 5 4 3 2 1 0 44 7 6 5 4 3 2 1 0
45 | 0 |AOEF| AIP | 0 |AINC| AICH | */ 45 | 0 |AOEF| AIP | 0 |AINC| AICH | */
46 46
47/* Analog Output Enable Flag (analog output active if 1) */ 47/* Analog Output Enable Flag (analog output active if 1) */
48#define PCF8591_CONTROL_AOEF 0x40 48#define PCF8591_CONTROL_AOEF 0x40
49 49
50/* Analog Input Programming 50/* Analog Input Programming
51 0x00 = four single ended inputs 51 0x00 = four single ended inputs
52 0x10 = three differential inputs 52 0x10 = three differential inputs
53 0x20 = single ended and differential mixed 53 0x20 = single ended and differential mixed
@@ -58,7 +58,7 @@ MODULE_PARM_DESC(input_mode,
58#define PCF8591_CONTROL_AINC 0x04 58#define PCF8591_CONTROL_AINC 0x04
59 59
60/* Channel selection 60/* Channel selection
61 0x00 = channel 0 61 0x00 = channel 0
62 0x01 = channel 1 62 0x01 = channel 1
63 0x02 = channel 2 63 0x02 = channel 2
64 0x03 = channel 3 */ 64 0x03 = channel 3 */
@@ -114,7 +114,7 @@ static ssize_t set_out0_output(struct device *dev, struct device_attribute *attr
114 return -EINVAL; 114 return -EINVAL;
115} 115}
116 116
117static DEVICE_ATTR(out0_output, S_IWUSR | S_IRUGO, 117static DEVICE_ATTR(out0_output, S_IWUSR | S_IRUGO,
118 show_out0_ouput, set_out0_output); 118 show_out0_ouput, set_out0_output);
119 119
120static ssize_t show_out0_enable(struct device *dev, struct device_attribute *attr, char *buf) 120static ssize_t show_out0_enable(struct device *dev, struct device_attribute *attr, char *buf)
@@ -139,7 +139,7 @@ static ssize_t set_out0_enable(struct device *dev, struct device_attribute *attr
139 return count; 139 return count;
140} 140}
141 141
142static DEVICE_ATTR(out0_enable, S_IWUSR | S_IRUGO, 142static DEVICE_ATTR(out0_enable, S_IWUSR | S_IRUGO,
143 show_out0_enable, set_out0_enable); 143 show_out0_enable, set_out0_enable);
144 144
145static struct attribute *pcf8591_attributes[] = { 145static struct attribute *pcf8591_attributes[] = {
@@ -196,7 +196,7 @@ static int pcf8591_probe(struct i2c_client *client,
196 err = -ENOMEM; 196 err = -ENOMEM;
197 goto exit; 197 goto exit;
198 } 198 }
199 199
200 i2c_set_clientdata(client, data); 200 i2c_set_clientdata(client, data);
201 mutex_init(&data->update_lock); 201 mutex_init(&data->update_lock);
202 202
@@ -249,8 +249,8 @@ static void pcf8591_init_client(struct i2c_client *client)
249 data->aout = PCF8591_INIT_AOUT; 249 data->aout = PCF8591_INIT_AOUT;
250 250
251 i2c_smbus_write_byte_data(client, data->control, data->aout); 251 i2c_smbus_write_byte_data(client, data->control, data->aout);
252 252
253 /* The first byte transmitted contains the conversion code of the 253 /* The first byte transmitted contains the conversion code of the
254 previous read cycle. FLUSH IT! */ 254 previous read cycle. FLUSH IT! */
255 i2c_smbus_read_byte(client); 255 i2c_smbus_read_byte(client);
256} 256}
@@ -267,8 +267,8 @@ static int pcf8591_read_channel(struct device *dev, int channel)
267 data->control = (data->control & ~PCF8591_CONTROL_AICH_MASK) 267 data->control = (data->control & ~PCF8591_CONTROL_AICH_MASK)
268 | channel; 268 | channel;
269 i2c_smbus_write_byte(client, data->control); 269 i2c_smbus_write_byte(client, data->control);
270 270
271 /* The first byte transmitted contains the conversion code of 271 /* The first byte transmitted contains the conversion code of
272 the previous read cycle. FLUSH IT! */ 272 the previous read cycle. FLUSH IT! */
273 i2c_smbus_read_byte(client); 273 i2c_smbus_read_byte(client);
274 } 274 }
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
index feae743ba991..e64b42058b21 100644
--- a/drivers/hwmon/w83627ehf.c
+++ b/drivers/hwmon/w83627ehf.c
@@ -36,6 +36,7 @@
36 w83627ehf 10 5 4 3 0x8850 0x88 0x5ca3 36 w83627ehf 10 5 4 3 0x8850 0x88 0x5ca3
37 0x8860 0xa1 37 0x8860 0xa1
38 w83627dhg 9 5 4 3 0xa020 0xc1 0x5ca3 38 w83627dhg 9 5 4 3 0xa020 0xc1 0x5ca3
39 w83667hg 9 5 3 3 0xa510 0xc1 0x5ca3
39*/ 40*/
40 41
41#include <linux/module.h> 42#include <linux/module.h>
@@ -52,12 +53,13 @@
52#include <asm/io.h> 53#include <asm/io.h>
53#include "lm75.h" 54#include "lm75.h"
54 55
55enum kinds { w83627ehf, w83627dhg }; 56enum kinds { w83627ehf, w83627dhg, w83667hg };
56 57
57/* used to set data->name = w83627ehf_device_names[data->sio_kind] */ 58/* used to set data->name = w83627ehf_device_names[data->sio_kind] */
58static const char * w83627ehf_device_names[] = { 59static const char * w83627ehf_device_names[] = {
59 "w83627ehf", 60 "w83627ehf",
60 "w83627dhg", 61 "w83627dhg",
62 "w83667hg",
61}; 63};
62 64
63static unsigned short force_id; 65static unsigned short force_id;
@@ -71,6 +73,7 @@ MODULE_PARM_DESC(force_id, "Override the detected device ID");
71 */ 73 */
72 74
73#define W83627EHF_LD_HWM 0x0b 75#define W83627EHF_LD_HWM 0x0b
76#define W83667HG_LD_VID 0x0d
74 77
75#define SIO_REG_LDSEL 0x07 /* Logical device select */ 78#define SIO_REG_LDSEL 0x07 /* Logical device select */
76#define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */ 79#define SIO_REG_DEVID 0x20 /* Device ID (2 bytes) */
@@ -83,6 +86,7 @@ MODULE_PARM_DESC(force_id, "Override the detected device ID");
83#define SIO_W83627EHF_ID 0x8850 86#define SIO_W83627EHF_ID 0x8850
84#define SIO_W83627EHG_ID 0x8860 87#define SIO_W83627EHG_ID 0x8860
85#define SIO_W83627DHG_ID 0xa020 88#define SIO_W83627DHG_ID 0xa020
89#define SIO_W83667HG_ID 0xa510
86#define SIO_ID_MASK 0xFFF0 90#define SIO_ID_MASK 0xFFF0
87 91
88static inline void 92static inline void
@@ -289,6 +293,7 @@ struct w83627ehf_data {
289 u8 pwm_mode[4]; /* 0->DC variable voltage, 1->PWM variable duty cycle */ 293 u8 pwm_mode[4]; /* 0->DC variable voltage, 1->PWM variable duty cycle */
290 u8 pwm_enable[4]; /* 1->manual 294 u8 pwm_enable[4]; /* 1->manual
291 2->thermal cruise (also called SmartFan I) */ 295 2->thermal cruise (also called SmartFan I) */
296 u8 pwm_num; /* number of pwm */
292 u8 pwm[4]; 297 u8 pwm[4];
293 u8 target_temp[4]; 298 u8 target_temp[4];
294 u8 tolerance[4]; 299 u8 tolerance[4];
@@ -298,6 +303,9 @@ struct w83627ehf_data {
298 303
299 u8 vid; 304 u8 vid;
300 u8 vrm; 305 u8 vrm;
306
307 u8 temp3_disable;
308 u8 in6_skip;
301}; 309};
302 310
303struct w83627ehf_sio_data { 311struct w83627ehf_sio_data {
@@ -866,25 +874,37 @@ show_temp_type(struct device *dev, struct device_attribute *attr, char *buf)
866 return sprintf(buf, "%d\n", (int)data->temp_type[nr]); 874 return sprintf(buf, "%d\n", (int)data->temp_type[nr]);
867} 875}
868 876
869static struct sensor_device_attribute sda_temp[] = { 877static struct sensor_device_attribute sda_temp_input[] = {
870 SENSOR_ATTR(temp1_input, S_IRUGO, show_temp1, NULL, 0), 878 SENSOR_ATTR(temp1_input, S_IRUGO, show_temp1, NULL, 0),
871 SENSOR_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 0), 879 SENSOR_ATTR(temp2_input, S_IRUGO, show_temp, NULL, 0),
872 SENSOR_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 1), 880 SENSOR_ATTR(temp3_input, S_IRUGO, show_temp, NULL, 1),
881};
882
883static struct sensor_device_attribute sda_temp_max[] = {
873 SENSOR_ATTR(temp1_max, S_IRUGO | S_IWUSR, show_temp1_max, 884 SENSOR_ATTR(temp1_max, S_IRUGO | S_IWUSR, show_temp1_max,
874 store_temp1_max, 0), 885 store_temp1_max, 0),
875 SENSOR_ATTR(temp2_max, S_IRUGO | S_IWUSR, show_temp_max, 886 SENSOR_ATTR(temp2_max, S_IRUGO | S_IWUSR, show_temp_max,
876 store_temp_max, 0), 887 store_temp_max, 0),
877 SENSOR_ATTR(temp3_max, S_IRUGO | S_IWUSR, show_temp_max, 888 SENSOR_ATTR(temp3_max, S_IRUGO | S_IWUSR, show_temp_max,
878 store_temp_max, 1), 889 store_temp_max, 1),
890};
891
892static struct sensor_device_attribute sda_temp_max_hyst[] = {
879 SENSOR_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp1_max_hyst, 893 SENSOR_ATTR(temp1_max_hyst, S_IRUGO | S_IWUSR, show_temp1_max_hyst,
880 store_temp1_max_hyst, 0), 894 store_temp1_max_hyst, 0),
881 SENSOR_ATTR(temp2_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst, 895 SENSOR_ATTR(temp2_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst,
882 store_temp_max_hyst, 0), 896 store_temp_max_hyst, 0),
883 SENSOR_ATTR(temp3_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst, 897 SENSOR_ATTR(temp3_max_hyst, S_IRUGO | S_IWUSR, show_temp_max_hyst,
884 store_temp_max_hyst, 1), 898 store_temp_max_hyst, 1),
899};
900
901static struct sensor_device_attribute sda_temp_alarm[] = {
885 SENSOR_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4), 902 SENSOR_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4),
886 SENSOR_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5), 903 SENSOR_ATTR(temp2_alarm, S_IRUGO, show_alarm, NULL, 5),
887 SENSOR_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13), 904 SENSOR_ATTR(temp3_alarm, S_IRUGO, show_alarm, NULL, 13),
905};
906
907static struct sensor_device_attribute sda_temp_type[] = {
888 SENSOR_ATTR(temp1_type, S_IRUGO, show_temp_type, NULL, 0), 908 SENSOR_ATTR(temp1_type, S_IRUGO, show_temp_type, NULL, 0),
889 SENSOR_ATTR(temp2_type, S_IRUGO, show_temp_type, NULL, 1), 909 SENSOR_ATTR(temp2_type, S_IRUGO, show_temp_type, NULL, 1),
890 SENSOR_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2), 910 SENSOR_ATTR(temp3_type, S_IRUGO, show_temp_type, NULL, 2),
@@ -1181,6 +1201,8 @@ static void w83627ehf_device_remove_files(struct device *dev)
1181 for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) 1201 for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++)
1182 device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr); 1202 device_remove_file(dev, &sda_sf3_arrays_fan4[i].dev_attr);
1183 for (i = 0; i < data->in_num; i++) { 1203 for (i = 0; i < data->in_num; i++) {
1204 if ((i == 6) && data->in6_skip)
1205 continue;
1184 device_remove_file(dev, &sda_in_input[i].dev_attr); 1206 device_remove_file(dev, &sda_in_input[i].dev_attr);
1185 device_remove_file(dev, &sda_in_alarm[i].dev_attr); 1207 device_remove_file(dev, &sda_in_alarm[i].dev_attr);
1186 device_remove_file(dev, &sda_in_min[i].dev_attr); 1208 device_remove_file(dev, &sda_in_min[i].dev_attr);
@@ -1192,15 +1214,22 @@ static void w83627ehf_device_remove_files(struct device *dev)
1192 device_remove_file(dev, &sda_fan_div[i].dev_attr); 1214 device_remove_file(dev, &sda_fan_div[i].dev_attr);
1193 device_remove_file(dev, &sda_fan_min[i].dev_attr); 1215 device_remove_file(dev, &sda_fan_min[i].dev_attr);
1194 } 1216 }
1195 for (i = 0; i < 4; i++) { 1217 for (i = 0; i < data->pwm_num; i++) {
1196 device_remove_file(dev, &sda_pwm[i].dev_attr); 1218 device_remove_file(dev, &sda_pwm[i].dev_attr);
1197 device_remove_file(dev, &sda_pwm_mode[i].dev_attr); 1219 device_remove_file(dev, &sda_pwm_mode[i].dev_attr);
1198 device_remove_file(dev, &sda_pwm_enable[i].dev_attr); 1220 device_remove_file(dev, &sda_pwm_enable[i].dev_attr);
1199 device_remove_file(dev, &sda_target_temp[i].dev_attr); 1221 device_remove_file(dev, &sda_target_temp[i].dev_attr);
1200 device_remove_file(dev, &sda_tolerance[i].dev_attr); 1222 device_remove_file(dev, &sda_tolerance[i].dev_attr);
1201 } 1223 }
1202 for (i = 0; i < ARRAY_SIZE(sda_temp); i++) 1224 for (i = 0; i < 3; i++) {
1203 device_remove_file(dev, &sda_temp[i].dev_attr); 1225 if ((i == 2) && data->temp3_disable)
1226 continue;
1227 device_remove_file(dev, &sda_temp_input[i].dev_attr);
1228 device_remove_file(dev, &sda_temp_max[i].dev_attr);
1229 device_remove_file(dev, &sda_temp_max_hyst[i].dev_attr);
1230 device_remove_file(dev, &sda_temp_alarm[i].dev_attr);
1231 device_remove_file(dev, &sda_temp_type[i].dev_attr);
1232 }
1204 1233
1205 device_remove_file(dev, &dev_attr_name); 1234 device_remove_file(dev, &dev_attr_name);
1206 device_remove_file(dev, &dev_attr_cpu0_vid); 1235 device_remove_file(dev, &dev_attr_cpu0_vid);
@@ -1222,6 +1251,8 @@ static inline void __devinit w83627ehf_init_device(struct w83627ehf_data *data)
1222 for (i = 0; i < 2; i++) { 1251 for (i = 0; i < 2; i++) {
1223 tmp = w83627ehf_read_value(data, 1252 tmp = w83627ehf_read_value(data,
1224 W83627EHF_REG_TEMP_CONFIG[i]); 1253 W83627EHF_REG_TEMP_CONFIG[i]);
1254 if ((i == 1) && data->temp3_disable)
1255 continue;
1225 if (tmp & 0x01) 1256 if (tmp & 0x01)
1226 w83627ehf_write_value(data, 1257 w83627ehf_write_value(data,
1227 W83627EHF_REG_TEMP_CONFIG[i], 1258 W83627EHF_REG_TEMP_CONFIG[i],
@@ -1272,8 +1303,17 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
1272 data->name = w83627ehf_device_names[sio_data->kind]; 1303 data->name = w83627ehf_device_names[sio_data->kind];
1273 platform_set_drvdata(pdev, data); 1304 platform_set_drvdata(pdev, data);
1274 1305
1275 /* 627EHG and 627EHF have 10 voltage inputs; DHG has 9 */ 1306 /* 627EHG and 627EHF have 10 voltage inputs; 627DHG and 667HG have 9 */
1276 data->in_num = (sio_data->kind == w83627dhg) ? 9 : 10; 1307 data->in_num = (sio_data->kind == w83627ehf) ? 10 : 9;
1308 /* 667HG has 3 pwms */
1309 data->pwm_num = (sio_data->kind == w83667hg) ? 3 : 4;
1310
1311 /* Check temp3 configuration bit for 667HG */
1312 if (sio_data->kind == w83667hg) {
1313 data->temp3_disable = w83627ehf_read_value(data,
1314 W83627EHF_REG_TEMP_CONFIG[1]) & 0x01;
1315 data->in6_skip = !data->temp3_disable;
1316 }
1277 1317
1278 /* Initialize the chip */ 1318 /* Initialize the chip */
1279 w83627ehf_init_device(data); 1319 w83627ehf_init_device(data);
@@ -1281,44 +1321,64 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
1281 data->vrm = vid_which_vrm(); 1321 data->vrm = vid_which_vrm();
1282 superio_enter(sio_data->sioreg); 1322 superio_enter(sio_data->sioreg);
1283 /* Read VID value */ 1323 /* Read VID value */
1284 superio_select(sio_data->sioreg, W83627EHF_LD_HWM); 1324 if (sio_data->kind == w83667hg) {
1285 if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) { 1325 /* W83667HG has different pins for VID input and output, so
1286 /* Set VID input sensibility if needed. In theory the BIOS 1326 we can get the VID input values directly at logical device D
1287 should have set it, but in practice it's not always the 1327 0xe3. */
1288 case. We only do it for the W83627EHF/EHG because the 1328 superio_select(sio_data->sioreg, W83667HG_LD_VID);
1289 W83627DHG is more complex in this respect. */ 1329 data->vid = superio_inb(sio_data->sioreg, 0xe3);
1290 if (sio_data->kind == w83627ehf) {
1291 en_vrm10 = superio_inb(sio_data->sioreg,
1292 SIO_REG_EN_VRM10);
1293 if ((en_vrm10 & 0x08) && data->vrm == 90) {
1294 dev_warn(dev, "Setting VID input voltage to "
1295 "TTL\n");
1296 superio_outb(sio_data->sioreg, SIO_REG_EN_VRM10,
1297 en_vrm10 & ~0x08);
1298 } else if (!(en_vrm10 & 0x08) && data->vrm == 100) {
1299 dev_warn(dev, "Setting VID input voltage to "
1300 "VRM10\n");
1301 superio_outb(sio_data->sioreg, SIO_REG_EN_VRM10,
1302 en_vrm10 | 0x08);
1303 }
1304 }
1305
1306 data->vid = superio_inb(sio_data->sioreg, SIO_REG_VID_DATA);
1307 if (sio_data->kind == w83627ehf) /* 6 VID pins only */
1308 data->vid &= 0x3f;
1309
1310 err = device_create_file(dev, &dev_attr_cpu0_vid); 1330 err = device_create_file(dev, &dev_attr_cpu0_vid);
1311 if (err) 1331 if (err)
1312 goto exit_release; 1332 goto exit_release;
1313 } else { 1333 } else {
1314 dev_info(dev, "VID pins in output mode, CPU VID not " 1334 superio_select(sio_data->sioreg, W83627EHF_LD_HWM);
1315 "available\n"); 1335 if (superio_inb(sio_data->sioreg, SIO_REG_VID_CTRL) & 0x80) {
1336 /* Set VID input sensibility if needed. In theory the
1337 BIOS should have set it, but in practice it's not
1338 always the case. We only do it for the W83627EHF/EHG
1339 because the W83627DHG is more complex in this
1340 respect. */
1341 if (sio_data->kind == w83627ehf) {
1342 en_vrm10 = superio_inb(sio_data->sioreg,
1343 SIO_REG_EN_VRM10);
1344 if ((en_vrm10 & 0x08) && data->vrm == 90) {
1345 dev_warn(dev, "Setting VID input "
1346 "voltage to TTL\n");
1347 superio_outb(sio_data->sioreg,
1348 SIO_REG_EN_VRM10,
1349 en_vrm10 & ~0x08);
1350 } else if (!(en_vrm10 & 0x08)
1351 && data->vrm == 100) {
1352 dev_warn(dev, "Setting VID input "
1353 "voltage to VRM10\n");
1354 superio_outb(sio_data->sioreg,
1355 SIO_REG_EN_VRM10,
1356 en_vrm10 | 0x08);
1357 }
1358 }
1359
1360 data->vid = superio_inb(sio_data->sioreg,
1361 SIO_REG_VID_DATA);
1362 if (sio_data->kind == w83627ehf) /* 6 VID pins only */
1363 data->vid &= 0x3f;
1364
1365 err = device_create_file(dev, &dev_attr_cpu0_vid);
1366 if (err)
1367 goto exit_release;
1368 } else {
1369 dev_info(dev, "VID pins in output mode, CPU VID not "
1370 "available\n");
1371 }
1316 } 1372 }
1317 1373
1318 /* fan4 and fan5 share some pins with the GPIO and serial flash */ 1374 /* fan4 and fan5 share some pins with the GPIO and serial flash */
1319 1375 if (sio_data->kind == w83667hg) {
1320 fan5pin = superio_inb(sio_data->sioreg, 0x24) & 0x2; 1376 fan5pin = superio_inb(sio_data->sioreg, 0x27) & 0x20;
1321 fan4pin = superio_inb(sio_data->sioreg, 0x29) & 0x6; 1377 fan4pin = superio_inb(sio_data->sioreg, 0x27) & 0x40;
1378 } else {
1379 fan5pin = !(superio_inb(sio_data->sioreg, 0x24) & 0x02);
1380 fan4pin = !(superio_inb(sio_data->sioreg, 0x29) & 0x06);
1381 }
1322 superio_exit(sio_data->sioreg); 1382 superio_exit(sio_data->sioreg);
1323 1383
1324 /* It looks like fan4 and fan5 pins can be alternatively used 1384 /* It looks like fan4 and fan5 pins can be alternatively used
@@ -1329,9 +1389,9 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
1329 1389
1330 data->has_fan = 0x07; /* fan1, fan2 and fan3 */ 1390 data->has_fan = 0x07; /* fan1, fan2 and fan3 */
1331 i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV1); 1391 i = w83627ehf_read_value(data, W83627EHF_REG_FANDIV1);
1332 if ((i & (1 << 2)) && (!fan4pin)) 1392 if ((i & (1 << 2)) && fan4pin)
1333 data->has_fan |= (1 << 3); 1393 data->has_fan |= (1 << 3);
1334 if (!(i & (1 << 1)) && (!fan5pin)) 1394 if (!(i & (1 << 1)) && fan5pin)
1335 data->has_fan |= (1 << 4); 1395 data->has_fan |= (1 << 4);
1336 1396
1337 /* Read fan clock dividers immediately */ 1397 /* Read fan clock dividers immediately */
@@ -1344,14 +1404,16 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
1344 goto exit_remove; 1404 goto exit_remove;
1345 1405
1346 /* if fan4 is enabled create the sf3 files for it */ 1406 /* if fan4 is enabled create the sf3 files for it */
1347 if (data->has_fan & (1 << 3)) 1407 if ((data->has_fan & (1 << 3)) && data->pwm_num >= 4)
1348 for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) { 1408 for (i = 0; i < ARRAY_SIZE(sda_sf3_arrays_fan4); i++) {
1349 if ((err = device_create_file(dev, 1409 if ((err = device_create_file(dev,
1350 &sda_sf3_arrays_fan4[i].dev_attr))) 1410 &sda_sf3_arrays_fan4[i].dev_attr)))
1351 goto exit_remove; 1411 goto exit_remove;
1352 } 1412 }
1353 1413
1354 for (i = 0; i < data->in_num; i++) 1414 for (i = 0; i < data->in_num; i++) {
1415 if ((i == 6) && data->in6_skip)
1416 continue;
1355 if ((err = device_create_file(dev, &sda_in_input[i].dev_attr)) 1417 if ((err = device_create_file(dev, &sda_in_input[i].dev_attr))
1356 || (err = device_create_file(dev, 1418 || (err = device_create_file(dev,
1357 &sda_in_alarm[i].dev_attr)) 1419 &sda_in_alarm[i].dev_attr))
@@ -1360,6 +1422,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
1360 || (err = device_create_file(dev, 1422 || (err = device_create_file(dev,
1361 &sda_in_max[i].dev_attr))) 1423 &sda_in_max[i].dev_attr)))
1362 goto exit_remove; 1424 goto exit_remove;
1425 }
1363 1426
1364 for (i = 0; i < 5; i++) { 1427 for (i = 0; i < 5; i++) {
1365 if (data->has_fan & (1 << i)) { 1428 if (data->has_fan & (1 << i)) {
@@ -1372,7 +1435,7 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
1372 || (err = device_create_file(dev, 1435 || (err = device_create_file(dev,
1373 &sda_fan_min[i].dev_attr))) 1436 &sda_fan_min[i].dev_attr)))
1374 goto exit_remove; 1437 goto exit_remove;
1375 if (i < 4 && /* w83627ehf only has 4 pwm */ 1438 if (i < data->pwm_num &&
1376 ((err = device_create_file(dev, 1439 ((err = device_create_file(dev,
1377 &sda_pwm[i].dev_attr)) 1440 &sda_pwm[i].dev_attr))
1378 || (err = device_create_file(dev, 1441 || (err = device_create_file(dev,
@@ -1387,9 +1450,21 @@ static int __devinit w83627ehf_probe(struct platform_device *pdev)
1387 } 1450 }
1388 } 1451 }
1389 1452
1390 for (i = 0; i < ARRAY_SIZE(sda_temp); i++) 1453 for (i = 0; i < 3; i++) {
1391 if ((err = device_create_file(dev, &sda_temp[i].dev_attr))) 1454 if ((i == 2) && data->temp3_disable)
1455 continue;
1456 if ((err = device_create_file(dev,
1457 &sda_temp_input[i].dev_attr))
1458 || (err = device_create_file(dev,
1459 &sda_temp_max[i].dev_attr))
1460 || (err = device_create_file(dev,
1461 &sda_temp_max_hyst[i].dev_attr))
1462 || (err = device_create_file(dev,
1463 &sda_temp_alarm[i].dev_attr))
1464 || (err = device_create_file(dev,
1465 &sda_temp_type[i].dev_attr)))
1392 goto exit_remove; 1466 goto exit_remove;
1467 }
1393 1468
1394 err = device_create_file(dev, &dev_attr_name); 1469 err = device_create_file(dev, &dev_attr_name);
1395 if (err) 1470 if (err)
@@ -1442,6 +1517,7 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr,
1442 static const char __initdata sio_name_W83627EHF[] = "W83627EHF"; 1517 static const char __initdata sio_name_W83627EHF[] = "W83627EHF";
1443 static const char __initdata sio_name_W83627EHG[] = "W83627EHG"; 1518 static const char __initdata sio_name_W83627EHG[] = "W83627EHG";
1444 static const char __initdata sio_name_W83627DHG[] = "W83627DHG"; 1519 static const char __initdata sio_name_W83627DHG[] = "W83627DHG";
1520 static const char __initdata sio_name_W83667HG[] = "W83667HG";
1445 1521
1446 u16 val; 1522 u16 val;
1447 const char *sio_name; 1523 const char *sio_name;
@@ -1466,6 +1542,10 @@ static int __init w83627ehf_find(int sioaddr, unsigned short *addr,
1466 sio_data->kind = w83627dhg; 1542 sio_data->kind = w83627dhg;
1467 sio_name = sio_name_W83627DHG; 1543 sio_name = sio_name_W83627DHG;
1468 break; 1544 break;
1545 case SIO_W83667HG_ID:
1546 sio_data->kind = w83667hg;
1547 sio_name = sio_name_W83667HG;
1548 break;
1469 default: 1549 default:
1470 if (val != 0xffff) 1550 if (val != 0xffff)
1471 pr_debug(DRVNAME ": unsupported chip ID: 0x%04x\n", 1551 pr_debug(DRVNAME ": unsupported chip ID: 0x%04x\n",
diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
index 230238df56c4..10411848fd70 100644
--- a/drivers/i2c/busses/i2c-i801.c
+++ b/drivers/i2c/busses/i2c-i801.c
@@ -65,6 +65,7 @@
65#include <linux/i2c.h> 65#include <linux/i2c.h>
66#include <linux/acpi.h> 66#include <linux/acpi.h>
67#include <linux/io.h> 67#include <linux/io.h>
68#include <linux/dmi.h>
68 69
69/* I801 SMBus address offsets */ 70/* I801 SMBus address offsets */
70#define SMBHSTSTS (0 + i801_smba) 71#define SMBHSTSTS (0 + i801_smba)
@@ -616,10 +617,81 @@ static void __init input_apanel_init(void)
616static void __init input_apanel_init(void) {} 617static void __init input_apanel_init(void) {}
617#endif 618#endif
618 619
620#if defined CONFIG_SENSORS_FSCHMD || defined CONFIG_SENSORS_FSCHMD_MODULE
621struct dmi_onboard_device_info {
622 const char *name;
623 u8 type;
624 unsigned short i2c_addr;
625 const char *i2c_type;
626};
627
628static struct dmi_onboard_device_info __devinitdata dmi_devices[] = {
629 { "Syleus", DMI_DEV_TYPE_OTHER, 0x73, "fscsyl" },
630 { "Hermes", DMI_DEV_TYPE_OTHER, 0x73, "fscher" },
631 { "Hades", DMI_DEV_TYPE_OTHER, 0x73, "fschds" },
632};
633
634static void __devinit dmi_check_onboard_device(u8 type, const char *name,
635 struct i2c_adapter *adap)
636{
637 int i;
638 struct i2c_board_info info;
639
640 for (i = 0; i < ARRAY_SIZE(dmi_devices); i++) {
641 /* & ~0x80, ignore enabled/disabled bit */
642 if ((type & ~0x80) != dmi_devices[i].type)
643 continue;
644 if (strcmp(name, dmi_devices[i].name))
645 continue;
646
647 memset(&info, 0, sizeof(struct i2c_board_info));
648 info.addr = dmi_devices[i].i2c_addr;
649 strlcpy(info.type, dmi_devices[i].i2c_type, I2C_NAME_SIZE);
650 i2c_new_device(adap, &info);
651 break;
652 }
653}
654
655/* We use our own function to check for onboard devices instead of
656 dmi_find_device() as some buggy BIOS's have the devices we are interested
657 in marked as disabled */
658static void __devinit dmi_check_onboard_devices(const struct dmi_header *dm,
659 void *adap)
660{
661 int i, count;
662
663 if (dm->type != 10)
664 return;
665
666 count = (dm->length - sizeof(struct dmi_header)) / 2;
667 for (i = 0; i < count; i++) {
668 const u8 *d = (char *)(dm + 1) + (i * 2);
669 const char *name = ((char *) dm) + dm->length;
670 u8 type = d[0];
671 u8 s = d[1];
672
673 if (!s)
674 continue;
675 s--;
676 while (s > 0 && name[0]) {
677 name += strlen(name) + 1;
678 s--;
679 }
680 if (name[0] == 0) /* Bogus string reference */
681 continue;
682
683 dmi_check_onboard_device(type, name, adap);
684 }
685}
686#endif
687
619static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id *id) 688static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id *id)
620{ 689{
621 unsigned char temp; 690 unsigned char temp;
622 int err; 691 int err;
692#if defined CONFIG_SENSORS_FSCHMD || defined CONFIG_SENSORS_FSCHMD_MODULE
693 const char *vendor;
694#endif
623 695
624 I801_dev = dev; 696 I801_dev = dev;
625 i801_features = 0; 697 i801_features = 0;
@@ -712,6 +784,11 @@ static int __devinit i801_probe(struct pci_dev *dev, const struct pci_device_id
712 i2c_new_device(&i801_adapter, &info); 784 i2c_new_device(&i801_adapter, &info);
713 } 785 }
714#endif 786#endif
787#if defined CONFIG_SENSORS_FSCHMD || defined CONFIG_SENSORS_FSCHMD_MODULE
788 vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
789 if (vendor && !strcmp(vendor, "FUJITSU SIEMENS"))
790 dmi_walk(dmi_check_onboard_devices, &i801_adapter);
791#endif
715 792
716 return 0; 793 return 0;
717 794
diff --git a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
index c80312c1f382..8f8c81eb0aee 100644
--- a/drivers/i2c/chips/Kconfig
+++ b/drivers/i2c/chips/Kconfig
@@ -64,19 +64,6 @@ config SENSORS_PCA9539
64 This driver is deprecated and will be dropped soon. Use 64 This driver is deprecated and will be dropped soon. Use
65 drivers/gpio/pca953x.c instead. 65 drivers/gpio/pca953x.c instead.
66 66
67config SENSORS_PCF8591
68 tristate "Philips PCF8591"
69 depends on EXPERIMENTAL
70 default n
71 help
72 If you say yes here you get support for Philips PCF8591 chips.
73
74 This driver can also be built as a module. If so, the module
75 will be called pcf8591.
76
77 These devices are hard to detect and rarely found on mainstream
78 hardware. If unsure, say N.
79
80config SENSORS_MAX6875 67config SENSORS_MAX6875
81 tristate "Maxim MAX6875 Power supply supervisor" 68 tristate "Maxim MAX6875 Power supply supervisor"
82 depends on EXPERIMENTAL 69 depends on EXPERIMENTAL
diff --git a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile
index d142f238a2de..55a376037183 100644
--- a/drivers/i2c/chips/Makefile
+++ b/drivers/i2c/chips/Makefile
@@ -15,7 +15,6 @@ obj-$(CONFIG_SENSORS_MAX6875) += max6875.o
15obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o 15obj-$(CONFIG_SENSORS_PCA9539) += pca9539.o
16obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o 16obj-$(CONFIG_SENSORS_PCF8574) += pcf8574.o
17obj-$(CONFIG_PCF8575) += pcf8575.o 17obj-$(CONFIG_PCF8575) += pcf8575.o
18obj-$(CONFIG_SENSORS_PCF8591) += pcf8591.o
19obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o 18obj-$(CONFIG_SENSORS_TSL2550) += tsl2550.o
20 19
21ifeq ($(CONFIG_I2C_DEBUG_CHIP),y) 20ifeq ($(CONFIG_I2C_DEBUG_CHIP),y)
diff --git a/drivers/platform/x86/dell-laptop.c b/drivers/platform/x86/dell-laptop.c
index 16e11c2ee19a..af9f43021172 100644
--- a/drivers/platform/x86/dell-laptop.c
+++ b/drivers/platform/x86/dell-laptop.c
@@ -103,7 +103,7 @@ static void parse_da_table(const struct dmi_header *dm)
103 da_num_tokens += tokens; 103 da_num_tokens += tokens;
104} 104}
105 105
106static void find_tokens(const struct dmi_header *dm) 106static void find_tokens(const struct dmi_header *dm, void *dummy)
107{ 107{
108 switch (dm->type) { 108 switch (dm->type) {
109 case 0xd4: /* Indexed IO */ 109 case 0xd4: /* Indexed IO */
@@ -356,7 +356,7 @@ static int __init dell_init(void)
356 if (!dmi_check_system(dell_device_table)) 356 if (!dmi_check_system(dell_device_table))
357 return -ENODEV; 357 return -ENODEV;
358 358
359 dmi_walk(find_tokens); 359 dmi_walk(find_tokens, NULL);
360 360
361 if (!da_tokens) { 361 if (!da_tokens) {
362 printk(KERN_INFO "dell-laptop: Unable to find dmi tokens\n"); 362 printk(KERN_INFO "dell-laptop: Unable to find dmi tokens\n");
diff --git a/drivers/watchdog/hpwdt.c b/drivers/watchdog/hpwdt.c
index 6cf155d6b350..3137361ccbfe 100644
--- a/drivers/watchdog/hpwdt.c
+++ b/drivers/watchdog/hpwdt.c
@@ -380,7 +380,7 @@ asm(".text \n\t"
380 * This function checks whether or not a SMBIOS/DMI record is 380 * This function checks whether or not a SMBIOS/DMI record is
381 * the 64bit CRU info or not 381 * the 64bit CRU info or not
382 */ 382 */
383static void __devinit dmi_find_cru(const struct dmi_header *dm) 383static void __devinit dmi_find_cru(const struct dmi_header *dm, void *dummy)
384{ 384{
385 struct smbios_cru64_info *smbios_cru64_ptr; 385 struct smbios_cru64_info *smbios_cru64_ptr;
386 unsigned long cru_physical_address; 386 unsigned long cru_physical_address;
@@ -403,7 +403,7 @@ static int __devinit detect_cru_service(void)
403{ 403{
404 cru_rom_addr = NULL; 404 cru_rom_addr = NULL;
405 405
406 dmi_walk(dmi_find_cru); 406 dmi_walk(dmi_find_cru, NULL);
407 407
408 /* if cru_rom_addr has been set then we found a CRU service */ 408 /* if cru_rom_addr has been set then we found a CRU service */
409 return ((cru_rom_addr != NULL) ? 0 : -ENODEV); 409 return ((cru_rom_addr != NULL) ? 0 : -ENODEV);
diff --git a/include/linux/dmi.h b/include/linux/dmi.h
index d741b9ceb0e0..bb5489c82c99 100644
--- a/include/linux/dmi.h
+++ b/include/linux/dmi.h
@@ -47,7 +47,8 @@ extern int dmi_get_year(int field);
47extern int dmi_name_in_vendors(const char *str); 47extern int dmi_name_in_vendors(const char *str);
48extern int dmi_name_in_serial(const char *str); 48extern int dmi_name_in_serial(const char *str);
49extern int dmi_available; 49extern int dmi_available;
50extern int dmi_walk(void (*decode)(const struct dmi_header *)); 50extern int dmi_walk(void (*decode)(const struct dmi_header *, void *),
51 void *private_data);
51extern bool dmi_match(enum dmi_field f, const char *str); 52extern bool dmi_match(enum dmi_field f, const char *str);
52 53
53#else 54#else
@@ -61,8 +62,8 @@ static inline int dmi_get_year(int year) { return 0; }
61static inline int dmi_name_in_vendors(const char *s) { return 0; } 62static inline int dmi_name_in_vendors(const char *s) { return 0; }
62static inline int dmi_name_in_serial(const char *s) { return 0; } 63static inline int dmi_name_in_serial(const char *s) { return 0; }
63#define dmi_available 0 64#define dmi_available 0
64static inline int dmi_walk(void (*decode)(const struct dmi_header *)) 65static inline int dmi_walk(void (*decode)(const struct dmi_header *, void *),
65 { return -1; } 66 void *private_data) { return -1; }
66static inline bool dmi_match(enum dmi_field f, const char *str) 67static inline bool dmi_match(enum dmi_field f, const char *str)
67 { return false; } 68 { return false; }
68static inline const struct dmi_system_id * 69static inline const struct dmi_system_id *