diff options
author | Dmitry Torokhov <dtor@insightbb.com> | 2006-07-06 00:21:03 -0400 |
---|---|---|
committer | Dmitry Torokhov <dtor@insightbb.com> | 2006-07-06 00:21:03 -0400 |
commit | c7e8dc6ee6d59bf72f5478fa6355a27750e6c7d2 (patch) | |
tree | fb728aee7806ed08f23cb6e24749d3ce6030bb21 /drivers | |
parent | e9c8862f19958846dd0c7b39d0f6216aad6c7bee (diff) |
Input: add start() method to input handlers
The new start() method is called immediately after connect() and also
when "grabbed" device is released by its owner. This will allow input
handlers to re-synchronize state of once-grabbed device with the rest
of devices.
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
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 | ||