diff options
Diffstat (limited to 'drivers/tty/serial')
-rw-r--r-- | drivers/tty/serial/8250/8250_core.c | 4 | ||||
-rw-r--r-- | drivers/tty/serial/8250/8250_dma.c | 9 | ||||
-rw-r--r-- | drivers/tty/serial/Kconfig | 1 | ||||
-rw-r--r-- | drivers/tty/serial/amba-pl011.c | 8 | ||||
-rw-r--r-- | drivers/tty/serial/clps711x.c | 20 | ||||
-rw-r--r-- | drivers/tty/serial/efm32-uart.c | 3 | ||||
-rw-r--r-- | drivers/tty/serial/omap-serial.c | 30 | ||||
-rw-r--r-- | drivers/tty/serial/samsung.c | 23 | ||||
-rw-r--r-- | drivers/tty/serial/serial_core.c | 44 | ||||
-rw-r--r-- | drivers/tty/serial/st-asc.c | 4 |
10 files changed, 81 insertions, 65 deletions
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 | ||
40 | static void __dma_rx_complete(void *param) | 45 | static void __dma_rx_complete(void *param) |
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig index 2e6d8ddc4425..5d9b01aa54f4 100644 --- a/drivers/tty/serial/Kconfig +++ b/drivers/tty/serial/Kconfig | |||
@@ -1226,6 +1226,7 @@ config SERIAL_BFIN_SPORT3_UART_CTSRTS | |||
1226 | config SERIAL_TIMBERDALE | 1226 | config SERIAL_TIMBERDALE |
1227 | tristate "Support for timberdale UART" | 1227 | tristate "Support for timberdale UART" |
1228 | select SERIAL_CORE | 1228 | select SERIAL_CORE |
1229 | depends on X86_32 || COMPILE_TEST | ||
1229 | ---help--- | 1230 | ---help--- |
1230 | Add support for UART controller on timberdale. | 1231 | Add support for UART controller on timberdale. |
1231 | 1232 | ||
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c index d4eda24aa68b..dacf0a09ab24 100644 --- a/drivers/tty/serial/amba-pl011.c +++ b/drivers/tty/serial/amba-pl011.c | |||
@@ -318,7 +318,7 @@ static void pl011_dma_probe_initcall(struct device *dev, struct uart_amba_port * | |||
318 | .src_addr = uap->port.mapbase + UART01x_DR, | 318 | .src_addr = uap->port.mapbase + UART01x_DR, |
319 | .src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE, | 319 | .src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE, |
320 | .direction = DMA_DEV_TO_MEM, | 320 | .direction = DMA_DEV_TO_MEM, |
321 | .src_maxburst = uap->fifosize >> 1, | 321 | .src_maxburst = uap->fifosize >> 2, |
322 | .device_fc = false, | 322 | .device_fc = false, |
323 | }; | 323 | }; |
324 | 324 | ||
@@ -2176,6 +2176,7 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id) | |||
2176 | static int pl011_remove(struct amba_device *dev) | 2176 | static int pl011_remove(struct amba_device *dev) |
2177 | { | 2177 | { |
2178 | struct uart_amba_port *uap = amba_get_drvdata(dev); | 2178 | struct uart_amba_port *uap = amba_get_drvdata(dev); |
2179 | bool busy = false; | ||
2179 | int i; | 2180 | int i; |
2180 | 2181 | ||
2181 | uart_remove_one_port(&amba_reg, &uap->port); | 2182 | uart_remove_one_port(&amba_reg, &uap->port); |
@@ -2183,9 +2184,12 @@ static int pl011_remove(struct amba_device *dev) | |||
2183 | for (i = 0; i < ARRAY_SIZE(amba_ports); i++) | 2184 | for (i = 0; i < ARRAY_SIZE(amba_ports); i++) |
2184 | if (amba_ports[i] == uap) | 2185 | if (amba_ports[i] == uap) |
2185 | amba_ports[i] = NULL; | 2186 | amba_ports[i] = NULL; |
2187 | else if (amba_ports[i]) | ||
2188 | busy = true; | ||
2186 | 2189 | ||
2187 | pl011_dma_remove(uap); | 2190 | pl011_dma_remove(uap); |
2188 | uart_unregister_driver(&amba_reg); | 2191 | if (!busy) |
2192 | uart_unregister_driver(&amba_reg); | ||
2189 | return 0; | 2193 | return 0; |
2190 | } | 2194 | } |
2191 | 2195 | ||
diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c index 5e6fdb1ea73b..14aaea0d4131 100644 --- a/drivers/tty/serial/clps711x.c +++ b/drivers/tty/serial/clps711x.c | |||
@@ -368,16 +368,12 @@ static const struct uart_ops uart_clps711x_ops = { | |||
368 | static void uart_clps711x_console_putchar(struct uart_port *port, int ch) | 368 | static void uart_clps711x_console_putchar(struct uart_port *port, int ch) |
369 | { | 369 | { |
370 | struct clps711x_port *s = dev_get_drvdata(port->dev); | 370 | struct clps711x_port *s = dev_get_drvdata(port->dev); |
371 | u32 sysflg = 0; | ||
371 | 372 | ||
372 | /* Wait for FIFO is not full */ | 373 | /* Wait for FIFO is not full */ |
373 | while (1) { | 374 | do { |
374 | u32 sysflg = 0; | ||
375 | |||
376 | regmap_read(s->syscon, SYSFLG_OFFSET, &sysflg); | 375 | regmap_read(s->syscon, SYSFLG_OFFSET, &sysflg); |
377 | if (!(sysflg & SYSFLG_UTXFF)) | 376 | } while (sysflg & SYSFLG_UTXFF); |
378 | break; | ||
379 | cond_resched(); | ||
380 | } | ||
381 | 377 | ||
382 | writew(ch, port->membase + UARTDR_OFFSET); | 378 | writew(ch, port->membase + UARTDR_OFFSET); |
383 | } | 379 | } |
@@ -387,18 +383,14 @@ static void uart_clps711x_console_write(struct console *co, const char *c, | |||
387 | { | 383 | { |
388 | struct uart_port *port = clps711x_uart.state[co->index].uart_port; | 384 | struct uart_port *port = clps711x_uart.state[co->index].uart_port; |
389 | struct clps711x_port *s = dev_get_drvdata(port->dev); | 385 | struct clps711x_port *s = dev_get_drvdata(port->dev); |
386 | u32 sysflg = 0; | ||
390 | 387 | ||
391 | uart_console_write(port, c, n, uart_clps711x_console_putchar); | 388 | uart_console_write(port, c, n, uart_clps711x_console_putchar); |
392 | 389 | ||
393 | /* Wait for transmitter to become empty */ | 390 | /* Wait for transmitter to become empty */ |
394 | while (1) { | 391 | do { |
395 | u32 sysflg = 0; | ||
396 | |||
397 | regmap_read(s->syscon, SYSFLG_OFFSET, &sysflg); | 392 | regmap_read(s->syscon, SYSFLG_OFFSET, &sysflg); |
398 | if (!(sysflg & SYSFLG_UBUSY)) | 393 | } while (sysflg & SYSFLG_UBUSY); |
399 | break; | ||
400 | cond_resched(); | ||
401 | } | ||
402 | } | 394 | } |
403 | 395 | ||
404 | static int uart_clps711x_console_setup(struct console *co, char *options) | 396 | static int uart_clps711x_console_setup(struct console *co, char *options) |
diff --git a/drivers/tty/serial/efm32-uart.c b/drivers/tty/serial/efm32-uart.c index 028582e924a5..c167a710dc39 100644 --- a/drivers/tty/serial/efm32-uart.c +++ b/drivers/tty/serial/efm32-uart.c | |||
@@ -798,6 +798,9 @@ static int efm32_uart_remove(struct platform_device *pdev) | |||
798 | 798 | ||
799 | static const struct of_device_id efm32_uart_dt_ids[] = { | 799 | static const struct of_device_id efm32_uart_dt_ids[] = { |
800 | { | 800 | { |
801 | .compatible = "energymicro,efm32-uart", | ||
802 | }, { | ||
803 | /* doesn't follow the "vendor,device" scheme, don't use */ | ||
801 | .compatible = "efm32,uart", | 804 | .compatible = "efm32,uart", |
802 | }, { | 805 | }, { |
803 | /* sentinel */ | 806 | /* sentinel */ |
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c index dd8b1a5458ff..08b6b9419f0d 100644 --- a/drivers/tty/serial/omap-serial.c +++ b/drivers/tty/serial/omap-serial.c | |||
@@ -225,14 +225,19 @@ static inline void serial_omap_enable_wakeirq(struct uart_omap_port *up, | |||
225 | if (enable) | 225 | if (enable) |
226 | enable_irq(up->wakeirq); | 226 | enable_irq(up->wakeirq); |
227 | else | 227 | else |
228 | disable_irq(up->wakeirq); | 228 | disable_irq_nosync(up->wakeirq); |
229 | } | 229 | } |
230 | 230 | ||
231 | static void serial_omap_enable_wakeup(struct uart_omap_port *up, bool enable) | 231 | static void serial_omap_enable_wakeup(struct uart_omap_port *up, bool enable) |
232 | { | 232 | { |
233 | struct omap_uart_port_info *pdata = dev_get_platdata(up->dev); | 233 | struct omap_uart_port_info *pdata = dev_get_platdata(up->dev); |
234 | 234 | ||
235 | if (enable == up->wakeups_enabled) | ||
236 | return; | ||
237 | |||
235 | serial_omap_enable_wakeirq(up, enable); | 238 | serial_omap_enable_wakeirq(up, enable); |
239 | up->wakeups_enabled = enable; | ||
240 | |||
236 | if (!pdata || !pdata->enable_wakeup) | 241 | if (!pdata || !pdata->enable_wakeup) |
237 | return; | 242 | return; |
238 | 243 | ||
@@ -1495,6 +1500,11 @@ static int serial_omap_suspend(struct device *dev) | |||
1495 | uart_suspend_port(&serial_omap_reg, &up->port); | 1500 | uart_suspend_port(&serial_omap_reg, &up->port); |
1496 | flush_work(&up->qos_work); | 1501 | flush_work(&up->qos_work); |
1497 | 1502 | ||
1503 | if (device_may_wakeup(dev)) | ||
1504 | serial_omap_enable_wakeup(up, true); | ||
1505 | else | ||
1506 | serial_omap_enable_wakeup(up, false); | ||
1507 | |||
1498 | return 0; | 1508 | return 0; |
1499 | } | 1509 | } |
1500 | 1510 | ||
@@ -1502,6 +1512,9 @@ static int serial_omap_resume(struct device *dev) | |||
1502 | { | 1512 | { |
1503 | struct uart_omap_port *up = dev_get_drvdata(dev); | 1513 | struct uart_omap_port *up = dev_get_drvdata(dev); |
1504 | 1514 | ||
1515 | if (device_may_wakeup(dev)) | ||
1516 | serial_omap_enable_wakeup(up, false); | ||
1517 | |||
1505 | uart_resume_port(&serial_omap_reg, &up->port); | 1518 | uart_resume_port(&serial_omap_reg, &up->port); |
1506 | 1519 | ||
1507 | return 0; | 1520 | return 0; |
@@ -1789,6 +1802,7 @@ static int serial_omap_remove(struct platform_device *dev) | |||
1789 | pm_runtime_disable(up->dev); | 1802 | pm_runtime_disable(up->dev); |
1790 | uart_remove_one_port(&serial_omap_reg, &up->port); | 1803 | uart_remove_one_port(&serial_omap_reg, &up->port); |
1791 | pm_qos_remove_request(&up->pm_qos_request); | 1804 | pm_qos_remove_request(&up->pm_qos_request); |
1805 | device_init_wakeup(&dev->dev, false); | ||
1792 | 1806 | ||
1793 | return 0; | 1807 | return 0; |
1794 | } | 1808 | } |
@@ -1877,17 +1891,7 @@ static int serial_omap_runtime_suspend(struct device *dev) | |||
1877 | 1891 | ||
1878 | up->context_loss_cnt = serial_omap_get_context_loss_count(up); | 1892 | up->context_loss_cnt = serial_omap_get_context_loss_count(up); |
1879 | 1893 | ||
1880 | if (device_may_wakeup(dev)) { | 1894 | serial_omap_enable_wakeup(up, true); |
1881 | if (!up->wakeups_enabled) { | ||
1882 | serial_omap_enable_wakeup(up, true); | ||
1883 | up->wakeups_enabled = true; | ||
1884 | } | ||
1885 | } else { | ||
1886 | if (up->wakeups_enabled) { | ||
1887 | serial_omap_enable_wakeup(up, false); | ||
1888 | up->wakeups_enabled = false; | ||
1889 | } | ||
1890 | } | ||
1891 | 1895 | ||
1892 | up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; | 1896 | up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE; |
1893 | schedule_work(&up->qos_work); | 1897 | schedule_work(&up->qos_work); |
@@ -1901,6 +1905,8 @@ static int serial_omap_runtime_resume(struct device *dev) | |||
1901 | 1905 | ||
1902 | int loss_cnt = serial_omap_get_context_loss_count(up); | 1906 | int loss_cnt = serial_omap_get_context_loss_count(up); |
1903 | 1907 | ||
1908 | serial_omap_enable_wakeup(up, false); | ||
1909 | |||
1904 | if (loss_cnt < 0) { | 1910 | if (loss_cnt < 0) { |
1905 | dev_dbg(dev, "serial_omap_get_context_loss_count failed : %d\n", | 1911 | dev_dbg(dev, "serial_omap_get_context_loss_count failed : %d\n", |
1906 | loss_cnt); | 1912 | loss_cnt); |
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) | |||
1446 | static void s3c24xx_serial_put_poll_char(struct uart_port *port, | 1446 | static 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, | |||
1463 | static void | 1463 | static void |
1464 | s3c24xx_serial_console_putchar(struct uart_port *port, int ch) | 1464 | s3c24xx_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 | ||
1478 | static void | 1473 | static void |
1479 | s3c24xx_serial_console_write(struct console *co, const char *s, | 1474 | s3c24xx_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 2cf5649a6dc0..b68550d95a40 100644 --- a/drivers/tty/serial/serial_core.c +++ b/drivers/tty/serial/serial_core.c | |||
@@ -89,8 +89,7 @@ static void __uart_start(struct tty_struct *tty) | |||
89 | struct uart_state *state = tty->driver_data; | 89 | struct uart_state *state = tty->driver_data; |
90 | struct uart_port *port = state->uart_port; | 90 | struct uart_port *port = state->uart_port; |
91 | 91 | ||
92 | if (!uart_circ_empty(&state->xmit) && state->xmit.buf && | 92 | if (!tty->stopped && !tty->hw_stopped) |
93 | !tty->stopped && !tty->hw_stopped) | ||
94 | port->ops->start_tx(port); | 93 | port->ops->start_tx(port); |
95 | } | 94 | } |
96 | 95 | ||
@@ -138,6 +137,11 @@ static int uart_port_startup(struct tty_struct *tty, struct uart_state *state, | |||
138 | return 1; | 137 | return 1; |
139 | 138 | ||
140 | /* | 139 | /* |
140 | * Make sure the device is in D0 state. | ||
141 | */ | ||
142 | uart_change_pm(state, UART_PM_STATE_ON); | ||
143 | |||
144 | /* | ||
141 | * Initialise and allocate the transmit and temporary | 145 | * Initialise and allocate the transmit and temporary |
142 | * buffer. | 146 | * buffer. |
143 | */ | 147 | */ |
@@ -826,25 +830,29 @@ static int uart_set_info(struct tty_struct *tty, struct tty_port *port, | |||
826 | * If we fail to request resources for the | 830 | * If we fail to request resources for the |
827 | * new port, try to restore the old settings. | 831 | * new port, try to restore the old settings. |
828 | */ | 832 | */ |
829 | if (retval && old_type != PORT_UNKNOWN) { | 833 | if (retval) { |
830 | uport->iobase = old_iobase; | 834 | uport->iobase = old_iobase; |
831 | uport->type = old_type; | 835 | uport->type = old_type; |
832 | uport->hub6 = old_hub6; | 836 | uport->hub6 = old_hub6; |
833 | uport->iotype = old_iotype; | 837 | uport->iotype = old_iotype; |
834 | uport->regshift = old_shift; | 838 | uport->regshift = old_shift; |
835 | uport->mapbase = old_mapbase; | 839 | uport->mapbase = old_mapbase; |
836 | retval = uport->ops->request_port(uport); | ||
837 | /* | ||
838 | * If we failed to restore the old settings, | ||
839 | * we fail like this. | ||
840 | */ | ||
841 | if (retval) | ||
842 | uport->type = PORT_UNKNOWN; | ||
843 | 840 | ||
844 | /* | 841 | if (old_type != PORT_UNKNOWN) { |
845 | * We failed anyway. | 842 | retval = uport->ops->request_port(uport); |
846 | */ | 843 | /* |
847 | 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 | |||
848 | /* Added to return the correct error -Ram Gupta */ | 856 | /* Added to return the correct error -Ram Gupta */ |
849 | goto exit; | 857 | goto exit; |
850 | } | 858 | } |
@@ -1452,6 +1460,8 @@ static void uart_hangup(struct tty_struct *tty) | |||
1452 | clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags); | 1460 | clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags); |
1453 | spin_unlock_irqrestore(&port->lock, flags); | 1461 | spin_unlock_irqrestore(&port->lock, flags); |
1454 | tty_port_tty_set(port, NULL); | 1462 | tty_port_tty_set(port, NULL); |
1463 | if (!uart_console(state->uart_port)) | ||
1464 | uart_change_pm(state, UART_PM_STATE_OFF); | ||
1455 | wake_up_interruptible(&port->open_wait); | 1465 | wake_up_interruptible(&port->open_wait); |
1456 | wake_up_interruptible(&port->delta_msr_wait); | 1466 | wake_up_interruptible(&port->delta_msr_wait); |
1457 | } | 1467 | } |
@@ -1570,12 +1580,6 @@ static int uart_open(struct tty_struct *tty, struct file *filp) | |||
1570 | } | 1580 | } |
1571 | 1581 | ||
1572 | /* | 1582 | /* |
1573 | * Make sure the device is in D0 state. | ||
1574 | */ | ||
1575 | if (port->count == 1) | ||
1576 | uart_change_pm(state, UART_PM_STATE_ON); | ||
1577 | |||
1578 | /* | ||
1579 | * Start up the serial port. | 1583 | * Start up the serial port. |
1580 | */ | 1584 | */ |
1581 | retval = uart_startup(tty, state, 0); | 1585 | retval = uart_startup(tty, state, 0); |
diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c index 21e6e84c0df8..dd3a96e07026 100644 --- a/drivers/tty/serial/st-asc.c +++ b/drivers/tty/serial/st-asc.c | |||
@@ -295,7 +295,7 @@ static void asc_receive_chars(struct uart_port *port) | |||
295 | status & ASC_STA_OE) { | 295 | status & ASC_STA_OE) { |
296 | 296 | ||
297 | if (c & ASC_RXBUF_FE) { | 297 | if (c & ASC_RXBUF_FE) { |
298 | if (c == ASC_RXBUF_FE) { | 298 | if (c == (ASC_RXBUF_FE | ASC_RXBUF_DUMMY_RX)) { |
299 | port->icount.brk++; | 299 | port->icount.brk++; |
300 | if (uart_handle_break(port)) | 300 | if (uart_handle_break(port)) |
301 | continue; | 301 | continue; |
@@ -325,7 +325,7 @@ static void asc_receive_chars(struct uart_port *port) | |||
325 | flag = TTY_FRAME; | 325 | flag = TTY_FRAME; |
326 | } | 326 | } |
327 | 327 | ||
328 | if (uart_handle_sysrq_char(port, c)) | 328 | if (uart_handle_sysrq_char(port, c & 0xff)) |
329 | continue; | 329 | continue; |
330 | 330 | ||
331 | uart_insert_char(port, c, ASC_RXBUF_DUMMY_OE, c & 0xff, flag); | 331 | uart_insert_char(port, c, ASC_RXBUF_DUMMY_OE, c & 0xff, flag); |