aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/keyboard
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-05 18:55:37 -0400
committerLinus Torvalds <torvalds@woody.linux-foundation.org>2007-07-05 18:55:37 -0400
commitcab8e5c4444cb7d9b8035de5d81fbfd5284a02fa (patch)
tree04af29514a1e879eb254fb758f57a978d9033bd4 /drivers/input/keyboard
parent0dac723e5c15ddb9bd26c1db21ee64ab71ae4925 (diff)
parent4e4eda866ec7bd7a151e4884a291221eb74644ae (diff)
Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input
* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/dtor/input: Input: document some of keycodes Input: add a new EV_SW SW_RADIO event, for radio switches on laptops Input: serio - take drv_mutex in serio_cleanup() Input: atkbd - use printk_ratelimit for spurious ACK messages Input: atkbd - throttle LED switching Input: i8042 - add HP Pavilion ZT1000 to the MUX blacklist
Diffstat (limited to 'drivers/input/keyboard')
-rw-r--r--drivers/input/keyboard/atkbd.c47
1 files changed, 30 insertions, 17 deletions
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index be1fe46cd308..9950fcb33650 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -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) {