mirror of https://gitee.com/openkylin/linux.git
Merge branch 'tty-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
* 'tty-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: TTY: ldisc, wait for ldisc infinitely in hangup TTY: ldisc, move wait idle to caller TTY: ldisc, allow waiting for ldisc arbitrarily long Revert "tty/serial: Prevent drop of DCD on suspend for Tegra UARTs" RS485: fix inconsistencies in the meaning of some variables pch_uart: Fix DMA resource leak issue serial,mfd: Fix CMSPAR setup tty/serial: Prevent drop of DCD on suspend for Tegra UARTs pch_uart: Change company name OKI SEMICONDUCTOR to LAPIS Semiconductor pch_uart: Support new device LAPIS Semiconductor ML7831 IOH pch_uart: Fix hw-flow control issue tty: hvc_dcc: Fix duplicate character inputs jsm: Change maintainership
This commit is contained in:
commit
3b9abc7e48
|
@ -97,15 +97,23 @@
|
|||
|
||||
struct serial_rs485 rs485conf;
|
||||
|
||||
/* Set RS485 mode: */
|
||||
/* Enable RS485 mode: */
|
||||
rs485conf.flags |= SER_RS485_ENABLED;
|
||||
|
||||
/* Set logical level for RTS pin equal to 1 when sending: */
|
||||
rs485conf.flags |= SER_RS485_RTS_ON_SEND;
|
||||
/* or, set logical level for RTS pin equal to 0 when sending: */
|
||||
rs485conf.flags &= ~(SER_RS485_RTS_ON_SEND);
|
||||
|
||||
/* Set logical level for RTS pin equal to 1 after sending: */
|
||||
rs485conf.flags |= SER_RS485_RTS_AFTER_SEND;
|
||||
/* or, set logical level for RTS pin equal to 0 after sending: */
|
||||
rs485conf.flags &= ~(SER_RS485_RTS_AFTER_SEND);
|
||||
|
||||
/* Set rts delay before send, if needed: */
|
||||
rs485conf.flags |= SER_RS485_RTS_BEFORE_SEND;
|
||||
rs485conf.delay_rts_before_send = ...;
|
||||
|
||||
/* Set rts delay after send, if needed: */
|
||||
rs485conf.flags |= SER_RS485_RTS_AFTER_SEND;
|
||||
rs485conf.delay_rts_after_send = ...;
|
||||
|
||||
/* Set this flag if you want to receive data even whilst sending data */
|
||||
|
|
|
@ -3728,7 +3728,7 @@ F: fs/jbd2/
|
|||
F: include/linux/jbd2.h
|
||||
|
||||
JSM Neo PCI based serial card
|
||||
M: Breno Leitao <leitao@linux.vnet.ibm.com>
|
||||
M: Lucas Tavares <lucaskt@linux.vnet.ibm.com>
|
||||
L: linux-serial@vger.kernel.org
|
||||
S: Maintained
|
||||
F: drivers/tty/serial/jsm/
|
||||
|
|
|
@ -46,6 +46,7 @@ static inline char __dcc_getchar(void)
|
|||
|
||||
asm volatile("mrc p14, 0, %0, c0, c5, 0 @ read comms data reg"
|
||||
: "=r" (__c));
|
||||
isb();
|
||||
|
||||
return __c;
|
||||
}
|
||||
|
@ -55,6 +56,7 @@ static inline void __dcc_putchar(char c)
|
|||
asm volatile("mcr p14, 0, %0, c0, c5, 0 @ write a char"
|
||||
: /* no output register */
|
||||
: "r" (c));
|
||||
isb();
|
||||
}
|
||||
|
||||
static int hvc_dcc_put_chars(uint32_t vt, const char *buf, int count)
|
||||
|
|
|
@ -1560,7 +1560,7 @@ config SERIAL_IFX6X60
|
|||
Support for the IFX6x60 modem devices on Intel MID platforms.
|
||||
|
||||
config SERIAL_PCH_UART
|
||||
tristate "Intel EG20T PCH / OKI SEMICONDUCTOR IOH(ML7213/ML7223) UART"
|
||||
tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) UART"
|
||||
depends on PCI
|
||||
select SERIAL_CORE
|
||||
help
|
||||
|
@ -1568,12 +1568,12 @@ config SERIAL_PCH_UART
|
|||
which is an IOH(Input/Output Hub) for x86 embedded processor.
|
||||
Enabling PCH_DMA, this PCH UART works as DMA mode.
|
||||
|
||||
This driver also can be used for OKI SEMICONDUCTOR IOH(Input/
|
||||
Output Hub), ML7213 and ML7223.
|
||||
ML7213 IOH is for IVI(In-Vehicle Infotainment) use and ML7223 IOH is
|
||||
for MP(Media Phone) use.
|
||||
ML7213/ML7223 is companion chip for Intel Atom E6xx series.
|
||||
ML7213/ML7223 is completely compatible for Intel EG20T PCH.
|
||||
This driver also can be used for LAPIS Semiconductor IOH(Input/
|
||||
Output Hub), ML7213, ML7223 and ML7831.
|
||||
ML7213 IOH is for IVI(In-Vehicle Infotainment) use, ML7223 IOH is
|
||||
for MP(Media Phone) use and ML7831 IOH is for general purpose use.
|
||||
ML7213/ML7223/ML7831 is companion chip for Intel Atom E6xx series.
|
||||
ML7213/ML7223/ML7831 is completely compatible for Intel EG20T PCH.
|
||||
|
||||
config SERIAL_MSM_SMD
|
||||
bool "Enable tty device interface for some SMD ports"
|
||||
|
|
|
@ -228,7 +228,7 @@ void atmel_config_rs485(struct uart_port *port, struct serial_rs485 *rs485conf)
|
|||
if (rs485conf->flags & SER_RS485_ENABLED) {
|
||||
dev_dbg(port->dev, "Setting UART to RS485\n");
|
||||
atmel_port->tx_done_mask = ATMEL_US_TXEMPTY;
|
||||
if (rs485conf->flags & SER_RS485_RTS_AFTER_SEND)
|
||||
if ((rs485conf->delay_rts_after_send) > 0)
|
||||
UART_PUT_TTGR(port, rs485conf->delay_rts_after_send);
|
||||
mode |= ATMEL_US_USMODE_RS485;
|
||||
} else {
|
||||
|
@ -304,7 +304,7 @@ static void atmel_set_mctrl(struct uart_port *port, u_int mctrl)
|
|||
|
||||
if (atmel_port->rs485.flags & SER_RS485_ENABLED) {
|
||||
dev_dbg(port->dev, "Setting UART to RS485\n");
|
||||
if (atmel_port->rs485.flags & SER_RS485_RTS_AFTER_SEND)
|
||||
if ((atmel_port->rs485.delay_rts_after_send) > 0)
|
||||
UART_PUT_TTGR(port,
|
||||
atmel_port->rs485.delay_rts_after_send);
|
||||
mode |= ATMEL_US_USMODE_RS485;
|
||||
|
@ -1228,7 +1228,7 @@ static void atmel_set_termios(struct uart_port *port, struct ktermios *termios,
|
|||
|
||||
if (atmel_port->rs485.flags & SER_RS485_ENABLED) {
|
||||
dev_dbg(port->dev, "Setting UART to RS485\n");
|
||||
if (atmel_port->rs485.flags & SER_RS485_RTS_AFTER_SEND)
|
||||
if ((atmel_port->rs485.delay_rts_after_send) > 0)
|
||||
UART_PUT_TTGR(port,
|
||||
atmel_port->rs485.delay_rts_after_send);
|
||||
mode |= ATMEL_US_USMODE_RS485;
|
||||
|
@ -1447,16 +1447,6 @@ static void __devinit atmel_of_init_port(struct atmel_uart_port *atmel_port,
|
|||
rs485conf->delay_rts_after_send = rs485_delay[1];
|
||||
rs485conf->flags = 0;
|
||||
|
||||
if (rs485conf->delay_rts_before_send == 0 &&
|
||||
rs485conf->delay_rts_after_send == 0) {
|
||||
rs485conf->flags |= SER_RS485_RTS_ON_SEND;
|
||||
} else {
|
||||
if (rs485conf->delay_rts_before_send)
|
||||
rs485conf->flags |= SER_RS485_RTS_BEFORE_SEND;
|
||||
if (rs485conf->delay_rts_after_send)
|
||||
rs485conf->flags |= SER_RS485_RTS_AFTER_SEND;
|
||||
}
|
||||
|
||||
if (of_get_property(np, "rs485-rx-during-tx", NULL))
|
||||
rs485conf->flags |= SER_RS485_RX_DURING_TX;
|
||||
|
||||
|
|
|
@ -3234,9 +3234,8 @@ rs_write(struct tty_struct *tty,
|
|||
e100_disable_rx(info);
|
||||
e100_enable_rx_irq(info);
|
||||
#endif
|
||||
if ((info->rs485.flags & SER_RS485_RTS_BEFORE_SEND) &&
|
||||
(info->rs485.delay_rts_before_send > 0))
|
||||
msleep(info->rs485.delay_rts_before_send);
|
||||
if (info->rs485.delay_rts_before_send > 0)
|
||||
msleep(info->rs485.delay_rts_before_send);
|
||||
}
|
||||
#endif /* CONFIG_ETRAX_RS485 */
|
||||
|
||||
|
@ -3693,10 +3692,6 @@ rs_ioctl(struct tty_struct *tty,
|
|||
|
||||
rs485data.delay_rts_before_send = rs485ctrl.delay_rts_before_send;
|
||||
rs485data.flags = 0;
|
||||
if (rs485data.delay_rts_before_send != 0)
|
||||
rs485data.flags |= SER_RS485_RTS_BEFORE_SEND;
|
||||
else
|
||||
rs485data.flags &= ~(SER_RS485_RTS_BEFORE_SEND);
|
||||
|
||||
if (rs485ctrl.enabled)
|
||||
rs485data.flags |= SER_RS485_ENABLED;
|
||||
|
@ -4531,7 +4526,6 @@ static int __init rs_init(void)
|
|||
/* Set sane defaults */
|
||||
info->rs485.flags &= ~(SER_RS485_RTS_ON_SEND);
|
||||
info->rs485.flags |= SER_RS485_RTS_AFTER_SEND;
|
||||
info->rs485.flags &= ~(SER_RS485_RTS_BEFORE_SEND);
|
||||
info->rs485.delay_rts_before_send = 0;
|
||||
info->rs485.flags &= ~(SER_RS485_ENABLED);
|
||||
#endif
|
||||
|
|
|
@ -884,7 +884,6 @@ serial_hsu_set_termios(struct uart_port *port, struct ktermios *termios,
|
|||
{
|
||||
struct uart_hsu_port *up =
|
||||
container_of(port, struct uart_hsu_port, port);
|
||||
struct tty_struct *tty = port->state->port.tty;
|
||||
unsigned char cval, fcr = 0;
|
||||
unsigned long flags;
|
||||
unsigned int baud, quot;
|
||||
|
@ -907,8 +906,7 @@ serial_hsu_set_termios(struct uart_port *port, struct ktermios *termios,
|
|||
}
|
||||
|
||||
/* CMSPAR isn't supported by this driver */
|
||||
if (tty)
|
||||
tty->termios->c_cflag &= ~CMSPAR;
|
||||
termios->c_cflag &= ~CMSPAR;
|
||||
|
||||
if (termios->c_cflag & CSTOPB)
|
||||
cval |= UART_LCR_STOP;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
*Copyright (C) 2010 OKI SEMICONDUCTOR CO., LTD.
|
||||
*Copyright (C) 2011 LAPIS Semiconductor Co., Ltd.
|
||||
*
|
||||
*This program is free software; you can redistribute it and/or modify
|
||||
*it under the terms of the GNU General Public License as published by
|
||||
|
@ -46,8 +46,8 @@ enum {
|
|||
|
||||
/* Set the max number of UART port
|
||||
* Intel EG20T PCH: 4 port
|
||||
* OKI SEMICONDUCTOR ML7213 IOH: 3 port
|
||||
* OKI SEMICONDUCTOR ML7223 IOH: 2 port
|
||||
* LAPIS Semiconductor ML7213 IOH: 3 port
|
||||
* LAPIS Semiconductor ML7223 IOH: 2 port
|
||||
*/
|
||||
#define PCH_UART_NR 4
|
||||
|
||||
|
@ -258,6 +258,8 @@ enum pch_uart_num_t {
|
|||
pch_ml7213_uart2,
|
||||
pch_ml7223_uart0,
|
||||
pch_ml7223_uart1,
|
||||
pch_ml7831_uart0,
|
||||
pch_ml7831_uart1,
|
||||
};
|
||||
|
||||
static struct pch_uart_driver_data drv_dat[] = {
|
||||
|
@ -270,6 +272,8 @@ static struct pch_uart_driver_data drv_dat[] = {
|
|||
[pch_ml7213_uart2] = {PCH_UART_2LINE, 2},
|
||||
[pch_ml7223_uart0] = {PCH_UART_8LINE, 0},
|
||||
[pch_ml7223_uart1] = {PCH_UART_2LINE, 1},
|
||||
[pch_ml7831_uart0] = {PCH_UART_8LINE, 0},
|
||||
[pch_ml7831_uart1] = {PCH_UART_2LINE, 1},
|
||||
};
|
||||
|
||||
static unsigned int default_baud = 9600;
|
||||
|
@ -628,6 +632,7 @@ static void pch_request_dma(struct uart_port *port)
|
|||
dev_err(priv->port.dev, "%s:dma_request_channel FAILS(Rx)\n",
|
||||
__func__);
|
||||
dma_release_channel(priv->chan_tx);
|
||||
priv->chan_tx = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1215,8 +1220,7 @@ static void pch_uart_shutdown(struct uart_port *port)
|
|||
dev_err(priv->port.dev,
|
||||
"pch_uart_hal_set_fifo Failed(ret=%d)\n", ret);
|
||||
|
||||
if (priv->use_dma_flag)
|
||||
pch_free_dma(port);
|
||||
pch_free_dma(port);
|
||||
|
||||
free_irq(priv->port.irq, priv);
|
||||
}
|
||||
|
@ -1280,6 +1284,7 @@ static void pch_uart_set_termios(struct uart_port *port,
|
|||
if (rtn)
|
||||
goto out;
|
||||
|
||||
pch_uart_set_mctrl(&priv->port, priv->port.mctrl);
|
||||
/* Don't rewrite B0 */
|
||||
if (tty_termios_baud_rate(termios))
|
||||
tty_termios_encode_baud_rate(termios, baud, baud);
|
||||
|
@ -1552,6 +1557,10 @@ static DEFINE_PCI_DEVICE_TABLE(pch_uart_pci_id) = {
|
|||
.driver_data = pch_ml7223_uart0},
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x800D),
|
||||
.driver_data = pch_ml7223_uart1},
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8811),
|
||||
.driver_data = pch_ml7831_uart0},
|
||||
{PCI_DEVICE(PCI_VENDOR_ID_ROHM, 0x8812),
|
||||
.driver_data = pch_ml7831_uart1},
|
||||
{0,},
|
||||
};
|
||||
|
||||
|
|
|
@ -36,6 +36,7 @@
|
|||
|
||||
#include <linux/kmod.h>
|
||||
#include <linux/nsproxy.h>
|
||||
#include <linux/ratelimit.h>
|
||||
|
||||
/*
|
||||
* This guards the refcounted line discipline lists. The lock
|
||||
|
@ -547,15 +548,16 @@ static void tty_ldisc_flush_works(struct tty_struct *tty)
|
|||
/**
|
||||
* tty_ldisc_wait_idle - wait for the ldisc to become idle
|
||||
* @tty: tty to wait for
|
||||
* @timeout: for how long to wait at most
|
||||
*
|
||||
* Wait for the line discipline to become idle. The discipline must
|
||||
* have been halted for this to guarantee it remains idle.
|
||||
*/
|
||||
static int tty_ldisc_wait_idle(struct tty_struct *tty)
|
||||
static int tty_ldisc_wait_idle(struct tty_struct *tty, long timeout)
|
||||
{
|
||||
int ret;
|
||||
long ret;
|
||||
ret = wait_event_timeout(tty_ldisc_idle,
|
||||
atomic_read(&tty->ldisc->users) == 1, 5 * HZ);
|
||||
atomic_read(&tty->ldisc->users) == 1, timeout);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
return ret > 0 ? 0 : -EBUSY;
|
||||
|
@ -665,7 +667,7 @@ int tty_set_ldisc(struct tty_struct *tty, int ldisc)
|
|||
|
||||
tty_ldisc_flush_works(tty);
|
||||
|
||||
retval = tty_ldisc_wait_idle(tty);
|
||||
retval = tty_ldisc_wait_idle(tty, 5 * HZ);
|
||||
|
||||
tty_lock();
|
||||
mutex_lock(&tty->ldisc_mutex);
|
||||
|
@ -762,8 +764,6 @@ static int tty_ldisc_reinit(struct tty_struct *tty, int ldisc)
|
|||
if (IS_ERR(ld))
|
||||
return -1;
|
||||
|
||||
WARN_ON_ONCE(tty_ldisc_wait_idle(tty));
|
||||
|
||||
tty_ldisc_close(tty, tty->ldisc);
|
||||
tty_ldisc_put(tty->ldisc);
|
||||
tty->ldisc = NULL;
|
||||
|
@ -838,7 +838,7 @@ void tty_ldisc_hangup(struct tty_struct *tty)
|
|||
tty_unlock();
|
||||
cancel_work_sync(&tty->buf.work);
|
||||
mutex_unlock(&tty->ldisc_mutex);
|
||||
|
||||
retry:
|
||||
tty_lock();
|
||||
mutex_lock(&tty->ldisc_mutex);
|
||||
|
||||
|
@ -847,6 +847,22 @@ void tty_ldisc_hangup(struct tty_struct *tty)
|
|||
it means auditing a lot of other paths so this is
|
||||
a FIXME */
|
||||
if (tty->ldisc) { /* Not yet closed */
|
||||
if (atomic_read(&tty->ldisc->users) != 1) {
|
||||
char cur_n[TASK_COMM_LEN], tty_n[64];
|
||||
long timeout = 3 * HZ;
|
||||
tty_unlock();
|
||||
|
||||
while (tty_ldisc_wait_idle(tty, timeout) == -EBUSY) {
|
||||
timeout = MAX_SCHEDULE_TIMEOUT;
|
||||
printk_ratelimited(KERN_WARNING
|
||||
"%s: waiting (%s) for %s took too long, but we keep waiting...\n",
|
||||
__func__, get_task_comm(cur_n, current),
|
||||
tty_name(tty, tty_n));
|
||||
}
|
||||
mutex_unlock(&tty->ldisc_mutex);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
if (reset == 0) {
|
||||
|
||||
if (!tty_ldisc_reinit(tty, tty->termios->c_line))
|
||||
|
|
|
@ -207,13 +207,15 @@ struct serial_icounter_struct {
|
|||
|
||||
struct serial_rs485 {
|
||||
__u32 flags; /* RS485 feature flags */
|
||||
#define SER_RS485_ENABLED (1 << 0)
|
||||
#define SER_RS485_RTS_ON_SEND (1 << 1)
|
||||
#define SER_RS485_RTS_AFTER_SEND (1 << 2)
|
||||
#define SER_RS485_RTS_BEFORE_SEND (1 << 3)
|
||||
#define SER_RS485_ENABLED (1 << 0) /* If enabled */
|
||||
#define SER_RS485_RTS_ON_SEND (1 << 1) /* Logical level for
|
||||
RTS pin when
|
||||
sending */
|
||||
#define SER_RS485_RTS_AFTER_SEND (1 << 2) /* Logical level for
|
||||
RTS pin after sent*/
|
||||
#define SER_RS485_RX_DURING_TX (1 << 4)
|
||||
__u32 delay_rts_before_send; /* Milliseconds */
|
||||
__u32 delay_rts_after_send; /* Milliseconds */
|
||||
__u32 delay_rts_before_send; /* Delay before send (milliseconds) */
|
||||
__u32 delay_rts_after_send; /* Delay after send (milliseconds) */
|
||||
__u32 padding[5]; /* Memory is cheap, new structs
|
||||
are a royal PITA .. */
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue