Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 325615
b: refs/heads/master
c: 3db1ddb
h: refs/heads/master
i:
  325613: ea38721
  325611: 279f61b
  325607: 6a58891
  325599: ed92331
v: v3
  • Loading branch information
Alan Cox authored and Greg Kroah-Hartman committed Jul 17, 2012
1 parent fe2c6df commit 417b77f
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 20 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ce7240e445303de3ca66e6d08f17a2ec278a5bf6
refs/heads/master: 3db1ddb725dcd9a2bb32be2b64d0688c3e1c4579
41 changes: 23 additions & 18 deletions trunk/drivers/tty/vt/keyboard.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ static const int NR_TYPES = ARRAY_SIZE(max_vals);

static struct input_handler kbd_handler;
static DEFINE_SPINLOCK(kbd_event_lock);
static DEFINE_SPINLOCK(led_lock);
static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */
static unsigned char shift_down[NR_SHIFT]; /* shift state counters.. */
static bool dead_key_next;
Expand Down Expand Up @@ -984,23 +985,23 @@ static void k_brl(struct vc_data *vc, unsigned char value, char up_flag)
* or (ii) whatever pattern of lights people want to show using KDSETLED,
* or (iii) specified bits of specified words in kernel memory.
*/
unsigned char getledstate(void)
static unsigned char getledstate(void)
{
return ledstate;
}

void setledstate(struct kbd_struct *kbd, unsigned int led)
{
unsigned long flags;
spin_lock_irqsave(&kbd_event_lock, flags);
spin_lock_irqsave(&led_lock, flags);
if (!(led & ~7)) {
ledioctl = led;
kbd->ledmode = LED_SHOW_IOCTL;
} else
kbd->ledmode = LED_SHOW_FLAGS;

set_leds();
spin_unlock_irqrestore(&kbd_event_lock, flags);
spin_unlock_irqrestore(&led_lock, flags);
}

static inline unsigned char getleds(void)
Expand Down Expand Up @@ -1051,8 +1052,11 @@ int vt_get_leds(int console, int flag)
{
struct kbd_struct * kbd = kbd_table + console;
int ret;
unsigned long flags;

spin_lock_irqsave(&led_lock, flags);
ret = vc_kbd_led(kbd, flag);
spin_unlock_irqrestore(&led_lock, flags);

return ret;
}
Expand Down Expand Up @@ -1088,11 +1092,11 @@ void vt_set_led_state(int console, int leds)
void vt_kbd_con_start(int console)
{
struct kbd_struct * kbd = kbd_table + console;
/* unsigned long flags; */
/* spin_lock_irqsave(&kbd_event_lock, flags); */
unsigned long flags;
spin_lock_irqsave(&led_lock, flags);
clr_vc_kbd_led(kbd, VC_SCROLLOCK);
set_leds();
/* spin_unlock_irqrestore(&kbd_event_lock, flags); */
spin_unlock_irqrestore(&led_lock, flags);
}

/**
Expand All @@ -1101,21 +1105,15 @@ void vt_kbd_con_start(int console)
*
* Handle console stop. This is a wrapper for the VT layer
* so that we can keep kbd knowledge internal
*
* FIXME: We eventually need to hold the kbd lock here to protect
* the LED updating. We can't do it yet because fn_hold calls stop_tty
* and start_tty under the kbd_event_lock, while normal tty paths
* don't hold the lock. We probably need to split out an LED lock
* but not during an -rc release!
*/
void vt_kbd_con_stop(int console)
{
struct kbd_struct * kbd = kbd_table + console;
/* unsigned long flags; */
/* spin_lock_irqsave(&kbd_event_lock, flags); */
unsigned long flags;
spin_lock_irqsave(&led_lock, flags);
set_vc_kbd_led(kbd, VC_SCROLLOCK);
set_leds();
/* spin_unlock_irqrestore(&kbd_event_lock, flags); */
spin_unlock_irqrestore(&led_lock, flags);
}

/*
Expand All @@ -1127,7 +1125,12 @@ void vt_kbd_con_stop(int console)
*/
static void kbd_bh(unsigned long dummy)
{
unsigned char leds = getleds();
unsigned char leds;
unsigned long flags;

spin_lock_irqsave(&led_lock, flags);
leds = getleds();
spin_unlock_irqrestore(&led_lock, flags);

if (leds != ledstate) {
input_handler_for_each_handle(&kbd_handler, &leds,
Expand Down Expand Up @@ -2032,11 +2035,11 @@ int vt_do_kdskled(int console, int cmd, unsigned long arg, int perm)
return -EPERM;
if (arg & ~0x77)
return -EINVAL;
spin_lock_irqsave(&kbd_event_lock, flags);
spin_lock_irqsave(&led_lock, flags);
kbd->ledflagstate = (arg & 7);
kbd->default_ledflagstate = ((arg >> 4) & 7);
set_leds();
spin_unlock_irqrestore(&kbd_event_lock, flags);
spin_unlock_irqrestore(&led_lock, flags);
return 0;

/* the ioctls below only set the lights, not the functions */
Expand Down Expand Up @@ -2131,8 +2134,10 @@ void vt_reset_keyboard(int console)
clr_vc_kbd_mode(kbd, VC_CRLF);
kbd->lockstate = 0;
kbd->slockstate = 0;
spin_lock(&led_lock);
kbd->ledmode = LED_SHOW_FLAGS;
kbd->ledflagstate = kbd->default_ledflagstate;
spin_unlock(&led_lock);
/* do not do set_leds here because this causes an endless tasklet loop
when the keyboard hasn't been initialized yet */
spin_unlock_irqrestore(&kbd_event_lock, flags);
Expand Down
1 change: 0 additions & 1 deletion trunk/include/linux/kbd_kern.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ struct kbd_struct {

extern int kbd_init(void);

extern unsigned char getledstate(void);
extern void setledstate(struct kbd_struct *kbd, unsigned int led);

extern int do_poke_blanked_console;
Expand Down

0 comments on commit 417b77f

Please sign in to comment.