提交 69c37a92 编写于 作者: L Linus Torvalds

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

Pull tty/serial fixes from Greg KH:
 "Here are some tty/serial driver fixes for 4.4-rc6 that resolve some
  reported problems.  All of these have been in linux-next.  The details
  are in the shortlog"

* tag 'tty-4.4-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty:
  tty: Fix GPF in flush_to_ldisc()
  serial: earlycon: Add missing spinlock initialization
  serial: sh-sci: Fix length of scatterlist
  n_tty: Fix poll() after buffer-limited eof push read
  serial: 8250_uniphier: fix dl_read and dl_write functions
...@@ -2054,13 +2054,13 @@ static int canon_copy_from_read_buf(struct tty_struct *tty, ...@@ -2054,13 +2054,13 @@ static int canon_copy_from_read_buf(struct tty_struct *tty,
size_t eol; size_t eol;
size_t tail; size_t tail;
int ret, found = 0; int ret, found = 0;
bool eof_push = 0;
/* N.B. avoid overrun if nr == 0 */ /* N.B. avoid overrun if nr == 0 */
n = min(*nr, smp_load_acquire(&ldata->canon_head) - ldata->read_tail); if (!*nr)
if (!n)
return 0; return 0;
n = min(*nr + 1, smp_load_acquire(&ldata->canon_head) - ldata->read_tail);
tail = ldata->read_tail & (N_TTY_BUF_SIZE - 1); tail = ldata->read_tail & (N_TTY_BUF_SIZE - 1);
size = min_t(size_t, tail + n, N_TTY_BUF_SIZE); size = min_t(size_t, tail + n, N_TTY_BUF_SIZE);
...@@ -2081,12 +2081,11 @@ static int canon_copy_from_read_buf(struct tty_struct *tty, ...@@ -2081,12 +2081,11 @@ static int canon_copy_from_read_buf(struct tty_struct *tty,
n = eol - tail; n = eol - tail;
if (n > N_TTY_BUF_SIZE) if (n > N_TTY_BUF_SIZE)
n += N_TTY_BUF_SIZE; n += N_TTY_BUF_SIZE;
n += found; c = n + found;
c = n;
if (found && !ldata->push && read_buf(ldata, eol) == __DISABLED_CHAR) { if (!found || read_buf(ldata, eol) != __DISABLED_CHAR) {
n--; c = min(*nr, c);
eof_push = !n && ldata->read_tail != ldata->line_start; n = c;
} }
n_tty_trace("%s: eol:%zu found:%d n:%zu c:%zu size:%zu more:%zu\n", n_tty_trace("%s: eol:%zu found:%d n:%zu c:%zu size:%zu more:%zu\n",
...@@ -2116,7 +2115,7 @@ static int canon_copy_from_read_buf(struct tty_struct *tty, ...@@ -2116,7 +2115,7 @@ static int canon_copy_from_read_buf(struct tty_struct *tty,
ldata->push = 0; ldata->push = 0;
tty_audit_push(tty); tty_audit_push(tty);
} }
return eof_push ? -EAGAIN : 0; return 0;
} }
extern ssize_t redirected_tty_write(struct file *, const char __user *, extern ssize_t redirected_tty_write(struct file *, const char __user *,
...@@ -2273,10 +2272,7 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file, ...@@ -2273,10 +2272,7 @@ static ssize_t n_tty_read(struct tty_struct *tty, struct file *file,
if (ldata->icanon && !L_EXTPROC(tty)) { if (ldata->icanon && !L_EXTPROC(tty)) {
retval = canon_copy_from_read_buf(tty, &b, &nr); retval = canon_copy_from_read_buf(tty, &b, &nr);
if (retval == -EAGAIN) { if (retval)
retval = 0;
continue;
} else if (retval)
break; break;
} else { } else {
int uncopied; int uncopied;
......
...@@ -115,12 +115,16 @@ static void uniphier_serial_out(struct uart_port *p, int offset, int value) ...@@ -115,12 +115,16 @@ static void uniphier_serial_out(struct uart_port *p, int offset, int value)
*/ */
static int uniphier_serial_dl_read(struct uart_8250_port *up) static int uniphier_serial_dl_read(struct uart_8250_port *up)
{ {
return readl(up->port.membase + UNIPHIER_UART_DLR); int offset = UNIPHIER_UART_DLR << up->port.regshift;
return readl(up->port.membase + offset);
} }
static void uniphier_serial_dl_write(struct uart_8250_port *up, int value) static void uniphier_serial_dl_write(struct uart_8250_port *up, int value)
{ {
writel(value, up->port.membase + UNIPHIER_UART_DLR); int offset = UNIPHIER_UART_DLR << up->port.regshift;
writel(value, up->port.membase + offset);
} }
static int uniphier_of_serial_setup(struct device *dev, struct uart_port *port, static int uniphier_of_serial_setup(struct device *dev, struct uart_port *port,
......
...@@ -115,6 +115,7 @@ static int __init register_earlycon(char *buf, const struct earlycon_id *match) ...@@ -115,6 +115,7 @@ static int __init register_earlycon(char *buf, const struct earlycon_id *match)
if (buf && !parse_options(&early_console_dev, buf)) if (buf && !parse_options(&early_console_dev, buf))
buf = NULL; buf = NULL;
spin_lock_init(&port->lock);
port->uartclk = BASE_BAUD * 16; port->uartclk = BASE_BAUD * 16;
if (port->mapbase) if (port->mapbase)
port->membase = earlycon_map(port->mapbase, 64); port->membase = earlycon_map(port->mapbase, 64);
...@@ -202,6 +203,7 @@ int __init of_setup_earlycon(unsigned long addr, ...@@ -202,6 +203,7 @@ int __init of_setup_earlycon(unsigned long addr,
int err; int err;
struct uart_port *port = &early_console_dev.port; struct uart_port *port = &early_console_dev.port;
spin_lock_init(&port->lock);
port->iotype = UPIO_MEM; port->iotype = UPIO_MEM;
port->mapbase = addr; port->mapbase = addr;
port->uartclk = BASE_BAUD * 16; port->uartclk = BASE_BAUD * 16;
......
...@@ -1437,7 +1437,7 @@ static void sci_request_dma(struct uart_port *port) ...@@ -1437,7 +1437,7 @@ static void sci_request_dma(struct uart_port *port)
sg_init_table(sg, 1); sg_init_table(sg, 1);
s->rx_buf[i] = buf; s->rx_buf[i] = buf;
sg_dma_address(sg) = dma; sg_dma_address(sg) = dma;
sg->length = s->buf_len_rx; sg_dma_len(sg) = s->buf_len_rx;
buf += s->buf_len_rx; buf += s->buf_len_rx;
dma += s->buf_len_rx; dma += s->buf_len_rx;
......
...@@ -450,7 +450,7 @@ receive_buf(struct tty_struct *tty, struct tty_buffer *head, int count) ...@@ -450,7 +450,7 @@ receive_buf(struct tty_struct *tty, struct tty_buffer *head, int count)
count = disc->ops->receive_buf2(tty, p, f, count); count = disc->ops->receive_buf2(tty, p, f, count);
else { else {
count = min_t(int, count, tty->receive_room); count = min_t(int, count, tty->receive_room);
if (count) if (count && disc->ops->receive_buf)
disc->ops->receive_buf(tty, p, f, count); disc->ops->receive_buf(tty, p, f, count);
} }
return count; return count;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册