예제 #1
0
static void
uart00_set_termios(struct uart_port *port, struct termios *termios,
		   struct termios *old)
{
	unsigned int uart_mc, old_ies, baud, quot;
	unsigned long flags;

	/*
	 * We don't support CREAD (yet)
	 */
	termios->c_cflag |= CREAD;

	/*
	 * Ask the core to calculate the divisor for us.
	 */
	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); 
	quot = uart_get_divisor(port, baud);

	/* byte size and parity */
	switch (termios->c_cflag & CSIZE) {
	case CS5:
		uart_mc = UART_MC_CLS_CHARLEN_5;
		break;
	case CS6:
		uart_mc = UART_MC_CLS_CHARLEN_6;
		break;
	case CS7:
		uart_mc = UART_MC_CLS_CHARLEN_7;
		break;
	default: // CS8
		uart_mc = UART_MC_CLS_CHARLEN_8;
		break;
	}
	if (termios->c_cflag & CSTOPB)
		uart_mc|= UART_MC_ST_TWO;
	if (termios->c_cflag & PARENB) {
		uart_mc |= UART_MC_PE_MSK;
		if (!(termios->c_cflag & PARODD))
			uart_mc |= UART_MC_EP_MSK;
	}

	spin_lock_irqsave(&port->lock, flags);

	/*
	 * Update the per-port timeout.
	 */
	uart_update_timeout(port, termios->c_cflag, baud);

	port->read_status_mask = UART_RDS_OE_MSK;
	if (termios->c_iflag & INPCK)
		port->read_status_mask |= UART_RDS_FE_MSK | UART_RDS_PE_MSK;
	if (termios->c_iflag & (BRKINT | PARMRK))
		port->read_status_mask |= UART_RDS_BI_MSK;

	/*
	 * Characters to ignore
	 */
	port->ignore_status_mask = 0;
	if (termios->c_iflag & IGNPAR)
		port->ignore_status_mask |= UART_RDS_FE_MSK | UART_RDS_PE_MSK;
	if (termios->c_iflag & IGNBRK) {
		port->ignore_status_mask |= UART_RDS_BI_MSK;
		/*
		 * If we're ignoring parity and break indicators,
		 * ignore overruns to (for real raw support).
		 */
		if (termios->c_iflag & IGNPAR)
			port->ignore_status_mask |= UART_RDS_OE_MSK;
	}

	/* first, disable everything */
	old_ies = UART_GET_IES(port); 

	if (UART_ENABLE_MS(port, termios->c_cflag))
		old_ies |= UART_IES_ME_MSK;

	/* Set baud rate */
	UART_PUT_DIV_LO(port, (quot & 0xff));
	UART_PUT_DIV_HI(port, ((quot & 0xf00) >> 8));

	UART_PUT_MC(port, uart_mc);
	UART_PUT_IES(port, old_ies);

	spin_unlock_irqrestore(&port->lock, flags);
}
예제 #2
0
static void uart00_change_speed(struct uart_port *port, u_int cflag, u_int iflag, u_int quot)
{
	u_int uart_mc=0, old_ies;
	unsigned long flags;

#ifdef DEBUG
	printk("uart00_set_cflag(0x%x) called\n", cflag);
#endif
	/* byte size and parity */
	switch (cflag & CSIZE) {
	case CS5: uart_mc = UART_MC_CLS_CHARLEN_5; break;
	case CS6: uart_mc = UART_MC_CLS_CHARLEN_6; break;
	case CS7: uart_mc = UART_MC_CLS_CHARLEN_7; break;
	default:  uart_mc = UART_MC_CLS_CHARLEN_8; break; // CS8
	}
	if (cflag & CSTOPB)
		uart_mc|= UART_MC_ST_TWO;
	if (cflag & PARENB) {
		uart_mc |= UART_MC_PE_MSK;
		if (!(cflag & PARODD))
			uart_mc |= UART_MC_EP_MSK;
	}

	port->read_status_mask = UART_RDS_OE_MSK;
	if (iflag & INPCK)
		port->read_status_mask |= UART_RDS_FE_MSK | UART_RDS_PE_MSK;
	if (iflag & (BRKINT | PARMRK))
		port->read_status_mask |= UART_RDS_BI_MSK;

	/*
	 * Characters to ignore
	 */
	port->ignore_status_mask = 0;
	if (iflag & IGNPAR)
		port->ignore_status_mask |= UART_RDS_FE_MSK | UART_RDS_PE_MSK;
	if (iflag & IGNBRK) {
		port->ignore_status_mask |= UART_RDS_BI_MSK;
		/*
		 * If we're ignoring parity and break indicators,
		 * ignore overruns to (for real raw support).
		 */
		if (iflag & IGNPAR)
			port->ignore_status_mask |= UART_RDS_OE_MSK;
	}

	/* first, disable everything */
	save_flags(flags); cli();
	old_ies = UART_GET_IES(port); 

	if ((port->flags & ASYNC_HARDPPS_CD) ||
	    (cflag & CRTSCTS) || !(cflag & CLOCAL))
		old_ies |= UART_IES_ME_MSK;


	/* Set baud rate */
	UART_PUT_DIV_LO(port, (quot & 0xff));
	UART_PUT_DIV_HI(port, ((quot & 0xf00) >> 8));
   

	UART_PUT_MC(port, uart_mc);
	UART_PUT_IES(port, old_ies);

	restore_flags(flags);
}