diff options
Diffstat (limited to 'drivers/tty/hvc/hvc_console.c')
| -rw-r--r-- | drivers/tty/hvc/hvc_console.c | 19 | 
1 files changed, 15 insertions, 4 deletions
diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c index 9eba119bcdd..4fcec1d793a 100644 --- a/drivers/tty/hvc/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c @@ -31,6 +31,7 @@  #include <linux/list.h>  #include <linux/module.h>  #include <linux/major.h> +#include <linux/atomic.h>  #include <linux/sysrq.h>  #include <linux/tty.h>  #include <linux/tty_flip.h> @@ -70,6 +71,9 @@ static struct task_struct *hvc_task;  /* Picks up late kicks after list walk but before schedule() */  static int hvc_kicked; +/* hvc_init is triggered from hvc_alloc, i.e. only when actually used */ +static atomic_t hvc_needs_init __read_mostly = ATOMIC_INIT(-1); +  static int hvc_init(void);  #ifdef CONFIG_MAGIC_SYSRQ @@ -186,7 +190,7 @@ static struct tty_driver *hvc_console_device(struct console *c, int *index)  	return hvc_driver;  } -static int __init hvc_console_setup(struct console *co, char *options) +static int hvc_console_setup(struct console *co, char *options)  {	  	if (co->index < 0 || co->index >= MAX_NR_HVC_CONSOLES)  		return -ENODEV; @@ -756,10 +760,17 @@ static int khvcd(void *unused)  			if (poll_mask == 0)  				schedule();  			else { +				unsigned long j_timeout; +  				if (timeout < MAX_TIMEOUT)  					timeout += (timeout >> 6) + 1; -				msleep_interruptible(timeout); +				/* +				 * We don't use msleep_interruptible otherwise +				 * "kick" will fail to wake us up +				 */ +				j_timeout = msecs_to_jiffies(timeout) + 1; +				schedule_timeout_interruptible(j_timeout);  			}  		}  		__set_current_state(TASK_RUNNING); @@ -788,7 +799,7 @@ static int hvc_tiocmset(struct tty_struct *tty,  }  #ifdef CONFIG_CONSOLE_POLL -int hvc_poll_init(struct tty_driver *driver, int line, char *options) +static int hvc_poll_init(struct tty_driver *driver, int line, char *options)  {  	return 0;  } @@ -851,7 +862,7 @@ struct hvc_struct *hvc_alloc(uint32_t vtermno, int data,  	int i;  	/* We wait until a driver actually comes along */ -	if (!hvc_driver) { +	if (atomic_inc_not_zero(&hvc_needs_init)) {  		int err = hvc_init();  		if (err)  			return ERR_PTR(err);  | 
