Commit 9418d5dc9ba40b88737580457bf3b7c63c60ec43
Exists in
master
and in
7 other branches
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
Showing 15 changed files Side-by-side Diff
- Documentation/hwmon/sysfs-interface
- arch/arm/mach-iop32x/n2100.c
- drivers/hwmon/Kconfig
- drivers/hwmon/Makefile
- drivers/hwmon/abituguru3.c
- drivers/hwmon/applesmc.c
- drivers/hwmon/f75375s.c
- drivers/hwmon/i5k_amb.c
- drivers/hwmon/ibmpex.c
- drivers/hwmon/lm70.c
- drivers/hwmon/sis5595.c
- drivers/hwmon/w83627hf.c
- drivers/hwmon/w83781d.c
- include/linux/f75375s.h
- include/linux/pci_ids.h
Documentation/hwmon/sysfs-interface
... | ... | @@ -328,6 +328,37 @@ |
328 | 328 | Unit: milliampere |
329 | 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 | 364 | * Alarms * |
arch/arm/mach-iop32x/n2100.c
... | ... | @@ -16,6 +16,7 @@ |
16 | 16 | |
17 | 17 | #include <linux/mm.h> |
18 | 18 | #include <linux/init.h> |
19 | +#include <linux/f75375s.h> | |
19 | 20 | #include <linux/delay.h> |
20 | 21 | #include <linux/kernel.h> |
21 | 22 | #include <linux/pci.h> |
22 | 23 | |
... | ... | @@ -200,10 +201,20 @@ |
200 | 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 | 209 | static struct i2c_board_info __initdata n2100_i2c_devices[] = { |
204 | 210 | { |
205 | 211 | I2C_BOARD_INFO("rtc-rs5c372", 0x32), |
206 | 212 | .type = "rs5c372b", |
213 | + }, | |
214 | + { | |
215 | + I2C_BOARD_INFO("f75375", 0x2e), | |
216 | + .type = "f75375", | |
217 | + .platform_data = &n2100_f75375s, | |
207 | 218 | }, |
208 | 219 | }; |
209 | 220 |
drivers/hwmon/Kconfig
... | ... | @@ -216,6 +216,16 @@ |
216 | 216 | This driver can also be built as a module. If so, the module |
217 | 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 | 229 | config SENSORS_F71805F |
220 | 230 | tristate "Fintek F71805F/FG, F71806F/FG and F71872F/FG" |
221 | 231 | depends on EXPERIMENTAL |
drivers/hwmon/Makefile
... | ... | @@ -38,6 +38,7 @@ |
38 | 38 | obj-$(CONFIG_SENSORS_GL518SM) += gl518sm.o |
39 | 39 | obj-$(CONFIG_SENSORS_GL520SM) += gl520sm.o |
40 | 40 | obj-$(CONFIG_SENSORS_HDAPS) += hdaps.o |
41 | +obj-$(CONFIG_SENSORS_I5K_AMB) += i5k_amb.o | |
41 | 42 | obj-$(CONFIG_SENSORS_IBMPEX) += ibmpex.o |
42 | 43 | obj-$(CONFIG_SENSORS_IT87) += it87.o |
43 | 44 | obj-$(CONFIG_SENSORS_K8TEMP) += k8temp.o |
drivers/hwmon/abituguru3.c
... | ... | @@ -503,7 +503,7 @@ |
503 | 503 | { "AUX3 FAN", 36, 2, 60, 1, 0 }, |
504 | 504 | { NULL, 0, 0, 0, 0, 0 } } |
505 | 505 | }, |
506 | - { 0x001A, "unknown", { | |
506 | + { 0x001A, "Abit IP35 Pro", { | |
507 | 507 | { "CPU Core", 0, 0, 10, 1, 0 }, |
508 | 508 | { "DDR2", 1, 0, 20, 1, 0 }, |
509 | 509 | { "DDR2 VTT", 2, 0, 10, 1, 0 }, |
... | ... | @@ -519,6 +519,60 @@ |
519 | 519 | { "CPU", 24, 1, 1, 1, 0 }, |
520 | 520 | { "System ", 25, 1, 1, 1, 0 }, |
521 | 521 | { "PWM ", 26, 1, 1, 1, 0 }, |
522 | + { "PWM Phase2", 27, 1, 1, 1, 0 }, | |
523 | + { "PWM Phase3", 28, 1, 1, 1, 0 }, | |
524 | + { "PWM Phase4", 29, 1, 1, 1, 0 }, | |
525 | + { "PWM Phase5", 30, 1, 1, 1, 0 }, | |
526 | + { "CPU Fan", 32, 2, 60, 1, 0 }, | |
527 | + { "SYS Fan", 34, 2, 60, 1, 0 }, | |
528 | + { "AUX1 Fan", 33, 2, 60, 1, 0 }, | |
529 | + { "AUX2 Fan", 35, 2, 60, 1, 0 }, | |
530 | + { "AUX3 Fan", 36, 2, 60, 1, 0 }, | |
531 | + { NULL, 0, 0, 0, 0, 0 } } | |
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 }, | |
522 | 576 | { "PWM Phase2", 27, 1, 1, 1, 0 }, |
523 | 577 | { "PWM Phase3", 28, 1, 1, 1, 0 }, |
524 | 578 | { "PWM Phase4", 29, 1, 1, 1, 0 }, |
drivers/hwmon/applesmc.c
... | ... | @@ -80,7 +80,7 @@ |
80 | 80 | /* |
81 | 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 | 84 | /* Set 0: Macbook Pro */ |
85 | 85 | { "TA0P", "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "Th0H", |
86 | 86 | "Th1H", "Tm0P", "Ts0P", "Ts1P", NULL }, |
... | ... | @@ -88,7 +88,13 @@ |
88 | 88 | { "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TN1P", "Th0H", "Th0S", |
89 | 89 | "Th1H", "Ts0P", NULL }, |
90 | 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 | 100 | /* List of keys used to read/write fan speeds */ |
95 | 101 | |
96 | 102 | |
... | ... | @@ -990,14 +996,18 @@ |
990 | 996 | |
991 | 997 | /* |
992 | 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 | 1001 | sysfs_fan_speeds_offset(1); |
996 | 1002 | sysfs_fan_speeds_offset(2); |
1003 | +sysfs_fan_speeds_offset(3); | |
1004 | +sysfs_fan_speeds_offset(4); | |
997 | 1005 | |
998 | 1006 | static const struct attribute_group fan_attribute_groups[] = { |
999 | 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 @@ |
1027 | 1037 | applesmc_show_temperature, NULL, 10); |
1028 | 1038 | static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO, |
1029 | 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 | 1087 | static struct attribute *temperature_attributes[] = { |
1032 | 1088 | &sensor_dev_attr_temp1_input.dev_attr.attr, |
... | ... | @@ -1041,6 +1097,29 @@ |
1041 | 1097 | &sensor_dev_attr_temp10_input.dev_attr.attr, |
1042 | 1098 | &sensor_dev_attr_temp11_input.dev_attr.attr, |
1043 | 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 | 1123 | NULL |
1045 | 1124 | }; |
1046 | 1125 | |
... | ... | @@ -1137,6 +1216,8 @@ |
1137 | 1216 | { .accelerometer = 1, .light = 0, .temperature_set = 1 }, |
1138 | 1217 | /* MacMini: temperature set 2 */ |
1139 | 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 | 1223 | /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". |
... | ... | @@ -1154,6 +1235,10 @@ |
1154 | 1235 | DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), |
1155 | 1236 | DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") }, |
1156 | 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 | 1242 | { .ident = NULL } |
1158 | 1243 | }; |
1159 | 1244 | |
1160 | 1245 | |
... | ... | @@ -1204,9 +1289,19 @@ |
1204 | 1289 | |
1205 | 1290 | switch (count) { |
1206 | 1291 | default: |
1207 | - printk(KERN_WARNING "applesmc: More than 2 fans found," | |
1208 | - " but at most 2 fans are supported" | |
1292 | + printk(KERN_WARNING "applesmc: More than 4 fans found," | |
1293 | + " but at most 4 fans are supported" | |
1209 | 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 | 1305 | case 2: |
1211 | 1306 | ret = sysfs_create_group(&pdev->dev.kobj, |
1212 | 1307 | &fan_attribute_groups[1]); |
drivers/hwmon/f75375s.c
... | ... | @@ -34,6 +34,7 @@ |
34 | 34 | #include <linux/i2c.h> |
35 | 35 | #include <linux/err.h> |
36 | 36 | #include <linux/mutex.h> |
37 | +#include <linux/f75375s.h> | |
37 | 38 | |
38 | 39 | /* Addresses to scan */ |
39 | 40 | static unsigned short normal_i2c[] = { 0x2d, 0x2e, I2C_CLIENT_END }; |
... | ... | @@ -86,7 +87,7 @@ |
86 | 87 | |
87 | 88 | struct f75375_data { |
88 | 89 | unsigned short addr; |
89 | - struct i2c_client client; | |
90 | + struct i2c_client *client; | |
90 | 91 | struct device *hwmon_dev; |
91 | 92 | |
92 | 93 | const char *name; |
93 | 94 | |
94 | 95 | |
95 | 96 | |
... | ... | @@ -116,15 +117,25 @@ |
116 | 117 | static int f75375_attach_adapter(struct i2c_adapter *adapter); |
117 | 118 | static int f75375_detect(struct i2c_adapter *adapter, int address, int kind); |
118 | 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 | 124 | .driver = { |
122 | - .name = "f75375", | |
125 | + .name = "f75375_legacy", | |
123 | 126 | }, |
124 | 127 | .attach_adapter = f75375_attach_adapter, |
125 | 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 | 139 | static inline int f75375_read8(struct i2c_client *client, u8 reg) |
129 | 140 | { |
130 | 141 | return i2c_smbus_read_byte_data(client, reg); |
131 | 142 | |
132 | 143 | |
133 | 144 | |
... | ... | @@ -276,19 +287,14 @@ |
276 | 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, | |
280 | - const char *buf, size_t count) | |
290 | +static int set_pwm_enable_direct(struct i2c_client *client, int nr, int val) | |
281 | 291 | { |
282 | - int nr = to_sensor_dev_attr(attr)->index; | |
283 | - struct i2c_client *client = to_i2c_client(dev); | |
284 | 292 | struct f75375_data *data = i2c_get_clientdata(client); |
285 | - int val = simple_strtoul(buf, NULL, 10); | |
286 | 293 | u8 fanmode; |
287 | 294 | |
288 | 295 | if (val < 0 || val > 4) |
289 | 296 | return -EINVAL; |
290 | 297 | |
291 | - mutex_lock(&data->update_lock); | |
292 | 298 | fanmode = f75375_read8(client, F75375_REG_FAN_TIMER); |
293 | 299 | fanmode = ~(3 << FAN_CTRL_MODE(nr)); |
294 | 300 | |
295 | 301 | |
... | ... | @@ -310,8 +316,22 @@ |
310 | 316 | } |
311 | 317 | f75375_write8(client, F75375_REG_FAN_TIMER, fanmode); |
312 | 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 | 333 | mutex_unlock(&data->update_lock); |
314 | - return count; | |
334 | + return err ? err : count; | |
315 | 335 | } |
316 | 336 | |
317 | 337 | static ssize_t set_pwm_mode(struct device *dev, struct device_attribute *attr, |
... | ... | @@ -323,7 +343,7 @@ |
323 | 343 | int val = simple_strtoul(buf, NULL, 10); |
324 | 344 | u8 conf = 0; |
325 | 345 | |
326 | - if (val != 0 || val != 1 || data->kind == f75373) | |
346 | + if (!(val == 0 || val == 1)) | |
327 | 347 | return -EINVAL; |
328 | 348 | |
329 | 349 | mutex_lock(&data->update_lock); |
330 | 350 | |
... | ... | @@ -529,13 +549,13 @@ |
529 | 549 | show_pwm, set_pwm, 0); |
530 | 550 | static SENSOR_DEVICE_ATTR(pwm1_enable, S_IRUGO|S_IWUSR, |
531 | 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 | 553 | show_pwm_mode, set_pwm_mode, 0); |
534 | 554 | static SENSOR_DEVICE_ATTR(pwm2, S_IRUGO | S_IWUSR, |
535 | 555 | show_pwm, set_pwm, 1); |
536 | 556 | static SENSOR_DEVICE_ATTR(pwm2_enable, S_IRUGO|S_IWUSR, |
537 | 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 | 559 | show_pwm_mode, set_pwm_mode, 1); |
540 | 560 | |
541 | 561 | static struct attribute *f75375_attributes[] = { |
542 | 562 | |
... | ... | @@ -580,12 +600,9 @@ |
580 | 600 | |
581 | 601 | static int f75375_detach_client(struct i2c_client *client) |
582 | 602 | { |
583 | - struct f75375_data *data = i2c_get_clientdata(client); | |
584 | 603 | int err; |
585 | 604 | |
586 | - hwmon_device_unregister(data->hwmon_dev); | |
587 | - sysfs_remove_group(&client->dev.kobj, &f75375_group); | |
588 | - | |
605 | + f75375_remove(client); | |
589 | 606 | err = i2c_detach_client(client); |
590 | 607 | if (err) { |
591 | 608 | dev_err(&client->dev, |
592 | 609 | |
... | ... | @@ -593,7 +610,91 @@ |
593 | 610 | "client not detached.\n"); |
594 | 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 | 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 | 698 | return 0; |
598 | 699 | } |
599 | 700 | |
600 | 701 | |
601 | 702 | |
602 | 703 | |
... | ... | @@ -608,20 +709,17 @@ |
608 | 709 | static int f75375_detect(struct i2c_adapter *adapter, int address, int kind) |
609 | 710 | { |
610 | 711 | struct i2c_client *client; |
611 | - struct f75375_data *data; | |
612 | 712 | u8 version = 0; |
613 | 713 | int err = 0; |
614 | 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 | 717 | err = -ENOMEM; |
618 | 718 | goto exit; |
619 | 719 | } |
620 | - client = &data->client; | |
621 | - i2c_set_clientdata(client, data); | |
622 | 720 | client->addr = address; |
623 | 721 | client->adapter = adapter; |
624 | - client->driver = &f75375_driver; | |
722 | + client->driver = &f75375_legacy_driver; | |
625 | 723 | |
626 | 724 | if (kind < 0) { |
627 | 725 | u16 vendid = f75375_read16(client, F75375_REG_VENDOR); |
628 | 726 | |
629 | 727 | |
630 | 728 | |
631 | 729 | |
632 | 730 | |
633 | 731 | |
634 | 732 | |
... | ... | @@ -644,42 +742,42 @@ |
644 | 742 | } else if (kind == f75373) { |
645 | 743 | name = "f75373"; |
646 | 744 | } |
647 | - | |
648 | 745 | dev_info(&adapter->dev, "found %s version: %02X\n", name, version); |
649 | 746 | strlcpy(client->name, name, I2C_NAME_SIZE); |
650 | - data->kind = kind; | |
651 | - mutex_init(&data->update_lock); | |
747 | + | |
652 | 748 | if ((err = i2c_attach_client(client))) |
653 | 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 | 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 | 754 | return 0; |
665 | 755 | |
666 | -exit_remove: | |
667 | - sysfs_remove_group(&client->dev.kobj, &f75375_group); | |
668 | 756 | exit_detach: |
669 | 757 | i2c_detach_client(client); |
670 | 758 | exit_free: |
671 | - kfree(data); | |
759 | + kfree(client); | |
672 | 760 | exit: |
673 | 761 | return err; |
674 | 762 | } |
675 | 763 | |
676 | 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 | 778 | static void __exit sensors_f75375_exit(void) |
682 | 779 | { |
780 | + i2c_del_driver(&f75375_legacy_driver); | |
683 | 781 | i2c_del_driver(&f75375_driver); |
684 | 782 | } |
685 | 783 |
drivers/hwmon/i5k_amb.c
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); |
drivers/hwmon/ibmpex.c
... | ... | @@ -140,10 +140,10 @@ |
140 | 140 | |
141 | 141 | return 0; |
142 | 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 | 144 | return err; |
145 | 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 | 147 | return err; |
148 | 148 | } |
149 | 149 | |
... | ... | @@ -161,14 +161,14 @@ |
161 | 161 | data->sensor_major = data->rx_msg_data[0]; |
162 | 162 | data->sensor_minor = data->rx_msg_data[1]; |
163 | 163 | |
164 | - printk(KERN_INFO DRVNAME ": Found BMC with sensor interface " | |
165 | - "v%d.%d %d-%02d-%02d on interface %d\n", | |
166 | - data->sensor_major, | |
167 | - data->sensor_minor, | |
168 | - extract_value(data->rx_msg_data, 2), | |
169 | - data->rx_msg_data[4], | |
170 | - data->rx_msg_data[5], | |
171 | - data->interface); | |
164 | + dev_info(data->bmc_device, "Found BMC with sensor interface " | |
165 | + "v%d.%d %d-%02d-%02d on interface %d\n", | |
166 | + data->sensor_major, | |
167 | + data->sensor_minor, | |
168 | + extract_value(data->rx_msg_data, 2), | |
169 | + data->rx_msg_data[4], | |
170 | + data->rx_msg_data[5], | |
171 | + data->interface); | |
172 | 172 | |
173 | 173 | return 0; |
174 | 174 | } |
... | ... | @@ -212,8 +212,8 @@ |
212 | 212 | wait_for_completion(&data->read_complete); |
213 | 213 | |
214 | 214 | if (data->rx_result || data->rx_msg_len < 26) { |
215 | - printk(KERN_ERR "Error reading sensor %d, please check.\n", | |
216 | - sensor); | |
215 | + dev_err(data->bmc_device, "Error reading sensor %d.\n", | |
216 | + sensor); | |
217 | 217 | return -ENOENT; |
218 | 218 | } |
219 | 219 | |
... | ... | @@ -456,8 +456,7 @@ |
456 | 456 | |
457 | 457 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
458 | 458 | if (!data) { |
459 | - printk(KERN_ERR DRVNAME ": Insufficient memory for BMC " | |
460 | - "interface %d.\n", data->interface); | |
459 | + dev_err(dev, "Insufficient memory for BMC interface.\n"); | |
461 | 460 | return; |
462 | 461 | } |
463 | 462 | |
... | ... | @@ -471,9 +470,8 @@ |
471 | 470 | err = ipmi_create_user(data->interface, &driver_data.ipmi_hndlrs, |
472 | 471 | data, &data->user); |
473 | 472 | if (err < 0) { |
474 | - printk(KERN_ERR DRVNAME ": Error, unable to register user with " | |
475 | - "ipmi interface %d\n", | |
476 | - data->interface); | |
473 | + dev_err(dev, "Unable to register user with IPMI " | |
474 | + "interface %d\n", data->interface); | |
477 | 475 | goto out; |
478 | 476 | } |
479 | 477 | |
... | ... | @@ -495,9 +493,9 @@ |
495 | 493 | data->hwmon_dev = hwmon_device_register(data->bmc_device); |
496 | 494 | |
497 | 495 | if (IS_ERR(data->hwmon_dev)) { |
498 | - printk(KERN_ERR DRVNAME ": Error, unable to register hwmon " | |
499 | - "class device for interface %d\n", | |
500 | - data->interface); | |
496 | + dev_err(data->bmc_device, "Unable to register hwmon " | |
497 | + "device for IPMI interface %d\n", | |
498 | + data->interface); | |
501 | 499 | goto out_user; |
502 | 500 | } |
503 | 501 | |
... | ... | @@ -508,7 +506,7 @@ |
508 | 506 | /* Now go find all the sensors */ |
509 | 507 | err = ibmpex_find_sensors(data); |
510 | 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 | 510 | goto out_register; |
513 | 511 | } |
514 | 512 | |
... | ... | @@ -561,10 +559,10 @@ |
561 | 559 | struct ibmpex_bmc_data *data = (struct ibmpex_bmc_data *)user_msg_data; |
562 | 560 | |
563 | 561 | if (msg->msgid != data->tx_msgid) { |
564 | - printk(KERN_ERR "Received msgid (%02x) and transmitted " | |
565 | - "msgid (%02x) mismatch!\n", | |
566 | - (int)msg->msgid, | |
567 | - (int)data->tx_msgid); | |
562 | + dev_err(data->bmc_device, "Mismatch between received msgid " | |
563 | + "(%02x) and transmitted msgid (%02x)!\n", | |
564 | + (int)msg->msgid, | |
565 | + (int)data->tx_msgid); | |
568 | 566 | ipmi_free_recv_msg(msg); |
569 | 567 | return; |
570 | 568 | } |
drivers/hwmon/lm70.c
... | ... | @@ -31,14 +31,15 @@ |
31 | 31 | #include <linux/err.h> |
32 | 32 | #include <linux/sysfs.h> |
33 | 33 | #include <linux/hwmon.h> |
34 | +#include <linux/mutex.h> | |
34 | 35 | #include <linux/spi/spi.h> |
35 | -#include <asm/semaphore.h> | |
36 | 36 | |
37 | + | |
37 | 38 | #define DRVNAME "lm70" |
38 | 39 | |
39 | 40 | struct lm70 { |
40 | 41 | struct device *hwmon_dev; |
41 | - struct semaphore sem; | |
42 | + struct mutex lock; | |
42 | 43 | }; |
43 | 44 | |
44 | 45 | /* sysfs hook function */ |
... | ... | @@ -51,7 +52,7 @@ |
51 | 52 | s16 raw=0; |
52 | 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 | 56 | return -ERESTARTSYS; |
56 | 57 | |
57 | 58 | /* |
... | ... | @@ -83,7 +84,7 @@ |
83 | 84 | val = ((int)raw/32) * 250; |
84 | 85 | status = sprintf(buf, "%d\n", val); /* millidegrees Celsius */ |
85 | 86 | out: |
86 | - up(&p_lm70->sem); | |
87 | + mutex_unlock(&p_lm70->lock); | |
87 | 88 | return status; |
88 | 89 | } |
89 | 90 | |
... | ... | @@ -112,7 +113,7 @@ |
112 | 113 | if (!p_lm70) |
113 | 114 | return -ENOMEM; |
114 | 115 | |
115 | - init_MUTEX(&p_lm70->sem); | |
116 | + mutex_init(&p_lm70->lock); | |
116 | 117 | |
117 | 118 | /* sysfs hook */ |
118 | 119 | p_lm70->hwmon_dev = hwmon_device_register(&spi->dev); |
drivers/hwmon/sis5595.c
... | ... | @@ -435,6 +435,22 @@ |
435 | 435 | } |
436 | 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 | 454 | static ssize_t show_name(struct device *dev, struct device_attribute *attr, |
439 | 455 | char *buf) |
440 | 456 | { |
441 | 457 | |
442 | 458 | |
443 | 459 | |
444 | 460 | |
445 | 461 | |
... | ... | @@ -447,22 +463,28 @@ |
447 | 463 | &sensor_dev_attr_in0_input.dev_attr.attr, |
448 | 464 | &sensor_dev_attr_in0_min.dev_attr.attr, |
449 | 465 | &sensor_dev_attr_in0_max.dev_attr.attr, |
466 | + &sensor_dev_attr_in0_alarm.dev_attr.attr, | |
450 | 467 | &sensor_dev_attr_in1_input.dev_attr.attr, |
451 | 468 | &sensor_dev_attr_in1_min.dev_attr.attr, |
452 | 469 | &sensor_dev_attr_in1_max.dev_attr.attr, |
470 | + &sensor_dev_attr_in1_alarm.dev_attr.attr, | |
453 | 471 | &sensor_dev_attr_in2_input.dev_attr.attr, |
454 | 472 | &sensor_dev_attr_in2_min.dev_attr.attr, |
455 | 473 | &sensor_dev_attr_in2_max.dev_attr.attr, |
474 | + &sensor_dev_attr_in2_alarm.dev_attr.attr, | |
456 | 475 | &sensor_dev_attr_in3_input.dev_attr.attr, |
457 | 476 | &sensor_dev_attr_in3_min.dev_attr.attr, |
458 | 477 | &sensor_dev_attr_in3_max.dev_attr.attr, |
478 | + &sensor_dev_attr_in3_alarm.dev_attr.attr, | |
459 | 479 | |
460 | 480 | &sensor_dev_attr_fan1_input.dev_attr.attr, |
461 | 481 | &sensor_dev_attr_fan1_min.dev_attr.attr, |
462 | 482 | &sensor_dev_attr_fan1_div.dev_attr.attr, |
483 | + &sensor_dev_attr_fan1_alarm.dev_attr.attr, | |
463 | 484 | &sensor_dev_attr_fan2_input.dev_attr.attr, |
464 | 485 | &sensor_dev_attr_fan2_min.dev_attr.attr, |
465 | 486 | &sensor_dev_attr_fan2_div.dev_attr.attr, |
487 | + &sensor_dev_attr_fan2_alarm.dev_attr.attr, | |
466 | 488 | |
467 | 489 | &dev_attr_alarms.attr, |
468 | 490 | &dev_attr_name.attr, |
469 | 491 | |
470 | 492 | |
471 | 493 | |
472 | 494 | |
... | ... | @@ -473,19 +495,28 @@ |
473 | 495 | .attrs = sis5595_attributes, |
474 | 496 | }; |
475 | 497 | |
476 | -static struct attribute *sis5595_attributes_opt[] = { | |
498 | +static struct attribute *sis5595_attributes_in4[] = { | |
477 | 499 | &sensor_dev_attr_in4_input.dev_attr.attr, |
478 | 500 | &sensor_dev_attr_in4_min.dev_attr.attr, |
479 | 501 | &sensor_dev_attr_in4_max.dev_attr.attr, |
502 | + &sensor_dev_attr_in4_alarm.dev_attr.attr, | |
503 | + NULL | |
504 | +}; | |
480 | 505 | |
506 | +static const struct attribute_group sis5595_group_in4 = { | |
507 | + .attrs = sis5595_attributes_in4, | |
508 | +}; | |
509 | + | |
510 | +static struct attribute *sis5595_attributes_temp1[] = { | |
481 | 511 | &dev_attr_temp1_input.attr, |
482 | 512 | &dev_attr_temp1_max.attr, |
483 | 513 | &dev_attr_temp1_max_hyst.attr, |
514 | + &sensor_dev_attr_temp1_alarm.dev_attr.attr, | |
484 | 515 | NULL |
485 | 516 | }; |
486 | 517 | |
487 | -static const struct attribute_group sis5595_group_opt = { | |
488 | - .attrs = sis5595_attributes_opt, | |
518 | +static const struct attribute_group sis5595_group_temp1 = { | |
519 | + .attrs = sis5595_attributes_temp1, | |
489 | 520 | }; |
490 | 521 | |
491 | 522 | /* This is called when the module is loaded */ |
492 | 523 | |
... | ... | @@ -540,20 +571,12 @@ |
540 | 571 | if ((err = sysfs_create_group(&pdev->dev.kobj, &sis5595_group))) |
541 | 572 | goto exit_free; |
542 | 573 | if (data->maxins == 4) { |
543 | - if ((err = device_create_file(&pdev->dev, | |
544 | - &sensor_dev_attr_in4_input.dev_attr)) | |
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))) | |
574 | + if ((err = sysfs_create_group(&pdev->dev.kobj, | |
575 | + &sis5595_group_in4))) | |
549 | 576 | goto exit_remove_files; |
550 | 577 | } else { |
551 | - if ((err = device_create_file(&pdev->dev, | |
552 | - &dev_attr_temp1_input)) | |
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))) | |
578 | + if ((err = sysfs_create_group(&pdev->dev.kobj, | |
579 | + &sis5595_group_temp1))) | |
557 | 580 | goto exit_remove_files; |
558 | 581 | } |
559 | 582 | |
... | ... | @@ -567,7 +590,8 @@ |
567 | 590 | |
568 | 591 | exit_remove_files: |
569 | 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 | 595 | exit_free: |
572 | 596 | kfree(data); |
573 | 597 | exit_release: |
... | ... | @@ -582,7 +606,8 @@ |
582 | 606 | |
583 | 607 | hwmon_device_unregister(data->hwmon_dev); |
584 | 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 | 612 | release_region(data->addr, SIS5595_EXTENT); |
588 | 613 | platform_set_drvdata(pdev, NULL); |
drivers/hwmon/w83627hf.c
... | ... | @@ -170,20 +170,16 @@ |
170 | 170 | #define W83781D_REG_IN(nr) ((nr < 7) ? (0x20 + (nr)) : \ |
171 | 171 | (0x550 + (nr) - 7)) |
172 | 172 | |
173 | -#define W83781D_REG_FAN_MIN(nr) (0x3a + (nr)) | |
174 | -#define W83781D_REG_FAN(nr) (0x27 + (nr)) | |
173 | +/* nr:0-2 for fans:1-3 */ | |
174 | +#define W83627HF_REG_FAN_MIN(nr) (0x3b + (nr)) | |
175 | +#define W83627HF_REG_FAN(nr) (0x28 + (nr)) | |
175 | 176 | |
176 | -#define W83781D_REG_TEMP2_CONFIG 0x152 | |
177 | -#define W83781D_REG_TEMP3_CONFIG 0x252 | |
178 | -#define W83781D_REG_TEMP(nr) ((nr == 3) ? (0x0250) : \ | |
179 | - ((nr == 2) ? (0x0150) : \ | |
180 | - (0x27))) | |
181 | -#define W83781D_REG_TEMP_HYST(nr) ((nr == 3) ? (0x253) : \ | |
182 | - ((nr == 2) ? (0x153) : \ | |
183 | - (0x3A))) | |
184 | -#define W83781D_REG_TEMP_OVER(nr) ((nr == 3) ? (0x255) : \ | |
185 | - ((nr == 2) ? (0x155) : \ | |
186 | - (0x39))) | |
177 | +#define W83627HF_REG_TEMP2_CONFIG 0x152 | |
178 | +#define W83627HF_REG_TEMP3_CONFIG 0x252 | |
179 | +/* these are zero-based, unlike config constants above */ | |
180 | +static const u16 w83627hf_reg_temp[] = { 0x27, 0x150, 0x250 }; | |
181 | +static const u16 w83627hf_reg_temp_hyst[] = { 0x3A, 0x153, 0x253 }; | |
182 | +static const u16 w83627hf_reg_temp_over[] = { 0x39, 0x155, 0x255 }; | |
187 | 183 | |
188 | 184 | #define W83781D_REG_BANK 0x4E |
189 | 185 | |
... | ... | @@ -360,12 +356,9 @@ |
360 | 356 | u8 in_min[9]; /* Register value */ |
361 | 357 | u8 fan[3]; /* Register value */ |
362 | 358 | u8 fan_min[3]; /* Register value */ |
363 | - u8 temp; | |
364 | - u8 temp_max; /* Register value */ | |
365 | - u8 temp_max_hyst; /* 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 */ | |
359 | + u16 temp[3]; /* Register value */ | |
360 | + u16 temp_max[3]; /* Register value */ | |
361 | + u16 temp_max_hyst[3]; /* Register value */ | |
369 | 362 | u8 fan_div[3]; /* Register encoding, shifted right */ |
370 | 363 | u8 vid; /* Register encoding, combined */ |
371 | 364 | u32 alarms; /* Register encoding, combined */ |
... | ... | @@ -590,7 +583,7 @@ |
590 | 583 | |
591 | 584 | mutex_lock(&data->update_lock); |
592 | 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 | 587 | data->fan_min[nr]); |
595 | 588 | |
596 | 589 | mutex_unlock(&data->update_lock); |
... | ... | @@ -611,12 +604,10 @@ |
611 | 604 | { |
612 | 605 | int nr = to_sensor_dev_attr(devattr)->index; |
613 | 606 | struct w83627hf_data *data = w83627hf_update_device(dev); |
614 | - if (nr >= 2) { /* TEMP2 and TEMP3 */ | |
615 | - return sprintf(buf, "%ld\n", | |
616 | - (long)LM75_TEMP_FROM_REG(data->temp_add[nr-2])); | |
617 | - } else { /* TEMP1 */ | |
618 | - return sprintf(buf, "%ld\n", (long)TEMP_FROM_REG(data->temp)); | |
619 | - } | |
607 | + | |
608 | + u16 tmp = data->temp[nr]; | |
609 | + return sprintf(buf, "%ld\n", (nr) ? (long) LM75_TEMP_FROM_REG(tmp) | |
610 | + : (long) TEMP_FROM_REG(tmp)); | |
620 | 611 | } |
621 | 612 | |
622 | 613 | static ssize_t |
... | ... | @@ -625,13 +616,10 @@ |
625 | 616 | { |
626 | 617 | int nr = to_sensor_dev_attr(devattr)->index; |
627 | 618 | struct w83627hf_data *data = w83627hf_update_device(dev); |
628 | - if (nr >= 2) { /* TEMP2 and TEMP3 */ | |
629 | - return sprintf(buf, "%ld\n", | |
630 | - (long)LM75_TEMP_FROM_REG(data->temp_max_add[nr-2])); | |
631 | - } else { /* TEMP1 */ | |
632 | - return sprintf(buf, "%ld\n", | |
633 | - (long)TEMP_FROM_REG(data->temp_max)); | |
634 | - } | |
619 | + | |
620 | + u16 tmp = data->temp_max[nr]; | |
621 | + return sprintf(buf, "%ld\n", (nr) ? (long) LM75_TEMP_FROM_REG(tmp) | |
622 | + : (long) TEMP_FROM_REG(tmp)); | |
635 | 623 | } |
636 | 624 | |
637 | 625 | static ssize_t |
... | ... | @@ -640,13 +628,10 @@ |
640 | 628 | { |
641 | 629 | int nr = to_sensor_dev_attr(devattr)->index; |
642 | 630 | struct w83627hf_data *data = w83627hf_update_device(dev); |
643 | - if (nr >= 2) { /* TEMP2 and TEMP3 */ | |
644 | - return sprintf(buf, "%ld\n", | |
645 | - (long)LM75_TEMP_FROM_REG(data->temp_max_hyst_add[nr-2])); | |
646 | - } else { /* TEMP1 */ | |
647 | - return sprintf(buf, "%ld\n", | |
648 | - (long)TEMP_FROM_REG(data->temp_max_hyst)); | |
649 | - } | |
631 | + | |
632 | + u16 tmp = data->temp_max_hyst[nr]; | |
633 | + return sprintf(buf, "%ld\n", (nr) ? (long) LM75_TEMP_FROM_REG(tmp) | |
634 | + : (long) TEMP_FROM_REG(tmp)); | |
650 | 635 | } |
651 | 636 | |
652 | 637 | static ssize_t |
653 | 638 | |
... | ... | @@ -656,18 +641,11 @@ |
656 | 641 | int nr = to_sensor_dev_attr(devattr)->index; |
657 | 642 | struct w83627hf_data *data = dev_get_drvdata(dev); |
658 | 643 | long val = simple_strtol(buf, NULL, 10); |
644 | + u16 tmp = (nr) ? LM75_TEMP_TO_REG(val) : TEMP_TO_REG(val); | |
659 | 645 | |
660 | 646 | mutex_lock(&data->update_lock); |
661 | - | |
662 | - if (nr >= 2) { /* TEMP2 and TEMP3 */ | |
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 | - } | |
647 | + data->temp_max[nr] = tmp; | |
648 | + w83627hf_write_value(data, w83627hf_reg_temp_over[nr], tmp); | |
671 | 649 | mutex_unlock(&data->update_lock); |
672 | 650 | return count; |
673 | 651 | } |
674 | 652 | |
675 | 653 | |
676 | 654 | |
677 | 655 | |
... | ... | @@ -679,29 +657,22 @@ |
679 | 657 | int nr = to_sensor_dev_attr(devattr)->index; |
680 | 658 | struct w83627hf_data *data = dev_get_drvdata(dev); |
681 | 659 | long val = simple_strtol(buf, NULL, 10); |
660 | + u16 tmp = (nr) ? LM75_TEMP_TO_REG(val) : TEMP_TO_REG(val); | |
682 | 661 | |
683 | 662 | mutex_lock(&data->update_lock); |
684 | - | |
685 | - if (nr >= 2) { /* TEMP2 and TEMP3 */ | |
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 | - } | |
663 | + data->temp_max_hyst[nr] = tmp; | |
664 | + w83627hf_write_value(data, w83627hf_reg_temp_hyst[nr], tmp); | |
694 | 665 | mutex_unlock(&data->update_lock); |
695 | 666 | return count; |
696 | 667 | } |
697 | 668 | |
698 | 669 | #define sysfs_temp_decl(offset) \ |
699 | 670 | static SENSOR_DEVICE_ATTR(temp##offset##_input, S_IRUGO, \ |
700 | - show_temp, NULL, offset); \ | |
671 | + show_temp, NULL, offset - 1); \ | |
701 | 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 | 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 | 677 | sysfs_temp_decl(1); |
707 | 678 | sysfs_temp_decl(2); |
... | ... | @@ -844,7 +815,7 @@ |
844 | 815 | |
845 | 816 | /* Restore fan_min */ |
846 | 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 | 820 | mutex_unlock(&data->update_lock); |
850 | 821 | return count; |
... | ... | @@ -1170,7 +1141,7 @@ |
1170 | 1141 | struct w83627hf_sio_data *sio_data = dev->platform_data; |
1171 | 1142 | struct w83627hf_data *data; |
1172 | 1143 | struct resource *res; |
1173 | - int err; | |
1144 | + int err, i; | |
1174 | 1145 | |
1175 | 1146 | static const char *names[] = { |
1176 | 1147 | "w83627hf", |
... | ... | @@ -1204,9 +1175,9 @@ |
1204 | 1175 | w83627hf_init_device(pdev); |
1205 | 1176 | |
1206 | 1177 | /* A few vars need to be filled upon startup */ |
1207 | - data->fan_min[0] = w83627hf_read_value(data, W83781D_REG_FAN_MIN(1)); | |
1208 | - data->fan_min[1] = w83627hf_read_value(data, W83781D_REG_FAN_MIN(2)); | |
1209 | - data->fan_min[2] = w83627hf_read_value(data, W83781D_REG_FAN_MIN(3)); | |
1178 | + for (i = 0; i <= 2; i++) | |
1179 | + data->fan_min[i] = w83627hf_read_value( | |
1180 | + data, W83627HF_REG_FAN_MIN(i)); | |
1210 | 1181 | w83627hf_update_fan_div(data); |
1211 | 1182 | |
1212 | 1183 | /* Register common device attributes */ |
1213 | 1184 | |
1214 | 1185 | |
1215 | 1186 | |
... | ... | @@ -1514,23 +1485,23 @@ |
1514 | 1485 | |
1515 | 1486 | if(init) { |
1516 | 1487 | /* Enable temp2 */ |
1517 | - tmp = w83627hf_read_value(data, W83781D_REG_TEMP2_CONFIG); | |
1488 | + tmp = w83627hf_read_value(data, W83627HF_REG_TEMP2_CONFIG); | |
1518 | 1489 | if (tmp & 0x01) { |
1519 | 1490 | dev_warn(&pdev->dev, "Enabling temp2, readings " |
1520 | 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 | 1493 | tmp & 0xfe); |
1523 | 1494 | } |
1524 | 1495 | |
1525 | 1496 | /* Enable temp3 */ |
1526 | 1497 | if (type != w83697hf) { |
1527 | 1498 | tmp = w83627hf_read_value(data, |
1528 | - W83781D_REG_TEMP3_CONFIG); | |
1499 | + W83627HF_REG_TEMP3_CONFIG); | |
1529 | 1500 | if (tmp & 0x01) { |
1530 | 1501 | dev_warn(&pdev->dev, "Enabling temp3, " |
1531 | 1502 | "readings might not make sense\n"); |
1532 | 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 @@ |
1563 | 1534 | static struct w83627hf_data *w83627hf_update_device(struct device *dev) |
1564 | 1535 | { |
1565 | 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 | 1539 | mutex_lock(&data->update_lock); |
1569 | 1540 | |
1570 | 1541 | |
... | ... | @@ -1584,12 +1555,12 @@ |
1584 | 1555 | w83627hf_read_value(data, |
1585 | 1556 | W83781D_REG_IN_MAX(i)); |
1586 | 1557 | } |
1587 | - for (i = 1; i <= 3; i++) { | |
1588 | - data->fan[i - 1] = | |
1589 | - w83627hf_read_value(data, W83781D_REG_FAN(i)); | |
1590 | - data->fan_min[i - 1] = | |
1558 | + for (i = 0; i <= 2; i++) { | |
1559 | + data->fan[i] = | |
1560 | + w83627hf_read_value(data, W83627HF_REG_FAN(i)); | |
1561 | + data->fan_min[i] = | |
1591 | 1562 | w83627hf_read_value(data, |
1592 | - W83781D_REG_FAN_MIN(i)); | |
1563 | + W83627HF_REG_FAN_MIN(i)); | |
1593 | 1564 | } |
1594 | 1565 | for (i = 0; i <= 2; i++) { |
1595 | 1566 | u8 tmp = w83627hf_read_value(data, |
... | ... | @@ -1616,25 +1587,13 @@ |
1616 | 1587 | break; |
1617 | 1588 | } |
1618 | 1589 | } |
1619 | - | |
1620 | - data->temp = w83627hf_read_value(data, W83781D_REG_TEMP(1)); | |
1621 | - data->temp_max = | |
1622 | - w83627hf_read_value(data, W83781D_REG_TEMP_OVER(1)); | |
1623 | - data->temp_max_hyst = | |
1624 | - w83627hf_read_value(data, W83781D_REG_TEMP_HYST(1)); | |
1625 | - data->temp_add[0] = | |
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)); | |
1590 | + for (i = 0; i < num_temps; i++) { | |
1591 | + data->temp[i] = w83627hf_read_value( | |
1592 | + data, w83627hf_reg_temp[i]); | |
1593 | + data->temp_max[i] = w83627hf_read_value( | |
1594 | + data, w83627hf_reg_temp_over[i]); | |
1595 | + data->temp_max_hyst[i] = w83627hf_read_value( | |
1596 | + data, w83627hf_reg_temp_hyst[i]); | |
1638 | 1597 | } |
1639 | 1598 | |
1640 | 1599 | w83627hf_update_fan_div(data); |
drivers/hwmon/w83781d.c
... | ... | @@ -1122,12 +1122,13 @@ |
1122 | 1122 | &sensor_dev_attr_temp3_beep.dev_attr))) |
1123 | 1123 | return err; |
1124 | 1124 | |
1125 | - if (kind != w83781d) | |
1125 | + if (kind != w83781d) { | |
1126 | 1126 | err = sysfs_chmod_file(&dev->kobj, |
1127 | 1127 | &sensor_dev_attr_temp3_alarm.dev_attr.attr, |
1128 | 1128 | S_IRUGO | S_IWUSR); |
1129 | 1129 | if (err) |
1130 | 1130 | return err; |
1131 | + } | |
1131 | 1132 | } |
1132 | 1133 | |
1133 | 1134 | if (kind != w83781d && kind != as99127f) { |
include/linux/f75375s.h
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 */ |
include/linux/pci_ids.h
... | ... | @@ -2276,6 +2276,9 @@ |
2276 | 2276 | #define PCI_DEVICE_ID_INTEL_82915G_IG 0x2582 |
2277 | 2277 | #define PCI_DEVICE_ID_INTEL_82915GM_HB 0x2590 |
2278 | 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 | 2282 | #define PCI_DEVICE_ID_INTEL_82945G_HB 0x2770 |
2280 | 2283 | #define PCI_DEVICE_ID_INTEL_82945G_IG 0x2772 |
2281 | 2284 | #define PCI_DEVICE_ID_INTEL_3000_HB 0x2778 |