diff options
-rw-r--r-- | drivers/platform/x86/eeepc-laptop.c | 160 |
1 files changed, 84 insertions, 76 deletions
diff --git a/drivers/platform/x86/eeepc-laptop.c b/drivers/platform/x86/eeepc-laptop.c index d14f7149cb13..e46981a5f20b 100644 --- a/drivers/platform/x86/eeepc-laptop.c +++ b/drivers/platform/x86/eeepc-laptop.c | |||
@@ -139,8 +139,8 @@ struct eeepc_hotk { | |||
139 | u16 event_count[128]; /* count for each event */ | 139 | u16 event_count[128]; /* count for each event */ |
140 | struct input_dev *inputdev; | 140 | struct input_dev *inputdev; |
141 | u16 *keycode_map; | 141 | u16 *keycode_map; |
142 | struct rfkill *eeepc_wlan_rfkill; | 142 | struct rfkill *wlan_rfkill; |
143 | struct rfkill *eeepc_bluetooth_rfkill; | 143 | struct rfkill *bluetooth_rfkill; |
144 | struct hotplug_slot *hotplug_slot; | 144 | struct hotplug_slot *hotplug_slot; |
145 | }; | 145 | }; |
146 | 146 | ||
@@ -663,7 +663,7 @@ static void eeepc_rfkill_hotplug(void) | |||
663 | } | 663 | } |
664 | } | 664 | } |
665 | 665 | ||
666 | rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill, blocked); | 666 | rfkill_set_sw_state(ehotk->wlan_rfkill, blocked); |
667 | } | 667 | } |
668 | 668 | ||
669 | static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) | 669 | static void eeepc_rfkill_notify(acpi_handle handle, u32 event, void *data) |
@@ -828,66 +828,8 @@ static int eeepc_hotk_add(struct acpi_device *device) | |||
828 | if (result) | 828 | if (result) |
829 | goto ehotk_fail; | 829 | goto ehotk_fail; |
830 | 830 | ||
831 | eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6"); | ||
832 | eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); | ||
833 | |||
834 | if (get_acpi(CM_ASL_WLAN) != -1) { | ||
835 | ehotk->eeepc_wlan_rfkill = rfkill_alloc("eeepc-wlan", | ||
836 | &device->dev, | ||
837 | RFKILL_TYPE_WLAN, | ||
838 | &eeepc_rfkill_ops, | ||
839 | (void *)CM_ASL_WLAN); | ||
840 | |||
841 | if (!ehotk->eeepc_wlan_rfkill) | ||
842 | goto wlan_fail; | ||
843 | |||
844 | rfkill_init_sw_state(ehotk->eeepc_wlan_rfkill, | ||
845 | get_acpi(CM_ASL_WLAN) != 1); | ||
846 | result = rfkill_register(ehotk->eeepc_wlan_rfkill); | ||
847 | if (result) | ||
848 | goto wlan_fail; | ||
849 | } | ||
850 | |||
851 | if (get_acpi(CM_ASL_BLUETOOTH) != -1) { | ||
852 | ehotk->eeepc_bluetooth_rfkill = | ||
853 | rfkill_alloc("eeepc-bluetooth", | ||
854 | &device->dev, | ||
855 | RFKILL_TYPE_BLUETOOTH, | ||
856 | &eeepc_rfkill_ops, | ||
857 | (void *)CM_ASL_BLUETOOTH); | ||
858 | |||
859 | if (!ehotk->eeepc_bluetooth_rfkill) | ||
860 | goto bluetooth_fail; | ||
861 | |||
862 | rfkill_init_sw_state(ehotk->eeepc_bluetooth_rfkill, | ||
863 | get_acpi(CM_ASL_BLUETOOTH) != 1); | ||
864 | result = rfkill_register(ehotk->eeepc_bluetooth_rfkill); | ||
865 | if (result) | ||
866 | goto bluetooth_fail; | ||
867 | } | ||
868 | |||
869 | result = eeepc_setup_pci_hotplug(); | ||
870 | /* | ||
871 | * If we get -EBUSY then something else is handling the PCI hotplug - | ||
872 | * don't fail in this case | ||
873 | */ | ||
874 | if (result == -EBUSY) | ||
875 | return 0; | ||
876 | else if (result) | ||
877 | goto pci_fail; | ||
878 | |||
879 | return 0; | 831 | return 0; |
880 | 832 | ||
881 | pci_fail: | ||
882 | if (ehotk->eeepc_bluetooth_rfkill) | ||
883 | rfkill_unregister(ehotk->eeepc_bluetooth_rfkill); | ||
884 | bluetooth_fail: | ||
885 | rfkill_destroy(ehotk->eeepc_bluetooth_rfkill); | ||
886 | rfkill_unregister(ehotk->eeepc_wlan_rfkill); | ||
887 | wlan_fail: | ||
888 | rfkill_destroy(ehotk->eeepc_wlan_rfkill); | ||
889 | eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); | ||
890 | eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); | ||
891 | ehotk_fail: | 833 | ehotk_fail: |
892 | kfree(ehotk); | 834 | kfree(ehotk); |
893 | ehotk = NULL; | 835 | ehotk = NULL; |
@@ -900,18 +842,13 @@ static int eeepc_hotk_remove(struct acpi_device *device, int type) | |||
900 | if (!device || !acpi_driver_data(device)) | 842 | if (!device || !acpi_driver_data(device)) |
901 | return -EINVAL; | 843 | return -EINVAL; |
902 | 844 | ||
903 | eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); | ||
904 | eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); | ||
905 | if (ehotk->hotplug_slot) | ||
906 | pci_hp_deregister(ehotk->hotplug_slot); | ||
907 | |||
908 | kfree(ehotk); | 845 | kfree(ehotk); |
909 | return 0; | 846 | return 0; |
910 | } | 847 | } |
911 | 848 | ||
912 | static int eeepc_hotk_resume(struct acpi_device *device) | 849 | static int eeepc_hotk_resume(struct acpi_device *device) |
913 | { | 850 | { |
914 | if (ehotk->eeepc_wlan_rfkill) { | 851 | if (ehotk->wlan_rfkill) { |
915 | bool wlan; | 852 | bool wlan; |
916 | 853 | ||
917 | /* Workaround - it seems that _PTS disables the wireless | 854 | /* Workaround - it seems that _PTS disables the wireless |
@@ -923,14 +860,13 @@ static int eeepc_hotk_resume(struct acpi_device *device) | |||
923 | wlan = get_acpi(CM_ASL_WLAN); | 860 | wlan = get_acpi(CM_ASL_WLAN); |
924 | set_acpi(CM_ASL_WLAN, wlan); | 861 | set_acpi(CM_ASL_WLAN, wlan); |
925 | 862 | ||
926 | rfkill_set_sw_state(ehotk->eeepc_wlan_rfkill, | 863 | rfkill_set_sw_state(ehotk->wlan_rfkill, wlan != 1); |
927 | wlan != 1); | ||
928 | 864 | ||
929 | eeepc_rfkill_hotplug(); | 865 | eeepc_rfkill_hotplug(); |
930 | } | 866 | } |
931 | 867 | ||
932 | if (ehotk->eeepc_bluetooth_rfkill) | 868 | if (ehotk->bluetooth_rfkill) |
933 | rfkill_set_sw_state(ehotk->eeepc_bluetooth_rfkill, | 869 | rfkill_set_sw_state(ehotk->bluetooth_rfkill, |
934 | get_acpi(CM_ASL_BLUETOOTH) != 1); | 870 | get_acpi(CM_ASL_BLUETOOTH) != 1); |
935 | 871 | ||
936 | return 0; | 872 | return 0; |
@@ -1052,10 +988,14 @@ static void eeepc_backlight_exit(void) | |||
1052 | 988 | ||
1053 | static void eeepc_rfkill_exit(void) | 989 | static void eeepc_rfkill_exit(void) |
1054 | { | 990 | { |
1055 | if (ehotk->eeepc_wlan_rfkill) | 991 | eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P6"); |
1056 | rfkill_unregister(ehotk->eeepc_wlan_rfkill); | 992 | eeepc_unregister_rfkill_notifier("\\_SB.PCI0.P0P7"); |
1057 | if (ehotk->eeepc_bluetooth_rfkill) | 993 | if (ehotk->wlan_rfkill) |
1058 | rfkill_unregister(ehotk->eeepc_bluetooth_rfkill); | 994 | rfkill_unregister(ehotk->wlan_rfkill); |
995 | if (ehotk->bluetooth_rfkill) | ||
996 | rfkill_unregister(ehotk->bluetooth_rfkill); | ||
997 | if (ehotk->hotplug_slot) | ||
998 | pci_hp_deregister(ehotk->hotplug_slot); | ||
1059 | } | 999 | } |
1060 | 1000 | ||
1061 | static void eeepc_input_exit(void) | 1001 | static void eeepc_input_exit(void) |
@@ -1090,6 +1030,67 @@ static void __exit eeepc_laptop_exit(void) | |||
1090 | platform_driver_unregister(&platform_driver); | 1030 | platform_driver_unregister(&platform_driver); |
1091 | } | 1031 | } |
1092 | 1032 | ||
1033 | static int eeepc_new_rfkill(struct rfkill **rfkill, | ||
1034 | const char *name, struct device *dev, | ||
1035 | enum rfkill_type type, int cm) | ||
1036 | { | ||
1037 | int result; | ||
1038 | |||
1039 | if (get_acpi(cm) == -1) | ||
1040 | return -ENODEV; | ||
1041 | |||
1042 | *rfkill = rfkill_alloc(name, dev, type, | ||
1043 | &eeepc_rfkill_ops, (void *)(unsigned long)cm); | ||
1044 | |||
1045 | if (!*rfkill) | ||
1046 | return -EINVAL; | ||
1047 | |||
1048 | rfkill_init_sw_state(*rfkill, get_acpi(cm) != 1); | ||
1049 | result = rfkill_register(*rfkill); | ||
1050 | if (result) { | ||
1051 | rfkill_destroy(*rfkill); | ||
1052 | *rfkill = NULL; | ||
1053 | return result; | ||
1054 | } | ||
1055 | return 0; | ||
1056 | } | ||
1057 | |||
1058 | |||
1059 | static int eeepc_rfkill_init(struct device *dev) | ||
1060 | { | ||
1061 | int result = 0; | ||
1062 | |||
1063 | eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P6"); | ||
1064 | eeepc_register_rfkill_notifier("\\_SB.PCI0.P0P7"); | ||
1065 | |||
1066 | result = eeepc_new_rfkill(&ehotk->wlan_rfkill, | ||
1067 | "eeepc-wlan", dev, | ||
1068 | RFKILL_TYPE_WLAN, CM_ASL_WLAN); | ||
1069 | |||
1070 | if (result && result != -ENODEV) | ||
1071 | goto exit; | ||
1072 | |||
1073 | result = eeepc_new_rfkill(&ehotk->bluetooth_rfkill, | ||
1074 | "eeepc-bluetooth", dev, | ||
1075 | RFKILL_TYPE_BLUETOOTH, CM_ASL_BLUETOOTH); | ||
1076 | |||
1077 | if (result && result != -ENODEV) | ||
1078 | goto exit; | ||
1079 | |||
1080 | result = eeepc_setup_pci_hotplug(); | ||
1081 | /* | ||
1082 | * If we get -EBUSY then something else is handling the PCI hotplug - | ||
1083 | * don't fail in this case | ||
1084 | */ | ||
1085 | if (result == -EBUSY) | ||
1086 | result = 0; | ||
1087 | |||
1088 | exit: | ||
1089 | if (result && result != -ENODEV) | ||
1090 | eeepc_rfkill_exit(); | ||
1091 | return result; | ||
1092 | } | ||
1093 | |||
1093 | static int eeepc_backlight_init(struct device *dev) | 1094 | static int eeepc_backlight_init(struct device *dev) |
1094 | { | 1095 | { |
1095 | struct backlight_device *bd; | 1096 | struct backlight_device *bd; |
@@ -1173,7 +1174,15 @@ static int __init eeepc_laptop_init(void) | |||
1173 | &platform_attribute_group); | 1174 | &platform_attribute_group); |
1174 | if (result) | 1175 | if (result) |
1175 | goto fail_sysfs; | 1176 | goto fail_sysfs; |
1177 | |||
1178 | result = eeepc_rfkill_init(dev); | ||
1179 | if (result) | ||
1180 | goto fail_rfkill; | ||
1181 | |||
1176 | return 0; | 1182 | return 0; |
1183 | fail_rfkill: | ||
1184 | sysfs_remove_group(&platform_device->dev.kobj, | ||
1185 | &platform_attribute_group); | ||
1177 | fail_sysfs: | 1186 | fail_sysfs: |
1178 | platform_device_del(platform_device); | 1187 | platform_device_del(platform_device); |
1179 | fail_platform_device2: | 1188 | fail_platform_device2: |
@@ -1186,7 +1195,6 @@ fail_hwmon: | |||
1186 | eeepc_backlight_exit(); | 1195 | eeepc_backlight_exit(); |
1187 | fail_backlight: | 1196 | fail_backlight: |
1188 | eeepc_input_exit(); | 1197 | eeepc_input_exit(); |
1189 | eeepc_rfkill_exit(); | ||
1190 | return result; | 1198 | return result; |
1191 | } | 1199 | } |
1192 | 1200 | ||