| .. | .. |
|---|
| 7 | 7 | * Copyright (c) 2011, Code Aurora Forum. All rights reserved. |
|---|
| 8 | 8 | */ |
|---|
| 9 | 9 | |
|---|
| 10 | | -#if defined(CONFIG_SERIAL_MSM_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) |
|---|
| 11 | | -# define SUPPORT_SYSRQ |
|---|
| 12 | | -#endif |
|---|
| 13 | | - |
|---|
| 14 | 10 | #include <linux/kernel.h> |
|---|
| 15 | 11 | #include <linux/atomic.h> |
|---|
| 16 | 12 | #include <linux/dma-mapping.h> |
|---|
| .. | .. |
|---|
| 301 | 297 | dma = &msm_port->tx_dma; |
|---|
| 302 | 298 | |
|---|
| 303 | 299 | /* allocate DMA resources, if available */ |
|---|
| 304 | | - dma->chan = dma_request_slave_channel_reason(dev, "tx"); |
|---|
| 300 | + dma->chan = dma_request_chan(dev, "tx"); |
|---|
| 305 | 301 | if (IS_ERR(dma->chan)) |
|---|
| 306 | 302 | goto no_tx; |
|---|
| 307 | 303 | |
|---|
| .. | .. |
|---|
| 344 | 340 | dma = &msm_port->rx_dma; |
|---|
| 345 | 341 | |
|---|
| 346 | 342 | /* allocate DMA resources, if available */ |
|---|
| 347 | | - dma->chan = dma_request_slave_channel_reason(dev, "rx"); |
|---|
| 343 | + dma->chan = dma_request_chan(dev, "rx"); |
|---|
| 348 | 344 | if (IS_ERR(dma->chan)) |
|---|
| 349 | 345 | goto no_rx; |
|---|
| 350 | 346 | |
|---|
| .. | .. |
|---|
| 613 | 609 | UARTDM_RX_SIZE, dma->dir); |
|---|
| 614 | 610 | ret = dma_mapping_error(uart->dev, dma->phys); |
|---|
| 615 | 611 | if (ret) |
|---|
| 616 | | - return; |
|---|
| 612 | + goto sw_mode; |
|---|
| 617 | 613 | |
|---|
| 618 | 614 | dma->desc = dmaengine_prep_slave_single(dma->chan, dma->phys, |
|---|
| 619 | 615 | UARTDM_RX_SIZE, DMA_DEV_TO_MEM, |
|---|
| .. | .. |
|---|
| 664 | 660 | return; |
|---|
| 665 | 661 | unmap: |
|---|
| 666 | 662 | dma_unmap_single(uart->dev, dma->phys, UARTDM_RX_SIZE, dma->dir); |
|---|
| 663 | + |
|---|
| 664 | +sw_mode: |
|---|
| 665 | + /* |
|---|
| 666 | + * Switch from DMA to SW/FIFO mode. After clearing Rx BAM (UARTDM_DMEN), |
|---|
| 667 | + * receiver must be reset. |
|---|
| 668 | + */ |
|---|
| 669 | + msm_write(uart, UART_CR_CMD_RESET_RX, UART_CR); |
|---|
| 670 | + msm_write(uart, UART_CR_RX_ENABLE, UART_CR); |
|---|
| 671 | + |
|---|
| 672 | + msm_write(uart, UART_CR_CMD_RESET_STALE_INT, UART_CR); |
|---|
| 673 | + msm_write(uart, 0xFFFFFF, UARTDM_DMRX); |
|---|
| 674 | + msm_write(uart, UART_CR_CMD_STALE_EVENT_ENABLE, UART_CR); |
|---|
| 675 | + |
|---|
| 676 | + /* Re-enable RX interrupts */ |
|---|
| 677 | + msm_port->imr |= (UART_IMR_RXLEV | UART_IMR_RXSTALE); |
|---|
| 678 | + msm_write(uart, msm_port->imr, UART_IMR); |
|---|
| 667 | 679 | } |
|---|
| 668 | 680 | |
|---|
| 669 | 681 | static void msm_stop_rx(struct uart_port *port) |
|---|
| .. | .. |
|---|
| 687 | 699 | } |
|---|
| 688 | 700 | |
|---|
| 689 | 701 | static void msm_handle_rx_dm(struct uart_port *port, unsigned int misr) |
|---|
| 702 | + __must_hold(&port->lock) |
|---|
| 690 | 703 | { |
|---|
| 691 | 704 | struct tty_port *tport = &port->state->port; |
|---|
| 692 | 705 | unsigned int sr; |
|---|
| .. | .. |
|---|
| 762 | 775 | } |
|---|
| 763 | 776 | |
|---|
| 764 | 777 | static void msm_handle_rx(struct uart_port *port) |
|---|
| 778 | + __must_hold(&port->lock) |
|---|
| 765 | 779 | { |
|---|
| 766 | 780 | struct tty_port *tport = &port->state->port; |
|---|
| 767 | 781 | unsigned int sr; |
|---|
| .. | .. |
|---|
| 1579 | 1593 | static void __msm_console_write(struct uart_port *port, const char *s, |
|---|
| 1580 | 1594 | unsigned int count, bool is_uartdm) |
|---|
| 1581 | 1595 | { |
|---|
| 1596 | + unsigned long flags; |
|---|
| 1582 | 1597 | int i; |
|---|
| 1583 | 1598 | int num_newlines = 0; |
|---|
| 1584 | 1599 | bool replaced = false; |
|---|
| .. | .. |
|---|
| 1595 | 1610 | if (s[i] == '\n') |
|---|
| 1596 | 1611 | num_newlines++; |
|---|
| 1597 | 1612 | count += num_newlines; |
|---|
| 1613 | + |
|---|
| 1614 | + local_irq_save(flags); |
|---|
| 1598 | 1615 | |
|---|
| 1599 | 1616 | if (port->sysrq) |
|---|
| 1600 | 1617 | locked = 0; |
|---|
| .. | .. |
|---|
| 1641 | 1658 | |
|---|
| 1642 | 1659 | if (locked) |
|---|
| 1643 | 1660 | spin_unlock(&port->lock); |
|---|
| 1661 | + |
|---|
| 1662 | + local_irq_restore(flags); |
|---|
| 1644 | 1663 | } |
|---|
| 1645 | 1664 | |
|---|
| 1646 | 1665 | static void msm_console_write(struct console *co, const char *s, |
|---|
| .. | .. |
|---|
| 1657 | 1676 | __msm_console_write(port, s, count, msm_port->is_uartdm); |
|---|
| 1658 | 1677 | } |
|---|
| 1659 | 1678 | |
|---|
| 1660 | | -static int __init msm_console_setup(struct console *co, char *options) |
|---|
| 1679 | +static int msm_console_setup(struct console *co, char *options) |
|---|
| 1661 | 1680 | { |
|---|
| 1662 | 1681 | struct uart_port *port; |
|---|
| 1663 | 1682 | int baud = 115200; |
|---|
| .. | .. |
|---|
| 1813 | 1832 | if (unlikely(irq < 0)) |
|---|
| 1814 | 1833 | return -ENXIO; |
|---|
| 1815 | 1834 | port->irq = irq; |
|---|
| 1835 | + port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_MSM_CONSOLE); |
|---|
| 1816 | 1836 | |
|---|
| 1817 | 1837 | platform_set_drvdata(pdev, port); |
|---|
| 1818 | 1838 | |
|---|