diff options
author | Ingo Molnar <mingo@elte.hu> | 2008-10-28 11:26:12 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2008-10-28 11:26:12 -0400 |
commit | 7a9787e1eba95a166265e6a260cf30af04ef0a99 (patch) | |
tree | e730a4565e0318140d2fbd2f0415d18a339d7336 /drivers/misc/acer-wmi.c | |
parent | 41b9eb264c8407655db57b60b4457fe1b2ec9977 (diff) | |
parent | 0173a3265b228da319ceb9c1ec6a5682fd1b2d92 (diff) |
Merge commit 'v2.6.28-rc2' into x86/pci-ioapic-boot-irq-quirks
Diffstat (limited to 'drivers/misc/acer-wmi.c')
-rw-r--r-- | drivers/misc/acer-wmi.c | 252 |
1 files changed, 166 insertions, 86 deletions
diff --git a/drivers/misc/acer-wmi.c b/drivers/misc/acer-wmi.c index e7a3fe508dff..0532a2de2ce4 100644 --- a/drivers/misc/acer-wmi.c +++ b/drivers/misc/acer-wmi.c | |||
@@ -33,6 +33,8 @@ | |||
33 | #include <linux/platform_device.h> | 33 | #include <linux/platform_device.h> |
34 | #include <linux/acpi.h> | 34 | #include <linux/acpi.h> |
35 | #include <linux/i8042.h> | 35 | #include <linux/i8042.h> |
36 | #include <linux/rfkill.h> | ||
37 | #include <linux/workqueue.h> | ||
36 | #include <linux/debugfs.h> | 38 | #include <linux/debugfs.h> |
37 | 39 | ||
38 | #include <acpi/acpi_drivers.h> | 40 | #include <acpi/acpi_drivers.h> |
@@ -123,21 +125,15 @@ enum interface_flags { | |||
123 | 125 | ||
124 | static int max_brightness = 0xF; | 126 | static int max_brightness = 0xF; |
125 | 127 | ||
126 | static int wireless = -1; | ||
127 | static int bluetooth = -1; | ||
128 | static int mailled = -1; | 128 | static int mailled = -1; |
129 | static int brightness = -1; | 129 | static int brightness = -1; |
130 | static int threeg = -1; | 130 | static int threeg = -1; |
131 | static int force_series; | 131 | static int force_series; |
132 | 132 | ||
133 | module_param(mailled, int, 0444); | 133 | module_param(mailled, int, 0444); |
134 | module_param(wireless, int, 0444); | ||
135 | module_param(bluetooth, int, 0444); | ||
136 | module_param(brightness, int, 0444); | 134 | module_param(brightness, int, 0444); |
137 | module_param(threeg, int, 0444); | 135 | module_param(threeg, int, 0444); |
138 | module_param(force_series, int, 0444); | 136 | module_param(force_series, int, 0444); |
139 | MODULE_PARM_DESC(wireless, "Set initial state of Wireless hardware"); | ||
140 | MODULE_PARM_DESC(bluetooth, "Set initial state of Bluetooth hardware"); | ||
141 | MODULE_PARM_DESC(mailled, "Set initial state of Mail LED"); | 137 | MODULE_PARM_DESC(mailled, "Set initial state of Mail LED"); |
142 | MODULE_PARM_DESC(brightness, "Set initial LCD backlight brightness"); | 138 | MODULE_PARM_DESC(brightness, "Set initial LCD backlight brightness"); |
143 | MODULE_PARM_DESC(threeg, "Set initial state of 3G hardware"); | 139 | MODULE_PARM_DESC(threeg, "Set initial state of 3G hardware"); |
@@ -145,8 +141,6 @@ MODULE_PARM_DESC(force_series, "Force a different laptop series"); | |||
145 | 141 | ||
146 | struct acer_data { | 142 | struct acer_data { |
147 | int mailled; | 143 | int mailled; |
148 | int wireless; | ||
149 | int bluetooth; | ||
150 | int threeg; | 144 | int threeg; |
151 | int brightness; | 145 | int brightness; |
152 | }; | 146 | }; |
@@ -157,6 +151,9 @@ struct acer_debug { | |||
157 | u32 wmid_devices; | 151 | u32 wmid_devices; |
158 | }; | 152 | }; |
159 | 153 | ||
154 | static struct rfkill *wireless_rfkill; | ||
155 | static struct rfkill *bluetooth_rfkill; | ||
156 | |||
160 | /* Each low-level interface must define at least some of the following */ | 157 | /* Each low-level interface must define at least some of the following */ |
161 | struct wmi_interface { | 158 | struct wmi_interface { |
162 | /* The WMI device type */ | 159 | /* The WMI device type */ |
@@ -192,6 +189,9 @@ static struct quirk_entry *quirks; | |||
192 | 189 | ||
193 | static void set_quirks(void) | 190 | static void set_quirks(void) |
194 | { | 191 | { |
192 | if (!interface) | ||
193 | return; | ||
194 | |||
195 | if (quirks->mailled) | 195 | if (quirks->mailled) |
196 | interface->capability |= ACER_CAP_MAILLED; | 196 | interface->capability |= ACER_CAP_MAILLED; |
197 | 197 | ||
@@ -473,7 +473,7 @@ struct wmi_interface *iface) | |||
473 | } | 473 | } |
474 | break; | 474 | break; |
475 | default: | 475 | default: |
476 | return AE_BAD_ADDRESS; | 476 | return AE_ERROR; |
477 | } | 477 | } |
478 | return AE_OK; | 478 | return AE_OK; |
479 | } | 479 | } |
@@ -511,7 +511,7 @@ static acpi_status AMW0_set_u32(u32 value, u32 cap, struct wmi_interface *iface) | |||
511 | break; | 511 | break; |
512 | } | 512 | } |
513 | default: | 513 | default: |
514 | return AE_BAD_ADDRESS; | 514 | return AE_ERROR; |
515 | } | 515 | } |
516 | 516 | ||
517 | /* Actually do the set */ | 517 | /* Actually do the set */ |
@@ -686,7 +686,7 @@ struct wmi_interface *iface) | |||
686 | return 0; | 686 | return 0; |
687 | } | 687 | } |
688 | default: | 688 | default: |
689 | return AE_BAD_ADDRESS; | 689 | return AE_ERROR; |
690 | } | 690 | } |
691 | status = WMI_execute_u32(method_id, 0, &result); | 691 | status = WMI_execute_u32(method_id, 0, &result); |
692 | 692 | ||
@@ -732,7 +732,7 @@ static acpi_status WMID_set_u32(u32 value, u32 cap, struct wmi_interface *iface) | |||
732 | } | 732 | } |
733 | break; | 733 | break; |
734 | default: | 734 | default: |
735 | return AE_BAD_ADDRESS; | 735 | return AE_ERROR; |
736 | } | 736 | } |
737 | return WMI_execute_u32(method_id, (u32)value, NULL); | 737 | return WMI_execute_u32(method_id, (u32)value, NULL); |
738 | } | 738 | } |
@@ -782,7 +782,7 @@ static struct wmi_interface wmid_interface = { | |||
782 | 782 | ||
783 | static acpi_status get_u32(u32 *value, u32 cap) | 783 | static acpi_status get_u32(u32 *value, u32 cap) |
784 | { | 784 | { |
785 | acpi_status status = AE_BAD_ADDRESS; | 785 | acpi_status status = AE_ERROR; |
786 | 786 | ||
787 | switch (interface->type) { | 787 | switch (interface->type) { |
788 | case ACER_AMW0: | 788 | case ACER_AMW0: |
@@ -803,11 +803,30 @@ static acpi_status get_u32(u32 *value, u32 cap) | |||
803 | 803 | ||
804 | static acpi_status set_u32(u32 value, u32 cap) | 804 | static acpi_status set_u32(u32 value, u32 cap) |
805 | { | 805 | { |
806 | acpi_status status; | ||
807 | |||
806 | if (interface->capability & cap) { | 808 | if (interface->capability & cap) { |
807 | switch (interface->type) { | 809 | switch (interface->type) { |
808 | case ACER_AMW0: | 810 | case ACER_AMW0: |
809 | return AMW0_set_u32(value, cap, interface); | 811 | return AMW0_set_u32(value, cap, interface); |
810 | case ACER_AMW0_V2: | 812 | case ACER_AMW0_V2: |
813 | if (cap == ACER_CAP_MAILLED) | ||
814 | return AMW0_set_u32(value, cap, interface); | ||
815 | |||
816 | /* | ||
817 | * On some models, some WMID methods don't toggle | ||
818 | * properly. For those cases, we want to run the AMW0 | ||
819 | * method afterwards to be certain we've really toggled | ||
820 | * the device state. | ||
821 | */ | ||
822 | if (cap == ACER_CAP_WIRELESS || | ||
823 | cap == ACER_CAP_BLUETOOTH) { | ||
824 | status = WMID_set_u32(value, cap, interface); | ||
825 | if (ACPI_FAILURE(status)) | ||
826 | return status; | ||
827 | |||
828 | return AMW0_set_u32(value, cap, interface); | ||
829 | } | ||
811 | case ACER_WMID: | 830 | case ACER_WMID: |
812 | return WMID_set_u32(value, cap, interface); | 831 | return WMID_set_u32(value, cap, interface); |
813 | default: | 832 | default: |
@@ -824,8 +843,6 @@ static void __init acer_commandline_init(void) | |||
824 | * capability isn't available on the given interface | 843 | * capability isn't available on the given interface |
825 | */ | 844 | */ |
826 | set_u32(mailled, ACER_CAP_MAILLED); | 845 | set_u32(mailled, ACER_CAP_MAILLED); |
827 | set_u32(wireless, ACER_CAP_WIRELESS); | ||
828 | set_u32(bluetooth, ACER_CAP_BLUETOOTH); | ||
829 | set_u32(threeg, ACER_CAP_THREEG); | 846 | set_u32(threeg, ACER_CAP_THREEG); |
830 | set_u32(brightness, ACER_CAP_BRIGHTNESS); | 847 | set_u32(brightness, ACER_CAP_BRIGHTNESS); |
831 | } | 848 | } |
@@ -911,40 +928,135 @@ static void acer_backlight_exit(void) | |||
911 | } | 928 | } |
912 | 929 | ||
913 | /* | 930 | /* |
914 | * Read/ write bool sysfs macro | 931 | * Rfkill devices |
915 | */ | 932 | */ |
916 | #define show_set_bool(value, cap) \ | 933 | static void acer_rfkill_update(struct work_struct *ignored); |
917 | static ssize_t \ | 934 | static DECLARE_DELAYED_WORK(acer_rfkill_work, acer_rfkill_update); |
918 | show_bool_##value(struct device *dev, struct device_attribute *attr, \ | 935 | static void acer_rfkill_update(struct work_struct *ignored) |
919 | char *buf) \ | 936 | { |
920 | { \ | 937 | u32 state; |
921 | u32 result; \ | 938 | acpi_status status; |
922 | acpi_status status = get_u32(&result, cap); \ | 939 | |
923 | if (ACPI_SUCCESS(status)) \ | 940 | status = get_u32(&state, ACER_CAP_WIRELESS); |
924 | return sprintf(buf, "%u\n", result); \ | 941 | if (ACPI_SUCCESS(status)) |
925 | return sprintf(buf, "Read error\n"); \ | 942 | rfkill_force_state(wireless_rfkill, state ? |
926 | } \ | 943 | RFKILL_STATE_UNBLOCKED : RFKILL_STATE_SOFT_BLOCKED); |
927 | \ | 944 | |
928 | static ssize_t \ | 945 | if (has_cap(ACER_CAP_BLUETOOTH)) { |
929 | set_bool_##value(struct device *dev, struct device_attribute *attr, \ | 946 | status = get_u32(&state, ACER_CAP_BLUETOOTH); |
930 | const char *buf, size_t count) \ | 947 | if (ACPI_SUCCESS(status)) |
931 | { \ | 948 | rfkill_force_state(bluetooth_rfkill, state ? |
932 | u32 tmp = simple_strtoul(buf, NULL, 10); \ | 949 | RFKILL_STATE_UNBLOCKED : |
933 | acpi_status status = set_u32(tmp, cap); \ | 950 | RFKILL_STATE_SOFT_BLOCKED); |
934 | if (ACPI_FAILURE(status)) \ | 951 | } |
935 | return -EINVAL; \ | 952 | |
936 | return count; \ | 953 | schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ)); |
937 | } \ | 954 | } |
938 | static DEVICE_ATTR(value, S_IWUGO | S_IRUGO | S_IWUSR, \ | 955 | |
939 | show_bool_##value, set_bool_##value); | 956 | static int acer_rfkill_set(void *data, enum rfkill_state state) |
940 | 957 | { | |
941 | show_set_bool(wireless, ACER_CAP_WIRELESS); | 958 | acpi_status status; |
942 | show_set_bool(bluetooth, ACER_CAP_BLUETOOTH); | 959 | u32 *cap = data; |
943 | show_set_bool(threeg, ACER_CAP_THREEG); | 960 | status = set_u32((u32) (state == RFKILL_STATE_UNBLOCKED), *cap); |
961 | if (ACPI_FAILURE(status)) | ||
962 | return -ENODEV; | ||
963 | return 0; | ||
964 | } | ||
965 | |||
966 | static struct rfkill * acer_rfkill_register(struct device *dev, | ||
967 | enum rfkill_type type, char *name, u32 cap) | ||
968 | { | ||
969 | int err; | ||
970 | u32 state; | ||
971 | u32 *data; | ||
972 | struct rfkill *rfkill_dev; | ||
973 | |||
974 | rfkill_dev = rfkill_allocate(dev, type); | ||
975 | if (!rfkill_dev) | ||
976 | return ERR_PTR(-ENOMEM); | ||
977 | rfkill_dev->name = name; | ||
978 | get_u32(&state, cap); | ||
979 | rfkill_dev->state = state ? RFKILL_STATE_UNBLOCKED : | ||
980 | RFKILL_STATE_SOFT_BLOCKED; | ||
981 | data = kzalloc(sizeof(u32), GFP_KERNEL); | ||
982 | if (!data) { | ||
983 | rfkill_free(rfkill_dev); | ||
984 | return ERR_PTR(-ENOMEM); | ||
985 | } | ||
986 | *data = cap; | ||
987 | rfkill_dev->data = data; | ||
988 | rfkill_dev->toggle_radio = acer_rfkill_set; | ||
989 | rfkill_dev->user_claim_unsupported = 1; | ||
990 | |||
991 | err = rfkill_register(rfkill_dev); | ||
992 | if (err) { | ||
993 | kfree(rfkill_dev->data); | ||
994 | rfkill_free(rfkill_dev); | ||
995 | return ERR_PTR(err); | ||
996 | } | ||
997 | return rfkill_dev; | ||
998 | } | ||
999 | |||
1000 | static int acer_rfkill_init(struct device *dev) | ||
1001 | { | ||
1002 | wireless_rfkill = acer_rfkill_register(dev, RFKILL_TYPE_WLAN, | ||
1003 | "acer-wireless", ACER_CAP_WIRELESS); | ||
1004 | if (IS_ERR(wireless_rfkill)) | ||
1005 | return PTR_ERR(wireless_rfkill); | ||
1006 | |||
1007 | if (has_cap(ACER_CAP_BLUETOOTH)) { | ||
1008 | bluetooth_rfkill = acer_rfkill_register(dev, | ||
1009 | RFKILL_TYPE_BLUETOOTH, "acer-bluetooth", | ||
1010 | ACER_CAP_BLUETOOTH); | ||
1011 | if (IS_ERR(bluetooth_rfkill)) { | ||
1012 | kfree(wireless_rfkill->data); | ||
1013 | rfkill_unregister(wireless_rfkill); | ||
1014 | return PTR_ERR(bluetooth_rfkill); | ||
1015 | } | ||
1016 | } | ||
1017 | |||
1018 | schedule_delayed_work(&acer_rfkill_work, round_jiffies_relative(HZ)); | ||
1019 | |||
1020 | return 0; | ||
1021 | } | ||
1022 | |||
1023 | static void acer_rfkill_exit(void) | ||
1024 | { | ||
1025 | cancel_delayed_work_sync(&acer_rfkill_work); | ||
1026 | kfree(wireless_rfkill->data); | ||
1027 | rfkill_unregister(wireless_rfkill); | ||
1028 | if (has_cap(ACER_CAP_BLUETOOTH)) { | ||
1029 | kfree(wireless_rfkill->data); | ||
1030 | rfkill_unregister(bluetooth_rfkill); | ||
1031 | } | ||
1032 | return; | ||
1033 | } | ||
944 | 1034 | ||
945 | /* | 1035 | /* |
946 | * Read interface sysfs macro | 1036 | * sysfs interface |
947 | */ | 1037 | */ |
1038 | static ssize_t show_bool_threeg(struct device *dev, | ||
1039 | struct device_attribute *attr, char *buf) | ||
1040 | { | ||
1041 | u32 result; \ | ||
1042 | acpi_status status = get_u32(&result, ACER_CAP_THREEG); | ||
1043 | if (ACPI_SUCCESS(status)) | ||
1044 | return sprintf(buf, "%u\n", result); | ||
1045 | return sprintf(buf, "Read error\n"); | ||
1046 | } | ||
1047 | |||
1048 | static ssize_t set_bool_threeg(struct device *dev, | ||
1049 | struct device_attribute *attr, const char *buf, size_t count) | ||
1050 | { | ||
1051 | u32 tmp = simple_strtoul(buf, NULL, 10); | ||
1052 | acpi_status status = set_u32(tmp, ACER_CAP_THREEG); | ||
1053 | if (ACPI_FAILURE(status)) | ||
1054 | return -EINVAL; | ||
1055 | return count; | ||
1056 | } | ||
1057 | static DEVICE_ATTR(threeg, S_IWUGO | S_IRUGO | S_IWUSR, show_bool_threeg, | ||
1058 | set_bool_threeg); | ||
1059 | |||
948 | static ssize_t show_interface(struct device *dev, struct device_attribute *attr, | 1060 | static ssize_t show_interface(struct device *dev, struct device_attribute *attr, |
949 | char *buf) | 1061 | char *buf) |
950 | { | 1062 | { |
@@ -1004,7 +1116,9 @@ static int __devinit acer_platform_probe(struct platform_device *device) | |||
1004 | goto error_brightness; | 1116 | goto error_brightness; |
1005 | } | 1117 | } |
1006 | 1118 | ||
1007 | return 0; | 1119 | err = acer_rfkill_init(&device->dev); |
1120 | |||
1121 | return err; | ||
1008 | 1122 | ||
1009 | error_brightness: | 1123 | error_brightness: |
1010 | acer_led_exit(); | 1124 | acer_led_exit(); |
@@ -1018,6 +1132,8 @@ static int acer_platform_remove(struct platform_device *device) | |||
1018 | acer_led_exit(); | 1132 | acer_led_exit(); |
1019 | if (has_cap(ACER_CAP_BRIGHTNESS)) | 1133 | if (has_cap(ACER_CAP_BRIGHTNESS)) |
1020 | acer_backlight_exit(); | 1134 | acer_backlight_exit(); |
1135 | |||
1136 | acer_rfkill_exit(); | ||
1021 | return 0; | 1137 | return 0; |
1022 | } | 1138 | } |
1023 | 1139 | ||
@@ -1030,16 +1146,6 @@ pm_message_t state) | |||
1030 | if (!data) | 1146 | if (!data) |
1031 | return -ENOMEM; | 1147 | return -ENOMEM; |
1032 | 1148 | ||
1033 | if (has_cap(ACER_CAP_WIRELESS)) { | ||
1034 | get_u32(&value, ACER_CAP_WIRELESS); | ||
1035 | data->wireless = value; | ||
1036 | } | ||
1037 | |||
1038 | if (has_cap(ACER_CAP_BLUETOOTH)) { | ||
1039 | get_u32(&value, ACER_CAP_BLUETOOTH); | ||
1040 | data->bluetooth = value; | ||
1041 | } | ||
1042 | |||
1043 | if (has_cap(ACER_CAP_MAILLED)) { | 1149 | if (has_cap(ACER_CAP_MAILLED)) { |
1044 | get_u32(&value, ACER_CAP_MAILLED); | 1150 | get_u32(&value, ACER_CAP_MAILLED); |
1045 | data->mailled = value; | 1151 | data->mailled = value; |
@@ -1060,15 +1166,6 @@ static int acer_platform_resume(struct platform_device *device) | |||
1060 | if (!data) | 1166 | if (!data) |
1061 | return -ENOMEM; | 1167 | return -ENOMEM; |
1062 | 1168 | ||
1063 | if (has_cap(ACER_CAP_WIRELESS)) | ||
1064 | set_u32(data->wireless, ACER_CAP_WIRELESS); | ||
1065 | |||
1066 | if (has_cap(ACER_CAP_BLUETOOTH)) | ||
1067 | set_u32(data->bluetooth, ACER_CAP_BLUETOOTH); | ||
1068 | |||
1069 | if (has_cap(ACER_CAP_THREEG)) | ||
1070 | set_u32(data->threeg, ACER_CAP_THREEG); | ||
1071 | |||
1072 | if (has_cap(ACER_CAP_MAILLED)) | 1169 | if (has_cap(ACER_CAP_MAILLED)) |
1073 | set_u32(data->mailled, ACER_CAP_MAILLED); | 1170 | set_u32(data->mailled, ACER_CAP_MAILLED); |
1074 | 1171 | ||
@@ -1093,12 +1190,6 @@ static struct platform_device *acer_platform_device; | |||
1093 | 1190 | ||
1094 | static int remove_sysfs(struct platform_device *device) | 1191 | static int remove_sysfs(struct platform_device *device) |
1095 | { | 1192 | { |
1096 | if (has_cap(ACER_CAP_WIRELESS)) | ||
1097 | device_remove_file(&device->dev, &dev_attr_wireless); | ||
1098 | |||
1099 | if (has_cap(ACER_CAP_BLUETOOTH)) | ||
1100 | device_remove_file(&device->dev, &dev_attr_bluetooth); | ||
1101 | |||
1102 | if (has_cap(ACER_CAP_THREEG)) | 1193 | if (has_cap(ACER_CAP_THREEG)) |
1103 | device_remove_file(&device->dev, &dev_attr_threeg); | 1194 | device_remove_file(&device->dev, &dev_attr_threeg); |
1104 | 1195 | ||
@@ -1111,20 +1202,6 @@ static int create_sysfs(void) | |||
1111 | { | 1202 | { |
1112 | int retval = -ENOMEM; | 1203 | int retval = -ENOMEM; |
1113 | 1204 | ||
1114 | if (has_cap(ACER_CAP_WIRELESS)) { | ||
1115 | retval = device_create_file(&acer_platform_device->dev, | ||
1116 | &dev_attr_wireless); | ||
1117 | if (retval) | ||
1118 | goto error_sysfs; | ||
1119 | } | ||
1120 | |||
1121 | if (has_cap(ACER_CAP_BLUETOOTH)) { | ||
1122 | retval = device_create_file(&acer_platform_device->dev, | ||
1123 | &dev_attr_bluetooth); | ||
1124 | if (retval) | ||
1125 | goto error_sysfs; | ||
1126 | } | ||
1127 | |||
1128 | if (has_cap(ACER_CAP_THREEG)) { | 1205 | if (has_cap(ACER_CAP_THREEG)) { |
1129 | retval = device_create_file(&acer_platform_device->dev, | 1206 | retval = device_create_file(&acer_platform_device->dev, |
1130 | &dev_attr_threeg); | 1207 | &dev_attr_threeg); |
@@ -1167,7 +1244,7 @@ static int create_debugfs(void) | |||
1167 | return 0; | 1244 | return 0; |
1168 | 1245 | ||
1169 | error_debugfs: | 1246 | error_debugfs: |
1170 | remove_debugfs(); | 1247 | remove_debugfs(); |
1171 | return -ENOMEM; | 1248 | return -ENOMEM; |
1172 | } | 1249 | } |
1173 | 1250 | ||
@@ -1218,6 +1295,8 @@ static int __init acer_wmi_init(void) | |||
1218 | return -ENODEV; | 1295 | return -ENODEV; |
1219 | } | 1296 | } |
1220 | 1297 | ||
1298 | set_quirks(); | ||
1299 | |||
1221 | if (platform_driver_register(&acer_platform_driver)) { | 1300 | if (platform_driver_register(&acer_platform_driver)) { |
1222 | printk(ACER_ERR "Unable to register platform driver.\n"); | 1301 | printk(ACER_ERR "Unable to register platform driver.\n"); |
1223 | goto error_platform_register; | 1302 | goto error_platform_register; |
@@ -1248,6 +1327,7 @@ error_platform_register: | |||
1248 | static void __exit acer_wmi_exit(void) | 1327 | static void __exit acer_wmi_exit(void) |
1249 | { | 1328 | { |
1250 | remove_sysfs(acer_platform_device); | 1329 | remove_sysfs(acer_platform_device); |
1330 | remove_debugfs(); | ||
1251 | platform_device_del(acer_platform_device); | 1331 | platform_device_del(acer_platform_device); |
1252 | platform_driver_unregister(&acer_platform_driver); | 1332 | platform_driver_unregister(&acer_platform_driver); |
1253 | 1333 | ||