aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
Diffstat (limited to 'drivers')
-rw-r--r--drivers/char/keyboard.c39
-rw-r--r--drivers/input/input.c12
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
994static void kbd_bh(unsigned long dummy) 994static void kbd_bh(unsigned long dummy)
@@ -1011,23 +1011,6 @@ static void kbd_bh(unsigned long dummy)
1011 1011
1012DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0); 1012DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0);
1013 1013
1014/*
1015 * This allows a newly plugged keyboard to pick the LED state.
1016 */
1017static 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 */
1307static 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
1321static struct input_device_id kbd_ids[] = { 1321static 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
210void input_release_device(struct input_handle *handle) 210void 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}
215EXPORT_SYMBOL(input_release_device); 220EXPORT_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