summaryrefslogtreecommitdiffstats
path: root/drivers/tty/vt/keyboard.c
diff options
context:
space:
mode:
authorOlof Johansson <olof@lixom.net>2012-09-20 13:19:32 -0700
committerOlof Johansson <olof@lixom.net>2012-09-20 13:22:20 -0700
commit2843c7d2c03da38dfb14102254d0c767d2483349 (patch)
tree8698671fd889ed9d6237cf9ea093e8bb1fc999b3 /drivers/tty/vt/keyboard.c
parent084cfebc03ede864835594181210b501aa9f1933 (diff)
parent6bfc82ff589a00e5fbc12b958c649d703d273c86 (diff)
Merge tag 'omap-devel-dt-merged-for-v3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap into next/dt
Device tree related changes for omaps. Note that this branch is based on omap-cleanup-sparseirq-for-v3.7 to avoid merge conflicts with the sparseirq changes for gpio-twl4030 driver. * tag 'omap-devel-dt-merged-for-v3.7' of git://git.kernel.org/pub/scm/linux/kernel/git/tmlind/linux-omap: arm/dts: Mux uart pins for omap4-sdp ARM: OMAP2+: select PINCTRL in Kconfig arm/dts: Add pinctrl driver entries for omap2/3/4 arm/dts: Add omap36xx.dtsi file and rename omap3-beagle to omap3-beagle-xm ARM: dts: omap3-overo: Add support for the blue LED Documentation: dt: Update the OMAP documentation with Overo/Toby ARM: dts: OMAP3: Add support for Gumstix Overo with Tobi expansion board ARM: dts: OMAP4: Add reg and interrupts for every nodes ARM: dts: AM33XX: Specify reg and interrupt property for all nodes ARM: dts: AM33XX: Convert all hex numbers to lower-case ARM: dts: omap3-beagle: Enable audio support ARM: dts: omap5: Add McPDM and DMIC section to the dtsi file ARM: dts: omap5: Add McBSP entries ARM: dts: omap4: Add reg-names for McPDM and DMIC ARM: dts: omap4: Add McBSP entries ARM: dts: omap3: Add McBSP entries ARM: dts: omap2420-h4: Include omap2420.dtsi file instead the common omap2 ARM: dts: omap2: Add McBSP entries for OMAP2420 and OMAP2430 SoC ARM: dts: omap3-beagle: Add heartbeat and mmc LEDs support ARM: dts: omap3: Add gpio-twl4030 properties for BeagleBoard and omap3-EVM ...
Diffstat (limited to 'drivers/tty/vt/keyboard.c')
-rw-r--r--drivers/tty/vt/keyboard.c50
1 files changed, 26 insertions, 24 deletions
diff --git a/drivers/tty/vt/keyboard.c b/drivers/tty/vt/keyboard.c
index 48cc6f25cfd..681765baef6 100644
--- a/drivers/tty/vt/keyboard.c
+++ b/drivers/tty/vt/keyboard.c
@@ -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;
@@ -310,7 +311,7 @@ static void put_queue(struct vc_data *vc, int ch)
if (tty) {
tty_insert_flip_char(tty, ch, 0);
- con_schedule_flip(tty);
+ tty_schedule_flip(tty);
}
}
@@ -325,7 +326,7 @@ static void puts_queue(struct vc_data *vc, char *cp)
tty_insert_flip_char(tty, *cp, 0);
cp++;
}
- con_schedule_flip(tty);
+ tty_schedule_flip(tty);
}
static void applkey(struct vc_data *vc, int key, char mode)
@@ -586,7 +587,7 @@ static void fn_send_intr(struct vc_data *vc)
if (!tty)
return;
tty_insert_flip_char(tty, 0, TTY_BREAK);
- con_schedule_flip(tty);
+ tty_schedule_flip(tty);
}
static void fn_scroll_forw(struct vc_data *vc)
@@ -984,7 +985,7 @@ 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;
}
@@ -992,7 +993,7 @@ unsigned char getledstate(void)
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;
@@ -1000,7 +1001,7 @@ void setledstate(struct kbd_struct *kbd, unsigned int led)
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)
@@ -1049,13 +1050,13 @@ static int kbd_update_leds_helper(struct input_handle *handle, void *data)
*/
int vt_get_leds(int console, int flag)
{
- unsigned long flags;
struct kbd_struct * kbd = kbd_table + console;
int ret;
+ unsigned long flags;
- spin_lock_irqsave(&kbd_event_lock, flags);
+ spin_lock_irqsave(&led_lock, flags);
ret = vc_kbd_led(kbd, flag);
- spin_unlock_irqrestore(&kbd_event_lock, flags);
+ spin_unlock_irqrestore(&led_lock, flags);
return ret;
}
@@ -1091,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);
}
/**
@@ -1104,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);
}
/*
@@ -1130,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,
@@ -2035,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 */
@@ -2134,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);