diff options
author | Henrik Rydberg <rydberg@euromail.se> | 2010-11-10 05:58:04 -0500 |
---|---|---|
committer | Guenter Roeck <guenter.roeck@ericsson.com> | 2011-01-08 13:55:39 -0500 |
commit | 9792dadfce22ae1518c88577ac743a3077a85084 (patch) | |
tree | 5dbfb4edaeb30221507abd226cbd6924ec8d86c1 /drivers/hwmon/applesmc.c | |
parent | 5874583d5662de5550b0ed1c54a9dea70bcdcba4 (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.c | 500 |
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 | */ | ||
90 | static 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 */ |
176 | static const char* fan_speed_keys[] = { | 88 | static 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 */ |
196 | struct dmi_match_data { | 110 | struct 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 */ | ||
120 | struct 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 */ | ||
126 | struct 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 */ |
206 | struct applesmc_entry { | 134 | struct 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 { | |||
215 | static struct applesmc_registers { | 143 | static 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 */ |
240 | static unsigned int fans_handled; | 171 | static unsigned int fans_handled; |
241 | 172 | ||
242 | /* Indicates which temperature sensors set to use. */ | ||
243 | static 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: | |||
775 | static ssize_t applesmc_show_sensor_label(struct device *dev, | 711 | static 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 */ |
786 | static ssize_t applesmc_show_temperature(struct device *dev, | 725 | static 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 | ||
806 | static ssize_t applesmc_show_fan_speed(struct device *dev, | 748 | static 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 | /* | 1106 | static 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 }, |
1167 | static SENSOR_DEVICE_ATTR(temp1_label, S_IRUGO, | 1109 | { } |
1168 | applesmc_show_sensor_label, NULL, 0); | ||
1169 | static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, | ||
1170 | applesmc_show_sensor_label, NULL, 1); | ||
1171 | static SENSOR_DEVICE_ATTR(temp3_label, S_IRUGO, | ||
1172 | applesmc_show_sensor_label, NULL, 2); | ||
1173 | static SENSOR_DEVICE_ATTR(temp4_label, S_IRUGO, | ||
1174 | applesmc_show_sensor_label, NULL, 3); | ||
1175 | static SENSOR_DEVICE_ATTR(temp5_label, S_IRUGO, | ||
1176 | applesmc_show_sensor_label, NULL, 4); | ||
1177 | static SENSOR_DEVICE_ATTR(temp6_label, S_IRUGO, | ||
1178 | applesmc_show_sensor_label, NULL, 5); | ||
1179 | static SENSOR_DEVICE_ATTR(temp7_label, S_IRUGO, | ||
1180 | applesmc_show_sensor_label, NULL, 6); | ||
1181 | static SENSOR_DEVICE_ATTR(temp8_label, S_IRUGO, | ||
1182 | applesmc_show_sensor_label, NULL, 7); | ||
1183 | static SENSOR_DEVICE_ATTR(temp9_label, S_IRUGO, | ||
1184 | applesmc_show_sensor_label, NULL, 8); | ||
1185 | static SENSOR_DEVICE_ATTR(temp10_label, S_IRUGO, | ||
1186 | applesmc_show_sensor_label, NULL, 9); | ||
1187 | static SENSOR_DEVICE_ATTR(temp11_label, S_IRUGO, | ||
1188 | applesmc_show_sensor_label, NULL, 10); | ||
1189 | static SENSOR_DEVICE_ATTR(temp12_label, S_IRUGO, | ||
1190 | applesmc_show_sensor_label, NULL, 11); | ||
1191 | static SENSOR_DEVICE_ATTR(temp13_label, S_IRUGO, | ||
1192 | applesmc_show_sensor_label, NULL, 12); | ||
1193 | static SENSOR_DEVICE_ATTR(temp14_label, S_IRUGO, | ||
1194 | applesmc_show_sensor_label, NULL, 13); | ||
1195 | static SENSOR_DEVICE_ATTR(temp15_label, S_IRUGO, | ||
1196 | applesmc_show_sensor_label, NULL, 14); | ||
1197 | static SENSOR_DEVICE_ATTR(temp16_label, S_IRUGO, | ||
1198 | applesmc_show_sensor_label, NULL, 15); | ||
1199 | static SENSOR_DEVICE_ATTR(temp17_label, S_IRUGO, | ||
1200 | applesmc_show_sensor_label, NULL, 16); | ||
1201 | static SENSOR_DEVICE_ATTR(temp18_label, S_IRUGO, | ||
1202 | applesmc_show_sensor_label, NULL, 17); | ||
1203 | static SENSOR_DEVICE_ATTR(temp19_label, S_IRUGO, | ||
1204 | applesmc_show_sensor_label, NULL, 18); | ||
1205 | static SENSOR_DEVICE_ATTR(temp20_label, S_IRUGO, | ||
1206 | applesmc_show_sensor_label, NULL, 19); | ||
1207 | static SENSOR_DEVICE_ATTR(temp21_label, S_IRUGO, | ||
1208 | applesmc_show_sensor_label, NULL, 20); | ||
1209 | static SENSOR_DEVICE_ATTR(temp22_label, S_IRUGO, | ||
1210 | applesmc_show_sensor_label, NULL, 21); | ||
1211 | static SENSOR_DEVICE_ATTR(temp23_label, S_IRUGO, | ||
1212 | applesmc_show_sensor_label, NULL, 22); | ||
1213 | static SENSOR_DEVICE_ATTR(temp24_label, S_IRUGO, | ||
1214 | applesmc_show_sensor_label, NULL, 23); | ||
1215 | static SENSOR_DEVICE_ATTR(temp25_label, S_IRUGO, | ||
1216 | applesmc_show_sensor_label, NULL, 24); | ||
1217 | static SENSOR_DEVICE_ATTR(temp26_label, S_IRUGO, | ||
1218 | applesmc_show_sensor_label, NULL, 25); | ||
1219 | static SENSOR_DEVICE_ATTR(temp27_label, S_IRUGO, | ||
1220 | applesmc_show_sensor_label, NULL, 26); | ||
1221 | static SENSOR_DEVICE_ATTR(temp28_label, S_IRUGO, | ||
1222 | applesmc_show_sensor_label, NULL, 27); | ||
1223 | static SENSOR_DEVICE_ATTR(temp29_label, S_IRUGO, | ||
1224 | applesmc_show_sensor_label, NULL, 28); | ||
1225 | static SENSOR_DEVICE_ATTR(temp30_label, S_IRUGO, | ||
1226 | applesmc_show_sensor_label, NULL, 29); | ||
1227 | static SENSOR_DEVICE_ATTR(temp31_label, S_IRUGO, | ||
1228 | applesmc_show_sensor_label, NULL, 30); | ||
1229 | static SENSOR_DEVICE_ATTR(temp32_label, S_IRUGO, | ||
1230 | applesmc_show_sensor_label, NULL, 31); | ||
1231 | static SENSOR_DEVICE_ATTR(temp33_label, S_IRUGO, | ||
1232 | applesmc_show_sensor_label, NULL, 32); | ||
1233 | static SENSOR_DEVICE_ATTR(temp34_label, S_IRUGO, | ||
1234 | applesmc_show_sensor_label, NULL, 33); | ||
1235 | static SENSOR_DEVICE_ATTR(temp35_label, S_IRUGO, | ||
1236 | applesmc_show_sensor_label, NULL, 34); | ||
1237 | static SENSOR_DEVICE_ATTR(temp36_label, S_IRUGO, | ||
1238 | applesmc_show_sensor_label, NULL, 35); | ||
1239 | static SENSOR_DEVICE_ATTR(temp37_label, S_IRUGO, | ||
1240 | applesmc_show_sensor_label, NULL, 36); | ||
1241 | static SENSOR_DEVICE_ATTR(temp38_label, S_IRUGO, | ||
1242 | applesmc_show_sensor_label, NULL, 37); | ||
1243 | static SENSOR_DEVICE_ATTR(temp39_label, S_IRUGO, | ||
1244 | applesmc_show_sensor_label, NULL, 38); | ||
1245 | static SENSOR_DEVICE_ATTR(temp40_label, S_IRUGO, | ||
1246 | applesmc_show_sensor_label, NULL, 39); | ||
1247 | static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, | ||
1248 | applesmc_show_temperature, NULL, 0); | ||
1249 | static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, | ||
1250 | applesmc_show_temperature, NULL, 1); | ||
1251 | static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, | ||
1252 | applesmc_show_temperature, NULL, 2); | ||
1253 | static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, | ||
1254 | applesmc_show_temperature, NULL, 3); | ||
1255 | static SENSOR_DEVICE_ATTR(temp5_input, S_IRUGO, | ||
1256 | applesmc_show_temperature, NULL, 4); | ||
1257 | static SENSOR_DEVICE_ATTR(temp6_input, S_IRUGO, | ||
1258 | applesmc_show_temperature, NULL, 5); | ||
1259 | static SENSOR_DEVICE_ATTR(temp7_input, S_IRUGO, | ||
1260 | applesmc_show_temperature, NULL, 6); | ||
1261 | static SENSOR_DEVICE_ATTR(temp8_input, S_IRUGO, | ||
1262 | applesmc_show_temperature, NULL, 7); | ||
1263 | static SENSOR_DEVICE_ATTR(temp9_input, S_IRUGO, | ||
1264 | applesmc_show_temperature, NULL, 8); | ||
1265 | static SENSOR_DEVICE_ATTR(temp10_input, S_IRUGO, | ||
1266 | applesmc_show_temperature, NULL, 9); | ||
1267 | static SENSOR_DEVICE_ATTR(temp11_input, S_IRUGO, | ||
1268 | applesmc_show_temperature, NULL, 10); | ||
1269 | static SENSOR_DEVICE_ATTR(temp12_input, S_IRUGO, | ||
1270 | applesmc_show_temperature, NULL, 11); | ||
1271 | static SENSOR_DEVICE_ATTR(temp13_input, S_IRUGO, | ||
1272 | applesmc_show_temperature, NULL, 12); | ||
1273 | static SENSOR_DEVICE_ATTR(temp14_input, S_IRUGO, | ||
1274 | applesmc_show_temperature, NULL, 13); | ||
1275 | static SENSOR_DEVICE_ATTR(temp15_input, S_IRUGO, | ||
1276 | applesmc_show_temperature, NULL, 14); | ||
1277 | static SENSOR_DEVICE_ATTR(temp16_input, S_IRUGO, | ||
1278 | applesmc_show_temperature, NULL, 15); | ||
1279 | static SENSOR_DEVICE_ATTR(temp17_input, S_IRUGO, | ||
1280 | applesmc_show_temperature, NULL, 16); | ||
1281 | static SENSOR_DEVICE_ATTR(temp18_input, S_IRUGO, | ||
1282 | applesmc_show_temperature, NULL, 17); | ||
1283 | static SENSOR_DEVICE_ATTR(temp19_input, S_IRUGO, | ||
1284 | applesmc_show_temperature, NULL, 18); | ||
1285 | static SENSOR_DEVICE_ATTR(temp20_input, S_IRUGO, | ||
1286 | applesmc_show_temperature, NULL, 19); | ||
1287 | static SENSOR_DEVICE_ATTR(temp21_input, S_IRUGO, | ||
1288 | applesmc_show_temperature, NULL, 20); | ||
1289 | static SENSOR_DEVICE_ATTR(temp22_input, S_IRUGO, | ||
1290 | applesmc_show_temperature, NULL, 21); | ||
1291 | static SENSOR_DEVICE_ATTR(temp23_input, S_IRUGO, | ||
1292 | applesmc_show_temperature, NULL, 22); | ||
1293 | static SENSOR_DEVICE_ATTR(temp24_input, S_IRUGO, | ||
1294 | applesmc_show_temperature, NULL, 23); | ||
1295 | static SENSOR_DEVICE_ATTR(temp25_input, S_IRUGO, | ||
1296 | applesmc_show_temperature, NULL, 24); | ||
1297 | static SENSOR_DEVICE_ATTR(temp26_input, S_IRUGO, | ||
1298 | applesmc_show_temperature, NULL, 25); | ||
1299 | static SENSOR_DEVICE_ATTR(temp27_input, S_IRUGO, | ||
1300 | applesmc_show_temperature, NULL, 26); | ||
1301 | static SENSOR_DEVICE_ATTR(temp28_input, S_IRUGO, | ||
1302 | applesmc_show_temperature, NULL, 27); | ||
1303 | static SENSOR_DEVICE_ATTR(temp29_input, S_IRUGO, | ||
1304 | applesmc_show_temperature, NULL, 28); | ||
1305 | static SENSOR_DEVICE_ATTR(temp30_input, S_IRUGO, | ||
1306 | applesmc_show_temperature, NULL, 29); | ||
1307 | static SENSOR_DEVICE_ATTR(temp31_input, S_IRUGO, | ||
1308 | applesmc_show_temperature, NULL, 30); | ||
1309 | static SENSOR_DEVICE_ATTR(temp32_input, S_IRUGO, | ||
1310 | applesmc_show_temperature, NULL, 31); | ||
1311 | static SENSOR_DEVICE_ATTR(temp33_input, S_IRUGO, | ||
1312 | applesmc_show_temperature, NULL, 32); | ||
1313 | static SENSOR_DEVICE_ATTR(temp34_input, S_IRUGO, | ||
1314 | applesmc_show_temperature, NULL, 33); | ||
1315 | static SENSOR_DEVICE_ATTR(temp35_input, S_IRUGO, | ||
1316 | applesmc_show_temperature, NULL, 34); | ||
1317 | static SENSOR_DEVICE_ATTR(temp36_input, S_IRUGO, | ||
1318 | applesmc_show_temperature, NULL, 35); | ||
1319 | static SENSOR_DEVICE_ATTR(temp37_input, S_IRUGO, | ||
1320 | applesmc_show_temperature, NULL, 36); | ||
1321 | static SENSOR_DEVICE_ATTR(temp38_input, S_IRUGO, | ||
1322 | applesmc_show_temperature, NULL, 37); | ||
1323 | static SENSOR_DEVICE_ATTR(temp39_input, S_IRUGO, | ||
1324 | applesmc_show_temperature, NULL, 38); | ||
1325 | static SENSOR_DEVICE_ATTR(temp40_input, S_IRUGO, | ||
1326 | applesmc_show_temperature, NULL, 39); | ||
1327 | |||
1328 | static 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 | |||
1372 | static 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 | |||
1416 | static const struct attribute_group temperature_attributes_group = | ||
1417 | { .attrs = temperature_attributes }; | ||
1418 | |||
1419 | static 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 | */ |
1428 | static int applesmc_dmi_match(const struct dmi_system_id *id) | 1117 | static 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 | */ | ||
1134 | static 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 | */ | ||
1151 | static 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; | ||
1182 | out: | ||
1183 | applesmc_destroy_nodes(groups); | ||
1184 | return ret; | ||
1185 | } | ||
1186 | |||
1447 | /* Create accelerometer ressources */ | 1187 | /* Create accelerometer ressources */ |
1448 | static int applesmc_create_accelerometer(void) | 1188 | static 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(); |
1796 | out_temperature: | 1520 | out_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); | ||
1799 | out_fans: | 1522 | out_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]); |