parport_pc: show the detection of a 2 serial port ITE8874 chip
[linux-2.6.git] / drivers / char / keyboard.c
index cbf64b9..a7ca752 100644 (file)
@@ -24,6 +24,8 @@
  * 21-08-02: Converted to input API, major cleanup. (Vojtech Pavlik)
  */
 
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
 #include <linux/consolemap.h>
 #include <linux/module.h>
 #include <linux/sched.h>
@@ -38,7 +40,6 @@
 #include <linux/kbd_kern.h>
 #include <linux/kbd_diacr.h>
 #include <linux/vt_kern.h>
-#include <linux/sysrq.h>
 #include <linux/input.h>
 #include <linux/reboot.h>
 #include <linux/notifier.h>
@@ -82,8 +83,7 @@ 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;
-k_handler_fn *k_handler[16] = { K_HANDLERS };
-EXPORT_SYMBOL_GPL(k_handler);
+static k_handler_fn *k_handler[16] = { K_HANDLERS };
 
 #define FN_HANDLERS\
        fn_null,        fn_enter,       fn_show_ptregs, fn_show_mem,\
@@ -133,7 +133,7 @@ static struct input_handler kbd_handler;
 static DEFINE_SPINLOCK(kbd_event_lock);
 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 bool dead_key_next;
 static int npadch = -1;                                        /* -1 or number assembled on pad */
 static unsigned int diacr;
 static char rep;                                       /* flag telling character repeat */
@@ -147,22 +147,6 @@ static struct ledptr {
        unsigned char valid:1;
 } ledptrs[3];
 
-/* Simple translation table for the SysRq keys */
-
-#ifdef CONFIG_MAGIC_SYSRQ
-unsigned char kbd_sysrq_xlate[KEY_MAX + 1] =
-        "\000\0331234567890-=\177\t"                    /* 0x00 - 0x0f */
-        "qwertyuiop[]\r\000as"                          /* 0x10 - 0x1f */
-        "dfghjkl;'`\000\\zxcv"                          /* 0x20 - 0x2f */
-        "bnm,./\000*\000 \000\201\202\203\204\205"      /* 0x30 - 0x3f */
-        "\206\207\210\211\212\000\000789-456+1"         /* 0x40 - 0x4f */
-        "230\177\000\000\213\214\000\000\000\000\000\000\000\000\000\000" /* 0x50 - 0x5f */
-        "\r\000/";                                      /* 0x60 - 0x6f */
-static int sysrq_down;
-static int sysrq_alt_use;
-#endif
-static int sysrq_alt;
-
 /*
  * Notifier list for console keyboard events
  */
@@ -315,7 +299,7 @@ int kbd_rate(struct kbd_repeat *rep)
  */
 static void put_queue(struct vc_data *vc, int ch)
 {
-       struct tty_struct *tty = vc->vc_tty;
+       struct tty_struct *tty = vc->port.tty;
 
        if (tty) {
                tty_insert_flip_char(tty, ch, 0);
@@ -325,7 +309,7 @@ static void put_queue(struct vc_data *vc, int ch)
 
 static void puts_queue(struct vc_data *vc, char *cp)
 {
-       struct tty_struct *tty = vc->vc_tty;
+       struct tty_struct *tty = vc->port.tty;
 
        if (!tty)
                return;
@@ -361,8 +345,8 @@ static void to_utf8(struct vc_data *vc, uint c)
                /* 110***** 10****** */
                put_queue(vc, 0xc0 | (c >> 6));
                put_queue(vc, 0x80 | (c & 0x3f));
-       } else if (c < 0x10000) {
-               if (c >= 0xD800 && c < 0xE000)
+       } else if (c < 0x10000) {
+               if (c >= 0xD800 && c < 0xE000)
                        return;
                if (c == 0xFFFF)
                        return;
@@ -370,7 +354,7 @@ static void to_utf8(struct vc_data *vc, uint c)
                put_queue(vc, 0xe0 | (c >> 12));
                put_queue(vc, 0x80 | ((c >> 6) & 0x3f));
                put_queue(vc, 0x80 | (c & 0x3f));
-       } else if (c < 0x110000) {
+       } else if (c < 0x110000) {
                /* 11110*** 10****** 10****** 10****** */
                put_queue(vc, 0xf0 | (c >> 18));
                put_queue(vc, 0x80 | ((c >> 12) & 0x3f));
@@ -469,6 +453,7 @@ static void fn_enter(struct vc_data *vc)
                }
                diacr = 0;
        }
+
        put_queue(vc, 13);
        if (vc_kbd_mode(kbd, VC_CRLF))
                put_queue(vc, 10);
@@ -478,6 +463,7 @@ static void fn_caps_toggle(struct vc_data *vc)
 {
        if (rep)
                return;
+
        chg_vc_kbd_led(kbd, VC_CAPSLOCK);
 }
 
@@ -485,19 +471,21 @@ static void fn_caps_on(struct vc_data *vc)
 {
        if (rep)
                return;
+
        set_vc_kbd_led(kbd, VC_CAPSLOCK);
 }
 
 static void fn_show_ptregs(struct vc_data *vc)
 {
        struct pt_regs *regs = get_irq_regs();
+
        if (regs)
                show_regs(regs);
 }
 
 static void fn_hold(struct vc_data *vc)
 {
-       struct tty_struct *tty = vc->vc_tty;
+       struct tty_struct *tty = vc->port.tty;
 
        if (rep || !tty)
                return;
@@ -515,7 +503,7 @@ static void fn_hold(struct vc_data *vc)
 
 static void fn_num(struct vc_data *vc)
 {
-       if (vc_kbd_mode(kbd,VC_APPLIC))
+       if (vc_kbd_mode(kbd, VC_APPLIC))
                applkey(vc, 'P', 1);
        else
                fn_bare_num(vc);
@@ -575,7 +563,7 @@ static void fn_inc_console(struct vc_data *vc)
 
 static void fn_send_intr(struct vc_data *vc)
 {
-       struct tty_struct *tty = vc->vc_tty;
+       struct tty_struct *tty = vc->port.tty;
 
        if (!tty)
                return;
@@ -610,7 +598,7 @@ static void fn_boot_it(struct vc_data *vc)
 
 static void fn_compose(struct vc_data *vc)
 {
-       dead_key_next = 1;
+       dead_key_next = true;
 }
 
 static void fn_spawn_con(struct vc_data *vc)
@@ -657,7 +645,7 @@ static void k_spec(struct vc_data *vc, unsigned char value, char up_flag)
 
 static void k_lowercase(struct vc_data *vc, unsigned char value, char up_flag)
 {
-       printk(KERN_ERR "keyboard.c: k_lowercase was called - impossible\n");
+       pr_err("k_lowercase was called - impossible\n");
 }
 
 static void k_unicode(struct vc_data *vc, unsigned int value, char up_flag)
@@ -669,7 +657,7 @@ static void k_unicode(struct vc_data *vc, unsigned int value, char up_flag)
                value = handle_diacr(vc, value);
 
        if (dead_key_next) {
-               dead_key_next = 0;
+               dead_key_next = false;
                diacr = value;
                return;
        }
@@ -691,6 +679,7 @@ static void k_deadunicode(struct vc_data *vc, unsigned int value, char up_flag)
 {
        if (up_flag)
                return;
+
        diacr = (diacr ? handle_diacr(vc, value) : value);
 }
 
@@ -710,29 +699,28 @@ static void k_dead2(struct vc_data *vc, unsigned char value, char up_flag)
 static void k_dead(struct vc_data *vc, unsigned char value, char up_flag)
 {
        static const unsigned char ret_diacr[NR_DEAD] = {'`', '\'', '^', '~', '"', ',' };
-       value = ret_diacr[value];
-       k_deadunicode(vc, value, up_flag);
+
+       k_deadunicode(vc, ret_diacr[value], up_flag);
 }
 
 static void k_cons(struct vc_data *vc, unsigned char value, char up_flag)
 {
        if (up_flag)
                return;
+
        set_console(value);
 }
 
 static void k_fn(struct vc_data *vc, unsigned char value, char up_flag)
 {
-       unsigned v;
-
        if (up_flag)
                return;
-       v = value;
-       if (v < ARRAY_SIZE(func_table)) {
+
+       if ((unsigned)value < ARRAY_SIZE(func_table)) {
                if (func_table[value])
                        puts_queue(vc, func_table[value]);
        } else
-               printk(KERN_ERR "k_fn called with value=%d\n", value);
+               pr_err("k_fn called with value=%d\n", value);
 }
 
 static void k_cur(struct vc_data *vc, unsigned char value, char up_flag)
@@ -741,6 +729,7 @@ static void k_cur(struct vc_data *vc, unsigned char value, char up_flag)
 
        if (up_flag)
                return;
+
        applkey(vc, cur_chars[value], vc_kbd_mode(kbd, VC_CKMODE));
 }
 
@@ -758,43 +747,45 @@ static void k_pad(struct vc_data *vc, unsigned char value, char up_flag)
                return;
        }
 
-       if (!vc_kbd_led(kbd, VC_NUMLOCK))
+       if (!vc_kbd_led(kbd, VC_NUMLOCK)) {
+
                switch (value) {
-                       case KVAL(K_PCOMMA):
-                       case KVAL(K_PDOT):
-                               k_fn(vc, KVAL(K_REMOVE), 0);
-                               return;
-                       case KVAL(K_P0):
-                               k_fn(vc, KVAL(K_INSERT), 0);
-                               return;
-                       case KVAL(K_P1):
-                               k_fn(vc, KVAL(K_SELECT), 0);
-                               return;
-                       case KVAL(K_P2):
-                               k_cur(vc, KVAL(K_DOWN), 0);
-                               return;
-                       case KVAL(K_P3):
-                               k_fn(vc, KVAL(K_PGDN), 0);
-                               return;
-                       case KVAL(K_P4):
-                               k_cur(vc, KVAL(K_LEFT), 0);
-                               return;
-                       case KVAL(K_P6):
-                               k_cur(vc, KVAL(K_RIGHT), 0);
-                               return;
-                       case KVAL(K_P7):
-                               k_fn(vc, KVAL(K_FIND), 0);
-                               return;
-                       case KVAL(K_P8):
-                               k_cur(vc, KVAL(K_UP), 0);
-                               return;
-                       case KVAL(K_P9):
-                               k_fn(vc, KVAL(K_PGUP), 0);
-                               return;
-                       case KVAL(K_P5):
-                               applkey(vc, 'G', vc_kbd_mode(kbd, VC_APPLIC));
-                               return;
+               case KVAL(K_PCOMMA):
+               case KVAL(K_PDOT):
+                       k_fn(vc, KVAL(K_REMOVE), 0);
+                       return;
+               case KVAL(K_P0):
+                       k_fn(vc, KVAL(K_INSERT), 0);
+                       return;
+               case KVAL(K_P1):
+                       k_fn(vc, KVAL(K_SELECT), 0);
+                       return;
+               case KVAL(K_P2):
+                       k_cur(vc, KVAL(K_DOWN), 0);
+                       return;
+               case KVAL(K_P3):
+                       k_fn(vc, KVAL(K_PGDN), 0);
+                       return;
+               case KVAL(K_P4):
+                       k_cur(vc, KVAL(K_LEFT), 0);
+                       return;
+               case KVAL(K_P6):
+                       k_cur(vc, KVAL(K_RIGHT), 0);
+                       return;
+               case KVAL(K_P7):
+                       k_fn(vc, KVAL(K_FIND), 0);
+                       return;
+               case KVAL(K_P8):
+                       k_cur(vc, KVAL(K_UP), 0);
+                       return;
+               case KVAL(K_P9):
+                       k_fn(vc, KVAL(K_PGUP), 0);
+                       return;
+               case KVAL(K_P5):
+                       applkey(vc, 'G', vc_kbd_mode(kbd, VC_APPLIC));
+                       return;
                }
+       }
 
        put_queue(vc, pad_chars[value]);
        if (value == KVAL(K_PENTER) && vc_kbd_mode(kbd, VC_CRLF))
@@ -880,6 +871,7 @@ static void k_lock(struct vc_data *vc, unsigned char value, char up_flag)
 {
        if (up_flag || rep)
                return;
+
        chg_vc_kbd_lock(kbd, value);
 }
 
@@ -888,6 +880,7 @@ static void k_slock(struct vc_data *vc, unsigned char value, char up_flag)
        k_shift(vc, value, up_flag);
        if (up_flag || rep)
                return;
+
        chg_vc_kbd_slock(kbd, value);
        /* try to make Alt, oops, AltGr and such work */
        if (!key_maps[kbd->lockstate ^ kbd->slockstate]) {
@@ -925,12 +918,12 @@ static void k_brlcommit(struct vc_data *vc, unsigned int pattern, char up_flag)
 
 static void k_brl(struct vc_data *vc, unsigned char value, char up_flag)
 {
-       static unsigned pressed,committing;
+       static unsigned pressed, committing;
        static unsigned long releasestart;
 
        if (kbd->kbdmode != VC_UNICODE) {
                if (!up_flag)
-                       printk("keyboard mode must be unicode for braille patterns\n");
+                       pr_warning("keyboard mode must be unicode for braille patterns\n");
                return;
        }
 
@@ -942,32 +935,28 @@ static void k_brl(struct vc_data *vc, unsigned char value, char up_flag)
        if (value > 8)
                return;
 
-       if (up_flag) {
-               if (brl_timeout) {
-                       if (!committing ||
-                           time_after(jiffies,
-                                      releasestart + msecs_to_jiffies(brl_timeout))) {
-                               committing = pressed;
-                               releasestart = jiffies;
-                       }
-                       pressed &= ~(1 << (value - 1));
-                       if (!pressed) {
-                               if (committing) {
-                                       k_brlcommit(vc, committing, 0);
-                                       committing = 0;
-                               }
-                       }
-               } else {
-                       if (committing) {
-                               k_brlcommit(vc, committing, 0);
-                               committing = 0;
-                       }
-                       pressed &= ~(1 << (value - 1));
-               }
-       } else {
+       if (!up_flag) {
                pressed |= 1 << (value - 1);
                if (!brl_timeout)
                        committing = pressed;
+       } else if (brl_timeout) {
+               if (!committing ||
+                   time_after(jiffies,
+                              releasestart + msecs_to_jiffies(brl_timeout))) {
+                       committing = pressed;
+                       releasestart = jiffies;
+               }
+               pressed &= ~(1 << (value - 1));
+               if (!pressed && committing) {
+                       k_brlcommit(vc, committing, 0);
+                       committing = 0;
+               }
+       } else {
+               if (committing) {
+                       k_brlcommit(vc, committing, 0);
+                       committing = 0;
+               }
+               pressed &= ~(1 << (value - 1));
        }
 }
 
@@ -988,6 +977,7 @@ void setledstate(struct kbd_struct *kbd, unsigned int led)
                kbd->ledmode = LED_SHOW_IOCTL;
        } else
                kbd->ledmode = LED_SHOW_FLAGS;
+
        set_leds();
 }
 
@@ -1075,7 +1065,7 @@ static const unsigned short x86_keycodes[256] =
        332,340,365,342,343,344,345,346,356,270,341,368,369,370,371,372 };
 
 #ifdef CONFIG_SPARC
-static int sparc_l1_a_state = 0;
+static int sparc_l1_a_state;
 extern void sun_do_break(void);
 #endif
 
@@ -1085,52 +1075,54 @@ static int emulate_raw(struct vc_data *vc, unsigned int keycode,
        int code;
 
        switch (keycode) {
-               case KEY_PAUSE:
-                       put_queue(vc, 0xe1);
-                       put_queue(vc, 0x1d | up_flag);
-                       put_queue(vc, 0x45 | up_flag);
-                       break;
 
-               case KEY_HANGEUL:
-                       if (!up_flag)
-                               put_queue(vc, 0xf2);
-                       break;
+       case KEY_PAUSE:
+               put_queue(vc, 0xe1);
+               put_queue(vc, 0x1d | up_flag);
+               put_queue(vc, 0x45 | up_flag);
+               break;
 
-               case KEY_HANJA:
-                       if (!up_flag)
-                               put_queue(vc, 0xf1);
-                       break;
+       case KEY_HANGEUL:
+               if (!up_flag)
+                       put_queue(vc, 0xf2);
+               break;
 
-               case KEY_SYSRQ:
-                       /*
-                        * Real AT keyboards (that's what we're trying
-                        * to emulate here emit 0xe0 0x2a 0xe0 0x37 when
-                        * pressing PrtSc/SysRq alone, but simply 0x54
-                        * when pressing Alt+PrtSc/SysRq.
-                        */
-                       if (sysrq_alt) {
-                               put_queue(vc, 0x54 | up_flag);
-                       } else {
-                               put_queue(vc, 0xe0);
-                               put_queue(vc, 0x2a | up_flag);
-                               put_queue(vc, 0xe0);
-                               put_queue(vc, 0x37 | up_flag);
-                       }
-                       break;
+       case KEY_HANJA:
+               if (!up_flag)
+                       put_queue(vc, 0xf1);
+               break;
 
-               default:
-                       if (keycode > 255)
-                               return -1;
+       case KEY_SYSRQ:
+               /*
+                * Real AT keyboards (that's what we're trying
+                * to emulate here emit 0xe0 0x2a 0xe0 0x37 when
+                * pressing PrtSc/SysRq alone, but simply 0x54
+                * when pressing Alt+PrtSc/SysRq.
+                */
+               if (test_bit(KEY_LEFTALT, key_down) ||
+                   test_bit(KEY_RIGHTALT, key_down)) {
+                       put_queue(vc, 0x54 | up_flag);
+               } else {
+                       put_queue(vc, 0xe0);
+                       put_queue(vc, 0x2a | up_flag);
+                       put_queue(vc, 0xe0);
+                       put_queue(vc, 0x37 | up_flag);
+               }
+               break;
 
-                       code = x86_keycodes[keycode];
-                       if (!code)
-                               return -1;
+       default:
+               if (keycode > 255)
+                       return -1;
 
-                       if (code & 0x100)
-                               put_queue(vc, 0xe0);
-                       put_queue(vc, (code & 0x7f) | up_flag);
+               code = x86_keycodes[keycode];
+               if (!code)
+                       return -1;
 
-                       break;
+               if (code & 0x100)
+                       put_queue(vc, 0xe0);
+               put_queue(vc, (code & 0x7f) | up_flag);
+
+               break;
        }
 
        return 0;
@@ -1153,6 +1145,7 @@ static int emulate_raw(struct vc_data *vc, unsigned int keycode, unsigned char u
 static void kbd_rawcode(unsigned char data)
 {
        struct vc_data *vc = vc_cons[fg_console].d;
+
        kbd = kbd_table + vc->vc_num;
        if (kbd->kbdmode == VC_RAW)
                put_queue(vc, data);
@@ -1162,12 +1155,14 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
 {
        struct vc_data *vc = vc_cons[fg_console].d;
        unsigned short keysym, *key_map;
-       unsigned char type, raw_mode;
+       unsigned char type;
+       bool raw_mode;
        struct tty_struct *tty;
        int shift_final;
        struct keyboard_notifier_param param = { .vc = vc, .value = keycode, .down = down };
+       int rc;
 
-       tty = vc->vc_tty;
+       tty = vc->port.tty;
 
        if (tty && (!tty->driver_data)) {
                /* No driver data? Strange. Okay we fix it then. */
@@ -1176,8 +1171,6 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
 
        kbd = kbd_table + vc->vc_num;
 
-       if (keycode == KEY_LEFTALT || keycode == KEY_RIGHTALT)
-               sysrq_alt = down ? keycode : 0;
 #ifdef CONFIG_SPARC
        if (keycode == KEY_STOP)
                sparc_l1_a_state = down;
@@ -1185,29 +1178,16 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
 
        rep = (down == 2);
 
-       if ((raw_mode = (kbd->kbdmode == VC_RAW)) && !hw_raw)
+       raw_mode = (kbd->kbdmode == VC_RAW);
+       if (raw_mode && !hw_raw)
                if (emulate_raw(vc, keycode, !down << 7))
                        if (keycode < BTN_MISC && printk_ratelimit())
-                               printk(KERN_WARNING "keyboard.c: can't emulate rawmode for keycode %d\n", keycode);
+                               pr_warning("can't emulate rawmode for keycode %d\n",
+                                          keycode);
 
-#ifdef CONFIG_MAGIC_SYSRQ             /* Handle the SysRq Hack */
-       if (keycode == KEY_SYSRQ && (sysrq_down || (down == 1 && sysrq_alt))) {
-               if (!sysrq_down) {
-                       sysrq_down = down;
-                       sysrq_alt_use = sysrq_alt;
-               }
-               return;
-       }
-       if (sysrq_down && !down && keycode == sysrq_alt_use)
-               sysrq_down = 0;
-       if (sysrq_down && down && !rep) {
-               handle_sysrq(kbd_sysrq_xlate[keycode], tty);
-               return;
-       }
-#endif
 #ifdef CONFIG_SPARC
        if (keycode == KEY_A && sparc_l1_a_state) {
-               sparc_l1_a_state = 0;
+               sparc_l1_a_state = false;
                sun_do_break();
        }
 #endif
@@ -1229,7 +1209,7 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
                        put_queue(vc, (keycode >> 7) | 0x80);
                        put_queue(vc, keycode | 0x80);
                }
-               raw_mode = 1;
+               raw_mode = true;
        }
 
        if (down)
@@ -1252,29 +1232,32 @@ static void kbd_keycode(unsigned int keycode, int down, int hw_raw)
        param.ledstate = kbd->ledflagstate;
        key_map = key_maps[shift_final];
 
-       if (atomic_notifier_call_chain(&keyboard_notifier_list, KBD_KEYCODE, &param) == NOTIFY_STOP || !key_map) {
-               atomic_notifier_call_chain(&keyboard_notifier_list, KBD_UNBOUND_KEYCODE, &param);
+       rc = atomic_notifier_call_chain(&keyboard_notifier_list,
+                                       KBD_KEYCODE, &param);
+       if (rc == NOTIFY_STOP || !key_map) {
+               atomic_notifier_call_chain(&keyboard_notifier_list,
+                                          KBD_UNBOUND_KEYCODE, &param);
                compute_shiftstate();
                kbd->slockstate = 0;
                return;
        }
 
-       if (keycode >= NR_KEYS)
-               if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8)
-                       keysym = U(K(KT_BRL, keycode - KEY_BRL_DOT1 + 1));
-               else
-                       return;
-       else
+       if (keycode < NR_KEYS)
                keysym = key_map[keycode];
+       else if (keycode >= KEY_BRL_DOT1 && keycode <= KEY_BRL_DOT8)
+               keysym = U(K(KT_BRL, keycode - KEY_BRL_DOT1 + 1));
+       else
+               return;
 
        type = KTYP(keysym);
 
        if (type < 0xf0) {
                param.value = keysym;
-               if (atomic_notifier_call_chain(&keyboard_notifier_list, KBD_UNICODE, &param) == NOTIFY_STOP)
-                       return;
-               if (down && !raw_mode)
-                       to_utf8(vc, keysym);
+               rc = atomic_notifier_call_chain(&keyboard_notifier_list,
+                                               KBD_UNICODE, &param);
+               if (rc != NOTIFY_STOP)
+                       if (down && !raw_mode)
+                               to_utf8(vc, keysym);
                return;
        }
 
@@ -1288,9 +1271,11 @@ 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, &param) == NOTIFY_STOP)
+       param.value = keysym;
+       rc = atomic_notifier_call_chain(&keyboard_notifier_list,
+                                       KBD_KEYSYM, &param);
+       if (rc == NOTIFY_STOP)
                return;
 
        if (raw_mode && type != KT_SPEC && type != KT_SHIFT)
@@ -1323,6 +1308,25 @@ static void kbd_event(struct input_handle *handle, unsigned int event_type,
        schedule_console_callback();
 }
 
+static bool kbd_match(struct input_handler *handler, struct input_dev *dev)
+{
+       int i;
+
+       if (test_bit(EV_SND, dev->evbit))
+               return true;
+
+       if (test_bit(EV_KEY, dev->evbit)) {
+               for (i = KEY_RESERVED; i < BTN_MISC; i++)
+                       if (test_bit(i, dev->keybit))
+                               return true;
+               for (i = KEY_BRL_DOT1; i <= KEY_BRL_DOT10; i++)
+                       if (test_bit(i, dev->keybit))
+                               return true;
+       }
+
+       return false;
+}
+
 /*
  * When a keyboard (or other input device) is found, the kbd_connect
  * function is called. The function then looks at the device, and if it
@@ -1334,14 +1338,6 @@ static int kbd_connect(struct input_handler *handler, struct input_dev *dev,
 {
        struct input_handle *handle;
        int error;
-       int i;
-
-       for (i = KEY_RESERVED; i < BTN_MISC; i++)
-               if (test_bit(i, dev->keybit))
-                       break;
-
-       if (i == BTN_MISC && !test_bit(EV_SND, dev->evbit))
-               return -ENODEV;
 
        handle = kzalloc(sizeof(struct input_handle), GFP_KERNEL);
        if (!handle)
@@ -1407,6 +1403,7 @@ MODULE_DEVICE_TABLE(input, kbd_ids);
 
 static struct input_handler kbd_handler = {
        .event          = kbd_event,
+       .match          = kbd_match,
        .connect        = kbd_connect,
        .disconnect     = kbd_disconnect,
        .start          = kbd_start,