| .. | .. | 
|---|
| 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 */ | 
|---|