aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/keyboard/atkbd.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/keyboard/atkbd.c')
-rw-r--r--drivers/input/keyboard/atkbd.c51
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
566static void atkbd_event_work(struct work_struct *work) 568static 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 */
587static 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
587static int atkbd_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) 606static 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) {