Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a93f66dc authored by Linus Torvalds's avatar Linus Torvalds
Browse files
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
Loading
Loading
Loading
Loading
+1 −1
Original line number Original line Diff line number Diff line
@@ -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");
+22 −16
Original line number Original line Diff line number Diff line
@@ -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);
}
}
+2 −3
Original line number Original line Diff line number Diff line
@@ -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);


/**
/**