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

Commit c1e7179a authored by Linus Torvalds's avatar Linus Torvalds
Browse files


Pull TTY/Serial patches from Greg Kroah-Hartman:
 "Here's the "tiny" set of patches for 3.6-rc1 for the tty layer and
  serial drivers.  They were cherry-picked from the tty-next branch of
  the tty git tree, as they are small and "obvious" fixes.  The larger
  changes, as mentioned before, will be saved for the 3.7-rc1 merge
  window.

  All of these changes have been in the linux-next releases for quite a
  while.

  Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org&gt;">

* tag 'tty-3.6-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty:
  pch_uart: Fix parity setting issue
  pch_uart: Fix rx error interrupt setting issue
  pch_uart: Fix missing break for 16 byte fifo
  tty ldisc: Close/Reopen race prevention should check the proper flag
  pch_uart: Add eg20t_port lock field, avoid recursive spinlocks
  vt: fix race in vt_waitactive()
  serial/of-serial: Add LPC3220 standard UART compatible string
  serial/8250: Add LPC3220 standard UART type
  serial_core: Update buffer overrun statistics.
  serial: samsung: Fixed wrong comparison for baudclk_rate
parents 84eda280 38bd2a1a
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@ Required properties:
	- "ns16750"
	- "ns16850"
	- "nvidia,tegra20-uart"
	- "nxp,lpc3220-uart"
	- "ibm,qpace-nwp-serial"
	- "serial" if the port type is unknown.
- reg : offset and length of the register set for the device.
+8 −0
Original line number Diff line number Diff line
@@ -282,6 +282,14 @@ static const struct serial8250_config uart_config[] = {
		.fcr		= UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
		.flags		= UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR,
	},
	[PORT_LPC3220] = {
		.name		= "LPC3220",
		.fifo_size	= 64,
		.tx_loadsz	= 32,
		.fcr		= UART_FCR_DMA_SELECT | UART_FCR_ENABLE_FIFO |
				  UART_FCR_R_TRIG_00 | UART_FCR_T_TRIG_00,
		.flags		= UART_CAP_FIFO,
	},
};

/* Uart divisor latch read */
+1 −0
Original line number Diff line number Diff line
@@ -208,6 +208,7 @@ static struct of_device_id __devinitdata of_platform_serial_table[] = {
	{ .compatible = "ns16750",  .data = (void *)PORT_16750, },
	{ .compatible = "ns16850",  .data = (void *)PORT_16850, },
	{ .compatible = "nvidia,tegra20-uart", .data = (void *)PORT_TEGRA, },
	{ .compatible = "nxp,lpc3220-uart", .data = (void *)PORT_LPC3220, },
#ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL
	{ .compatible = "ibm,qpace-nwp-serial",
		.data = (void *)PORT_NWPSERIAL, },
+40 −19
Original line number Diff line number Diff line
@@ -253,6 +253,9 @@ struct eg20t_port {
	dma_addr_t			rx_buf_dma;

	struct dentry	*debugfs;

	/* protect the eg20t_port private structure and io access to membase */
	spinlock_t lock;
};

/**
@@ -754,7 +757,8 @@ static void pch_dma_rx_complete(void *arg)
		tty_flip_buffer_push(tty);
	tty_kref_put(tty);
	async_tx_ack(priv->desc_rx);
	pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_RX_INT);
	pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_RX_INT |
					    PCH_UART_HAL_RX_ERR_INT);
}

static void pch_dma_tx_complete(void *arg)
@@ -809,7 +813,8 @@ static int handle_rx_to(struct eg20t_port *priv)
	int rx_size;
	int ret;
	if (!priv->start_rx) {
		pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_RX_INT);
		pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_RX_INT |
						     PCH_UART_HAL_RX_ERR_INT);
		return 0;
	}
	buf = &priv->rxbuf;
@@ -1058,7 +1063,7 @@ static irqreturn_t pch_uart_interrupt(int irq, void *dev_id)
	int next = 1;
	u8 msr;

	spin_lock_irqsave(&priv->port.lock, flags);
	spin_lock_irqsave(&priv->lock, flags);
	handled = 0;
	while (next) {
		iid = pch_uart_hal_get_iid(priv);
@@ -1078,11 +1083,13 @@ static irqreturn_t pch_uart_interrupt(int irq, void *dev_id)
		case PCH_UART_IID_RDR:	/* Received Data Ready */
			if (priv->use_dma) {
				pch_uart_hal_disable_interrupt(priv,
							PCH_UART_HAL_RX_INT);
						PCH_UART_HAL_RX_INT |
						PCH_UART_HAL_RX_ERR_INT);
				ret = dma_handle_rx(priv);
				if (!ret)
					pch_uart_hal_enable_interrupt(priv,
							PCH_UART_HAL_RX_INT);
						PCH_UART_HAL_RX_INT |
						PCH_UART_HAL_RX_ERR_INT);
			} else {
				ret = handle_rx(priv);
			}
@@ -1116,7 +1123,7 @@ static irqreturn_t pch_uart_interrupt(int irq, void *dev_id)
		handled |= (unsigned int)ret;
	}

	spin_unlock_irqrestore(&priv->port.lock, flags);
	spin_unlock_irqrestore(&priv->lock, flags);
	return IRQ_RETVAL(handled);
}

@@ -1208,7 +1215,8 @@ static void pch_uart_stop_rx(struct uart_port *port)
	struct eg20t_port *priv;
	priv = container_of(port, struct eg20t_port, port);
	priv->start_rx = 0;
	pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_RX_INT);
	pch_uart_hal_disable_interrupt(priv, PCH_UART_HAL_RX_INT |
					     PCH_UART_HAL_RX_ERR_INT);
}

/* Enable the modem status interrupts. */
@@ -1226,9 +1234,9 @@ static void pch_uart_break_ctl(struct uart_port *port, int ctl)
	unsigned long flags;

	priv = container_of(port, struct eg20t_port, port);
	spin_lock_irqsave(&port->lock, flags);
	spin_lock_irqsave(&priv->lock, flags);
	pch_uart_hal_set_break(priv, ctl);
	spin_unlock_irqrestore(&port->lock, flags);
	spin_unlock_irqrestore(&priv->lock, flags);
}

/* Grab any interrupt resources and initialise any low level driver state. */
@@ -1263,6 +1271,7 @@ static int pch_uart_startup(struct uart_port *port)
		break;
	case 16:
		fifo_size = PCH_UART_HAL_FIFO16;
		break;
	case 1:
	default:
		fifo_size = PCH_UART_HAL_FIFO_DIS;
@@ -1300,7 +1309,8 @@ static int pch_uart_startup(struct uart_port *port)
		pch_request_dma(port);

	priv->start_rx = 1;
	pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_RX_INT);
	pch_uart_hal_enable_interrupt(priv, PCH_UART_HAL_RX_INT |
					    PCH_UART_HAL_RX_ERR_INT);
	uart_update_timeout(port, CS8, default_baud);

	return 0;
@@ -1358,7 +1368,7 @@ static void pch_uart_set_termios(struct uart_port *port,
		stb = PCH_UART_HAL_STB1;

	if (termios->c_cflag & PARENB) {
		if (!(termios->c_cflag & PARODD))
		if (termios->c_cflag & PARODD)
			parity = PCH_UART_HAL_PARITY_ODD;
		else
			parity = PCH_UART_HAL_PARITY_EVEN;
@@ -1376,7 +1386,8 @@ static void pch_uart_set_termios(struct uart_port *port,

	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16);

	spin_lock_irqsave(&port->lock, flags);
	spin_lock_irqsave(&priv->lock, flags);
	spin_lock(&port->lock);

	uart_update_timeout(port, termios->c_cflag, baud);
	rtn = pch_uart_hal_set_line(priv, baud, parity, bits, stb);
@@ -1389,7 +1400,8 @@ static void pch_uart_set_termios(struct uart_port *port,
		tty_termios_encode_baud_rate(termios, baud, baud);

out:
	spin_unlock_irqrestore(&port->lock, flags);
	spin_unlock(&port->lock);
	spin_unlock_irqrestore(&priv->lock, flags);
}

static const char *pch_uart_type(struct uart_port *port)
@@ -1538,8 +1550,9 @@ pch_console_write(struct console *co, const char *s, unsigned int count)
{
	struct eg20t_port *priv;
	unsigned long flags;
	int priv_locked = 1;
	int port_locked = 1;
	u8 ier;
	int locked = 1;

	priv = pch_uart_ports[co->index];

@@ -1547,12 +1560,16 @@ pch_console_write(struct console *co, const char *s, unsigned int count)

	local_irq_save(flags);
	if (priv->port.sysrq) {
		/* serial8250_handle_port() already took the lock */
		locked = 0;
		spin_lock(&priv->lock);
		/* serial8250_handle_port() already took the port lock */
		port_locked = 0;
	} else if (oops_in_progress) {
		locked = spin_trylock(&priv->port.lock);
	} else
		priv_locked = spin_trylock(&priv->lock);
		port_locked = spin_trylock(&priv->port.lock);
	} else {
		spin_lock(&priv->lock);
		spin_lock(&priv->port.lock);
	}

	/*
	 *	First save the IER then disable the interrupts
@@ -1570,8 +1587,10 @@ pch_console_write(struct console *co, const char *s, unsigned int count)
	wait_for_xmitr(priv, BOTH_EMPTY);
	iowrite8(ier, priv->membase + UART_IER);

	if (locked)
	if (port_locked)
		spin_unlock(&priv->port.lock);
	if (priv_locked)
		spin_unlock(&priv->lock);
	local_irq_restore(flags);
}

@@ -1669,6 +1688,8 @@ static struct eg20t_port *pch_uart_init_port(struct pci_dev *pdev,
	pci_enable_msi(pdev);
	pci_set_master(pdev);

	spin_lock_init(&priv->lock);

	iobase = pci_resource_start(pdev, 0);
	mapbase = pci_resource_start(pdev, 1);
	priv->mapbase = mapbase;
+2 −2
Original line number Diff line number Diff line
@@ -1014,10 +1014,10 @@ static int s3c24xx_serial_cpufreq_transition(struct notifier_block *nb,
	 * a disturbance in the clock-rate over the change.
	 */

	if (IS_ERR(port->clk))
	if (IS_ERR(port->baudclk))
		goto exit;

	if (port->baudclk_rate == clk_get_rate(port->clk))
	if (port->baudclk_rate == clk_get_rate(port->baudclk))
		goto exit;

	if (val == CPUFREQ_PRECHANGE) {
Loading