aboutsummaryrefslogtreecommitdiff
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 056ebe84b81..38de44b8750 100644
--- a/drivers/char/keyboard.c
+++ b/drivers/char/keyboard.c
@@ -988,7 +988,7 @@ static inline unsigned char getleds(void)
* interrupt routines for this thing allows us to easily mask
* this when we don't want any of the above to happen.
* This allows for easy and efficient race-condition prevention
- * for kbd_refresh_leds => input_event(dev, EV_LED, ...) => ...
+ * for kbd_start => input_event(dev, EV_LED, ...) => ...
*/
static void kbd_bh(unsigned long dummy)
@@ -1011,23 +1011,6 @@ static void kbd_bh(unsigned long dummy)
DECLARE_TASKLET_DISABLED(keyboard_tasklet, kbd_bh, 0);
-/*
- * This allows a newly plugged keyboard to pick the LED state.
- */
-static void kbd_refresh_leds(struct input_handle *handle)
-{
- unsigned char leds = ledstate;
-
- tasklet_disable(&keyboard_tasklet);
- if (leds != 0xff) {
- input_event(handle->dev, EV_LED, LED_SCROLLL, !!(leds & 0x01));
- input_event(handle->dev, EV_LED, LED_NUML, !!(leds & 0x02));
- input_event(handle->dev, EV_LED, LED_CAPSL, !!(leds & 0x04));
- input_sync(handle->dev);
- }
- tasklet_enable(&keyboard_tasklet);
-}
-
#if defined(CONFIG_X86) || defined(CONFIG_IA64) || defined(CONFIG_ALPHA) ||\
defined(CONFIG_MIPS) || defined(CONFIG_PPC) || defined(CONFIG_SPARC) ||\
defined(CONFIG_PARISC) || defined(CONFIG_SUPERH) ||\
@@ -1307,7 +1290,6 @@ static struct input_handle *kbd_connect(struct input_handler *handler,
handle->name = "kbd";
input_open_device(handle);
- kbd_refresh_leds(handle);
return handle;
}
@@ -1318,6 +1300,24 @@ static void kbd_disconnect(struct input_handle *handle)
kfree(handle);
}
+/*
+ * Start keyboard handler on the new keyboard by refreshing LED state to
+ * match the rest of the system.
+ */
+static void kbd_start(struct input_handle *handle)
+{
+ unsigned char leds = ledstate;
+
+ tasklet_disable(&keyboard_tasklet);
+ if (leds != 0xff) {
+ input_event(handle->dev, EV_LED, LED_SCROLLL, !!(leds & 0x01));
+ input_event(handle->dev, EV_LED, LED_NUML, !!(leds & 0x02));
+ input_event(handle->dev, EV_LED, LED_CAPSL, !!(leds & 0x04));
+ input_sync(handle->dev);
+ }
+ tasklet_enable(&keyboard_tasklet);
+}
+
static struct input_device_id kbd_ids[] = {
{
.flags = INPUT_DEVICE_ID_MATCH_EVBIT,
@@ -1338,6 +1338,7 @@ static struct input_handler kbd_handler = {
.event = kbd_event,
.connect = kbd_connect,
.disconnect = kbd_disconnect,
+ .start = kbd_start,
.name = "kbd",
.id_table = kbd_ids,
};
diff --git a/drivers/input/input.c b/drivers/input/input.c
index c2e4d9bdcab..7aeebb9071c 100644
--- a/drivers/input/input.c
+++ b/drivers/input/input.c
@@ -209,8 +209,13 @@ EXPORT_SYMBOL(input_grab_device);
void input_release_device(struct input_handle *handle)
{
- if (handle->dev->grab == handle)
+ if (handle->dev->grab == handle) {
handle->dev->grab = NULL;
+
+ list_for_each_entry(handle, &handle->dev->h_list, d_node)
+ if (handle->handler->start)
+ handle->handler->start(handle);
+ }
}
EXPORT_SYMBOL(input_release_device);
@@ -954,8 +959,11 @@ int input_register_device(struct input_dev *dev)
list_for_each_entry(handler, &input_handler_list, node)
if (!handler->blacklist || !input_match_device(handler->blacklist, dev))
if ((id = input_match_device(handler->id_table, dev)))
- if ((handle = handler->connect(handler, dev, id)))
+ if ((handle = handler->connect(handler, dev, id))) {
input_link_handle(handle);
+ if (handler->start)
+ handler->start(handle);
+ }
input_wakeup_procfs_readers();