aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/hwmon/applesmc.c
diff options
context:
space:
mode:
authorHenrik Rydberg <rydberg@euromail.se>2010-11-10 05:58:04 -0500
committerGuenter Roeck <guenter.roeck@ericsson.com>2011-01-08 13:55:39 -0500
commit9792dadfce22ae1518c88577ac743a3077a85084 (patch)
tree5dbfb4edaeb30221507abd226cbd6924ec8d86c1 /drivers/hwmon/applesmc.c
parent5874583d5662de5550b0ed1c54a9dea70bcdcba4 (diff)
hwmon: (applesmc) Dynamic creation of temperature files
The current driver creates temperature files based on a list of temperature keys given per device. Apart from slow adaption to new machine models, the number of sensors also depends on the number of processors. This patch looks up the temperature keys dynamically, thereby supporting all models. Signed-off-by: Henrik Rydberg <rydberg@euromail.se> Signed-off-by: Guenter Roeck <guenter.roeck@ericsson.com>
Diffstat (limited to 'drivers/hwmon/applesmc.c')
-rw-r--r--drivers/hwmon/applesmc.c500
1 files changed, 111 insertions, 389 deletions
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index f213997adaec..03c24b7c9cbd 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -84,94 +84,6 @@
84#define FAN_TARGET_SPEED "F0Tg" /* r-w fpe2 (2 bytes) */ 84#define FAN_TARGET_SPEED "F0Tg" /* r-w fpe2 (2 bytes) */
85#define FAN_POSITION "F0ID" /* r-o char[16] */ 85#define FAN_POSITION "F0ID" /* r-o char[16] */
86 86
87/*
88 * Temperature sensors keys (sp78 - 2 bytes).
89 */
90static const char *temperature_sensors_sets[][41] = {
91/* Set 0: Macbook Pro */
92 { "TA0P", "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "Th0H",
93 "Th1H", "Tm0P", "Ts0P", "Ts1P", NULL },
94/* Set 1: Macbook2 set */
95 { "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TN1P", "TTF0", "Th0H",
96 "Th0S", "Th1H", NULL },
97/* Set 2: Macbook set */
98 { "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TN1P", "Th0H", "Th0S",
99 "Th1H", "Ts0P", NULL },
100/* Set 3: Macmini set */
101 { "TC0D", "TC0P", NULL },
102/* Set 4: Mac Pro (2 x Quad-Core) */
103 { "TA0P", "TCAG", "TCAH", "TCBG", "TCBH", "TC0C", "TC0D", "TC0P",
104 "TC1C", "TC1D", "TC2C", "TC2D", "TC3C", "TC3D", "THTG", "TH0P",
105 "TH1P", "TH2P", "TH3P", "TMAP", "TMAS", "TMBS", "TM0P", "TM0S",
106 "TM1P", "TM1S", "TM2P", "TM2S", "TM3S", "TM8P", "TM8S", "TM9P",
107 "TM9S", "TN0H", "TS0C", NULL },
108/* Set 5: iMac */
109 { "TC0D", "TA0P", "TG0P", "TG0D", "TG0H", "TH0P", "Tm0P", "TO0P",
110 "Tp0C", NULL },
111/* Set 6: Macbook3 set */
112 { "TB0T", "TC0D", "TC0P", "TM0P", "TN0P", "TTF0", "TW0P", "Th0H",
113 "Th0S", "Th1H", NULL },
114/* Set 7: Macbook Air */
115 { "TB0T", "TB1S", "TB1T", "TB2S", "TB2T", "TC0D", "TC0P", "TCFP",
116 "TTF0", "TW0P", "Th0H", "Tp0P", "TpFP", "Ts0P", "Ts0S", NULL },
117/* Set 8: Macbook Pro 4,1 (Penryn) */
118 { "TB0T", "TC0D", "TC0P", "TG0D", "TG0H", "TTF0", "TW0P", "Th0H",
119 "Th1H", "Th2H", "Tm0P", "Ts0P", NULL },
120/* Set 9: Macbook Pro 3,1 (Santa Rosa) */
121 { "TALP", "TB0T", "TC0D", "TC0P", "TG0D", "TG0H", "TTF0", "TW0P",
122 "Th0H", "Th1H", "Th2H", "Tm0P", "Ts0P", NULL },
123/* Set 10: iMac 5,1 */
124 { "TA0P", "TC0D", "TC0P", "TG0D", "TH0P", "TO0P", "Tm0P", NULL },
125/* Set 11: Macbook 5,1 */
126 { "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", "TC0P", "TN0D", "TN0P",
127 "TTF0", "Th0H", "Th1H", "ThFH", "Ts0P", "Ts0S", NULL },
128/* Set 12: Macbook Pro 5,1 */
129 { "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", "TC0F", "TC0P", "TG0D",
130 "TG0F", "TG0H", "TG0P", "TG0T", "TG1H", "TN0D", "TN0P", "TTF0",
131 "Th2H", "Tm0P", "Ts0P", "Ts0S", NULL },
132/* Set 13: iMac 8,1 */
133 { "TA0P", "TC0D", "TC0H", "TC0P", "TG0D", "TG0H", "TG0P", "TH0P",
134 "TL0P", "TO0P", "TW0P", "Tm0P", "Tp0P", NULL },
135/* Set 14: iMac 6,1 */
136 { "TA0P", "TC0D", "TC0H", "TC0P", "TG0D", "TG0H", "TG0P", "TH0P",
137 "TO0P", "Tp0P", NULL },
138/* Set 15: MacBook Air 2,1 */
139 { "TB0T", "TB1S", "TB1T", "TB2S", "TB2T", "TC0D", "TN0D", "TTF0",
140 "TV0P", "TVFP", "TW0P", "Th0P", "Tp0P", "Tp1P", "TpFP", "Ts0P",
141 "Ts0S", NULL },
142/* Set 16: Mac Pro 3,1 (2 x Quad-Core) */
143 { "TA0P", "TCAG", "TCAH", "TCBG", "TCBH", "TC0C", "TC0D", "TC0P",
144 "TC1C", "TC1D", "TC2C", "TC2D", "TC3C", "TC3D", "TH0P", "TH1P",
145 "TH2P", "TH3P", "TMAP", "TMAS", "TMBS", "TM0P", "TM0S", "TM1P",
146 "TM1S", "TM2P", "TM2S", "TM3S", "TM8P", "TM8S", "TM9P", "TM9S",
147 "TN0C", "TN0D", "TN0H", "TS0C", "Tp0C", "Tp1C", "Tv0S", "Tv1S",
148 NULL },
149/* Set 17: iMac 9,1 */
150 { "TA0P", "TC0D", "TC0H", "TC0P", "TG0D", "TG0H", "TH0P", "TL0P",
151 "TN0D", "TN0H", "TN0P", "TO0P", "Tm0P", "Tp0P", NULL },
152/* Set 18: MacBook Pro 2,2 */
153 { "TB0T", "TC0D", "TC0P", "TG0H", "TG0P", "TG0T", "TM0P", "TTF0",
154 "Th0H", "Th1H", "Tm0P", "Ts0P", NULL },
155/* Set 19: Macbook Pro 5,3 */
156 { "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", "TC0F", "TC0P", "TG0D",
157 "TG0F", "TG0H", "TG0P", "TG0T", "TN0D", "TN0P", "TTF0", "Th2H",
158 "Tm0P", "Ts0P", "Ts0S", NULL },
159/* Set 20: MacBook Pro 5,4 */
160 { "TB0T", "TB1T", "TB2T", "TB3T", "TC0D", "TC0F", "TC0P", "TN0D",
161 "TN0P", "TTF0", "Th2H", "Ts0P", "Ts0S", NULL },
162/* Set 21: MacBook Pro 6,2 */
163 { "TB0T", "TB1T", "TB2T", "TC0C", "TC0D", "TC0P", "TC1C", "TG0D",
164 "TG0P", "TG0T", "TMCD", "TP0P", "TPCD", "Th1H", "Th2H", "Tm0P",
165 "Ts0P", "Ts0S", NULL },
166/* Set 22: MacBook Pro 7,1 */
167 { "TB0T", "TB1T", "TB2T", "TC0D", "TC0P", "TN0D", "TN0P", "TN0S",
168 "TN1D", "TN1F", "TN1G", "TN1S", "Th1H", "Ts0P", "Ts0S", NULL },
169/* Set 23: MacBook Air 3,1 */
170 { "TB0T", "TB1T", "TB2T", "TC0D", "TC0E", "TC0P", "TC1E", "TCZ3",
171 "TCZ4", "TCZ5", "TG0E", "TG1E", "TG2E", "TGZ3", "TGZ4", "TGZ5",
172 "TH0F", "TH0O", "TM0P" },
173};
174
175/* List of keys used to read/write fan speeds */ 87/* List of keys used to read/write fan speeds */
176static const char* fan_speed_keys[] = { 88static const char* fan_speed_keys[] = {
177 FAN_ACTUAL_SPEED, 89 FAN_ACTUAL_SPEED,
@@ -192,6 +104,8 @@ static const char* fan_speed_keys[] = {
192#define SENSOR_Y 1 104#define SENSOR_Y 1
193#define SENSOR_Z 2 105#define SENSOR_Z 2
194 106
107#define to_index(attr) (to_sensor_dev_attr(attr)->index)
108
195/* Structure to be passed to DMI_MATCH function */ 109/* Structure to be passed to DMI_MATCH function */
196struct dmi_match_data { 110struct dmi_match_data {
197/* Indicates whether this computer has an accelerometer. */ 111/* Indicates whether this computer has an accelerometer. */
@@ -202,6 +116,20 @@ struct dmi_match_data {
202 int temperature_set; 116 int temperature_set;
203}; 117};
204 118
119/* Dynamic device node attributes */
120struct applesmc_dev_attr {
121 struct sensor_device_attribute sda; /* hwmon attributes */
122 char name[32]; /* room for node file name */
123};
124
125/* Dynamic device node group */
126struct applesmc_node_group {
127 char *format; /* format string */
128 void *show; /* show function */
129 void *store; /* store function */
130 struct applesmc_dev_attr *nodes; /* dynamic node array */
131};
132
205/* AppleSMC entry - cached register information */ 133/* AppleSMC entry - cached register information */
206struct applesmc_entry { 134struct applesmc_entry {
207 char key[5]; /* four-letter key code */ 135 char key[5]; /* four-letter key code */
@@ -215,6 +143,9 @@ struct applesmc_entry {
215static struct applesmc_registers { 143static struct applesmc_registers {
216 struct mutex mutex; /* register read/write mutex */ 144 struct mutex mutex; /* register read/write mutex */
217 unsigned int key_count; /* number of SMC registers */ 145 unsigned int key_count; /* number of SMC registers */
146 unsigned int temp_count; /* number of temperature registers */
147 unsigned int temp_begin; /* temperature lower index bound */
148 unsigned int temp_end; /* temperature upper index bound */
218 bool init_complete; /* true when fully initialized */ 149 bool init_complete; /* true when fully initialized */
219 struct applesmc_entry *cache; /* cached key entries */ 150 struct applesmc_entry *cache; /* cached key entries */
220} smcreg = { 151} smcreg = {
@@ -239,9 +170,6 @@ static unsigned int applesmc_light;
239/* The number of fans handled by the driver */ 170/* The number of fans handled by the driver */
240static unsigned int fans_handled; 171static unsigned int fans_handled;
241 172
242/* Indicates which temperature sensors set to use. */
243static unsigned int applesmc_temperature_set;
244
245/* 173/*
246 * Last index written to key_at_index sysfs file, and value to use for all other 174 * Last index written to key_at_index sysfs file, and value to use for all other
247 * key_at_index_* sysfs files. 175 * key_at_index_* sysfs files.
@@ -592,9 +520,17 @@ static int applesmc_init_smcreg_try(void)
592 if (!s->cache) 520 if (!s->cache)
593 return -ENOMEM; 521 return -ENOMEM;
594 522
523 ret = applesmc_get_lower_bound(&s->temp_begin, "T");
524 if (ret)
525 return ret;
526 ret = applesmc_get_lower_bound(&s->temp_end, "U");
527 if (ret)
528 return ret;
529 s->temp_count = s->temp_end - s->temp_begin;
530
595 s->init_complete = true; 531 s->init_complete = true;
596 532
597 pr_info("key=%d\n", s->key_count); 533 pr_info("key=%d temp=%d\n", s->key_count, s->temp_count);
598 534
599 return 0; 535 return 0;
600} 536}
@@ -775,32 +711,38 @@ out:
775static ssize_t applesmc_show_sensor_label(struct device *dev, 711static ssize_t applesmc_show_sensor_label(struct device *dev,
776 struct device_attribute *devattr, char *sysfsbuf) 712 struct device_attribute *devattr, char *sysfsbuf)
777{ 713{
778 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 714 int index = smcreg.temp_begin + to_index(devattr);
779 const char *key = 715 const struct applesmc_entry *entry;
780 temperature_sensors_sets[applesmc_temperature_set][attr->index];
781 716
782 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", key); 717 entry = applesmc_get_entry_by_index(index);
718 if (IS_ERR(entry))
719 return PTR_ERR(entry);
720
721 return snprintf(sysfsbuf, PAGE_SIZE, "%s\n", entry->key);
783} 722}
784 723
785/* Displays degree Celsius * 1000 */ 724/* Displays degree Celsius * 1000 */
786static ssize_t applesmc_show_temperature(struct device *dev, 725static ssize_t applesmc_show_temperature(struct device *dev,
787 struct device_attribute *devattr, char *sysfsbuf) 726 struct device_attribute *devattr, char *sysfsbuf)
788{ 727{
728 int index = smcreg.temp_begin + to_index(devattr);
729 const struct applesmc_entry *entry;
789 int ret; 730 int ret;
790 u8 buffer[2]; 731 u8 buffer[2];
791 unsigned int temp; 732 unsigned int temp;
792 struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
793 const char* key =
794 temperature_sensors_sets[applesmc_temperature_set][attr->index];
795 733
796 ret = applesmc_read_key(key, buffer, 2); 734 entry = applesmc_get_entry_by_index(index);
797 temp = buffer[0]*1000; 735 if (IS_ERR(entry))
798 temp += (buffer[1] >> 6) * 250; 736 return PTR_ERR(entry);
799 737
738 ret = applesmc_read_entry(entry, buffer, 2);
800 if (ret) 739 if (ret)
801 return ret; 740 return ret;
802 else 741
803 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", temp); 742 temp = buffer[0]*1000;
743 temp += (buffer[1] >> 6) * 250;
744
745 return snprintf(sysfsbuf, PAGE_SIZE, "%u\n", temp);
804} 746}
805 747
806static ssize_t applesmc_show_fan_speed(struct device *dev, 748static ssize_t applesmc_show_fan_speed(struct device *dev,
@@ -1161,263 +1103,10 @@ static const struct attribute_group fan_attribute_groups[] = {
1161 { .attrs = fan4_attributes }, 1103 { .attrs = fan4_attributes },
1162}; 1104};
1163 1105
1164/* 1106static struct applesmc_node_group temp_group[] = {
1165 * Temperature sensors sysfs entries. 1107 { "temp%d_label", applesmc_show_sensor_label },
1166 */ 1108 { "temp%d_input", applesmc_show_temperature },
1167static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, 1109 { }
1168 applesmc_show_sensor_label, NULL, 0);
1169static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO,
1170 applesmc_show_sensor_label, NULL, 1);
1171static SENSOR_DEVICE_ATTR(temp3_label, S_IRUGO,
1172 applesmc_show_sensor_label, NULL, 2);
1173static SENSOR_DEVICE_ATTR(temp4_label, S_IRUGO,
1174 applesmc_show_sensor_label, NULL, 3);
1175static SENSOR_DEVICE_ATTR(temp5_label, S_IRUGO,
1176 applesmc_show_sensor_label, NULL, 4);
1177static SENSOR_DEVICE_ATTR(temp6_label, S_IRUGO,
1178 applesmc_show_sensor_label, NULL, 5);
1179static SENSOR_DEVICE_ATTR(temp7_label, S_IRUGO,
1180 applesmc_show_sensor_label, NULL, 6);
1181static SENSOR_DEVICE_ATTR(temp8_label, S_IRUGO,
1182 applesmc_show_sensor_label, NULL, 7);
1183static SENSOR_DEVICE_ATTR(temp9_label, S_IRUGO,
1184 applesmc_show_sensor_label, NULL, 8);
1185static SENSOR_DEVICE_ATTR(temp10_label, S_IRUGO,
1186 applesmc_show_sensor_label, NULL, 9);
1187static SENSOR_DEVICE_ATTR(temp11_label, S_IRUGO,
1188 applesmc_show_sensor_label, NULL, 10);
1189static SENSOR_DEVICE_ATTR(temp12_label, S_IRUGO,
1190 applesmc_show_sensor_label, NULL, 11);
1191static SENSOR_DEVICE_ATTR(temp13_label, S_IRUGO,
1192 applesmc_show_sensor_label, NULL, 12);
1193static SENSOR_DEVICE_ATTR(temp14_label, S_IRUGO,
1194 applesmc_show_sensor_label, NULL, 13);
1195static SENSOR_DEVICE_ATTR(temp15_label, S_IRUGO,
1196 applesmc_show_sensor_label, NULL, 14);
1197static SENSOR_DEVICE_ATTR(temp16_label, S_IRUGO,
1198 applesmc_show_sensor_label, NULL, 15);
1199static SENSOR_DEVICE_ATTR(temp17_label, S_IRUGO,
1200 applesmc_show_sensor_label, NULL, 16);
1201static SENSOR_DEVICE_ATTR(temp18_label, S_IRUGO,
1202 applesmc_show_sensor_label, NULL, 17);
1203static SENSOR_DEVICE_ATTR(temp19_label, S_IRUGO,
1204 applesmc_show_sensor_label, NULL, 18);
1205static SENSOR_DEVICE_ATTR(temp20_label, S_IRUGO,
1206 applesmc_show_sensor_label, NULL, 19);
1207static SENSOR_DEVICE_ATTR(temp21_label, S_IRUGO,
1208 applesmc_show_sensor_label, NULL, 20);
1209static SENSOR_DEVICE_ATTR(temp22_label, S_IRUGO,
1210 applesmc_show_sensor_label, NULL, 21);
1211static SENSOR_DEVICE_ATTR(temp23_label, S_IRUGO,
1212 applesmc_show_sensor_label, NULL, 22);
1213static SENSOR_DEVICE_ATTR(temp24_label, S_IRUGO,
1214 applesmc_show_sensor_label, NULL, 23);
1215static SENSOR_DEVICE_ATTR(temp25_label, S_IRUGO,
1216 applesmc_show_sensor_label, NULL, 24);
1217static SENSOR_DEVICE_ATTR(temp26_label, S_IRUGO,
1218 applesmc_show_sensor_label, NULL, 25);
1219static SENSOR_DEVICE_ATTR(temp27_label, S_IRUGO,
1220 applesmc_show_sensor_label, NULL, 26);
1221static SENSOR_DEVICE_ATTR(temp28_label, S_IRUGO,
1222 applesmc_show_sensor_label, NULL, 27);
1223static SENSOR_DEVICE_ATTR(temp29_label, S_IRUGO,
1224 applesmc_show_sensor_label, NULL, 28);
1225static SENSOR_DEVICE_ATTR(temp30_label, S_IRUGO,
1226 applesmc_show_sensor_label, NULL, 29);
1227static SENSOR_DEVICE_ATTR(temp31_label, S_IRUGO,
1228 applesmc_show_sensor_label, NULL, 30);
1229static SENSOR_DEVICE_ATTR(temp32_label, S_IRUGO,
1230 applesmc_show_sensor_label, NULL, 31);
1231static SENSOR_DEVICE_ATTR(temp33_label, S_IRUGO,
1232 applesmc_show_sensor_label, NULL, 32);
1233static SENSOR_DEVICE_ATTR(temp34_label, S_IRUGO,
1234 applesmc_show_sensor_label, NULL, 33);
1235static SENSOR_DEVICE_ATTR(temp35_label, S_IRUGO,
1236 applesmc_show_sensor_label, NULL, 34);
1237static SENSOR_DEVICE_ATTR(temp36_label, S_IRUGO,
1238 applesmc_show_sensor_label, NULL, 35);
1239static SENSOR_DEVICE_ATTR(temp37_label, S_IRUGO,
1240 applesmc_show_sensor_label, NULL, 36);
1241static SENSOR_DEVICE_ATTR(temp38_label, S_IRUGO,
1242 applesmc_show_sensor_label, NULL, 37);
1243static SENSOR_DEVICE_ATTR(temp39_label, S_IRUGO,
1244 applesmc_show_sensor_label, NULL, 38);
1245static SENSOR_DEVICE_ATTR(temp40_label, S_IRUGO,
1246 applesmc_show_sensor_label, NULL, 39);
1247static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
1248 applesmc_show_temperature, NULL, 0);
1249static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO,
1250 applesmc_show_temperature, NULL, 1);
1251static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO,
1252 applesmc_show_temperature, NULL, 2);
1253static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO,
1254 applesmc_show_temperature, NULL, 3);
1255static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO,
1256 applesmc_show_temperature, NULL, 4);
1257static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO,
1258 applesmc_show_temperature, NULL, 5);
1259static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO,
1260 applesmc_show_temperature, NULL, 6);
1261static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO,
1262 applesmc_show_temperature, NULL, 7);
1263static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO,
1264 applesmc_show_temperature, NULL, 8);
1265static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO,
1266 applesmc_show_temperature, NULL, 9);
1267static SENSOR_DEVICE_ATTR(temp11_input, S_IRUGO,
1268 applesmc_show_temperature, NULL, 10);
1269static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO,
1270 applesmc_show_temperature, NULL, 11);
1271static SENSOR_DEVICE_ATTR(temp13_input, S_IRUGO,
1272 applesmc_show_temperature, NULL, 12);
1273static SENSOR_DEVICE_ATTR(temp14_input, S_IRUGO,
1274 applesmc_show_temperature, NULL, 13);
1275static SENSOR_DEVICE_ATTR(temp15_input, S_IRUGO,
1276 applesmc_show_temperature, NULL, 14);
1277static SENSOR_DEVICE_ATTR(temp16_input, S_IRUGO,
1278 applesmc_show_temperature, NULL, 15);
1279static SENSOR_DEVICE_ATTR(temp17_input, S_IRUGO,
1280 applesmc_show_temperature, NULL, 16);
1281static SENSOR_DEVICE_ATTR(temp18_input, S_IRUGO,
1282 applesmc_show_temperature, NULL, 17);
1283static SENSOR_DEVICE_ATTR(temp19_input, S_IRUGO,
1284 applesmc_show_temperature, NULL, 18);
1285static SENSOR_DEVICE_ATTR(temp20_input, S_IRUGO,
1286 applesmc_show_temperature, NULL, 19);
1287static SENSOR_DEVICE_ATTR(temp21_input, S_IRUGO,
1288 applesmc_show_temperature, NULL, 20);
1289static SENSOR_DEVICE_ATTR(temp22_input, S_IRUGO,
1290 applesmc_show_temperature, NULL, 21);
1291static SENSOR_DEVICE_ATTR(temp23_input, S_IRUGO,
1292 applesmc_show_temperature, NULL, 22);
1293static SENSOR_DEVICE_ATTR(temp24_input, S_IRUGO,
1294 applesmc_show_temperature, NULL, 23);
1295static SENSOR_DEVICE_ATTR(temp25_input, S_IRUGO,
1296 applesmc_show_temperature, NULL, 24);
1297static SENSOR_DEVICE_ATTR(temp26_input, S_IRUGO,
1298 applesmc_show_temperature, NULL, 25);
1299static SENSOR_DEVICE_ATTR(temp27_input, S_IRUGO,
1300 applesmc_show_temperature, NULL, 26);
1301static SENSOR_DEVICE_ATTR(temp28_input, S_IRUGO,
1302 applesmc_show_temperature, NULL, 27);
1303static SENSOR_DEVICE_ATTR(temp29_input, S_IRUGO,
1304 applesmc_show_temperature, NULL, 28);
1305static SENSOR_DEVICE_ATTR(temp30_input, S_IRUGO,
1306 applesmc_show_temperature, NULL, 29);
1307static SENSOR_DEVICE_ATTR(temp31_input, S_IRUGO,
1308 applesmc_show_temperature, NULL, 30);
1309static SENSOR_DEVICE_ATTR(temp32_input, S_IRUGO,
1310 applesmc_show_temperature, NULL, 31);
1311static SENSOR_DEVICE_ATTR(temp33_input, S_IRUGO,
1312 applesmc_show_temperature, NULL, 32);
1313static SENSOR_DEVICE_ATTR(temp34_input, S_IRUGO,
1314 applesmc_show_temperature, NULL, 33);
1315static SENSOR_DEVICE_ATTR(temp35_input, S_IRUGO,
1316 applesmc_show_temperature, NULL, 34);
1317static SENSOR_DEVICE_ATTR(temp36_input, S_IRUGO,
1318 applesmc_show_temperature, NULL, 35);
1319static SENSOR_DEVICE_ATTR(temp37_input, S_IRUGO,
1320 applesmc_show_temperature, NULL, 36);
1321static SENSOR_DEVICE_ATTR(temp38_input, S_IRUGO,
1322 applesmc_show_temperature, NULL, 37);
1323static SENSOR_DEVICE_ATTR(temp39_input, S_IRUGO,
1324 applesmc_show_temperature, NULL, 38);
1325static SENSOR_DEVICE_ATTR(temp40_input, S_IRUGO,
1326 applesmc_show_temperature, NULL, 39);
1327
1328static struct attribute *label_attributes[] = {
1329 &sensor_dev_attr_temp1_label.dev_attr.attr,
1330 &sensor_dev_attr_temp2_label.dev_attr.attr,
1331 &sensor_dev_attr_temp3_label.dev_attr.attr,
1332 &sensor_dev_attr_temp4_label.dev_attr.attr,
1333 &sensor_dev_attr_temp5_label.dev_attr.attr,
1334 &sensor_dev_attr_temp6_label.dev_attr.attr,
1335 &sensor_dev_attr_temp7_label.dev_attr.attr,
1336 &sensor_dev_attr_temp8_label.dev_attr.attr,
1337 &sensor_dev_attr_temp9_label.dev_attr.attr,
1338 &sensor_dev_attr_temp10_label.dev_attr.attr,
1339 &sensor_dev_attr_temp11_label.dev_attr.attr,
1340 &sensor_dev_attr_temp12_label.dev_attr.attr,
1341 &sensor_dev_attr_temp13_label.dev_attr.attr,
1342 &sensor_dev_attr_temp14_label.dev_attr.attr,
1343 &sensor_dev_attr_temp15_label.dev_attr.attr,
1344 &sensor_dev_attr_temp16_label.dev_attr.attr,
1345 &sensor_dev_attr_temp17_label.dev_attr.attr,
1346 &sensor_dev_attr_temp18_label.dev_attr.attr,
1347 &sensor_dev_attr_temp19_label.dev_attr.attr,
1348 &sensor_dev_attr_temp20_label.dev_attr.attr,
1349 &sensor_dev_attr_temp21_label.dev_attr.attr,
1350 &sensor_dev_attr_temp22_label.dev_attr.attr,
1351 &sensor_dev_attr_temp23_label.dev_attr.attr,
1352 &sensor_dev_attr_temp24_label.dev_attr.attr,
1353 &sensor_dev_attr_temp25_label.dev_attr.attr,
1354 &sensor_dev_attr_temp26_label.dev_attr.attr,
1355 &sensor_dev_attr_temp27_label.dev_attr.attr,
1356 &sensor_dev_attr_temp28_label.dev_attr.attr,
1357 &sensor_dev_attr_temp29_label.dev_attr.attr,
1358 &sensor_dev_attr_temp30_label.dev_attr.attr,
1359 &sensor_dev_attr_temp31_label.dev_attr.attr,
1360 &sensor_dev_attr_temp32_label.dev_attr.attr,
1361 &sensor_dev_attr_temp33_label.dev_attr.attr,
1362 &sensor_dev_attr_temp34_label.dev_attr.attr,
1363 &sensor_dev_attr_temp35_label.dev_attr.attr,
1364 &sensor_dev_attr_temp36_label.dev_attr.attr,
1365 &sensor_dev_attr_temp37_label.dev_attr.attr,
1366 &sensor_dev_attr_temp38_label.dev_attr.attr,
1367 &sensor_dev_attr_temp39_label.dev_attr.attr,
1368 &sensor_dev_attr_temp40_label.dev_attr.attr,
1369 NULL
1370};
1371
1372static struct attribute *temperature_attributes[] = {
1373 &sensor_dev_attr_temp1_input.dev_attr.attr,
1374 &sensor_dev_attr_temp2_input.dev_attr.attr,
1375 &sensor_dev_attr_temp3_input.dev_attr.attr,
1376 &sensor_dev_attr_temp4_input.dev_attr.attr,
1377 &sensor_dev_attr_temp5_input.dev_attr.attr,
1378 &sensor_dev_attr_temp6_input.dev_attr.attr,
1379 &sensor_dev_attr_temp7_input.dev_attr.attr,
1380 &sensor_dev_attr_temp8_input.dev_attr.attr,
1381 &sensor_dev_attr_temp9_input.dev_attr.attr,
1382 &sensor_dev_attr_temp10_input.dev_attr.attr,
1383 &sensor_dev_attr_temp11_input.dev_attr.attr,
1384 &sensor_dev_attr_temp12_input.dev_attr.attr,
1385 &sensor_dev_attr_temp13_input.dev_attr.attr,
1386 &sensor_dev_attr_temp14_input.dev_attr.attr,
1387 &sensor_dev_attr_temp15_input.dev_attr.attr,
1388 &sensor_dev_attr_temp16_input.dev_attr.attr,
1389 &sensor_dev_attr_temp17_input.dev_attr.attr,
1390 &sensor_dev_attr_temp18_input.dev_attr.attr,
1391 &sensor_dev_attr_temp19_input.dev_attr.attr,
1392 &sensor_dev_attr_temp20_input.dev_attr.attr,
1393 &sensor_dev_attr_temp21_input.dev_attr.attr,
1394 &sensor_dev_attr_temp22_input.dev_attr.attr,
1395 &sensor_dev_attr_temp23_input.dev_attr.attr,
1396 &sensor_dev_attr_temp24_input.dev_attr.attr,
1397 &sensor_dev_attr_temp25_input.dev_attr.attr,
1398 &sensor_dev_attr_temp26_input.dev_attr.attr,
1399 &sensor_dev_attr_temp27_input.dev_attr.attr,
1400 &sensor_dev_attr_temp28_input.dev_attr.attr,
1401 &sensor_dev_attr_temp29_input.dev_attr.attr,
1402 &sensor_dev_attr_temp30_input.dev_attr.attr,
1403 &sensor_dev_attr_temp31_input.dev_attr.attr,
1404 &sensor_dev_attr_temp32_input.dev_attr.attr,
1405 &sensor_dev_attr_temp33_input.dev_attr.attr,
1406 &sensor_dev_attr_temp34_input.dev_attr.attr,
1407 &sensor_dev_attr_temp35_input.dev_attr.attr,
1408 &sensor_dev_attr_temp36_input.dev_attr.attr,
1409 &sensor_dev_attr_temp37_input.dev_attr.attr,
1410 &sensor_dev_attr_temp38_input.dev_attr.attr,
1411 &sensor_dev_attr_temp39_input.dev_attr.attr,
1412 &sensor_dev_attr_temp40_input.dev_attr.attr,
1413 NULL
1414};
1415
1416static const struct attribute_group temperature_attributes_group =
1417 { .attrs = temperature_attributes };
1418
1419static const struct attribute_group label_attributes_group = {
1420 .attrs = label_attributes
1421}; 1110};
1422 1111
1423/* Module stuff */ 1112/* Module stuff */
@@ -1427,7 +1116,6 @@ static const struct attribute_group label_attributes_group = {
1427 */ 1116 */
1428static int applesmc_dmi_match(const struct dmi_system_id *id) 1117static int applesmc_dmi_match(const struct dmi_system_id *id)
1429{ 1118{
1430 int i = 0;
1431 struct dmi_match_data* dmi_data = id->driver_data; 1119 struct dmi_match_data* dmi_data = id->driver_data;
1432 pr_info("%s detected:\n", id->ident); 1120 pr_info("%s detected:\n", id->ident);
1433 applesmc_accelerometer = dmi_data->accelerometer; 1121 applesmc_accelerometer = dmi_data->accelerometer;
@@ -1437,13 +1125,65 @@ static int applesmc_dmi_match(const struct dmi_system_id *id)
1437 pr_info(" - Model %s light sensors and backlight\n", 1125 pr_info(" - Model %s light sensors and backlight\n",
1438 applesmc_light ? "with" : "without"); 1126 applesmc_light ? "with" : "without");
1439 1127
1440 applesmc_temperature_set = dmi_data->temperature_set;
1441 while (temperature_sensors_sets[applesmc_temperature_set][i] != NULL)
1442 i++;
1443 pr_info(" - Model with %d temperature sensors\n", i);
1444 return 1; 1128 return 1;
1445} 1129}
1446 1130
1131/*
1132 * applesmc_destroy_nodes - remove files and free associated memory
1133 */
1134static void applesmc_destroy_nodes(struct applesmc_node_group *groups)
1135{
1136 struct applesmc_node_group *grp;
1137 struct applesmc_dev_attr *node;
1138
1139 for (grp = groups; grp->nodes; grp++) {
1140 for (node = grp->nodes; node->sda.dev_attr.attr.name; node++)
1141 sysfs_remove_file(&pdev->dev.kobj,
1142 &node->sda.dev_attr.attr);
1143 kfree(grp->nodes);
1144 grp->nodes = NULL;
1145 }
1146}
1147
1148/*
1149 * applesmc_create_nodes - create a two-dimensional group of sysfs files
1150 */
1151static int applesmc_create_nodes(struct applesmc_node_group *groups, int num)
1152{
1153 struct applesmc_node_group *grp;
1154 struct applesmc_dev_attr *node;
1155 struct attribute *attr;
1156 int ret, i;
1157
1158 for (grp = groups; grp->format; grp++) {
1159 grp->nodes = kcalloc(num + 1, sizeof(*node), GFP_KERNEL);
1160 if (!grp->nodes) {
1161 ret = -ENOMEM;
1162 goto out;
1163 }
1164 for (i = 0; i < num; i++) {
1165 node = &grp->nodes[i];
1166 sprintf(node->name, grp->format, i + 1);
1167 node->sda.index = i;
1168 node->sda.dev_attr.show = grp->show;
1169 node->sda.dev_attr.store = grp->store;
1170 attr = &node->sda.dev_attr.attr;
1171 attr->name = node->name;
1172 attr->mode = S_IRUGO | (grp->store ? S_IWUSR : 0);
1173 ret = sysfs_create_file(&pdev->dev.kobj, attr);
1174 if (ret) {
1175 attr->name = NULL;
1176 goto out;
1177 }
1178 }
1179 }
1180
1181 return 0;
1182out:
1183 applesmc_destroy_nodes(groups);
1184 return ret;
1185}
1186
1447/* Create accelerometer ressources */ 1187/* Create accelerometer ressources */
1448static int applesmc_create_accelerometer(void) 1188static int applesmc_create_accelerometer(void)
1449{ 1189{
@@ -1668,7 +1408,6 @@ static int __init applesmc_init(void)
1668{ 1408{
1669 int ret; 1409 int ret;
1670 int count; 1410 int count;
1671 int i;
1672 1411
1673 if (!dmi_check_system(applesmc_whitelist)) { 1412 if (!dmi_check_system(applesmc_whitelist)) {
1674 pr_warn("supported laptop not found!\n"); 1413 pr_warn("supported laptop not found!\n");
@@ -1727,24 +1466,9 @@ static int __init applesmc_init(void)
1727 fans_handled++; 1466 fans_handled++;
1728 } 1467 }
1729 1468
1730 for (i = 0; 1469 ret = applesmc_create_nodes(temp_group, smcreg.temp_count);
1731 temperature_sensors_sets[applesmc_temperature_set][i] != NULL; 1470 if (ret)
1732 i++) { 1471 goto out_fans;
1733 if (temperature_attributes[i] == NULL ||
1734 label_attributes[i] == NULL) {
1735 pr_err("More temperature sensors in temperature_sensors_sets (at least %i) than available sysfs files in temperature_attributes (%i), please report this bug\n",
1736 i, i-1);
1737 goto out_temperature;
1738 }
1739 ret = sysfs_create_file(&pdev->dev.kobj,
1740 temperature_attributes[i]);
1741 if (ret)
1742 goto out_temperature;
1743 ret = sysfs_create_file(&pdev->dev.kobj,
1744 label_attributes[i]);
1745 if (ret)
1746 goto out_temperature;
1747 }
1748 1472
1749 if (applesmc_accelerometer) { 1473 if (applesmc_accelerometer) {
1750 ret = applesmc_create_accelerometer(); 1474 ret = applesmc_create_accelerometer();
@@ -1794,8 +1518,7 @@ out_accelerometer:
1794 if (applesmc_accelerometer) 1518 if (applesmc_accelerometer)
1795 applesmc_release_accelerometer(); 1519 applesmc_release_accelerometer();
1796out_temperature: 1520out_temperature:
1797 sysfs_remove_group(&pdev->dev.kobj, &label_attributes_group); 1521 applesmc_destroy_nodes(temp_group);
1798 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1799out_fans: 1522out_fans:
1800 while (fans_handled) 1523 while (fans_handled)
1801 sysfs_remove_group(&pdev->dev.kobj, 1524 sysfs_remove_group(&pdev->dev.kobj,
@@ -1826,8 +1549,7 @@ static void __exit applesmc_exit(void)
1826 } 1549 }
1827 if (applesmc_accelerometer) 1550 if (applesmc_accelerometer)
1828 applesmc_release_accelerometer(); 1551 applesmc_release_accelerometer();
1829 sysfs_remove_group(&pdev->dev.kobj, &label_attributes_group); 1552 applesmc_destroy_nodes(temp_group);
1830 sysfs_remove_group(&pdev->dev.kobj, &temperature_attributes_group);
1831 while (fans_handled) 1553 while (fans_handled)
1832 sysfs_remove_group(&pdev->dev.kobj, 1554 sysfs_remove_group(&pdev->dev.kobj,
1833 &fan_attribute_groups[--fans_handled]); 1555 &fan_attribute_groups[--fans_handled]);