发布时间 : 星期五 文章Linux Bootconsole更新完毕开始阅读78b74312e53a580217fcfe3b
}
/*
* MCR-based auto flow control. When AFE is enabled, RTS will be * deasserted when the receive FIFO contains more characters than * the trigger, or the MCR RTS bit is cleared. In the case where * the remote UART is not using CTS auto flow control, we must * have sufficient FIFO entries for the latency of the remote * UART to respond. IOW, at least 32 bytes of FIFO. */
if (up->capabilities & UART_CAP_AFE && up->port.fifosize >= 32) {//是否支持硬件流控 up->mcr &= ~UART_MCR_AFE; if (termios->c_cflag & CRTSCTS) up->mcr |= UART_MCR_AFE; }
/*
* Ok, we're now changing the port state. Do it with * interrupts disabled. */
spin_lock_irqsave(&up->port.lock, flags);
/*
* Update the per-port timeout. */
uart_update_timeout(port, termios->c_cflag, baud);
up->port.read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; if (termios->c_iflag & INPCK)
up->port.read_status_mask |= UART_LSR_FE | UART_LSR_PE; if (termios->c_iflag & (BRKINT | PARMRK)) up->port.read_status_mask |= UART_LSR_BI;
/*
* Characteres to ignore */
up->port.ignore_status_mask = 0; if (termios->c_iflag & IGNPAR)
up->port.ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; if (termios->c_iflag & IGNBRK) {
up->port.ignore_status_mask |= UART_LSR_BI; /*
* If we're ignoring parity and break indicators, * ignore overruns too (for real raw support).
*/
if (termios->c_iflag & IGNPAR)
up->port.ignore_status_mask |= UART_LSR_OE; }
/*
* ignore all characters if CREAD is not set */
if ((termios->c_cflag & CREAD) == 0)
up->port.ignore_status_mask |= UART_LSR_DR;
/*
* CTS flow control flag and modem status interrupts */
up->ier &= ~UART_IER_MSI;
if (!(up->bugs & UART_BUG_NOMSR) &&
UART_ENABLE_MS(&up->port, termios->c_cflag)) up->ier |= UART_IER_MSI;
if (up->capabilities & UART_CAP_UUE)
up->ier |= UART_IER_UUE | UART_IER_RTOIE;
serial_out(up, UART_IER, up->ier);
if (up->capabilities & UART_CAP_EFR) { unsigned char efr = 0; /*
* TI16C752/Startech hardware flow control. FIXME: * - TI16C752 requires control thresholds to be set.
* - UART_MCR_RTS is ineffective if auto-RTS mode is enabled. */
if (termios->c_cflag & CRTSCTS) efr |= UART_EFR_CTS;
serial_outp(up, UART_LCR, 0xBF); serial_outp(up, UART_EFR, efr); }
#ifdef CONFIG_ARCH_OMAP
/* Workaround to enable 115200 baud on OMAP1510 internal ports */ if (cpu_is_omap1510() && is_omap_port(up)) { if (baud == 115200) { quot = 1;
serial_out(up, UART_OMAP_OSC_12M_SEL, 1); } else
serial_out(up, UART_OMAP_OSC_12M_SEL, 0); } #endif
if (up->capabilities & UART_NATSEMI) {
/* Switch to bank 2 not bank 1, to avoid resetting EXCR2 */ serial_outp(up, UART_LCR, 0xe0); } else {
serial_outp(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */ }
serial_dl_write(up, quot);
/*
* LCR DLAB must be set to enable 64-byte FIFO mode. If the FCR * is written without DLAB set, this mode will be disabled. */
if (up->port.type == PORT_16750) serial_outp(up, UART_FCR, fcr);
serial_outp(up, UART_LCR, cval); /* reset DLAB */ up->lcr = cval; /* Save LCR */ if (up->port.type != PORT_16750) {
if (fcr & UART_FCR_ENABLE_FIFO) {
/* emulated UARTs (Lucent Venus 167x) need two steps */ serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO); }
serial_outp(up, UART_FCR, fcr); /* set fcr */ }
serial8250_set_mctrl(&up->port, up->port.mctrl); spin_unlock_irqrestore(&up->port.lock, flags); /* Don't rewrite B0 */
if (tty_termios_baud_rate(termios))
tty_termios_encode_baud_rate(termios, baud, baud); }
//获得串口波特率
参数1:uart_port uart端口 2:ktermios 结构 4:最小波特率 5:最大波特率 unsigned int
uart_get_baud_rate(struct uart_port *port, struct ktermios *termios, struct ktermios *old, unsigned int min, unsigned int max)
{
unsigned int try, baud, altbaud = 38400; int hung_up = 0;
upf_t flags = port->flags & UPF_SPD_MASK;
if (flags == UPF_SPD_HI) altbaud = 57600;
if (flags == UPF_SPD_VHI) altbaud = 115200;
if (flags == UPF_SPD_SHI) altbaud = 230400;
if (flags == UPF_SPD_WARP) altbaud = 460800;
for (try = 0; try < 2; try++) {
baud = tty_termios_baud_rate(termios);//根据termios的设置得到其波特率为115200
/*
* The spd_hi, spd_vhi, spd_shi, spd_warp kludge... * Die! Die! Die! */
if (baud == 38400) baud = altbaud;
/*
* Special case: B0 rate. */
if (baud == 0) { hung_up = 1; baud = 9600; }
if (baud >= min && baud <= max)//判断波特率是否合法,并返回 return baud;
/*
* Oops, the quotient was zero. Try again with * the old baud rate if possible. */
termios->c_cflag &= ~CBAUD; if (old) {
baud = tty_termios_baud_rate(old); if (!hung_up)
tty_termios_encode_baud_rate(termios,