diff options
author | Henrik Rydberg <rydberg@euromail.se> | 2010-11-09 10:15:08 -0500 |
---|---|---|
committer | Guenter Roeck <guenter.roeck@ericsson.com> | 2011-01-08 13:55:42 -0500 |
commit | 3eba2bf7c5fb7863412554cd73646cb80ac293ff (patch) | |
tree | caca1638ca1a022adcc8e77d8a7e23ad805e14ee /drivers/hwmon/applesmc.c | |
parent | 40ef06f1120bcc0a2ad483b5cd42f58c4df78a5b (diff) |
hwmon: (applesmc) Dynamic creation of fan files
With the dynamic temperature group in place, the setup of fans
can be simplified. This patch sets up the fans dynamically, removing
a hundred lines of code.
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 | 188 |
1 files changed, 43 insertions, 145 deletions
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c index d4d647522331..b0792361c52e 100644 --- a/drivers/hwmon/applesmc.c +++ b/drivers/hwmon/applesmc.c | |||
@@ -77,20 +77,15 @@ | |||
77 | 77 | ||
78 | #define FANS_COUNT "FNum" /* r-o ui8 */ | 78 | #define FANS_COUNT "FNum" /* r-o ui8 */ |
79 | #define FANS_MANUAL "FS! " /* r-w ui16 */ | 79 | #define FANS_MANUAL "FS! " /* r-w ui16 */ |
80 | #define FAN_ACTUAL_SPEED "F0Ac" /* r-o fpe2 (2 bytes) */ | 80 | #define FAN_ID_FMT "F%dID" /* r-o char[16] */ |
81 | #define FAN_MIN_SPEED "F0Mn" /* r-o fpe2 (2 bytes) */ | ||
82 | #define FAN_MAX_SPEED "F0Mx" /* r-o fpe2 (2 bytes) */ | ||
83 | #define FAN_SAFE_SPEED "F0Sf" /* r-o fpe2 (2 bytes) */ | ||
84 | #define FAN_TARGET_SPEED "F0Tg" /* r-w fpe2 (2 bytes) */ | ||
85 | #define FAN_POSITION "F0ID" /* r-o char[16] */ | ||
86 | 81 | ||
87 | /* List of keys used to read/write fan speeds */ | 82 | /* List of keys used to read/write fan speeds */ |
88 | static const char* fan_speed_keys[] = { | 83 | static const char *const fan_speed_fmt[] = { |
89 | FAN_ACTUAL_SPEED, | 84 | "F%dAc", /* actual speed */ |
90 | FAN_MIN_SPEED, | 85 | "F%dMn", /* minimum speed (rw) */ |
91 | FAN_MAX_SPEED, | 86 | "F%dMx", /* maximum speed */ |
92 | FAN_SAFE_SPEED, | 87 | "F%dSf", /* safe speed - not all models */ |
93 | FAN_TARGET_SPEED | 88 | "F%dTg", /* target speed (manual: rw) */ |
94 | }; | 89 | }; |
95 | 90 | ||
96 | #define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */ | 91 | #define INIT_TIMEOUT_MSECS 5000 /* wait up to 5s for device init ... */ |
@@ -104,7 +99,8 @@ static const char* fan_speed_keys[] = { | |||
104 | #define SENSOR_Y 1 | 99 | #define SENSOR_Y 1 |
105 | #define SENSOR_Z 2 | 100 | #define SENSOR_Z 2 |
106 | 101 | ||
107 | #define to_index(attr) (to_sensor_dev_attr(attr)->index) | 102 | #define to_index(attr) (to_sensor_dev_attr(attr)->index & 0xffff) |
103 | #define to_option(attr) (to_sensor_dev_attr(attr)->index >> 16) | ||
108 | 104 | ||
109 | /* Dynamic device node attributes */ | 105 | /* Dynamic device node attributes */ |
110 | struct applesmc_dev_attr { | 106 | struct applesmc_dev_attr { |
@@ -117,6 +113,7 @@ struct applesmc_node_group { | |||
117 | char *format; /* format string */ | 113 | char *format; /* format string */ |
118 | void *show; /* show function */ | 114 | void *show; /* show function */ |
119 | void *store; /* store function */ | 115 | void *store; /* store function */ |
116 | int option; /* function argument */ | ||
120 | struct applesmc_dev_attr *nodes; /* dynamic node array */ | 117 | struct applesmc_dev_attr *nodes; /* dynamic node array */ |
121 | }; | 118 | }; |
122 | 119 | ||
@@ -133,6 +130,7 @@ struct applesmc_entry { | |||
133 | static struct applesmc_registers { | 130 | static struct applesmc_registers { |
134 | struct mutex mutex; /* register read/write mutex */ | 131 | struct mutex mutex; /* register read/write mutex */ |
135 | unsigned int key_count; /* number of SMC registers */ | 132 | unsigned int key_count; /* number of SMC registers */ |
133 | unsigned int fan_count; /* number of fans */ | ||
136 | unsigned int temp_count; /* number of temperature registers */ | 134 | unsigned int temp_count; /* number of temperature registers */ |
137 | unsigned int temp_begin; /* temperature lower index bound */ | 135 | unsigned int temp_begin; /* temperature lower index bound */ |
138 | unsigned int temp_end; /* temperature upper index bound */ | 136 | unsigned int temp_end; /* temperature upper index bound */ |
@@ -154,9 +152,6 @@ static u8 backlight_state[2]; | |||
154 | static struct device *hwmon_dev; | 152 | static struct device *hwmon_dev; |
155 | static struct input_polled_dev *applesmc_idev; | 153 | static struct input_polled_dev *applesmc_idev; |
156 | 154 | ||
157 | /* The number of fans handled by the driver */ | ||
158 | static unsigned int fans_handled; | ||
159 | |||
160 | /* | 155 | /* |
161 | * Last index written to key_at_index sysfs file, and value to use for all other | 156 | * Last index written to key_at_index sysfs file, and value to use for all other |
162 | * key_at_index_* sysfs files. | 157 | * key_at_index_* sysfs files. |
@@ -484,28 +479,13 @@ static void applesmc_device_init(void) | |||
484 | } | 479 | } |
485 | 480 | ||
486 | /* | 481 | /* |
487 | * applesmc_get_fan_count - get the number of fans. | ||
488 | */ | ||
489 | static int applesmc_get_fan_count(void) | ||
490 | { | ||
491 | int ret; | ||
492 | u8 buffer[1]; | ||
493 | |||
494 | ret = applesmc_read_key(FANS_COUNT, buffer, 1); | ||
495 | |||
496 | if (ret) | ||
497 | return ret; | ||
498 | else | ||
499 | return buffer[0]; | ||
500 | } | ||
501 | |||
502 | /* | ||
503 | * applesmc_init_smcreg_try - Try to initialize register cache. Idempotent. | 482 | * applesmc_init_smcreg_try - Try to initialize register cache. Idempotent. |
504 | */ | 483 | */ |
505 | static int applesmc_init_smcreg_try(void) | 484 | static int applesmc_init_smcreg_try(void) |
506 | { | 485 | { |
507 | struct applesmc_registers *s = &smcreg; | 486 | struct applesmc_registers *s = &smcreg; |
508 | bool left_light_sensor, right_light_sensor; | 487 | bool left_light_sensor, right_light_sensor; |
488 | u8 tmp[1]; | ||
509 | int ret; | 489 | int ret; |
510 | 490 | ||
511 | if (s->init_complete) | 491 | if (s->init_complete) |
@@ -520,6 +500,11 @@ static int applesmc_init_smcreg_try(void) | |||
520 | if (!s->cache) | 500 | if (!s->cache) |
521 | return -ENOMEM; | 501 | return -ENOMEM; |
522 | 502 | ||
503 | ret = applesmc_read_key(FANS_COUNT, tmp, 1); | ||
504 | if (ret) | ||
505 | return ret; | ||
506 | s->fan_count = tmp[0]; | ||
507 | |||
523 | ret = applesmc_get_lower_bound(&s->temp_begin, "T"); | 508 | ret = applesmc_get_lower_bound(&s->temp_begin, "T"); |
524 | if (ret) | 509 | if (ret) |
525 | return ret; | 510 | return ret; |
@@ -544,8 +529,8 @@ static int applesmc_init_smcreg_try(void) | |||
544 | s->num_light_sensors = left_light_sensor + right_light_sensor; | 529 | s->num_light_sensors = left_light_sensor + right_light_sensor; |
545 | s->init_complete = true; | 530 | s->init_complete = true; |
546 | 531 | ||
547 | pr_info("key=%d temp=%d acc=%d lux=%d kbd=%d\n", | 532 | pr_info("key=%d fan=%d temp=%d acc=%d lux=%d kbd=%d\n", |
548 | s->key_count, s->temp_count, | 533 | s->key_count, s->fan_count, s->temp_count, |
549 | s->has_accelerometer, | 534 | s->has_accelerometer, |
550 | s->num_light_sensors, | 535 | s->num_light_sensors, |
551 | s->has_key_backlight); | 536 | s->has_key_backlight); |
@@ -776,14 +761,8 @@ static ssize_t applesmc_show_fan_speed(struct device *dev, | |||
776 | unsigned int speed = 0; | 761 | unsigned int speed = 0; |
777 | char newkey[5]; | 762 | char newkey[5]; |
778 | u8 buffer[2]; | 763 | u8 buffer[2]; |
779 | struct sensor_device_attribute_2 *sensor_attr = | ||
780 | to_sensor_dev_attr_2(attr); | ||
781 | 764 | ||
782 | newkey[0] = fan_speed_keys[sensor_attr->nr][0]; | 765 | sprintf(newkey, fan_speed_fmt[to_option(attr)], to_index(attr)); |
783 | newkey[1] = '0' + sensor_attr->index; | ||
784 | newkey[2] = fan_speed_keys[sensor_attr->nr][2]; | ||
785 | newkey[3] = fan_speed_keys[sensor_attr->nr][3]; | ||
786 | newkey[4] = 0; | ||
787 | 766 | ||
788 | ret = applesmc_read_key(newkey, buffer, 2); | 767 | ret = applesmc_read_key(newkey, buffer, 2); |
789 | speed = ((buffer[0] << 8 | buffer[1]) >> 2); | 768 | speed = ((buffer[0] << 8 | buffer[1]) >> 2); |
@@ -802,19 +781,13 @@ static ssize_t applesmc_store_fan_speed(struct device *dev, | |||
802 | u32 speed; | 781 | u32 speed; |
803 | char newkey[5]; | 782 | char newkey[5]; |
804 | u8 buffer[2]; | 783 | u8 buffer[2]; |
805 | struct sensor_device_attribute_2 *sensor_attr = | ||
806 | to_sensor_dev_attr_2(attr); | ||
807 | 784 | ||
808 | speed = simple_strtoul(sysfsbuf, NULL, 10); | 785 | speed = simple_strtoul(sysfsbuf, NULL, 10); |
809 | 786 | ||
810 | if (speed > 0x4000) /* Bigger than a 14-bit value */ | 787 | if (speed > 0x4000) /* Bigger than a 14-bit value */ |
811 | return -EINVAL; | 788 | return -EINVAL; |
812 | 789 | ||
813 | newkey[0] = fan_speed_keys[sensor_attr->nr][0]; | 790 | sprintf(newkey, fan_speed_fmt[to_option(attr)], to_index(attr)); |
814 | newkey[1] = '0' + sensor_attr->index; | ||
815 | newkey[2] = fan_speed_keys[sensor_attr->nr][2]; | ||
816 | newkey[3] = fan_speed_keys[sensor_attr->nr][3]; | ||
817 | newkey[4] = 0; | ||
818 | 791 | ||
819 | buffer[0] = (speed >> 6) & 0xff; | 792 | buffer[0] = (speed >> 6) & 0xff; |
820 | buffer[1] = (speed << 2) & 0xff; | 793 | buffer[1] = (speed << 2) & 0xff; |
@@ -827,15 +800,14 @@ static ssize_t applesmc_store_fan_speed(struct device *dev, | |||
827 | } | 800 | } |
828 | 801 | ||
829 | static ssize_t applesmc_show_fan_manual(struct device *dev, | 802 | static ssize_t applesmc_show_fan_manual(struct device *dev, |
830 | struct device_attribute *devattr, char *sysfsbuf) | 803 | struct device_attribute *attr, char *sysfsbuf) |
831 | { | 804 | { |
832 | int ret; | 805 | int ret; |
833 | u16 manual = 0; | 806 | u16 manual = 0; |
834 | u8 buffer[2]; | 807 | u8 buffer[2]; |
835 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
836 | 808 | ||
837 | ret = applesmc_read_key(FANS_MANUAL, buffer, 2); | 809 | ret = applesmc_read_key(FANS_MANUAL, buffer, 2); |
838 | manual = ((buffer[0] << 8 | buffer[1]) >> attr->index) & 0x01; | 810 | manual = ((buffer[0] << 8 | buffer[1]) >> to_index(attr)) & 0x01; |
839 | 811 | ||
840 | if (ret) | 812 | if (ret) |
841 | return ret; | 813 | return ret; |
@@ -844,14 +816,13 @@ static ssize_t applesmc_show_fan_manual(struct device *dev, | |||
844 | } | 816 | } |
845 | 817 | ||
846 | static ssize_t applesmc_store_fan_manual(struct device *dev, | 818 | static ssize_t applesmc_store_fan_manual(struct device *dev, |
847 | struct device_attribute *devattr, | 819 | struct device_attribute *attr, |
848 | const char *sysfsbuf, size_t count) | 820 | const char *sysfsbuf, size_t count) |
849 | { | 821 | { |
850 | int ret; | 822 | int ret; |
851 | u8 buffer[2]; | 823 | u8 buffer[2]; |
852 | u32 input; | 824 | u32 input; |
853 | u16 val; | 825 | u16 val; |
854 | struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); | ||
855 | 826 | ||
856 | input = simple_strtoul(sysfsbuf, NULL, 10); | 827 | input = simple_strtoul(sysfsbuf, NULL, 10); |
857 | 828 | ||
@@ -861,9 +832,9 @@ static ssize_t applesmc_store_fan_manual(struct device *dev, | |||
861 | goto out; | 832 | goto out; |
862 | 833 | ||
863 | if (input) | 834 | if (input) |
864 | val = val | (0x01 << attr->index); | 835 | val = val | (0x01 << to_index(attr)); |
865 | else | 836 | else |
866 | val = val & ~(0x01 << attr->index); | 837 | val = val & ~(0x01 << to_index(attr)); |
867 | 838 | ||
868 | buffer[0] = (val >> 8) & 0xFF; | 839 | buffer[0] = (val >> 8) & 0xFF; |
869 | buffer[1] = val & 0xFF; | 840 | buffer[1] = val & 0xFF; |
@@ -883,14 +854,8 @@ static ssize_t applesmc_show_fan_position(struct device *dev, | |||
883 | int ret; | 854 | int ret; |
884 | char newkey[5]; | 855 | char newkey[5]; |
885 | u8 buffer[17]; | 856 | u8 buffer[17]; |
886 | struct sensor_device_attribute_2 *sensor_attr = | ||
887 | to_sensor_dev_attr_2(attr); | ||
888 | 857 | ||
889 | newkey[0] = FAN_POSITION[0]; | 858 | sprintf(newkey, FAN_ID_FMT, to_index(attr)); |
890 | newkey[1] = '0' + sensor_attr->index; | ||
891 | newkey[2] = FAN_POSITION[2]; | ||
892 | newkey[3] = FAN_POSITION[3]; | ||
893 | newkey[4] = 0; | ||
894 | 859 | ||
895 | ret = applesmc_read_key(newkey, buffer, 16); | 860 | ret = applesmc_read_key(newkey, buffer, 16); |
896 | buffer[16] = 0; | 861 | buffer[16] = 0; |
@@ -1069,62 +1034,15 @@ static struct attribute *key_enumeration_attributes[] = { | |||
1069 | static const struct attribute_group key_enumeration_group = | 1034 | static const struct attribute_group key_enumeration_group = |
1070 | { .attrs = key_enumeration_attributes }; | 1035 | { .attrs = key_enumeration_attributes }; |
1071 | 1036 | ||
1072 | /* | 1037 | static struct applesmc_node_group fan_group[] = { |
1073 | * Macro defining SENSOR_DEVICE_ATTR for a fan sysfs entries. | 1038 | { "fan%d_label", applesmc_show_fan_position }, |
1074 | * - show actual speed | 1039 | { "fan%d_input", applesmc_show_fan_speed, NULL, 0 }, |
1075 | * - show/store minimum speed | 1040 | { "fan%d_min", applesmc_show_fan_speed, applesmc_store_fan_speed, 1 }, |
1076 | * - show maximum speed | 1041 | { "fan%d_max", applesmc_show_fan_speed, NULL, 2 }, |
1077 | * - show safe speed | 1042 | { "fan%d_safe", applesmc_show_fan_speed, NULL, 3 }, |
1078 | * - show/store target speed | 1043 | { "fan%d_output", applesmc_show_fan_speed, applesmc_store_fan_speed, 4 }, |
1079 | * - show/store manual mode | 1044 | { "fan%d_manual", applesmc_show_fan_manual, applesmc_store_fan_manual }, |
1080 | */ | 1045 | { } |
1081 | #define sysfs_fan_speeds_offset(offset) \ | ||
1082 | static SENSOR_DEVICE_ATTR_2(fan##offset##_input, S_IRUGO, \ | ||
1083 | applesmc_show_fan_speed, NULL, 0, offset-1); \ | ||
1084 | \ | ||
1085 | static SENSOR_DEVICE_ATTR_2(fan##offset##_min, S_IRUGO | S_IWUSR, \ | ||
1086 | applesmc_show_fan_speed, applesmc_store_fan_speed, 1, offset-1); \ | ||
1087 | \ | ||
1088 | static SENSOR_DEVICE_ATTR_2(fan##offset##_max, S_IRUGO, \ | ||
1089 | applesmc_show_fan_speed, NULL, 2, offset-1); \ | ||
1090 | \ | ||
1091 | static SENSOR_DEVICE_ATTR_2(fan##offset##_safe, S_IRUGO, \ | ||
1092 | applesmc_show_fan_speed, NULL, 3, offset-1); \ | ||
1093 | \ | ||
1094 | static SENSOR_DEVICE_ATTR_2(fan##offset##_output, S_IRUGO | S_IWUSR, \ | ||
1095 | applesmc_show_fan_speed, applesmc_store_fan_speed, 4, offset-1); \ | ||
1096 | \ | ||
1097 | static SENSOR_DEVICE_ATTR(fan##offset##_manual, S_IRUGO | S_IWUSR, \ | ||
1098 | applesmc_show_fan_manual, applesmc_store_fan_manual, offset-1); \ | ||
1099 | \ | ||
1100 | static SENSOR_DEVICE_ATTR(fan##offset##_label, S_IRUGO, \ | ||
1101 | applesmc_show_fan_position, NULL, offset-1); \ | ||
1102 | \ | ||
1103 | static struct attribute *fan##offset##_attributes[] = { \ | ||
1104 | &sensor_dev_attr_fan##offset##_input.dev_attr.attr, \ | ||
1105 | &sensor_dev_attr_fan##offset##_min.dev_attr.attr, \ | ||
1106 | &sensor_dev_attr_fan##offset##_max.dev_attr.attr, \ | ||
1107 | &sensor_dev_attr_fan##offset##_safe.dev_attr.attr, \ | ||
1108 | &sensor_dev_attr_fan##offset##_output.dev_attr.attr, \ | ||
1109 | &sensor_dev_attr_fan##offset##_manual.dev_attr.attr, \ | ||
1110 | &sensor_dev_attr_fan##offset##_label.dev_attr.attr, \ | ||
1111 | NULL \ | ||
1112 | }; | ||
1113 | |||
1114 | /* | ||
1115 | * Create the needed functions for each fan using the macro defined above | ||
1116 | * (4 fans are supported) | ||
1117 | */ | ||
1118 | sysfs_fan_speeds_offset(1); | ||
1119 | sysfs_fan_speeds_offset(2); | ||
1120 | sysfs_fan_speeds_offset(3); | ||
1121 | sysfs_fan_speeds_offset(4); | ||
1122 | |||
1123 | static const struct attribute_group fan_attribute_groups[] = { | ||
1124 | { .attrs = fan1_attributes }, | ||
1125 | { .attrs = fan2_attributes }, | ||
1126 | { .attrs = fan3_attributes }, | ||
1127 | { .attrs = fan4_attributes }, | ||
1128 | }; | 1046 | }; |
1129 | 1047 | ||
1130 | static struct applesmc_node_group temp_group[] = { | 1048 | static struct applesmc_node_group temp_group[] = { |
@@ -1171,7 +1089,7 @@ static int applesmc_create_nodes(struct applesmc_node_group *groups, int num) | |||
1171 | for (i = 0; i < num; i++) { | 1089 | for (i = 0; i < num; i++) { |
1172 | node = &grp->nodes[i]; | 1090 | node = &grp->nodes[i]; |
1173 | sprintf(node->name, grp->format, i + 1); | 1091 | sprintf(node->name, grp->format, i + 1); |
1174 | node->sda.index = i; | 1092 | node->sda.index = (grp->option << 16) | (i & 0xffff); |
1175 | node->sda.dev_attr.show = grp->show; | 1093 | node->sda.dev_attr.show = grp->show; |
1176 | node->sda.dev_attr.store = grp->store; | 1094 | node->sda.dev_attr.store = grp->store; |
1177 | attr = &node->sda.dev_attr.attr; | 1095 | attr = &node->sda.dev_attr.attr; |
@@ -1287,7 +1205,6 @@ static __initdata struct dmi_system_id applesmc_whitelist[] = { | |||
1287 | static int __init applesmc_init(void) | 1205 | static int __init applesmc_init(void) |
1288 | { | 1206 | { |
1289 | int ret; | 1207 | int ret; |
1290 | int count; | ||
1291 | 1208 | ||
1292 | if (!dmi_check_system(applesmc_whitelist)) { | 1209 | if (!dmi_check_system(applesmc_whitelist)) { |
1293 | pr_warn("supported laptop not found!\n"); | 1210 | pr_warn("supported laptop not found!\n"); |
@@ -1326,25 +1243,9 @@ static int __init applesmc_init(void) | |||
1326 | if (ret) | 1243 | if (ret) |
1327 | goto out_name; | 1244 | goto out_name; |
1328 | 1245 | ||
1329 | /* create fan files */ | 1246 | ret = applesmc_create_nodes(fan_group, smcreg.fan_count); |
1330 | count = applesmc_get_fan_count(); | 1247 | if (ret) |
1331 | if (count < 0) | 1248 | goto out_info; |
1332 | pr_err("Cannot get the number of fans\n"); | ||
1333 | else | ||
1334 | pr_info("%d fans found\n", count); | ||
1335 | |||
1336 | if (count > 4) { | ||
1337 | count = 4; | ||
1338 | pr_warn("A maximum of 4 fans are supported by this driver\n"); | ||
1339 | } | ||
1340 | |||
1341 | while (fans_handled < count) { | ||
1342 | ret = sysfs_create_group(&pdev->dev.kobj, | ||
1343 | &fan_attribute_groups[fans_handled]); | ||
1344 | if (ret) | ||
1345 | goto out_fans; | ||
1346 | fans_handled++; | ||
1347 | } | ||
1348 | 1249 | ||
1349 | ret = applesmc_create_nodes(temp_group, smcreg.temp_count); | 1250 | ret = applesmc_create_nodes(temp_group, smcreg.temp_count); |
1350 | if (ret) | 1251 | if (ret) |
@@ -1402,9 +1303,8 @@ out_accelerometer: | |||
1402 | out_temperature: | 1303 | out_temperature: |
1403 | applesmc_destroy_nodes(temp_group); | 1304 | applesmc_destroy_nodes(temp_group); |
1404 | out_fans: | 1305 | out_fans: |
1405 | while (fans_handled) | 1306 | applesmc_destroy_nodes(fan_group); |
1406 | sysfs_remove_group(&pdev->dev.kobj, | 1307 | out_info: |
1407 | &fan_attribute_groups[--fans_handled]); | ||
1408 | sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group); | 1308 | sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group); |
1409 | out_name: | 1309 | out_name: |
1410 | sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr); | 1310 | sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr); |
@@ -1433,9 +1333,7 @@ static void __exit applesmc_exit(void) | |||
1433 | if (smcreg.has_accelerometer) | 1333 | if (smcreg.has_accelerometer) |
1434 | applesmc_release_accelerometer(); | 1334 | applesmc_release_accelerometer(); |
1435 | applesmc_destroy_nodes(temp_group); | 1335 | applesmc_destroy_nodes(temp_group); |
1436 | while (fans_handled) | 1336 | applesmc_destroy_nodes(fan_group); |
1437 | sysfs_remove_group(&pdev->dev.kobj, | ||
1438 | &fan_attribute_groups[--fans_handled]); | ||
1439 | sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group); | 1337 | sysfs_remove_group(&pdev->dev.kobj, &key_enumeration_group); |
1440 | sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr); | 1338 | sysfs_remove_file(&pdev->dev.kobj, &dev_attr_name.attr); |
1441 | applesmc_destroy_smcreg(); | 1339 | applesmc_destroy_smcreg(); |