aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/tty
diff options
context:
space:
mode:
authorRob Herring <robh@kernel.org>2014-05-13 19:34:35 -0400
committerRob Herring <robh@kernel.org>2014-05-13 19:34:35 -0400
commiteafd370dfe487facfdef499057f4eac9aa0b4bf5 (patch)
tree0925a67cd658cdf4811f49b4cd2073f663166bd0 /drivers/tty
parentc3fc952d2fbe3ec78defd70cf73d5d76d27092ec (diff)
parentfb2caa50fbacd21719a90dd66b617ce3cb4fd6d7 (diff)
Merge branch 'dt-bus-name' into for-next
Diffstat (limited to 'drivers/tty')
-rw-r--r--drivers/tty/hvc/hvc_console.c2
-rw-r--r--drivers/tty/n_tty.c4
-rw-r--r--drivers/tty/serial/8250/8250_core.c4
-rw-r--r--drivers/tty/serial/8250/8250_dma.c9
-rw-r--r--drivers/tty/serial/samsung.c23
-rw-r--r--drivers/tty/serial/serial_core.c39
-rw-r--r--drivers/tty/tty_buffer.c17
7 files changed, 61 insertions, 37 deletions
diff --git a/drivers/tty/hvc/hvc_console.c b/drivers/tty/hvc/hvc_console.c
index 94f9e3a38412..0ff7fda0742f 100644
--- a/drivers/tty/hvc/hvc_console.c
+++ b/drivers/tty/hvc/hvc_console.c
@@ -190,7 +190,7 @@ static struct tty_driver *hvc_console_device(struct console *c, int *index)
190 return hvc_driver; 190 return hvc_driver;
191} 191}
192 192
193static int __init hvc_console_setup(struct console *co, char *options) 193static int hvc_console_setup(struct console *co, char *options)
194{ 194{
195 if (co->index < 0 || co->index >= MAX_NR_HVC_CONSOLES) 195 if (co->index < 0 || co->index >= MAX_NR_HVC_CONSOLES)
196 return -ENODEV; 196 return -ENODEV;
diff --git a/drivers/tty/n_tty.c b/drivers/tty/n_tty.c
index 41fe8a047d37..fe9d129c8735 100644
--- a/drivers/tty/n_tty.c
+++ b/drivers/tty/n_tty.c
@@ -2353,8 +2353,12 @@ static ssize_t n_tty_write(struct tty_struct *tty, struct file *file,
2353 if (tty->ops->flush_chars) 2353 if (tty->ops->flush_chars)
2354 tty->ops->flush_chars(tty); 2354 tty->ops->flush_chars(tty);
2355 } else { 2355 } else {
2356 struct n_tty_data *ldata = tty->disc_data;
2357
2356 while (nr > 0) { 2358 while (nr > 0) {
2359 mutex_lock(&ldata->output_lock);
2357 c = tty->ops->write(tty, b, nr); 2360 c = tty->ops->write(tty, b, nr);
2361 mutex_unlock(&ldata->output_lock);
2358 if (c < 0) { 2362 if (c < 0) {
2359 retval = c; 2363 retval = c;
2360 goto break_out; 2364 goto break_out;
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
index 81f909c2101f..2d4bd3929e50 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -555,7 +555,7 @@ static void serial8250_set_sleep(struct uart_8250_port *p, int sleep)
555 */ 555 */
556 if ((p->port.type == PORT_XR17V35X) || 556 if ((p->port.type == PORT_XR17V35X) ||
557 (p->port.type == PORT_XR17D15X)) { 557 (p->port.type == PORT_XR17D15X)) {
558 serial_out(p, UART_EXAR_SLEEP, 0xff); 558 serial_out(p, UART_EXAR_SLEEP, sleep ? 0xff : 0);
559 return; 559 return;
560 } 560 }
561 561
@@ -1520,7 +1520,7 @@ int serial8250_handle_irq(struct uart_port *port, unsigned int iir)
1520 status = serial8250_rx_chars(up, status); 1520 status = serial8250_rx_chars(up, status);
1521 } 1521 }
1522 serial8250_modem_status(up); 1522 serial8250_modem_status(up);
1523 if (status & UART_LSR_THRE) 1523 if (!up->dma && (status & UART_LSR_THRE))
1524 serial8250_tx_chars(up); 1524 serial8250_tx_chars(up);
1525 1525
1526 spin_unlock_irqrestore(&port->lock, flags); 1526 spin_unlock_irqrestore(&port->lock, flags);
diff --git a/drivers/tty/serial/8250/8250_dma.c b/drivers/tty/serial/8250/8250_dma.c
index 7046769608d4..ab9096dc3849 100644
--- a/drivers/tty/serial/8250/8250_dma.c
+++ b/drivers/tty/serial/8250/8250_dma.c
@@ -20,12 +20,15 @@ static void __dma_tx_complete(void *param)
20 struct uart_8250_port *p = param; 20 struct uart_8250_port *p = param;
21 struct uart_8250_dma *dma = p->dma; 21 struct uart_8250_dma *dma = p->dma;
22 struct circ_buf *xmit = &p->port.state->xmit; 22 struct circ_buf *xmit = &p->port.state->xmit;
23 23 unsigned long flags;
24 dma->tx_running = 0;
25 24
26 dma_sync_single_for_cpu(dma->txchan->device->dev, dma->tx_addr, 25 dma_sync_single_for_cpu(dma->txchan->device->dev, dma->tx_addr,
27 UART_XMIT_SIZE, DMA_TO_DEVICE); 26 UART_XMIT_SIZE, DMA_TO_DEVICE);
28 27
28 spin_lock_irqsave(&p->port.lock, flags);
29
30 dma->tx_running = 0;
31
29 xmit->tail += dma->tx_size; 32 xmit->tail += dma->tx_size;
30 xmit->tail &= UART_XMIT_SIZE - 1; 33 xmit->tail &= UART_XMIT_SIZE - 1;
31 p->port.icount.tx += dma->tx_size; 34 p->port.icount.tx += dma->tx_size;
@@ -35,6 +38,8 @@ static void __dma_tx_complete(void *param)
35 38
36 if (!uart_circ_empty(xmit) && !uart_tx_stopped(&p->port)) 39 if (!uart_circ_empty(xmit) && !uart_tx_stopped(&p->port))
37 serial8250_tx_dma(p); 40 serial8250_tx_dma(p);
41
42 spin_unlock_irqrestore(&p->port.lock, flags);
38} 43}
39 44
40static void __dma_rx_complete(void *param) 45static void __dma_rx_complete(void *param)
diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c
index 23f459600738..1f5505e7f90d 100644
--- a/drivers/tty/serial/samsung.c
+++ b/drivers/tty/serial/samsung.c
@@ -1446,8 +1446,8 @@ static int s3c24xx_serial_get_poll_char(struct uart_port *port)
1446static void s3c24xx_serial_put_poll_char(struct uart_port *port, 1446static void s3c24xx_serial_put_poll_char(struct uart_port *port,
1447 unsigned char c) 1447 unsigned char c)
1448{ 1448{
1449 unsigned int ufcon = rd_regl(cons_uart, S3C2410_UFCON); 1449 unsigned int ufcon = rd_regl(port, S3C2410_UFCON);
1450 unsigned int ucon = rd_regl(cons_uart, S3C2410_UCON); 1450 unsigned int ucon = rd_regl(port, S3C2410_UCON);
1451 1451
1452 /* not possible to xmit on unconfigured port */ 1452 /* not possible to xmit on unconfigured port */
1453 if (!s3c24xx_port_configured(ucon)) 1453 if (!s3c24xx_port_configured(ucon))
@@ -1455,7 +1455,7 @@ static void s3c24xx_serial_put_poll_char(struct uart_port *port,
1455 1455
1456 while (!s3c24xx_serial_console_txrdy(port, ufcon)) 1456 while (!s3c24xx_serial_console_txrdy(port, ufcon))
1457 cpu_relax(); 1457 cpu_relax();
1458 wr_regb(cons_uart, S3C2410_UTXH, c); 1458 wr_regb(port, S3C2410_UTXH, c);
1459} 1459}
1460 1460
1461#endif /* CONFIG_CONSOLE_POLL */ 1461#endif /* CONFIG_CONSOLE_POLL */
@@ -1463,22 +1463,23 @@ static void s3c24xx_serial_put_poll_char(struct uart_port *port,
1463static void 1463static void
1464s3c24xx_serial_console_putchar(struct uart_port *port, int ch) 1464s3c24xx_serial_console_putchar(struct uart_port *port, int ch)
1465{ 1465{
1466 unsigned int ufcon = rd_regl(cons_uart, S3C2410_UFCON); 1466 unsigned int ufcon = rd_regl(port, S3C2410_UFCON);
1467 unsigned int ucon = rd_regl(cons_uart, S3C2410_UCON);
1468
1469 /* not possible to xmit on unconfigured port */
1470 if (!s3c24xx_port_configured(ucon))
1471 return;
1472 1467
1473 while (!s3c24xx_serial_console_txrdy(port, ufcon)) 1468 while (!s3c24xx_serial_console_txrdy(port, ufcon))
1474 barrier(); 1469 cpu_relax();
1475 wr_regb(cons_uart, S3C2410_UTXH, ch); 1470 wr_regb(port, S3C2410_UTXH, ch);
1476} 1471}
1477 1472
1478static void 1473static void
1479s3c24xx_serial_console_write(struct console *co, const char *s, 1474s3c24xx_serial_console_write(struct console *co, const char *s,
1480 unsigned int count) 1475 unsigned int count)
1481{ 1476{
1477 unsigned int ucon = rd_regl(cons_uart, S3C2410_UCON);
1478
1479 /* not possible to xmit on unconfigured port */
1480 if (!s3c24xx_port_configured(ucon))
1481 return;
1482
1482 uart_console_write(cons_uart, s, count, s3c24xx_serial_console_putchar); 1483 uart_console_write(cons_uart, s, count, s3c24xx_serial_console_putchar);
1483} 1484}
1484 1485
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index f26834d262b3..b68550d95a40 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -137,6 +137,11 @@ static int uart_port_startup(struct tty_struct *tty, struct uart_state *state,
137 return 1; 137 return 1;
138 138
139 /* 139 /*
140 * Make sure the device is in D0 state.
141 */
142 uart_change_pm(state, UART_PM_STATE_ON);
143
144 /*
140 * Initialise and allocate the transmit and temporary 145 * Initialise and allocate the transmit and temporary
141 * buffer. 146 * buffer.
142 */ 147 */
@@ -825,25 +830,29 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port,
825 * If we fail to request resources for the 830 * If we fail to request resources for the
826 * new port, try to restore the old settings. 831 * new port, try to restore the old settings.
827 */ 832 */
828 if (retval && old_type != PORT_UNKNOWN) { 833 if (retval) {
829 uport->iobase = old_iobase; 834 uport->iobase = old_iobase;
830 uport->type = old_type; 835 uport->type = old_type;
831 uport->hub6 = old_hub6; 836 uport->hub6 = old_hub6;
832 uport->iotype = old_iotype; 837 uport->iotype = old_iotype;
833 uport->regshift = old_shift; 838 uport->regshift = old_shift;
834 uport->mapbase = old_mapbase; 839 uport->mapbase = old_mapbase;
835 retval = uport->ops->request_port(uport);
836 /*
837 * If we failed to restore the old settings,
838 * we fail like this.
839 */
840 if (retval)
841 uport->type = PORT_UNKNOWN;
842 840
843 /* 841 if (old_type != PORT_UNKNOWN) {
844 * We failed anyway. 842 retval = uport->ops->request_port(uport);
845 */ 843 /*
846 retval = -EBUSY; 844 * If we failed to restore the old settings,
845 * we fail like this.
846 */
847 if (retval)
848 uport->type = PORT_UNKNOWN;
849
850 /*
851 * We failed anyway.
852 */
853 retval = -EBUSY;
854 }
855
847 /* Added to return the correct error -Ram Gupta */ 856 /* Added to return the correct error -Ram Gupta */
848 goto exit; 857 goto exit;
849 } 858 }
@@ -1571,12 +1580,6 @@ static int uart_open(struct tty_struct *tty, struct file *filp)
1571 } 1580 }
1572 1581
1573 /* 1582 /*
1574 * Make sure the device is in D0 state.
1575 */
1576 if (port->count == 1)
1577 uart_change_pm(state, UART_PM_STATE_ON);
1578
1579 /*
1580 * Start up the serial port. 1583 * Start up the serial port.
1581 */ 1584 */
1582 retval = uart_startup(tty, state, 0); 1585 retval = uart_startup(tty, state, 0);
diff --git a/drivers/tty/tty_buffer.c b/drivers/tty/tty_buffer.c
index 8ebd9f88a6f6..cf78d1985cd8 100644
--- a/drivers/tty/tty_buffer.c
+++ b/drivers/tty/tty_buffer.c
@@ -258,7 +258,11 @@ static int __tty_buffer_request_room(struct tty_port *port, size_t size,
258 n->flags = flags; 258 n->flags = flags;
259 buf->tail = n; 259 buf->tail = n;
260 b->commit = b->used; 260 b->commit = b->used;
261 smp_mb(); 261 /* paired w/ barrier in flush_to_ldisc(); ensures the
262 * latest commit value can be read before the head is
263 * advanced to the next buffer
264 */
265 smp_wmb();
262 b->next = n; 266 b->next = n;
263 } else if (change) 267 } else if (change)
264 size = 0; 268 size = 0;
@@ -444,17 +448,24 @@ static void flush_to_ldisc(struct work_struct *work)
444 448
445 while (1) { 449 while (1) {
446 struct tty_buffer *head = buf->head; 450 struct tty_buffer *head = buf->head;
451 struct tty_buffer *next;
447 int count; 452 int count;
448 453
449 /* Ldisc or user is trying to gain exclusive access */ 454 /* Ldisc or user is trying to gain exclusive access */
450 if (atomic_read(&buf->priority)) 455 if (atomic_read(&buf->priority))
451 break; 456 break;
452 457
458 next = head->next;
459 /* paired w/ barrier in __tty_buffer_request_room();
460 * ensures commit value read is not stale if the head
461 * is advancing to the next buffer
462 */
463 smp_rmb();
453 count = head->commit - head->read; 464 count = head->commit - head->read;
454 if (!count) { 465 if (!count) {
455 if (head->next == NULL) 466 if (next == NULL)
456 break; 467 break;
457 buf->head = head->next; 468 buf->head = next;
458 tty_buffer_free(port, head); 469 tty_buffer_free(port, head);
459 continue; 470 continue;
460 } 471 }