Merge tag 'v3.15-rc1' into patchwork
[firefly-linux-kernel-4.4.55.git] / drivers / tty / serial / sirfsoc_uart.c
index 49a2ffd101a7145ca1de4a7eccb72d56964037d0..68b0fd4b9a6a216b50c6a93c483b0a6a266e4c52 100644 (file)
@@ -24,7 +24,6 @@
 #include <linux/dmaengine.h>
 #include <linux/dma-direction.h>
 #include <linux/dma-mapping.h>
-#include <linux/sirfsoc_dma.h>
 #include <asm/irq.h>
 #include <asm/mach/irq.h>
 
@@ -173,7 +172,7 @@ static void sirfsoc_uart_stop_tx(struct uart_port *port)
        struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg;
        struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en;
 
-       if (IS_DMA_CHAN_VALID(sirfport->tx_dma_no)) {
+       if (sirfport->tx_dma_chan) {
                if (sirfport->tx_dma_state == TX_DMA_RUNNING) {
                        dmaengine_pause(sirfport->tx_dma_chan);
                        sirfport->tx_dma_state = TX_DMA_PAUSE;
@@ -288,7 +287,7 @@ static void sirfsoc_uart_start_tx(struct uart_port *port)
        struct sirfsoc_uart_port *sirfport = to_sirfport(port);
        struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg;
        struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en;
-       if (IS_DMA_CHAN_VALID(sirfport->tx_dma_no))
+       if (sirfport->tx_dma_chan)
                sirfsoc_uart_tx_with_dma(sirfport);
        else {
                sirfsoc_uart_pio_tx_chars(sirfport, 1);
@@ -310,7 +309,7 @@ static void sirfsoc_uart_stop_rx(struct uart_port *port)
        struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en;
 
        wr_regl(port, ureg->sirfsoc_rx_fifo_op, 0);
-       if (IS_DMA_CHAN_VALID(sirfport->rx_dma_no)) {
+       if (sirfport->rx_dma_chan) {
                if (!sirfport->is_marco)
                        wr_regl(port, ureg->sirfsoc_int_en_reg,
                                rd_regl(port, ureg->sirfsoc_int_en_reg) &
@@ -542,8 +541,10 @@ static void sirfsoc_rx_tmo_process_tl(unsigned long param)
        wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl,
                        rd_regl(port, ureg->sirfsoc_rx_dma_io_ctrl) |
                        SIRFUART_IO_MODE);
-       sirfsoc_uart_pio_rx_chars(port, 4 - sirfport->rx_io_count);
        spin_unlock_irqrestore(&sirfport->rx_lock, flags);
+       spin_lock(&port->lock);
+       sirfsoc_uart_pio_rx_chars(port, 4 - sirfport->rx_io_count);
+       spin_unlock(&port->lock);
        if (sirfport->rx_io_count == 4) {
                spin_lock_irqsave(&sirfport->rx_lock, flags);
                sirfport->rx_io_count = 0;
@@ -673,7 +674,7 @@ recv_char:
                uart_handle_cts_change(port, cts_status);
                wake_up_interruptible(&state->port.delta_msr_wait);
        }
-       if (IS_DMA_CHAN_VALID(sirfport->rx_dma_no)) {
+       if (sirfport->rx_dma_chan) {
                if (intr_status & uint_st->sirfsoc_rx_timeout)
                        sirfsoc_uart_handle_rx_tmo(sirfport);
                if (intr_status & uint_st->sirfsoc_rx_done)
@@ -684,7 +685,7 @@ recv_char:
                                        SIRFSOC_UART_IO_RX_MAX_CNT);
        }
        if (intr_status & uint_st->sirfsoc_txfifo_empty) {
-               if (IS_DMA_CHAN_VALID(sirfport->tx_dma_no))
+               if (sirfport->tx_dma_chan)
                        sirfsoc_uart_tx_with_dma(sirfport);
                else {
                        if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
@@ -776,7 +777,7 @@ static void sirfsoc_uart_start_rx(struct uart_port *port)
        wr_regl(port, ureg->sirfsoc_rx_fifo_op, SIRFUART_FIFO_RESET);
        wr_regl(port, ureg->sirfsoc_rx_fifo_op, 0);
        wr_regl(port, ureg->sirfsoc_rx_fifo_op, SIRFUART_FIFO_START);
-       if (IS_DMA_CHAN_VALID(sirfport->rx_dma_no))
+       if (sirfport->rx_dma_chan)
                sirfsoc_uart_start_next_rx_dma(port);
        else {
                if (!sirfport->is_marco)
@@ -1012,11 +1013,11 @@ static void sirfsoc_uart_set_termios(struct uart_port *port,
                        (sample_div_reg & SIRFSOC_USP_ASYNC_DIV2_MASK) <<
                        SIRFSOC_USP_ASYNC_DIV2_OFFSET);
        }
-       if (IS_DMA_CHAN_VALID(sirfport->tx_dma_no))
+       if (sirfport->tx_dma_chan)
                wr_regl(port, ureg->sirfsoc_tx_dma_io_ctrl, SIRFUART_DMA_MODE);
        else
                wr_regl(port, ureg->sirfsoc_tx_dma_io_ctrl, SIRFUART_IO_MODE);
-       if (IS_DMA_CHAN_VALID(sirfport->rx_dma_no))
+       if (sirfport->rx_dma_chan)
                wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, SIRFUART_DMA_MODE);
        else
                wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, SIRFUART_IO_MODE);
@@ -1047,93 +1048,6 @@ static void sirfsoc_uart_pm(struct uart_port *port, unsigned int state,
                clk_disable_unprepare(sirfport->clk);
 }
 
-static unsigned int sirfsoc_uart_init_tx_dma(struct uart_port *port)
-{
-       struct sirfsoc_uart_port *sirfport = to_sirfport(port);
-       dma_cap_mask_t dma_mask;
-       struct dma_slave_config tx_slv_cfg = {
-               .dst_maxburst = 2,
-       };
-
-       dma_cap_zero(dma_mask);
-       dma_cap_set(DMA_SLAVE, dma_mask);
-       sirfport->tx_dma_chan = dma_request_channel(dma_mask,
-               (dma_filter_fn)sirfsoc_dma_filter_id,
-               (void *)sirfport->tx_dma_no);
-       if (!sirfport->tx_dma_chan) {
-               dev_err(port->dev, "Uart Request Dma Channel Fail %d\n",
-                                       sirfport->tx_dma_no);
-               return  -EPROBE_DEFER;
-       }
-       dmaengine_slave_config(sirfport->tx_dma_chan, &tx_slv_cfg);
-
-       return 0;
-}
-
-static unsigned int sirfsoc_uart_init_rx_dma(struct uart_port *port)
-{
-       struct sirfsoc_uart_port *sirfport = to_sirfport(port);
-       dma_cap_mask_t dma_mask;
-       int ret;
-       int i, j;
-       struct dma_slave_config slv_cfg = {
-               .src_maxburst = 2,
-       };
-
-       dma_cap_zero(dma_mask);
-       dma_cap_set(DMA_SLAVE, dma_mask);
-       sirfport->rx_dma_chan = dma_request_channel(dma_mask,
-                                       (dma_filter_fn)sirfsoc_dma_filter_id,
-                                       (void *)sirfport->rx_dma_no);
-       if (!sirfport->rx_dma_chan) {
-               dev_err(port->dev, "Uart Request Dma Channel Fail %d\n",
-                               sirfport->rx_dma_no);
-               ret = -EPROBE_DEFER;
-               goto request_err;
-       }
-       for (i = 0; i < SIRFSOC_RX_LOOP_BUF_CNT; i++) {
-               sirfport->rx_dma_items[i].xmit.buf =
-                       dma_alloc_coherent(port->dev, SIRFSOC_RX_DMA_BUF_SIZE,
-                       &sirfport->rx_dma_items[i].dma_addr, GFP_KERNEL);
-               if (!sirfport->rx_dma_items[i].xmit.buf) {
-                       dev_err(port->dev, "Uart alloc bufa failed\n");
-                       ret = -ENOMEM;
-                       goto alloc_coherent_err;
-               }
-               sirfport->rx_dma_items[i].xmit.head =
-                       sirfport->rx_dma_items[i].xmit.tail = 0;
-       }
-       dmaengine_slave_config(sirfport->rx_dma_chan, &slv_cfg);
-
-       return 0;
-alloc_coherent_err:
-       for (j = 0; j < i; j++)
-               dma_free_coherent(port->dev, SIRFSOC_RX_DMA_BUF_SIZE,
-                               sirfport->rx_dma_items[j].xmit.buf,
-                               sirfport->rx_dma_items[j].dma_addr);
-       dma_release_channel(sirfport->rx_dma_chan);
-request_err:
-       return ret;
-}
-
-static void sirfsoc_uart_uninit_tx_dma(struct sirfsoc_uart_port *sirfport)
-{
-       dmaengine_terminate_all(sirfport->tx_dma_chan);
-       dma_release_channel(sirfport->tx_dma_chan);
-}
-
-static void sirfsoc_uart_uninit_rx_dma(struct sirfsoc_uart_port *sirfport)
-{
-       int i;
-       struct uart_port *port = &sirfport->port;
-       dmaengine_terminate_all(sirfport->rx_dma_chan);
-       dma_release_channel(sirfport->rx_dma_chan);
-       for (i = 0; i < SIRFSOC_RX_LOOP_BUF_CNT; i++)
-               dma_free_coherent(port->dev, SIRFSOC_RX_DMA_BUF_SIZE,
-                               sirfport->rx_dma_items[i].xmit.buf,
-                               sirfport->rx_dma_items[i].dma_addr);
-}
-
 static int sirfsoc_uart_startup(struct uart_port *port)
 {
        struct sirfsoc_uart_port *sirfport      = to_sirfport(port);
@@ -1172,18 +1086,12 @@ static int sirfsoc_uart_startup(struct uart_port *port)
        wr_regl(port, ureg->sirfsoc_rx_fifo_op, 0);
        wr_regl(port, ureg->sirfsoc_tx_fifo_ctrl, SIRFUART_FIFO_THD(port));
        wr_regl(port, ureg->sirfsoc_rx_fifo_ctrl, SIRFUART_FIFO_THD(port));
-
-       if (IS_DMA_CHAN_VALID(sirfport->rx_dma_no)) {
-               ret = sirfsoc_uart_init_rx_dma(port);
-               if (ret)
-                       goto init_rx_err;
+       if (sirfport->rx_dma_chan)
                wr_regl(port, ureg->sirfsoc_rx_fifo_level_chk,
-                               SIRFUART_RX_FIFO_CHK_SC(port->line, 0x4) |
-                               SIRFUART_RX_FIFO_CHK_LC(port->line, 0xe) |
-                               SIRFUART_RX_FIFO_CHK_HC(port->line, 0x1b));
-       }
-       if (IS_DMA_CHAN_VALID(sirfport->tx_dma_no)) {
-               sirfsoc_uart_init_tx_dma(port);
+                       SIRFUART_RX_FIFO_CHK_SC(port->line, 0x4) |
+                       SIRFUART_RX_FIFO_CHK_LC(port->line, 0xe) |
+                       SIRFUART_RX_FIFO_CHK_HC(port->line, 0x1b));
+       if (sirfport->tx_dma_chan) {
                sirfport->tx_dma_state = TX_DMA_IDLE;
                wr_regl(port, ureg->sirfsoc_tx_fifo_level_chk,
                                SIRFUART_TX_FIFO_CHK_SC(port->line, 0x1b) |
@@ -1230,12 +1138,8 @@ static void sirfsoc_uart_shutdown(struct uart_port *port)
                gpio_set_value(sirfport->rts_gpio, 1);
                free_irq(gpio_to_irq(sirfport->cts_gpio), sirfport);
        }
-       if (IS_DMA_CHAN_VALID(sirfport->rx_dma_no))
-               sirfsoc_uart_uninit_rx_dma(sirfport);
-       if (IS_DMA_CHAN_VALID(sirfport->tx_dma_no)) {
-               sirfsoc_uart_uninit_tx_dma(sirfport);
+       if (sirfport->tx_dma_chan)
                sirfport->tx_dma_state = TX_DMA_IDLE;
-       }
 }
 
 static const char *sirfsoc_uart_type(struct uart_port *port)
@@ -1311,8 +1215,8 @@ sirfsoc_uart_console_setup(struct console *co, char *options)
        port->cons = co;
 
        /* default console tx/rx transfer using io mode */
-       sirfport->rx_dma_no = UNVALID_DMA_CHAN;
-       sirfport->tx_dma_no = UNVALID_DMA_CHAN;
+       sirfport->rx_dma_chan = NULL;
+       sirfport->tx_dma_chan = NULL;
        return uart_set_options(port, co, baud, parity, bits, flow);
 }
 
@@ -1380,6 +1284,13 @@ static int sirfsoc_uart_probe(struct platform_device *pdev)
        struct uart_port *port;
        struct resource *res;
        int ret;
+       int i, j;
+       struct dma_slave_config slv_cfg = {
+               .src_maxburst = 2,
+       };
+       struct dma_slave_config tx_slv_cfg = {
+               .dst_maxburst = 2,
+       };
        const struct of_device_id *match;
 
        match = of_match_node(sirfsoc_uart_ids, pdev->dev.of_node);
@@ -1400,27 +1311,10 @@ static int sirfsoc_uart_probe(struct platform_device *pdev)
 
        sirfport->hw_flow_ctrl = of_property_read_bool(pdev->dev.of_node,
                "sirf,uart-has-rtscts");
-       if (of_device_is_compatible(pdev->dev.of_node, "sirf,prima2-uart")) {
+       if (of_device_is_compatible(pdev->dev.of_node, "sirf,prima2-uart"))
                sirfport->uart_reg->uart_type = SIRF_REAL_UART;
-               if (of_property_read_u32(pdev->dev.of_node,
-                               "sirf,uart-dma-rx-channel",
-                               &sirfport->rx_dma_no))
-                       sirfport->rx_dma_no = UNVALID_DMA_CHAN;
-               if (of_property_read_u32(pdev->dev.of_node,
-                               "sirf,uart-dma-tx-channel",
-                               &sirfport->tx_dma_no))
-                       sirfport->tx_dma_no = UNVALID_DMA_CHAN;
-       }
        if (of_device_is_compatible(pdev->dev.of_node, "sirf,prima2-usp-uart")) {
                sirfport->uart_reg->uart_type = SIRF_USP_UART;
-               if (of_property_read_u32(pdev->dev.of_node,
-                               "sirf,usp-dma-rx-channel",
-                               &sirfport->rx_dma_no))
-                       sirfport->rx_dma_no = UNVALID_DMA_CHAN;
-               if (of_property_read_u32(pdev->dev.of_node,
-                               "sirf,usp-dma-tx-channel",
-                               &sirfport->tx_dma_no))
-                       sirfport->tx_dma_no = UNVALID_DMA_CHAN;
                if (!sirfport->hw_flow_ctrl)
                        goto usp_no_flow_control;
                if (of_find_property(pdev->dev.of_node, "cts-gpios", NULL))
@@ -1513,8 +1407,32 @@ usp_no_flow_control:
                goto port_err;
        }
 
-       return 0;
+       sirfport->rx_dma_chan = dma_request_slave_channel(port->dev, "rx");
+       for (i = 0; sirfport->rx_dma_chan && i < SIRFSOC_RX_LOOP_BUF_CNT; i++) {
+               sirfport->rx_dma_items[i].xmit.buf =
+                       dma_alloc_coherent(port->dev, SIRFSOC_RX_DMA_BUF_SIZE,
+                       &sirfport->rx_dma_items[i].dma_addr, GFP_KERNEL);
+               if (!sirfport->rx_dma_items[i].xmit.buf) {
+                       dev_err(port->dev, "Uart alloc bufa failed\n");
+                       ret = -ENOMEM;
+                       goto alloc_coherent_err;
+               }
+               sirfport->rx_dma_items[i].xmit.head =
+                       sirfport->rx_dma_items[i].xmit.tail = 0;
+       }
+       if (sirfport->rx_dma_chan)
+               dmaengine_slave_config(sirfport->rx_dma_chan, &slv_cfg);
+       sirfport->tx_dma_chan = dma_request_slave_channel(port->dev, "tx");
+       if (sirfport->tx_dma_chan)
+               dmaengine_slave_config(sirfport->tx_dma_chan, &tx_slv_cfg);
 
+       return 0;
+alloc_coherent_err:
+       for (j = 0; j < i; j++)
+               dma_free_coherent(port->dev, SIRFSOC_RX_DMA_BUF_SIZE,
+                               sirfport->rx_dma_items[j].xmit.buf,
+                               sirfport->rx_dma_items[j].dma_addr);
+       dma_release_channel(sirfport->rx_dma_chan);
 port_err:
        clk_put(sirfport->clk);
 err:
@@ -1527,6 +1445,19 @@ static int sirfsoc_uart_remove(struct platform_device *pdev)
        struct uart_port *port = &sirfport->port;
        clk_put(sirfport->clk);
        uart_remove_one_port(&sirfsoc_uart_drv, port);
+       if (sirfport->rx_dma_chan) {
+               int i;
+               dmaengine_terminate_all(sirfport->rx_dma_chan);
+               dma_release_channel(sirfport->rx_dma_chan);
+               for (i = 0; i < SIRFSOC_RX_LOOP_BUF_CNT; i++)
+                       dma_free_coherent(port->dev, SIRFSOC_RX_DMA_BUF_SIZE,
+                                       sirfport->rx_dma_items[i].xmit.buf,
+                                       sirfport->rx_dma_items[i].dma_addr);
+       }
+       if (sirfport->tx_dma_chan) {
+               dmaengine_terminate_all(sirfport->tx_dma_chan);
+               dma_release_channel(sirfport->tx_dma_chan);
+       }
        return 0;
 }