diff options
-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; |