mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-07-07 06:52:07 +00:00
TTY/Serial driver fixes for 3.11-rc4
Here are 4 tiny tty and serial driver fixes for 3.11-rc4. Nothing big, a refcount leak, a module alias fix, and two fixes to the mxs-auart serial driver. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> -----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.19 (GNU/Linux) iEYEABECAAYFAlH4ELoACgkQMUfUDdst+yktaACg1NxfFkjuz7A8uG7sST5pGJPb +K8AoKmTPl0hGXOWEdgXdCnCmL+B223g =u0GE -----END PGP SIGNATURE----- Merge tag 'tty-3.11-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty Pull tty/serial driver fixes from Greg KH: "Here are 4 tiny tty and serial driver fixes for 3.11-rc4. Nothing big, a refcount leak, a module alias fix, and two fixes to the mxs-auart serial driver" * tag 'tty-3.11-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: serial: arc_uart: Fix module alias tty_port: Fix refcounting leak in tty_port_tty_hangup() serial/mxs-auart: increase time to wait for transmitter to become idle serial/mxs-auart: fix race condition in interrupt handler
This commit is contained in:
commit
a93f66dc5f
3 changed files with 25 additions and 20 deletions
|
@ -773,6 +773,6 @@ module_init(arc_serial_init);
|
||||||
module_exit(arc_serial_exit);
|
module_exit(arc_serial_exit);
|
||||||
|
|
||||||
MODULE_LICENSE("GPL");
|
MODULE_LICENSE("GPL");
|
||||||
MODULE_ALIAS("plat-arcfpga/uart");
|
MODULE_ALIAS("platform:" DRIVER_NAME);
|
||||||
MODULE_AUTHOR("Vineet Gupta");
|
MODULE_AUTHOR("Vineet Gupta");
|
||||||
MODULE_DESCRIPTION("ARC(Synopsys) On-Chip(fpga) serial driver");
|
MODULE_DESCRIPTION("ARC(Synopsys) On-Chip(fpga) serial driver");
|
||||||
|
|
|
@ -678,11 +678,18 @@ static void mxs_auart_settermios(struct uart_port *u,
|
||||||
|
|
||||||
static irqreturn_t mxs_auart_irq_handle(int irq, void *context)
|
static irqreturn_t mxs_auart_irq_handle(int irq, void *context)
|
||||||
{
|
{
|
||||||
u32 istatus, istat;
|
u32 istat;
|
||||||
struct mxs_auart_port *s = context;
|
struct mxs_auart_port *s = context;
|
||||||
u32 stat = readl(s->port.membase + AUART_STAT);
|
u32 stat = readl(s->port.membase + AUART_STAT);
|
||||||
|
|
||||||
istatus = istat = readl(s->port.membase + AUART_INTR);
|
istat = readl(s->port.membase + AUART_INTR);
|
||||||
|
|
||||||
|
/* ack irq */
|
||||||
|
writel(istat & (AUART_INTR_RTIS
|
||||||
|
| AUART_INTR_TXIS
|
||||||
|
| AUART_INTR_RXIS
|
||||||
|
| AUART_INTR_CTSMIS),
|
||||||
|
s->port.membase + AUART_INTR_CLR);
|
||||||
|
|
||||||
if (istat & AUART_INTR_CTSMIS) {
|
if (istat & AUART_INTR_CTSMIS) {
|
||||||
uart_handle_cts_change(&s->port, stat & AUART_STAT_CTS);
|
uart_handle_cts_change(&s->port, stat & AUART_STAT_CTS);
|
||||||
|
@ -702,12 +709,6 @@ static irqreturn_t mxs_auart_irq_handle(int irq, void *context)
|
||||||
istat &= ~AUART_INTR_TXIS;
|
istat &= ~AUART_INTR_TXIS;
|
||||||
}
|
}
|
||||||
|
|
||||||
writel(istatus & (AUART_INTR_RTIS
|
|
||||||
| AUART_INTR_TXIS
|
|
||||||
| AUART_INTR_RXIS
|
|
||||||
| AUART_INTR_CTSMIS),
|
|
||||||
s->port.membase + AUART_INTR_CLR);
|
|
||||||
|
|
||||||
return IRQ_HANDLED;
|
return IRQ_HANDLED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -850,7 +851,7 @@ auart_console_write(struct console *co, const char *str, unsigned int count)
|
||||||
struct mxs_auart_port *s;
|
struct mxs_auart_port *s;
|
||||||
struct uart_port *port;
|
struct uart_port *port;
|
||||||
unsigned int old_ctrl0, old_ctrl2;
|
unsigned int old_ctrl0, old_ctrl2;
|
||||||
unsigned int to = 1000;
|
unsigned int to = 20000;
|
||||||
|
|
||||||
if (co->index >= MXS_AUART_PORTS || co->index < 0)
|
if (co->index >= MXS_AUART_PORTS || co->index < 0)
|
||||||
return;
|
return;
|
||||||
|
@ -871,18 +872,23 @@ auart_console_write(struct console *co, const char *str, unsigned int count)
|
||||||
|
|
||||||
uart_console_write(port, str, count, mxs_auart_console_putchar);
|
uart_console_write(port, str, count, mxs_auart_console_putchar);
|
||||||
|
|
||||||
/*
|
/* Finally, wait for transmitter to become empty ... */
|
||||||
* Finally, wait for transmitter to become empty
|
|
||||||
* and restore the TCR
|
|
||||||
*/
|
|
||||||
while (readl(port->membase + AUART_STAT) & AUART_STAT_BUSY) {
|
while (readl(port->membase + AUART_STAT) & AUART_STAT_BUSY) {
|
||||||
|
udelay(1);
|
||||||
if (!to--)
|
if (!to--)
|
||||||
break;
|
break;
|
||||||
udelay(1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ... and restore the TCR if we waited long enough for the transmitter
|
||||||
|
* to be idle. This might keep the transmitter enabled although it is
|
||||||
|
* unused, but that is better than to disable it while it is still
|
||||||
|
* transmitting.
|
||||||
|
*/
|
||||||
|
if (!(readl(port->membase + AUART_STAT) & AUART_STAT_BUSY)) {
|
||||||
writel(old_ctrl0, port->membase + AUART_CTRL0);
|
writel(old_ctrl0, port->membase + AUART_CTRL0);
|
||||||
writel(old_ctrl2, port->membase + AUART_CTRL2);
|
writel(old_ctrl2, port->membase + AUART_CTRL2);
|
||||||
|
}
|
||||||
|
|
||||||
clk_disable(s->clk);
|
clk_disable(s->clk);
|
||||||
}
|
}
|
||||||
|
|
|
@ -256,11 +256,10 @@ void tty_port_tty_hangup(struct tty_port *port, bool check_clocal)
|
||||||
{
|
{
|
||||||
struct tty_struct *tty = tty_port_tty_get(port);
|
struct tty_struct *tty = tty_port_tty_get(port);
|
||||||
|
|
||||||
if (tty && (!check_clocal || !C_CLOCAL(tty))) {
|
if (tty && (!check_clocal || !C_CLOCAL(tty)))
|
||||||
tty_hangup(tty);
|
tty_hangup(tty);
|
||||||
tty_kref_put(tty);
|
tty_kref_put(tty);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
EXPORT_SYMBOL_GPL(tty_port_tty_hangup);
|
EXPORT_SYMBOL_GPL(tty_port_tty_hangup);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue