linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / drivers / input / keyboard / atkbd.c
index 5550b6d..ffacf6e 100644 (file)
@@ -27,7 +27,6 @@
 #include <linux/serio.h>
 #include <linux/workqueue.h>
 #include <linux/libps2.h>
-#include <linux/mutex.h>
 
 #define DRIVER_DESC    "AT and PS/2 keyboard driver"
 
@@ -217,7 +216,7 @@ struct atkbd {
        unsigned long time;
 
        struct work_struct event_work;
-       struct mutex event_mutex;
+       struct semaphore event_sem;
        unsigned long event_mask;
 };
 
@@ -303,19 +302,19 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
        if (atkbd->translated) {
 
                if (atkbd->emul ||
-                   (code != ATKBD_RET_EMUL0 && code != ATKBD_RET_EMUL1 &&
-                    code != ATKBD_RET_HANGUEL && code != ATKBD_RET_HANJA &&
-                    (code != ATKBD_RET_ERR || atkbd->err_xl) &&
-                    (code != ATKBD_RET_BAT || atkbd->bat_xl))) {
+                   !(code == ATKBD_RET_EMUL0 || code == ATKBD_RET_EMUL1 ||
+                     code == ATKBD_RET_HANGUEL || code == ATKBD_RET_HANJA ||
+                    (code == ATKBD_RET_ERR && !atkbd->err_xl) ||
+                    (code == ATKBD_RET_BAT && !atkbd->bat_xl))) {
                        atkbd->release = code >> 7;
                        code &= 0x7f;
                }
 
                if (!atkbd->emul) {
                     if ((code & 0x7f) == (ATKBD_RET_BAT & 0x7f))
-                       atkbd->bat_xl = !(data >> 7);
+                       atkbd->bat_xl = !atkbd->release;
                     if ((code & 0x7f) == (ATKBD_RET_ERR & 0x7f))
-                       atkbd->err_xl = !(data >> 7);
+                       atkbd->err_xl = !atkbd->release;
                }
        }
 
@@ -340,7 +339,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
                        atkbd_report_key(atkbd->dev, regs, KEY_HANJA, 3);
                        goto out;
                case ATKBD_RET_ERR:
-//                     printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys);
+                       printk(KERN_DEBUG "atkbd.c: Keyboard on %s reports too many keys pressed.\n", serio->phys);
                        goto out;
        }
 
@@ -360,13 +359,9 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data,
                        break;
                case ATKBD_KEY_UNKNOWN:
                        if (data == ATKBD_RET_ACK || data == ATKBD_RET_NAK) {
-#if 0
-/* Quite a few key switchers and other tools trigger this and it confuses
-   people who can do nothing about it */                       
                                printk(KERN_WARNING "atkbd.c: Spurious %s on %s. Some program, "
                                       "like XFree86, might be trying access hardware directly.\n",
                                       data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys);
-#endif                                
                        } else {
                                printk(KERN_WARNING "atkbd.c: Unknown key %s "
                                       "(%s set %d, code %#x on %s).\n",
@@ -454,7 +449,7 @@ static void atkbd_event_work(void *data)
        unsigned char param[2];
        int i, j;
 
-       mutex_lock(&atkbd->event_mutex);
+       down(&atkbd->event_sem);
 
        if (test_and_clear_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask)) {
                param[0] = (test_bit(LED_SCROLLL, dev->led) ? 1 : 0)
@@ -485,7 +480,7 @@ static void atkbd_event_work(void *data)
                ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_SETREP);
        }
 
-       mutex_unlock(&atkbd->event_mutex);
+       up(&atkbd->event_sem);
 }
 
 /*
@@ -851,7 +846,7 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
        atkbd->dev = dev;
        ps2_init(&atkbd->ps2dev, serio);
        INIT_WORK(&atkbd->event_work, atkbd_event_work, atkbd);
-       mutex_init(&atkbd->event_mutex);
+       init_MUTEX(&atkbd->event_sem);
 
        switch (serio->id.type) {
 
@@ -867,6 +862,9 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv)
        atkbd->softrepeat = atkbd_softrepeat;
        atkbd->scroll = atkbd_scroll;
 
+       if (!atkbd->write)
+               atkbd->softrepeat = 1;
+
        if (atkbd->softrepeat)
                atkbd->softraw = 1;