void serial8250_rx_dma_flush(struct uart_8250_port *p) { struct uart_8250_dma *dma = p->dma; if (dma->rx_running) { dmaengine_pause(dma->rxchan); __dma_rx_complete(p); dmaengine_terminate_async(dma->rxchan); } }
int serial8250_rx_dma(struct uart_8250_port *p, unsigned int iir) { struct uart_8250_dma *dma = p->dma; struct dma_async_tx_descriptor *desc; struct dma_tx_state state; int dma_status; dma_status = dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state); switch (iir & 0x3f) { case UART_IIR_RLSI: /* 8250_core handles errors and break interrupts */ return -EIO; case UART_IIR_RX_TIMEOUT: /* * If RCVR FIFO trigger level was not reached, complete the * transfer and let 8250_core copy the remaining data. */ if (dma_status == DMA_IN_PROGRESS) { dmaengine_pause(dma->rxchan); __dma_rx_complete(p); } return -ETIMEDOUT; default: break; } if (dma_status) return 0; desc = dmaengine_prep_slave_single(dma->rxchan, dma->rx_addr, dma->rx_size, DMA_DEV_TO_MEM, DMA_PREP_INTERRUPT | DMA_CTRL_ACK); if (!desc) return -EBUSY; desc->callback = __dma_rx_complete; desc->callback_param = p; dma->rx_cookie = dmaengine_submit(desc); dma_sync_single_for_device(dma->rxchan->device->dev, dma->rx_addr, dma->rx_size, DMA_FROM_DEVICE); dma_async_issue_pending(dma->rxchan); return 0; }