Loading drivers/input/keyboard/atkbd.c +60 −43 Original line number Diff line number Diff line Loading @@ -482,13 +482,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, return IRQ_HANDLED; } /* * atkbd_event_work() is used to complete processing of events that * can not be processed by input_event() which is often called from * interrupt context. */ static void atkbd_event_work(void *data) static int atkbd_set_repeat_rate(struct atkbd *atkbd) { const short period[32] = { 33, 37, 42, 46, 50, 54, 58, 63, 67, 75, 83, 92, 100, 109, 116, 125, Loading @@ -496,18 +490,32 @@ static void atkbd_event_work(void *data) const short delay[4] = { 250, 500, 750, 1000 }; struct atkbd *atkbd = data; struct input_dev *dev = atkbd->dev; unsigned char param[2]; int i, j; unsigned char param; int i = 0, j = 0; mutex_lock(&atkbd->event_mutex); while (i < ARRAY_SIZE(period) - 1 && period[i] < dev->rep[REP_PERIOD]) i++; dev->rep[REP_PERIOD] = period[i]; while (j < ARRAY_SIZE(period) - 1 && delay[j] < dev->rep[REP_DELAY]) j++; dev->rep[REP_DELAY] = delay[j]; param = i | (j << 5); return ps2_command(&atkbd->ps2dev, ¶m, ATKBD_CMD_SETREP); } static int atkbd_set_leds(struct atkbd *atkbd) { struct input_dev *dev = atkbd->dev; unsigned char param[2]; if (test_and_clear_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask)) { param[0] = (test_bit(LED_SCROLLL, dev->led) ? 1 : 0) | (test_bit(LED_NUML, dev->led) ? 2 : 0) | (test_bit(LED_CAPSL, dev->led) ? 4 : 0); ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_SETLEDS); if (ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_SETLEDS)) return -1; if (atkbd->extra) { param[0] = 0; Loading @@ -516,22 +524,31 @@ static void atkbd_event_work(void *data) | (test_bit(LED_SUSPEND, dev->led) ? 0x04 : 0) | (test_bit(LED_MISC, dev->led) ? 0x10 : 0) | (test_bit(LED_MUTE, dev->led) ? 0x20 : 0); ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_EX_SETLEDS); } if (ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_EX_SETLEDS)) return -1; } if (test_and_clear_bit(ATKBD_REP_EVENT_BIT, &atkbd->event_mask)) { i = j = 0; while (i < 31 && period[i] < dev->rep[REP_PERIOD]) i++; while (j < 3 && delay[j] < dev->rep[REP_DELAY]) j++; dev->rep[REP_PERIOD] = period[i]; dev->rep[REP_DELAY] = delay[j]; param[0] = i | (j << 5); ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_SETREP); return 0; } /* * atkbd_event_work() is used to complete processing of events that * can not be processed by input_event() which is often called from * interrupt context. */ static void atkbd_event_work(void *data) { struct atkbd *atkbd = data; mutex_lock(&atkbd->event_mutex); if (test_and_clear_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask)) atkbd_set_leds(atkbd); if (test_and_clear_bit(ATKBD_REP_EVENT_BIT, &atkbd->event_mask)) atkbd_set_repeat_rate(atkbd); mutex_unlock(&atkbd->event_mutex); } Loading Loading @@ -975,7 +992,6 @@ static int atkbd_reconnect(struct serio *serio) { struct atkbd *atkbd = serio_get_drvdata(serio); struct serio_driver *drv = serio->drv; unsigned char param[1]; if (!atkbd || !drv) { printk(KERN_DEBUG "atkbd: reconnect request, but serio is disconnected, ignoring...\n"); Loading @@ -985,10 +1001,6 @@ static int atkbd_reconnect(struct serio *serio) atkbd_disable(atkbd); if (atkbd->write) { param[0] = (test_bit(LED_SCROLLL, atkbd->dev->led) ? 1 : 0) | (test_bit(LED_NUML, atkbd->dev->led) ? 2 : 0) | (test_bit(LED_CAPSL, atkbd->dev->led) ? 4 : 0); if (atkbd_probe(atkbd)) return -1; if (atkbd->set != atkbd_select_set(atkbd, atkbd->set, atkbd->extra)) Loading @@ -996,8 +1008,13 @@ static int atkbd_reconnect(struct serio *serio) atkbd_activate(atkbd); if (ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_SETLEDS)) return -1; /* * Restore repeat rate and LEDs (that were reset by atkbd_activate) * to pre-resume state */ if (!atkbd->softrepeat) atkbd_set_repeat_rate(atkbd); atkbd_set_leds(atkbd); } atkbd_enable(atkbd); Loading Loading
drivers/input/keyboard/atkbd.c +60 −43 Original line number Diff line number Diff line Loading @@ -482,13 +482,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, return IRQ_HANDLED; } /* * atkbd_event_work() is used to complete processing of events that * can not be processed by input_event() which is often called from * interrupt context. */ static void atkbd_event_work(void *data) static int atkbd_set_repeat_rate(struct atkbd *atkbd) { const short period[32] = { 33, 37, 42, 46, 50, 54, 58, 63, 67, 75, 83, 92, 100, 109, 116, 125, Loading @@ -496,18 +490,32 @@ static void atkbd_event_work(void *data) const short delay[4] = { 250, 500, 750, 1000 }; struct atkbd *atkbd = data; struct input_dev *dev = atkbd->dev; unsigned char param[2]; int i, j; unsigned char param; int i = 0, j = 0; mutex_lock(&atkbd->event_mutex); while (i < ARRAY_SIZE(period) - 1 && period[i] < dev->rep[REP_PERIOD]) i++; dev->rep[REP_PERIOD] = period[i]; while (j < ARRAY_SIZE(period) - 1 && delay[j] < dev->rep[REP_DELAY]) j++; dev->rep[REP_DELAY] = delay[j]; param = i | (j << 5); return ps2_command(&atkbd->ps2dev, ¶m, ATKBD_CMD_SETREP); } static int atkbd_set_leds(struct atkbd *atkbd) { struct input_dev *dev = atkbd->dev; unsigned char param[2]; if (test_and_clear_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask)) { param[0] = (test_bit(LED_SCROLLL, dev->led) ? 1 : 0) | (test_bit(LED_NUML, dev->led) ? 2 : 0) | (test_bit(LED_CAPSL, dev->led) ? 4 : 0); ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_SETLEDS); if (ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_SETLEDS)) return -1; if (atkbd->extra) { param[0] = 0; Loading @@ -516,22 +524,31 @@ static void atkbd_event_work(void *data) | (test_bit(LED_SUSPEND, dev->led) ? 0x04 : 0) | (test_bit(LED_MISC, dev->led) ? 0x10 : 0) | (test_bit(LED_MUTE, dev->led) ? 0x20 : 0); ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_EX_SETLEDS); } if (ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_EX_SETLEDS)) return -1; } if (test_and_clear_bit(ATKBD_REP_EVENT_BIT, &atkbd->event_mask)) { i = j = 0; while (i < 31 && period[i] < dev->rep[REP_PERIOD]) i++; while (j < 3 && delay[j] < dev->rep[REP_DELAY]) j++; dev->rep[REP_PERIOD] = period[i]; dev->rep[REP_DELAY] = delay[j]; param[0] = i | (j << 5); ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_SETREP); return 0; } /* * atkbd_event_work() is used to complete processing of events that * can not be processed by input_event() which is often called from * interrupt context. */ static void atkbd_event_work(void *data) { struct atkbd *atkbd = data; mutex_lock(&atkbd->event_mutex); if (test_and_clear_bit(ATKBD_LED_EVENT_BIT, &atkbd->event_mask)) atkbd_set_leds(atkbd); if (test_and_clear_bit(ATKBD_REP_EVENT_BIT, &atkbd->event_mask)) atkbd_set_repeat_rate(atkbd); mutex_unlock(&atkbd->event_mutex); } Loading Loading @@ -975,7 +992,6 @@ static int atkbd_reconnect(struct serio *serio) { struct atkbd *atkbd = serio_get_drvdata(serio); struct serio_driver *drv = serio->drv; unsigned char param[1]; if (!atkbd || !drv) { printk(KERN_DEBUG "atkbd: reconnect request, but serio is disconnected, ignoring...\n"); Loading @@ -985,10 +1001,6 @@ static int atkbd_reconnect(struct serio *serio) atkbd_disable(atkbd); if (atkbd->write) { param[0] = (test_bit(LED_SCROLLL, atkbd->dev->led) ? 1 : 0) | (test_bit(LED_NUML, atkbd->dev->led) ? 2 : 0) | (test_bit(LED_CAPSL, atkbd->dev->led) ? 4 : 0); if (atkbd_probe(atkbd)) return -1; if (atkbd->set != atkbd_select_set(atkbd, atkbd->set, atkbd->extra)) Loading @@ -996,8 +1008,13 @@ static int atkbd_reconnect(struct serio *serio) atkbd_activate(atkbd); if (ps2_command(&atkbd->ps2dev, param, ATKBD_CMD_SETLEDS)) return -1; /* * Restore repeat rate and LEDs (that were reset by atkbd_activate) * to pre-resume state */ if (!atkbd->softrepeat) atkbd_set_repeat_rate(atkbd); atkbd_set_leds(atkbd); } atkbd_enable(atkbd); Loading