/** * serial_omap_irq() - This handles the interrupt from one port * @irq: uart port irq number * @dev_id: uart port info */ static inline irqreturn_t serial_omap_irq(int irq, void *dev_id) { struct uart_omap_port *up = dev_id; unsigned int iir, lsr; unsigned long flags; spin_lock_irqsave(&up->port.lock, flags); #ifdef CONFIG_PM /* * This will enable the clock for some reason if the * clocks get disabled. This would enable the ICK also * in case if the Idle state is set and the PRCM modul * just shutdown the ICK because of inactivity. */ omap_uart_enable_clock_from_irq(up->pdev->id); #endif iir = serial_in(up, UART_IIR); if (iir & UART_IIR_NO_INT) { spin_unlock_irqrestore(&up->port.lock, flags); return IRQ_NONE; } lsr = serial_in(up, UART_LSR); if (iir & UART_IIR_RLSI) { if (!up->use_dma) { if (lsr & UART_LSR_DR) { receive_chars(up, &lsr); if (omap_is_console_port(&up->port) && (up->plat_hold_wakelock)) { spin_unlock(&up->port.lock); up->plat_hold_wakelock(up, WAKELK_IRQ); spin_lock(&up->port.lock); } } } else { up->ier &= ~UART_IER_RDI; serial_out(up, UART_IER, up->ier); if (serial_omap_start_rxdma(up) != 0) if (lsr & UART_LSR_DR) receive_chars(up, &lsr); } } check_modem_status(up); if ((lsr & UART_LSR_THRE) && (iir & UART_IIR_THRI)) transmit_chars(up); spin_unlock_irqrestore(&up->port.lock, flags); up->port_activity = jiffies; return IRQ_HANDLED; }
static void uart_tx_dma_callback(int lch, u16 ch_status, void *data) { struct uart_omap_port *up = (struct uart_omap_port *)data; struct circ_buf *xmit = &up->port.state->xmit; xmit->tail = (xmit->tail + up->uart_dma.tx_buf_size) & \ (UART_XMIT_SIZE - 1); up->port.icount.tx += up->uart_dma.tx_buf_size; if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&up->port); if (uart_circ_empty(xmit)) { spin_lock(&(up->uart_dma.tx_lock)); serial_omap_stop_tx(&up->port); up->uart_dma.tx_dma_used = false; spin_unlock(&(up->uart_dma.tx_lock)); if (up->plat_hold_wakelock) (up->plat_hold_wakelock(up, WAKELK_TX)); } else { #ifdef CONFIG_PM /* * This will enable the clock for some reason if the * clocks get disabled. This would enable the ICK also * in case if the Idle state is set and the PRCM modul * just shutdown the ICK because of inactivity. */ omap_uart_enable_clock_from_irq(up->pdev->id); #endif omap_stop_dma(up->uart_dma.tx_dma_channel); serial_omap_continue_tx(up); } up->port_activity = jiffies; return; }