diff options
| author | Qipan Li <Qipan.Li@csr.com> | 2014-01-30 00:57:29 -0500 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-02-13 13:36:25 -0500 |
| commit | 9be16b38cf43181efc12ee6f467aaf222ad31b03 (patch) | |
| tree | a2ee5255bc6e3089e7644c91f1fae744e0568f70 | |
| parent | ef2889f7ffee67f0aed49e854c72be63f1466759 (diff) | |
serial: sirf: move to use generic dma dt-binding to get dma channels
instead of using sirf specific dma channel property like "sirf,uart-dma-rx-channel"
and "sirf,uart-dma-tx-channel", here we move to use generic dma dt-binding to get
the channel like:
- sirf,uart-dma-rx-channel = <21>;
- sirf,uart-dma-tx-channel = <2>;
+ dmas = <&dmac1 5>, <&dmac0 2>;
+ dma-names = "rx", "tx";
and we move dma_request_channel() to dma_request_slave_channel(), we don't need to
call sirfsoc dma filter function sirfsoc_dma_filter_id() again.
Signed-off-by: Qipan Li <Qipan.Li@csr.com>
Signed-off-by: Barry Song <Baohua.Song@csr.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
| -rw-r--r-- | arch/arm/boot/dts/atlas6.dtsi | 17 | ||||
| -rw-r--r-- | arch/arm/boot/dts/prima2.dtsi | 20 | ||||
| -rw-r--r-- | drivers/tty/serial/sirfsoc_uart.c | 195 | ||||
| -rw-r--r-- | drivers/tty/serial/sirfsoc_uart.h | 5 |
4 files changed, 81 insertions, 156 deletions
diff --git a/arch/arm/boot/dts/atlas6.dtsi b/arch/arm/boot/dts/atlas6.dtsi index f8674bcc4489..0c81dc945aed 100644 --- a/arch/arm/boot/dts/atlas6.dtsi +++ b/arch/arm/boot/dts/atlas6.dtsi | |||
| @@ -217,8 +217,8 @@ | |||
| 217 | interrupts = <17>; | 217 | interrupts = <17>; |
| 218 | fifosize = <128>; | 218 | fifosize = <128>; |
| 219 | clocks = <&clks 13>; | 219 | clocks = <&clks 13>; |
| 220 | sirf,uart-dma-rx-channel = <21>; | 220 | dmas = <&dmac1 5>, <&dmac0 2>; |
| 221 | sirf,uart-dma-tx-channel = <2>; | 221 | dma-names = "rx", "tx"; |
| 222 | }; | 222 | }; |
| 223 | 223 | ||
| 224 | uart1: uart@b0060000 { | 224 | uart1: uart@b0060000 { |
| @@ -228,6 +228,7 @@ | |||
| 228 | interrupts = <18>; | 228 | interrupts = <18>; |
| 229 | fifosize = <32>; | 229 | fifosize = <32>; |
| 230 | clocks = <&clks 14>; | 230 | clocks = <&clks 14>; |
| 231 | dma-names = "no-rx", "no-tx"; | ||
| 231 | }; | 232 | }; |
| 232 | 233 | ||
| 233 | uart2: uart@b0070000 { | 234 | uart2: uart@b0070000 { |
| @@ -237,8 +238,8 @@ | |||
| 237 | interrupts = <19>; | 238 | interrupts = <19>; |
| 238 | fifosize = <128>; | 239 | fifosize = <128>; |
| 239 | clocks = <&clks 15>; | 240 | clocks = <&clks 15>; |
| 240 | sirf,uart-dma-rx-channel = <6>; | 241 | dmas = <&dmac0 6>, <&dmac0 7>; |
| 241 | sirf,uart-dma-tx-channel = <7>; | 242 | dma-names = "rx", "tx"; |
| 242 | }; | 243 | }; |
| 243 | 244 | ||
| 244 | usp0: usp@b0080000 { | 245 | usp0: usp@b0080000 { |
| @@ -248,8 +249,8 @@ | |||
| 248 | interrupts = <20>; | 249 | interrupts = <20>; |
| 249 | fifosize = <128>; | 250 | fifosize = <128>; |
| 250 | clocks = <&clks 28>; | 251 | clocks = <&clks 28>; |
| 251 | sirf,usp-dma-rx-channel = <17>; | 252 | dmas = <&dmac1 1>, <&dmac1 2>; |
| 252 | sirf,usp-dma-tx-channel = <18>; | 253 | dma-names = "rx", "tx"; |
| 253 | }; | 254 | }; |
| 254 | 255 | ||
| 255 | usp1: usp@b0090000 { | 256 | usp1: usp@b0090000 { |
| @@ -259,8 +260,8 @@ | |||
| 259 | interrupts = <21>; | 260 | interrupts = <21>; |
| 260 | fifosize = <128>; | 261 | fifosize = <128>; |
| 261 | clocks = <&clks 29>; | 262 | clocks = <&clks 29>; |
| 262 | sirf,usp-dma-rx-channel = <14>; | 263 | dmas = <&dmac0 14>, <&dmac0 15>; |
| 263 | sirf,usp-dma-tx-channel = <15>; | 264 | dma-names = "rx", "tx"; |
| 264 | }; | 265 | }; |
| 265 | 266 | ||
| 266 | dmac0: dma-controller@b00b0000 { | 267 | dmac0: dma-controller@b00b0000 { |
diff --git a/arch/arm/boot/dts/prima2.dtsi b/arch/arm/boot/dts/prima2.dtsi index 0e219932d7cc..8582ae41a583 100644 --- a/arch/arm/boot/dts/prima2.dtsi +++ b/arch/arm/boot/dts/prima2.dtsi | |||
| @@ -223,8 +223,8 @@ | |||
| 223 | interrupts = <17>; | 223 | interrupts = <17>; |
| 224 | fifosize = <128>; | 224 | fifosize = <128>; |
| 225 | clocks = <&clks 13>; | 225 | clocks = <&clks 13>; |
| 226 | sirf,uart-dma-rx-channel = <21>; | 226 | dmas = <&dmac1 5>, <&dmac0 2>; |
| 227 | sirf,uart-dma-tx-channel = <2>; | 227 | dma-names = "rx", "tx"; |
| 228 | }; | 228 | }; |
| 229 | 229 | ||
| 230 | uart1: uart@b0060000 { | 230 | uart1: uart@b0060000 { |
| @@ -243,8 +243,8 @@ | |||
| 243 | interrupts = <19>; | 243 | interrupts = <19>; |
| 244 | fifosize = <128>; | 244 | fifosize = <128>; |
| 245 | clocks = <&clks 15>; | 245 | clocks = <&clks 15>; |
| 246 | sirf,uart-dma-rx-channel = <6>; | 246 | dmas = <&dmac0 6>, <&dmac0 7>; |
| 247 | sirf,uart-dma-tx-channel = <7>; | 247 | dma-names = "rx", "tx"; |
| 248 | }; | 248 | }; |
| 249 | 249 | ||
| 250 | usp0: usp@b0080000 { | 250 | usp0: usp@b0080000 { |
| @@ -254,8 +254,8 @@ | |||
| 254 | interrupts = <20>; | 254 | interrupts = <20>; |
| 255 | fifosize = <128>; | 255 | fifosize = <128>; |
| 256 | clocks = <&clks 28>; | 256 | clocks = <&clks 28>; |
| 257 | sirf,usp-dma-rx-channel = <17>; | 257 | dmas = <&dmac1 1>, <&dmac1 2>; |
| 258 | sirf,usp-dma-tx-channel = <18>; | 258 | dma-names = "rx", "tx"; |
| 259 | }; | 259 | }; |
| 260 | 260 | ||
| 261 | usp1: usp@b0090000 { | 261 | usp1: usp@b0090000 { |
| @@ -265,8 +265,8 @@ | |||
| 265 | interrupts = <21>; | 265 | interrupts = <21>; |
| 266 | fifosize = <128>; | 266 | fifosize = <128>; |
| 267 | clocks = <&clks 29>; | 267 | clocks = <&clks 29>; |
| 268 | sirf,usp-dma-rx-channel = <14>; | 268 | dmas = <&dmac0 14>, <&dmac0 15>; |
| 269 | sirf,usp-dma-tx-channel = <15>; | 269 | dma-names = "rx", "tx"; |
| 270 | }; | 270 | }; |
| 271 | 271 | ||
| 272 | usp2: usp@b00a0000 { | 272 | usp2: usp@b00a0000 { |
| @@ -276,8 +276,8 @@ | |||
| 276 | interrupts = <22>; | 276 | interrupts = <22>; |
| 277 | fifosize = <128>; | 277 | fifosize = <128>; |
| 278 | clocks = <&clks 30>; | 278 | clocks = <&clks 30>; |
| 279 | sirf,usp-dma-rx-channel = <10>; | 279 | dmas = <&dmac0 10>, <&dmac0 11>; |
| 280 | sirf,usp-dma-tx-channel = <11>; | 280 | dma-names = "rx", "tx"; |
| 281 | }; | 281 | }; |
| 282 | 282 | ||
| 283 | dmac0: dma-controller@b00b0000 { | 283 | dmac0: dma-controller@b00b0000 { |
diff --git a/drivers/tty/serial/sirfsoc_uart.c b/drivers/tty/serial/sirfsoc_uart.c index b7bfe24d4ebc..68b0fd4b9a6a 100644 --- a/drivers/tty/serial/sirfsoc_uart.c +++ b/drivers/tty/serial/sirfsoc_uart.c | |||
| @@ -24,7 +24,6 @@ | |||
| 24 | #include <linux/dmaengine.h> | 24 | #include <linux/dmaengine.h> |
| 25 | #include <linux/dma-direction.h> | 25 | #include <linux/dma-direction.h> |
| 26 | #include <linux/dma-mapping.h> | 26 | #include <linux/dma-mapping.h> |
| 27 | #include <linux/sirfsoc_dma.h> | ||
| 28 | #include <asm/irq.h> | 27 | #include <asm/irq.h> |
| 29 | #include <asm/mach/irq.h> | 28 | #include <asm/mach/irq.h> |
| 30 | 29 | ||
| @@ -173,7 +172,7 @@ static void sirfsoc_uart_stop_tx(struct uart_port *port) | |||
| 173 | struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; | 172 | struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; |
| 174 | struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en; | 173 | struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en; |
| 175 | 174 | ||
| 176 | if (IS_DMA_CHAN_VALID(sirfport->tx_dma_no)) { | 175 | if (sirfport->tx_dma_chan) { |
| 177 | if (sirfport->tx_dma_state == TX_DMA_RUNNING) { | 176 | if (sirfport->tx_dma_state == TX_DMA_RUNNING) { |
| 178 | dmaengine_pause(sirfport->tx_dma_chan); | 177 | dmaengine_pause(sirfport->tx_dma_chan); |
| 179 | sirfport->tx_dma_state = TX_DMA_PAUSE; | 178 | sirfport->tx_dma_state = TX_DMA_PAUSE; |
| @@ -288,7 +287,7 @@ static void sirfsoc_uart_start_tx(struct uart_port *port) | |||
| 288 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); | 287 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); |
| 289 | struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; | 288 | struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; |
| 290 | struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en; | 289 | struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en; |
| 291 | if (IS_DMA_CHAN_VALID(sirfport->tx_dma_no)) | 290 | if (sirfport->tx_dma_chan) |
| 292 | sirfsoc_uart_tx_with_dma(sirfport); | 291 | sirfsoc_uart_tx_with_dma(sirfport); |
| 293 | else { | 292 | else { |
| 294 | sirfsoc_uart_pio_tx_chars(sirfport, 1); | 293 | sirfsoc_uart_pio_tx_chars(sirfport, 1); |
| @@ -310,7 +309,7 @@ static void sirfsoc_uart_stop_rx(struct uart_port *port) | |||
| 310 | struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en; | 309 | struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en; |
| 311 | 310 | ||
| 312 | wr_regl(port, ureg->sirfsoc_rx_fifo_op, 0); | 311 | wr_regl(port, ureg->sirfsoc_rx_fifo_op, 0); |
| 313 | if (IS_DMA_CHAN_VALID(sirfport->rx_dma_no)) { | 312 | if (sirfport->rx_dma_chan) { |
| 314 | if (!sirfport->is_marco) | 313 | if (!sirfport->is_marco) |
| 315 | wr_regl(port, ureg->sirfsoc_int_en_reg, | 314 | wr_regl(port, ureg->sirfsoc_int_en_reg, |
| 316 | rd_regl(port, ureg->sirfsoc_int_en_reg) & | 315 | rd_regl(port, ureg->sirfsoc_int_en_reg) & |
| @@ -675,7 +674,7 @@ recv_char: | |||
| 675 | uart_handle_cts_change(port, cts_status); | 674 | uart_handle_cts_change(port, cts_status); |
| 676 | wake_up_interruptible(&state->port.delta_msr_wait); | 675 | wake_up_interruptible(&state->port.delta_msr_wait); |
| 677 | } | 676 | } |
| 678 | if (IS_DMA_CHAN_VALID(sirfport->rx_dma_no)) { | 677 | if (sirfport->rx_dma_chan) { |
| 679 | if (intr_status & uint_st->sirfsoc_rx_timeout) | 678 | if (intr_status & uint_st->sirfsoc_rx_timeout) |
| 680 | sirfsoc_uart_handle_rx_tmo(sirfport); | 679 | sirfsoc_uart_handle_rx_tmo(sirfport); |
| 681 | if (intr_status & uint_st->sirfsoc_rx_done) | 680 | if (intr_status & uint_st->sirfsoc_rx_done) |
| @@ -686,7 +685,7 @@ recv_char: | |||
| 686 | SIRFSOC_UART_IO_RX_MAX_CNT); | 685 | SIRFSOC_UART_IO_RX_MAX_CNT); |
| 687 | } | 686 | } |
| 688 | if (intr_status & uint_st->sirfsoc_txfifo_empty) { | 687 | if (intr_status & uint_st->sirfsoc_txfifo_empty) { |
| 689 | if (IS_DMA_CHAN_VALID(sirfport->tx_dma_no)) | 688 | if (sirfport->tx_dma_chan) |
| 690 | sirfsoc_uart_tx_with_dma(sirfport); | 689 | sirfsoc_uart_tx_with_dma(sirfport); |
| 691 | else { | 690 | else { |
| 692 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { | 691 | if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { |
| @@ -778,7 +777,7 @@ static void sirfsoc_uart_start_rx(struct uart_port *port) | |||
| 778 | wr_regl(port, ureg->sirfsoc_rx_fifo_op, SIRFUART_FIFO_RESET); | 777 | wr_regl(port, ureg->sirfsoc_rx_fifo_op, SIRFUART_FIFO_RESET); |
| 779 | wr_regl(port, ureg->sirfsoc_rx_fifo_op, 0); | 778 | wr_regl(port, ureg->sirfsoc_rx_fifo_op, 0); |
| 780 | wr_regl(port, ureg->sirfsoc_rx_fifo_op, SIRFUART_FIFO_START); | 779 | wr_regl(port, ureg->sirfsoc_rx_fifo_op, SIRFUART_FIFO_START); |
| 781 | if (IS_DMA_CHAN_VALID(sirfport->rx_dma_no)) | 780 | if (sirfport->rx_dma_chan) |
| 782 | sirfsoc_uart_start_next_rx_dma(port); | 781 | sirfsoc_uart_start_next_rx_dma(port); |
| 783 | else { | 782 | else { |
| 784 | if (!sirfport->is_marco) | 783 | if (!sirfport->is_marco) |
| @@ -1014,11 +1013,11 @@ static void sirfsoc_uart_set_termios(struct uart_port *port, | |||
| 1014 | (sample_div_reg & SIRFSOC_USP_ASYNC_DIV2_MASK) << | 1013 | (sample_div_reg & SIRFSOC_USP_ASYNC_DIV2_MASK) << |
| 1015 | SIRFSOC_USP_ASYNC_DIV2_OFFSET); | 1014 | SIRFSOC_USP_ASYNC_DIV2_OFFSET); |
| 1016 | } | 1015 | } |
| 1017 | if (IS_DMA_CHAN_VALID(sirfport->tx_dma_no)) | 1016 | if (sirfport->tx_dma_chan) |
| 1018 | wr_regl(port, ureg->sirfsoc_tx_dma_io_ctrl, SIRFUART_DMA_MODE); | 1017 | wr_regl(port, ureg->sirfsoc_tx_dma_io_ctrl, SIRFUART_DMA_MODE); |
| 1019 | else | 1018 | else |
| 1020 | wr_regl(port, ureg->sirfsoc_tx_dma_io_ctrl, SIRFUART_IO_MODE); | 1019 | wr_regl(port, ureg->sirfsoc_tx_dma_io_ctrl, SIRFUART_IO_MODE); |
| 1021 | if (IS_DMA_CHAN_VALID(sirfport->rx_dma_no)) | 1020 | if (sirfport->rx_dma_chan) |
| 1022 | wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, SIRFUART_DMA_MODE); | 1021 | wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, SIRFUART_DMA_MODE); |
| 1023 | else | 1022 | else |
| 1024 | wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, SIRFUART_IO_MODE); | 1023 | wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, SIRFUART_IO_MODE); |
| @@ -1049,93 +1048,6 @@ static void sirfsoc_uart_pm(struct uart_port *port, unsigned int state, | |||
| 1049 | clk_disable_unprepare(sirfport->clk); | 1048 | clk_disable_unprepare(sirfport->clk); |
| 1050 | } | 1049 | } |
| 1051 | 1050 | ||
| 1052 | static unsigned int sirfsoc_uart_init_tx_dma(struct uart_port *port) | ||
| 1053 | { | ||
| 1054 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); | ||
| 1055 | dma_cap_mask_t dma_mask; | ||
| 1056 | struct dma_slave_config tx_slv_cfg = { | ||
| 1057 | .dst_maxburst = 2, | ||
| 1058 | }; | ||
| 1059 | |||
| 1060 | dma_cap_zero(dma_mask); | ||
| 1061 | dma_cap_set(DMA_SLAVE, dma_mask); | ||
| 1062 | sirfport->tx_dma_chan = dma_request_channel(dma_mask, | ||
| 1063 | (dma_filter_fn)sirfsoc_dma_filter_id, | ||
| 1064 | (void *)sirfport->tx_dma_no); | ||
| 1065 | if (!sirfport->tx_dma_chan) { | ||
| 1066 | dev_err(port->dev, "Uart Request Dma Channel Fail %d\n", | ||
| 1067 | sirfport->tx_dma_no); | ||
| 1068 | return -EPROBE_DEFER; | ||
| 1069 | } | ||
| 1070 | dmaengine_slave_config(sirfport->tx_dma_chan, &tx_slv_cfg); | ||
| 1071 | |||
| 1072 | return 0; | ||
| 1073 | } | ||
| 1074 | |||
| 1075 | static unsigned int sirfsoc_uart_init_rx_dma(struct uart_port *port) | ||
| 1076 | { | ||
| 1077 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); | ||
| 1078 | dma_cap_mask_t dma_mask; | ||
| 1079 | int ret; | ||
| 1080 | int i, j; | ||
| 1081 | struct dma_slave_config slv_cfg = { | ||
| 1082 | .src_maxburst = 2, | ||
| 1083 | }; | ||
| 1084 | |||
| 1085 | dma_cap_zero(dma_mask); | ||
| 1086 | dma_cap_set(DMA_SLAVE, dma_mask); | ||
| 1087 | sirfport->rx_dma_chan = dma_request_channel(dma_mask, | ||
| 1088 | (dma_filter_fn)sirfsoc_dma_filter_id, | ||
| 1089 | (void *)sirfport->rx_dma_no); | ||
| 1090 | if (!sirfport->rx_dma_chan) { | ||
| 1091 | dev_err(port->dev, "Uart Request Dma Channel Fail %d\n", | ||
| 1092 | sirfport->rx_dma_no); | ||
| 1093 | ret = -EPROBE_DEFER; | ||
| 1094 | goto request_err; | ||
| 1095 | } | ||
| 1096 | for (i = 0; i < SIRFSOC_RX_LOOP_BUF_CNT; i++) { | ||
| 1097 | sirfport->rx_dma_items[i].xmit.buf = | ||
| 1098 | dma_alloc_coherent(port->dev, SIRFSOC_RX_DMA_BUF_SIZE, | ||
| 1099 | &sirfport->rx_dma_items[i].dma_addr, GFP_KERNEL); | ||
| 1100 | if (!sirfport->rx_dma_items[i].xmit.buf) { | ||
| 1101 | dev_err(port->dev, "Uart alloc bufa failed\n"); | ||
| 1102 | ret = -ENOMEM; | ||
| 1103 | goto alloc_coherent_err; | ||
| 1104 | } | ||
| 1105 | sirfport->rx_dma_items[i].xmit.head = | ||
| 1106 | sirfport->rx_dma_items[i].xmit.tail = 0; | ||
| 1107 | } | ||
| 1108 | dmaengine_slave_config(sirfport->rx_dma_chan, &slv_cfg); | ||
| 1109 | |||
| 1110 | return 0; | ||
| 1111 | alloc_coherent_err: | ||
| 1112 | for (j = 0; j < i; j++) | ||
| 1113 | dma_free_coherent(port->dev, SIRFSOC_RX_DMA_BUF_SIZE, | ||
| 1114 | sirfport->rx_dma_items[j].xmit.buf, | ||
| 1115 | sirfport->rx_dma_items[j].dma_addr); | ||
| 1116 | dma_release_channel(sirfport->rx_dma_chan); | ||
| 1117 | request_err: | ||
| 1118 | return ret; | ||
| 1119 | } | ||
| 1120 | |||
| 1121 | static void sirfsoc_uart_uninit_tx_dma(struct sirfsoc_uart_port *sirfport) | ||
| 1122 | { | ||
| 1123 | dmaengine_terminate_all(sirfport->tx_dma_chan); | ||
| 1124 | dma_release_channel(sirfport->tx_dma_chan); | ||
| 1125 | } | ||
| 1126 | |||
| 1127 | static void sirfsoc_uart_uninit_rx_dma(struct sirfsoc_uart_port *sirfport) | ||
| 1128 | { | ||
| 1129 | int i; | ||
| 1130 | struct uart_port *port = &sirfport->port; | ||
| 1131 | dmaengine_terminate_all(sirfport->rx_dma_chan); | ||
| 1132 | dma_release_channel(sirfport->rx_dma_chan); | ||
| 1133 | for (i = 0; i < SIRFSOC_RX_LOOP_BUF_CNT; i++) | ||
| 1134 | dma_free_coherent(port->dev, SIRFSOC_RX_DMA_BUF_SIZE, | ||
| 1135 | sirfport->rx_dma_items[i].xmit.buf, | ||
| 1136 | sirfport->rx_dma_items[i].dma_addr); | ||
| 1137 | } | ||
| 1138 | |||
| 1139 | static int sirfsoc_uart_startup(struct uart_port *port) | 1051 | static int sirfsoc_uart_startup(struct uart_port *port) |
| 1140 | { | 1052 | { |
| 1141 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); | 1053 | struct sirfsoc_uart_port *sirfport = to_sirfport(port); |
| @@ -1174,18 +1086,12 @@ static int sirfsoc_uart_startup(struct uart_port *port) | |||
| 1174 | wr_regl(port, ureg->sirfsoc_rx_fifo_op, 0); | 1086 | wr_regl(port, ureg->sirfsoc_rx_fifo_op, 0); |
| 1175 | wr_regl(port, ureg->sirfsoc_tx_fifo_ctrl, SIRFUART_FIFO_THD(port)); | 1087 | wr_regl(port, ureg->sirfsoc_tx_fifo_ctrl, SIRFUART_FIFO_THD(port)); |
| 1176 | wr_regl(port, ureg->sirfsoc_rx_fifo_ctrl, SIRFUART_FIFO_THD(port)); | 1088 | wr_regl(port, ureg->sirfsoc_rx_fifo_ctrl, SIRFUART_FIFO_THD(port)); |
| 1177 | 1089 | if (sirfport->rx_dma_chan) | |
| 1178 | if (IS_DMA_CHAN_VALID(sirfport->rx_dma_no)) { | ||
| 1179 | ret = sirfsoc_uart_init_rx_dma(port); | ||
| 1180 | if (ret) | ||
| 1181 | goto init_rx_err; | ||
| 1182 | wr_regl(port, ureg->sirfsoc_rx_fifo_level_chk, | 1090 | wr_regl(port, ureg->sirfsoc_rx_fifo_level_chk, |
| 1183 | SIRFUART_RX_FIFO_CHK_SC(port->line, 0x4) | | 1091 | SIRFUART_RX_FIFO_CHK_SC(port->line, 0x4) | |
| 1184 | SIRFUART_RX_FIFO_CHK_LC(port->line, 0xe) | | 1092 | SIRFUART_RX_FIFO_CHK_LC(port->line, 0xe) | |
| 1185 | SIRFUART_RX_FIFO_CHK_HC(port->line, 0x1b)); | 1093 | SIRFUART_RX_FIFO_CHK_HC(port->line, 0x1b)); |
| 1186 | } | 1094 | if (sirfport->tx_dma_chan) { |
| 1187 | if (IS_DMA_CHAN_VALID(sirfport->tx_dma_no)) { | ||
| 1188 | sirfsoc_uart_init_tx_dma(port); | ||
| 1189 | sirfport->tx_dma_state = TX_DMA_IDLE; | 1095 | sirfport->tx_dma_state = TX_DMA_IDLE; |
| 1190 | wr_regl(port, ureg->sirfsoc_tx_fifo_level_chk, | 1096 | wr_regl(port, ureg->sirfsoc_tx_fifo_level_chk, |
| 1191 | SIRFUART_TX_FIFO_CHK_SC(port->line, 0x1b) | | 1097 | SIRFUART_TX_FIFO_CHK_SC(port->line, 0x1b) | |
| @@ -1232,12 +1138,8 @@ static void sirfsoc_uart_shutdown(struct uart_port *port) | |||
| 1232 | gpio_set_value(sirfport->rts_gpio, 1); | 1138 | gpio_set_value(sirfport->rts_gpio, 1); |
| 1233 | free_irq(gpio_to_irq(sirfport->cts_gpio), sirfport); | 1139 | free_irq(gpio_to_irq(sirfport->cts_gpio), sirfport); |
| 1234 | } | 1140 | } |
| 1235 | if (IS_DMA_CHAN_VALID(sirfport->rx_dma_no)) | 1141 | if (sirfport->tx_dma_chan) |
| 1236 | sirfsoc_uart_uninit_rx_dma(sirfport); | ||
| 1237 | if (IS_DMA_CHAN_VALID(sirfport->tx_dma_no)) { | ||
| 1238 | sirfsoc_uart_uninit_tx_dma(sirfport); | ||
| 1239 | sirfport->tx_dma_state = TX_DMA_IDLE; | 1142 | sirfport->tx_dma_state = TX_DMA_IDLE; |
| 1240 | } | ||
| 1241 | } | 1143 | } |
| 1242 | 1144 | ||
| 1243 | static const char *sirfsoc_uart_type(struct uart_port *port) | 1145 | static const char *sirfsoc_uart_type(struct uart_port *port) |
| @@ -1313,8 +1215,8 @@ sirfsoc_uart_console_setup(struct console *co, char *options) | |||
| 1313 | port->cons = co; | 1215 | port->cons = co; |
| 1314 | 1216 | ||
| 1315 | /* default console tx/rx transfer using io mode */ | 1217 | /* default console tx/rx transfer using io mode */ |
| 1316 | sirfport->rx_dma_no = UNVALID_DMA_CHAN; | 1218 | sirfport->rx_dma_chan = NULL; |
| 1317 | sirfport->tx_dma_no = UNVALID_DMA_CHAN; | 1219 | sirfport->tx_dma_chan = NULL; |
| 1318 | return uart_set_options(port, co, baud, parity, bits, flow); | 1220 | return uart_set_options(port, co, baud, parity, bits, flow); |
| 1319 | } | 1221 | } |
| 1320 | 1222 | ||
| @@ -1382,6 +1284,13 @@ static int sirfsoc_uart_probe(struct platform_device *pdev) | |||
| 1382 | struct uart_port *port; | 1284 | struct uart_port *port; |
| 1383 | struct resource *res; | 1285 | struct resource *res; |
| 1384 | int ret; | 1286 | int ret; |
| 1287 | int i, j; | ||
| 1288 | struct dma_slave_config slv_cfg = { | ||
| 1289 | .src_maxburst = 2, | ||
| 1290 | }; | ||
| 1291 | struct dma_slave_config tx_slv_cfg = { | ||
| 1292 | .dst_maxburst = 2, | ||
| 1293 | }; | ||
| 1385 | const struct of_device_id *match; | 1294 | const struct of_device_id *match; |
| 1386 | 1295 | ||
| 1387 | match = of_match_node(sirfsoc_uart_ids, pdev->dev.of_node); | 1296 | match = of_match_node(sirfsoc_uart_ids, pdev->dev.of_node); |
| @@ -1402,27 +1311,10 @@ static int sirfsoc_uart_probe(struct platform_device *pdev) | |||
| 1402 | 1311 | ||
| 1403 | sirfport->hw_flow_ctrl = of_property_read_bool(pdev->dev.of_node, | 1312 | sirfport->hw_flow_ctrl = of_property_read_bool(pdev->dev.of_node, |
| 1404 | "sirf,uart-has-rtscts"); | 1313 | "sirf,uart-has-rtscts"); |
| 1405 | if (of_device_is_compatible(pdev->dev.of_node, "sirf,prima2-uart")) { | 1314 | if (of_device_is_compatible(pdev->dev.of_node, "sirf,prima2-uart")) |
| 1406 | sirfport->uart_reg->uart_type = SIRF_REAL_UART; | 1315 | sirfport->uart_reg->uart_type = SIRF_REAL_UART; |
| 1407 | if (of_property_read_u32(pdev->dev.of_node, | ||
| 1408 | "sirf,uart-dma-rx-channel", | ||
| 1409 | &sirfport->rx_dma_no)) | ||
| 1410 | sirfport->rx_dma_no = UNVALID_DMA_CHAN; | ||
| 1411 | if (of_property_read_u32(pdev->dev.of_node, | ||
| 1412 | "sirf,uart-dma-tx-channel", | ||
| 1413 | &sirfport->tx_dma_no)) | ||
| 1414 | sirfport->tx_dma_no = UNVALID_DMA_CHAN; | ||
| 1415 | } | ||
| 1416 | if (of_device_is_compatible(pdev->dev.of_node, "sirf,prima2-usp-uart")) { | 1316 | if (of_device_is_compatible(pdev->dev.of_node, "sirf,prima2-usp-uart")) { |
| 1417 | sirfport->uart_reg->uart_type = SIRF_USP_UART; | 1317 | sirfport->uart_reg->uart_type = SIRF_USP_UART; |
| 1418 | if (of_property_read_u32(pdev->dev.of_node, | ||
| 1419 | "sirf,usp-dma-rx-channel", | ||
| 1420 | &sirfport->rx_dma_no)) | ||
| 1421 | sirfport->rx_dma_no = UNVALID_DMA_CHAN; | ||
| 1422 | if (of_property_read_u32(pdev->dev.of_node, | ||
| 1423 | "sirf,usp-dma-tx-channel", | ||
| 1424 | &sirfport->tx_dma_no)) | ||
| 1425 | sirfport->tx_dma_no = UNVALID_DMA_CHAN; | ||
| 1426 | if (!sirfport->hw_flow_ctrl) | 1318 | if (!sirfport->hw_flow_ctrl) |
| 1427 | goto usp_no_flow_control; | 1319 | goto usp_no_flow_control; |
| 1428 | if (of_find_property(pdev->dev.of_node, "cts-gpios", NULL)) | 1320 | if (of_find_property(pdev->dev.of_node, "cts-gpios", NULL)) |
| @@ -1515,8 +1407,32 @@ usp_no_flow_control: | |||
| 1515 | goto port_err; | 1407 | goto port_err; |
| 1516 | } | 1408 | } |
| 1517 | 1409 | ||
| 1518 | return 0; | 1410 | sirfport->rx_dma_chan = dma_request_slave_channel(port->dev, "rx"); |
| 1411 | for (i = 0; sirfport->rx_dma_chan && i < SIRFSOC_RX_LOOP_BUF_CNT; i++) { | ||
| 1412 | sirfport->rx_dma_items[i].xmit.buf = | ||
| 1413 | dma_alloc_coherent(port->dev, SIRFSOC_RX_DMA_BUF_SIZE, | ||
| 1414 | &sirfport->rx_dma_items[i].dma_addr, GFP_KERNEL); | ||
| 1415 | if (!sirfport->rx_dma_items[i].xmit.buf) { | ||
| 1416 | dev_err(port->dev, "Uart alloc bufa failed\n"); | ||
| 1417 | ret = -ENOMEM; | ||
| 1418 | goto alloc_coherent_err; | ||
| 1419 | } | ||
| 1420 | sirfport->rx_dma_items[i].xmit.head = | ||
| 1421 | sirfport->rx_dma_items[i].xmit.tail = 0; | ||
| 1422 | } | ||
| 1423 | if (sirfport->rx_dma_chan) | ||
| 1424 | dmaengine_slave_config(sirfport->rx_dma_chan, &slv_cfg); | ||
| 1425 | sirfport->tx_dma_chan = dma_request_slave_channel(port->dev, "tx"); | ||
| 1426 | if (sirfport->tx_dma_chan) | ||
| 1427 | dmaengine_slave_config(sirfport->tx_dma_chan, &tx_slv_cfg); | ||
| 1519 | 1428 | ||
| 1429 | return 0; | ||
| 1430 | alloc_coherent_err: | ||
| 1431 | for (j = 0; j < i; j++) | ||
| 1432 | dma_free_coherent(port->dev, SIRFSOC_RX_DMA_BUF_SIZE, | ||
| 1433 | sirfport->rx_dma_items[j].xmit.buf, | ||
| 1434 | sirfport->rx_dma_items[j].dma_addr); | ||
| 1435 | dma_release_channel(sirfport->rx_dma_chan); | ||
| 1520 | port_err: | 1436 | port_err: |
| 1521 | clk_put(sirfport->clk); | 1437 | clk_put(sirfport->clk); |
| 1522 | err: | 1438 | err: |
| @@ -1529,6 +1445,19 @@ static int sirfsoc_uart_remove(struct platform_device *pdev) | |||
| 1529 | struct uart_port *port = &sirfport->port; | 1445 | struct uart_port *port = &sirfport->port; |
| 1530 | clk_put(sirfport->clk); | 1446 | clk_put(sirfport->clk); |
| 1531 | uart_remove_one_port(&sirfsoc_uart_drv, port); | 1447 | uart_remove_one_port(&sirfsoc_uart_drv, port); |
| 1448 | if (sirfport->rx_dma_chan) { | ||
| 1449 | int i; | ||
| 1450 | dmaengine_terminate_all(sirfport->rx_dma_chan); | ||
| 1451 | dma_release_channel(sirfport->rx_dma_chan); | ||
| 1452 | for (i = 0; i < SIRFSOC_RX_LOOP_BUF_CNT; i++) | ||
| 1453 | dma_free_coherent(port->dev, SIRFSOC_RX_DMA_BUF_SIZE, | ||
| 1454 | sirfport->rx_dma_items[i].xmit.buf, | ||
| 1455 | sirfport->rx_dma_items[i].dma_addr); | ||
| 1456 | } | ||
| 1457 | if (sirfport->tx_dma_chan) { | ||
| 1458 | dmaengine_terminate_all(sirfport->tx_dma_chan); | ||
| 1459 | dma_release_channel(sirfport->tx_dma_chan); | ||
| 1460 | } | ||
| 1532 | return 0; | 1461 | return 0; |
| 1533 | } | 1462 | } |
| 1534 | 1463 | ||
diff --git a/drivers/tty/serial/sirfsoc_uart.h b/drivers/tty/serial/sirfsoc_uart.h index b7d679c0881b..8a6eddad2f3c 100644 --- a/drivers/tty/serial/sirfsoc_uart.h +++ b/drivers/tty/serial/sirfsoc_uart.h | |||
| @@ -392,9 +392,6 @@ struct sirfsoc_uart_register sirfsoc_uart = { | |||
| 392 | /* Indicate how many buffers used */ | 392 | /* Indicate how many buffers used */ |
| 393 | #define SIRFSOC_RX_LOOP_BUF_CNT 2 | 393 | #define SIRFSOC_RX_LOOP_BUF_CNT 2 |
| 394 | 394 | ||
| 395 | /* Indicate if DMA channel valid */ | ||
| 396 | #define IS_DMA_CHAN_VALID(x) ((x) != -1) | ||
| 397 | #define UNVALID_DMA_CHAN -1 | ||
| 398 | /* For Fast Baud Rate Calculation */ | 395 | /* For Fast Baud Rate Calculation */ |
| 399 | struct sirfsoc_baudrate_to_regv { | 396 | struct sirfsoc_baudrate_to_regv { |
| 400 | unsigned int baud_rate; | 397 | unsigned int baud_rate; |
| @@ -423,8 +420,6 @@ struct sirfsoc_uart_port { | |||
| 423 | /* for SiRFmarco, there are SET/CLR for UART_INT_EN */ | 420 | /* for SiRFmarco, there are SET/CLR for UART_INT_EN */ |
| 424 | bool is_marco; | 421 | bool is_marco; |
| 425 | struct sirfsoc_uart_register *uart_reg; | 422 | struct sirfsoc_uart_register *uart_reg; |
| 426 | int rx_dma_no; | ||
| 427 | int tx_dma_no; | ||
| 428 | struct dma_chan *rx_dma_chan; | 423 | struct dma_chan *rx_dma_chan; |
| 429 | struct dma_chan *tx_dma_chan; | 424 | struct dma_chan *tx_dma_chan; |
| 430 | dma_addr_t tx_dma_addr; | 425 | dma_addr_t tx_dma_addr; |
