static int apbuart_scan_fifo_size(struct uart_port *port, int portnumber) { int ctrl; int status; int fifosize; unsigned long flags; ctrl = UART_GET_CTRL(port); printk("Testing fifo size for UART port %i: ", portnumber); /* * Enable the transceiver and wait for it to be ready to send data. * Clear interrupts so that this process will not be externally * interrupted in the middle (which can cause the transceiver to * drain prematurely). */ local_irq_save(flags); UART_PUT_CTRL(port, ctrl | LEON_REG_UART_CTRL_TE); while (!UART_TX_READY(UART_GET_STATUS(port))); /* * Disable the transceiver so data isn't actually sent during the * actual test. */ UART_PUT_CTRL(port, ctrl & ~(LEON_REG_UART_CTRL_TE)); fifosize = 1; UART_PUT_CHAR(port, 0); /* * So long as transmitting a character increments the tranceivier FIFO * length the FIFO must be at least that big. These bytes will automatically * drain off of the FIFO. */ 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); printk("got %i bytes.\n", fifosize); if (fifosize == 0) { fifosize = 1; } return fifosize; }
static int leonuart_startup(struct uart_port *port) { struct uart_leon_port *uap = (struct uart_leon_port *)port; int retval; unsigned int cr; /* * Allocate the IRQ */ retval = request_irq(port->irq, leonuart_int, 0, "leon", port); if (retval) return retval; /* * initialise the old status of the modem signals */ uap->old_status = 0; /* * Finally, enable interrupts */ cr = UART_GET_CTRL(port); UART_PUT_CTRL(port, cr | LEON_REG_UART_CTRL_RE | LEON_REG_UART_CTRL_TE | LEON_REG_UART_CTRL_RI | LEON_REG_UART_CTRL_TI); return 0; }
static void leonuart_stop_rx(struct uart_port *port) { unsigned int cr; cr = UART_GET_CTRL(port); cr &= ~(LEON_REG_UART_CTRL_RI); UART_PUT_CTRL(port, cr); }
static void leonuart_stop_tx(struct uart_port *port/*, unsigned int tty_stop*/) { unsigned int cr; cr = UART_GET_CTRL(port); cr &= ~LEON_REG_UART_CTRL_TI; UART_PUT_CTRL(port, cr); }
static void apbuart_stop_rx(struct uart_port *port) { unsigned int cr; cr = UART_GET_CTRL(port); cr &= ~(UART_CTRL_RI); UART_PUT_CTRL(port, cr); }
static void leonuart_set_termios(struct uart_port *port, struct termios *termios, struct termios *old) { unsigned int cr; unsigned long flags; unsigned int baud, quot; /* * Ask the core to calculate the divisor for us. */ baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); if (baud == 0) { panic("invalid baudrate %i\n", port->uartclk / 16); } quot = (uart_get_divisor(port, baud)) * 2; //uart_get_divisor calc a *16 uart freq, leon is *8 cr = UART_GET_CTRL(port); cr &= ~(LEON_UCTRL_PE | LEON_UCTRL_PS); if (termios->c_cflag & PARENB) { cr |= LEON_UCTRL_PE; if ((termios->c_cflag & PARODD)) cr |= LEON_UCTRL_PS; } spin_lock_irqsave(&port->lock, flags); /* * Update the per-port timeout. */ uart_update_timeout(port, termios->c_cflag, baud); port->read_status_mask = LEON_USTAT_OV; if (termios->c_iflag & INPCK) port->read_status_mask |= LEON_USTAT_FE | LEON_USTAT_PE; /* * Characters to ignore */ port->ignore_status_mask = 0; if (termios->c_iflag & IGNPAR) port->ignore_status_mask |= LEON_USTAT_FE | LEON_USTAT_PE; /* * Ignore all characters if CREAD is not set. */ if ((termios->c_cflag & CREAD) == 0) port->ignore_status_mask |= LEON_USTAT_OV | LEON_USTAT_FE | LEON_USTAT_PE; /* Set baud rate */ quot -= 1; UART_PUT_SCAL(port, quot); UART_PUT_CTRL(port, cr); spin_unlock_irqrestore(&port->lock, flags); }
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 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 void apbuart_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { unsigned int cr; unsigned long flags; unsigned int baud, quot; baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); if (baud == 0) panic("invalid baudrate %i\n", port->uartclk / 16); quot = (uart_get_divisor(port, baud)) * 2; cr = UART_GET_CTRL(port); cr &= ~(UART_CTRL_PE | UART_CTRL_PS); if (termios->c_cflag & PARENB) { cr |= UART_CTRL_PE; if ((termios->c_cflag & PARODD)) cr |= UART_CTRL_PS; } if (termios->c_cflag & CRTSCTS) cr |= UART_CTRL_FL; spin_lock_irqsave(&port->lock, flags); uart_update_timeout(port, termios->c_cflag, baud); port->read_status_mask = UART_STATUS_OE; if (termios->c_iflag & INPCK) port->read_status_mask |= UART_STATUS_FE | UART_STATUS_PE; port->ignore_status_mask = 0; if (termios->c_iflag & IGNPAR) port->ignore_status_mask |= UART_STATUS_FE | UART_STATUS_PE; if ((termios->c_cflag & CREAD) == 0) port->ignore_status_mask |= UART_DUMMY_RSR_RX; quot -= 1; UART_PUT_SCAL(port, quot); UART_PUT_CTRL(port, cr); spin_unlock_irqrestore(&port->lock, flags); }
static void apbuart_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { unsigned int cr; unsigned long flags; unsigned int baud, quot; /* Ask the core to calculate the divisor for us. */ baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); if (baud == 0) panic("invalid baudrate %i\n", port->uartclk / 16); /* uart_get_divisor calc a *16 uart freq, apbuart is *8 */ quot = (uart_get_divisor(port, baud)) * 2; cr = UART_GET_CTRL(port); cr &= ~(UART_CTRL_PE | UART_CTRL_PS); if (termios->c_cflag & PARENB) { cr |= UART_CTRL_PE; if ((termios->c_cflag & PARODD)) cr |= UART_CTRL_PS; } /* Enable flow control. */ if (termios->c_cflag & CRTSCTS) cr |= UART_CTRL_FL; spin_lock_irqsave(&port->lock, flags); /* Update the per-port timeout. */ uart_update_timeout(port, termios->c_cflag, baud); port->read_status_mask = UART_STATUS_OE; if (termios->c_iflag & INPCK) port->read_status_mask |= UART_STATUS_FE | UART_STATUS_PE; /* Characters to ignore */ port->ignore_status_mask = 0; if (termios->c_iflag & IGNPAR) port->ignore_status_mask |= UART_STATUS_FE | UART_STATUS_PE; /* Ignore all characters if CREAD is not set. */ if ((termios->c_cflag & CREAD) == 0) port->ignore_status_mask |= UART_DUMMY_RSR_RX; /* Set baud rate */ quot -= 1; UART_PUT_SCAL(port, quot); UART_PUT_CTRL(port, cr); spin_unlock_irqrestore(&port->lock, flags); }
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); }
static void apbuart_shutdown(struct uart_port *port) { unsigned int cr; /* disable all interrupts, disable the port */ cr = UART_GET_CTRL(port); UART_PUT_CTRL(port, cr & ~(UART_CTRL_RE | UART_CTRL_TE | UART_CTRL_RI | UART_CTRL_TI)); /* Free the interrupt */ free_irq(port->irq, port); }
static void apbuart_shutdown(struct uart_port *port) { unsigned int cr; cr = UART_GET_CTRL(port); UART_PUT_CTRL(port, cr & ~(UART_CTRL_RE | UART_CTRL_TE | UART_CTRL_RI | UART_CTRL_TI)); free_irq(port->irq, port); }
static int apbuart_startup(struct uart_port *port) { int retval; unsigned int cr; /* Allocate the IRQ */ retval = request_irq(port->irq, apbuart_int, 0, "apbuart", port); if (retval) return retval; /* Finally, enable interrupts */ cr = UART_GET_CTRL(port); UART_PUT_CTRL(port, cr | UART_CTRL_RE | UART_CTRL_TE | UART_CTRL_RI | UART_CTRL_TI); return 0; }
static int apbuart_startup(struct uart_port *port) { int retval; unsigned int cr; retval = request_irq(port->irq, apbuart_int, 0, "apbuart", port); if (retval) return retval; cr = UART_GET_CTRL(port); UART_PUT_CTRL(port, cr | UART_CTRL_RE | UART_CTRL_TE | UART_CTRL_RI | UART_CTRL_TI); return 0; }