diff options
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/char/keyboard.c | 39 | ||||
-rw-r--r-- | drivers/input/input.c | 12 |
2 files changed, 30 insertions, 21 deletions
diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 056ebe84b81d..38de44b87506 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c | |||
@@ -988,7 +988,7 @@ static inline unsigned char getleds(void) | |||
988 | * interrupt routines for this thing allows us to easily mask | 988 | * interrupt routines for this thing allows us to easily mask |
989 | * this when we don't want any of the above to happen. | 989 | * this when we don't want any of the above to happen. |
990 | * This allows for easy and efficient race-condition prevention | 990 | * This allows for easy and efficient race-condition prevention |
991 | * for kbd_refresh_leds => input_event(dev, EV_LED, ...) => ... | 991 | * for kbd_start => input_event(dev, EV_LED, ...) => ... |
992 | */ | 992 | */ |
993 | 993 | ||
994 | static void kbd_bh(unsigned long dummy) | 994 | static void kbd_bh(unsigned long dummy) |
@@ -1011,23 +1011,6 @@ static void kbd_bh(unsigned long dummy) | |||
1011 | 1011 | ||
1012 | DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0); | 1012 | DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0); |
1013 | 1013 | ||
1014 | /* | ||
1015 | * This allows a newly plugged keyboard to pick the LED state. | ||
1016 | */ | ||
1017 | static void kbd_refresh_leds(struct input_handle *handle) | ||
1018 | { | ||
1019 | unsigned char leds = ledstate; | ||
1020 | |||
1021 | tasklet_disable(&keyboard_tasklet); | ||
1022 | if (leds != 0xff) { | ||
1023 | input_event(handle->dev, EV_LED, LED_SCROLLL, !!(leds & 0x01)); | ||
1024 | input_event(handle->dev, EV_LED, LED_NUML, !!(leds & 0x02)); | ||
1025 | input_event(handle->dev, EV_LED, LED_CAPSL, !!(leds & 0x04)); | ||
1026 | input_sync(handle->dev); | ||
1027 | } | ||
1028 | tasklet_enable(&keyboard_tasklet); | ||
1029 | } | ||
1030 | |||
1031 | #if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) ||\ | 1014 | #if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) ||\ |
1032 | defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) ||\ | 1015 | defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) ||\ |
1033 | defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\ | 1016 | defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\ |
@@ -1307,7 +1290,6 @@ static struct input_handle *kbd_connect(struct input_handler *handler, | |||
1307 | handle->name = "kbd"; | 1290 | handle->name = "kbd"; |
1308 | 1291 | ||
1309 | input_open_device(handle); | 1292 | input_open_device(handle); |
1310 | kbd_refresh_leds(handle); | ||
1311 | 1293 | ||
1312 | return handle; | 1294 | return handle; |
1313 | } | 1295 | } |
@@ -1318,6 +1300,24 @@ static void kbd_disconnect(struct input_handle *handle) | |||
1318 | kfree(handle); | 1300 | kfree(handle); |
1319 | } | 1301 | } |
1320 | 1302 | ||
1303 | /* | ||
1304 | * Start keyboard handler on the new keyboard by refreshing LED state to | ||
1305 | * match the rest of the system. | ||
1306 | */ | ||
1307 | static void kbd_start(struct input_handle *handle) | ||
1308 | { | ||
1309 | unsigned char leds = ledstate; | ||
1310 | |||
1311 | tasklet_disable(&keyboard_tasklet); | ||
1312 | if (leds != 0xff) { | ||
1313 | input_event(handle->dev, EV_LED, LED_SCROLLL, !!(leds & 0x01)); | ||
1314 | input_event(handle->dev, EV_LED, LED_NUML, !!(leds & 0x02)); | ||
1315 | input_event(handle->dev, EV_LED, LED_CAPSL, !!(leds & 0x04)); | ||
1316 | input_sync(handle->dev); | ||
1317 | } | ||
1318 | tasklet_enable(&keyboard_tasklet); | ||
1319 | } | ||
1320 | |||
1321 | static struct input_device_id kbd_ids[] = { | 1321 | static struct input_device_id kbd_ids[] = { |
1322 | { | 1322 | { |
1323 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT, | 1323 | .flags = INPUT_DEVICE_ID_MATCH_EVBIT, |
@@ -1338,6 +1338,7 @@ static struct input_handler kbd_handler = { | |||
1338 | .event = kbd_event, | 1338 | .event = kbd_event, |
1339 | .connect = kbd_connect, | 1339 | .connect = kbd_connect, |
1340 | .disconnect = kbd_disconnect, | 1340 | .disconnect = kbd_disconnect, |
1341 | .start = kbd_start, | ||
1341 | .name = "kbd", | 1342 | .name = "kbd", |
1342 | .id_table = kbd_ids, | 1343 | .id_table = kbd_ids, |
1343 | }; | 1344 | }; |
diff --git a/drivers/input/input.c b/drivers/input/input.c index c2e4d9bdcabf..7aeebb9071c2 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -209,8 +209,13 @@ EXPORT_SYMBOL(input_grab_device); | |||
209 | 209 | ||
210 | void input_release_device(struct input_handle *handle) | 210 | void input_release_device(struct input_handle *handle) |
211 | { | 211 | { |
212 | if (handle->dev->grab == handle) | 212 | if (handle->dev->grab == handle) { |
213 | handle->dev->grab = NULL; | 213 | handle->dev->grab = NULL; |
214 | |||
215 | list_for_each_entry(handle, &handle->dev->h_list, d_node) | ||
216 | if (handle->handler->start) | ||
217 | handle->handler->start(handle); | ||
218 | } | ||
214 | } | 219 | } |
215 | EXPORT_SYMBOL(input_release_device); | 220 | EXPORT_SYMBOL(input_release_device); |
216 | 221 | ||
@@ -954,8 +959,11 @@ int input_register_device(struct input_dev *dev) | |||
954 | list_for_each_entry(handler, &input_handler_list, node) | 959 | list_for_each_entry(handler, &input_handler_list, node) |
955 | if (!handler->blacklist || !input_match_device(handler->blacklist, dev)) | 960 | if (!handler->blacklist || !input_match_device(handler->blacklist, dev)) |
956 | if ((id = input_match_device(handler->id_table, dev))) | 961 | if ((id = input_match_device(handler->id_table, dev))) |
957 | if ((handle = handler->connect(handler, dev, id))) | 962 | if ((handle = handler->connect(handler, dev, id))) { |
958 | input_link_handle(handle); | 963 | input_link_handle(handle); |
964 | if (handler->start) | ||
965 | handler->start(handle); | ||
966 | } | ||
959 | 967 | ||
960 | input_wakeup_procfs_readers(); | 968 | input_wakeup_procfs_readers(); |
961 | 969 | ||