Commit a93f66dc authored by Linus Torvalds's avatar Linus Torvalds

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
parents 36f571e9 d5a12ea7
...@@ -773,6 +773,6 @@ module_init(arc_serial_init); ...@@ -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, ...@@ -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) ...@@ -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) ...@@ -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) ...@@ -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);
} }
writel(old_ctrl0, port->membase + AUART_CTRL0); /*
writel(old_ctrl2, port->membase + AUART_CTRL2); * ... 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_ctrl2, port->membase + AUART_CTRL2);
}
clk_disable(s->clk); clk_disable(s->clk);
} }
......
...@@ -256,10 +256,9 @@ void tty_port_tty_hangup(struct tty_port *port, bool check_clocal) ...@@ -256,10 +256,9 @@ 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);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment