summaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-10-14 22:41:27 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2012-10-14 22:41:27 -0700
commitc362495586e8a3a6487a318fcd82eaf15ffe2142 (patch)
tree86f7b195d36ba198f24f86be327f21a8d24ec248 /drivers/tty
parentb70936d9ffbf0f45f4fa13a03122f015f13ecdb0 (diff)
parentddffeb8c4d0331609ef2581d84de4d763607bd37 (diff)
Merge 3.7-rc1 into tty-linus
This syncs up the tty-linus branch to the latest in Linus's tree to get all of the UAPI stuff needed for the next set of patches to merge. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/hvc/hvc_console.c33
-rw-r--r--drivers/tty/hvc/hvc_vio.c123
-rw-r--r--drivers/tty/hvc/hvc_xen.c5
-rw-r--r--drivers/tty/serial/kgdboc.c3
-rw-r--r--drivers/tty/vt/vt.c13
5 files changed, 115 insertions, 62 deletions
diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c
index 4a652999380..a5dec1ca1b8 100644
--- a/drivers/tty/hvc/hvc_console.c
+++ b/drivers/tty/hvc/hvc_console.c
@@ -245,6 +245,20 @@ static void hvc_port_destruct(struct tty_port *port)
kfree(hp);
}
+static void hvc_check_console(int index)
+{
+ /* Already enabled, bail out */
+ if (hvc_console.flags & CON_ENABLED)
+ return;
+
+ /* If this index is what the user requested, then register
+ * now (setup won't fail at this point). It's ok to just
+ * call register again if previously .setup failed.
+ */
+ if (index == hvc_console.index)
+ register_console(&hvc_console);
+}
+
/*
* hvc_instantiate() is an early console discovery method which locates
* consoles * prior to the vio subsystem discovering them. Hotplugged
@@ -275,12 +289,8 @@ int hvc_instantiate(uint32_t vtermno, int index, const struct hv_ops *ops)
if (last_hvc < index)
last_hvc = index;
- /* if this index is what the user requested, then register
- * now (setup won't fail at this point). It's ok to just
- * call register again if previously .setup failed.
- */
- if (index == hvc_console.index)
- register_console(&hvc_console);
+ /* check if we need to re-register the kernel console */
+ hvc_check_console(index);
return 0;
}
@@ -877,10 +887,15 @@ struct hvc_struct *hvc_alloc(uint32_t vtermno, int data,
i = ++last_hvc;
hp->index = i;
+ cons_ops[i] = ops;
+ vtermnos[i] = vtermno;
list_add_tail(&(hp->next), &hvc_structs);
spin_unlock(&hvc_structs_lock);
+ /* check if we need to re-register the kernel console */
+ hvc_check_console(i);
+
return hp;
}
EXPORT_SYMBOL_GPL(hvc_alloc);
@@ -893,8 +908,12 @@ int hvc_remove(struct hvc_struct *hp)
tty = tty_port_tty_get(&hp->port);
spin_lock_irqsave(&hp->lock, flags);
- if (hp->index < MAX_NR_HVC_CONSOLES)
+ if (hp->index < MAX_NR_HVC_CONSOLES) {
+ console_lock();
vtermnos[hp->index] = -1;
+ cons_ops[hp->index] = NULL;
+ console_unlock();
+ }
/* Don't whack hp->irq because tty_hangup() will need to free the irq. */
diff --git a/drivers/tty/hvc/hvc_vio.c b/drivers/tty/hvc/hvc_vio.c
index ee307799271..070c0ee6864 100644
--- a/drivers/tty/hvc/hvc_vio.c
+++ b/drivers/tty/hvc/hvc_vio.c
@@ -230,6 +230,69 @@ static const struct hv_ops hvterm_hvsi_ops = {
.tiocmset = hvterm_hvsi_tiocmset,
};
+static void udbg_hvc_putc(char c)
+{
+ int count = -1;
+
+ if (!hvterm_privs[0])
+ return;
+
+ if (c == '\n')
+ udbg_hvc_putc('\r');
+
+ do {
+ switch(hvterm_privs[0]->proto) {
+ case HV_PROTOCOL_RAW:
+ count = hvterm_raw_put_chars(0, &c, 1);
+ break;
+ case HV_PROTOCOL_HVSI:
+ count = hvterm_hvsi_put_chars(0, &c, 1);
+ break;
+ }
+ } while(count == 0);
+}
+
+static int udbg_hvc_getc_poll(void)
+{
+ int rc = 0;
+ char c;
+
+ if (!hvterm_privs[0])
+ return -1;
+
+ switch(hvterm_privs[0]->proto) {
+ case HV_PROTOCOL_RAW:
+ rc = hvterm_raw_get_chars(0, &c, 1);
+ break;
+ case HV_PROTOCOL_HVSI:
+ rc = hvterm_hvsi_get_chars(0, &c, 1);
+ break;
+ }
+ if (!rc)
+ return -1;
+ return c;
+}
+
+static int udbg_hvc_getc(void)
+{
+ int ch;
+
+ if (!hvterm_privs[0])
+ return -1;
+
+ for (;;) {
+ ch = udbg_hvc_getc_poll();
+ if (ch == -1) {
+ /* This shouldn't be needed...but... */
+ volatile unsigned long delay;
+ for (delay=0; delay < 2000000; delay++)
+ ;
+ } else {
+ return ch;
+ }
+ }
+}
+
static int __devinit hvc_vio_probe(struct vio_dev *vdev,
const struct vio_device_id *id)
{
@@ -289,6 +352,13 @@ static int __devinit hvc_vio_probe(struct vio_dev *vdev,
return PTR_ERR(hp);
dev_set_drvdata(&vdev->dev, hp);
+ /* register udbg if it's not there already for console 0 */
+ if (hp->index == 0 && !udbg_putc) {
+ udbg_putc = udbg_hvc_putc;
+ udbg_getc = udbg_hvc_getc;
+ udbg_getc_poll = udbg_hvc_getc_poll;
+ }
+
return 0;
}
@@ -331,59 +401,6 @@ static void __exit hvc_vio_exit(void)
}
module_exit(hvc_vio_exit);
-static void udbg_hvc_putc(char c)
-{
- int count = -1;
-
- if (c == '\n')
- udbg_hvc_putc('\r');
-
- do {
- switch(hvterm_priv0.proto) {
- case HV_PROTOCOL_RAW:
- count = hvterm_raw_put_chars(0, &c, 1);
- break;
- case HV_PROTOCOL_HVSI:
- count = hvterm_hvsi_put_chars(0, &c, 1);
- break;
- }
- } while(count == 0);
-}
-
-static int udbg_hvc_getc_poll(void)
-{
- int rc = 0;
- char c;
-
- switch(hvterm_priv0.proto) {
- case HV_PROTOCOL_RAW:
- rc = hvterm_raw_get_chars(0, &c, 1);
- break;
- case HV_PROTOCOL_HVSI:
- rc = hvterm_hvsi_get_chars(0, &c, 1);
- break;
- }
- if (!rc)
- return -1;
- return c;
-}
-
-static int udbg_hvc_getc(void)
-{
- int ch;
- for (;;) {
- ch = udbg_hvc_getc_poll();
- if (ch == -1) {
- /* This shouldn't be needed...but... */
- volatile unsigned long delay;
- for (delay=0; delay < 2000000; delay++)
- ;
- } else {
- return ch;
- }
- }
-}
-
void __init hvc_vio_init_early(void)
{
struct device_node *stdout_node;
diff --git a/drivers/tty/hvc/hvc_xen.c b/drivers/tty/hvc/hvc_xen.c
index 2944ff88fdc..f4abfe238f9 100644
--- a/drivers/tty/hvc/hvc_xen.c
+++ b/drivers/tty/hvc/hvc_xen.c
@@ -478,7 +478,6 @@ static void xencons_backend_changed(struct xenbus_device *dev,
case XenbusStateInitialising:
case XenbusStateInitialised:
case XenbusStateUnknown:
- case XenbusStateClosed:
break;
case XenbusStateInitWait:
@@ -488,6 +487,10 @@ static void xencons_backend_changed(struct xenbus_device *dev,
xenbus_switch_state(dev, XenbusStateConnected);
break;
+ case XenbusStateClosed:
+ if (dev->state == XenbusStateClosed)
+ break;
+ /* Missed the backend's CLOSING state -- fallthrough */
case XenbusStateClosing:
xenbus_frontend_closed(dev);
break;
diff --git a/drivers/tty/serial/kgdboc.c b/drivers/tty/serial/kgdboc.c
index c0b334327d9..10020547c60 100644
--- a/drivers/tty/serial/kgdboc.c
+++ b/drivers/tty/serial/kgdboc.c
@@ -97,7 +97,8 @@ static void kgdboc_restore_input(void)
static int kgdboc_register_kbd(char **cptr)
{
- if (strncmp(*cptr, "kbd", 3) == 0) {
+ if (strncmp(*cptr, "kbd", 3) == 0 ||
+ strncmp(*cptr, "kdb", 3) == 0) {
if (kdb_poll_idx < KDB_POLL_FUNC_MAX) {
kdb_poll_funcs[kdb_poll_idx] = kdb_get_kbd_char;
kdb_poll_idx++;
diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 999ca63afde..f87d7e8964b 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -3442,6 +3442,19 @@ int con_debug_enter(struct vc_data *vc)
kdb_set(2, setargs);
}
}
+ if (vc->vc_cols < 999) {
+ int colcount;
+ char cols[4];
+ const char *setargs[3] = {
+ "set",
+ "COLUMNS",
+ cols,
+ };
+ if (kdbgetintenv(setargs[0], &colcount)) {
+ snprintf(cols, 4, "%i", vc->vc_cols);
+ kdb_set(2, setargs);
+ }
+ }
#endif /* CONFIG_KGDB_KDB */
return ret;
}