static void tegra_uart_handle_rx_pio(struct tegra_uart_port *tup, struct tty_port *tty) { int copied; do { char flag = TTY_NORMAL; unsigned long lsr = 0; unsigned char ch; lsr = tegra_uart_read(tup, UART_LSR); if (!(lsr & UART_LSR_DR)) break; flag = tegra_uart_decode_rx_error(tup, lsr); ch = (unsigned char) tegra_uart_read(tup, UART_RX); tup->uport.icount.rx++; if (!uart_handle_sysrq_char(&tup->uport, ch) && tty) { copied = tty_insert_flip_char_lock(tty, ch, flag); if (copied != 1) dev_err(tup->uport.dev, "RxData PIO to tty layer failed\n"); } } while (1); return; }
static void tegra_uart_handle_rx_pio(struct tegra_uart_port *tup, struct tty_port *tty) { do { char flag = TTY_NORMAL; unsigned long lsr = 0; unsigned char ch; lsr = tegra_uart_read(tup, UART_LSR); if (!(lsr & UART_LSR_DR)) break; flag = tegra_uart_decode_rx_error(tup, lsr); ch = (unsigned char) tegra_uart_read(tup, UART_RX); tup->uport.icount.rx++; if (!uart_handle_sysrq_char(&tup->uport, ch) && tty) tty_insert_flip_char(tty, ch, flag); } while (1); }
static irqreturn_t tegra_uart_isr(int irq, void *data) { struct tegra_uart_port *tup = data; struct uart_port *u = &tup->uport; unsigned long iir; unsigned long ier; bool is_rx_int = false; unsigned long flags; spin_lock_irqsave(&u->lock, flags); while (1) { iir = tegra_uart_read(tup, UART_IIR); if (iir & UART_IIR_NO_INT) { if (is_rx_int) { tegra_uart_handle_rx_dma(tup); if (tup->rx_in_progress) { ier = tup->ier_shadow; ier |= (UART_IER_RLSI | UART_IER_RTOIE | TEGRA_UART_IER_EORD); tup->ier_shadow = ier; tegra_uart_write(tup, ier, UART_IER); } } spin_unlock_irqrestore(&u->lock, flags); return IRQ_HANDLED; } switch ((iir >> 1) & 0x7) { case 0: /* Modem signal change interrupt */ tegra_uart_handle_modem_signal_change(u); break; case 1: /* Transmit interrupt only triggered when using PIO */ tup->ier_shadow &= ~UART_IER_THRI; tegra_uart_write(tup, tup->ier_shadow, UART_IER); tegra_uart_handle_tx_pio(tup); break; case 4: /* End of data */ case 6: /* Rx timeout */ case 2: /* Receive */ if (!is_rx_int) { is_rx_int = true; /* Disable Rx interrupts */ ier = tup->ier_shadow; ier |= UART_IER_RDI; tegra_uart_write(tup, ier, UART_IER); ier &= ~(UART_IER_RDI | UART_IER_RLSI | UART_IER_RTOIE | TEGRA_UART_IER_EORD); tup->ier_shadow = ier; tegra_uart_write(tup, ier, UART_IER); } break; case 3: /* Receive error */ tegra_uart_decode_rx_error(tup, tegra_uart_read(tup, UART_LSR)); break; case 5: /* break nothing to handle */ case 7: /* break nothing to handle */ break; } } }