diff options
Diffstat (limited to 'drivers/input/keyboard/atkbd.c')
-rw-r--r-- | drivers/input/keyboard/atkbd.c | 51 |
1 files changed, 32 insertions, 19 deletions
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c index be1fe46cd308..41fc3d03b6eb 100644 --- a/drivers/input/keyboard/atkbd.c +++ b/drivers/input/keyboard/atkbd.c | |||
@@ -89,7 +89,7 @@ static unsigned char atkbd_set2_keycode[512] = { | |||
89 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, | 89 | 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, |
90 | 217,100,255, 0, 97,165, 0, 0,156, 0, 0, 0, 0, 0, 0,125, | 90 | 217,100,255, 0, 97,165, 0, 0,156, 0, 0, 0, 0, 0, 0,125, |
91 | 173,114, 0,113, 0, 0, 0,126,128, 0, 0,140, 0, 0, 0,127, | 91 | 173,114, 0,113, 0, 0, 0,126,128, 0, 0,140, 0, 0, 0,127, |
92 | 159, 0,115, 0,164, 0, 0,116,158, 0,150,166, 0, 0, 0,142, | 92 | 159, 0,115, 0,164, 0, 0,116,158, 0,172,166, 0, 0, 0,142, |
93 | 157, 0, 0, 0, 0, 0, 0, 0,155, 0, 98, 0, 0,163, 0, 0, | 93 | 157, 0, 0, 0, 0, 0, 0, 0,155, 0, 98, 0, 0,163, 0, 0, |
94 | 226, 0, 0, 0, 0, 0, 0, 0, 0,255, 96, 0, 0, 0,143, 0, | 94 | 226, 0, 0, 0, 0, 0, 0, 0, 0,255, 96, 0, 0, 0,143, 0, |
95 | 0, 0, 0, 0, 0, 0, 0, 0, 0,107, 0,105,102, 0, 0,112, | 95 | 0, 0, 0, 0, 0, 0, 0, 0, 0,107, 0,105,102, 0, 0,112, |
@@ -111,7 +111,7 @@ static unsigned char atkbd_set3_keycode[512] = { | |||
111 | 82, 83, 80, 76, 77, 72, 69, 98, 0, 96, 81, 0, 78, 73, 55,183, | 111 | 82, 83, 80, 76, 77, 72, 69, 98, 0, 96, 81, 0, 78, 73, 55,183, |
112 | 112 | ||
113 | 184,185,186,187, 74, 94, 92, 93, 0, 0, 0,125,126,127,112, 0, | 113 | 184,185,186,187, 74, 94, 92, 93, 0, 0, 0,125,126,127,112, 0, |
114 | 0,139,150,163,165,115,152,150,166,140,160,154,113,114,167,168, | 114 | 0,139,172,163,165,115,152,172,166,140,160,154,113,114,167,168, |
115 | 148,149,147,140 | 115 | 148,149,147,140 |
116 | }; | 116 | }; |
117 | 117 | ||
@@ -219,7 +219,8 @@ struct atkbd { | |||
219 | unsigned long time; | 219 | unsigned long time; |
220 | unsigned long err_count; | 220 | unsigned long err_count; |
221 | 221 | ||
222 | struct work_struct event_work; | 222 | struct delayed_work event_work; |
223 | unsigned long event_jiffies; | ||
223 | struct mutex event_mutex; | 224 | struct mutex event_mutex; |
224 | unsigned long event_mask; | 225 | unsigned long event_mask; |
225 | }; | 226 | }; |
@@ -408,9 +409,10 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, | |||
408 | goto out; | 409 | goto out; |
409 | case ATKBD_RET_ACK: | 410 | case ATKBD_RET_ACK: |
410 | case ATKBD_RET_NAK: | 411 | case ATKBD_RET_NAK: |
411 | printk(KERN_WARNING "atkbd.c: Spurious %s on %s. " | 412 | if (printk_ratelimit()) |
412 | "Some program might be trying access hardware directly.\n", | 413 | printk(KERN_WARNING "atkbd.c: Spurious %s on %s. " |
413 | data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys); | 414 | "Some program might be trying access hardware directly.\n", |
415 | data == ATKBD_RET_ACK ? "ACK" : "NAK", serio->phys); | ||
414 | goto out; | 416 | goto out; |
415 | case ATKBD_RET_HANGEUL: | 417 | case ATKBD_RET_HANGEUL: |
416 | case ATKBD_RET_HANJA: | 418 | case ATKBD_RET_HANJA: |
@@ -565,7 +567,7 @@ static int atkbd_set_leds(struct atkbd *atkbd) | |||
565 | 567 | ||
566 | static void atkbd_event_work(struct work_struct *work) | 568 | static void atkbd_event_work(struct work_struct *work) |
567 | { | 569 | { |
568 | struct atkbd *atkbd = container_of(work, struct atkbd, event_work); | 570 | struct atkbd *atkbd = container_of(work, struct atkbd, event_work.work); |
569 | 571 | ||
570 | mutex_lock(&atkbd->event_mutex); | 572 | mutex_lock(&atkbd->event_mutex); |
571 | 573 | ||
@@ -579,12 +581,30 @@ static void atkbd_event_work(struct work_struct *work) | |||
579 | } | 581 | } |
580 | 582 | ||
581 | /* | 583 | /* |
584 | * Schedule switch for execution. We need to throttle requests, | ||
585 | * otherwise keyboard may become unresponsive. | ||
586 | */ | ||
587 | static void atkbd_schedule_event_work(struct atkbd *atkbd, int event_bit) | ||
588 | { | ||
589 | unsigned long delay = msecs_to_jiffies(50); | ||
590 | |||
591 | if (time_after(jiffies, atkbd->event_jiffies + delay)) | ||
592 | delay = 0; | ||
593 | |||
594 | atkbd->event_jiffies = jiffies; | ||
595 | set_bit(event_bit, &atkbd->event_mask); | ||
596 | wmb(); | ||
597 | schedule_delayed_work(&atkbd->event_work, delay); | ||
598 | } | ||
599 | |||
600 | /* | ||
582 | * Event callback from the input module. Events that change the state of | 601 | * Event callback from the input module. Events that change the state of |
583 | * the hardware are processed here. If action can not be performed in | 602 | * the hardware are processed here. If action can not be performed in |
584 | * interrupt context it is offloaded to atkbd_event_work. | 603 | * interrupt context it is offloaded to atkbd_event_work. |
585 | */ | 604 | */ |
586 | 605 | ||
587 | static int atkbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) | 606 | static int atkbd_event(struct input_dev *dev, |
607 | unsigned int type, unsigned int code, int value) | ||
588 | { | 608 | { |
589 | struct atkbd *atkbd = input_get_drvdata(dev); | 609 | struct atkbd *atkbd = input_get_drvdata(dev); |
590 | 610 | ||
@@ -594,19 +614,12 @@ static int atkbd_event(struct input_dev *dev, unsigned int type, unsigned int co | |||
594 | switch (type) { | 614 | switch (type) { |
595 | 615 | ||
596 | case EV_LED: | 616 | case EV_LED: |
597 | set_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask); | 617 | atkbd_schedule_event_work(atkbd, ATKBD_LED_EVENT_BIT); |
598 | wmb(); | ||
599 | schedule_work(&atkbd->event_work); | ||
600 | return 0; | 618 | return 0; |
601 | 619 | ||
602 | case EV_REP: | 620 | case EV_REP: |
603 | 621 | if (!atkbd->softrepeat) | |
604 | if (!atkbd->softrepeat) { | 622 | atkbd_schedule_event_work(atkbd, ATKBD_REP_EVENT_BIT); |
605 | set_bit(ATKBD_REP_EVENT_BIT, &atkbd->event_mask); | ||
606 | wmb(); | ||
607 | schedule_work(&atkbd->event_work); | ||
608 | } | ||
609 | |||
610 | return 0; | 623 | return 0; |
611 | } | 624 | } |
612 | 625 | ||
@@ -940,7 +953,7 @@ static int atkbd_connect(struct serio *serio, struct serio_driver *drv) | |||
940 | 953 | ||
941 | atkbd->dev = dev; | 954 | atkbd->dev = dev; |
942 | ps2_init(&atkbd->ps2dev, serio); | 955 | ps2_init(&atkbd->ps2dev, serio); |
943 | INIT_WORK(&atkbd->event_work, atkbd_event_work); | 956 | INIT_DELAYED_WORK(&atkbd->event_work, atkbd_event_work); |
944 | mutex_init(&atkbd->event_mutex); | 957 | mutex_init(&atkbd->event_mutex); |
945 | 958 | ||
946 | switch (serio->id.type) { | 959 | switch (serio->id.type) { |