diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-11-13 12:09:36 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-11-13 12:09:36 -0500 |
commit | 9418d5dc9ba40b88737580457bf3b7c63c60ec43 (patch) | |
tree | 764c82c8cfeea907b06514d9ccfb599fb4d49cae | |
parent | 31083eba370fbc5d544ac2fe67ca549c0aa2bdf7 (diff) | |
parent | 59a030a9b7a1bab5bdae57d469583e611759e90b (diff) |
Merge branch 'release' of git://lm-sensors.org/kernel/mhoffman/hwmon-2.6
* 'release' of git://lm-sensors.org/kernel/mhoffman/hwmon-2.6:
hwmon: (i5k_amb) Convert macros to C functions
hwmon: (w83781d) Add missing curly braces
hwmon: (abituguru3) Identify ABit IP35 Pro as such
hwmon: (f75375s) pwmX_mode sysfs files writable for f75375 variant
hwmon: (f75375s) On n2100 systems, set fans to full speed on boot
hwmon: (f75375s) Allow setting up fans with platform_data
hwmon: (f75375s) Add new style bindings
hwmon: (lm70) Convert semaphore to mutex
hwmon: (applesmc) Add support for Mac Pro 2 x Quad-Core
hwmon: (abituguru3) Add support for 2 new motherboards
hwmon: (ibmpex) Change printk to dev_{info,err} macros
hwmon: (i5k_amb) New memory temperature sensor driver
hwmon: (f75375s) fix pwm mode setting
hwmon: (ibmpex.c) fix NULL dereference
hwmon: (sis5595) Split sis5595_attributes_opt
hwmon: (sis5595) Add individual alarm files
hwmon: (w83627hf) push nr+1 offset into *_REG_FAN macros and simplify
hwmon: (w83627hf) hoist nr-1 offset out of show-store-temp-X
hwmon: Add power meter spec to Documentation/hwmon/sysfs-interface
-rw-r--r-- | Documentation/hwmon/sysfs-interface | 31 | ||||
-rw-r--r-- | arch/arm/mach-iop32x/n2100.c | 11 | ||||
-rw-r--r-- | drivers/hwmon/Kconfig | 10 | ||||
-rw-r--r-- | drivers/hwmon/Makefile | 1 | ||||
-rw-r--r-- | drivers/hwmon/abituguru3.c | 56 | ||||
-rw-r--r-- | drivers/hwmon/applesmc.c | 107 | ||||
-rw-r--r-- | drivers/hwmon/f75375s.c | 170 | ||||
-rw-r--r-- | drivers/hwmon/i5k_amb.c | 552 | ||||
-rw-r--r-- | drivers/hwmon/ibmpex.c | 48 | ||||
-rw-r--r-- | drivers/hwmon/lm70.c | 11 | ||||
-rw-r--r-- | drivers/hwmon/sis5595.c | 59 | ||||
-rw-r--r-- | drivers/hwmon/w83627hf.c | 155 | ||||
-rw-r--r-- | drivers/hwmon/w83781d.c | 3 | ||||
-rw-r--r-- | include/linux/f75375s.h | 21 | ||||
-rw-r--r-- | include/linux/pci_ids.h | 3 |
15 files changed, 1049 insertions, 189 deletions
diff --git a/Documentation/hwmon/sysfs-interface b/Documentation/hwmon/sysfs-interface index a17b692d2679..f4a8ebc1ef1a 100644 --- a/Documentation/hwmon/sysfs-interface +++ b/Documentation/hwmon/sysfs-interface | |||
@@ -328,6 +328,37 @@ curr[1-*]_input Current input value | |||
328 | Unit: milliampere | 328 | Unit: milliampere |
329 | RO | 329 | RO |
330 | 330 | ||
331 | ********* | ||
332 | * Power * | ||
333 | ********* | ||
334 | |||
335 | power[1-*]_average Average power use | ||
336 | Unit: microWatt | ||
337 | RO | ||
338 | |||
339 | power[1-*]_average_highest Historical average maximum power use | ||
340 | Unit: microWatt | ||
341 | RO | ||
342 | |||
343 | power[1-*]_average_lowest Historical average minimum power use | ||
344 | Unit: microWatt | ||
345 | RO | ||
346 | |||
347 | power[1-*]_input Instantaneous power use | ||
348 | Unit: microWatt | ||
349 | RO | ||
350 | |||
351 | power[1-*]_input_highest Historical maximum power use | ||
352 | Unit: microWatt | ||
353 | RO | ||
354 | |||
355 | power[1-*]_input_lowest Historical minimum power use | ||
356 | Unit: microWatt | ||
357 | RO | ||
358 | |||
359 | power[1-*]_reset_history Reset input_highest, input_lowest, | ||
360 | average_highest and average_lowest. | ||
361 | WO | ||
331 | 362 | ||
332 | ********** | 363 | ********** |
333 | * Alarms * | 364 | * Alarms * |
diff --git a/arch/arm/mach-iop32x/n2100.c b/arch/arm/mach-iop32x/n2100.c index 1873bd8cd1b2..bc91d6e66bc4 100644 --- a/arch/arm/mach-iop32x/n2100.c +++ b/arch/arm/mach-iop32x/n2100.c | |||
@@ -16,6 +16,7 @@ | |||
16 | 16 | ||
17 | #include <linux/mm.h> | 17 | #include <linux/mm.h> |
18 | #include <linux/init.h> | 18 | #include <linux/init.h> |
19 | #include <linux/f75375s.h> | ||
19 | #include <linux/delay.h> | 20 | #include <linux/delay.h> |
20 | #include <linux/kernel.h> | 21 | #include <linux/kernel.h> |
21 | #include <linux/pci.h> | 22 | #include <linux/pci.h> |
@@ -200,11 +201,21 @@ static struct platform_device n2100_serial_device = { | |||
200 | .resource = &n2100_uart_resource, | 201 | .resource = &n2100_uart_resource, |
201 | }; | 202 | }; |
202 | 203 | ||
204 | static struct f75375s_platform_data n2100_f75375s = { | ||
205 | .pwm = { 255, 255 }, | ||
206 | .pwm_enable = { 0, 0 }, | ||
207 | }; | ||
208 | |||
203 | static struct i2c_board_info __initdata n2100_i2c_devices[] = { | 209 | static struct i2c_board_info __initdata n2100_i2c_devices[] = { |
204 | { | 210 | { |
205 | I2C_BOARD_INFO("rtc-rs5c372", 0x32), | 211 | I2C_BOARD_INFO("rtc-rs5c372", 0x32), |
206 | .type = "rs5c372b", | 212 | .type = "rs5c372b", |
207 | }, | 213 | }, |
214 | { | ||
215 | I2C_BOARD_INFO("f75375", 0x2e), | ||
216 | .type = "f75375", | ||
217 | .platform_data = &n2100_f75375s, | ||
218 | }, | ||
208 | }; | 219 | }; |
209 | 220 | ||
210 | /* | 221 | /* |
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 700a1657554f..a0445bea9f75 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig | |||
@@ -216,6 +216,16 @@ config SENSORS_DS1621 | |||
216 | This driver can also be built as a module. If so, the module | 216 | This driver can also be built as a module. If so, the module |
217 | will be called ds1621. | 217 | will be called ds1621. |
218 | 218 | ||
219 | config SENSORS_I5K_AMB | ||
220 | tristate "FB-DIMM AMB temperature sensor on Intel 5000 series chipsets" | ||
221 | depends on PCI && EXPERIMENTAL | ||
222 | help | ||
223 | If you say yes here you get support for FB-DIMM AMB temperature | ||
224 | monitoring chips on systems with the Intel 5000 series chipset. | ||
225 | |||
226 | This driver can also be built as a module. If so, the module | ||
227 | will be called i5k_amb. | ||
228 | |||
219 | config SENSORS_F71805F | 229 | config SENSORS_F71805F |
220 | tristate "Fintek F71805F/FG, F71806F/FG and F71872F/FG" | 230 | tristate "Fintek F71805F/FG, F71806F/FG and F71872F/FG" |
221 | depends on EXPERIMENTAL | 231 | depends on EXPERIMENTAL |
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 6da3eef94306..55595f6e1aa6 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile | |||
@@ -38,6 +38,7 @@ obj-$(CONFIG_SENSORS_FSCPOS) += fscpos.o | |||
38 | obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o | 38 | obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o |
39 | obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o | 39 | obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o |
40 | obj-$(CONFIG_SENSORS_HDAPS) += hdaps.o | 40 | obj-$(CONFIG_SENSORS_HDAPS) += hdaps.o |
41 | obj-$(CONFIG_SENSORS_I5K_AMB) += i5k_amb.o | ||
41 | obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o | 42 | obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o |
42 | obj-$(CONFIG_SENSORS_IT87) += it87.o | 43 | obj-$(CONFIG_SENSORS_IT87) += it87.o |
43 | obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o | 44 | obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o |
diff --git a/drivers/hwmon/abituguru3.c b/drivers/hwmon/abituguru3.c index cb2331bfd9d5..d9f04ce90327 100644 --- a/drivers/hwmon/abituguru3.c +++ b/drivers/hwmon/abituguru3.c | |||
@@ -503,7 +503,7 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
503 | { "AUX3 FAN", 36, 2, 60, 1, 0 }, | 503 | { "AUX3 FAN", 36, 2, 60, 1, 0 }, |
504 | { NULL, 0, 0, 0, 0, 0 } } | 504 | { NULL, 0, 0, 0, 0, 0 } } |
505 | }, | 505 | }, |
506 | { 0x001A, "unknown", { | 506 | { 0x001A, "Abit IP35 Pro", { |
507 | { "CPU Core", 0, 0, 10, 1, 0 }, | 507 | { "CPU Core", 0, 0, 10, 1, 0 }, |
508 | { "DDR2", 1, 0, 20, 1, 0 }, | 508 | { "DDR2", 1, 0, 20, 1, 0 }, |
509 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, | 509 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, |
@@ -530,6 +530,60 @@ static const struct abituguru3_motherboard_info abituguru3_motherboards[] = { | |||
530 | { "AUX3 Fan", 36, 2, 60, 1, 0 }, | 530 | { "AUX3 Fan", 36, 2, 60, 1, 0 }, |
531 | { NULL, 0, 0, 0, 0, 0 } } | 531 | { NULL, 0, 0, 0, 0, 0 } } |
532 | }, | 532 | }, |
533 | { 0x001B, "unknown", { | ||
534 | { "CPU Core", 0, 0, 10, 1, 0 }, | ||
535 | { "DDR3", 1, 0, 20, 1, 0 }, | ||
536 | { "DDR3 VTT", 2, 0, 10, 1, 0 }, | ||
537 | { "CPU VTT", 3, 0, 10, 1, 0 }, | ||
538 | { "MCH 1.25V", 4, 0, 10, 1, 0 }, | ||
539 | { "ICHIO 1.5V", 5, 0, 10, 1, 0 }, | ||
540 | { "ICH 1.05V", 6, 0, 10, 1, 0 }, | ||
541 | { "ATX +12V (24-Pin)", 7, 0, 60, 1, 0 }, | ||
542 | { "ATX +12V (8-pin)", 8, 0, 60, 1, 0 }, | ||
543 | { "ATX +5V", 9, 0, 30, 1, 0 }, | ||
544 | { "+3.3V", 10, 0, 20, 1, 0 }, | ||
545 | { "5VSB", 11, 0, 30, 1, 0 }, | ||
546 | { "CPU", 24, 1, 1, 1, 0 }, | ||
547 | { "System", 25, 1, 1, 1, 0 }, | ||
548 | { "PWM Phase1", 26, 1, 1, 1, 0 }, | ||
549 | { "PWM Phase2", 27, 1, 1, 1, 0 }, | ||
550 | { "PWM Phase3", 28, 1, 1, 1, 0 }, | ||
551 | { "PWM Phase4", 29, 1, 1, 1, 0 }, | ||
552 | { "PWM Phase5", 30, 1, 1, 1, 0 }, | ||
553 | { "CPU Fan", 32, 2, 60, 1, 0 }, | ||
554 | { "SYS Fan", 34, 2, 60, 1, 0 }, | ||
555 | { "AUX1 Fan", 33, 2, 60, 1, 0 }, | ||
556 | { "AUX2 Fan", 35, 2, 60, 1, 0 }, | ||
557 | { "AUX3 Fan", 36, 2, 60, 1, 0 }, | ||
558 | { NULL, 0, 0, 0, 0, 0 } } | ||
559 | }, | ||
560 | { 0x001C, "unknown", { | ||
561 | { "CPU Core", 0, 0, 10, 1, 0 }, | ||
562 | { "DDR2", 1, 0, 20, 1, 0 }, | ||
563 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, | ||
564 | { "CPU VTT", 3, 0, 10, 1, 0 }, | ||
565 | { "MCH 1.25V", 4, 0, 10, 1, 0 }, | ||
566 | { "ICHIO 1.5V", 5, 0, 10, 1, 0 }, | ||
567 | { "ICH 1.05V", 6, 0, 10, 1, 0 }, | ||
568 | { "ATX +12V (24-Pin)", 7, 0, 60, 1, 0 }, | ||
569 | { "ATX +12V (8-pin)", 8, 0, 60, 1, 0 }, | ||
570 | { "ATX +5V", 9, 0, 30, 1, 0 }, | ||
571 | { "+3.3V", 10, 0, 20, 1, 0 }, | ||
572 | { "5VSB", 11, 0, 30, 1, 0 }, | ||
573 | { "CPU", 24, 1, 1, 1, 0 }, | ||
574 | { "System", 25, 1, 1, 1, 0 }, | ||
575 | { "PWM Phase1", 26, 1, 1, 1, 0 }, | ||
576 | { "PWM Phase2", 27, 1, 1, 1, 0 }, | ||
577 | { "PWM Phase3", 28, 1, 1, 1, 0 }, | ||
578 | { "PWM Phase4", 29, 1, 1, 1, 0 }, | ||
579 | { "PWM Phase5", 30, 1, 1, 1, 0 }, | ||
580 | { "CPU Fan", 32, 2, 60, 1, 0 }, | ||
581 | { "SYS Fan", 34, 2, 60, 1, 0 }, | ||
582 | { "AUX1 Fan", 33, 2, 60, 1, 0 }, | ||
583 | { "AUX2 Fan", 35, 2, 60, 1, 0 }, | ||
584 | { "AUX3 Fan", 36, 2, 60, 1, 0 }, | ||
585 | { NULL, 0, 0, 0, 0, 0 } } | ||
586 | }, | ||
533 | { 0x0000, NULL, { { NULL, 0, 0, 0, 0, 0 } } } | 587 | { 0x0000, NULL, { { NULL, 0, 0, 0, 0, 0 } } } |
534 | }; | 588 | }; |
535 | 589 | ||
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index 1001d2e122a2..86c66c345f8b 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c | |||
@@ -80,7 +80,7 @@ | |||
80 | /* | 80 | /* |
81 | * Temperature sensors keys (sp78 - 2 bytes). | 81 | * Temperature sensors keys (sp78 - 2 bytes). |
82 | */ | 82 | */ |
83 | static const char* temperature_sensors_sets[][13] = { | 83 | static const char* temperature_sensors_sets[][36] = { |
84 | /* Set 0: Macbook Pro */ | 84 | /* Set 0: Macbook Pro */ |
85 | { "TA0P", "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "Th0H", | 85 | { "TA0P", "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "Th0H", |
86 | "Th1H", "Tm0P", "Ts0P", "Ts1P", NULL }, | 86 | "Th1H", "Tm0P", "Ts0P", "Ts1P", NULL }, |
@@ -88,7 +88,13 @@ static const char* temperature_sensors_sets[][13] = { | |||
88 | { "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TN1P", "Th0H", "Th0S", | 88 | { "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TN1P", "Th0H", "Th0S", |
89 | "Th1H", "Ts0P", NULL }, | 89 | "Th1H", "Ts0P", NULL }, |
90 | /* Set 2: Macmini set */ | 90 | /* Set 2: Macmini set */ |
91 | { "TC0D", "TC0P", NULL } | 91 | { "TC0D", "TC0P", NULL }, |
92 | /* Set 3: Mac Pro (2 x Quad-Core) */ | ||
93 | { "TA0P", "TCAG", "TCAH", "TCBG", "TCBH", "TC0C", "TC0D", "TC0P", | ||
94 | "TC1C", "TC1D", "TC2C", "TC2D", "TC3C", "TC3D", "THTG", "TH0P", | ||
95 | "TH1P", "TH2P", "TH3P", "TMAP", "TMAS", "TMBS", "TM0P", "TM0S", | ||
96 | "TM1P", "TM1S", "TM2P", "TM2S", "TM3S", "TM8P", "TM8S", "TM9P", | ||
97 | "TM9S", "TN0H", "TS0C", NULL }, | ||
92 | }; | 98 | }; |
93 | 99 | ||
94 | /* List of keys used to read/write fan speeds */ | 100 | /* List of keys used to read/write fan speeds */ |
@@ -990,14 +996,18 @@ static struct attribute *fan##offset##_attributes[] = { \ | |||
990 | 996 | ||
991 | /* | 997 | /* |
992 | * Create the needed functions for each fan using the macro defined above | 998 | * Create the needed functions for each fan using the macro defined above |
993 | * (2 fans are supported) | 999 | * (4 fans are supported) |
994 | */ | 1000 | */ |
995 | sysfs_fan_speeds_offset(1); | 1001 | sysfs_fan_speeds_offset(1); |
996 | sysfs_fan_speeds_offset(2); | 1002 | sysfs_fan_speeds_offset(2); |
1003 | sysfs_fan_speeds_offset(3); | ||
1004 | sysfs_fan_speeds_offset(4); | ||
997 | 1005 | ||
998 | static const struct attribute_group fan_attribute_groups[] = { | 1006 | static const struct attribute_group fan_attribute_groups[] = { |
999 | { .attrs = fan1_attributes }, | 1007 | { .attrs = fan1_attributes }, |
1000 | { .attrs = fan2_attributes } | 1008 | { .attrs = fan2_attributes }, |
1009 | { .attrs = fan3_attributes }, | ||
1010 | { .attrs = fan4_attributes }, | ||
1001 | }; | 1011 | }; |
1002 | 1012 | ||
1003 | /* | 1013 | /* |
@@ -1027,6 +1037,52 @@ static SENSOR_DEVICE_ATTR(temp11_input, S_IRUGO, | |||
1027 | applesmc_show_temperature, NULL, 10); | 1037 | applesmc_show_temperature, NULL, 10); |
1028 | static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO, | 1038 | static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO, |
1029 | applesmc_show_temperature, NULL, 11); | 1039 | applesmc_show_temperature, NULL, 11); |
1040 | static SENSOR_DEVICE_ATTR(temp13_input, S_IRUGO, | ||
1041 | applesmc_show_temperature, NULL, 12); | ||
1042 | static SENSOR_DEVICE_ATTR(temp14_input, S_IRUGO, | ||
1043 | applesmc_show_temperature, NULL, 13); | ||
1044 | static SENSOR_DEVICE_ATTR(temp15_input, S_IRUGO, | ||
1045 | applesmc_show_temperature, NULL, 14); | ||
1046 | static SENSOR_DEVICE_ATTR(temp16_input, S_IRUGO, | ||
1047 | applesmc_show_temperature, NULL, 15); | ||
1048 | static SENSOR_DEVICE_ATTR(temp17_input, S_IRUGO, | ||
1049 | applesmc_show_temperature, NULL, 16); | ||
1050 | static SENSOR_DEVICE_ATTR(temp18_input, S_IRUGO, | ||
1051 | applesmc_show_temperature, NULL, 17); | ||
1052 | static SENSOR_DEVICE_ATTR(temp19_input, S_IRUGO, | ||
1053 | applesmc_show_temperature, NULL, 18); | ||
1054 | static SENSOR_DEVICE_ATTR(temp20_input, S_IRUGO, | ||
1055 | applesmc_show_temperature, NULL, 19); | ||
1056 | static SENSOR_DEVICE_ATTR(temp21_input, S_IRUGO, | ||
1057 | applesmc_show_temperature, NULL, 20); | ||
1058 | static SENSOR_DEVICE_ATTR(temp22_input, S_IRUGO, | ||
1059 | applesmc_show_temperature, NULL, 21); | ||
1060 | static SENSOR_DEVICE_ATTR(temp23_input, S_IRUGO, | ||
1061 | applesmc_show_temperature, NULL, 22); | ||
1062 | static SENSOR_DEVICE_ATTR(temp24_input, S_IRUGO, | ||
1063 | applesmc_show_temperature, NULL, 23); | ||
1064 | static SENSOR_DEVICE_ATTR(temp25_input, S_IRUGO, | ||
1065 | applesmc_show_temperature, NULL, 24); | ||
1066 | static SENSOR_DEVICE_ATTR(temp26_input, S_IRUGO, | ||
1067 | applesmc_show_temperature, NULL, 25); | ||
1068 | static SENSOR_DEVICE_ATTR(temp27_input, S_IRUGO, | ||
1069 | applesmc_show_temperature, NULL, 26); | ||
1070 | static SENSOR_DEVICE_ATTR(temp28_input, S_IRUGO, | ||
1071 | applesmc_show_temperature, NULL, 27); | ||
1072 | static SENSOR_DEVICE_ATTR(temp29_input, S_IRUGO, | ||
1073 | applesmc_show_temperature, NULL, 28); | ||
1074 | static SENSOR_DEVICE_ATTR(temp30_input, S_IRUGO, | ||
1075 | applesmc_show_temperature, NULL, 29); | ||
1076 | static SENSOR_DEVICE_ATTR(temp31_input, S_IRUGO, | ||
1077 | applesmc_show_temperature, NULL, 30); | ||
1078 | static SENSOR_DEVICE_ATTR(temp32_input, S_IRUGO, | ||
1079 | applesmc_show_temperature, NULL, 31); | ||
1080 | static SENSOR_DEVICE_ATTR(temp33_input, S_IRUGO, | ||
1081 | applesmc_show_temperature, NULL, 32); | ||
1082 | static SENSOR_DEVICE_ATTR(temp34_input, S_IRUGO, | ||
1083 | applesmc_show_temperature, NULL, 33); | ||
1084 | static SENSOR_DEVICE_ATTR(temp35_input, S_IRUGO, | ||
1085 | applesmc_show_temperature, NULL, 34); | ||
1030 | 1086 | ||
1031 | static struct attribute *temperature_attributes[] = { | 1087 | static struct attribute *temperature_attributes[] = { |
1032 | &sensor_dev_attr_temp1_input.dev_attr.attr, | 1088 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
@@ -1041,6 +1097,29 @@ static struct attribute *temperature_attributes[] = { | |||
1041 | &sensor_dev_attr_temp10_input.dev_attr.attr, | 1097 | &sensor_dev_attr_temp10_input.dev_attr.attr, |
1042 | &sensor_dev_attr_temp11_input.dev_attr.attr, | 1098 | &sensor_dev_attr_temp11_input.dev_attr.attr, |
1043 | &sensor_dev_attr_temp12_input.dev_attr.attr, | 1099 | &sensor_dev_attr_temp12_input.dev_attr.attr, |
1100 | &sensor_dev_attr_temp13_input.dev_attr.attr, | ||
1101 | &sensor_dev_attr_temp14_input.dev_attr.attr, | ||
1102 | &sensor_dev_attr_temp15_input.dev_attr.attr, | ||
1103 | &sensor_dev_attr_temp16_input.dev_attr.attr, | ||
1104 | &sensor_dev_attr_temp17_input.dev_attr.attr, | ||
1105 | &sensor_dev_attr_temp18_input.dev_attr.attr, | ||
1106 | &sensor_dev_attr_temp19_input.dev_attr.attr, | ||
1107 | &sensor_dev_attr_temp20_input.dev_attr.attr, | ||
1108 | &sensor_dev_attr_temp21_input.dev_attr.attr, | ||
1109 | &sensor_dev_attr_temp22_input.dev_attr.attr, | ||
1110 | &sensor_dev_attr_temp23_input.dev_attr.attr, | ||
1111 | &sensor_dev_attr_temp24_input.dev_attr.attr, | ||
1112 | &sensor_dev_attr_temp25_input.dev_attr.attr, | ||
1113 | &sensor_dev_attr_temp26_input.dev_attr.attr, | ||
1114 | &sensor_dev_attr_temp27_input.dev_attr.attr, | ||
1115 | &sensor_dev_attr_temp28_input.dev_attr.attr, | ||
1116 | &sensor_dev_attr_temp29_input.dev_attr.attr, | ||
1117 | &sensor_dev_attr_temp30_input.dev_attr.attr, | ||
1118 | &sensor_dev_attr_temp31_input.dev_attr.attr, | ||
1119 | &sensor_dev_attr_temp32_input.dev_attr.attr, | ||
1120 | &sensor_dev_attr_temp33_input.dev_attr.attr, | ||
1121 | &sensor_dev_attr_temp34_input.dev_attr.attr, | ||
1122 | &sensor_dev_attr_temp35_input.dev_attr.attr, | ||
1044 | NULL | 1123 | NULL |
1045 | }; | 1124 | }; |
1046 | 1125 | ||
@@ -1137,6 +1216,8 @@ static __initdata struct dmi_match_data applesmc_dmi_data[] = { | |||
1137 | { .accelerometer = 1, .light = 0, .temperature_set = 1 }, | 1216 | { .accelerometer = 1, .light = 0, .temperature_set = 1 }, |
1138 | /* MacMini: temperature set 2 */ | 1217 | /* MacMini: temperature set 2 */ |
1139 | { .accelerometer = 0, .light = 0, .temperature_set = 2 }, | 1218 | { .accelerometer = 0, .light = 0, .temperature_set = 2 }, |
1219 | /* MacPro: temperature set 3 */ | ||
1220 | { .accelerometer = 0, .light = 0, .temperature_set = 3 }, | ||
1140 | }; | 1221 | }; |
1141 | 1222 | ||
1142 | /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". | 1223 | /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". |
@@ -1154,6 +1235,10 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = { | |||
1154 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), | 1235 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), |
1155 | DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") }, | 1236 | DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") }, |
1156 | (void*)&applesmc_dmi_data[2]}, | 1237 | (void*)&applesmc_dmi_data[2]}, |
1238 | { applesmc_dmi_match, "Apple MacPro2", { | ||
1239 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), | ||
1240 | DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") }, | ||
1241 | (void*)&applesmc_dmi_data[3]}, | ||
1157 | { .ident = NULL } | 1242 | { .ident = NULL } |
1158 | }; | 1243 | }; |
1159 | 1244 | ||
@@ -1204,9 +1289,19 @@ static int __init applesmc_init(void) | |||
1204 | 1289 | ||
1205 | switch (count) { | 1290 | switch (count) { |
1206 | default: | 1291 | default: |
1207 | printk(KERN_WARNING "applesmc: More than 2 fans found," | 1292 | printk(KERN_WARNING "applesmc: More than 4 fans found," |
1208 | " but at most 2 fans are supported" | 1293 | " but at most 4 fans are supported" |
1209 | " by the driver.\n"); | 1294 | " by the driver.\n"); |
1295 | case 4: | ||
1296 | ret = sysfs_create_group(&pdev->dev.kobj, | ||
1297 | &fan_attribute_groups[3]); | ||
1298 | if (ret) | ||
1299 | goto out_key_enumeration; | ||
1300 | case 3: | ||
1301 | ret = sysfs_create_group(&pdev->dev.kobj, | ||
1302 | &fan_attribute_groups[2]); | ||
1303 | if (ret) | ||
1304 | goto out_key_enumeration; | ||
1210 | case 2: | 1305 | case 2: |
1211 | ret = sysfs_create_group(&pdev->dev.kobj, | 1306 | ret = sysfs_create_group(&pdev->dev.kobj, |
1212 | &fan_attribute_groups[1]); | 1307 | &fan_attribute_groups[1]); |
diff --git a/drivers/hwmon/f75375s.c b/drivers/hwmon/f75375s.c index 13a041326a04..6892f76fc18a 100644 --- a/drivers/hwmon/f75375s.c +++ b/drivers/hwmon/f75375s.c | |||
@@ -34,6 +34,7 @@ | |||
34 | #include <linux/i2c.h> | 34 | #include <linux/i2c.h> |
35 | #include <linux/err.h> | 35 | #include <linux/err.h> |
36 | #include <linux/mutex.h> | 36 | #include <linux/mutex.h> |
37 | #include <linux/f75375s.h> | ||
37 | 38 | ||
38 | /* Addresses to scan */ | 39 | /* Addresses to scan */ |
39 | static unsigned short normal_i2c[] = { 0x2d, 0x2e, I2C_CLIENT_END }; | 40 | static unsigned short normal_i2c[] = { 0x2d, 0x2e, I2C_CLIENT_END }; |
@@ -86,7 +87,7 @@ I2C_CLIENT_INSMOD_2(f75373, f75375); | |||
86 | 87 | ||
87 | struct f75375_data { | 88 | struct f75375_data { |
88 | unsigned short addr; | 89 | unsigned short addr; |
89 | struct i2c_client client; | 90 | struct i2c_client *client; |
90 | struct device *hwmon_dev; | 91 | struct device *hwmon_dev; |
91 | 92 | ||
92 | const char *name; | 93 | const char *name; |
@@ -116,15 +117,25 @@ struct f75375_data { | |||
116 | static int f75375_attach_adapter(struct i2c_adapter *adapter); | 117 | static int f75375_attach_adapter(struct i2c_adapter *adapter); |
117 | static int f75375_detect(struct i2c_adapter *adapter, int address, int kind); | 118 | static int f75375_detect(struct i2c_adapter *adapter, int address, int kind); |
118 | static int f75375_detach_client(struct i2c_client *client); | 119 | static int f75375_detach_client(struct i2c_client *client); |
120 | static int f75375_probe(struct i2c_client *client); | ||
121 | static int f75375_remove(struct i2c_client *client); | ||
119 | 122 | ||
120 | static struct i2c_driver f75375_driver = { | 123 | static struct i2c_driver f75375_legacy_driver = { |
121 | .driver = { | 124 | .driver = { |
122 | .name = "f75375", | 125 | .name = "f75375_legacy", |
123 | }, | 126 | }, |
124 | .attach_adapter = f75375_attach_adapter, | 127 | .attach_adapter = f75375_attach_adapter, |
125 | .detach_client = f75375_detach_client, | 128 | .detach_client = f75375_detach_client, |
126 | }; | 129 | }; |
127 | 130 | ||
131 | static struct i2c_driver f75375_driver = { | ||
132 | .driver = { | ||
133 | .name = "f75375", | ||
134 | }, | ||
135 | .probe = f75375_probe, | ||
136 | .remove = f75375_remove, | ||
137 | }; | ||
138 | |||
128 | static inline int f75375_read8(struct i2c_client *client, u8 reg) | 139 | static inline int f75375_read8(struct i2c_client *client, u8 reg) |
129 | { | 140 | { |
130 | return i2c_smbus_read_byte_data(client, reg); | 141 | return i2c_smbus_read_byte_data(client, reg); |
@@ -276,19 +287,14 @@ static ssize_t show_pwm_enable(struct device *dev, struct device_attribute | |||
276 | return sprintf(buf, "%d\n", data->pwm_enable[nr]); | 287 | return sprintf(buf, "%d\n", data->pwm_enable[nr]); |
277 | } | 288 | } |
278 | 289 | ||
279 | static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr, | 290 | static int set_pwm_enable_direct(struct i2c_client *client, int nr, int val) |
280 | const char *buf, size_t count) | ||
281 | { | 291 | { |
282 | int nr = to_sensor_dev_attr(attr)->index; | ||
283 | struct i2c_client *client = to_i2c_client(dev); | ||
284 | struct f75375_data *data = i2c_get_clientdata(client); | 292 | struct f75375_data *data = i2c_get_clientdata(client); |
285 | int val = simple_strtoul(buf, NULL, 10); | ||
286 | u8 fanmode; | 293 | u8 fanmode; |
287 | 294 | ||
288 | if (val < 0 || val > 4) | 295 | if (val < 0 || val > 4) |
289 | return -EINVAL; | 296 | return -EINVAL; |
290 | 297 | ||
291 | mutex_lock(&data->update_lock); | ||
292 | fanmode = f75375_read8(client, F75375_REG_FAN_TIMER); | 298 | fanmode = f75375_read8(client, F75375_REG_FAN_TIMER); |
293 | fanmode = ~(3 << FAN_CTRL_MODE(nr)); | 299 | fanmode = ~(3 << FAN_CTRL_MODE(nr)); |
294 | 300 | ||
@@ -310,8 +316,22 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr, | |||
310 | } | 316 | } |
311 | f75375_write8(client, F75375_REG_FAN_TIMER, fanmode); | 317 | f75375_write8(client, F75375_REG_FAN_TIMER, fanmode); |
312 | data->pwm_enable[nr] = val; | 318 | data->pwm_enable[nr] = val; |
319 | return 0; | ||
320 | } | ||
321 | |||
322 | static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr, | ||
323 | const char *buf, size_t count) | ||
324 | { | ||
325 | int nr = to_sensor_dev_attr(attr)->index; | ||
326 | struct i2c_client *client = to_i2c_client(dev); | ||
327 | struct f75375_data *data = i2c_get_clientdata(client); | ||
328 | int val = simple_strtoul(buf, NULL, 10); | ||
329 | int err = 0; | ||
330 | |||
331 | mutex_lock(&data->update_lock); | ||
332 | err = set_pwm_enable_direct(client, nr, val); | ||
313 | mutex_unlock(&data->update_lock); | 333 | mutex_unlock(&data->update_lock); |
314 | return count; | 334 | return err ? err : count; |
315 | } | 335 | } |
316 | 336 | ||
317 | static ssize_t set_pwm_mode(struct device *dev, struct device_attribute *attr, | 337 | static ssize_t set_pwm_mode(struct device *dev, struct device_attribute *attr, |
@@ -323,7 +343,7 @@ static ssize_t set_pwm_mode(struct device *dev, struct device_attribute *attr, | |||
323 | int val = simple_strtoul(buf, NULL, 10); | 343 | int val = simple_strtoul(buf, NULL, 10); |
324 | u8 conf = 0; | 344 | u8 conf = 0; |
325 | 345 | ||
326 | if (val != 0 || val != 1 || data->kind == f75373) | 346 | if (!(val == 0 || val == 1)) |
327 | return -EINVAL; | 347 | return -EINVAL; |
328 | 348 | ||
329 | mutex_lock(&data->update_lock); | 349 | mutex_lock(&data->update_lock); |
@@ -529,13 +549,13 @@ static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO|S_IWUSR, | |||
529 | show_pwm, set_pwm, 0); | 549 | show_pwm, set_pwm, 0); |
530 | static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO|S_IWUSR, | 550 | static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO|S_IWUSR, |
531 | show_pwm_enable, set_pwm_enable, 0); | 551 | show_pwm_enable, set_pwm_enable, 0); |
532 | static SENSOR_DEVICE_ATTR(pwm1_mode, S_IRUGO|S_IWUSR, | 552 | static SENSOR_DEVICE_ATTR(pwm1_mode, S_IRUGO, |
533 | show_pwm_mode, set_pwm_mode, 0); | 553 | show_pwm_mode, set_pwm_mode, 0); |
534 | static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, | 554 | static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, |
535 | show_pwm, set_pwm, 1); | 555 | show_pwm, set_pwm, 1); |
536 | static SENSOR_DEVICE_ATTR(pwm2_enable, S_IRUGO|S_IWUSR, | 556 | static SENSOR_DEVICE_ATTR(pwm2_enable, S_IRUGO|S_IWUSR, |
537 | show_pwm_enable, set_pwm_enable, 1); | 557 | show_pwm_enable, set_pwm_enable, 1); |
538 | static SENSOR_DEVICE_ATTR(pwm2_mode, S_IRUGO|S_IWUSR, | 558 | static SENSOR_DEVICE_ATTR(pwm2_mode, S_IRUGO, |
539 | show_pwm_mode, set_pwm_mode, 1); | 559 | show_pwm_mode, set_pwm_mode, 1); |
540 | 560 | ||
541 | static struct attribute *f75375_attributes[] = { | 561 | static struct attribute *f75375_attributes[] = { |
@@ -580,12 +600,9 @@ static const struct attribute_group f75375_group = { | |||
580 | 600 | ||
581 | static int f75375_detach_client(struct i2c_client *client) | 601 | static int f75375_detach_client(struct i2c_client *client) |
582 | { | 602 | { |
583 | struct f75375_data *data = i2c_get_clientdata(client); | ||
584 | int err; | 603 | int err; |
585 | 604 | ||
586 | hwmon_device_unregister(data->hwmon_dev); | 605 | f75375_remove(client); |
587 | sysfs_remove_group(&client->dev.kobj, &f75375_group); | ||
588 | |||
589 | err = i2c_detach_client(client); | 606 | err = i2c_detach_client(client); |
590 | if (err) { | 607 | if (err) { |
591 | dev_err(&client->dev, | 608 | dev_err(&client->dev, |
@@ -593,7 +610,91 @@ static int f75375_detach_client(struct i2c_client *client) | |||
593 | "client not detached.\n"); | 610 | "client not detached.\n"); |
594 | return err; | 611 | return err; |
595 | } | 612 | } |
613 | kfree(client); | ||
614 | return 0; | ||
615 | } | ||
616 | |||
617 | static void f75375_init(struct i2c_client *client, struct f75375_data *data, | ||
618 | struct f75375s_platform_data *f75375s_pdata) | ||
619 | { | ||
620 | int nr; | ||
621 | set_pwm_enable_direct(client, 0, f75375s_pdata->pwm_enable[0]); | ||
622 | set_pwm_enable_direct(client, 1, f75375s_pdata->pwm_enable[1]); | ||
623 | for (nr = 0; nr < 2; nr++) { | ||
624 | data->pwm[nr] = SENSORS_LIMIT(f75375s_pdata->pwm[nr], 0, 255); | ||
625 | f75375_write8(client, F75375_REG_FAN_PWM_DUTY(nr), | ||
626 | data->pwm[nr]); | ||
627 | } | ||
628 | |||
629 | } | ||
630 | |||
631 | static int f75375_probe(struct i2c_client *client) | ||
632 | { | ||
633 | struct f75375_data *data = i2c_get_clientdata(client); | ||
634 | struct f75375s_platform_data *f75375s_pdata = client->dev.platform_data; | ||
635 | int err; | ||
636 | |||
637 | if (!i2c_check_functionality(client->adapter, | ||
638 | I2C_FUNC_SMBUS_BYTE_DATA)) | ||
639 | return -EIO; | ||
640 | if (!(data = kzalloc(sizeof(struct f75375_data), GFP_KERNEL))) | ||
641 | return -ENOMEM; | ||
642 | |||
643 | i2c_set_clientdata(client, data); | ||
644 | data->client = client; | ||
645 | mutex_init(&data->update_lock); | ||
646 | |||
647 | if (strcmp(client->name, "f75375") == 0) | ||
648 | data->kind = f75375; | ||
649 | else if (strcmp(client->name, "f75373") == 0) | ||
650 | data->kind = f75373; | ||
651 | else { | ||
652 | dev_err(&client->dev, "Unsupported device: %s\n", client->name); | ||
653 | return -ENODEV; | ||
654 | } | ||
655 | |||
656 | if ((err = sysfs_create_group(&client->dev.kobj, &f75375_group))) | ||
657 | goto exit_free; | ||
658 | |||
659 | if (data->kind == f75375) { | ||
660 | err = sysfs_chmod_file(&client->dev.kobj, | ||
661 | &sensor_dev_attr_pwm1_mode.dev_attr.attr, | ||
662 | S_IRUGO | S_IWUSR); | ||
663 | if (err) | ||
664 | goto exit_remove; | ||
665 | err = sysfs_chmod_file(&client->dev.kobj, | ||
666 | &sensor_dev_attr_pwm2_mode.dev_attr.attr, | ||
667 | S_IRUGO | S_IWUSR); | ||
668 | if (err) | ||
669 | goto exit_remove; | ||
670 | } | ||
671 | |||
672 | data->hwmon_dev = hwmon_device_register(&client->dev); | ||
673 | if (IS_ERR(data->hwmon_dev)) { | ||
674 | err = PTR_ERR(data->hwmon_dev); | ||
675 | goto exit_remove; | ||
676 | } | ||
677 | |||
678 | if (f75375s_pdata != NULL) | ||
679 | f75375_init(client, data, f75375s_pdata); | ||
680 | |||
681 | return 0; | ||
682 | |||
683 | exit_remove: | ||
684 | sysfs_remove_group(&client->dev.kobj, &f75375_group); | ||
685 | exit_free: | ||
596 | kfree(data); | 686 | kfree(data); |
687 | i2c_set_clientdata(client, NULL); | ||
688 | return err; | ||
689 | } | ||
690 | |||
691 | static int f75375_remove(struct i2c_client *client) | ||
692 | { | ||
693 | struct f75375_data *data = i2c_get_clientdata(client); | ||
694 | hwmon_device_unregister(data->hwmon_dev); | ||
695 | sysfs_remove_group(&client->dev.kobj, &f75375_group); | ||
696 | kfree(data); | ||
697 | i2c_set_clientdata(client, NULL); | ||
597 | return 0; | 698 | return 0; |
598 | } | 699 | } |
599 | 700 | ||
@@ -608,20 +709,17 @@ static int f75375_attach_adapter(struct i2c_adapter *adapter) | |||
608 | static int f75375_detect(struct i2c_adapter *adapter, int address, int kind) | 709 | static int f75375_detect(struct i2c_adapter *adapter, int address, int kind) |
609 | { | 710 | { |
610 | struct i2c_client *client; | 711 | struct i2c_client *client; |
611 | struct f75375_data *data; | ||
612 | u8 version = 0; | 712 | u8 version = 0; |
613 | int err = 0; | 713 | int err = 0; |
614 | const char *name = ""; | 714 | const char *name = ""; |
615 | 715 | ||
616 | if (!(data = kzalloc(sizeof(struct f75375_data), GFP_KERNEL))) { | 716 | if (!(client = kzalloc(sizeof(*client), GFP_KERNEL))) { |
617 | err = -ENOMEM; | 717 | err = -ENOMEM; |
618 | goto exit; | 718 | goto exit; |
619 | } | 719 | } |
620 | client = &data->client; | ||
621 | i2c_set_clientdata(client, data); | ||
622 | client->addr = address; | 720 | client->addr = address; |
623 | client->adapter = adapter; | 721 | client->adapter = adapter; |
624 | client->driver = &f75375_driver; | 722 | client->driver = &f75375_legacy_driver; |
625 | 723 | ||
626 | if (kind < 0) { | 724 | if (kind < 0) { |
627 | u16 vendid = f75375_read16(client, F75375_REG_VENDOR); | 725 | u16 vendid = f75375_read16(client, F75375_REG_VENDOR); |
@@ -644,42 +742,42 @@ static int f75375_detect(struct i2c_adapter *adapter, int address, int kind) | |||
644 | } else if (kind == f75373) { | 742 | } else if (kind == f75373) { |
645 | name = "f75373"; | 743 | name = "f75373"; |
646 | } | 744 | } |
647 | |||
648 | dev_info(&adapter->dev, "found %s version: %02X\n", name, version); | 745 | dev_info(&adapter->dev, "found %s version: %02X\n", name, version); |
649 | strlcpy(client->name, name, I2C_NAME_SIZE); | 746 | strlcpy(client->name, name, I2C_NAME_SIZE); |
650 | data->kind = kind; | 747 | |
651 | mutex_init(&data->update_lock); | ||
652 | if ((err = i2c_attach_client(client))) | 748 | if ((err = i2c_attach_client(client))) |
653 | goto exit_free; | 749 | goto exit_free; |
654 | 750 | ||
655 | if ((err = sysfs_create_group(&client->dev.kobj, &f75375_group))) | 751 | if ((err = f75375_probe(client)) < 0) |
656 | goto exit_detach; | 752 | goto exit_detach; |
657 | 753 | ||
658 | data->hwmon_dev = hwmon_device_register(&client->dev); | ||
659 | if (IS_ERR(data->hwmon_dev)) { | ||
660 | err = PTR_ERR(data->hwmon_dev); | ||
661 | goto exit_remove; | ||
662 | } | ||
663 | |||
664 | return 0; | 754 | return 0; |
665 | 755 | ||
666 | exit_remove: | ||
667 | sysfs_remove_group(&client->dev.kobj, &f75375_group); | ||
668 | exit_detach: | 756 | exit_detach: |
669 | i2c_detach_client(client); | 757 | i2c_detach_client(client); |
670 | exit_free: | 758 | exit_free: |
671 | kfree(data); | 759 | kfree(client); |
672 | exit: | 760 | exit: |
673 | return err; | 761 | return err; |
674 | } | 762 | } |
675 | 763 | ||
676 | static int __init sensors_f75375_init(void) | 764 | static int __init sensors_f75375_init(void) |
677 | { | 765 | { |
678 | return i2c_add_driver(&f75375_driver); | 766 | int status; |
767 | status = i2c_add_driver(&f75375_driver); | ||
768 | if (status) | ||
769 | return status; | ||
770 | |||
771 | status = i2c_add_driver(&f75375_legacy_driver); | ||
772 | if (status) | ||
773 | i2c_del_driver(&f75375_driver); | ||
774 | |||
775 | return status; | ||
679 | } | 776 | } |
680 | 777 | ||
681 | static void __exit sensors_f75375_exit(void) | 778 | static void __exit sensors_f75375_exit(void) |
682 | { | 779 | { |
780 | i2c_del_driver(&f75375_legacy_driver); | ||
683 | i2c_del_driver(&f75375_driver); | 781 | i2c_del_driver(&f75375_driver); |
684 | } | 782 | } |
685 | 783 | ||
diff --git a/drivers/hwmon/i5k_amb.c b/drivers/hwmon/i5k_amb.c new file mode 100644 index 000000000000..6ac5c6f53585 --- /dev/null +++ b/drivers/hwmon/i5k_amb.c | |||
@@ -0,0 +1,552 @@ | |||
1 | /* | ||
2 | * A hwmon driver for the Intel 5000 series chipset FB-DIMM AMB | ||
3 | * temperature sensors | ||
4 | * Copyright (C) 2007 IBM | ||
5 | * | ||
6 | * Author: Darrick J. Wong <djwong@us.ibm.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | */ | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/jiffies.h> | ||
25 | #include <linux/hwmon.h> | ||
26 | #include <linux/hwmon-sysfs.h> | ||
27 | #include <linux/err.h> | ||
28 | #include <linux/mutex.h> | ||
29 | #include <linux/delay.h> | ||
30 | #include <linux/log2.h> | ||
31 | #include <linux/pci.h> | ||
32 | #include <linux/platform_device.h> | ||
33 | |||
34 | #define DRVNAME "i5k_amb" | ||
35 | |||
36 | #define I5K_REG_AMB_BASE_ADDR 0x48 | ||
37 | #define I5K_REG_AMB_LEN_ADDR 0x50 | ||
38 | #define I5K_REG_CHAN0_PRESENCE_ADDR 0x64 | ||
39 | #define I5K_REG_CHAN1_PRESENCE_ADDR 0x66 | ||
40 | |||
41 | #define AMB_REG_TEMP_MIN_ADDR 0x80 | ||
42 | #define AMB_REG_TEMP_MID_ADDR 0x81 | ||
43 | #define AMB_REG_TEMP_MAX_ADDR 0x82 | ||
44 | #define AMB_REG_TEMP_STATUS_ADDR 0x84 | ||
45 | #define AMB_REG_TEMP_ADDR 0x85 | ||
46 | |||
47 | #define AMB_CONFIG_SIZE 2048 | ||
48 | #define AMB_FUNC_3_OFFSET 768 | ||
49 | |||
50 | static unsigned long amb_reg_temp_status(unsigned int amb) | ||
51 | { | ||
52 | return AMB_FUNC_3_OFFSET + AMB_REG_TEMP_STATUS_ADDR + | ||
53 | AMB_CONFIG_SIZE * amb; | ||
54 | } | ||
55 | |||
56 | static unsigned long amb_reg_temp_min(unsigned int amb) | ||
57 | { | ||
58 | return AMB_FUNC_3_OFFSET + AMB_REG_TEMP_MIN_ADDR + | ||
59 | AMB_CONFIG_SIZE * amb; | ||
60 | } | ||
61 | |||
62 | static unsigned long amb_reg_temp_mid(unsigned int amb) | ||
63 | { | ||
64 | return AMB_FUNC_3_OFFSET + AMB_REG_TEMP_MID_ADDR + | ||
65 | AMB_CONFIG_SIZE * amb; | ||
66 | } | ||
67 | |||
68 | static unsigned long amb_reg_temp_max(unsigned int amb) | ||
69 | { | ||
70 | return AMB_FUNC_3_OFFSET + AMB_REG_TEMP_MAX_ADDR + | ||
71 | AMB_CONFIG_SIZE * amb; | ||
72 | } | ||
73 | |||
74 | static unsigned long amb_reg_temp(unsigned int amb) | ||
75 | { | ||
76 | return AMB_FUNC_3_OFFSET + AMB_REG_TEMP_ADDR + | ||
77 | AMB_CONFIG_SIZE * amb; | ||
78 | } | ||
79 | |||
80 | #define MAX_MEM_CHANNELS 4 | ||
81 | #define MAX_AMBS_PER_CHANNEL 16 | ||
82 | #define MAX_AMBS (MAX_MEM_CHANNELS * \ | ||
83 | MAX_AMBS_PER_CHANNEL) | ||
84 | /* | ||
85 | * Ugly hack: For some reason the highest bit is set if there | ||
86 | * are _any_ DIMMs in the channel. Attempting to read from | ||
87 | * this "high-order" AMB results in a memory bus error, so | ||
88 | * for now we'll just ignore that top bit, even though that | ||
89 | * might prevent us from seeing the 16th DIMM in the channel. | ||
90 | */ | ||
91 | #define REAL_MAX_AMBS_PER_CHANNEL 15 | ||
92 | #define KNOBS_PER_AMB 5 | ||
93 | |||
94 | static unsigned long amb_num_from_reg(unsigned int byte_num, unsigned int bit) | ||
95 | { | ||
96 | return byte_num * MAX_AMBS_PER_CHANNEL + bit; | ||
97 | } | ||
98 | |||
99 | #define AMB_SYSFS_NAME_LEN 16 | ||
100 | struct i5k_device_attribute { | ||
101 | struct sensor_device_attribute s_attr; | ||
102 | char name[AMB_SYSFS_NAME_LEN]; | ||
103 | }; | ||
104 | |||
105 | struct i5k_amb_data { | ||
106 | struct device *hwmon_dev; | ||
107 | |||
108 | unsigned long amb_base; | ||
109 | unsigned long amb_len; | ||
110 | u16 amb_present[MAX_MEM_CHANNELS]; | ||
111 | void __iomem *amb_mmio; | ||
112 | struct i5k_device_attribute *attrs; | ||
113 | unsigned int num_attrs; | ||
114 | }; | ||
115 | |||
116 | static ssize_t show_name(struct device *dev, struct device_attribute *devattr, | ||
117 | char *buf) | ||
118 | { | ||
119 | return sprintf(buf, "%s\n", DRVNAME); | ||
120 | } | ||
121 | |||
122 | |||
123 | static DEVICE_ATTR(name, S_IRUGO, show_name, NULL); | ||
124 | |||
125 | static struct platform_device *amb_pdev; | ||
126 | |||
127 | static u8 amb_read_byte(struct i5k_amb_data *data, unsigned long offset) | ||
128 | { | ||
129 | return ioread8(data->amb_mmio + offset); | ||
130 | } | ||
131 | |||
132 | static void amb_write_byte(struct i5k_amb_data *data, unsigned long offset, | ||
133 | u8 val) | ||
134 | { | ||
135 | iowrite8(val, data->amb_mmio + offset); | ||
136 | } | ||
137 | |||
138 | static ssize_t show_amb_alarm(struct device *dev, | ||
139 | struct device_attribute *devattr, | ||
140 | char *buf) | ||
141 | { | ||
142 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
143 | struct i5k_amb_data *data = dev_get_drvdata(dev); | ||
144 | |||
145 | if (!(amb_read_byte(data, amb_reg_temp_status(attr->index)) & 0x20) && | ||
146 | (amb_read_byte(data, amb_reg_temp_status(attr->index)) & 0x8)) | ||
147 | return sprintf(buf, "1\n"); | ||
148 | else | ||
149 | return sprintf(buf, "0\n"); | ||
150 | } | ||
151 | |||
152 | static ssize_t store_amb_min(struct device *dev, | ||
153 | struct device_attribute *devattr, | ||
154 | const char *buf, | ||
155 | size_t count) | ||
156 | { | ||
157 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
158 | struct i5k_amb_data *data = dev_get_drvdata(dev); | ||
159 | unsigned long temp = simple_strtoul(buf, NULL, 10) / 500; | ||
160 | |||
161 | if (temp > 255) | ||
162 | temp = 255; | ||
163 | |||
164 | amb_write_byte(data, amb_reg_temp_min(attr->index), temp); | ||
165 | return count; | ||
166 | } | ||
167 | |||
168 | static ssize_t store_amb_mid(struct device *dev, | ||
169 | struct device_attribute *devattr, | ||
170 | const char *buf, | ||
171 | size_t count) | ||
172 | { | ||
173 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
174 | struct i5k_amb_data *data = dev_get_drvdata(dev); | ||
175 | unsigned long temp = simple_strtoul(buf, NULL, 10) / 500; | ||
176 | |||
177 | if (temp > 255) | ||
178 | temp = 255; | ||
179 | |||
180 | amb_write_byte(data, amb_reg_temp_mid(attr->index), temp); | ||
181 | return count; | ||
182 | } | ||
183 | |||
184 | static ssize_t store_amb_max(struct device *dev, | ||
185 | struct device_attribute *devattr, | ||
186 | const char *buf, | ||
187 | size_t count) | ||
188 | { | ||
189 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
190 | struct i5k_amb_data *data = dev_get_drvdata(dev); | ||
191 | unsigned long temp = simple_strtoul(buf, NULL, 10) / 500; | ||
192 | |||
193 | if (temp > 255) | ||
194 | temp = 255; | ||
195 | |||
196 | amb_write_byte(data, amb_reg_temp_max(attr->index), temp); | ||
197 | return count; | ||
198 | } | ||
199 | |||
200 | static ssize_t show_amb_min(struct device *dev, | ||
201 | struct device_attribute *devattr, | ||
202 | char *buf) | ||
203 | { | ||
204 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
205 | struct i5k_amb_data *data = dev_get_drvdata(dev); | ||
206 | return sprintf(buf, "%d\n", | ||
207 | 500 * amb_read_byte(data, amb_reg_temp_min(attr->index))); | ||
208 | } | ||
209 | |||
210 | static ssize_t show_amb_mid(struct device *dev, | ||
211 | struct device_attribute *devattr, | ||
212 | char *buf) | ||
213 | { | ||
214 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
215 | struct i5k_amb_data *data = dev_get_drvdata(dev); | ||
216 | return sprintf(buf, "%d\n", | ||
217 | 500 * amb_read_byte(data, amb_reg_temp_mid(attr->index))); | ||
218 | } | ||
219 | |||
220 | static ssize_t show_amb_max(struct device *dev, | ||
221 | struct device_attribute *devattr, | ||
222 | char *buf) | ||
223 | { | ||
224 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
225 | struct i5k_amb_data *data = dev_get_drvdata(dev); | ||
226 | return sprintf(buf, "%d\n", | ||
227 | 500 * amb_read_byte(data, amb_reg_temp_max(attr->index))); | ||
228 | } | ||
229 | |||
230 | static ssize_t show_amb_temp(struct device *dev, | ||
231 | struct device_attribute *devattr, | ||
232 | char *buf) | ||
233 | { | ||
234 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
235 | struct i5k_amb_data *data = dev_get_drvdata(dev); | ||
236 | return sprintf(buf, "%d\n", | ||
237 | 500 * amb_read_byte(data, amb_reg_temp(attr->index))); | ||
238 | } | ||
239 | |||
240 | static int __devinit i5k_amb_hwmon_init(struct platform_device *pdev) | ||
241 | { | ||
242 | int i, j, k, d = 0; | ||
243 | u16 c; | ||
244 | int res = 0; | ||
245 | int num_ambs = 0; | ||
246 | struct i5k_amb_data *data = platform_get_drvdata(pdev); | ||
247 | |||
248 | /* Count the number of AMBs found */ | ||
249 | /* ignore the high-order bit, see "Ugly hack" comment above */ | ||
250 | for (i = 0; i < MAX_MEM_CHANNELS; i++) | ||
251 | num_ambs += hweight16(data->amb_present[i] & 0x7fff); | ||
252 | |||
253 | /* Set up sysfs stuff */ | ||
254 | data->attrs = kzalloc(sizeof(*data->attrs) * num_ambs * KNOBS_PER_AMB, | ||
255 | GFP_KERNEL); | ||
256 | if (!data->attrs) | ||
257 | return -ENOMEM; | ||
258 | data->num_attrs = 0; | ||
259 | |||
260 | for (i = 0; i < MAX_MEM_CHANNELS; i++) { | ||
261 | c = data->amb_present[i]; | ||
262 | for (j = 0; j < REAL_MAX_AMBS_PER_CHANNEL; j++, c >>= 1) { | ||
263 | struct i5k_device_attribute *iattr; | ||
264 | |||
265 | k = amb_num_from_reg(i, j); | ||
266 | if (!(c & 0x1)) | ||
267 | continue; | ||
268 | d++; | ||
269 | |||
270 | /* Temperature sysfs knob */ | ||
271 | iattr = data->attrs + data->num_attrs; | ||
272 | snprintf(iattr->name, AMB_SYSFS_NAME_LEN, | ||
273 | "temp%d_input", d); | ||
274 | iattr->s_attr.dev_attr.attr.name = iattr->name; | ||
275 | iattr->s_attr.dev_attr.attr.mode = S_IRUGO; | ||
276 | iattr->s_attr.dev_attr.show = show_amb_temp; | ||
277 | iattr->s_attr.index = k; | ||
278 | res = device_create_file(&pdev->dev, | ||
279 | &iattr->s_attr.dev_attr); | ||
280 | if (res) | ||
281 | goto exit_remove; | ||
282 | data->num_attrs++; | ||
283 | |||
284 | /* Temperature min sysfs knob */ | ||
285 | iattr = data->attrs + data->num_attrs; | ||
286 | snprintf(iattr->name, AMB_SYSFS_NAME_LEN, | ||
287 | "temp%d_min", d); | ||
288 | iattr->s_attr.dev_attr.attr.name = iattr->name; | ||
289 | iattr->s_attr.dev_attr.attr.mode = S_IWUSR | S_IRUGO; | ||
290 | iattr->s_attr.dev_attr.show = show_amb_min; | ||
291 | iattr->s_attr.dev_attr.store = store_amb_min; | ||
292 | iattr->s_attr.index = k; | ||
293 | res = device_create_file(&pdev->dev, | ||
294 | &iattr->s_attr.dev_attr); | ||
295 | if (res) | ||
296 | goto exit_remove; | ||
297 | data->num_attrs++; | ||
298 | |||
299 | /* Temperature mid sysfs knob */ | ||
300 | iattr = data->attrs + data->num_attrs; | ||
301 | snprintf(iattr->name, AMB_SYSFS_NAME_LEN, | ||
302 | "temp%d_mid", d); | ||
303 | iattr->s_attr.dev_attr.attr.name = iattr->name; | ||
304 | iattr->s_attr.dev_attr.attr.mode = S_IWUSR | S_IRUGO; | ||
305 | iattr->s_attr.dev_attr.show = show_amb_mid; | ||
306 | iattr->s_attr.dev_attr.store = store_amb_mid; | ||
307 | iattr->s_attr.index = k; | ||
308 | res = device_create_file(&pdev->dev, | ||
309 | &iattr->s_attr.dev_attr); | ||
310 | if (res) | ||
311 | goto exit_remove; | ||
312 | data->num_attrs++; | ||
313 | |||
314 | /* Temperature max sysfs knob */ | ||
315 | iattr = data->attrs + data->num_attrs; | ||
316 | snprintf(iattr->name, AMB_SYSFS_NAME_LEN, | ||
317 | "temp%d_max", d); | ||
318 | iattr->s_attr.dev_attr.attr.name = iattr->name; | ||
319 | iattr->s_attr.dev_attr.attr.mode = S_IWUSR | S_IRUGO; | ||
320 | iattr->s_attr.dev_attr.show = show_amb_max; | ||
321 | iattr->s_attr.dev_attr.store = store_amb_max; | ||
322 | iattr->s_attr.index = k; | ||
323 | res = device_create_file(&pdev->dev, | ||
324 | &iattr->s_attr.dev_attr); | ||
325 | if (res) | ||
326 | goto exit_remove; | ||
327 | data->num_attrs++; | ||
328 | |||
329 | /* Temperature alarm sysfs knob */ | ||
330 | iattr = data->attrs + data->num_attrs; | ||
331 | snprintf(iattr->name, AMB_SYSFS_NAME_LEN, | ||
332 | "temp%d_alarm", d); | ||
333 | iattr->s_attr.dev_attr.attr.name = iattr->name; | ||
334 | iattr->s_attr.dev_attr.attr.mode = S_IRUGO; | ||
335 | iattr->s_attr.dev_attr.show = show_amb_alarm; | ||
336 | iattr->s_attr.index = k; | ||
337 | res = device_create_file(&pdev->dev, | ||
338 | &iattr->s_attr.dev_attr); | ||
339 | if (res) | ||
340 | goto exit_remove; | ||
341 | data->num_attrs++; | ||
342 | } | ||
343 | } | ||
344 | |||
345 | res = device_create_file(&pdev->dev, &dev_attr_name); | ||
346 | if (res) | ||
347 | goto exit_remove; | ||
348 | |||
349 | data->hwmon_dev = hwmon_device_register(&pdev->dev); | ||
350 | if (IS_ERR(data->hwmon_dev)) { | ||
351 | res = PTR_ERR(data->hwmon_dev); | ||
352 | goto exit_remove; | ||
353 | } | ||
354 | |||
355 | return res; | ||
356 | |||
357 | exit_remove: | ||
358 | device_remove_file(&pdev->dev, &dev_attr_name); | ||
359 | for (i = 0; i < data->num_attrs; i++) | ||
360 | device_remove_file(&pdev->dev, &data->attrs[i].s_attr.dev_attr); | ||
361 | kfree(data->attrs); | ||
362 | |||
363 | return res; | ||
364 | } | ||
365 | |||
366 | static int __devinit i5k_amb_add(void) | ||
367 | { | ||
368 | int res = -ENODEV; | ||
369 | |||
370 | /* only ever going to be one of these */ | ||
371 | amb_pdev = platform_device_alloc(DRVNAME, 0); | ||
372 | if (!amb_pdev) | ||
373 | return -ENOMEM; | ||
374 | |||
375 | res = platform_device_add(amb_pdev); | ||
376 | if (res) | ||
377 | goto err; | ||
378 | return 0; | ||
379 | |||
380 | err: | ||
381 | platform_device_put(amb_pdev); | ||
382 | return res; | ||
383 | } | ||
384 | |||
385 | static int __devinit i5k_find_amb_registers(struct i5k_amb_data *data) | ||
386 | { | ||
387 | struct pci_dev *pcidev; | ||
388 | u32 val32; | ||
389 | int res = -ENODEV; | ||
390 | |||
391 | /* Find AMB register memory space */ | ||
392 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, | ||
393 | PCI_DEVICE_ID_INTEL_5000_ERR, | ||
394 | NULL); | ||
395 | if (!pcidev) | ||
396 | return -ENODEV; | ||
397 | |||
398 | if (pci_read_config_dword(pcidev, I5K_REG_AMB_BASE_ADDR, &val32)) | ||
399 | goto out; | ||
400 | data->amb_base = val32; | ||
401 | |||
402 | if (pci_read_config_dword(pcidev, I5K_REG_AMB_LEN_ADDR, &val32)) | ||
403 | goto out; | ||
404 | data->amb_len = val32; | ||
405 | |||
406 | /* Is it big enough? */ | ||
407 | if (data->amb_len < AMB_CONFIG_SIZE * MAX_AMBS) { | ||
408 | dev_err(&pcidev->dev, "AMB region too small!\n"); | ||
409 | goto out; | ||
410 | } | ||
411 | |||
412 | res = 0; | ||
413 | out: | ||
414 | pci_dev_put(pcidev); | ||
415 | return res; | ||
416 | } | ||
417 | |||
418 | static int __devinit i5k_channel_probe(u16 *amb_present, unsigned long dev_id) | ||
419 | { | ||
420 | struct pci_dev *pcidev; | ||
421 | u16 val16; | ||
422 | int res = -ENODEV; | ||
423 | |||
424 | /* Copy the DIMM presence map for these two channels */ | ||
425 | pcidev = pci_get_device(PCI_VENDOR_ID_INTEL, dev_id, NULL); | ||
426 | if (!pcidev) | ||
427 | return -ENODEV; | ||
428 | |||
429 | if (pci_read_config_word(pcidev, I5K_REG_CHAN0_PRESENCE_ADDR, &val16)) | ||
430 | goto out; | ||
431 | amb_present[0] = val16; | ||
432 | |||
433 | if (pci_read_config_word(pcidev, I5K_REG_CHAN1_PRESENCE_ADDR, &val16)) | ||
434 | goto out; | ||
435 | amb_present[1] = val16; | ||
436 | |||
437 | res = 0; | ||
438 | |||
439 | out: | ||
440 | pci_dev_put(pcidev); | ||
441 | return res; | ||
442 | } | ||
443 | |||
444 | static int __devinit i5k_amb_probe(struct platform_device *pdev) | ||
445 | { | ||
446 | struct i5k_amb_data *data; | ||
447 | struct resource *reso; | ||
448 | int res = -ENODEV; | ||
449 | |||
450 | data = kzalloc(sizeof(*data), GFP_KERNEL); | ||
451 | if (!data) | ||
452 | return -ENOMEM; | ||
453 | |||
454 | /* Figure out where the AMB registers live */ | ||
455 | res = i5k_find_amb_registers(data); | ||
456 | if (res) | ||
457 | goto err; | ||
458 | |||
459 | /* Copy the DIMM presence map for the first two channels */ | ||
460 | res = i5k_channel_probe(&data->amb_present[0], | ||
461 | PCI_DEVICE_ID_INTEL_5000_FBD0); | ||
462 | if (res) | ||
463 | goto err; | ||
464 | |||
465 | /* Copy the DIMM presence map for the optional second two channels */ | ||
466 | i5k_channel_probe(&data->amb_present[2], | ||
467 | PCI_DEVICE_ID_INTEL_5000_FBD1); | ||
468 | |||
469 | /* Set up resource regions */ | ||
470 | reso = request_mem_region(data->amb_base, data->amb_len, DRVNAME); | ||
471 | if (!reso) { | ||
472 | res = -EBUSY; | ||
473 | goto err; | ||
474 | } | ||
475 | |||
476 | data->amb_mmio = ioremap_nocache(data->amb_base, data->amb_len); | ||
477 | if (!data->amb_mmio) { | ||
478 | res = -EBUSY; | ||
479 | goto err_map_failed; | ||
480 | } | ||
481 | |||
482 | platform_set_drvdata(pdev, data); | ||
483 | |||
484 | res = i5k_amb_hwmon_init(pdev); | ||
485 | if (res) | ||
486 | goto err_init_failed; | ||
487 | |||
488 | return res; | ||
489 | |||
490 | err_init_failed: | ||
491 | iounmap(data->amb_mmio); | ||
492 | platform_set_drvdata(pdev, NULL); | ||
493 | err_map_failed: | ||
494 | release_mem_region(data->amb_base, data->amb_len); | ||
495 | err: | ||
496 | kfree(data); | ||
497 | return res; | ||
498 | } | ||
499 | |||
500 | static int __devexit i5k_amb_remove(struct platform_device *pdev) | ||
501 | { | ||
502 | int i; | ||
503 | struct i5k_amb_data *data = platform_get_drvdata(pdev); | ||
504 | |||
505 | hwmon_device_unregister(data->hwmon_dev); | ||
506 | device_remove_file(&pdev->dev, &dev_attr_name); | ||
507 | for (i = 0; i < data->num_attrs; i++) | ||
508 | device_remove_file(&pdev->dev, &data->attrs[i].s_attr.dev_attr); | ||
509 | kfree(data->attrs); | ||
510 | iounmap(data->amb_mmio); | ||
511 | release_mem_region(data->amb_base, data->amb_len); | ||
512 | platform_set_drvdata(pdev, NULL); | ||
513 | kfree(data); | ||
514 | return 0; | ||
515 | } | ||
516 | |||
517 | static struct platform_driver i5k_amb_driver = { | ||
518 | .driver = { | ||
519 | .owner = THIS_MODULE, | ||
520 | .name = DRVNAME, | ||
521 | }, | ||
522 | .probe = i5k_amb_probe, | ||
523 | .remove = __devexit_p(i5k_amb_remove), | ||
524 | }; | ||
525 | |||
526 | static int __init i5k_amb_init(void) | ||
527 | { | ||
528 | int res; | ||
529 | |||
530 | res = platform_driver_register(&i5k_amb_driver); | ||
531 | if (res) | ||
532 | return res; | ||
533 | |||
534 | res = i5k_amb_add(); | ||
535 | if (res) | ||
536 | platform_driver_unregister(&i5k_amb_driver); | ||
537 | |||
538 | return res; | ||
539 | } | ||
540 | |||
541 | static void __exit i5k_amb_exit(void) | ||
542 | { | ||
543 | platform_device_unregister(amb_pdev); | ||
544 | platform_driver_unregister(&i5k_amb_driver); | ||
545 | } | ||
546 | |||
547 | MODULE_AUTHOR("Darrick J. Wong <djwong@us.ibm.com>"); | ||
548 | MODULE_DESCRIPTION("Intel 5000 chipset FB-DIMM AMB temperature sensor"); | ||
549 | MODULE_LICENSE("GPL"); | ||
550 | |||
551 | module_init(i5k_amb_init); | ||
552 | module_exit(i5k_amb_exit); | ||
diff --git a/drivers/hwmon/ibmpex.c b/drivers/hwmon/ibmpex.c index c462824ffccf..9c9cdb0685e4 100644 --- a/drivers/hwmon/ibmpex.c +++ b/drivers/hwmon/ibmpex.c | |||
@@ -140,10 +140,10 @@ static int ibmpex_send_message(struct ibmpex_bmc_data *data) | |||
140 | 140 | ||
141 | return 0; | 141 | return 0; |
142 | out1: | 142 | out1: |
143 | printk(KERN_ERR "%s: request_settime=%x\n", __FUNCTION__, err); | 143 | dev_err(data->bmc_device, "request_settime=%x\n", err); |
144 | return err; | 144 | return err; |
145 | out: | 145 | out: |
146 | printk(KERN_ERR "%s: validate_addr=%x\n", __FUNCTION__, err); | 146 | dev_err(data->bmc_device, "validate_addr=%x\n", err); |
147 | return err; | 147 | return err; |
148 | } | 148 | } |
149 | 149 | ||
@@ -161,14 +161,14 @@ static int ibmpex_ver_check(struct ibmpex_bmc_data *data) | |||
161 | data->sensor_major = data->rx_msg_data[0]; | 161 | data->sensor_major = data->rx_msg_data[0]; |
162 | data->sensor_minor = data->rx_msg_data[1]; | 162 | data->sensor_minor = data->rx_msg_data[1]; |
163 | 163 | ||
164 | printk(KERN_INFO DRVNAME ": Found BMC with sensor interface " | 164 | dev_info(data->bmc_device, "Found BMC with sensor interface " |
165 | "v%d.%d %d-%02d-%02d on interface %d\n", | 165 | "v%d.%d %d-%02d-%02d on interface %d\n", |
166 | data->sensor_major, | 166 | data->sensor_major, |
167 | data->sensor_minor, | 167 | data->sensor_minor, |
168 | extract_value(data->rx_msg_data, 2), | 168 | extract_value(data->rx_msg_data, 2), |
169 | data->rx_msg_data[4], | 169 | data->rx_msg_data[4], |
170 | data->rx_msg_data[5], | 170 | data->rx_msg_data[5], |
171 | data->interface); | 171 | data->interface); |
172 | 172 | ||
173 | return 0; | 173 | return 0; |
174 | } | 174 | } |
@@ -212,8 +212,8 @@ static int ibmpex_query_sensor_data(struct ibmpex_bmc_data *data, int sensor) | |||
212 | wait_for_completion(&data->read_complete); | 212 | wait_for_completion(&data->read_complete); |
213 | 213 | ||
214 | if (data->rx_result || data->rx_msg_len < 26) { | 214 | if (data->rx_result || data->rx_msg_len < 26) { |
215 | printk(KERN_ERR "Error reading sensor %d, please check.\n", | 215 | dev_err(data->bmc_device, "Error reading sensor %d.\n", |
216 | sensor); | 216 | sensor); |
217 | return -ENOENT; | 217 | return -ENOENT; |
218 | } | 218 | } |
219 | 219 | ||
@@ -456,8 +456,7 @@ static void ibmpex_register_bmc(int iface, struct device *dev) | |||
456 | 456 | ||
457 | data = kzalloc(sizeof(*data), GFP_KERNEL); | 457 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
458 | if (!data) { | 458 | if (!data) { |
459 | printk(KERN_ERR DRVNAME ": Insufficient memory for BMC " | 459 | dev_err(dev, "Insufficient memory for BMC interface.\n"); |
460 | "interface %d.\n", data->interface); | ||
461 | return; | 460 | return; |
462 | } | 461 | } |
463 | 462 | ||
@@ -471,9 +470,8 @@ static void ibmpex_register_bmc(int iface, struct device *dev) | |||
471 | err = ipmi_create_user(data->interface, &driver_data.ipmi_hndlrs, | 470 | err = ipmi_create_user(data->interface, &driver_data.ipmi_hndlrs, |
472 | data, &data->user); | 471 | data, &data->user); |
473 | if (err < 0) { | 472 | if (err < 0) { |
474 | printk(KERN_ERR DRVNAME ": Error, unable to register user with " | 473 | dev_err(dev, "Unable to register user with IPMI " |
475 | "ipmi interface %d\n", | 474 | "interface %d\n", data->interface); |
476 | data->interface); | ||
477 | goto out; | 475 | goto out; |
478 | } | 476 | } |
479 | 477 | ||
@@ -495,9 +493,9 @@ static void ibmpex_register_bmc(int iface, struct device *dev) | |||
495 | data->hwmon_dev = hwmon_device_register(data->bmc_device); | 493 | data->hwmon_dev = hwmon_device_register(data->bmc_device); |
496 | 494 | ||
497 | if (IS_ERR(data->hwmon_dev)) { | 495 | if (IS_ERR(data->hwmon_dev)) { |
498 | printk(KERN_ERR DRVNAME ": Error, unable to register hwmon " | 496 | dev_err(data->bmc_device, "Unable to register hwmon " |
499 | "class device for interface %d\n", | 497 | "device for IPMI interface %d\n", |
500 | data->interface); | 498 | data->interface); |
501 | goto out_user; | 499 | goto out_user; |
502 | } | 500 | } |
503 | 501 | ||
@@ -508,7 +506,7 @@ static void ibmpex_register_bmc(int iface, struct device *dev) | |||
508 | /* Now go find all the sensors */ | 506 | /* Now go find all the sensors */ |
509 | err = ibmpex_find_sensors(data); | 507 | err = ibmpex_find_sensors(data); |
510 | if (err) { | 508 | if (err) { |
511 | printk(KERN_ERR "Error %d allocating memory\n", err); | 509 | dev_err(data->bmc_device, "Error %d finding sensors\n", err); |
512 | goto out_register; | 510 | goto out_register; |
513 | } | 511 | } |
514 | 512 | ||
@@ -561,10 +559,10 @@ static void ibmpex_msg_handler(struct ipmi_recv_msg *msg, void *user_msg_data) | |||
561 | struct ibmpex_bmc_data *data = (struct ibmpex_bmc_data *)user_msg_data; | 559 | struct ibmpex_bmc_data *data = (struct ibmpex_bmc_data *)user_msg_data; |
562 | 560 | ||
563 | if (msg->msgid != data->tx_msgid) { | 561 | if (msg->msgid != data->tx_msgid) { |
564 | printk(KERN_ERR "Received msgid (%02x) and transmitted " | 562 | dev_err(data->bmc_device, "Mismatch between received msgid " |
565 | "msgid (%02x) mismatch!\n", | 563 | "(%02x) and transmitted msgid (%02x)!\n", |
566 | (int)msg->msgid, | 564 | (int)msg->msgid, |
567 | (int)data->tx_msgid); | 565 | (int)data->tx_msgid); |
568 | ipmi_free_recv_msg(msg); | 566 | ipmi_free_recv_msg(msg); |
569 | return; | 567 | return; |
570 | } | 568 | } |
diff --git a/drivers/hwmon/lm70.c b/drivers/hwmon/lm70.c index dd366889ce9b..d435f003292d 100644 --- a/drivers/hwmon/lm70.c +++ b/drivers/hwmon/lm70.c | |||
@@ -31,14 +31,15 @@ | |||
31 | #include <linux/err.h> | 31 | #include <linux/err.h> |
32 | #include <linux/sysfs.h> | 32 | #include <linux/sysfs.h> |
33 | #include <linux/hwmon.h> | 33 | #include <linux/hwmon.h> |
34 | #include <linux/mutex.h> | ||
34 | #include <linux/spi/spi.h> | 35 | #include <linux/spi/spi.h> |
35 | #include <asm/semaphore.h> | 36 | |
36 | 37 | ||
37 | #define DRVNAME "lm70" | 38 | #define DRVNAME "lm70" |
38 | 39 | ||
39 | struct lm70 { | 40 | struct lm70 { |
40 | struct device *hwmon_dev; | 41 | struct device *hwmon_dev; |
41 | struct semaphore sem; | 42 | struct mutex lock; |
42 | }; | 43 | }; |
43 | 44 | ||
44 | /* sysfs hook function */ | 45 | /* sysfs hook function */ |
@@ -51,7 +52,7 @@ static ssize_t lm70_sense_temp(struct device *dev, | |||
51 | s16 raw=0; | 52 | s16 raw=0; |
52 | struct lm70 *p_lm70 = dev_get_drvdata(&spi->dev); | 53 | struct lm70 *p_lm70 = dev_get_drvdata(&spi->dev); |
53 | 54 | ||
54 | if (down_interruptible(&p_lm70->sem)) | 55 | if (mutex_lock_interruptible(&p_lm70->lock)) |
55 | return -ERESTARTSYS; | 56 | return -ERESTARTSYS; |
56 | 57 | ||
57 | /* | 58 | /* |
@@ -83,7 +84,7 @@ static ssize_t lm70_sense_temp(struct device *dev, | |||
83 | val = ((int)raw/32) * 250; | 84 | val = ((int)raw/32) * 250; |
84 | status = sprintf(buf, "%d\n", val); /* millidegrees Celsius */ | 85 | status = sprintf(buf, "%d\n", val); /* millidegrees Celsius */ |
85 | out: | 86 | out: |
86 | up(&p_lm70->sem); | 87 | mutex_unlock(&p_lm70->lock); |
87 | return status; | 88 | return status; |
88 | } | 89 | } |
89 | 90 | ||
@@ -112,7 +113,7 @@ static int __devinit lm70_probe(struct spi_device *spi) | |||
112 | if (!p_lm70) | 113 | if (!p_lm70) |
113 | return -ENOMEM; | 114 | return -ENOMEM; |
114 | 115 | ||
115 | init_MUTEX(&p_lm70->sem); | 116 | mutex_init(&p_lm70->lock); |
116 | 117 | ||
117 | /* sysfs hook */ | 118 | /* sysfs hook */ |
118 | p_lm70->hwmon_dev = hwmon_device_register(&spi->dev); | 119 | p_lm70->hwmon_dev = hwmon_device_register(&spi->dev); |
diff --git a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c index 7e2d9787babc..a276806f3d53 100644 --- a/drivers/hwmon/sis5595.c +++ b/drivers/hwmon/sis5595.c | |||
@@ -435,6 +435,22 @@ static ssize_t show_alarms(struct device *dev, struct device_attribute *attr, ch | |||
435 | } | 435 | } |
436 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); | 436 | static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL); |
437 | 437 | ||
438 | static ssize_t show_alarm(struct device *dev, struct device_attribute *da, | ||
439 | char *buf) | ||
440 | { | ||
441 | struct sis5595_data *data = sis5595_update_device(dev); | ||
442 | int nr = to_sensor_dev_attr(da)->index; | ||
443 | return sprintf(buf, "%u\n", (data->alarms >> nr) & 1); | ||
444 | } | ||
445 | static SENSOR_DEVICE_ATTR(in0_alarm, S_IRUGO, show_alarm, NULL, 0); | ||
446 | static SENSOR_DEVICE_ATTR(in1_alarm, S_IRUGO, show_alarm, NULL, 1); | ||
447 | static SENSOR_DEVICE_ATTR(in2_alarm, S_IRUGO, show_alarm, NULL, 2); | ||
448 | static SENSOR_DEVICE_ATTR(in3_alarm, S_IRUGO, show_alarm, NULL, 3); | ||
449 | static SENSOR_DEVICE_ATTR(in4_alarm, S_IRUGO, show_alarm, NULL, 15); | ||
450 | static SENSOR_DEVICE_ATTR(fan1_alarm, S_IRUGO, show_alarm, NULL, 6); | ||
451 | static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7); | ||
452 | static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 15); | ||
453 | |||
438 | static ssize_t show_name(struct device *dev, struct device_attribute *attr, | 454 | static ssize_t show_name(struct device *dev, struct device_attribute *attr, |
439 | char *buf) | 455 | char *buf) |
440 | { | 456 | { |
@@ -447,22 +463,28 @@ static struct attribute *sis5595_attributes[] = { | |||
447 | &sensor_dev_attr_in0_input.dev_attr.attr, | 463 | &sensor_dev_attr_in0_input.dev_attr.attr, |
448 | &sensor_dev_attr_in0_min.dev_attr.attr, | 464 | &sensor_dev_attr_in0_min.dev_attr.attr, |
449 | &sensor_dev_attr_in0_max.dev_attr.attr, | 465 | &sensor_dev_attr_in0_max.dev_attr.attr, |
466 | &sensor_dev_attr_in0_alarm.dev_attr.attr, | ||
450 | &sensor_dev_attr_in1_input.dev_attr.attr, | 467 | &sensor_dev_attr_in1_input.dev_attr.attr, |
451 | &sensor_dev_attr_in1_min.dev_attr.attr, | 468 | &sensor_dev_attr_in1_min.dev_attr.attr, |
452 | &sensor_dev_attr_in1_max.dev_attr.attr, | 469 | &sensor_dev_attr_in1_max.dev_attr.attr, |
470 | &sensor_dev_attr_in1_alarm.dev_attr.attr, | ||
453 | &sensor_dev_attr_in2_input.dev_attr.attr, | 471 | &sensor_dev_attr_in2_input.dev_attr.attr, |
454 | &sensor_dev_attr_in2_min.dev_attr.attr, | 472 | &sensor_dev_attr_in2_min.dev_attr.attr, |
455 | &sensor_dev_attr_in2_max.dev_attr.attr, | 473 | &sensor_dev_attr_in2_max.dev_attr.attr, |
474 | &sensor_dev_attr_in2_alarm.dev_attr.attr, | ||
456 | &sensor_dev_attr_in3_input.dev_attr.attr, | 475 | &sensor_dev_attr_in3_input.dev_attr.attr, |
457 | &sensor_dev_attr_in3_min.dev_attr.attr, | 476 | &sensor_dev_attr_in3_min.dev_attr.attr, |
458 | &sensor_dev_attr_in3_max.dev_attr.attr, | 477 | &sensor_dev_attr_in3_max.dev_attr.attr, |
478 | &sensor_dev_attr_in3_alarm.dev_attr.attr, | ||
459 | 479 | ||
460 | &sensor_dev_attr_fan1_input.dev_attr.attr, | 480 | &sensor_dev_attr_fan1_input.dev_attr.attr, |
461 | &sensor_dev_attr_fan1_min.dev_attr.attr, | 481 | &sensor_dev_attr_fan1_min.dev_attr.attr, |
462 | &sensor_dev_attr_fan1_div.dev_attr.attr, | 482 | &sensor_dev_attr_fan1_div.dev_attr.attr, |
483 | &sensor_dev_attr_fan1_alarm.dev_attr.attr, | ||
463 | &sensor_dev_attr_fan2_input.dev_attr.attr, | 484 | &sensor_dev_attr_fan2_input.dev_attr.attr, |
464 | &sensor_dev_attr_fan2_min.dev_attr.attr, | 485 | &sensor_dev_attr_fan2_min.dev_attr.attr, |
465 | &sensor_dev_attr_fan2_div.dev_attr.attr, | 486 | &sensor_dev_attr_fan2_div.dev_attr.attr, |
487 | &sensor_dev_attr_fan2_alarm.dev_attr.attr, | ||
466 | 488 | ||
467 | &dev_attr_alarms.attr, | 489 | &dev_attr_alarms.attr, |
468 | &dev_attr_name.attr, | 490 | &dev_attr_name.attr, |
@@ -473,19 +495,28 @@ static const struct attribute_group sis5595_group = { | |||
473 | .attrs = sis5595_attributes, | 495 | .attrs = sis5595_attributes, |
474 | }; | 496 | }; |
475 | 497 | ||
476 | static struct attribute *sis5595_attributes_opt[] = { | 498 | static struct attribute *sis5595_attributes_in4[] = { |
477 | &sensor_dev_attr_in4_input.dev_attr.attr, | 499 | &sensor_dev_attr_in4_input.dev_attr.attr, |
478 | &sensor_dev_attr_in4_min.dev_attr.attr, | 500 | &sensor_dev_attr_in4_min.dev_attr.attr, |
479 | &sensor_dev_attr_in4_max.dev_attr.attr, | 501 | &sensor_dev_attr_in4_max.dev_attr.attr, |
502 | &sensor_dev_attr_in4_alarm.dev_attr.attr, | ||
503 | NULL | ||
504 | }; | ||
505 | |||
506 | static const struct attribute_group sis5595_group_in4 = { | ||
507 | .attrs = sis5595_attributes_in4, | ||
508 | }; | ||
480 | 509 | ||
510 | static struct attribute *sis5595_attributes_temp1[] = { | ||
481 | &dev_attr_temp1_input.attr, | 511 | &dev_attr_temp1_input.attr, |
482 | &dev_attr_temp1_max.attr, | 512 | &dev_attr_temp1_max.attr, |
483 | &dev_attr_temp1_max_hyst.attr, | 513 | &dev_attr_temp1_max_hyst.attr, |
514 | &sensor_dev_attr_temp1_alarm.dev_attr.attr, | ||
484 | NULL | 515 | NULL |
485 | }; | 516 | }; |
486 | 517 | ||
487 | static const struct attribute_group sis5595_group_opt = { | 518 | static const struct attribute_group sis5595_group_temp1 = { |
488 | .attrs = sis5595_attributes_opt, | 519 | .attrs = sis5595_attributes_temp1, |
489 | }; | 520 | }; |
490 | 521 | ||
491 | /* This is called when the module is loaded */ | 522 | /* This is called when the module is loaded */ |
@@ -540,20 +571,12 @@ static int __devinit sis5595_probe(struct platform_device *pdev) | |||
540 | if ((err = sysfs_create_group(&pdev->dev.kobj, &sis5595_group))) | 571 | if ((err = sysfs_create_group(&pdev->dev.kobj, &sis5595_group))) |
541 | goto exit_free; | 572 | goto exit_free; |
542 | if (data->maxins == 4) { | 573 | if (data->maxins == 4) { |
543 | if ((err = device_create_file(&pdev->dev, | 574 | if ((err = sysfs_create_group(&pdev->dev.kobj, |
544 | &sensor_dev_attr_in4_input.dev_attr)) | 575 | &sis5595_group_in4))) |
545 | || (err = device_create_file(&pdev->dev, | ||
546 | &sensor_dev_attr_in4_min.dev_attr)) | ||
547 | || (err = device_create_file(&pdev->dev, | ||
548 | &sensor_dev_attr_in4_max.dev_attr))) | ||
549 | goto exit_remove_files; | 576 | goto exit_remove_files; |
550 | } else { | 577 | } else { |
551 | if ((err = device_create_file(&pdev->dev, | 578 | if ((err = sysfs_create_group(&pdev->dev.kobj, |
552 | &dev_attr_temp1_input)) | 579 | &sis5595_group_temp1))) |
553 | || (err = device_create_file(&pdev->dev, | ||
554 | &dev_attr_temp1_max)) | ||
555 | || (err = device_create_file(&pdev->dev, | ||
556 | &dev_attr_temp1_max_hyst))) | ||
557 | goto exit_remove_files; | 580 | goto exit_remove_files; |
558 | } | 581 | } |
559 | 582 | ||
@@ -567,7 +590,8 @@ static int __devinit sis5595_probe(struct platform_device *pdev) | |||
567 | 590 | ||
568 | exit_remove_files: | 591 | exit_remove_files: |
569 | sysfs_remove_group(&pdev->dev.kobj, &sis5595_group); | 592 | sysfs_remove_group(&pdev->dev.kobj, &sis5595_group); |
570 | sysfs_remove_group(&pdev->dev.kobj, &sis5595_group_opt); | 593 | sysfs_remove_group(&pdev->dev.kobj, &sis5595_group_in4); |
594 | sysfs_remove_group(&pdev->dev.kobj, &sis5595_group_temp1); | ||
571 | exit_free: | 595 | exit_free: |
572 | kfree(data); | 596 | kfree(data); |
573 | exit_release: | 597 | exit_release: |
@@ -582,7 +606,8 @@ static int __devexit sis5595_remove(struct platform_device *pdev) | |||
582 | 606 | ||
583 | hwmon_device_unregister(data->hwmon_dev); | 607 | hwmon_device_unregister(data->hwmon_dev); |
584 | sysfs_remove_group(&pdev->dev.kobj, &sis5595_group); | 608 | sysfs_remove_group(&pdev->dev.kobj, &sis5595_group); |
585 | sysfs_remove_group(&pdev->dev.kobj, &sis5595_group_opt); | 609 | sysfs_remove_group(&pdev->dev.kobj, &sis5595_group_in4); |
610 | sysfs_remove_group(&pdev->dev.kobj, &sis5595_group_temp1); | ||
586 | 611 | ||
587 | release_region(data->addr, SIS5595_EXTENT); | 612 | release_region(data->addr, SIS5595_EXTENT); |
588 | platform_set_drvdata(pdev, NULL); | 613 | platform_set_drvdata(pdev, NULL); |
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c index 20ae425a1980..879d0a6544cc 100644 --- a/drivers/hwmon/w83627hf.c +++ b/drivers/hwmon/w83627hf.c | |||
@@ -170,20 +170,16 @@ superio_exit(void) | |||
170 | #define W83781D_REG_IN(nr) ((nr < 7) ? (0x20 + (nr)) : \ | 170 | #define W83781D_REG_IN(nr) ((nr < 7) ? (0x20 + (nr)) : \ |
171 | (0x550 + (nr) - 7)) | 171 | (0x550 + (nr) - 7)) |
172 | 172 | ||
173 | #define W83781D_REG_FAN_MIN(nr) (0x3a + (nr)) | 173 | /* nr:0-2 for fans:1-3 */ |
174 | #define W83781D_REG_FAN(nr) (0x27 + (nr)) | 174 | #define W83627HF_REG_FAN_MIN(nr) (0x3b + (nr)) |
175 | 175 | #define W83627HF_REG_FAN(nr) (0x28 + (nr)) | |
176 | #define W83781D_REG_TEMP2_CONFIG 0x152 | 176 | |
177 | #define W83781D_REG_TEMP3_CONFIG 0x252 | 177 | #define W83627HF_REG_TEMP2_CONFIG 0x152 |
178 | #define W83781D_REG_TEMP(nr) ((nr == 3) ? (0x0250) : \ | 178 | #define W83627HF_REG_TEMP3_CONFIG 0x252 |
179 | ((nr == 2) ? (0x0150) : \ | 179 | /* these are zero-based, unlike config constants above */ |
180 | (0x27))) | 180 | static const u16 w83627hf_reg_temp[] = { 0x27, 0x150, 0x250 }; |
181 | #define W83781D_REG_TEMP_HYST(nr) ((nr == 3) ? (0x253) : \ | 181 | static const u16 w83627hf_reg_temp_hyst[] = { 0x3A, 0x153, 0x253 }; |
182 | ((nr == 2) ? (0x153) : \ | 182 | static const u16 w83627hf_reg_temp_over[] = { 0x39, 0x155, 0x255 }; |
183 | (0x3A))) | ||
184 | #define W83781D_REG_TEMP_OVER(nr) ((nr == 3) ? (0x255) : \ | ||
185 | ((nr == 2) ? (0x155) : \ | ||
186 | (0x39))) | ||
187 | 183 | ||
188 | #define W83781D_REG_BANK 0x4E | 184 | #define W83781D_REG_BANK 0x4E |
189 | 185 | ||
@@ -360,12 +356,9 @@ struct w83627hf_data { | |||
360 | u8 in_min[9]; /* Register value */ | 356 | u8 in_min[9]; /* Register value */ |
361 | u8 fan[3]; /* Register value */ | 357 | u8 fan[3]; /* Register value */ |
362 | u8 fan_min[3]; /* Register value */ | 358 | u8 fan_min[3]; /* Register value */ |
363 | u8 temp; | 359 | u16 temp[3]; /* Register value */ |
364 | u8 temp_max; /* Register value */ | 360 | u16 temp_max[3]; /* Register value */ |
365 | u8 temp_max_hyst; /* Register value */ | 361 | u16 temp_max_hyst[3]; /* Register value */ |
366 | u16 temp_add[2]; /* Register value */ | ||
367 | u16 temp_max_add[2]; /* Register value */ | ||
368 | u16 temp_max_hyst_add[2]; /* Register value */ | ||
369 | u8 fan_div[3]; /* Register encoding, shifted right */ | 362 | u8 fan_div[3]; /* Register encoding, shifted right */ |
370 | u8 vid; /* Register encoding, combined */ | 363 | u8 vid; /* Register encoding, combined */ |
371 | u32 alarms; /* Register encoding, combined */ | 364 | u32 alarms; /* Register encoding, combined */ |
@@ -590,7 +583,7 @@ store_fan_min(struct device *dev, struct device_attribute *devattr, | |||
590 | 583 | ||
591 | mutex_lock(&data->update_lock); | 584 | mutex_lock(&data->update_lock); |
592 | data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); | 585 | data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr])); |
593 | w83627hf_write_value(data, W83781D_REG_FAN_MIN(nr+1), | 586 | w83627hf_write_value(data, W83627HF_REG_FAN_MIN(nr), |
594 | data->fan_min[nr]); | 587 | data->fan_min[nr]); |
595 | 588 | ||
596 | mutex_unlock(&data->update_lock); | 589 | mutex_unlock(&data->update_lock); |
@@ -611,12 +604,10 @@ show_temp(struct device *dev, struct device_attribute *devattr, char *buf) | |||
611 | { | 604 | { |
612 | int nr = to_sensor_dev_attr(devattr)->index; | 605 | int nr = to_sensor_dev_attr(devattr)->index; |
613 | struct w83627hf_data *data = w83627hf_update_device(dev); | 606 | struct w83627hf_data *data = w83627hf_update_device(dev); |
614 | if (nr >= 2) { /* TEMP2 and TEMP3 */ | 607 | |
615 | return sprintf(buf, "%ld\n", | 608 | u16 tmp = data->temp[nr]; |
616 | (long)LM75_TEMP_FROM_REG(data->temp_add[nr-2])); | 609 | return sprintf(buf, "%ld\n", (nr) ? (long) LM75_TEMP_FROM_REG(tmp) |
617 | } else { /* TEMP1 */ | 610 | : (long) TEMP_FROM_REG(tmp)); |
618 | return sprintf(buf, "%ld\n", (long)TEMP_FROM_REG(data->temp)); | ||
619 | } | ||
620 | } | 611 | } |
621 | 612 | ||
622 | static ssize_t | 613 | static ssize_t |
@@ -625,13 +616,10 @@ show_temp_max(struct device *dev, struct device_attribute *devattr, | |||
625 | { | 616 | { |
626 | int nr = to_sensor_dev_attr(devattr)->index; | 617 | int nr = to_sensor_dev_attr(devattr)->index; |
627 | struct w83627hf_data *data = w83627hf_update_device(dev); | 618 | struct w83627hf_data *data = w83627hf_update_device(dev); |
628 | if (nr >= 2) { /* TEMP2 and TEMP3 */ | 619 | |
629 | return sprintf(buf, "%ld\n", | 620 | u16 tmp = data->temp_max[nr]; |
630 | (long)LM75_TEMP_FROM_REG(data->temp_max_add[nr-2])); | 621 | return sprintf(buf, "%ld\n", (nr) ? (long) LM75_TEMP_FROM_REG(tmp) |
631 | } else { /* TEMP1 */ | 622 | : (long) TEMP_FROM_REG(tmp)); |
632 | return sprintf(buf, "%ld\n", | ||
633 | (long)TEMP_FROM_REG(data->temp_max)); | ||
634 | } | ||
635 | } | 623 | } |
636 | 624 | ||
637 | static ssize_t | 625 | static ssize_t |
@@ -640,13 +628,10 @@ show_temp_max_hyst(struct device *dev, struct device_attribute *devattr, | |||
640 | { | 628 | { |
641 | int nr = to_sensor_dev_attr(devattr)->index; | 629 | int nr = to_sensor_dev_attr(devattr)->index; |
642 | struct w83627hf_data *data = w83627hf_update_device(dev); | 630 | struct w83627hf_data *data = w83627hf_update_device(dev); |
643 | if (nr >= 2) { /* TEMP2 and TEMP3 */ | 631 | |
644 | return sprintf(buf, "%ld\n", | 632 | u16 tmp = data->temp_max_hyst[nr]; |
645 | (long)LM75_TEMP_FROM_REG(data->temp_max_hyst_add[nr-2])); | 633 | return sprintf(buf, "%ld\n", (nr) ? (long) LM75_TEMP_FROM_REG(tmp) |
646 | } else { /* TEMP1 */ | 634 | : (long) TEMP_FROM_REG(tmp)); |
647 | return sprintf(buf, "%ld\n", | ||
648 | (long)TEMP_FROM_REG(data->temp_max_hyst)); | ||
649 | } | ||
650 | } | 635 | } |
651 | 636 | ||
652 | static ssize_t | 637 | static ssize_t |
@@ -656,18 +641,11 @@ store_temp_max(struct device *dev, struct device_attribute *devattr, | |||
656 | int nr = to_sensor_dev_attr(devattr)->index; | 641 | int nr = to_sensor_dev_attr(devattr)->index; |
657 | struct w83627hf_data *data = dev_get_drvdata(dev); | 642 | struct w83627hf_data *data = dev_get_drvdata(dev); |
658 | long val = simple_strtol(buf, NULL, 10); | 643 | long val = simple_strtol(buf, NULL, 10); |
644 | u16 tmp = (nr) ? LM75_TEMP_TO_REG(val) : TEMP_TO_REG(val); | ||
659 | 645 | ||
660 | mutex_lock(&data->update_lock); | 646 | mutex_lock(&data->update_lock); |
661 | 647 | data->temp_max[nr] = tmp; | |
662 | if (nr >= 2) { /* TEMP2 and TEMP3 */ | 648 | w83627hf_write_value(data, w83627hf_reg_temp_over[nr], tmp); |
663 | data->temp_max_add[nr-2] = LM75_TEMP_TO_REG(val); | ||
664 | w83627hf_write_value(data, W83781D_REG_TEMP_OVER(nr), | ||
665 | data->temp_max_add[nr-2]); | ||
666 | } else { /* TEMP1 */ | ||
667 | data->temp_max = TEMP_TO_REG(val); | ||
668 | w83627hf_write_value(data, W83781D_REG_TEMP_OVER(nr), | ||
669 | data->temp_max); | ||
670 | } | ||
671 | mutex_unlock(&data->update_lock); | 649 | mutex_unlock(&data->update_lock); |
672 | return count; | 650 | return count; |
673 | } | 651 | } |
@@ -679,29 +657,22 @@ store_temp_max_hyst(struct device *dev, struct device_attribute *devattr, | |||
679 | int nr = to_sensor_dev_attr(devattr)->index; | 657 | int nr = to_sensor_dev_attr(devattr)->index; |
680 | struct w83627hf_data *data = dev_get_drvdata(dev); | 658 | struct w83627hf_data *data = dev_get_drvdata(dev); |
681 | long val = simple_strtol(buf, NULL, 10); | 659 | long val = simple_strtol(buf, NULL, 10); |
660 | u16 tmp = (nr) ? LM75_TEMP_TO_REG(val) : TEMP_TO_REG(val); | ||
682 | 661 | ||
683 | mutex_lock(&data->update_lock); | 662 | mutex_lock(&data->update_lock); |
684 | 663 | data->temp_max_hyst[nr] = tmp; | |
685 | if (nr >= 2) { /* TEMP2 and TEMP3 */ | 664 | w83627hf_write_value(data, w83627hf_reg_temp_hyst[nr], tmp); |
686 | data->temp_max_hyst_add[nr-2] = LM75_TEMP_TO_REG(val); | ||
687 | w83627hf_write_value(data, W83781D_REG_TEMP_HYST(nr), | ||
688 | data->temp_max_hyst_add[nr-2]); | ||
689 | } else { /* TEMP1 */ | ||
690 | data->temp_max_hyst = TEMP_TO_REG(val); | ||
691 | w83627hf_write_value(data, W83781D_REG_TEMP_HYST(nr), | ||
692 | data->temp_max_hyst); | ||
693 | } | ||
694 | mutex_unlock(&data->update_lock); | 665 | mutex_unlock(&data->update_lock); |
695 | return count; | 666 | return count; |
696 | } | 667 | } |
697 | 668 | ||
698 | #define sysfs_temp_decl(offset) \ | 669 | #define sysfs_temp_decl(offset) \ |
699 | static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ | 670 | static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ |
700 | show_temp, NULL, offset); \ | 671 | show_temp, NULL, offset - 1); \ |
701 | static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO|S_IWUSR, \ | 672 | static SENSOR_DEVICE_ATTR(temp##offset##_max, S_IRUGO|S_IWUSR, \ |
702 | show_temp_max, store_temp_max, offset); \ | 673 | show_temp_max, store_temp_max, offset - 1); \ |
703 | static SENSOR_DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO|S_IWUSR, \ | 674 | static SENSOR_DEVICE_ATTR(temp##offset##_max_hyst, S_IRUGO|S_IWUSR, \ |
704 | show_temp_max_hyst, store_temp_max_hyst, offset); | 675 | show_temp_max_hyst, store_temp_max_hyst, offset - 1); |
705 | 676 | ||
706 | sysfs_temp_decl(1); | 677 | sysfs_temp_decl(1); |
707 | sysfs_temp_decl(2); | 678 | sysfs_temp_decl(2); |
@@ -844,7 +815,7 @@ store_fan_div(struct device *dev, struct device_attribute *devattr, | |||
844 | 815 | ||
845 | /* Restore fan_min */ | 816 | /* Restore fan_min */ |
846 | data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); | 817 | data->fan_min[nr] = FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr])); |
847 | w83627hf_write_value(data, W83781D_REG_FAN_MIN(nr+1), data->fan_min[nr]); | 818 | w83627hf_write_value(data, W83627HF_REG_FAN_MIN(nr), data->fan_min[nr]); |
848 | 819 | ||
849 | mutex_unlock(&data->update_lock); | 820 | mutex_unlock(&data->update_lock); |
850 | return count; | 821 | return count; |
@@ -1170,7 +1141,7 @@ static int __devinit w83627hf_probe(struct platform_device *pdev) | |||
1170 | struct w83627hf_sio_data *sio_data = dev->platform_data; | 1141 | struct w83627hf_sio_data *sio_data = dev->platform_data; |
1171 | struct w83627hf_data *data; | 1142 | struct w83627hf_data *data; |
1172 | struct resource *res; | 1143 | struct resource *res; |
1173 | int err; | 1144 | int err, i; |
1174 | 1145 | ||
1175 | static const char *names[] = { | 1146 | static const char *names[] = { |
1176 | "w83627hf", | 1147 | "w83627hf", |
@@ -1204,9 +1175,9 @@ static int __devinit w83627hf_probe(struct platform_device *pdev) | |||
1204 | w83627hf_init_device(pdev); | 1175 | w83627hf_init_device(pdev); |
1205 | 1176 | ||
1206 | /* A few vars need to be filled upon startup */ | 1177 | /* A few vars need to be filled upon startup */ |
1207 | data->fan_min[0] = w83627hf_read_value(data, W83781D_REG_FAN_MIN(1)); | 1178 | for (i = 0; i <= 2; i++) |
1208 | data->fan_min[1] = w83627hf_read_value(data, W83781D_REG_FAN_MIN(2)); | 1179 | data->fan_min[i] = w83627hf_read_value( |
1209 | data->fan_min[2] = w83627hf_read_value(data, W83781D_REG_FAN_MIN(3)); | 1180 | data, W83627HF_REG_FAN_MIN(i)); |
1210 | w83627hf_update_fan_div(data); | 1181 | w83627hf_update_fan_div(data); |
1211 | 1182 | ||
1212 | /* Register common device attributes */ | 1183 | /* Register common device attributes */ |
@@ -1514,23 +1485,23 @@ static void __devinit w83627hf_init_device(struct platform_device *pdev) | |||
1514 | 1485 | ||
1515 | if(init) { | 1486 | if(init) { |
1516 | /* Enable temp2 */ | 1487 | /* Enable temp2 */ |
1517 | tmp = w83627hf_read_value(data, W83781D_REG_TEMP2_CONFIG); | 1488 | tmp = w83627hf_read_value(data, W83627HF_REG_TEMP2_CONFIG); |
1518 | if (tmp & 0x01) { | 1489 | if (tmp & 0x01) { |
1519 | dev_warn(&pdev->dev, "Enabling temp2, readings " | 1490 | dev_warn(&pdev->dev, "Enabling temp2, readings " |
1520 | "might not make sense\n"); | 1491 | "might not make sense\n"); |
1521 | w83627hf_write_value(data, W83781D_REG_TEMP2_CONFIG, | 1492 | w83627hf_write_value(data, W83627HF_REG_TEMP2_CONFIG, |
1522 | tmp & 0xfe); | 1493 | tmp & 0xfe); |
1523 | } | 1494 | } |
1524 | 1495 | ||
1525 | /* Enable temp3 */ | 1496 | /* Enable temp3 */ |
1526 | if (type != w83697hf) { | 1497 | if (type != w83697hf) { |
1527 | tmp = w83627hf_read_value(data, | 1498 | tmp = w83627hf_read_value(data, |
1528 | W83781D_REG_TEMP3_CONFIG); | 1499 | W83627HF_REG_TEMP3_CONFIG); |
1529 | if (tmp & 0x01) { | 1500 | if (tmp & 0x01) { |
1530 | dev_warn(&pdev->dev, "Enabling temp3, " | 1501 | dev_warn(&pdev->dev, "Enabling temp3, " |
1531 | "readings might not make sense\n"); | 1502 | "readings might not make sense\n"); |
1532 | w83627hf_write_value(data, | 1503 | w83627hf_write_value(data, |
1533 | W83781D_REG_TEMP3_CONFIG, tmp & 0xfe); | 1504 | W83627HF_REG_TEMP3_CONFIG, tmp & 0xfe); |
1534 | } | 1505 | } |
1535 | } | 1506 | } |
1536 | } | 1507 | } |
@@ -1563,7 +1534,7 @@ static void w83627hf_update_fan_div(struct w83627hf_data *data) | |||
1563 | static struct w83627hf_data *w83627hf_update_device(struct device *dev) | 1534 | static struct w83627hf_data *w83627hf_update_device(struct device *dev) |
1564 | { | 1535 | { |
1565 | struct w83627hf_data *data = dev_get_drvdata(dev); | 1536 | struct w83627hf_data *data = dev_get_drvdata(dev); |
1566 | int i; | 1537 | int i, num_temps = (data->type == w83697hf) ? 2 : 3; |
1567 | 1538 | ||
1568 | mutex_lock(&data->update_lock); | 1539 | mutex_lock(&data->update_lock); |
1569 | 1540 | ||
@@ -1584,12 +1555,12 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev) | |||
1584 | w83627hf_read_value(data, | 1555 | w83627hf_read_value(data, |
1585 | W83781D_REG_IN_MAX(i)); | 1556 | W83781D_REG_IN_MAX(i)); |
1586 | } | 1557 | } |
1587 | for (i = 1; i <= 3; i++) { | 1558 | for (i = 0; i <= 2; i++) { |
1588 | data->fan[i - 1] = | 1559 | data->fan[i] = |
1589 | w83627hf_read_value(data, W83781D_REG_FAN(i)); | 1560 | w83627hf_read_value(data, W83627HF_REG_FAN(i)); |
1590 | data->fan_min[i - 1] = | 1561 | data->fan_min[i] = |
1591 | w83627hf_read_value(data, | 1562 | w83627hf_read_value(data, |
1592 | W83781D_REG_FAN_MIN(i)); | 1563 | W83627HF_REG_FAN_MIN(i)); |
1593 | } | 1564 | } |
1594 | for (i = 0; i <= 2; i++) { | 1565 | for (i = 0; i <= 2; i++) { |
1595 | u8 tmp = w83627hf_read_value(data, | 1566 | u8 tmp = w83627hf_read_value(data, |
@@ -1616,25 +1587,13 @@ static struct w83627hf_data *w83627hf_update_device(struct device *dev) | |||
1616 | break; | 1587 | break; |
1617 | } | 1588 | } |
1618 | } | 1589 | } |
1619 | 1590 | for (i = 0; i < num_temps; i++) { | |
1620 | data->temp = w83627hf_read_value(data, W83781D_REG_TEMP(1)); | 1591 | data->temp[i] = w83627hf_read_value( |
1621 | data->temp_max = | 1592 | data, w83627hf_reg_temp[i]); |
1622 | w83627hf_read_value(data, W83781D_REG_TEMP_OVER(1)); | 1593 | data->temp_max[i] = w83627hf_read_value( |
1623 | data->temp_max_hyst = | 1594 | data, w83627hf_reg_temp_over[i]); |
1624 | w83627hf_read_value(data, W83781D_REG_TEMP_HYST(1)); | 1595 | data->temp_max_hyst[i] = w83627hf_read_value( |
1625 | data->temp_add[0] = | 1596 | data, w83627hf_reg_temp_hyst[i]); |
1626 | w83627hf_read_value(data, W83781D_REG_TEMP(2)); | ||
1627 | data->temp_max_add[0] = | ||
1628 | w83627hf_read_value(data, W83781D_REG_TEMP_OVER(2)); | ||
1629 | data->temp_max_hyst_add[0] = | ||
1630 | w83627hf_read_value(data, W83781D_REG_TEMP_HYST(2)); | ||
1631 | if (data->type != w83697hf) { | ||
1632 | data->temp_add[1] = | ||
1633 | w83627hf_read_value(data, W83781D_REG_TEMP(3)); | ||
1634 | data->temp_max_add[1] = | ||
1635 | w83627hf_read_value(data, W83781D_REG_TEMP_OVER(3)); | ||
1636 | data->temp_max_hyst_add[1] = | ||
1637 | w83627hf_read_value(data, W83781D_REG_TEMP_HYST(3)); | ||
1638 | } | 1597 | } |
1639 | 1598 | ||
1640 | w83627hf_update_fan_div(data); | 1599 | w83627hf_update_fan_div(data); |
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c index a6a1edfe7614..e0fa7520400d 100644 --- a/drivers/hwmon/w83781d.c +++ b/drivers/hwmon/w83781d.c | |||
@@ -1122,12 +1122,13 @@ w83781d_create_files(struct device *dev, int kind, int is_isa) | |||
1122 | &sensor_dev_attr_temp3_beep.dev_attr))) | 1122 | &sensor_dev_attr_temp3_beep.dev_attr))) |
1123 | return err; | 1123 | return err; |
1124 | 1124 | ||
1125 | if (kind != w83781d) | 1125 | if (kind != w83781d) { |
1126 | err = sysfs_chmod_file(&dev->kobj, | 1126 | err = sysfs_chmod_file(&dev->kobj, |
1127 | &sensor_dev_attr_temp3_alarm.dev_attr.attr, | 1127 | &sensor_dev_attr_temp3_alarm.dev_attr.attr, |
1128 | S_IRUGO | S_IWUSR); | 1128 | S_IRUGO | S_IWUSR); |
1129 | if (err) | 1129 | if (err) |
1130 | return err; | 1130 | return err; |
1131 | } | ||
1131 | } | 1132 | } |
1132 | 1133 | ||
1133 | if (kind != w83781d && kind != as99127f) { | 1134 | if (kind != w83781d && kind != as99127f) { |
diff --git a/include/linux/f75375s.h b/include/linux/f75375s.h new file mode 100644 index 000000000000..e99e22500668 --- /dev/null +++ b/include/linux/f75375s.h | |||
@@ -0,0 +1,21 @@ | |||
1 | /* | ||
2 | * f75375s.h - platform data structure for f75375s sensor | ||
3 | * | ||
4 | * This file is subject to the terms and conditions of the GNU General Public | ||
5 | * License. See the file "COPYING" in the main directory of this archive | ||
6 | * for more details. | ||
7 | * | ||
8 | * Copyright (C) 2007, Riku Voipio <riku.voipio@iki.fi> | ||
9 | */ | ||
10 | |||
11 | #ifndef __LINUX_F75375S_H | ||
12 | #define __LINUX_F75375S_H | ||
13 | |||
14 | /* We want to set fans spinning on systems where there is no | ||
15 | * BIOS to do that for us */ | ||
16 | struct f75375s_platform_data { | ||
17 | u8 pwm[2]; | ||
18 | u8 pwm_enable[2]; | ||
19 | }; | ||
20 | |||
21 | #endif /* __LINUX_F75375S_H */ | ||
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h index fbe19648bf91..cd6cdb3cd7a5 100644 --- a/include/linux/pci_ids.h +++ b/include/linux/pci_ids.h | |||
@@ -2276,6 +2276,9 @@ | |||
2276 | #define PCI_DEVICE_ID_INTEL_82915G_IG 0x2582 | 2276 | #define PCI_DEVICE_ID_INTEL_82915G_IG 0x2582 |
2277 | #define PCI_DEVICE_ID_INTEL_82915GM_HB 0x2590 | 2277 | #define PCI_DEVICE_ID_INTEL_82915GM_HB 0x2590 |
2278 | #define PCI_DEVICE_ID_INTEL_82915GM_IG 0x2592 | 2278 | #define PCI_DEVICE_ID_INTEL_82915GM_IG 0x2592 |
2279 | #define PCI_DEVICE_ID_INTEL_5000_ERR 0x25F0 | ||
2280 | #define PCI_DEVICE_ID_INTEL_5000_FBD0 0x25F5 | ||
2281 | #define PCI_DEVICE_ID_INTEL_5000_FBD1 0x25F6 | ||
2279 | #define PCI_DEVICE_ID_INTEL_82945G_HB 0x2770 | 2282 | #define PCI_DEVICE_ID_INTEL_82945G_HB 0x2770 |
2280 | #define PCI_DEVICE_ID_INTEL_82945G_IG 0x2772 | 2283 | #define PCI_DEVICE_ID_INTEL_82945G_IG 0x2772 |
2281 | #define PCI_DEVICE_ID_INTEL_3000_HB 0x2778 | 2284 | #define PCI_DEVICE_ID_INTEL_3000_HB 0x2778 |