diff options
Diffstat (limited to 'drivers/platform/x86/toshiba_acpi.c')
-rw-r--r-- | drivers/platform/x86/toshiba_acpi.c | 254 |
1 files changed, 213 insertions, 41 deletions
diff --git a/drivers/platform/x86/toshiba_acpi.c b/drivers/platform/x86/toshiba_acpi.c index dcdc1f4a4624..ee79ce64d9df 100644 --- a/drivers/platform/x86/toshiba_acpi.c +++ b/drivers/platform/x86/toshiba_acpi.c | |||
@@ -52,6 +52,8 @@ | |||
52 | #include <linux/input/sparse-keymap.h> | 52 | #include <linux/input/sparse-keymap.h> |
53 | #include <linux/leds.h> | 53 | #include <linux/leds.h> |
54 | #include <linux/slab.h> | 54 | #include <linux/slab.h> |
55 | #include <linux/workqueue.h> | ||
56 | #include <linux/i8042.h> | ||
55 | 57 | ||
56 | #include <asm/uaccess.h> | 58 | #include <asm/uaccess.h> |
57 | 59 | ||
@@ -61,6 +63,11 @@ MODULE_AUTHOR("John Belmonte"); | |||
61 | MODULE_DESCRIPTION("Toshiba Laptop ACPI Extras Driver"); | 63 | MODULE_DESCRIPTION("Toshiba Laptop ACPI Extras Driver"); |
62 | MODULE_LICENSE("GPL"); | 64 | MODULE_LICENSE("GPL"); |
63 | 65 | ||
66 | #define TOSHIBA_WMI_EVENT_GUID "59142400-C6A3-40FA-BADB-8A2652834100" | ||
67 | |||
68 | /* Scan code for Fn key on TOS1900 models */ | ||
69 | #define TOS1900_FN_SCAN 0x6e | ||
70 | |||
64 | /* Toshiba ACPI method paths */ | 71 | /* Toshiba ACPI method paths */ |
65 | #define METHOD_VIDEO_OUT "\\_SB_.VALX.DSSX" | 72 | #define METHOD_VIDEO_OUT "\\_SB_.VALX.DSSX" |
66 | 73 | ||
@@ -95,6 +102,8 @@ MODULE_LICENSE("GPL"); | |||
95 | #define HCI_WIRELESS 0x0056 | 102 | #define HCI_WIRELESS 0x0056 |
96 | 103 | ||
97 | /* field definitions */ | 104 | /* field definitions */ |
105 | #define HCI_HOTKEY_DISABLE 0x0b | ||
106 | #define HCI_HOTKEY_ENABLE 0x09 | ||
98 | #define HCI_LCD_BRIGHTNESS_BITS 3 | 107 | #define HCI_LCD_BRIGHTNESS_BITS 3 |
99 | #define HCI_LCD_BRIGHTNESS_SHIFT (16-HCI_LCD_BRIGHTNESS_BITS) | 108 | #define HCI_LCD_BRIGHTNESS_SHIFT (16-HCI_LCD_BRIGHTNESS_BITS) |
100 | #define HCI_LCD_BRIGHTNESS_LEVELS (1 << HCI_LCD_BRIGHTNESS_BITS) | 109 | #define HCI_LCD_BRIGHTNESS_LEVELS (1 << HCI_LCD_BRIGHTNESS_BITS) |
@@ -111,6 +120,7 @@ struct toshiba_acpi_dev { | |||
111 | const char *method_hci; | 120 | const char *method_hci; |
112 | struct rfkill *bt_rfk; | 121 | struct rfkill *bt_rfk; |
113 | struct input_dev *hotkey_dev; | 122 | struct input_dev *hotkey_dev; |
123 | struct work_struct hotkey_work; | ||
114 | struct backlight_device *backlight_dev; | 124 | struct backlight_device *backlight_dev; |
115 | struct led_classdev led_dev; | 125 | struct led_classdev led_dev; |
116 | 126 | ||
@@ -118,14 +128,18 @@ struct toshiba_acpi_dev { | |||
118 | int last_key_event; | 128 | int last_key_event; |
119 | int key_event_valid; | 129 | int key_event_valid; |
120 | 130 | ||
121 | int illumination_supported:1; | 131 | unsigned int illumination_supported:1; |
122 | int video_supported:1; | 132 | unsigned int video_supported:1; |
123 | int fan_supported:1; | 133 | unsigned int fan_supported:1; |
124 | int system_event_supported:1; | 134 | unsigned int system_event_supported:1; |
135 | unsigned int ntfy_supported:1; | ||
136 | unsigned int info_supported:1; | ||
125 | 137 | ||
126 | struct mutex mutex; | 138 | struct mutex mutex; |
127 | }; | 139 | }; |
128 | 140 | ||
141 | static struct toshiba_acpi_dev *toshiba_acpi; | ||
142 | |||
129 | static const struct acpi_device_id toshiba_device_ids[] = { | 143 | static const struct acpi_device_id toshiba_device_ids[] = { |
130 | {"TOS6200", 0}, | 144 | {"TOS6200", 0}, |
131 | {"TOS6208", 0}, | 145 | {"TOS6208", 0}, |
@@ -138,6 +152,8 @@ static const struct key_entry toshiba_acpi_keymap[] __devinitconst = { | |||
138 | { KE_KEY, 0x101, { KEY_MUTE } }, | 152 | { KE_KEY, 0x101, { KEY_MUTE } }, |
139 | { KE_KEY, 0x102, { KEY_ZOOMOUT } }, | 153 | { KE_KEY, 0x102, { KEY_ZOOMOUT } }, |
140 | { KE_KEY, 0x103, { KEY_ZOOMIN } }, | 154 | { KE_KEY, 0x103, { KEY_ZOOMIN } }, |
155 | { KE_KEY, 0x12c, { KEY_KBDILLUMTOGGLE } }, | ||
156 | { KE_KEY, 0x139, { KEY_ZOOMRESET } }, | ||
141 | { KE_KEY, 0x13b, { KEY_COFFEE } }, | 157 | { KE_KEY, 0x13b, { KEY_COFFEE } }, |
142 | { KE_KEY, 0x13c, { KEY_BATTERY } }, | 158 | { KE_KEY, 0x13c, { KEY_BATTERY } }, |
143 | { KE_KEY, 0x13d, { KEY_SLEEP } }, | 159 | { KE_KEY, 0x13d, { KEY_SLEEP } }, |
@@ -146,7 +162,7 @@ static const struct key_entry toshiba_acpi_keymap[] __devinitconst = { | |||
146 | { KE_KEY, 0x140, { KEY_BRIGHTNESSDOWN } }, | 162 | { KE_KEY, 0x140, { KEY_BRIGHTNESSDOWN } }, |
147 | { KE_KEY, 0x141, { KEY_BRIGHTNESSUP } }, | 163 | { KE_KEY, 0x141, { KEY_BRIGHTNESSUP } }, |
148 | { KE_KEY, 0x142, { KEY_WLAN } }, | 164 | { KE_KEY, 0x142, { KEY_WLAN } }, |
149 | { KE_KEY, 0x143, { KEY_PROG1 } }, | 165 | { KE_KEY, 0x143, { KEY_TOUCHPAD_TOGGLE } }, |
150 | { KE_KEY, 0x17f, { KEY_FN } }, | 166 | { KE_KEY, 0x17f, { KEY_FN } }, |
151 | { KE_KEY, 0xb05, { KEY_PROG2 } }, | 167 | { KE_KEY, 0xb05, { KEY_PROG2 } }, |
152 | { KE_KEY, 0xb06, { KEY_WWW } }, | 168 | { KE_KEY, 0xb06, { KEY_WWW } }, |
@@ -156,6 +172,7 @@ static const struct key_entry toshiba_acpi_keymap[] __devinitconst = { | |||
156 | { KE_KEY, 0xb32, { KEY_NEXTSONG } }, | 172 | { KE_KEY, 0xb32, { KEY_NEXTSONG } }, |
157 | { KE_KEY, 0xb33, { KEY_PLAYPAUSE } }, | 173 | { KE_KEY, 0xb33, { KEY_PLAYPAUSE } }, |
158 | { KE_KEY, 0xb5a, { KEY_MEDIA } }, | 174 | { KE_KEY, 0xb5a, { KEY_MEDIA } }, |
175 | { KE_IGNORE, 0x1430, { KEY_RESERVED } }, | ||
159 | { KE_END, 0 }, | 176 | { KE_END, 0 }, |
160 | }; | 177 | }; |
161 | 178 | ||
@@ -847,10 +864,78 @@ static const struct backlight_ops toshiba_backlight_data = { | |||
847 | .update_status = set_lcd_status, | 864 | .update_status = set_lcd_status, |
848 | }; | 865 | }; |
849 | 866 | ||
867 | static bool toshiba_acpi_i8042_filter(unsigned char data, unsigned char str, | ||
868 | struct serio *port) | ||
869 | { | ||
870 | if (str & 0x20) | ||
871 | return false; | ||
872 | |||
873 | if (unlikely(data == 0xe0)) | ||
874 | return false; | ||
875 | |||
876 | if ((data & 0x7f) == TOS1900_FN_SCAN) { | ||
877 | schedule_work(&toshiba_acpi->hotkey_work); | ||
878 | return true; | ||
879 | } | ||
880 | |||
881 | return false; | ||
882 | } | ||
883 | |||
884 | static void toshiba_acpi_hotkey_work(struct work_struct *work) | ||
885 | { | ||
886 | acpi_handle ec_handle = ec_get_handle(); | ||
887 | acpi_status status; | ||
888 | |||
889 | if (!ec_handle) | ||
890 | return; | ||
891 | |||
892 | status = acpi_evaluate_object(ec_handle, "NTFY", NULL, NULL); | ||
893 | if (ACPI_FAILURE(status)) | ||
894 | pr_err("ACPI NTFY method execution failed\n"); | ||
895 | } | ||
896 | |||
897 | /* | ||
898 | * Returns hotkey scancode, or < 0 on failure. | ||
899 | */ | ||
900 | static int toshiba_acpi_query_hotkey(struct toshiba_acpi_dev *dev) | ||
901 | { | ||
902 | struct acpi_buffer buf; | ||
903 | union acpi_object out_obj; | ||
904 | acpi_status status; | ||
905 | |||
906 | buf.pointer = &out_obj; | ||
907 | buf.length = sizeof(out_obj); | ||
908 | |||
909 | status = acpi_evaluate_object(dev->acpi_dev->handle, "INFO", | ||
910 | NULL, &buf); | ||
911 | if (ACPI_FAILURE(status) || out_obj.type != ACPI_TYPE_INTEGER) { | ||
912 | pr_err("ACPI INFO method execution failed\n"); | ||
913 | return -EIO; | ||
914 | } | ||
915 | |||
916 | return out_obj.integer.value; | ||
917 | } | ||
918 | |||
919 | static void toshiba_acpi_report_hotkey(struct toshiba_acpi_dev *dev, | ||
920 | int scancode) | ||
921 | { | ||
922 | if (scancode == 0x100) | ||
923 | return; | ||
924 | |||
925 | /* act on key press; ignore key release */ | ||
926 | if (scancode & 0x80) | ||
927 | return; | ||
928 | |||
929 | if (!sparse_keymap_report_event(dev->hotkey_dev, scancode, 1, true)) | ||
930 | pr_info("Unknown key %x\n", scancode); | ||
931 | } | ||
932 | |||
850 | static int __devinit toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev) | 933 | static int __devinit toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev) |
851 | { | 934 | { |
852 | acpi_status status; | 935 | acpi_status status; |
936 | acpi_handle ec_handle, handle; | ||
853 | int error; | 937 | int error; |
938 | u32 hci_result; | ||
854 | 939 | ||
855 | dev->hotkey_dev = input_allocate_device(); | 940 | dev->hotkey_dev = input_allocate_device(); |
856 | if (!dev->hotkey_dev) { | 941 | if (!dev->hotkey_dev) { |
@@ -866,21 +951,67 @@ static int __devinit toshiba_acpi_setup_keyboard(struct toshiba_acpi_dev *dev) | |||
866 | if (error) | 951 | if (error) |
867 | goto err_free_dev; | 952 | goto err_free_dev; |
868 | 953 | ||
954 | /* | ||
955 | * For some machines the SCI responsible for providing hotkey | ||
956 | * notification doesn't fire. We can trigger the notification | ||
957 | * whenever the Fn key is pressed using the NTFY method, if | ||
958 | * supported, so if it's present set up an i8042 key filter | ||
959 | * for this purpose. | ||
960 | */ | ||
961 | status = AE_ERROR; | ||
962 | ec_handle = ec_get_handle(); | ||
963 | if (ec_handle) | ||
964 | status = acpi_get_handle(ec_handle, "NTFY", &handle); | ||
965 | |||
966 | if (ACPI_SUCCESS(status)) { | ||
967 | INIT_WORK(&dev->hotkey_work, toshiba_acpi_hotkey_work); | ||
968 | |||
969 | error = i8042_install_filter(toshiba_acpi_i8042_filter); | ||
970 | if (error) { | ||
971 | pr_err("Error installing key filter\n"); | ||
972 | goto err_free_keymap; | ||
973 | } | ||
974 | |||
975 | dev->ntfy_supported = 1; | ||
976 | } | ||
977 | |||
978 | /* | ||
979 | * Determine hotkey query interface. Prefer using the INFO | ||
980 | * method when it is available. | ||
981 | */ | ||
982 | status = acpi_get_handle(dev->acpi_dev->handle, "INFO", &handle); | ||
983 | if (ACPI_SUCCESS(status)) { | ||
984 | dev->info_supported = 1; | ||
985 | } else { | ||
986 | hci_write1(dev, HCI_SYSTEM_EVENT, 1, &hci_result); | ||
987 | if (hci_result == HCI_SUCCESS) | ||
988 | dev->system_event_supported = 1; | ||
989 | } | ||
990 | |||
991 | if (!dev->info_supported && !dev->system_event_supported) { | ||
992 | pr_warn("No hotkey query interface found\n"); | ||
993 | goto err_remove_filter; | ||
994 | } | ||
995 | |||
869 | status = acpi_evaluate_object(dev->acpi_dev->handle, "ENAB", NULL, NULL); | 996 | status = acpi_evaluate_object(dev->acpi_dev->handle, "ENAB", NULL, NULL); |
870 | if (ACPI_FAILURE(status)) { | 997 | if (ACPI_FAILURE(status)) { |
871 | pr_info("Unable to enable hotkeys\n"); | 998 | pr_info("Unable to enable hotkeys\n"); |
872 | error = -ENODEV; | 999 | error = -ENODEV; |
873 | goto err_free_keymap; | 1000 | goto err_remove_filter; |
874 | } | 1001 | } |
875 | 1002 | ||
876 | error = input_register_device(dev->hotkey_dev); | 1003 | error = input_register_device(dev->hotkey_dev); |
877 | if (error) { | 1004 | if (error) { |
878 | pr_info("Unable to register input device\n"); | 1005 | pr_info("Unable to register input device\n"); |
879 | goto err_free_keymap; | 1006 | goto err_remove_filter; |
880 | } | 1007 | } |
881 | 1008 | ||
1009 | hci_write1(dev, HCI_HOTKEY_EVENT, HCI_HOTKEY_ENABLE, &hci_result); | ||
882 | return 0; | 1010 | return 0; |
883 | 1011 | ||
1012 | err_remove_filter: | ||
1013 | if (dev->ntfy_supported) | ||
1014 | i8042_remove_filter(toshiba_acpi_i8042_filter); | ||
884 | err_free_keymap: | 1015 | err_free_keymap: |
885 | sparse_keymap_free(dev->hotkey_dev); | 1016 | sparse_keymap_free(dev->hotkey_dev); |
886 | err_free_dev: | 1017 | err_free_dev: |
@@ -895,6 +1026,11 @@ static int toshiba_acpi_remove(struct acpi_device *acpi_dev, int type) | |||
895 | 1026 | ||
896 | remove_toshiba_proc_entries(dev); | 1027 | remove_toshiba_proc_entries(dev); |
897 | 1028 | ||
1029 | if (dev->ntfy_supported) { | ||
1030 | i8042_remove_filter(toshiba_acpi_i8042_filter); | ||
1031 | cancel_work_sync(&dev->hotkey_work); | ||
1032 | } | ||
1033 | |||
898 | if (dev->hotkey_dev) { | 1034 | if (dev->hotkey_dev) { |
899 | input_unregister_device(dev->hotkey_dev); | 1035 | input_unregister_device(dev->hotkey_dev); |
900 | sparse_keymap_free(dev->hotkey_dev); | 1036 | sparse_keymap_free(dev->hotkey_dev); |
@@ -911,6 +1047,9 @@ static int toshiba_acpi_remove(struct acpi_device *acpi_dev, int type) | |||
911 | if (dev->illumination_supported) | 1047 | if (dev->illumination_supported) |
912 | led_classdev_unregister(&dev->led_dev); | 1048 | led_classdev_unregister(&dev->led_dev); |
913 | 1049 | ||
1050 | if (toshiba_acpi) | ||
1051 | toshiba_acpi = NULL; | ||
1052 | |||
914 | kfree(dev); | 1053 | kfree(dev); |
915 | 1054 | ||
916 | return 0; | 1055 | return 0; |
@@ -936,12 +1075,14 @@ static int __devinit toshiba_acpi_add(struct acpi_device *acpi_dev) | |||
936 | { | 1075 | { |
937 | struct toshiba_acpi_dev *dev; | 1076 | struct toshiba_acpi_dev *dev; |
938 | const char *hci_method; | 1077 | const char *hci_method; |
939 | u32 hci_result; | ||
940 | u32 dummy; | 1078 | u32 dummy; |
941 | bool bt_present; | 1079 | bool bt_present; |
942 | int ret = 0; | 1080 | int ret = 0; |
943 | struct backlight_properties props; | 1081 | struct backlight_properties props; |
944 | 1082 | ||
1083 | if (toshiba_acpi) | ||
1084 | return -EBUSY; | ||
1085 | |||
945 | pr_info("Toshiba Laptop ACPI Extras version %s\n", | 1086 | pr_info("Toshiba Laptop ACPI Extras version %s\n", |
946 | TOSHIBA_ACPI_VERSION); | 1087 | TOSHIBA_ACPI_VERSION); |
947 | 1088 | ||
@@ -963,11 +1104,6 @@ static int __devinit toshiba_acpi_add(struct acpi_device *acpi_dev) | |||
963 | 1104 | ||
964 | mutex_init(&dev->mutex); | 1105 | mutex_init(&dev->mutex); |
965 | 1106 | ||
966 | /* enable event fifo */ | ||
967 | hci_write1(dev, HCI_SYSTEM_EVENT, 1, &hci_result); | ||
968 | if (hci_result == HCI_SUCCESS) | ||
969 | dev->system_event_supported = 1; | ||
970 | |||
971 | props.type = BACKLIGHT_PLATFORM; | 1107 | props.type = BACKLIGHT_PLATFORM; |
972 | props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1; | 1108 | props.max_brightness = HCI_LCD_BRIGHTNESS_LEVELS - 1; |
973 | dev->backlight_dev = backlight_device_register("toshiba", | 1109 | dev->backlight_dev = backlight_device_register("toshiba", |
@@ -1024,6 +1160,8 @@ static int __devinit toshiba_acpi_add(struct acpi_device *acpi_dev) | |||
1024 | 1160 | ||
1025 | create_toshiba_proc_entries(dev); | 1161 | create_toshiba_proc_entries(dev); |
1026 | 1162 | ||
1163 | toshiba_acpi = dev; | ||
1164 | |||
1027 | return 0; | 1165 | return 0; |
1028 | 1166 | ||
1029 | error: | 1167 | error: |
@@ -1036,40 +1174,64 @@ static void toshiba_acpi_notify(struct acpi_device *acpi_dev, u32 event) | |||
1036 | struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev); | 1174 | struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev); |
1037 | u32 hci_result, value; | 1175 | u32 hci_result, value; |
1038 | int retries = 3; | 1176 | int retries = 3; |
1177 | int scancode; | ||
1039 | 1178 | ||
1040 | if (!dev->system_event_supported || event != 0x80) | 1179 | if (event != 0x80) |
1041 | return; | 1180 | return; |
1042 | 1181 | ||
1043 | do { | 1182 | if (dev->info_supported) { |
1044 | hci_read1(dev, HCI_SYSTEM_EVENT, &value, &hci_result); | 1183 | scancode = toshiba_acpi_query_hotkey(dev); |
1045 | switch (hci_result) { | 1184 | if (scancode < 0) |
1046 | case HCI_SUCCESS: | 1185 | pr_err("Failed to query hotkey event\n"); |
1047 | if (value == 0x100) | 1186 | else if (scancode != 0) |
1048 | continue; | 1187 | toshiba_acpi_report_hotkey(dev, scancode); |
1049 | /* act on key press; ignore key release */ | 1188 | } else if (dev->system_event_supported) { |
1050 | if (value & 0x80) | 1189 | do { |
1051 | continue; | 1190 | hci_read1(dev, HCI_SYSTEM_EVENT, &value, &hci_result); |
1052 | 1191 | switch (hci_result) { | |
1053 | if (!sparse_keymap_report_event(dev->hotkey_dev, | 1192 | case HCI_SUCCESS: |
1054 | value, 1, true)) { | 1193 | toshiba_acpi_report_hotkey(dev, (int)value); |
1055 | pr_info("Unknown key %x\n", | 1194 | break; |
1056 | value); | 1195 | case HCI_NOT_SUPPORTED: |
1196 | /* | ||
1197 | * This is a workaround for an unresolved | ||
1198 | * issue on some machines where system events | ||
1199 | * sporadically become disabled. | ||
1200 | */ | ||
1201 | hci_write1(dev, HCI_SYSTEM_EVENT, 1, | ||
1202 | &hci_result); | ||
1203 | pr_notice("Re-enabled hotkeys\n"); | ||
1204 | /* fall through */ | ||
1205 | default: | ||
1206 | retries--; | ||
1207 | break; | ||
1057 | } | 1208 | } |
1058 | break; | 1209 | } while (retries && hci_result != HCI_EMPTY); |
1059 | case HCI_NOT_SUPPORTED: | 1210 | } |
1060 | /* This is a workaround for an unresolved issue on | 1211 | } |
1061 | * some machines where system events sporadically | 1212 | |
1062 | * become disabled. */ | 1213 | static int toshiba_acpi_suspend(struct acpi_device *acpi_dev, |
1063 | hci_write1(dev, HCI_SYSTEM_EVENT, 1, &hci_result); | 1214 | pm_message_t state) |
1064 | pr_notice("Re-enabled hotkeys\n"); | 1215 | { |
1065 | /* fall through */ | 1216 | struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev); |
1066 | default: | 1217 | u32 result; |
1067 | retries--; | 1218 | |
1068 | break; | 1219 | if (dev->hotkey_dev) |
1069 | } | 1220 | hci_write1(dev, HCI_HOTKEY_EVENT, HCI_HOTKEY_DISABLE, &result); |
1070 | } while (retries && hci_result != HCI_EMPTY); | 1221 | |
1222 | return 0; | ||
1071 | } | 1223 | } |
1072 | 1224 | ||
1225 | static int toshiba_acpi_resume(struct acpi_device *acpi_dev) | ||
1226 | { | ||
1227 | struct toshiba_acpi_dev *dev = acpi_driver_data(acpi_dev); | ||
1228 | u32 result; | ||
1229 | |||
1230 | if (dev->hotkey_dev) | ||
1231 | hci_write1(dev, HCI_HOTKEY_EVENT, HCI_HOTKEY_ENABLE, &result); | ||
1232 | |||
1233 | return 0; | ||
1234 | } | ||
1073 | 1235 | ||
1074 | static struct acpi_driver toshiba_acpi_driver = { | 1236 | static struct acpi_driver toshiba_acpi_driver = { |
1075 | .name = "Toshiba ACPI driver", | 1237 | .name = "Toshiba ACPI driver", |
@@ -1080,6 +1242,8 @@ static struct acpi_driver toshiba_acpi_driver = { | |||
1080 | .add = toshiba_acpi_add, | 1242 | .add = toshiba_acpi_add, |
1081 | .remove = toshiba_acpi_remove, | 1243 | .remove = toshiba_acpi_remove, |
1082 | .notify = toshiba_acpi_notify, | 1244 | .notify = toshiba_acpi_notify, |
1245 | .suspend = toshiba_acpi_suspend, | ||
1246 | .resume = toshiba_acpi_resume, | ||
1083 | }, | 1247 | }, |
1084 | }; | 1248 | }; |
1085 | 1249 | ||
@@ -1087,6 +1251,14 @@ static int __init toshiba_acpi_init(void) | |||
1087 | { | 1251 | { |
1088 | int ret; | 1252 | int ret; |
1089 | 1253 | ||
1254 | /* | ||
1255 | * Machines with this WMI guid aren't supported due to bugs in | ||
1256 | * their AML. This check relies on wmi initializing before | ||
1257 | * toshiba_acpi to guarantee guids have been identified. | ||
1258 | */ | ||
1259 | if (wmi_has_guid(TOSHIBA_WMI_EVENT_GUID)) | ||
1260 | return -ENODEV; | ||
1261 | |||
1090 | toshiba_proc_dir = proc_mkdir(PROC_TOSHIBA, acpi_root_dir); | 1262 | toshiba_proc_dir = proc_mkdir(PROC_TOSHIBA, acpi_root_dir); |
1091 | if (!toshiba_proc_dir) { | 1263 | if (!toshiba_proc_dir) { |
1092 | pr_err("Unable to create proc dir " PROC_TOSHIBA "\n"); | 1264 | pr_err("Unable to create proc dir " PROC_TOSHIBA "\n"); |