summaryrefslogtreecommitdiff
path: root/drivers/tty
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/Kconfig11
-rw-r--r--drivers/tty/amiserial.c6
-rw-r--r--drivers/tty/mxser.c6
-rw-r--r--drivers/tty/n_gsm.c231
-rw-r--r--drivers/tty/n_tty.c43
-rw-r--r--drivers/tty/pty.c2
-rw-r--r--drivers/tty/serdev/core.c17
-rw-r--r--drivers/tty/serdev/serdev-ttyport.c16
-rw-r--r--drivers/tty/serial/8250/8250.h12
-rw-r--r--drivers/tty/serial/8250/8250_bcm7271.c18
-rw-r--r--drivers/tty/serial/8250/8250_core.c1
-rw-r--r--drivers/tty/serial/8250/8250_em.c113
-rw-r--r--drivers/tty/serial/8250/8250_port.c22
-rw-r--r--drivers/tty/serial/8250/8250_tegra.c1
-rw-r--r--drivers/tty/serial/Kconfig11
-rw-r--r--drivers/tty/serial/bcm63xx_uart.c38
-rw-r--r--drivers/tty/serial/cpm_uart/cpm_uart_core.c5
-rw-r--r--drivers/tty/serial/fsl_lpuart.c20
-rw-r--r--drivers/tty/serial/imx.c48
-rw-r--r--drivers/tty/serial/max310x.c17
-rw-r--r--drivers/tty/serial/meson_uart.c8
-rw-r--r--drivers/tty/serial/mxs-auart.c4
-rw-r--r--drivers/tty/serial/qcom_geni_serial.c11
-rw-r--r--drivers/tty/serial/sb1250-duart.c2
-rw-r--r--drivers/tty/serial/serial_core.c125
-rw-r--r--drivers/tty/serial/sh-sci.c125
-rw-r--r--drivers/tty/serial/sh-sci.h3
-rw-r--r--drivers/tty/serial/sprd_serial.c2
-rw-r--r--drivers/tty/serial/stm32-usart.c6
-rw-r--r--drivers/tty/serial/stm32-usart.h1
-rw-r--r--drivers/tty/serial/sunzilog.c4
-rw-r--r--drivers/tty/serial/ucc_uart.c7
-rw-r--r--drivers/tty/synclink_gt.c24
-rw-r--r--drivers/tty/tty.h2
-rw-r--r--drivers/tty/tty_io.c48
-rw-r--r--drivers/tty/tty_ioctl.c54
-rw-r--r--drivers/tty/tty_ldisc.c3
-rw-r--r--drivers/tty/vt/vc_screen.c2
-rw-r--r--drivers/tty/vt/vt.c209
39 files changed, 852 insertions, 426 deletions
diff --git a/drivers/tty/Kconfig b/drivers/tty/Kconfig
index d35fc068da74..341abaed4ce2 100644
--- a/drivers/tty/Kconfig
+++ b/drivers/tty/Kconfig
@@ -160,7 +160,7 @@ config LEGACY_TIOCSTI
a dangerous legacy operation, and can be disabled on most
systems.
- Say 'Y here only if you have confirmed that your system's
+ Say Y here only if you have confirmed that your system's
userspace depends on this functionality to continue operating
normally.
@@ -301,6 +301,15 @@ config GOLDFISH_TTY_EARLY_CONSOLE
default y if GOLDFISH_TTY=y
select SERIAL_EARLYCON
+config IPWIRELESS
+ tristate "IPWireless 3G UMTS PCMCIA card support"
+ depends on PCMCIA && NETDEVICES
+ select PPP
+ help
+ This is a driver for 3G UMTS PCMCIA card from IPWireless company. In
+ some countries (for example Czech Republic, T-Mobile ISP) this card
+ is shipped for service called UMTS 4G.
+
config N_GSM
tristate "GSM MUX line discipline support (EXPERIMENTAL)"
depends on NET
diff --git a/drivers/tty/amiserial.c b/drivers/tty/amiserial.c
index d7515d61659e..c06ad0a0744b 100644
--- a/drivers/tty/amiserial.c
+++ b/drivers/tty/amiserial.c
@@ -347,7 +347,7 @@ static void check_modem_status(struct serial_state *info)
#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
printk("CTS tx start...");
#endif
- port->tty->hw_stopped = 0;
+ port->tty->hw_stopped = false;
info->IER |= UART_IER_THRI;
amiga_custom.intena = IF_SETCLR | IF_TBE;
mb();
@@ -362,7 +362,7 @@ static void check_modem_status(struct serial_state *info)
#if (defined(SERIAL_DEBUG_INTR) || defined(SERIAL_DEBUG_FLOW))
printk("CTS tx stop...");
#endif
- port->tty->hw_stopped = 1;
+ port->tty->hw_stopped = true;
info->IER &= ~UART_IER_THRI;
/* disable Tx interrupt and remove any pending interrupts */
amiga_custom.intena = IF_TBE;
@@ -1197,7 +1197,7 @@ static void rs_set_termios(struct tty_struct *tty, const struct ktermios *old_te
/* Handle turning off CRTSCTS */
if ((old_termios->c_cflag & CRTSCTS) && !C_CRTSCTS(tty)) {
- tty->hw_stopped = 0;
+ tty->hw_stopped = false;
rs_start(tty);
}
diff --git a/drivers/tty/mxser.c b/drivers/tty/mxser.c
index ef3116e87975..10855e66fda1 100644
--- a/drivers/tty/mxser.c
+++ b/drivers/tty/mxser.c
@@ -553,7 +553,7 @@ static void mxser_handle_cts(struct tty_struct *tty, struct mxser_port *info,
if (tty->hw_stopped) {
if (cts) {
- tty->hw_stopped = 0;
+ tty->hw_stopped = false;
if (!mxser_16550A_or_MUST(info))
__mxser_start_tx(info);
@@ -563,7 +563,7 @@ static void mxser_handle_cts(struct tty_struct *tty, struct mxser_port *info,
} else if (cts)
return;
- tty->hw_stopped = 1;
+ tty->hw_stopped = true;
if (!mxser_16550A_or_MUST(info))
__mxser_stop_tx(info);
}
@@ -1361,7 +1361,7 @@ static void mxser_set_termios(struct tty_struct *tty,
spin_unlock_irqrestore(&info->slock, flags);
if ((old_termios->c_cflag & CRTSCTS) && !C_CRTSCTS(tty)) {
- tty->hw_stopped = 0;
+ tty->hw_stopped = false;
mxser_start(tty);
}
diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c
index 7aa05ebed8e1..b411a26cc092 100644
--- a/drivers/tty/n_gsm.c
+++ b/drivers/tty/n_gsm.c
@@ -42,6 +42,7 @@
#include <linux/ctype.h>
#include <linux/mm.h>
#include <linux/math.h>
+#include <linux/nospec.h>
#include <linux/string.h>
#include <linux/slab.h>
#include <linux/poll.h>
@@ -128,6 +129,7 @@ struct gsm_msg {
enum gsm_dlci_state {
DLCI_CLOSED,
+ DLCI_WAITING_CONFIG, /* Waiting for DLCI configuration from user */
DLCI_CONFIGURE, /* Sending PN (for adaption > 1) */
DLCI_OPENING, /* Sending SABM not seen UA */
DLCI_OPEN, /* SABM/UA complete */
@@ -330,6 +332,7 @@ struct gsm_mux {
unsigned int t3; /* Power wake-up timer in seconds. */
int n2; /* Retry count */
u8 k; /* Window size */
+ bool wait_config; /* Wait for configuration by ioctl before DLCI open */
u32 keep_alive; /* Control channel keep-alive in 10ms */
/* Statistics (not currently exposed) */
@@ -451,6 +454,7 @@ static int gsm_modem_update(struct gsm_dlci *dlci, u8 brk);
static struct gsm_msg *gsm_data_alloc(struct gsm_mux *gsm, u8 addr, int len,
u8 ctrl);
static int gsm_send_packet(struct gsm_mux *gsm, struct gsm_msg *msg);
+static struct gsm_dlci *gsm_dlci_alloc(struct gsm_mux *gsm, int addr);
static void gsmld_write_trigger(struct gsm_mux *gsm);
static void gsmld_write_task(struct work_struct *work);
@@ -2280,6 +2284,7 @@ static void gsm_dlci_begin_open(struct gsm_dlci *dlci)
switch (dlci->state) {
case DLCI_CLOSED:
+ case DLCI_WAITING_CONFIG:
case DLCI_CLOSING:
dlci->retries = gsm->n2;
if (!need_pn) {
@@ -2311,6 +2316,7 @@ static void gsm_dlci_set_opening(struct gsm_dlci *dlci)
{
switch (dlci->state) {
case DLCI_CLOSED:
+ case DLCI_WAITING_CONFIG:
case DLCI_CLOSING:
dlci->state = DLCI_OPENING;
break;
@@ -2320,6 +2326,24 @@ static void gsm_dlci_set_opening(struct gsm_dlci *dlci)
}
/**
+ * gsm_dlci_set_wait_config - wait for channel configuration
+ * @dlci: DLCI to configure
+ *
+ * Wait for a DLCI configuration from the application.
+ */
+static void gsm_dlci_set_wait_config(struct gsm_dlci *dlci)
+{
+ switch (dlci->state) {
+ case DLCI_CLOSED:
+ case DLCI_CLOSING:
+ dlci->state = DLCI_WAITING_CONFIG;
+ break;
+ default:
+ break;
+ }
+}
+
+/**
* gsm_dlci_begin_close - start channel open procedure
* @dlci: DLCI to open
*
@@ -2453,6 +2477,128 @@ static void gsm_kick_timer(struct timer_list *t)
pr_info("%s TX queue stalled\n", __func__);
}
+/**
+ * gsm_dlci_copy_config_values - copy DLCI configuration
+ * @dlci: source DLCI
+ * @dc: configuration structure to fill
+ */
+static void gsm_dlci_copy_config_values(struct gsm_dlci *dlci, struct gsm_dlci_config *dc)
+{
+ memset(dc, 0, sizeof(*dc));
+ dc->channel = (u32)dlci->addr;
+ dc->adaption = (u32)dlci->adaption;
+ dc->mtu = (u32)dlci->mtu;
+ dc->priority = (u32)dlci->prio;
+ if (dlci->ftype == UIH)
+ dc->i = 1;
+ else
+ dc->i = 2;
+ dc->k = (u32)dlci->k;
+}
+
+/**
+ * gsm_dlci_config - configure DLCI from configuration
+ * @dlci: DLCI to configure
+ * @dc: DLCI configuration
+ * @open: open DLCI after configuration?
+ */
+static int gsm_dlci_config(struct gsm_dlci *dlci, struct gsm_dlci_config *dc, int open)
+{
+ struct gsm_mux *gsm;
+ bool need_restart = false;
+ bool need_open = false;
+ unsigned int i;
+
+ /*
+ * Check that userspace doesn't put stuff in here to prevent breakages
+ * in the future.
+ */
+ for (i = 0; i < ARRAY_SIZE(dc->reserved); i++)
+ if (dc->reserved[i])
+ return -EINVAL;
+
+ if (!dlci)
+ return -EINVAL;
+ gsm = dlci->gsm;
+
+ /* Stuff we don't support yet - I frame transport */
+ if (dc->adaption != 1 && dc->adaption != 2)
+ return -EOPNOTSUPP;
+ if (dc->mtu > MAX_MTU || dc->mtu < MIN_MTU || dc->mtu > gsm->mru)
+ return -EINVAL;
+ if (dc->priority >= 64)
+ return -EINVAL;
+ if (dc->i == 0 || dc->i > 2) /* UIH and UI only */
+ return -EINVAL;
+ if (dc->k > 7)
+ return -EINVAL;
+
+ /*
+ * See what is needed for reconfiguration
+ */
+ /* Framing fields */
+ if (dc->adaption != dlci->adaption)
+ need_restart = true;
+ if (dc->mtu != dlci->mtu)
+ need_restart = true;
+ if (dc->i != dlci->ftype)
+ need_restart = true;
+ /* Requires care */
+ if (dc->priority != dlci->prio)
+ need_restart = true;
+
+ if ((open && gsm->wait_config) || need_restart)
+ need_open = true;
+ if (dlci->state == DLCI_WAITING_CONFIG) {
+ need_restart = false;
+ need_open = true;
+ }
+
+ /*
+ * Close down what is needed, restart and initiate the new
+ * configuration.
+ */
+ if (need_restart) {
+ gsm_dlci_begin_close(dlci);
+ wait_event_interruptible(gsm->event, dlci->state == DLCI_CLOSED);
+ if (signal_pending(current))
+ return -EINTR;
+ }
+ /*
+ * Setup the new configuration values
+ */
+ dlci->adaption = (int)dc->adaption;
+
+ if (dc->mtu)
+ dlci->mtu = (unsigned int)dc->mtu;
+ else
+ dlci->mtu = gsm->mtu;
+
+ if (dc->priority)
+ dlci->prio = (u8)dc->priority;
+ else
+ dlci->prio = roundup(dlci->addr + 1, 8) - 1;
+
+ if (dc->i == 1)
+ dlci->ftype = UIH;
+ else if (dc->i == 2)
+ dlci->ftype = UI;
+
+ if (dc->k)
+ dlci->k = (u8)dc->k;
+ else
+ dlci->k = gsm->k;
+
+ if (need_open) {
+ if (gsm->initiator)
+ gsm_dlci_begin_open(dlci);
+ else
+ gsm_dlci_set_opening(dlci);
+ }
+
+ return 0;
+}
+
/*
* Allocate/Free DLCI channels
*/
@@ -3078,6 +3224,7 @@ static struct gsm_mux *gsm_alloc_mux(void)
gsm->mru = 64; /* Default to encoding 1 so these should be 64 */
gsm->mtu = 64;
gsm->dead = true; /* Avoid early tty opens */
+ gsm->wait_config = false; /* Disabled */
gsm->keep_alive = 0; /* Disabled */
/* Store the instance to the mux array or abort if no space is
@@ -3130,8 +3277,8 @@ static int gsm_config(struct gsm_mux *gsm, struct gsm_config *c)
int need_close = 0;
int need_restart = 0;
- /* Stuff we don't support yet - UI or I frame transport, windowing */
- if ((c->adaption != 1 && c->adaption != 2) || c->k)
+ /* Stuff we don't support yet - UI or I frame transport */
+ if (c->adaption != 1 && c->adaption != 2)
return -EOPNOTSUPP;
/* Check the MRU/MTU range looks sane */
if (c->mru < MIN_MTU || c->mtu < MIN_MTU)
@@ -3218,6 +3365,7 @@ static void gsm_copy_config_ext_values(struct gsm_mux *gsm,
struct gsm_config_ext *ce)
{
memset(ce, 0, sizeof(*ce));
+ ce->wait_config = gsm->wait_config ? 1 : 0;
ce->keep_alive = gsm->keep_alive;
}
@@ -3233,7 +3381,12 @@ static int gsm_config_ext(struct gsm_mux *gsm, struct gsm_config_ext *ce)
if (ce->reserved[i])
return -EINVAL;
+ /*
+ * Setup the new configuration values
+ */
+ gsm->wait_config = ce->wait_config ? true : false;
gsm->keep_alive = ce->keep_alive;
+
return 0;
}
@@ -3433,9 +3586,16 @@ static int gsmld_open(struct tty_struct *tty)
tty->receive_room = 65536;
/* Attach the initial passive connection */
- gsm->encoding = GSM_ADV_OPT;
gsmld_attach_gsm(tty, gsm);
+ /* The mux will not be activated yet, we wait for correct
+ * configuration first.
+ */
+ if (gsm->encoding == GSM_BASIC_OPT)
+ gsm->receive = gsm0_receive;
+ else
+ gsm->receive = gsm1_receive;
+
return 0;
}
@@ -3556,8 +3716,10 @@ static int gsmld_ioctl(struct tty_struct *tty, unsigned int cmd,
{
struct gsm_config c;
struct gsm_config_ext ce;
+ struct gsm_dlci_config dc;
struct gsm_mux *gsm = tty->disc_data;
- unsigned int base;
+ unsigned int base, addr;
+ struct gsm_dlci *dlci;
switch (cmd) {
case GSMIOC_GETCONF:
@@ -3581,6 +3743,35 @@ static int gsmld_ioctl(struct tty_struct *tty, unsigned int cmd,
if (copy_from_user(&ce, (void __user *)arg, sizeof(ce)))
return -EFAULT;
return gsm_config_ext(gsm, &ce);
+ case GSMIOC_GETCONF_DLCI:
+ if (copy_from_user(&dc, (void __user *)arg, sizeof(dc)))
+ return -EFAULT;
+ if (dc.channel == 0 || dc.channel >= NUM_DLCI)
+ return -EINVAL;
+ addr = array_index_nospec(dc.channel, NUM_DLCI);
+ dlci = gsm->dlci[addr];
+ if (!dlci) {
+ dlci = gsm_dlci_alloc(gsm, addr);
+ if (!dlci)
+ return -ENOMEM;
+ }
+ gsm_dlci_copy_config_values(dlci, &dc);
+ if (copy_to_user((void __user *)arg, &dc, sizeof(dc)))
+ return -EFAULT;
+ return 0;
+ case GSMIOC_SETCONF_DLCI:
+ if (copy_from_user(&dc, (void __user *)arg, sizeof(dc)))
+ return -EFAULT;
+ if (dc.channel == 0 || dc.channel >= NUM_DLCI)
+ return -EINVAL;
+ addr = array_index_nospec(dc.channel, NUM_DLCI);
+ dlci = gsm->dlci[addr];
+ if (!dlci) {
+ dlci = gsm_dlci_alloc(gsm, addr);
+ if (!dlci)
+ return -ENOMEM;
+ }
+ return gsm_dlci_config(dlci, &dc, 0);
default:
return n_tty_ioctl_helper(tty, cmd, arg);
}
@@ -4008,7 +4199,6 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp)
{
struct gsm_dlci *dlci = tty->driver_data;
struct tty_port *port = &dlci->port;
- struct gsm_mux *gsm = dlci->gsm;
port->count++;
tty_port_tty_set(port, tty);
@@ -4018,10 +4208,15 @@ static int gsmtty_open(struct tty_struct *tty, struct file *filp)
a DM straight back. This is ok as that will have caused a hangup */
tty_port_set_initialized(port, true);
/* Start sending off SABM messages */
- if (gsm->initiator)
- gsm_dlci_begin_open(dlci);
- else
- gsm_dlci_set_opening(dlci);
+ if (!dlci->gsm->wait_config) {
+ /* Start sending off SABM messages */
+ if (dlci->gsm->initiator)
+ gsm_dlci_begin_open(dlci);
+ else
+ gsm_dlci_set_opening(dlci);
+ } else {
+ gsm_dlci_set_wait_config(dlci);
+ }
/* And wait for virtual carrier */
return tty_port_block_til_ready(port, tty, filp);
}
@@ -4142,6 +4337,7 @@ static int gsmtty_ioctl(struct tty_struct *tty,
{
struct gsm_dlci *dlci = tty->driver_data;
struct gsm_netconfig nc;
+ struct gsm_dlci_config dc;
int index;
if (dlci->state == DLCI_CLOSED)
@@ -4165,6 +4361,23 @@ static int gsmtty_ioctl(struct tty_struct *tty,
gsm_destroy_network(dlci);
mutex_unlock(&dlci->mutex);
return 0;
+ case GSMIOC_GETCONF_DLCI:
+ if (copy_from_user(&dc, (void __user *)arg, sizeof(dc)))
+ return -EFAULT;
+ if (dc.channel != dlci->addr)
+ return -EPERM;
+ gsm_dlci_copy_config_values(dlci, &dc);
+ if (copy_to_user((void __user *)arg, &dc, sizeof(dc)))
+ return -EFAULT;
+ return 0;
+ case GSMIOC_SETCONF_DLCI:
+ if (copy_from_user(&dc, (void __user *)arg, sizeof(dc)))
+ return -EFAULT;
+ if (dc.channel >= NUM_DLCI)
+ return -EINVAL;
+ if (dc.channel != 0 && dc.channel != dlci->addr)
+ return -EPERM;
+ return gsm_dlci_config(dlci, &dc, 1);
case TIOCMIWAIT:
return gsm_wait_modem_change(dlci, (u32)arg);
default:
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
index c8f56c9b1a1c..1c9e5d2ea7de 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -28,27 +28,26 @@
* EAGAIN
*/
-#include <linux/types.h>
-#include <linux/major.h>
+#include <linux/bitmap.h>
+#include <linux/bitops.h>
+#include <linux/ctype.h>
#include <linux/errno.h>
-#include <linux/signal.h>
+#include <linux/export.h>
#include <linux/fcntl.h>
+#include <linux/file.h>
+#include <linux/jiffies.h>
+#include <linux/math.h>
+#include <linux/poll.h>
+#include <linux/ratelimit.h>
#include <linux/sched.h>
-#include <linux/interrupt.h>
-#include <linux/tty.h>
-#include <linux/timer.h>
-#include <linux/ctype.h>
-#include <linux/mm.h>
-#include <linux/string.h>
+#include <linux/signal.h>
#include <linux/slab.h>
-#include <linux/poll.h>
-#include <linux/bitops.h>
-#include <linux/audit.h>
-#include <linux/file.h>
+#include <linux/string.h>
+#include <linux/tty.h>
+#include <linux/types.h>
#include <linux/uaccess.h>
-#include <linux/module.h>
-#include <linux/ratelimit.h>
#include <linux/vmalloc.h>
+
#include "tty.h"
/*
@@ -625,7 +624,7 @@ static size_t __process_echoes(struct tty_struct *tty)
c = echo_buf(ldata, tail);
if (c == ECHO_OP_START) {
unsigned char op;
- int no_space_left = 0;
+ bool space_left = true;
/*
* Since add_echo_byte() is called without holding
@@ -664,7 +663,7 @@ static size_t __process_echoes(struct tty_struct *tty)
num_bs = 8 - (num_chars & 7);
if (num_bs > space) {
- no_space_left = 1;
+ space_left = false;
break;
}
space -= num_bs;
@@ -690,7 +689,7 @@ static size_t __process_echoes(struct tty_struct *tty)
case ECHO_OP_START:
/* This is an escaped echo op start code */
if (!space) {
- no_space_left = 1;
+ space_left = false;
break;
}
tty_put_char(tty, ECHO_OP_START);
@@ -710,7 +709,7 @@ static size_t __process_echoes(struct tty_struct *tty)
*
*/
if (space < 2) {
- no_space_left = 1;
+ space_left = false;
break;
}
tty_put_char(tty, '^');
@@ -720,7 +719,7 @@ static size_t __process_echoes(struct tty_struct *tty)
tail += 2;
}
- if (no_space_left)
+ if (!space_left)
break;
} else {
if (O_OPOST(tty)) {
@@ -1177,7 +1176,7 @@ static void n_tty_receive_overrun(struct tty_struct *tty)
ldata->num_overrun++;
if (time_after(jiffies, ldata->overrun_time + HZ) ||
- time_after(ldata->overrun_time, jiffies)) {
+ time_after(ldata->overrun_time, jiffies)) {
tty_warn(tty, "%d input overrun(s)\n", ldata->num_overrun);
ldata->overrun_time = jiffies;
ldata->num_overrun = 0;
@@ -1691,7 +1690,7 @@ n_tty_receive_buf_common(struct tty_struct *tty, const unsigned char *cp,
room = N_TTY_BUF_SIZE - (ldata->read_head - tail);
if (I_PARMRK(tty))
- room = (room + 2) / 3;
+ room = DIV_ROUND_UP(room, 3);
room--;
if (room <= 0) {
overflow = ldata->icanon && ldata->canon_head == tail;
diff --git a/drivers/tty/pty.c b/drivers/tty/pty.c
index 07394fdaf522..2b1c8ab99dba 100644
--- a/drivers/tty/pty.c
+++ b/drivers/tty/pty.c
@@ -931,7 +931,7 @@ static void __init unix98_pty_init(void)
if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) ||
register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0)
panic("Couldn't register /dev/ptmx driver");
- device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx");
+ device_create(&tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx");
}
#else
diff --git a/drivers/tty/serdev/core.c b/drivers/tty/serdev/core.c
index 678014253b7b..e7d663901c07 100644
--- a/drivers/tty/serdev/core.c
+++ b/drivers/tty/serdev/core.c
@@ -366,7 +366,7 @@ int serdev_device_set_parity(struct serdev_device *serdev,
struct serdev_controller *ctrl = serdev->ctrl;
if (!ctrl || !ctrl->ops->set_parity)
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
return ctrl->ops->set_parity(ctrl, parity);
}
@@ -388,7 +388,7 @@ int serdev_device_get_tiocm(struct serdev_device *serdev)
struct serdev_controller *ctrl = serdev->ctrl;
if (!ctrl || !ctrl->ops->get_tiocm)
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
return ctrl->ops->get_tiocm(ctrl);
}
@@ -399,12 +399,23 @@ int serdev_device_set_tiocm(struct serdev_device *serdev, int set, int clear)
struct serdev_controller *ctrl = serdev->ctrl;
if (!ctrl || !ctrl->ops->set_tiocm)
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
return ctrl->ops->set_tiocm(ctrl, set, clear);
}
EXPORT_SYMBOL_GPL(serdev_device_set_tiocm);
+int serdev_device_break_ctl(struct serdev_device *serdev, int break_state)
+{
+ struct serdev_controller *ctrl = serdev->ctrl;
+
+ if (!ctrl || !ctrl->ops->break_ctl)
+ return -EOPNOTSUPP;
+
+ return ctrl->ops->break_ctl(ctrl, break_state);
+}
+EXPORT_SYMBOL_GPL(serdev_device_break_ctl);
+
static int serdev_drv_probe(struct device *dev)
{
const struct serdev_device_driver *sdrv = to_serdev_device_driver(dev->driver);
diff --git a/drivers/tty/serdev/serdev-ttyport.c b/drivers/tty/serdev/serdev-ttyport.c
index d367803e2044..8033ef19669c 100644
--- a/drivers/tty/serdev/serdev-ttyport.c
+++ b/drivers/tty/serdev/serdev-ttyport.c
@@ -231,7 +231,7 @@ static int ttyport_get_tiocm(struct serdev_controller *ctrl)
struct tty_struct *tty = serport->tty;
if (!tty->ops->tiocmget)
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
return tty->ops->tiocmget(tty);
}
@@ -242,11 +242,22 @@ static int ttyport_set_tiocm(struct serdev_controller *ctrl, unsigned int set, u
struct tty_struct *tty = serport->tty;
if (!tty->ops->tiocmset)
- return -ENOTSUPP;
+ return -EOPNOTSUPP;
return tty->ops->tiocmset(tty, set, clear);
}
+static int ttyport_break_ctl(struct serdev_controller *ctrl, unsigned int break_state)
+{
+ struct serport *serport = serdev_controller_get_drvdata(ctrl);
+ struct tty_struct *tty = serport->tty;
+
+ if (!tty->ops->break_ctl)
+ return -EOPNOTSUPP;
+
+ return tty->ops->break_ctl(tty, break_state);
+}
+
static const struct serdev_controller_ops ctrl_ops = {
.write_buf = ttyport_write_buf,
.write_flush = ttyport_write_flush,
@@ -259,6 +270,7 @@ static const struct serdev_controller_ops ctrl_ops = {
.wait_until_sent = ttyport_wait_until_sent,
.get_tiocm = ttyport_get_tiocm,
.set_tiocm = ttyport_set_tiocm,
+ .break_ctl = ttyport_break_ctl,
};
struct device *serdev_tty_port_register(struct tty_port *port,
diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h
index 287153d32536..1e8fe44a7099 100644
--- a/drivers/tty/serial/8250/8250.h
+++ b/drivers/tty/serial/8250/8250.h
@@ -365,6 +365,13 @@ static inline void serial8250_do_prepare_rx_dma(struct uart_8250_port *p)
if (dma->prepare_rx_dma)
dma->prepare_rx_dma(p);
}
+
+static inline bool serial8250_tx_dma_running(struct uart_8250_port *p)
+{
+ struct uart_8250_dma *dma = p->dma;
+
+ return dma && dma->tx_running;
+}
#else
static inline int serial8250_tx_dma(struct uart_8250_port *p)
{
@@ -380,6 +387,11 @@ static inline int serial8250_request_dma(struct uart_8250_port *p)
return -1;
}
static inline void serial8250_release_dma(struct uart_8250_port *p) { }
+
+static inline bool serial8250_tx_dma_running(struct uart_8250_port *p)
+{
+ return false;
+}
#endif
static inline int ns16550a_goto_highspeed(struct uart_8250_port *up)
diff --git a/drivers/tty/serial/8250/8250_bcm7271.c b/drivers/tty/serial/8250/8250_bcm7271.c
index ed5a94747692..f801b1f5b46c 100644
--- a/drivers/tty/serial/8250/8250_bcm7271.c
+++ b/drivers/tty/serial/8250/8250_bcm7271.c
@@ -1014,14 +1014,16 @@ static int brcmuart_probe(struct platform_device *pdev)
/* See if a Baud clock has been specified */
baud_mux_clk = of_clk_get_by_name(np, "sw_baud");
if (IS_ERR(baud_mux_clk)) {
- if (PTR_ERR(baud_mux_clk) == -EPROBE_DEFER)
- return -EPROBE_DEFER;
+ if (PTR_ERR(baud_mux_clk) == -EPROBE_DEFER) {
+ ret = -EPROBE_DEFER;
+ goto release_dma;
+ }
dev_dbg(dev, "BAUD MUX clock not specified\n");
} else {
dev_dbg(dev, "BAUD MUX clock found\n");
ret = clk_prepare_enable(baud_mux_clk);
if (ret)
- return ret;
+ goto release_dma;
priv->baud_mux_clk = baud_mux_clk;
init_real_clk_rates(dev, priv);
clk_rate = priv->default_mux_rate;
@@ -1029,7 +1031,8 @@ static int brcmuart_probe(struct platform_device *pdev)
if (clk_rate == 0) {
dev_err(dev, "clock-frequency or clk not defined\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto release_dma;
}
dev_dbg(dev, "DMA is %senabled\n", priv->dma_enabled ? "" : "not ");
@@ -1116,7 +1119,9 @@ err1:
serial8250_unregister_port(priv->line);
err:
brcmuart_free_bu