static void apbuart_rx_chars(struct uart_port *port) { struct tty_struct *tty = port->state->port.tty; unsigned int status, ch, rsr, flag; unsigned int max_chars = port->fifosize; status = UART_GET_STATUS(port); while (UART_RX_DATA(status) && (max_chars--)) { ch = UART_GET_CHAR(port); flag = TTY_NORMAL; port->icount.rx++; rsr = UART_GET_STATUS(port) | UART_DUMMY_RSR_RX; UART_PUT_STATUS(port, 0); if (rsr & UART_STATUS_ERR) { if (rsr & UART_STATUS_BR) { rsr &= ~(UART_STATUS_FE | UART_STATUS_PE); port->icount.brk++; if (uart_handle_break(port)) goto ignore_char; } else if (rsr & UART_STATUS_PE) { port->icount.parity++; } else if (rsr & UART_STATUS_FE) { port->icount.frame++; } if (rsr & UART_STATUS_OE) port->icount.overrun++; rsr &= port->read_status_mask; if (rsr & UART_STATUS_PE) flag = TTY_PARITY; else if (rsr & UART_STATUS_FE) flag = TTY_FRAME; } if (uart_handle_sysrq_char(port, ch)) goto ignore_char; uart_insert_char(port, rsr, UART_STATUS_OE, ch, flag); ignore_char: status = UART_GET_STATUS(port); } tty_flip_buffer_push(tty); }
static void apbuart_console_putchar(struct uart_port *port, int ch) { unsigned int status; do { status = UART_GET_STATUS(port); } while (!UART_TX_READY(status)); UART_PUT_CHAR(port, ch); }
static void apbuart_start_tx(struct uart_port *port) { unsigned int cr; cr = UART_GET_CTRL(port); cr |= UART_CTRL_TI; UART_PUT_CTRL(port, cr); if (UART_GET_STATUS(port) & UART_STATUS_THE) apbuart_tx_chars(port); }
static int apbuart_scan_fifo_size(struct uart_port *port, int portnumber) { int ctrl, loop = 0; int status; int fifosize; unsigned long flags; ctrl = UART_GET_CTRL(port); local_irq_save(flags); UART_PUT_CTRL(port, ctrl | UART_CTRL_TE); while (!UART_TX_READY(UART_GET_STATUS(port))) loop++; UART_PUT_CTRL(port, ctrl & ~(UART_CTRL_TE)); fifosize = 1; UART_PUT_CHAR(port, 0); status = UART_GET_STATUS(port); while (((status >> 20) & 0x3F) == fifosize) { fifosize++; UART_PUT_CHAR(port, 0); status = UART_GET_STATUS(port); } fifosize--; UART_PUT_CTRL(port, ctrl); local_irq_restore(flags); if (fifosize == 0) fifosize = 1; return fifosize; }
static void leonuart_console_write(struct console *co, const char *s, unsigned int count) { struct uart_port *port = &leon_ports[co->index].port; unsigned int status, old_cr; int i; /* * First save the CR then disable the interrupts */ old_cr = UART_GET_CTRL(port); UART_PUT_CTRL(port, (old_cr & ~(LEON_REG_UART_CTRL_RI | LEON_REG_UART_CTRL_TI)) | (LEON_REG_UART_CTRL_RE | LEON_REG_UART_CTRL_TE)); /* * Now, do each character */ for (i = 0; i < count; i++) { do { status = UART_GET_STATUS(port); } while (!UART_TX_READY(status)); UART_PUT_CHAR(port, s[i]); if (s[i] == '\n') { do { status = UART_GET_STATUS(port); } while (!UART_TX_READY(status)); UART_PUT_CHAR(port, '\r'); } } /* * Finally, wait for transmitter to become empty * and restore the TCR */ do { status = UART_GET_STATUS(port); } while (!UART_TX_READY(status)); UART_PUT_CTRL(port, old_cr); }
static void leonuart_start_tx(struct uart_port *port/*, unsigned int tty_start*/) { unsigned int cr; cr = UART_GET_CTRL(port); cr |= LEON_REG_UART_CTRL_TI; UART_PUT_CTRL(port, cr); if (UART_GET_STATUS(port) & LEON_REG_UART_STATUS_THE) { leonuart_tx_chars(port); } }
static irqreturn_t apbuart_int(int irq, void *dev_id) { struct uart_port *port = dev_id; unsigned int status; spin_lock(&port->lock); status = UART_GET_STATUS(port); if (status & UART_STATUS_DR) apbuart_rx_chars(port); if (status & UART_STATUS_THE) apbuart_tx_chars(port); spin_unlock(&port->lock); return IRQ_HANDLED; }
static void apbuart_console_write(struct console *co, const char *s, unsigned int count) { struct uart_port *port = &grlib_apbuart_ports[co->index]; unsigned int status, old_cr, new_cr; old_cr = UART_GET_CTRL(port); new_cr = old_cr & ~(UART_CTRL_RI | UART_CTRL_TI); UART_PUT_CTRL(port, new_cr); uart_console_write(port, s, count, apbuart_console_putchar); do { status = UART_GET_STATUS(port); } while (!UART_TX_READY(status)); UART_PUT_CTRL(port, old_cr); }
static void __init apbuart_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits) { if (UART_GET_CTRL(port) & (UART_CTRL_RE | UART_CTRL_TE)) { unsigned int quot, status; status = UART_GET_STATUS(port); *parity = 'n'; if (status & UART_CTRL_PE) { if ((status & UART_CTRL_PS) == 0) *parity = 'e'; else *parity = 'o'; } *bits = 8; quot = UART_GET_SCAL(port) / 8; *baud = port->uartclk / (16 * (quot + 1)); } }
static void apbuart_console_write(struct console *co, const char *s, unsigned int count) { struct uart_port *port = &grlib_apbuart_ports[co->index]; unsigned int status, old_cr, new_cr; /* First save the CR then disable the interrupts */ old_cr = UART_GET_CTRL(port); new_cr = old_cr & ~(UART_CTRL_RI | UART_CTRL_TI); UART_PUT_CTRL(port, new_cr); uart_console_write(port, s, count, apbuart_console_putchar); /* * Finally, wait for transmitter to become empty * and restore the TCR */ do { status = UART_GET_STATUS(port); } while (!UART_TX_READY(status)); UART_PUT_CTRL(port, old_cr); }
irqreturn_t leonuart_int(int irq, void *dev_id) #endif { struct uart_port *port = dev_id; unsigned int status; spin_lock(&port->lock); status = UART_GET_STATUS(port); if (status & LEON_REG_UART_STATUS_DR) { #ifdef SUPPORT_SYSRQ leonuart_rx_chars(port, regs); #else leonuart_rx_chars(port); #endif } if (status & LEON_REG_UART_STATUS_THE) { leonuart_tx_chars(port); } spin_unlock(&port->lock); return IRQ_HANDLED; }
static unsigned int apbuart_tx_empty(struct uart_port *port) { unsigned int status = UART_GET_STATUS(port); return status & UART_STATUS_THE ? TIOCSER_TEMT : 0; }
static unsigned int leonuart_tx_empty(struct uart_port *port) { return UART_GET_STATUS(port) & LEON_REG_UART_STATUS_THE ? TIOCSER_TEMT : 0; }
leonuart_rx_chars(struct uart_port *port) #endif { struct tty_struct *tty = port->info->port.tty; unsigned int status, ch, rsr, flag; unsigned int max_chars = port->fifosize; status = UART_GET_STATUS(port); while (UART_RX_DATA(status) && (max_chars--)) { /* if (tty->flip.count >= TTY_FLIPBUF_SIZE) { tty->flip.work.func((void *)tty); if (tty->flip.count >= TTY_FLIPBUF_SIZE) { printk(KERN_WARNING "TTY_DONT_FLIP set\n"); return; } } */ ch = UART_GET_CHAR(port); flag = TTY_NORMAL; /**tty->flip.char_buf_ptr = ch; *tty->flip.flag_buf_ptr = TTY_NORMAL;*/ port->icount.rx++; /* * Note that the error handling code is * out of the main execution path */ rsr = UART_GET_STATUS(port) | UART_DUMMY_RSR_RX; UART_PUT_STATUS(port, 0); if (rsr & LEON_REG_UART_STATUS_ERR) { if (rsr & LEON_REG_UART_STATUS_BR) { rsr &= ~(LEON_REG_UART_STATUS_FE | LEON_REG_UART_STATUS_PE); port->icount.brk++; if (uart_handle_break(port)) goto ignore_char; } else if (rsr & LEON_REG_UART_STATUS_PE) { port->icount.parity++; } else if (rsr & LEON_REG_UART_STATUS_FE) { port->icount.frame++; } if (rsr & LEON_REG_UART_STATUS_OE) port->icount.overrun++; rsr &= port->read_status_mask; /* if (rsr & LEON_REG_UART_STATUS_PE) *tty->flip.flag_buf_ptr = TTY_PARITY; else if (rsr & LEON_REG_UART_STATUS_FE) *tty->flip.flag_buf_ptr = TTY_FRAME; */ if (rsr & LEON_REG_UART_STATUS_PE) flag = TTY_PARITY; else if (rsr & LEON_REG_UART_STATUS_FE) flag = TTY_FRAME; } if (uart_handle_sysrq_char(port, ch)) goto ignore_char; /* if ((rsr & port->ignore_status_mask) == 0) { tty->flip.flag_buf_ptr++; tty->flip.char_buf_ptr++; tty->flip.count++; } */ if ((rsr & port->ignore_status_mask) == 0) { tty_insert_flip_char(tty, ch, flag); } if ( rsr & LEON_REG_UART_STATUS_OE ) { /* * Overrun is special, since it's reported * immediately, and doesn't affect the current * character */ tty_insert_flip_char(tty, 0, TTY_OVERRUN); } ignore_char: status = UART_GET_STATUS(port); } tty_flip_buffer_push(tty); return; }
leonuart_rx_chars(struct uart_port *port) #endif { struct tty_struct *tty = port->info->tty; unsigned int status, ch, flag, rsr, max_count = 256; status = UART_GET_STATUS(port); while (UART_RX_DATA(status) && max_count--) { //if (tty->flip.count >= TTY_FLIPBUF_SIZE) { // if (tty->low_latency) // tty_flip_buffer_push(tty); /* * If this failed then we will throw away the * bytes but must do so to clear interrupts. */ //} ch = UART_GET_CHAR(port); flag = TTY_NORMAL; port->icount.rx++; /* * Note that the error handling code is * out of the main execution path */ rsr = UART_GET_STATUS(port) | UART_DUMMY_RSR_RX; UART_PUT_STATUS(port, 0); if (rsr & LEON_USTAT_ERROR) { if (rsr & LEON_USTAT_BR) { rsr &= ~(LEON_USTAT_FE | LEON_USTAT_PE); port->icount.brk++; if (uart_handle_break(port)) goto ignore_char; } else if (rsr & LEON_USTAT_PE) { port->icount.parity++; } else if (rsr & LEON_USTAT_FE) { port->icount.frame++; } if (rsr & LEON_USTAT_OV) port->icount.overrun++; rsr &= port->read_status_mask; if (rsr & LEON_USTAT_BR) flag = TTY_BREAK; else if (rsr & LEON_USTAT_PE) flag = TTY_PARITY; else if (rsr & LEON_USTAT_FE) flag = TTY_FRAME; } if (uart_handle_sysrq_char(port, ch)) goto ignore_char; if ((rsr & port->ignore_status_mask) == 0) { tty_insert_flip_char(tty, ch, flag); } if (rsr & LEON_USTAT_OV) { /* * Overrun is special, since it's reported * immediately, and doesn't affect the current * character */ tty_insert_flip_char(tty, 0, TTY_OVERRUN); } ignore_char: status = UART_GET_STATUS(port); } tty_flip_buffer_push(tty); return; }