diff options
| -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 |
