summaryrefslogtreecommitdiffstats
path: root/drivers/tty/tty_ldisc.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-07-04 05:04:16 +0200
committerLinus Torvalds <torvalds@linux-foundation.org>2017-07-04 05:04:16 +0200
commit9a715cd54347948e74f1a597da22884af287727d (patch)
tree0a824e6501e9a8dcb3fdd05749e13c149e7dfb9f /drivers/tty/tty_ldisc.c
parentMerge tag 'staging-4.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git... (diff)
parenttty: serial: lpuart: add a more accurate baud rate calculation method (diff)
downloadlinux-9a715cd54347948e74f1a597da22884af287727d.tar.xz
linux-9a715cd54347948e74f1a597da22884af287727d.zip
Merge tag 'tty-4.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull tty/serial updates from Greg KH: "Here is the large tty/serial patchset for 4.13-rc1. A lot of tty and serial driver updates are in here, along with some fixups for some __get/put_user usages that were reported. Nothing huge, just lots of development by a number of different developers, full details in the shortlog. All of these have been in linux-next for a while" * tag 'tty-4.13-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (71 commits) tty: serial: lpuart: add a more accurate baud rate calculation method tty: serial: lpuart: add earlycon support for imx7ulp tty: serial: lpuart: add imx7ulp support dt-bindings: serial: fsl-lpuart: add i.MX7ULP support tty: serial: lpuart: add little endian 32 bit register support tty: serial: lpuart: refactor lpuart32_{read|write} prototype tty: serial: lpuart: introduce lpuart_soc_data to represent SoC property serial: imx-serial - move DMA buffer configuration to DT serial: imx: Enable RTSD only when needed serial: imx: Remove unused members from imx_port struct serial: 8250: 8250_omap: Fix race b/w dma completion and RX timeout serial: 8250: Fix THRE flag usage for CAP_MINI tty/serial: meson_uart: update to stable bindings dt-bindings: serial: Add bindings for the Amlogic Meson UARTs serial: Delete dead code for CIR serial ports serial: sirf: make of_device_ids const serial/mpsc: switch to dma_alloc_attrs tty: serial: Add Actions Semi Owl UART earlycon dt-bindings: serial: Document Actions Semi Owl UARTs tty/serial: atmel: make the driver DT only ...
Diffstat (limited to 'drivers/tty/tty_ldisc.c')
-rw-r--r--drivers/tty/tty_ldisc.c44
1 files changed, 30 insertions, 14 deletions
diff --git a/drivers/tty/tty_ldisc.c b/drivers/tty/tty_ldisc.c
index f6ffe28b8a0d..2fe216b276e2 100644
--- a/drivers/tty/tty_ldisc.c
+++ b/drivers/tty/tty_ldisc.c
@@ -492,6 +492,29 @@ static void tty_ldisc_close(struct tty_struct *tty, struct tty_ldisc *ld)
}
/**
+ * tty_ldisc_failto - helper for ldisc failback
+ * @tty: tty to open the ldisc on
+ * @ld: ldisc we are trying to fail back to
+ *
+ * Helper to try and recover a tty when switching back to the old
+ * ldisc fails and we need something attached.
+ */
+
+static int tty_ldisc_failto(struct tty_struct *tty, int ld)
+{
+ struct tty_ldisc *disc = tty_ldisc_get(tty, ld);
+ int r;
+
+ if (IS_ERR(disc))
+ return PTR_ERR(disc);
+ tty->ldisc = disc;
+ tty_set_termios_ldisc(tty, ld);
+ if ((r = tty_ldisc_open(tty, disc)) < 0)
+ tty_ldisc_put(disc);
+ return r;
+}
+
+/**
* tty_ldisc_restore - helper for tty ldisc change
* @tty: tty to recover
* @old: previous ldisc
@@ -502,9 +525,6 @@ static void tty_ldisc_close(struct tty_struct *tty, struct tty_ldisc *ld)
static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old)
{
- struct tty_ldisc *new_ldisc;
- int r;
-
/* There is an outstanding reference here so this is safe */
old = tty_ldisc_get(tty, old->ops->num);
WARN_ON(IS_ERR(old));
@@ -512,17 +532,13 @@ static void tty_ldisc_restore(struct tty_struct *tty, struct tty_ldisc *old)
tty_set_termios_ldisc(tty, old->ops->num);
if (tty_ldisc_open(tty, old) < 0) {
tty_ldisc_put(old);
- /* This driver is always present */
- new_ldisc = tty_ldisc_get(tty, N_TTY);
- if (IS_ERR(new_ldisc))
- panic("n_tty: get");
- tty->ldisc = new_ldisc;
- tty_set_termios_ldisc(tty, N_TTY);
- r = tty_ldisc_open(tty, new_ldisc);
- if (r < 0)
- panic("Couldn't open N_TTY ldisc for "
- "%s --- error %d.",
- tty_name(tty), r);
+ /* The traditional behaviour is to fall back to N_TTY, we
+ want to avoid falling back to N_NULL unless we have no
+ choice to avoid the risk of breaking anything */
+ if (tty_ldisc_failto(tty, N_TTY) < 0 &&
+ tty_ldisc_failto(tty, N_NULL) < 0)
+ panic("Couldn't open N_NULL ldisc for %s.",
+ tty_name(tty));
}
}