Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

hwmon: (applesmc) Add support for Mac Pro 2 x Quad-Core

At least the 2x Quad-Core Apple Mac Pro appears to have some over-heat
protection which suddenly powers off the whole box under load. This adds
support for the fans and temerature sensors in the Mac Pro - later some
"windwarm" a-like code should probably monitor the values. For now
manually tweaking the fans prevents the sudden shutdown for me.

cd /sys/devices/platform/applesmc.768
for x in fan{1,2,3,4}; do
echo 1 > ${x}_manual
echo 1285 > ${x}_output
done

Two sensors are 0, while four are 129 °C, those might be removed again,
later.

Signed-off-by: René Rebe <rene@exactcode.de>
Cc: Nicolas Boichat <nicolas@boichat.ch>
Cc: Jean Delvare <khali@linux-fr.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Mark M. Hoffman <mhoffman@lightlink.com>

authored by

René Rebe and committed by
Mark M. Hoffman
8de57709 ff8966ac

+101 -6
+101 -6
drivers/hwmon/applesmc.c
··· 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 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 */ ··· 996 990 997 991 /* 998 992 * Create the needed functions for each fan using the macro defined above 999 - * (2 fans are supported) 993 + * (4 fans are supported) 1000 994 */ 1001 995 sysfs_fan_speeds_offset(1); 1002 996 sysfs_fan_speeds_offset(2); 997 + sysfs_fan_speeds_offset(3); 998 + sysfs_fan_speeds_offset(4); 1003 999 1004 1000 static const struct attribute_group fan_attribute_groups[] = { 1005 1001 { .attrs = fan1_attributes }, 1006 - { .attrs = fan2_attributes } 1002 + { .attrs = fan2_attributes }, 1003 + { .attrs = fan3_attributes }, 1004 + { .attrs = fan4_attributes }, 1007 1005 }; 1008 1006 1009 1007 /* ··· 1037 1027 applesmc_show_temperature, NULL, 10); 1038 1028 static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO, 1039 1029 applesmc_show_temperature, NULL, 11); 1030 + static SENSOR_DEVICE_ATTR(temp13_input, S_IRUGO, 1031 + applesmc_show_temperature, NULL, 12); 1032 + static SENSOR_DEVICE_ATTR(temp14_input, S_IRUGO, 1033 + applesmc_show_temperature, NULL, 13); 1034 + static SENSOR_DEVICE_ATTR(temp15_input, S_IRUGO, 1035 + applesmc_show_temperature, NULL, 14); 1036 + static SENSOR_DEVICE_ATTR(temp16_input, S_IRUGO, 1037 + applesmc_show_temperature, NULL, 15); 1038 + static SENSOR_DEVICE_ATTR(temp17_input, S_IRUGO, 1039 + applesmc_show_temperature, NULL, 16); 1040 + static SENSOR_DEVICE_ATTR(temp18_input, S_IRUGO, 1041 + applesmc_show_temperature, NULL, 17); 1042 + static SENSOR_DEVICE_ATTR(temp19_input, S_IRUGO, 1043 + applesmc_show_temperature, NULL, 18); 1044 + static SENSOR_DEVICE_ATTR(temp20_input, S_IRUGO, 1045 + applesmc_show_temperature, NULL, 19); 1046 + static SENSOR_DEVICE_ATTR(temp21_input, S_IRUGO, 1047 + applesmc_show_temperature, NULL, 20); 1048 + static SENSOR_DEVICE_ATTR(temp22_input, S_IRUGO, 1049 + applesmc_show_temperature, NULL, 21); 1050 + static SENSOR_DEVICE_ATTR(temp23_input, S_IRUGO, 1051 + applesmc_show_temperature, NULL, 22); 1052 + static SENSOR_DEVICE_ATTR(temp24_input, S_IRUGO, 1053 + applesmc_show_temperature, NULL, 23); 1054 + static SENSOR_DEVICE_ATTR(temp25_input, S_IRUGO, 1055 + applesmc_show_temperature, NULL, 24); 1056 + static SENSOR_DEVICE_ATTR(temp26_input, S_IRUGO, 1057 + applesmc_show_temperature, NULL, 25); 1058 + static SENSOR_DEVICE_ATTR(temp27_input, S_IRUGO, 1059 + applesmc_show_temperature, NULL, 26); 1060 + static SENSOR_DEVICE_ATTR(temp28_input, S_IRUGO, 1061 + applesmc_show_temperature, NULL, 27); 1062 + static SENSOR_DEVICE_ATTR(temp29_input, S_IRUGO, 1063 + applesmc_show_temperature, NULL, 28); 1064 + static SENSOR_DEVICE_ATTR(temp30_input, S_IRUGO, 1065 + applesmc_show_temperature, NULL, 29); 1066 + static SENSOR_DEVICE_ATTR(temp31_input, S_IRUGO, 1067 + applesmc_show_temperature, NULL, 30); 1068 + static SENSOR_DEVICE_ATTR(temp32_input, S_IRUGO, 1069 + applesmc_show_temperature, NULL, 31); 1070 + static SENSOR_DEVICE_ATTR(temp33_input, S_IRUGO, 1071 + applesmc_show_temperature, NULL, 32); 1072 + static SENSOR_DEVICE_ATTR(temp34_input, S_IRUGO, 1073 + applesmc_show_temperature, NULL, 33); 1074 + static SENSOR_DEVICE_ATTR(temp35_input, S_IRUGO, 1075 + applesmc_show_temperature, NULL, 34); 1040 1076 1041 1077 static struct attribute *temperature_attributes[] = { 1042 1078 &sensor_dev_attr_temp1_input.dev_attr.attr, ··· 1097 1041 &sensor_dev_attr_temp10_input.dev_attr.attr, 1098 1042 &sensor_dev_attr_temp11_input.dev_attr.attr, 1099 1043 &sensor_dev_attr_temp12_input.dev_attr.attr, 1044 + &sensor_dev_attr_temp13_input.dev_attr.attr, 1045 + &sensor_dev_attr_temp14_input.dev_attr.attr, 1046 + &sensor_dev_attr_temp15_input.dev_attr.attr, 1047 + &sensor_dev_attr_temp16_input.dev_attr.attr, 1048 + &sensor_dev_attr_temp17_input.dev_attr.attr, 1049 + &sensor_dev_attr_temp18_input.dev_attr.attr, 1050 + &sensor_dev_attr_temp19_input.dev_attr.attr, 1051 + &sensor_dev_attr_temp20_input.dev_attr.attr, 1052 + &sensor_dev_attr_temp21_input.dev_attr.attr, 1053 + &sensor_dev_attr_temp22_input.dev_attr.attr, 1054 + &sensor_dev_attr_temp23_input.dev_attr.attr, 1055 + &sensor_dev_attr_temp24_input.dev_attr.attr, 1056 + &sensor_dev_attr_temp25_input.dev_attr.attr, 1057 + &sensor_dev_attr_temp26_input.dev_attr.attr, 1058 + &sensor_dev_attr_temp27_input.dev_attr.attr, 1059 + &sensor_dev_attr_temp28_input.dev_attr.attr, 1060 + &sensor_dev_attr_temp29_input.dev_attr.attr, 1061 + &sensor_dev_attr_temp30_input.dev_attr.attr, 1062 + &sensor_dev_attr_temp31_input.dev_attr.attr, 1063 + &sensor_dev_attr_temp32_input.dev_attr.attr, 1064 + &sensor_dev_attr_temp33_input.dev_attr.attr, 1065 + &sensor_dev_attr_temp34_input.dev_attr.attr, 1066 + &sensor_dev_attr_temp35_input.dev_attr.attr, 1100 1067 NULL 1101 1068 }; 1102 1069 ··· 1216 1137 { .accelerometer = 1, .light = 0, .temperature_set = 1 }, 1217 1138 /* MacMini: temperature set 2 */ 1218 1139 { .accelerometer = 0, .light = 0, .temperature_set = 2 }, 1140 + /* MacPro: temperature set 3 */ 1141 + { .accelerometer = 0, .light = 0, .temperature_set = 3 }, 1219 1142 }; 1220 1143 1221 1144 /* Note that DMI_MATCH(...,"MacBook") will match "MacBookPro1,1". ··· 1235 1154 DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), 1236 1155 DMI_MATCH(DMI_PRODUCT_NAME,"Macmini") }, 1237 1156 (void*)&applesmc_dmi_data[2]}, 1157 + { applesmc_dmi_match, "Apple MacPro2", { 1158 + DMI_MATCH(DMI_BOARD_VENDOR,"Apple"), 1159 + DMI_MATCH(DMI_PRODUCT_NAME,"MacPro2") }, 1160 + (void*)&applesmc_dmi_data[3]}, 1238 1161 { .ident = NULL } 1239 1162 }; 1240 1163 ··· 1289 1204 1290 1205 switch (count) { 1291 1206 default: 1292 - printk(KERN_WARNING "applesmc: More than 2 fans found," 1293 - " but at most 2 fans are supported" 1207 + printk(KERN_WARNING "applesmc: More than 4 fans found," 1208 + " but at most 4 fans are supported" 1294 1209 " by the driver.\n"); 1210 + case 4: 1211 + ret = sysfs_create_group(&pdev->dev.kobj, 1212 + &fan_attribute_groups[3]); 1213 + if (ret) 1214 + goto out_key_enumeration; 1215 + case 3: 1216 + ret = sysfs_create_group(&pdev->dev.kobj, 1217 + &fan_attribute_groups[2]); 1218 + if (ret) 1219 + goto out_key_enumeration; 1295 1220 case 2: 1296 1221 ret = sysfs_create_group(&pdev->dev.kobj, 1297 1222 &fan_attribute_groups[1]);