diff options
Diffstat (limited to 'drivers/tty')
| -rw-r--r-- | drivers/tty/goldfish.c | 32 | ||||
| -rw-r--r-- | drivers/tty/n_gsm.c | 17 | ||||
| -rw-r--r-- | drivers/tty/serial/8250/8250_omap.c | 4 | ||||
| -rw-r--r-- | drivers/tty/serial/sccnxp.c | 15 | ||||
| -rw-r--r-- | drivers/tty/serial/sh-sci.c | 16 |
5 files changed, 58 insertions, 26 deletions
diff --git a/drivers/tty/goldfish.c b/drivers/tty/goldfish.c index dc5c0e6cdb84..4686e93aaf94 100644 --- a/drivers/tty/goldfish.c +++ b/drivers/tty/goldfish.c @@ -87,32 +87,35 @@ static void do_rw_io(struct goldfish_tty *qtty, } static void goldfish_tty_rw(struct goldfish_tty *qtty, - unsigned long addr, + const void *address_ptr, unsigned int count, int is_write) { dma_addr_t dma_handle; enum dma_data_direction dma_dir; + uintptr_t address; + address = (uintptr_t)address_ptr; dma_dir = (is_write ? DMA_TO_DEVICE : DMA_FROM_DEVICE); + if (qtty->version > 0) { /* * Goldfish TTY for Ranchu platform uses * physical addresses and DMA for read/write operations */ - unsigned long addr_end = addr + count; + uintptr_t address_end = address + count; - while (addr < addr_end) { - unsigned long pg_end = (addr & PAGE_MASK) + PAGE_SIZE; - unsigned long next = - pg_end < addr_end ? pg_end : addr_end; - unsigned long avail = next - addr; + while (address < address_end) { + uintptr_t page_end = (address & PAGE_MASK) + PAGE_SIZE; + uintptr_t next = page_end < address_end ? + page_end : address_end; + uintptr_t avail = next - address; /* * Map the buffer's virtual address to the DMA address * so the buffer can be accessed by the device. */ - dma_handle = dma_map_single(qtty->dev, (void *)addr, + dma_handle = dma_map_single(qtty->dev, (void *)address, avail, dma_dir); if (dma_mapping_error(qtty->dev, dma_handle)) { @@ -127,31 +130,30 @@ static void goldfish_tty_rw(struct goldfish_tty *qtty, */ dma_unmap_single(qtty->dev, dma_handle, avail, dma_dir); - addr += avail; + address += avail; } } else { /* * Old style Goldfish TTY used on the Goldfish platform * uses virtual addresses. */ - do_rw_io(qtty, addr, count, is_write); + do_rw_io(qtty, address, count, is_write); } + } static void goldfish_tty_do_write(int line, const char *buf, unsigned int count) { struct goldfish_tty *qtty = &goldfish_ttys[line]; - unsigned long address = (unsigned long)(void *)buf; - goldfish_tty_rw(qtty, address, count, 1); + goldfish_tty_rw(qtty, buf, count, 1); } static irqreturn_t goldfish_tty_interrupt(int irq, void *dev_id) { struct goldfish_tty *qtty = dev_id; void __iomem *base = qtty->base; - unsigned long address; unsigned char *buf; u32 count; @@ -160,9 +162,7 @@ static irqreturn_t goldfish_tty_interrupt(int irq, void *dev_id) return IRQ_NONE; count = tty_prepare_flip_string(&qtty->port, &buf, count); - - address = (unsigned long)(void *)buf; - goldfish_tty_rw(qtty, address, count, 0); + goldfish_tty_rw(qtty, buf, count, 0); tty_schedule_flip(&qtty->port); return IRQ_HANDLED; diff --git a/drivers/tty/n_gsm.c b/drivers/tty/n_gsm.c index 9aff37186246..78bd121ecede 100644 --- a/drivers/tty/n_gsm.c +++ b/drivers/tty/n_gsm.c @@ -1467,6 +1467,10 @@ static void gsm_dlci_open(struct gsm_dlci *dlci) * in which case an opening port goes back to closed and a closing port * is simply put into closed state (any further frames from the other * end will get a DM response) + * + * Some control dlci can stay in ADM mode with other dlci working just + * fine. In that case we can just keep the control dlci open after the + * DLCI_OPENING retries time out. */ static void gsm_dlci_t1(unsigned long data) @@ -1480,8 +1484,15 @@ static void gsm_dlci_t1(unsigned long data) if (dlci->retries) { gsm_command(dlci->gsm, dlci->addr, SABM|PF); mod_timer(&dlci->t1, jiffies + gsm->t1 * HZ / 100); - } else + } else if (!dlci->addr && gsm->control == (DM | PF)) { + if (debug & 8) + pr_info("DLCI %d opening in ADM mode.\n", + dlci->addr); + gsm_dlci_open(dlci); + } else { gsm_dlci_close(dlci); + } + break; case DLCI_CLOSING: dlci->retries--; @@ -1499,8 +1510,8 @@ static void gsm_dlci_t1(unsigned long data) * @dlci: DLCI to open * * Commence opening a DLCI from the Linux side. We issue SABM messages - * to the modem which should then reply with a UA, at which point we - * will move into open state. Opening is done asynchronously with retry + * to the modem which should then reply with a UA or ADM, at which point + * we will move into open state. Opening is done asynchronously with retry * running off timers and the responses. */ diff --git a/drivers/tty/serial/8250/8250_omap.c b/drivers/tty/serial/8250/8250_omap.c index e8dd296fb25b..c4383573cf66 100644 --- a/drivers/tty/serial/8250/8250_omap.c +++ b/drivers/tty/serial/8250/8250_omap.c @@ -608,6 +608,10 @@ static int omap_8250_startup(struct uart_port *port) up->lsr_saved_flags = 0; up->msr_saved_flags = 0; + /* Disable DMA for console UART */ + if (uart_console(port)) + up->dma = NULL; + if (up->dma) { ret = serial8250_request_dma(up); if (ret) { diff --git a/drivers/tty/serial/sccnxp.c b/drivers/tty/serial/sccnxp.c index fcf803ffad19..cdd2f942317c 100644 --- a/drivers/tty/serial/sccnxp.c +++ b/drivers/tty/serial/sccnxp.c @@ -884,14 +884,19 @@ static int sccnxp_probe(struct platform_device *pdev) clk = devm_clk_get(&pdev->dev, NULL); if (IS_ERR(clk)) { - if (PTR_ERR(clk) == -EPROBE_DEFER) { - ret = -EPROBE_DEFER; + ret = PTR_ERR(clk); + if (ret == -EPROBE_DEFER) goto err_out; - } + uartclk = 0; + } else { + clk_prepare_enable(clk); + uartclk = clk_get_rate(clk); + } + + if (!uartclk) { dev_notice(&pdev->dev, "Using default clock frequency\n"); uartclk = s->chip->freq_std; - } else - uartclk = clk_get_rate(clk); + } /* Check input frequency */ if ((uartclk < s->chip->freq_min) || (uartclk > s->chip->freq_max)) { diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index fc7711c75b01..8dd822feb972 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -1457,7 +1457,16 @@ static void sci_free_dma(struct uart_port *port) if (s->chan_rx) sci_rx_dma_release(s, false); } -#else + +static void sci_flush_buffer(struct uart_port *port) +{ + /* + * In uart_flush_buffer(), the xmit circular buffer has just been + * cleared, so we have to reset tx_dma_len accordingly. + */ + to_sci_port(port)->tx_dma_len = 0; +} +#else /* !CONFIG_SERIAL_SH_SCI_DMA */ static inline void sci_request_dma(struct uart_port *port) { } @@ -1465,7 +1474,9 @@ static inline void sci_request_dma(struct uart_port *port) static inline void sci_free_dma(struct uart_port *port) { } -#endif + +#define sci_flush_buffer NULL +#endif /* !CONFIG_SERIAL_SH_SCI_DMA */ static irqreturn_t sci_rx_interrupt(int irq, void *ptr) { @@ -2205,6 +2216,7 @@ static struct uart_ops sci_uart_ops = { .break_ctl = sci_break_ctl, .startup = sci_startup, .shutdown = sci_shutdown, + .flush_buffer = sci_flush_buffer, .set_termios = sci_set_termios, .pm = sci_pm, .type = sci_type, |
