| .. | .. |
|---|
| 11 | 11 | |
|---|
| 12 | 12 | #include "8250.h" |
|---|
| 13 | 13 | |
|---|
| 14 | | -#ifdef CONFIG_ARCH_ROCKCHIP |
|---|
| 14 | +#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI) |
|---|
| 15 | 15 | #define MAX_TX_BYTES 64 |
|---|
| 16 | 16 | #define MAX_FIFO_SIZE 64 |
|---|
| 17 | 17 | #define UART_RFL_16550A 0x21 |
|---|
| 18 | +#define DW_UART_DMASA 0x2a |
|---|
| 18 | 19 | #endif |
|---|
| 19 | 20 | |
|---|
| 20 | 21 | static void __dma_tx_complete(void *param) |
|---|
| .. | .. |
|---|
| 40 | 41 | uart_write_wakeup(&p->port); |
|---|
| 41 | 42 | |
|---|
| 42 | 43 | ret = serial8250_tx_dma(p); |
|---|
| 43 | | - if (ret) { |
|---|
| 44 | | - p->ier |= UART_IER_THRI; |
|---|
| 45 | | -#ifdef CONFIG_ARCH_ROCKCHIP |
|---|
| 46 | | - p->ier |= UART_IER_PTIME; |
|---|
| 47 | | -#endif |
|---|
| 48 | | - serial_port_out(&p->port, UART_IER, p->ier); |
|---|
| 49 | | - } |
|---|
| 44 | + if (ret) |
|---|
| 45 | + serial8250_set_THRI(p); |
|---|
| 50 | 46 | |
|---|
| 51 | 47 | spin_unlock_irqrestore(&p->port.lock, flags); |
|---|
| 52 | 48 | } |
|---|
| 53 | 49 | |
|---|
| 54 | | -#ifdef CONFIG_ARCH_ROCKCHIP |
|---|
| 50 | +#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI) |
|---|
| 55 | 51 | |
|---|
| 56 | 52 | static void __dma_rx_complete(void *param) |
|---|
| 57 | 53 | { |
|---|
| .. | .. |
|---|
| 90 | 86 | struct uart_8250_dma *dma = p->dma; |
|---|
| 91 | 87 | struct tty_port *tty_port = &p->port.state->port; |
|---|
| 92 | 88 | struct dma_tx_state state; |
|---|
| 89 | + enum dma_status dma_status; |
|---|
| 93 | 90 | int count; |
|---|
| 94 | 91 | |
|---|
| 95 | | - dma->rx_running = 0; |
|---|
| 96 | | - dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state); |
|---|
| 92 | + /* |
|---|
| 93 | + * New DMA Rx can be started during the completion handler before it |
|---|
| 94 | + * could acquire port's lock and it might still be ongoing. Don't to |
|---|
| 95 | + * anything in such case. |
|---|
| 96 | + */ |
|---|
| 97 | + dma_status = dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state); |
|---|
| 98 | + if (dma_status == DMA_IN_PROGRESS) |
|---|
| 99 | + return; |
|---|
| 97 | 100 | |
|---|
| 98 | 101 | count = dma->rx_size - state.residue; |
|---|
| 99 | 102 | |
|---|
| 100 | 103 | tty_insert_flip_string(tty_port, dma->rx_buf, count); |
|---|
| 101 | 104 | p->port.icount.rx += count; |
|---|
| 105 | + dma->rx_running = 0; |
|---|
| 102 | 106 | |
|---|
| 103 | 107 | tty_flip_buffer_push(tty_port); |
|---|
| 104 | 108 | } |
|---|
| 105 | 109 | |
|---|
| 110 | +static void dma_rx_complete(void *param) |
|---|
| 111 | +{ |
|---|
| 112 | + struct uart_8250_port *p = param; |
|---|
| 113 | + struct uart_8250_dma *dma = p->dma; |
|---|
| 114 | + unsigned long flags; |
|---|
| 115 | + |
|---|
| 116 | + spin_lock_irqsave(&p->port.lock, flags); |
|---|
| 117 | + if (dma->rx_running) |
|---|
| 118 | + __dma_rx_complete(p); |
|---|
| 119 | + spin_unlock_irqrestore(&p->port.lock, flags); |
|---|
| 120 | +} |
|---|
| 106 | 121 | #endif |
|---|
| 107 | 122 | |
|---|
| 108 | 123 | int serial8250_tx_dma(struct uart_8250_port *p) |
|---|
| .. | .. |
|---|
| 110 | 125 | struct uart_8250_dma *dma = p->dma; |
|---|
| 111 | 126 | struct circ_buf *xmit = &p->port.state->xmit; |
|---|
| 112 | 127 | struct dma_async_tx_descriptor *desc; |
|---|
| 128 | + struct uart_port *up = &p->port; |
|---|
| 113 | 129 | int ret; |
|---|
| 114 | 130 | |
|---|
| 115 | | - if (dma->tx_running) |
|---|
| 131 | + if (dma->tx_running) { |
|---|
| 132 | + if (up->x_char) { |
|---|
| 133 | + dmaengine_pause(dma->txchan); |
|---|
| 134 | + uart_xchar_out(up, UART_TX); |
|---|
| 135 | + dmaengine_resume(dma->txchan); |
|---|
| 136 | + } |
|---|
| 116 | 137 | return 0; |
|---|
| 138 | + } else if (up->x_char) { |
|---|
| 139 | + uart_xchar_out(up, UART_TX); |
|---|
| 140 | + } |
|---|
| 117 | 141 | |
|---|
| 118 | 142 | if (uart_tx_stopped(&p->port) || uart_circ_empty(xmit)) { |
|---|
| 119 | 143 | /* We have been called from __dma_tx_complete() */ |
|---|
| .. | .. |
|---|
| 122 | 146 | } |
|---|
| 123 | 147 | |
|---|
| 124 | 148 | dma->tx_size = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); |
|---|
| 125 | | -#ifdef CONFIG_ARCH_ROCKCHIP |
|---|
| 149 | +#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI) |
|---|
| 126 | 150 | if (dma->tx_size < MAX_TX_BYTES) { |
|---|
| 127 | 151 | ret = -EBUSY; |
|---|
| 128 | 152 | goto err; |
|---|
| .. | .. |
|---|
| 146 | 170 | dma_sync_single_for_device(dma->txchan->device->dev, dma->tx_addr, |
|---|
| 147 | 171 | UART_XMIT_SIZE, DMA_TO_DEVICE); |
|---|
| 148 | 172 | |
|---|
| 173 | +#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI) |
|---|
| 174 | + /* Clear uart dma request before start dma */ |
|---|
| 175 | + serial_port_out(&p->port, DW_UART_DMASA, 0x1); |
|---|
| 176 | +#endif |
|---|
| 149 | 177 | dma_async_issue_pending(dma->txchan); |
|---|
| 150 | 178 | if (dma->tx_err) { |
|---|
| 151 | 179 | dma->tx_err = 0; |
|---|
| 152 | | - if (p->ier & UART_IER_THRI) { |
|---|
| 153 | | - p->ier &= ~UART_IER_THRI; |
|---|
| 154 | | -#ifdef CONFIG_ARCH_ROCKCHIP |
|---|
| 155 | | - p->ier &= ~UART_IER_PTIME; |
|---|
| 156 | | -#endif |
|---|
| 157 | | - serial_out(p, UART_IER, p->ier); |
|---|
| 158 | | - } |
|---|
| 180 | + serial8250_clear_THRI(p); |
|---|
| 159 | 181 | } |
|---|
| 160 | 182 | return 0; |
|---|
| 161 | 183 | err: |
|---|
| .. | .. |
|---|
| 163 | 185 | return ret; |
|---|
| 164 | 186 | } |
|---|
| 165 | 187 | |
|---|
| 166 | | -#ifdef CONFIG_ARCH_ROCKCHIP |
|---|
| 188 | +#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI) |
|---|
| 167 | 189 | |
|---|
| 168 | 190 | int serial8250_rx_dma(struct uart_8250_port *p) |
|---|
| 169 | 191 | { |
|---|
| .. | .. |
|---|
| 236 | 258 | return -EBUSY; |
|---|
| 237 | 259 | |
|---|
| 238 | 260 | dma->rx_running = 1; |
|---|
| 239 | | - desc->callback = __dma_rx_complete; |
|---|
| 261 | + desc->callback = dma_rx_complete; |
|---|
| 240 | 262 | desc->callback_param = p; |
|---|
| 241 | 263 | |
|---|
| 242 | 264 | dma->rx_cookie = dmaengine_submit(desc); |
|---|
| .. | .. |
|---|
| 275 | 297 | dma->rxconf.direction = DMA_DEV_TO_MEM; |
|---|
| 276 | 298 | dma->rxconf.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; |
|---|
| 277 | 299 | dma->rxconf.src_addr = rx_dma_addr + UART_RX; |
|---|
| 278 | | -#ifdef CONFIG_ARCH_ROCKCHIP |
|---|
| 300 | +#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI) |
|---|
| 279 | 301 | if ((p->port.fifosize / 4) < 16) |
|---|
| 280 | 302 | dma->rxconf.src_maxburst = p->port.fifosize / 4; |
|---|
| 281 | 303 | else |
|---|
| .. | .. |
|---|
| 285 | 307 | dma->txconf.direction = DMA_MEM_TO_DEV; |
|---|
| 286 | 308 | dma->txconf.dst_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; |
|---|
| 287 | 309 | dma->txconf.dst_addr = tx_dma_addr + UART_TX; |
|---|
| 288 | | -#ifdef CONFIG_ARCH_ROCKCHIP |
|---|
| 310 | +#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI) |
|---|
| 289 | 311 | dma->txconf.dst_maxburst = 16; |
|---|
| 290 | 312 | #endif |
|---|
| 291 | 313 | dma_cap_zero(mask); |
|---|
| .. | .. |
|---|
| 301 | 323 | /* 8250 rx dma requires dmaengine driver to support pause/terminate */ |
|---|
| 302 | 324 | ret = dma_get_slave_caps(dma->rxchan, &caps); |
|---|
| 303 | 325 | if (ret) |
|---|
| 304 | | - goto err_rx; |
|---|
| 326 | + goto release_rx; |
|---|
| 305 | 327 | if (!caps.cmd_pause || !caps.cmd_terminate || |
|---|
| 306 | 328 | caps.residue_granularity == DMA_RESIDUE_GRANULARITY_DESCRIPTOR) { |
|---|
| 307 | 329 | ret = -EINVAL; |
|---|
| 308 | | - goto err_rx; |
|---|
| 330 | + goto release_rx; |
|---|
| 309 | 331 | } |
|---|
| 310 | 332 | |
|---|
| 311 | 333 | dmaengine_slave_config(dma->rxchan, &dma->rxconf); |
|---|
| 312 | 334 | |
|---|
| 313 | 335 | /* RX buffer */ |
|---|
| 314 | | -#ifdef CONFIG_ARCH_ROCKCHIP |
|---|
| 336 | +#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI) |
|---|
| 315 | 337 | if (!dma->rx_size) |
|---|
| 316 | 338 | dma->rx_size = PAGE_SIZE * 2; |
|---|
| 317 | 339 | #else |
|---|
| .. | .. |
|---|
| 321 | 343 | |
|---|
| 322 | 344 | dma->rx_buf = dma_alloc_coherent(dma->rxchan->device->dev, dma->rx_size, |
|---|
| 323 | 345 | &dma->rx_addr, GFP_KERNEL); |
|---|
| 324 | | - |
|---|
| 325 | 346 | if (!dma->rx_buf) { |
|---|
| 326 | 347 | ret = -ENOMEM; |
|---|
| 327 | | - goto err_rx; |
|---|
| 348 | + goto release_rx; |
|---|
| 328 | 349 | } |
|---|
| 329 | 350 | |
|---|
| 330 | 351 | /* Get a channel for TX */ |
|---|
| .. | .. |
|---|
| 352 | 373 | dev_info_ratelimited(p->port.dev, "got rx dma channels only\n"); |
|---|
| 353 | 374 | } |
|---|
| 354 | 375 | |
|---|
| 355 | | -#ifdef CONFIG_ARCH_ROCKCHIP |
|---|
| 376 | +#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI) |
|---|
| 356 | 377 | /* start dma for rx*/ |
|---|
| 357 | 378 | serial8250_start_rx_dma(p); |
|---|
| 358 | 379 | #endif |
|---|
| 359 | 380 | return 0; |
|---|
| 360 | | - |
|---|
| 361 | | -err_rx: |
|---|
| 381 | +release_rx: |
|---|
| 362 | 382 | dma_release_channel(dma->rxchan); |
|---|
| 363 | 383 | return ret; |
|---|
| 364 | 384 | } |
|---|
| .. | .. |
|---|
| 377 | 397 | dma->rx_addr); |
|---|
| 378 | 398 | dma_release_channel(dma->rxchan); |
|---|
| 379 | 399 | dma->rxchan = NULL; |
|---|
| 380 | | -#ifdef CONFIG_ARCH_ROCKCHIP |
|---|
| 400 | +#if defined(CONFIG_ARCH_ROCKCHIP) && defined(CONFIG_NO_GKI) |
|---|
| 381 | 401 | dma->rx_running = 0; |
|---|
| 382 | 402 | #endif |
|---|
| 383 | 403 | /* Release TX resources */ |
|---|