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 | ||
