X-Git-Url: http://pilppa.org/gitweb/gitweb.cgi?a=blobdiff_plain;f=drivers%2Fchar%2Fkeyboard.c;h=45806d27579ab8bbc13f94d2f6865fa0b9b5b9e9;hb=b39b04403bba4f807ee6e57ae2f4407187588fcd;hp=212276affa1f5c887233cdd3c14e987a6941fd22;hpb=fe2520094d88018423dfc42b3cd0015f74e8adea;p=linux-2.6-omap-h63xx.git diff --git a/drivers/char/keyboard.c b/drivers/char/keyboard.c index 212276affa1..45806d27579 100644 --- a/drivers/char/keyboard.c +++ b/drivers/char/keyboard.c @@ -38,10 +38,11 @@ #include #include #include -#include #include #include #include +#include +#include extern void ctrl_alt_del(void); @@ -81,7 +82,8 @@ void compute_shiftstate(void); typedef void (k_handler_fn)(struct vc_data *vc, unsigned char value, char up_flag); static k_handler_fn K_HANDLERS; -static k_handler_fn *k_handler[16] = { K_HANDLERS }; +k_handler_fn *k_handler[16] = { K_HANDLERS }; +EXPORT_SYMBOL_GPL(k_handler); #define FN_HANDLERS\ fn_null, fn_enter, fn_show_ptregs, fn_show_mem,\ @@ -127,7 +129,7 @@ int shift_state = 0; */ static struct input_handler kbd_handler; -static unsigned long key_down[NBITS(KEY_MAX)]; /* keyboard key bitmap */ +static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */ static unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */ static int dead_key_next; static int npadch = -1; /* -1 or number assembled on pad */ @@ -159,6 +161,23 @@ static int sysrq_alt_use; #endif static int sysrq_alt; +/* + * Notifier list for console keyboard events + */ +static ATOMIC_NOTIFIER_HEAD(keyboard_notifier_list); + +int register_keyboard_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_register(&keyboard_notifier_list, nb); +} +EXPORT_SYMBOL_GPL(register_keyboard_notifier); + +int unregister_keyboard_notifier(struct notifier_block *nb) +{ + return atomic_notifier_chain_unregister(&keyboard_notifier_list, nb); +} +EXPORT_SYMBOL_GPL(unregister_keyboard_notifier); + /* * Translation of scancodes to keycodes. We set them on only the first * keyboard in the list that accepts the scancode and keycode. @@ -175,7 +194,7 @@ int getkeycode(unsigned int scancode) int error = -ENODEV; list_for_each_entry(handle, &kbd_handler.h_list, h_node) { - error = handle->dev->getkeycode(handle->dev, scancode, &keycode); + error = input_get_keycode(handle->dev, scancode, &keycode); if (!error) return keycode; } @@ -189,7 +208,7 @@ int setkeycode(unsigned int scancode, unsigned int keycode) int error = -ENODEV; list_for_each_entry(handle, &kbd_handler.h_list, h_node) { - error = handle->dev->setkeycode(handle->dev, scancode, keycode); + error = input_set_keycode(handle->dev, scancode, keycode); if (!error) break; } @@ -910,7 +929,8 @@ static void k_brl(struct vc_data *vc, unsigned char value, char up_flag) if (up_flag) { if (brl_timeout) { if (!committing || - jiffies - releasestart > (brl_timeout * HZ) / 1000) { + time_after(jiffies, + releasestart + msecs_to_jiffies(brl_timeout))) { committing = pressed; releasestart = jiffies; } @@ -1130,6 +1150,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) unsigned char type, raw_mode; struct tty_struct *tty; int shift_final; + struct keyboard_notifier_param param = { .vc = vc, .value = keycode, .down = down }; tty = vc->vc_tty; @@ -1217,10 +1238,12 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) return; } - shift_final = (shift_state | kbd->slockstate) ^ kbd->lockstate; + param.shift = shift_final = (shift_state | kbd->slockstate) ^ kbd->lockstate; + param.ledstate = kbd->ledflagstate; key_map = key_maps[shift_final]; - if (!key_map) { + if (atomic_notifier_call_chain(&keyboard_notifier_list, KBD_KEYCODE, ¶m) == NOTIFY_STOP || !key_map) { + atomic_notifier_call_chain(&keyboard_notifier_list, KBD_UNBOUND_KEYCODE, ¶m); compute_shiftstate(); kbd->slockstate = 0; return; @@ -1237,6 +1260,9 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) type = KTYP(keysym); if (type < 0xf0) { + param.value = keysym; + if (atomic_notifier_call_chain(&keyboard_notifier_list, KBD_UNICODE, ¶m) == NOTIFY_STOP) + return; if (down && !raw_mode) to_utf8(vc, keysym); return; @@ -1244,9 +1270,6 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) type -= 0xf0; - if (raw_mode && type != KT_SPEC && type != KT_SHIFT) - return; - if (type == KT_LETTER) { type = KT_LATIN; if (vc_kbd_led(kbd, VC_CAPSLOCK)) { @@ -1255,9 +1278,19 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw) keysym = key_map[keycode]; } } + param.value = keysym; + + if (atomic_notifier_call_chain(&keyboard_notifier_list, KBD_KEYSYM, ¶m) == NOTIFY_STOP) + return; + + if (raw_mode && type != KT_SPEC && type != KT_SHIFT) + return; (*k_handler[type])(vc, keysym & 0xff, !down); + param.ledstate = kbd->ledflagstate; + atomic_notifier_call_chain(&keyboard_notifier_list, KBD_POST_KEYSYM, ¶m); + if (type != KT_SLOCK) kbd->slockstate = 0; } @@ -1347,12 +1380,12 @@ static void kbd_start(struct input_handle *handle) static const struct input_device_id kbd_ids[] = { { .flags = INPUT_DEVICE_ID_MATCH_EVBIT, - .evbit = { BIT(EV_KEY) }, + .evbit = { BIT_MASK(EV_KEY) }, }, { .flags = INPUT_DEVICE_ID_MATCH_EVBIT, - .evbit = { BIT(EV_SND) }, + .evbit = { BIT_MASK(EV_SND) }, }, { }, /* Terminating entry */