On Fri, June 15, 2007 07:41, Dmitry Torokhov wrote: > Does the patch below help?
Didn't try it yet, but will tomorrow. > Input: atkbd - throttle LED switching > > On some boxes keyboard controllers are too slow to withstand > continuous flow of requests to turn keyboard LEDs on and off > and start losing some keypresses or even all of them. > > Delay executing of LED switching request if we had another one > withing 50 ms thus easing load on the controller. > > Signed-off-by: Dmitry Torokhov <[EMAIL PROTECTED]> > --- > > drivers/input/keyboard/atkbd.c | 40 > ++++++++++++++++++++++++++-------------- > 1 files changed, 26 insertions(+), 14 deletions(-) > > Index: work/drivers/input/keyboard/atkbd.c > =================================================================== > --- work.orig/drivers/input/keyboard/atkbd.c > +++ work/drivers/input/keyboard/atkbd.c > @@ -219,7 +219,8 @@ struct atkbd { > unsigned long time; > unsigned long err_count; > > - struct work_struct event_work; > + struct delayed_work event_work; > + unsigned long event_jiffies; > struct mutex event_mutex; > unsigned long event_mask; > }; > @@ -565,7 +566,7 @@ static int atkbd_set_leds(struct atkbd * > > static void atkbd_event_work(struct work_struct *work) > { > - struct atkbd *atkbd = container_of(work, struct atkbd, event_work); > + struct atkbd *atkbd = container_of(work, struct atkbd, event_work.work); > > mutex_lock(&atkbd->event_mutex); > > @@ -579,12 +580,30 @@ static void atkbd_event_work(struct work > } > > /* > + * Schedule switch for execution. We need to throttle requests, > + * otherwise keyboard may become unresponsive. > + */ > +static void atkbd_schedule_event_work(struct atkbd *atkbd, int event_bit) > +{ > + unsigned long delay = msecs_to_jiffies(50); > + > + if (time_after(jiffies, atkbd->event_jiffies + delay)) > + delay = 0; > + > + atkbd->event_jiffies = jiffies; > + set_bit(event_bit, &atkbd->event_mask); > + wmb(); > + schedule_delayed_work(&atkbd->event_work, delay); > +} I don't know whether schedule_delayed_work() requeues event_work, or if it adds more work, but both seem to give wrong behaviour: In the first case event_work can be postponed forever if atkbd_schedule_event_work() is called repeatedly each time within 50 ms, and for the second case there's a delay added, but the number of times the LED is switched stays the same, so it's not being throttled. Greetings, Indan - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to [EMAIL PROTECTED] More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/