diff options
Diffstat (limited to 'drivers/platform/x86/fujitsu-laptop.c')
-rw-r--r-- | drivers/platform/x86/fujitsu-laptop.c | 109 |
1 files changed, 48 insertions, 61 deletions
diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index 218b9a16ac3f..f35aee5c2149 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c | |||
@@ -66,11 +66,11 @@ | |||
66 | #include <linux/kfifo.h> | 66 | #include <linux/kfifo.h> |
67 | #include <linux/video_output.h> | 67 | #include <linux/video_output.h> |
68 | #include <linux/platform_device.h> | 68 | #include <linux/platform_device.h> |
69 | #ifdef CONFIG_LEDS_CLASS | 69 | #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) |
70 | #include <linux/leds.h> | 70 | #include <linux/leds.h> |
71 | #endif | 71 | #endif |
72 | 72 | ||
73 | #define FUJITSU_DRIVER_VERSION "0.5.0" | 73 | #define FUJITSU_DRIVER_VERSION "0.6.0" |
74 | 74 | ||
75 | #define FUJITSU_LCD_N_LEVELS 8 | 75 | #define FUJITSU_LCD_N_LEVELS 8 |
76 | 76 | ||
@@ -96,7 +96,7 @@ | |||
96 | /* FUNC interface - responses */ | 96 | /* FUNC interface - responses */ |
97 | #define UNSUPPORTED_CMD 0x80000000 | 97 | #define UNSUPPORTED_CMD 0x80000000 |
98 | 98 | ||
99 | #ifdef CONFIG_LEDS_CLASS | 99 | #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) |
100 | /* FUNC interface - LED control */ | 100 | /* FUNC interface - LED control */ |
101 | #define FUNC_LED_OFF 0x1 | 101 | #define FUNC_LED_OFF 0x1 |
102 | #define FUNC_LED_ON 0x30001 | 102 | #define FUNC_LED_ON 0x30001 |
@@ -176,7 +176,7 @@ static struct fujitsu_hotkey_t *fujitsu_hotkey; | |||
176 | 176 | ||
177 | static void acpi_fujitsu_hotkey_notify(struct acpi_device *device, u32 event); | 177 | static void acpi_fujitsu_hotkey_notify(struct acpi_device *device, u32 event); |
178 | 178 | ||
179 | #ifdef CONFIG_LEDS_CLASS | 179 | #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) |
180 | static enum led_brightness logolamp_get(struct led_classdev *cdev); | 180 | static enum led_brightness logolamp_get(struct led_classdev *cdev); |
181 | static void logolamp_set(struct led_classdev *cdev, | 181 | static void logolamp_set(struct led_classdev *cdev, |
182 | enum led_brightness brightness); | 182 | enum led_brightness brightness); |
@@ -257,7 +257,7 @@ static int call_fext_func(int cmd, int arg0, int arg1, int arg2) | |||
257 | return out_obj.integer.value; | 257 | return out_obj.integer.value; |
258 | } | 258 | } |
259 | 259 | ||
260 | #ifdef CONFIG_LEDS_CLASS | 260 | #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) |
261 | /* LED class callbacks */ | 261 | /* LED class callbacks */ |
262 | 262 | ||
263 | static void logolamp_set(struct led_classdev *cdev, | 263 | static void logolamp_set(struct led_classdev *cdev, |
@@ -324,9 +324,6 @@ static int set_lcd_level(int level) | |||
324 | if (level < 0 || level >= fujitsu->max_brightness) | 324 | if (level < 0 || level >= fujitsu->max_brightness) |
325 | return -EINVAL; | 325 | return -EINVAL; |
326 | 326 | ||
327 | if (!fujitsu) | ||
328 | return -EINVAL; | ||
329 | |||
330 | status = acpi_get_handle(fujitsu->acpi_handle, "SBLL", &handle); | 327 | status = acpi_get_handle(fujitsu->acpi_handle, "SBLL", &handle); |
331 | if (ACPI_FAILURE(status)) { | 328 | if (ACPI_FAILURE(status)) { |
332 | vdbg_printk(FUJLAPTOP_DBG_ERROR, "SBLL not present\n"); | 329 | vdbg_printk(FUJLAPTOP_DBG_ERROR, "SBLL not present\n"); |
@@ -355,9 +352,6 @@ static int set_lcd_level_alt(int level) | |||
355 | if (level < 0 || level >= fujitsu->max_brightness) | 352 | if (level < 0 || level >= fujitsu->max_brightness) |
356 | return -EINVAL; | 353 | return -EINVAL; |
357 | 354 | ||
358 | if (!fujitsu) | ||
359 | return -EINVAL; | ||
360 | |||
361 | status = acpi_get_handle(fujitsu->acpi_handle, "SBL2", &handle); | 355 | status = acpi_get_handle(fujitsu->acpi_handle, "SBL2", &handle); |
362 | if (ACPI_FAILURE(status)) { | 356 | if (ACPI_FAILURE(status)) { |
363 | vdbg_printk(FUJLAPTOP_DBG_ERROR, "SBL2 not present\n"); | 357 | vdbg_printk(FUJLAPTOP_DBG_ERROR, "SBL2 not present\n"); |
@@ -697,10 +691,10 @@ static int acpi_fujitsu_add(struct acpi_device *device) | |||
697 | result = acpi_bus_get_power(fujitsu->acpi_handle, &state); | 691 | result = acpi_bus_get_power(fujitsu->acpi_handle, &state); |
698 | if (result) { | 692 | if (result) { |
699 | printk(KERN_ERR "Error reading power state\n"); | 693 | printk(KERN_ERR "Error reading power state\n"); |
700 | goto end; | 694 | goto err_unregister_input_dev; |
701 | } | 695 | } |
702 | 696 | ||
703 | printk(KERN_INFO PREFIX "%s [%s] (%s)\n", | 697 | printk(KERN_INFO "ACPI: %s [%s] (%s)\n", |
704 | acpi_device_name(device), acpi_device_bid(device), | 698 | acpi_device_name(device), acpi_device_bid(device), |
705 | !device->power.state ? "on" : "off"); | 699 | !device->power.state ? "on" : "off"); |
706 | 700 | ||
@@ -728,25 +722,22 @@ static int acpi_fujitsu_add(struct acpi_device *device) | |||
728 | 722 | ||
729 | return result; | 723 | return result; |
730 | 724 | ||
731 | end: | 725 | err_unregister_input_dev: |
726 | input_unregister_device(input); | ||
732 | err_free_input_dev: | 727 | err_free_input_dev: |
733 | input_free_device(input); | 728 | input_free_device(input); |
734 | err_stop: | 729 | err_stop: |
735 | |||
736 | return result; | 730 | return result; |
737 | } | 731 | } |
738 | 732 | ||
739 | static int acpi_fujitsu_remove(struct acpi_device *device, int type) | 733 | static int acpi_fujitsu_remove(struct acpi_device *device, int type) |
740 | { | 734 | { |
741 | struct fujitsu_t *fujitsu = NULL; | 735 | struct fujitsu_t *fujitsu = acpi_driver_data(device); |
736 | struct input_dev *input = fujitsu->input; | ||
742 | 737 | ||
743 | if (!device || !acpi_driver_data(device)) | 738 | input_unregister_device(input); |
744 | return -EINVAL; | ||
745 | 739 | ||
746 | fujitsu = acpi_driver_data(device); | 740 | input_free_device(input); |
747 | |||
748 | if (!device || !acpi_driver_data(device)) | ||
749 | return -EINVAL; | ||
750 | 741 | ||
751 | fujitsu->acpi_handle = NULL; | 742 | fujitsu->acpi_handle = NULL; |
752 | 743 | ||
@@ -871,10 +862,10 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) | |||
871 | result = acpi_bus_get_power(fujitsu_hotkey->acpi_handle, &state); | 862 | result = acpi_bus_get_power(fujitsu_hotkey->acpi_handle, &state); |
872 | if (result) { | 863 | if (result) { |
873 | printk(KERN_ERR "Error reading power state\n"); | 864 | printk(KERN_ERR "Error reading power state\n"); |
874 | goto end; | 865 | goto err_unregister_input_dev; |
875 | } | 866 | } |
876 | 867 | ||
877 | printk(KERN_INFO PREFIX "%s [%s] (%s)\n", | 868 | printk(KERN_INFO "ACPI: %s [%s] (%s)\n", |
878 | acpi_device_name(device), acpi_device_bid(device), | 869 | acpi_device_name(device), acpi_device_bid(device), |
879 | !device->power.state ? "on" : "off"); | 870 | !device->power.state ? "on" : "off"); |
880 | 871 | ||
@@ -911,7 +902,7 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) | |||
911 | printk(KERN_INFO "fujitsu-laptop: BTNI: [0x%x]\n", | 902 | printk(KERN_INFO "fujitsu-laptop: BTNI: [0x%x]\n", |
912 | call_fext_func(FUNC_BUTTONS, 0x0, 0x0, 0x0)); | 903 | call_fext_func(FUNC_BUTTONS, 0x0, 0x0, 0x0)); |
913 | 904 | ||
914 | #ifdef CONFIG_LEDS_CLASS | 905 | #if defined(CONFIG_LEDS_CLASS) || defined(CONFIG_LEDS_CLASS_MODULE) |
915 | if (call_fext_func(FUNC_LEDS, 0x0, 0x0, 0x0) & LOGOLAMP_POWERON) { | 906 | if (call_fext_func(FUNC_LEDS, 0x0, 0x0, 0x0) & LOGOLAMP_POWERON) { |
916 | result = led_classdev_register(&fujitsu->pf_device->dev, | 907 | result = led_classdev_register(&fujitsu->pf_device->dev, |
917 | &logolamp_led); | 908 | &logolamp_led); |
@@ -934,33 +925,41 @@ static int acpi_fujitsu_hotkey_add(struct acpi_device *device) | |||
934 | "LED handler for keyboard lamps, error %i\n", result); | 925 | "LED handler for keyboard lamps, error %i\n", result); |
935 | } | 926 | } |
936 | } | 927 | } |
937 | #endif | 928 | #endif |
938 | 929 | ||
939 | return result; | 930 | return result; |
940 | 931 | ||
941 | end: | 932 | err_unregister_input_dev: |
933 | input_unregister_device(input); | ||
942 | err_free_input_dev: | 934 | err_free_input_dev: |
943 | input_free_device(input); | 935 | input_free_device(input); |
944 | err_free_fifo: | 936 | err_free_fifo: |
945 | kfifo_free(fujitsu_hotkey->fifo); | 937 | kfifo_free(fujitsu_hotkey->fifo); |
946 | err_stop: | 938 | err_stop: |
947 | |||
948 | return result; | 939 | return result; |
949 | } | 940 | } |
950 | 941 | ||
951 | static int acpi_fujitsu_hotkey_remove(struct acpi_device *device, int type) | 942 | static int acpi_fujitsu_hotkey_remove(struct acpi_device *device, int type) |
952 | { | 943 | { |
953 | struct fujitsu_hotkey_t *fujitsu_hotkey = NULL; | 944 | struct fujitsu_hotkey_t *fujitsu_hotkey = acpi_driver_data(device); |
945 | struct input_dev *input = fujitsu_hotkey->input; | ||
954 | 946 | ||
955 | if (!device || !acpi_driver_data(device)) | 947 | #ifdef CONFIG_LEDS_CLASS |
956 | return -EINVAL; | 948 | if (fujitsu_hotkey->logolamp_registered) |
949 | led_classdev_unregister(&logolamp_led); | ||
957 | 950 | ||
958 | fujitsu_hotkey = acpi_driver_data(device); | 951 | if (fujitsu_hotkey->kblamps_registered) |
952 | led_classdev_unregister(&kblamps_led); | ||
953 | #endif | ||
959 | 954 | ||
960 | fujitsu_hotkey->acpi_handle = NULL; | 955 | input_unregister_device(input); |
956 | |||
957 | input_free_device(input); | ||
961 | 958 | ||
962 | kfifo_free(fujitsu_hotkey->fifo); | 959 | kfifo_free(fujitsu_hotkey->fifo); |
963 | 960 | ||
961 | fujitsu_hotkey->acpi_handle = NULL; | ||
962 | |||
964 | return 0; | 963 | return 0; |
965 | } | 964 | } |
966 | 965 | ||
@@ -1130,8 +1129,11 @@ static int __init fujitsu_init(void) | |||
1130 | fujitsu->bl_device = | 1129 | fujitsu->bl_device = |
1131 | backlight_device_register("fujitsu-laptop", NULL, NULL, | 1130 | backlight_device_register("fujitsu-laptop", NULL, NULL, |
1132 | &fujitsubl_ops); | 1131 | &fujitsubl_ops); |
1133 | if (IS_ERR(fujitsu->bl_device)) | 1132 | if (IS_ERR(fujitsu->bl_device)) { |
1134 | return PTR_ERR(fujitsu->bl_device); | 1133 | ret = PTR_ERR(fujitsu->bl_device); |
1134 | fujitsu->bl_device = NULL; | ||
1135 | goto fail_sysfs_group; | ||
1136 | } | ||
1135 | max_brightness = fujitsu->max_brightness; | 1137 | max_brightness = fujitsu->max_brightness; |
1136 | fujitsu->bl_device->props.max_brightness = max_brightness - 1; | 1138 | fujitsu->bl_device->props.max_brightness = max_brightness - 1; |
1137 | fujitsu->bl_device->props.brightness = fujitsu->brightness_level; | 1139 | fujitsu->bl_device->props.brightness = fujitsu->brightness_level; |
@@ -1171,32 +1173,22 @@ static int __init fujitsu_init(void) | |||
1171 | return 0; | 1173 | return 0; |
1172 | 1174 | ||
1173 | fail_hotkey1: | 1175 | fail_hotkey1: |
1174 | |||
1175 | kfree(fujitsu_hotkey); | 1176 | kfree(fujitsu_hotkey); |
1176 | |||
1177 | fail_hotkey: | 1177 | fail_hotkey: |
1178 | |||
1179 | platform_driver_unregister(&fujitsupf_driver); | 1178 | platform_driver_unregister(&fujitsupf_driver); |
1180 | |||
1181 | fail_backlight: | 1179 | fail_backlight: |
1182 | |||
1183 | if (fujitsu->bl_device) | 1180 | if (fujitsu->bl_device) |
1184 | backlight_device_unregister(fujitsu->bl_device); | 1181 | backlight_device_unregister(fujitsu->bl_device); |
1185 | 1182 | fail_sysfs_group: | |
1183 | sysfs_remove_group(&fujitsu->pf_device->dev.kobj, | ||
1184 | &fujitsupf_attribute_group); | ||
1186 | fail_platform_device2: | 1185 | fail_platform_device2: |
1187 | |||
1188 | platform_device_del(fujitsu->pf_device); | 1186 | platform_device_del(fujitsu->pf_device); |
1189 | |||
1190 | fail_platform_device1: | 1187 | fail_platform_device1: |
1191 | |||
1192 | platform_device_put(fujitsu->pf_device); | 1188 | platform_device_put(fujitsu->pf_device); |
1193 | |||
1194 | fail_platform_driver: | 1189 | fail_platform_driver: |
1195 | |||
1196 | acpi_bus_unregister_driver(&acpi_fujitsu_driver); | 1190 | acpi_bus_unregister_driver(&acpi_fujitsu_driver); |
1197 | |||
1198 | fail_acpi: | 1191 | fail_acpi: |
1199 | |||
1200 | kfree(fujitsu); | 1192 | kfree(fujitsu); |
1201 | 1193 | ||
1202 | return ret; | 1194 | return ret; |
@@ -1204,28 +1196,23 @@ fail_acpi: | |||
1204 | 1196 | ||
1205 | static void __exit fujitsu_cleanup(void) | 1197 | static void __exit fujitsu_cleanup(void) |
1206 | { | 1198 | { |
1207 | #ifdef CONFIG_LEDS_CLASS | 1199 | acpi_bus_unregister_driver(&acpi_fujitsu_hotkey_driver); |
1208 | if (fujitsu_hotkey->logolamp_registered != 0) | ||
1209 | led_classdev_unregister(&logolamp_led); | ||
1210 | 1200 | ||
1211 | if (fujitsu_hotkey->kblamps_registered != 0) | 1201 | kfree(fujitsu_hotkey); |
1212 | led_classdev_unregister(&kblamps_led); | ||
1213 | #endif | ||
1214 | 1202 | ||
1215 | sysfs_remove_group(&fujitsu->pf_device->dev.kobj, | ||
1216 | &fujitsupf_attribute_group); | ||
1217 | platform_device_unregister(fujitsu->pf_device); | ||
1218 | platform_driver_unregister(&fujitsupf_driver); | 1203 | platform_driver_unregister(&fujitsupf_driver); |
1204 | |||
1219 | if (fujitsu->bl_device) | 1205 | if (fujitsu->bl_device) |
1220 | backlight_device_unregister(fujitsu->bl_device); | 1206 | backlight_device_unregister(fujitsu->bl_device); |
1221 | 1207 | ||
1222 | acpi_bus_unregister_driver(&acpi_fujitsu_driver); | 1208 | sysfs_remove_group(&fujitsu->pf_device->dev.kobj, |
1209 | &fujitsupf_attribute_group); | ||
1223 | 1210 | ||
1224 | kfree(fujitsu); | 1211 | platform_device_unregister(fujitsu->pf_device); |
1225 | 1212 | ||
1226 | acpi_bus_unregister_driver(&acpi_fujitsu_hotkey_driver); | 1213 | acpi_bus_unregister_driver(&acpi_fujitsu_driver); |
1227 | 1214 | ||
1228 | kfree(fujitsu_hotkey); | 1215 | kfree(fujitsu); |
1229 | 1216 | ||
1230 | printk(KERN_INFO "fujitsu-laptop: driver unloaded.\n"); | 1217 | printk(KERN_INFO "fujitsu-laptop: driver unloaded.\n"); |
1231 | } | 1218 | } |