static void tegra_shutdown(struct uart_port *u) { struct tegra_uart_port *t; t = container_of(u, struct tegra_uart_port, uport); dev_vdbg(u->dev, "+tegra_shutdown\n"); if (t->is_irda && t->irda_shutdown) t->irda_shutdown(); tegra_uart_hw_deinit(t); t->rx_in_progress = 0; t->tx_in_progress = 0; tegra_uart_free_rx_dma(t); if (t->use_tx_dma) { tegra_dma_free_channel(t->tx_dma); t->tx_dma = NULL; t->use_tx_dma = false; dma_unmap_single(t->uport.dev, t->xmit_dma_addr, UART_XMIT_SIZE, DMA_TO_DEVICE); t->xmit_dma_addr = 0; } free_irq(u->irq, t); tasklet_kill(&t->tlet); dev_vdbg(u->dev, "-tegra_shutdown\n"); }
static int tegra_uart_init_rx_dma(struct tegra_uart_port *t) { dma_addr_t rx_dma_phys; void *rx_dma_virt; t->rx_dma = tegra_dma_allocate_channel(TEGRA_DMA_MODE_CONTINUOUS, "uart_rx_%d", t->uport.line); if (!t->rx_dma) { dev_err(t->uport.dev, "%s: failed to allocate RX DMA.\n", __func__); return -ENODEV; } t->rx_dma_req.size = UART_RX_DMA_BUFFER_SIZE; rx_dma_virt = dma_alloc_coherent(t->uport.dev, t->rx_dma_req.size, &rx_dma_phys, GFP_KERNEL); if (!rx_dma_virt) { dev_err(t->uport.dev, "DMA buffers allocate failed\n"); goto fail; } t->rx_dma_req.dest_addr = rx_dma_phys; t->rx_dma_req.virt_addr = rx_dma_virt; t->rx_dma_req.source_addr = (unsigned long)t->uport.mapbase; t->rx_dma_req.source_wrap = 4; t->rx_dma_req.dest_wrap = 0; t->rx_dma_req.to_memory = 1; t->rx_dma_req.source_bus_width = 8; t->rx_dma_req.dest_bus_width = 32; t->rx_dma_req.req_sel = dma_req_sel[t->uport.line]; t->rx_dma_req.complete = tegra_rx_dma_complete_callback; t->rx_dma_req.threshold = tegra_rx_dma_threshold_callback; t->rx_dma_req.dev = t; return 0; fail: tegra_uart_free_rx_dma(t); return -ENODEV; }
static int tegra_uart_hw_init(struct tegra_uart_port *t) { unsigned char ier; unsigned char sir; dev_vdbg(t->uport.dev, "+tegra_uart_hw_init\n"); t->fcr_shadow = 0; t->mcr_shadow = 0; t->lcr_shadow = 0; t->ier_shadow = 0; t->baud = 0; pm_runtime_get_sync((&t->uport)->dev); clk_prepare_enable(t->clk); /* Reset the UART controller to clear all previous status.*/ tegra_periph_reset_assert(t->clk); udelay(100); tegra_periph_reset_deassert(t->clk); udelay(100); t->rx_in_progress = 0; /* * Set the trigger level * * For PIO mode: * * For receive, this will interrupt the CPU after that many number of * bytes are received, for the remaining bytes the receive timeout * interrupt is received. * * Rx high watermark is set to 4. * * For transmit, if the trasnmit interrupt is enabled, this will * interrupt the CPU when the number of entries in the FIFO reaches the * low watermark. * * Tx low watermark is set to 8. * * For DMA mode: * * Set the Tx trigger to 4. This should match the DMA burst size that * programmed in the DMA registers. */ t->fcr_shadow = UART_FCR_ENABLE_FIFO; t->fcr_shadow |= UART_FCR_R_TRIG_01; t->fcr_shadow |= TEGRA_UART_TX_TRIG_8B; uart_writeb(t, t->fcr_shadow, UART_FCR); if (t->use_rx_dma) { /* * Initialize the UART for a simple default configuration * so that the receive DMA buffer may be enqueued */ t->lcr_shadow = 3; /* no parity, stop, 8 data bits */ tegra_set_baudrate(t, 115200); t->fcr_shadow |= UART_FCR_DMA_SELECT; uart_writeb(t, t->fcr_shadow, UART_FCR); if (tegra_start_dma_rx(t)) { dev_err(t->uport.dev, "Rx DMA enqueue failed\n"); tegra_uart_free_rx_dma(t); t->fcr_shadow &= ~UART_FCR_DMA_SELECT; uart_writeb(t, t->fcr_shadow, UART_FCR); } } else { uart_writeb(t, t->fcr_shadow, UART_FCR); } t->rx_in_progress = 1; /* * Enable IE_RXS for the receive status interrupts like line errros. * Enable IE_RX_TIMEOUT to get the bytes which cannot be DMA'd. * * If using DMA mode, enable EORD instead of receive interrupt which * will interrupt after the UART is done with the receive instead of * the interrupt when the FIFO "threshold" is reached. * * EORD is different interrupt than RX_TIMEOUT - RX_TIMEOUT occurs when * the DATA is sitting in the FIFO and couldn't be transferred to the * DMA as the DMA size alignment(4 bytes) is not met. EORD will be * triggered when there is a pause of the incomming data stream for 4 * characters long. * * For pauses in the data which is not aligned to 4 bytes, we get * both the EORD as well as RX_TIMEOUT - SW sees RX_TIMEOUT first * then the EORD. * * Don't get confused, believe in the magic of nvidia hw...:-) */ ier = 0; ier |= UART_IER_RLSI | UART_IER_RTOIE; if (t->use_rx_dma) ier |= UART_IER_EORD; else ier |= UART_IER_RDI; t->ier_shadow = ier; uart_writeb(t, ier, UART_IER); /* * Tegra UART controller also support SIR PHY * Enabled IRDA will transmit each zero bit as a short IR pulse. */ if (t->is_irda) { dev_vdbg(t->uport.dev, "SIR enabled\n"); sir = TEGRA_UART_SIR_ENABLED; uart_writeb(t, sir, TEGRA_UART_IRDA_CSR); } t->uart_state = TEGRA_UART_OPENED; dev_vdbg(t->uport.dev, "-tegra_uart_hw_init\n"); return 0; }