aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/keyboard/atkbd.c
diff options
context:
space:
mode:
authorDmitry Torokhov <dmitry.torokhov@gmail.com>2009-10-14 02:39:17 -0400
committerDmitry Torokhov <dmitry.torokhov@gmail.com>2009-10-14 03:01:19 -0400
commit94dfb0d6334a281a979fe5bee187a3698a4dc176 (patch)
tree2cc150d96a6eeec30b12d833b913c8e3a0478c3e /drivers/input/keyboard/atkbd.c
parentfc0eb28c0031ec2da872dd296b551453eb1963c9 (diff)
Input: atkbd - postpone restoring LED/repeat rate at resume
We need to postpone restoring LED state and typematic settings until keyboard is finished reconnecting upon resume. Normally driver core and PM infrastructure takes care of proper ordering and dependencies, but or case actual reconnect is done asynchronously from kseriod. So while driver core thinks that keyboard was resumed and it is time to let input core run it's resume handlers in reality keyboard is not ready yet. The solution is to keep rescheduling work that adjusts LED and rate settings until keyboard is fully enabled. Reported-by: Carlos R. Mafra <crmafra2@gmail.com> Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input/keyboard/atkbd.c')
-rw-r--r--drivers/input/keyboard/atkbd.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/drivers/input/keyboard/atkbd.c b/drivers/input/keyboard/atkbd.c
index 73b530424729..de520386f13f 100644
--- a/drivers/input/keyboard/atkbd.c
+++ b/drivers/input/keyboard/atkbd.c
@@ -574,11 +574,22 @@ static void atkbd_event_work(struct work_struct *work)
574 574
575 mutex_lock(&atkbd->event_mutex); 575 mutex_lock(&atkbd->event_mutex);
576 576
577 if (test_and_clear_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask)) 577 if (!atkbd->enabled) {
578 atkbd_set_leds(atkbd); 578 /*
579 * Serio ports are resumed asynchronously so while driver core
580 * thinks that device is already fully operational in reality
581 * it may not be ready yet. In this case we need to keep
582 * rescheduling till reconnect completes.
583 */
584 schedule_delayed_work(&atkbd->event_work,
585 msecs_to_jiffies(100));
586 } else {
587 if (test_and_clear_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask))
588 atkbd_set_leds(atkbd);
579 589
580 if (test_and_clear_bit(ATKBD_REP_EVENT_BIT, &atkbd->event_mask)) 590 if (test_and_clear_bit(ATKBD_REP_EVENT_BIT, &atkbd->event_mask))
581 atkbd_set_repeat_rate(atkbd); 591 atkbd_set_repeat_rate(atkbd);
592 }
582 593
583 mutex_unlock(&atkbd->event_mutex); 594 mutex_unlock(&atkbd->event_mutex);
584} 595}