TTY/Serial driver fixes for 4.2-rc4

Here are a number of small serial and tty fixes for reported issues.
 
 All have been in linux-next successfully.
 
 Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v2
 
 iEYEABECAAYFAlW0QW4ACgkQMUfUDdst+ym7UwCglnDVjGrWiw29PU42rXROq/Vf
 6boAniJehd4f/U9r5+aw/Hx6jqrhwC6c
 =dfFk
 -----END PGP SIGNATURE-----

Merge tag 'tty-4.2-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty

Pull tty/serial driver fixes from Greg KH:
 "Here are a number of small serial and tty fixes for reported issues.

  All have been in linux-next successfully"

* tag 'tty-4.2-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty:
  tty: vt: Fix !TASK_RUNNING diagnostic warning from paste_selection()
  serial: core: Fix crashes while echoing when closing
  m32r: Add ioreadXX/iowriteXX big-endian mmio accessors
  Revert "serial: imx: initialized DMA w/o HW flow enabled"
  sc16is7xx: fix FIFO address of secondary UART
  sc16is7xx: fix Kconfig dependencies
  serial: etraxfs-uart: Fix release etraxfs_uart_ports
  tty/vt: Fix the memory leak in visual_init
  serial: amba-pl011: Fix devm_ioremap_resource return value check
  n_tty: signal and flush atomically
This commit is contained in:
Linus Torvalds 2015-07-25 20:05:07 -07:00
commit 82b35f376c
10 changed files with 57 additions and 23 deletions

View File

@ -174,6 +174,11 @@ static inline void _writel(unsigned long l, unsigned long addr)
#define iowrite16 writew #define iowrite16 writew
#define iowrite32 writel #define iowrite32 writel
#define ioread16be(addr) be16_to_cpu(readw(addr))
#define ioread32be(addr) be32_to_cpu(readl(addr))
#define iowrite16be(v, addr) writew(cpu_to_be16(v), (addr))
#define iowrite32be(v, addr) writel(cpu_to_be32(v), (addr))
#define mmiowb() #define mmiowb()
#define flush_write_buffers() do { } while (0) /* M32R_FIXME */ #define flush_write_buffers() do { } while (0) /* M32R_FIXME */

View File

@ -1108,19 +1108,29 @@ static void eraser(unsigned char c, struct tty_struct *tty)
* Locking: ctrl_lock * Locking: ctrl_lock
*/ */
static void isig(int sig, struct tty_struct *tty) static void __isig(int sig, struct tty_struct *tty)
{ {
struct n_tty_data *ldata = tty->disc_data;
struct pid *tty_pgrp = tty_get_pgrp(tty); struct pid *tty_pgrp = tty_get_pgrp(tty);
if (tty_pgrp) { if (tty_pgrp) {
kill_pgrp(tty_pgrp, sig, 1); kill_pgrp(tty_pgrp, sig, 1);
put_pid(tty_pgrp); put_pid(tty_pgrp);
} }
}
if (!L_NOFLSH(tty)) { static void isig(int sig, struct tty_struct *tty)
{
struct n_tty_data *ldata = tty->disc_data;
if (L_NOFLSH(tty)) {
/* signal only */
__isig(sig, tty);
} else { /* signal and flush */
up_read(&tty->termios_rwsem); up_read(&tty->termios_rwsem);
down_write(&tty->termios_rwsem); down_write(&tty->termios_rwsem);
__isig(sig, tty);
/* clear echo buffer */ /* clear echo buffer */
mutex_lock(&ldata->output_lock); mutex_lock(&ldata->output_lock);
ldata->echo_head = ldata->echo_tail = 0; ldata->echo_head = ldata->echo_tail = 0;

View File

@ -1185,7 +1185,7 @@ config SERIAL_SC16IS7XX_CORE
config SERIAL_SC16IS7XX config SERIAL_SC16IS7XX
tristate "SC16IS7xx serial support" tristate "SC16IS7xx serial support"
select SERIAL_CORE select SERIAL_CORE
depends on I2C || SPI_MASTER depends on (SPI_MASTER && !I2C) || I2C
help help
This selects support for SC16IS7xx serial ports. This selects support for SC16IS7xx serial ports.
Supported ICs are SC16IS740, SC16IS741, SC16IS750, SC16IS752, Supported ICs are SC16IS740, SC16IS741, SC16IS750, SC16IS752,

View File

@ -2310,8 +2310,8 @@ static int pl011_setup_port(struct device *dev, struct uart_amba_port *uap,
void __iomem *base; void __iomem *base;
base = devm_ioremap_resource(dev, mmiobase); base = devm_ioremap_resource(dev, mmiobase);
if (!base) if (IS_ERR(base))
return -ENOMEM; return PTR_ERR(base);
index = pl011_probe_dt_alias(index, dev); index = pl011_probe_dt_alias(index, dev);

View File

@ -950,7 +950,7 @@ static int etraxfs_uart_remove(struct platform_device *pdev)
port = platform_get_drvdata(pdev); port = platform_get_drvdata(pdev);
uart_remove_one_port(&etraxfs_uart_driver, port); uart_remove_one_port(&etraxfs_uart_driver, port);
etraxfs_uart_ports[pdev->id] = NULL; etraxfs_uart_ports[port->line] = NULL;
return 0; return 0;
} }

View File

@ -1121,11 +1121,6 @@ static int imx_startup(struct uart_port *port)
writel(temp & ~UCR4_DREN, sport->port.membase + UCR4); writel(temp & ~UCR4_DREN, sport->port.membase + UCR4);
/* Can we enable the DMA support? */
if (is_imx6q_uart(sport) && !uart_console(port) &&
!sport->dma_is_inited)
imx_uart_dma_init(sport);
spin_lock_irqsave(&sport->port.lock, flags); spin_lock_irqsave(&sport->port.lock, flags);
/* Reset fifo's and state machines */ /* Reset fifo's and state machines */
i = 100; i = 100;
@ -1143,9 +1138,6 @@ static int imx_startup(struct uart_port *port)
writel(USR1_RTSD, sport->port.membase + USR1); writel(USR1_RTSD, sport->port.membase + USR1);
writel(USR2_ORE, sport->port.membase + USR2); writel(USR2_ORE, sport->port.membase + USR2);
if (sport->dma_is_inited && !sport->dma_is_enabled)
imx_enable_dma(sport);
temp = readl(sport->port.membase + UCR1); temp = readl(sport->port.membase + UCR1);
temp |= UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN; temp |= UCR1_RRDYEN | UCR1_RTSDEN | UCR1_UARTEN;
@ -1316,6 +1308,11 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
} else { } else {
ucr2 |= UCR2_CTSC; ucr2 |= UCR2_CTSC;
} }
/* Can we enable the DMA support? */
if (is_imx6q_uart(sport) && !uart_console(port)
&& !sport->dma_is_inited)
imx_uart_dma_init(sport);
} else { } else {
termios->c_cflag &= ~CRTSCTS; termios->c_cflag &= ~CRTSCTS;
} }
@ -1432,6 +1429,8 @@ imx_set_termios(struct uart_port *port, struct ktermios *termios,
if (UART_ENABLE_MS(&sport->port, termios->c_cflag)) if (UART_ENABLE_MS(&sport->port, termios->c_cflag))
imx_enable_ms(&sport->port); imx_enable_ms(&sport->port);
if (sport->dma_is_inited && !sport->dma_is_enabled)
imx_enable_dma(sport);
spin_unlock_irqrestore(&sport->port.lock, flags); spin_unlock_irqrestore(&sport->port.lock, flags);
} }

View File

@ -354,6 +354,26 @@ static void sc16is7xx_port_write(struct uart_port *port, u8 reg, u8 val)
(reg << SC16IS7XX_REG_SHIFT) | port->line, val); (reg << SC16IS7XX_REG_SHIFT) | port->line, val);
} }
static void sc16is7xx_fifo_read(struct uart_port *port, unsigned int rxlen)
{
struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
u8 addr = (SC16IS7XX_RHR_REG << SC16IS7XX_REG_SHIFT) | port->line;
regcache_cache_bypass(s->regmap, true);
regmap_raw_read(s->regmap, addr, s->buf, rxlen);
regcache_cache_bypass(s->regmap, false);
}
static void sc16is7xx_fifo_write(struct uart_port *port, u8 to_send)
{
struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
u8 addr = (SC16IS7XX_THR_REG << SC16IS7XX_REG_SHIFT) | port->line;
regcache_cache_bypass(s->regmap, true);
regmap_raw_write(s->regmap, addr, s->buf, to_send);
regcache_cache_bypass(s->regmap, false);
}
static void sc16is7xx_port_update(struct uart_port *port, u8 reg, static void sc16is7xx_port_update(struct uart_port *port, u8 reg,
u8 mask, u8 val) u8 mask, u8 val)
{ {
@ -508,10 +528,7 @@ static void sc16is7xx_handle_rx(struct uart_port *port, unsigned int rxlen,
s->buf[0] = sc16is7xx_port_read(port, SC16IS7XX_RHR_REG); s->buf[0] = sc16is7xx_port_read(port, SC16IS7XX_RHR_REG);
bytes_read = 1; bytes_read = 1;
} else { } else {
regcache_cache_bypass(s->regmap, true); sc16is7xx_fifo_read(port, rxlen);
regmap_raw_read(s->regmap, SC16IS7XX_RHR_REG,
s->buf, rxlen);
regcache_cache_bypass(s->regmap, false);
bytes_read = rxlen; bytes_read = rxlen;
} }
@ -591,9 +608,8 @@ static void sc16is7xx_handle_tx(struct uart_port *port)
s->buf[i] = xmit->buf[xmit->tail]; s->buf[i] = xmit->buf[xmit->tail];
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
} }
regcache_cache_bypass(s->regmap, true);
regmap_raw_write(s->regmap, SC16IS7XX_THR_REG, s->buf, to_send); sc16is7xx_fifo_write(port, to_send);
regcache_cache_bypass(s->regmap, false);
} }
if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)

View File

@ -1418,7 +1418,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
mutex_lock(&port->mutex); mutex_lock(&port->mutex);
uart_shutdown(tty, state); uart_shutdown(tty, state);
tty_port_tty_set(port, NULL); tty_port_tty_set(port, NULL);
tty->closing = 0;
spin_lock_irqsave(&port->lock, flags); spin_lock_irqsave(&port->lock, flags);
if (port->blocked_open) { if (port->blocked_open) {
@ -1444,6 +1444,7 @@ static void uart_close(struct tty_struct *tty, struct file *filp)
mutex_unlock(&port->mutex); mutex_unlock(&port->mutex);
tty_ldisc_flush(tty); tty_ldisc_flush(tty);
tty->closing = 0;
} }
static void uart_wait_until_sent(struct tty_struct *tty, int timeout) static void uart_wait_until_sent(struct tty_struct *tty, int timeout)

View File

@ -356,6 +356,7 @@ int paste_selection(struct tty_struct *tty)
schedule(); schedule();
continue; continue;
} }
__set_current_state(TASK_RUNNING);
count = sel_buffer_lth - pasted; count = sel_buffer_lth - pasted;
count = tty_ldisc_receive_buf(ld, sel_buffer + pasted, NULL, count = tty_ldisc_receive_buf(ld, sel_buffer + pasted, NULL,
count); count);

View File

@ -742,6 +742,8 @@ static void visual_init(struct vc_data *vc, int num, int init)
__module_get(vc->vc_sw->owner); __module_get(vc->vc_sw->owner);
vc->vc_num = num; vc->vc_num = num;
vc->vc_display_fg = &master_display_fg; vc->vc_display_fg = &master_display_fg;
if (vc->vc_uni_pagedir_loc)
con_free_unimap(vc);
vc->vc_uni_pagedir_loc = &vc->vc_uni_pagedir; vc->vc_uni_pagedir_loc = &vc->vc_uni_pagedir;
vc->vc_uni_pagedir = NULL; vc->vc_uni_pagedir = NULL;
vc->vc_hi_font_mask = 0; vc->vc_hi_font_mask = 0;