diff options
Diffstat (limited to 'drivers/input/keyboard/atkbd.c')
| -rw-r--r-- | drivers/input/keyboard/atkbd.c | 24 |
1 files changed, 11 insertions, 13 deletions
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index ffacf6eca5f5..fad04b66d268 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
| @@ -27,6 +27,7 @@ | |||
| 27 | #include <linux/serio.h> | 27 | #include <linux/serio.h> |
| 28 | #include <linux/workqueue.h> | 28 | #include <linux/workqueue.h> |
| 29 | #include <linux/libps2.h> | 29 | #include <linux/libps2.h> |
| 30 | #include <linux/mutex.h> | ||
| 30 | 31 | ||
| 31 | #define DRIVER_DESC "AT and PS/2 keyboard driver" | 32 | #define DRIVER_DESC "AT and PS/2 keyboard driver" |
| 32 | 33 | ||
| @@ -216,7 +217,7 @@ struct atkbd { | |||
| 216 | unsigned long time; | 217 | unsigned long time; |
| 217 | 218 | ||
| 218 | struct work_struct event_work; | 219 | struct work_struct event_work; |
| 219 | struct semaphore event_sem; | 220 | struct mutex event_mutex; |
| 220 | unsigned long event_mask; | 221 | unsigned long event_mask; |
| 221 | }; | 222 | }; |
| 222 | 223 | ||
| @@ -302,19 +303,19 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, | |||
| 302 | if (atkbd->translated) { | 303 | if (atkbd->translated) { |
| 303 | 304 | ||
| 304 | if (atkbd->emul || | 305 | if (atkbd->emul || |
| 305 | !(code == ATKBD_RET_EMUL0 || code == ATKBD_RET_EMUL1 || | 306 | (code != ATKBD_RET_EMUL0 && code != ATKBD_RET_EMUL1 && |
| 306 | code == ATKBD_RET_HANGUEL || code == ATKBD_RET_HANJA || | 307 | code != ATKBD_RET_HANGUEL && code != ATKBD_RET_HANJA && |
| 307 | (code == ATKBD_RET_ERR && !atkbd->err_xl) || | 308 | (code != ATKBD_RET_ERR || atkbd->err_xl) && |
| 308 | (code == ATKBD_RET_BAT && !atkbd->bat_xl))) { | 309 | (code != ATKBD_RET_BAT || atkbd->bat_xl))) { |
| 309 | atkbd->release = code >> 7; | 310 | atkbd->release = code >> 7; |
| 310 | code &= 0x7f; | 311 | code &= 0x7f; |
| 311 | } | 312 | } |
| 312 | 313 | ||
| 313 | if (!atkbd->emul) { | 314 | if (!atkbd->emul) { |
| 314 | if ((code & 0x7f) == (ATKBD_RET_BAT & 0x7f)) | 315 | if ((code & 0x7f) == (ATKBD_RET_BAT & 0x7f)) |
| 315 | atkbd->bat_xl = !atkbd->release; | 316 | atkbd->bat_xl = !(data >> 7); |
| 316 | if ((code & 0x7f) == (ATKBD_RET_ERR & 0x7f)) | 317 | if ((code & 0x7f) == (ATKBD_RET_ERR & 0x7f)) |
| 317 | atkbd->err_xl = !atkbd->release; | 318 | atkbd->err_xl = !(data >> 7); |
| 318 | } | 319 | } |
| 319 | } | 320 | } |
| 320 | 321 | ||
| @@ -449,7 +450,7 @@ static void atkbd_event_work(void *data) | |||
| 449 | unsigned char param[2]; | 450 | unsigned char param[2]; |
| 450 | int i, j; | 451 | int i, j; |
| 451 | 452 | ||
| 452 | down(&atkbd->event_sem); | 453 | mutex_lock(&atkbd->event_mutex); |
| 453 | 454 | ||
| 454 | if (test_and_clear_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask)) { | 455 | if (test_and_clear_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask)) { |
| 455 | param[0] = (test_bit(LED_SCROLLL, dev->led) ? 1 : 0) | 456 | param[0] = (test_bit(LED_SCROLLL, dev->led) ? 1 : 0) |
| @@ -480,7 +481,7 @@ static void atkbd_event_work(void *data) | |||
| 480 | ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_SETREP); | 481 | ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_SETREP); |
| 481 | } | 482 | } |
| 482 | 483 | ||
| 483 | up(&atkbd->event_sem); | 484 | mutex_unlock(&atkbd->event_mutex); |
| 484 | } | 485 | } |
| 485 | 486 | ||
| 486 | /* | 487 | /* |
| @@ -846,7 +847,7 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
| 846 | atkbd->dev = dev; | 847 | atkbd->dev = dev; |
| 847 | ps2_init(&atkbd->ps2dev, serio); | 848 | ps2_init(&atkbd->ps2dev, serio); |
| 848 | INIT_WORK(&atkbd->event_work, atkbd_event_work, atkbd); | 849 | INIT_WORK(&atkbd->event_work, atkbd_event_work, atkbd); |
| 849 | init_MUTEX(&atkbd->event_sem); | 850 | mutex_init(&atkbd->event_mutex); |
| 850 | 851 | ||
| 851 | switch (serio->id.type) { | 852 | switch (serio->id.type) { |
| 852 | 853 | ||
| @@ -862,9 +863,6 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
| 862 | atkbd->softrepeat = atkbd_softrepeat; | 863 | atkbd->softrepeat = atkbd_softrepeat; |
| 863 | atkbd->scroll = atkbd_scroll; | 864 | atkbd->scroll = atkbd_scroll; |
| 864 | 865 | ||
| 865 | if (!atkbd->write) | ||
| 866 | atkbd->softrepeat = 1; | ||
| 867 | |||
| 868 | if (atkbd->softrepeat) | 866 | if (atkbd->softrepeat) |
| 869 | atkbd->softraw = 1; | 867 | atkbd->softraw = 1; |
| 870 | 868 | ||
