Exemplo n.º 1
0
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);
}
Exemplo n.º 2
0
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);
}
Exemplo n.º 3
0
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);
}
Exemplo n.º 4
0
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;
}
Exemplo n.º 5
0
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);
}
Exemplo n.º 6
0
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);
	}
}
Exemplo n.º 7
0
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;
}
Exemplo n.º 8
0
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);
}
Exemplo n.º 9
0
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));
	}
}
Exemplo n.º 10
0
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);
}
Exemplo n.º 11
0
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;
}
Exemplo n.º 12
0
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;
}
Exemplo n.º 13
0
static unsigned int leonuart_tx_empty(struct uart_port *port)
{
	return UART_GET_STATUS(port) & LEON_REG_UART_STATUS_THE ? TIOCSER_TEMT :
	    0;
}
Exemplo n.º 14
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;
}
Exemplo n.º 15
0
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;
}