diff options
author | Max Krummenacher <max.krummenacher@toradex.com> | 2020-09-27 13:50:08 +0200 |
---|---|---|
committer | Max Krummenacher <max.krummenacher@toradex.com> | 2020-09-27 13:50:08 +0200 |
commit | f1442a59da02a0b5ef648925f2f274a3e64999cc (patch) | |
tree | 7d03cfca9b9f426a7af9bdd4a6a927a6a90b6a4e /drivers/tty/hvc/hvc_console.c | |
parent | a54df82931ac98d6f01acc9107a38ce0258ff8f1 (diff) | |
parent | 38779362ed7ce5c24c9ac88c45afaf93116fc459 (diff) |
Merge tag 'v4.4.237' into toradex_vf_4.4
This is the 4.4.237 stable release
Signed-off-by: Max Krummenacher <max.krummenacher@toradex.com>
Diffstat (limited to 'drivers/tty/hvc/hvc_console.c')
-rw-r--r-- | drivers/tty/hvc/hvc_console.c | 39 |
1 files changed, 28 insertions, 11 deletions
diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c index e46d628998f5..81f23af8beca 100644 --- a/drivers/tty/hvc/hvc_console.c +++ b/drivers/tty/hvc/hvc_console.c @@ -89,6 +89,8 @@ static LIST_HEAD(hvc_structs); */ static DEFINE_SPINLOCK(hvc_structs_lock); +/* Mutex to serialize hvc_open */ +static DEFINE_MUTEX(hvc_open_mutex); /* * This value is used to assign a tty->index value to a hvc_struct based * upon order of exposure via hvc_probe(), when we can not match it to @@ -289,10 +291,6 @@ int hvc_instantiate(uint32_t vtermno, int index, const struct hv_ops *ops) vtermnos[index] = vtermno; cons_ops[index] = ops; - /* reserve all indices up to and including this index */ - if (last_hvc < index) - last_hvc = index; - /* check if we need to re-register the kernel console */ hvc_check_console(index); @@ -337,16 +335,24 @@ static int hvc_install(struct tty_driver *driver, struct tty_struct *tty) */ static int hvc_open(struct tty_struct *tty, struct file * filp) { - struct hvc_struct *hp = tty->driver_data; + struct hvc_struct *hp; unsigned long flags; int rc = 0; + mutex_lock(&hvc_open_mutex); + + hp = tty->driver_data; + if (!hp) { + rc = -EIO; + goto out; + } + spin_lock_irqsave(&hp->port.lock, flags); /* Check and then increment for fast path open. */ if (hp->port.count++ > 0) { spin_unlock_irqrestore(&hp->port.lock, flags); hvc_kick(); - return 0; + goto out; } /* else count == 0 */ spin_unlock_irqrestore(&hp->port.lock, flags); @@ -375,6 +381,8 @@ static int hvc_open(struct tty_struct *tty, struct file * filp) /* Force wakeup of the polling thread */ hvc_kick(); +out: + mutex_unlock(&hvc_open_mutex); return rc; } @@ -896,13 +904,22 @@ struct hvc_struct *hvc_alloc(uint32_t vtermno, int data, cons_ops[i] == hp->ops) break; - /* no matching slot, just use a counter */ - if (i >= MAX_NR_HVC_CONSOLES) - i = ++last_hvc; + if (i >= MAX_NR_HVC_CONSOLES) { + + /* find 'empty' slot for console */ + for (i = 0; i < MAX_NR_HVC_CONSOLES && vtermnos[i] != -1; i++) { + } + + /* no matching slot, just use a counter */ + if (i == MAX_NR_HVC_CONSOLES) + i = ++last_hvc + MAX_NR_HVC_CONSOLES; + } hp->index = i; - cons_ops[i] = ops; - vtermnos[i] = vtermno; + if (i < MAX_NR_HVC_CONSOLES) { + cons_ops[i] = ops; + vtermnos[i] = vtermno; + } list_add_tail(&(hp->next), &hvc_structs); spin_unlock(&hvc_structs_lock); |