aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorDmitry Torokhov <dtor@insightbb.com>2006-07-06 00:21:03 -0400
committerDmitry Torokhov <dtor@insightbb.com>2006-07-06 00:21:03 -0400
commitc7e8dc6ee6d59bf72f5478fa6355a27750e6c7d2 (patch)
treefb728aee7806ed08f23cb6e24749d3ce6030bb21 /drivers
parente9c8862f19958846dd0c7b39d0f6216aad6c7bee (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.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