static void tc3162ser_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { unsigned int baud, quot; unsigned long flags; termios->c_cflag |= CREAD; baud = 115200; quot = uart_get_divisor(port, baud); spin_lock_irqsave(&port->lock, flags); /* * Update the per-port timeout. */ uart_update_timeout(port, termios->c_cflag, baud); /* * Characters to ignore */ port->ignore_status_mask = 0; spin_unlock_irqrestore(&port->lock, flags); }
static int serial_pxa_scale(struct notifier_block *self, unsigned long level, void *newop){ int n=0;int i=0; int ccsr=CCSR; n=sizeof(serial_pxa_ports)/sizeof(struct uart_pxa_port); for(i=0;i<n;++i){ struct uart_pxa_port *up = (struct uart_pxa_port *) &serial_pxa_ports[i]; if(up->isConsole){ unsigned int quot; if ((ccsr & (1<<30))){ if (up->port.uartclk == 13000000) return 0; /*if PPLL is Off (clocking with 13MHz now)*/ up->port.uartclk = 13000000; }else{ if (up->port.uartclk == 921600 * 16) return 0; /*clocking with 14.7456 MHz*/ up->port.uartclk = 921600 * 16; } quot = uart_get_divisor(&up->port, up->consoleBaud); serial_out(up, UART_LCR, up->lcr | UART_LCR_DLAB);/* set DLAB */ serial_out(up, UART_DLL, quot & 0xff); /* LS of divisor */ serial_out(up, UART_DLM, quot >> 8); /* MS of divisor */ serial_out(up, UART_LCR, up->lcr); /* reset DLAB */ } }
static void digicolor_uart_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { unsigned int baud, divisor; u8 config = 0; unsigned long flags; /* Mask termios capabilities we don't support */ termios->c_cflag &= ~CMSPAR; termios->c_iflag &= ~(BRKINT | IGNBRK); /* Limit baud rates so that we don't need the fractional divider */ baud = uart_get_baud_rate(port, termios, old, port->uartclk / (0x10000*16), port->uartclk / 256); divisor = uart_get_divisor(port, baud) - 1; switch (termios->c_cflag & CSIZE) { case CS7: break; case CS8: default: config |= UA_CONFIG_CHAR_LEN; break; } if (termios->c_cflag & CSTOPB) config |= UA_CONFIG_STOP_BITS; if (termios->c_cflag & PARENB) { config |= UA_CONFIG_PARITY; if (termios->c_cflag & PARODD) config |= UA_CONFIG_ODD_PARITY; } /* Set read status mask */ port->read_status_mask = UA_STATUS_OVERRUN_ERR; if (termios->c_iflag & INPCK) port->read_status_mask |= UA_STATUS_PARITY_ERR | UA_STATUS_FRAME_ERR; /* Set status ignore mask */ port->ignore_status_mask = 0; if (!(termios->c_cflag & CREAD)) port->ignore_status_mask |= UA_STATUS_OVERRUN_ERR | UA_STATUS_PARITY_ERR | UA_STATUS_FRAME_ERR; spin_lock_irqsave(&port->lock, flags); uart_update_timeout(port, termios->c_cflag, baud); writeb_relaxed(config, port->membase + UA_CONFIG); writeb_relaxed(divisor & 0xff, port->membase + UA_HBAUD_LO); writeb_relaxed(divisor >> 8, port->membase + UA_HBAUD_HI); spin_unlock_irqrestore(&port->lock, flags); }
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_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 milkymist_uart_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { unsigned long flags; unsigned int baud; unsigned int quot; baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); quot = uart_get_divisor(port, baud); spin_lock_irqsave(&port->lock, flags); uart_update_timeout(port, termios->c_cflag, baud); iowrite32be(quot, port->membase + UART_DIV); spin_unlock_irqrestore(&port->lock, flags); if (tty_termios_baud_rate(termios)) tty_termios_encode_baud_rate(termios, baud, baud); }
static unsigned int serial8250_get_divisor(struct uart_port *port, unsigned int baud) { unsigned int quot; /* * Handle magic divisors for baud rates above baud_base on * SMSC SuperIO chips. */ if ((port->flags & UPF_MAGIC_MULTIPLIER) && baud == (port->uartclk/4)) quot = 0x8001; else if ((port->flags & UPF_MAGIC_MULTIPLIER) && baud == (port->uartclk/8)) quot = 0x8002; else quot = uart_get_divisor(port, baud); return quot; }
static int vt8500_set_baud_rate(struct uart_port *port, unsigned int baud) { struct vt8500_port *vt8500_port = container_of(port, struct vt8500_port, uart); unsigned long div; unsigned int loops = 1000; div = ((vt8500_port->clk_predivisor - 1) & 0xf) << 16; div |= (uart_get_divisor(port, baud) - 1) & 0x3ff; /* Effective baud rate */ baud = port->uartclk / 16 / ((div & 0x3ff) + 1); while ((vt8500_read(port, VT8500_URUSR) & (1 << 5)) && --loops) cpu_relax(); vt8500_write(port, div, VT8500_URDIV); /* Break signal timing depends on baud rate, update accordingly */ vt8500_write(port, mult_frac(baud, 4096, 1000000), VT8500_URBKR); return baud; }
static void serial_pxa_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct uart_pxa_port *up = (struct uart_pxa_port *)port; unsigned char cval, fcr = 0; unsigned long flags; unsigned int baud, quot; switch (termios->c_cflag & CSIZE) { case CS5: cval = UART_LCR_WLEN5; break; case CS6: cval = UART_LCR_WLEN6; break; case CS7: cval = UART_LCR_WLEN7; break; default: case CS8: cval = UART_LCR_WLEN8; break; } if (termios->c_cflag & CSTOPB) cval |= UART_LCR_STOP; if (termios->c_cflag & PARENB) cval |= UART_LCR_PARITY; if (!(termios->c_cflag & PARODD)) cval |= UART_LCR_EPAR; /* * 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); if ((up->port.uartclk / quot) < (2400 * 16)) fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR1; else if ((up->port.uartclk / quot) < (230400 * 16)) fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR8; else fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR32; /* * Ok, we're now changing the port state. Do it with * interrupts disabled. */ spin_lock_irqsave(&up->port.lock, flags); /* * Ensure the port will be enabled. * This is required especially for serial console. */ up->ier |= IER_UUE; /* * 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; /* * Characters 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 (UART_ENABLE_MS(&up->port, termios->c_cflag)) up->ier |= UART_IER_MSI; serial_out(up, UART_IER, up->ier); serial_out(up, UART_LCR, cval | UART_LCR_DLAB);/* set DLAB */ serial_out(up, UART_DLL, quot & 0xff); /* LS of divisor */ serial_out(up, UART_DLM, quot >> 8); /* MS of divisor */ serial_out(up, UART_LCR, cval); /* reset DLAB */ up->lcr = cval; /* Save LCR */ serial_pxa_set_mctrl(&up->port, up->port.mctrl); serial_out(up, UART_FCR, fcr); spin_unlock_irqrestore(&up->port.lock, flags); }
/* port->lock is not held. */ static void sc26xx_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { unsigned int baud = uart_get_baud_rate(port, termios, old, 0, 4000000); unsigned int quot = uart_get_divisor(port, baud); unsigned int iflag, cflag; unsigned long flags; u8 mr1, mr2, csr; spin_lock_irqsave(&port->lock, flags); while ((READ_SC_PORT(port, SR) & ((1 << 3) | (1 << 2))) != 0xc) udelay(2); WRITE_SC_PORT(port, CR, CR_DIS_TX | CR_DIS_RX); iflag = termios->c_iflag; cflag = termios->c_cflag; port->read_status_mask = SR_OVERRUN; if (iflag & INPCK) port->read_status_mask |= SR_PARITY | SR_FRAME; if (iflag & (BRKINT | PARMRK)) port->read_status_mask |= SR_BREAK; port->ignore_status_mask = 0; if (iflag & IGNBRK) port->ignore_status_mask |= SR_BREAK; if ((cflag & CREAD) == 0) port->ignore_status_mask |= SR_BREAK | SR_FRAME | SR_PARITY | SR_OVERRUN; switch (cflag & CSIZE) { case CS5: mr1 = 0x00; break; case CS6: mr1 = 0x01; break; case CS7: mr1 = 0x02; break; default: case CS8: mr1 = 0x03; break; } mr2 = 0x07; if (cflag & CSTOPB) mr2 = 0x0f; if (cflag & PARENB) { if (cflag & PARODD) mr1 |= (1 << 2); } else mr1 |= (2 << 3); switch (baud) { case 50: csr = 0x00; break; case 110: csr = 0x11; break; case 134: csr = 0x22; break; case 200: csr = 0x33; break; case 300: csr = 0x44; break; case 600: csr = 0x55; break; case 1200: csr = 0x66; break; case 2400: csr = 0x88; break; case 4800: csr = 0x99; break; default: case 9600: csr = 0xbb; break; case 19200: csr = 0xcc; break; } WRITE_SC_PORT(port, CR, CR_RES_MR); WRITE_SC_PORT(port, MRx, mr1); WRITE_SC_PORT(port, MRx, mr2); WRITE_SC(port, ACR, 0x80); WRITE_SC_PORT(port, CSR, csr); /* reset tx and rx */ WRITE_SC_PORT(port, CR, CR_RES_RX); WRITE_SC_PORT(port, CR, CR_RES_TX); WRITE_SC_PORT(port, CR, CR_ENA_TX | CR_ENA_RX); while ((READ_SC_PORT(port, SR) & ((1 << 3) | (1 << 2))) != 0xc) udelay(2); /* XXX */ uart_update_timeout(port, cflag, (port->uartclk / (16 * quot))); spin_unlock_irqrestore(&port->lock, flags); }
static void sa1100_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct sa1100_port *sport = (struct sa1100_port *)port; unsigned long flags; unsigned int utcr0, old_utcr3, baud, quot; unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8; while ((termios->c_cflag & CSIZE) != CS7 && (termios->c_cflag & CSIZE) != CS8) { termios->c_cflag &= ~CSIZE; termios->c_cflag |= old_csize; old_csize = CS8; } if ((termios->c_cflag & CSIZE) == CS8) utcr0 = UTCR0_DSS; else utcr0 = 0; if (termios->c_cflag & CSTOPB) utcr0 |= UTCR0_SBS; if (termios->c_cflag & PARENB) { utcr0 |= UTCR0_PE; if (!(termios->c_cflag & PARODD)) utcr0 |= UTCR0_OES; } baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); quot = uart_get_divisor(port, baud); spin_lock_irqsave(&sport->port.lock, flags); sport->port.read_status_mask &= UTSR0_TO_SM(UTSR0_TFS); sport->port.read_status_mask |= UTSR1_TO_SM(UTSR1_ROR); if (termios->c_iflag & INPCK) sport->port.read_status_mask |= UTSR1_TO_SM(UTSR1_FRE | UTSR1_PRE); if (termios->c_iflag & (BRKINT | PARMRK)) sport->port.read_status_mask |= UTSR0_TO_SM(UTSR0_RBB | UTSR0_REB); sport->port.ignore_status_mask = 0; if (termios->c_iflag & IGNPAR) sport->port.ignore_status_mask |= UTSR1_TO_SM(UTSR1_FRE | UTSR1_PRE); if (termios->c_iflag & IGNBRK) { sport->port.ignore_status_mask |= UTSR0_TO_SM(UTSR0_RBB | UTSR0_REB); if (termios->c_iflag & IGNPAR) sport->port.ignore_status_mask |= UTSR1_TO_SM(UTSR1_ROR); } del_timer_sync(&sport->timer); uart_update_timeout(port, termios->c_cflag, baud); old_utcr3 = UART_GET_UTCR3(sport); UART_PUT_UTCR3(sport, old_utcr3 & ~(UTCR3_RIE | UTCR3_TIE)); while (UART_GET_UTSR1(sport) & UTSR1_TBY) barrier(); UART_PUT_UTCR3(sport, 0); UART_PUT_UTCR0(sport, utcr0); quot -= 1; UART_PUT_UTCR1(sport, ((quot & 0xf00) >> 8)); UART_PUT_UTCR2(sport, (quot & 0xff)); UART_PUT_UTSR0(sport, -1); UART_PUT_UTCR3(sport, old_utcr3); if (UART_ENABLE_MS(&sport->port, termios->c_cflag)) sa1100_enable_ms(&sport->port); spin_unlock_irqrestore(&sport->port.lock, flags); }
static void pnx8xxx_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct pnx8xxx_port *sport = (struct pnx8xxx_port *)port; unsigned long flags; unsigned int lcr_fcr, old_ien, baud, quot; unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8; while ((termios->c_cflag & CSIZE) != CS7 && (termios->c_cflag & CSIZE) != CS8) { termios->c_cflag &= ~CSIZE; termios->c_cflag |= old_csize; old_csize = CS8; } if ((termios->c_cflag & CSIZE) == CS8) lcr_fcr = PNX8XXX_UART_LCR_8BIT; else lcr_fcr = 0; if (termios->c_cflag & CSTOPB) lcr_fcr |= PNX8XXX_UART_LCR_2STOPB; if (termios->c_cflag & PARENB) { lcr_fcr |= PNX8XXX_UART_LCR_PAREN; if (!(termios->c_cflag & PARODD)) lcr_fcr |= PNX8XXX_UART_LCR_PAREVN; } baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); quot = uart_get_divisor(port, baud); spin_lock_irqsave(&sport->port.lock, flags); sport->port.read_status_mask = ISTAT_TO_SM(PNX8XXX_UART_INT_RXOVRN) | ISTAT_TO_SM(PNX8XXX_UART_INT_EMPTY) | ISTAT_TO_SM(PNX8XXX_UART_INT_RX); if (termios->c_iflag & INPCK) sport->port.read_status_mask |= FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFE) | FIFO_TO_SM(PNX8XXX_UART_FIFO_RXPAR); if (termios->c_iflag & (BRKINT | PARMRK)) sport->port.read_status_mask |= ISTAT_TO_SM(PNX8XXX_UART_INT_BREAK); sport->port.ignore_status_mask = 0; if (termios->c_iflag & IGNPAR) sport->port.ignore_status_mask |= FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFE) | FIFO_TO_SM(PNX8XXX_UART_FIFO_RXPAR); if (termios->c_iflag & IGNBRK) { sport->port.ignore_status_mask |= ISTAT_TO_SM(PNX8XXX_UART_INT_BREAK); if (termios->c_iflag & IGNPAR) sport->port.ignore_status_mask |= ISTAT_TO_SM(PNX8XXX_UART_INT_RXOVRN); } if ((termios->c_cflag & CREAD) == 0) sport->port.ignore_status_mask |= ISTAT_TO_SM(PNX8XXX_UART_INT_RX); del_timer_sync(&sport->timer); uart_update_timeout(port, termios->c_cflag, baud); old_ien = serial_in(sport, PNX8XXX_IEN); serial_out(sport, PNX8XXX_IEN, old_ien & ~(PNX8XXX_UART_INT_ALLTX | PNX8XXX_UART_INT_ALLRX)); while (serial_in(sport, PNX8XXX_FIFO) & PNX8XXX_UART_FIFO_TXFIFO_STA) barrier(); serial_out(sport, PNX8XXX_IEN, 0); lcr_fcr |= PNX8XXX_UART_LCR_TX_RST; lcr_fcr |= PNX8XXX_UART_LCR_RX_RST; serial_out(sport, PNX8XXX_LCR, lcr_fcr); quot -= 1; serial_out(sport, PNX8XXX_BAUD, quot); serial_out(sport, PNX8XXX_ICLR, -1); serial_out(sport, PNX8XXX_IEN, old_ien); if (UART_ENABLE_MS(&sport->port, termios->c_cflag)) pnx8xxx_enable_ms(&sport->port); spin_unlock_irqrestore(&sport->port.lock, flags); }
static unsigned int m32r_sio_get_divisor(struct uart_port *port, unsigned int baud) { return uart_get_divisor(port, baud); }
static void pl010_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { unsigned int lcr_h, old_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); quot = uart_get_divisor(port, baud); switch (termios->c_cflag & CSIZE) { case CS5: lcr_h = UART01x_LCRH_WLEN_5; break; case CS6: lcr_h = UART01x_LCRH_WLEN_6; break; case CS7: lcr_h = UART01x_LCRH_WLEN_7; break; default: // CS8 lcr_h = UART01x_LCRH_WLEN_8; break; } if (termios->c_cflag & CSTOPB) lcr_h |= UART01x_LCRH_STP2; if (termios->c_cflag & PARENB) { lcr_h |= UART01x_LCRH_PEN; if (!(termios->c_cflag & PARODD)) lcr_h |= UART01x_LCRH_EPS; } if (port->fifosize > 1) lcr_h |= UART01x_LCRH_FEN; spin_lock_irqsave(&port->lock, flags); /* * Update the per-port timeout. */ uart_update_timeout(port, termios->c_cflag, baud); port->read_status_mask = UART01x_RSR_OE; if (termios->c_iflag & INPCK) port->read_status_mask |= UART01x_RSR_FE | UART01x_RSR_PE; if (termios->c_iflag & (BRKINT | PARMRK)) port->read_status_mask |= UART01x_RSR_BE; /* * Characters to ignore */ port->ignore_status_mask = 0; if (termios->c_iflag & IGNPAR) port->ignore_status_mask |= UART01x_RSR_FE | UART01x_RSR_PE; if (termios->c_iflag & IGNBRK) { port->ignore_status_mask |= UART01x_RSR_BE; /* * If we're ignoring parity and break indicators, * ignore overruns too (for real raw support). */ if (termios->c_iflag & IGNPAR) port->ignore_status_mask |= UART01x_RSR_OE; } /* * Ignore all characters if CREAD is not set. */ if ((termios->c_cflag & CREAD) == 0) port->ignore_status_mask |= UART_DUMMY_RSR_RX; /* first, disable everything */ old_cr = readb(port->membase + UART010_CR) & ~UART010_CR_MSIE; if (UART_ENABLE_MS(port, termios->c_cflag)) old_cr |= UART010_CR_MSIE; writel(0, port->membase + UART010_CR); /* Set baud rate */ quot -= 1; writel((quot & 0xf00) >> 8, port->membase + UART010_LCRM); writel(quot & 0xff, port->membase + UART010_LCRL); /* * ----------v----------v----------v----------v----- * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L * ----------^----------^----------^----------^----- */ writel(lcr_h, port->membase + UART010_LCRH); writel(old_cr, port->membase + UART010_CR); spin_unlock_irqrestore(&port->lock, flags); }
static void ks8695uart_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { unsigned int lcr, fcr = 0; 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); quot = uart_get_divisor(port, baud); switch (termios->c_cflag & CSIZE) { case CS5: lcr = URCL_5; break; case CS6: lcr = URCL_6; break; case CS7: lcr = URCL_7; break; default: lcr = URCL_8; break; } /* stop bits */ if (termios->c_cflag & CSTOPB) lcr |= URLC_URSB; /* parity */ if (termios->c_cflag & PARENB) { if (termios->c_cflag & CMSPAR) { /* Mark or Space parity */ if (termios->c_cflag & PARODD) lcr |= URPE_MARK; else lcr |= URPE_SPACE; } else if (termios->c_cflag & PARODD) lcr |= URPE_ODD; else lcr |= URPE_EVEN; } if (port->fifosize > 1) fcr = URFC_URFRT_8 | URFC_URTFR | URFC_URRFR | URFC_URFE; spin_lock_irqsave(&port->lock, flags); /* * Update the per-port timeout. */ uart_update_timeout(port, termios->c_cflag, baud); port->read_status_mask = URLS_URROE; if (termios->c_iflag & INPCK) port->read_status_mask |= (URLS_URFE | URLS_URPE); if (termios->c_iflag & (BRKINT | PARMRK)) port->read_status_mask |= URLS_URBI; /* * Characters to ignore */ port->ignore_status_mask = 0; if (termios->c_iflag & IGNPAR) port->ignore_status_mask |= (URLS_URFE | URLS_URPE); if (termios->c_iflag & IGNBRK) { port->ignore_status_mask |= URLS_URBI; /* * If we're ignoring parity and break indicators, * ignore overruns too (for real raw support). */ if (termios->c_iflag & IGNPAR) port->ignore_status_mask |= URLS_URROE; } /* * Ignore all characters if CREAD is not set. */ if ((termios->c_cflag & CREAD) == 0) port->ignore_status_mask |= UART_DUMMY_LSR_RX; /* first, disable everything */ if (UART_ENABLE_MS(port, termios->c_cflag)) ks8695uart_enable_ms(port); else ks8695uart_disable_ms(port); /* Set baud rate */ UART_PUT_BRDR(port, quot); UART_PUT_LCR(port, lcr); UART_PUT_FCR(port, fcr); spin_unlock_irqrestore(&port->lock, flags); }
static void imx_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct imx_port *sport = (struct imx_port *)port; unsigned long flags; unsigned int ucr2, old_ucr1, old_txrxen, baud, quot; unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8; unsigned int div, ufcr; unsigned long num, denom; uint64_t tdiv64; /* * If we don't support modem control lines, don't allow * these to be set. */ if (0) { termios->c_cflag &= ~(HUPCL | CRTSCTS | CMSPAR); termios->c_cflag |= CLOCAL; } /* * We only support CS7 and CS8. */ while ((termios->c_cflag & CSIZE) != CS7 && (termios->c_cflag & CSIZE) != CS8) { termios->c_cflag &= ~CSIZE; termios->c_cflag |= old_csize; old_csize = CS8; } if ((termios->c_cflag & CSIZE) == CS8) ucr2 = UCR2_WS | UCR2_SRST | UCR2_IRTS; else ucr2 = UCR2_SRST | UCR2_IRTS; if (termios->c_cflag & CRTSCTS) { if( sport->have_rtscts ) { ucr2 &= ~UCR2_IRTS; ucr2 |= UCR2_CTSC; } else { termios->c_cflag &= ~CRTSCTS; } } if (termios->c_cflag & CSTOPB) ucr2 |= UCR2_STPB; if (termios->c_cflag & PARENB) { ucr2 |= UCR2_PREN; if (termios->c_cflag & PARODD) ucr2 |= UCR2_PROE; } /* * Ask the core to calculate the divisor for us. */ baud = uart_get_baud_rate(port, termios, old, 50, port->uartclk / 16); quot = uart_get_divisor(port, baud); spin_lock_irqsave(&sport->port.lock, flags); sport->port.read_status_mask = 0; if (termios->c_iflag & INPCK) sport->port.read_status_mask |= (URXD_FRMERR | URXD_PRERR); if (termios->c_iflag & (BRKINT | PARMRK)) sport->port.read_status_mask |= URXD_BRK; /* * Characters to ignore */ sport->port.ignore_status_mask = 0; if (termios->c_iflag & IGNPAR) sport->port.ignore_status_mask |= URXD_PRERR; if (termios->c_iflag & IGNBRK) { sport->port.ignore_status_mask |= URXD_BRK; /* * If we're ignoring parity and break indicators, * ignore overruns too (for real raw support). */ if (termios->c_iflag & IGNPAR) sport->port.ignore_status_mask |= URXD_OVRRUN; } del_timer_sync(&sport->timer); /* * Update the per-port timeout. */ uart_update_timeout(port, termios->c_cflag, baud); /* * disable interrupts and drain transmitter */ old_ucr1 = readl(sport->port.membase + UCR1); writel(old_ucr1 & ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN), sport->port.membase + UCR1); while ( !(readl(sport->port.membase + USR2) & USR2_TXDC)) barrier(); /* then, disable everything */ old_txrxen = readl(sport->port.membase + UCR2); writel(old_txrxen & ~( UCR2_TXEN | UCR2_RXEN), sport->port.membase + UCR2); old_txrxen &= (UCR2_TXEN | UCR2_RXEN); if (USE_IRDA(sport)) { /* * use maximum available submodule frequency to * avoid missing short pulses due to low sampling rate */ div = 1; } else { div = sport->port.uartclk / (baud * 16); if (div > 7) div = 7; if (!div) div = 1; } rational_best_approximation(16 * div * baud, sport->port.uartclk, 1 << 16, 1 << 16, &num, &denom); tdiv64 = sport->port.uartclk; tdiv64 *= num; do_div(tdiv64, denom * 16 * div); tty_termios_encode_baud_rate(termios, (speed_t)tdiv64, (speed_t)tdiv64); num -= 1; denom -= 1; ufcr = readl(sport->port.membase + UFCR); ufcr = (ufcr & (~UFCR_RFDIV)) | UFCR_RFDIV_REG(div); writel(ufcr, sport->port.membase + UFCR); writel(num, sport->port.membase + UBIR); writel(denom, sport->port.membase + UBMR); if (!cpu_is_mx1()) writel(sport->port.uartclk / div / 1000, sport->port.membase + MX2_ONEMS); writel(old_ucr1, sport->port.membase + UCR1); /* set the parity, stop bits and data size */ writel(ucr2 | old_txrxen, sport->port.membase + UCR2); if (UART_ENABLE_MS(&sport->port, termios->c_cflag)) imx_enable_ms(&sport->port); spin_unlock_irqrestore(&sport->port.lock, flags); }
static void uart_clps711x_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { unsigned int ubrlcr, baud, quot; unsigned long flags; /* Mask termios capabilities we don't support */ termios->c_cflag &= ~CMSPAR; termios->c_iflag &= ~(BRKINT | IGNBRK); /* Ask the core to calculate the divisor for us */ baud = uart_get_baud_rate(port, termios, old, port->uartclk / 4096, port->uartclk / 16); quot = uart_get_divisor(port, baud); switch (termios->c_cflag & CSIZE) { case CS5: ubrlcr = UBRLCR_WRDLEN5; break; case CS6: ubrlcr = UBRLCR_WRDLEN6; break; case CS7: ubrlcr = UBRLCR_WRDLEN7; break; case CS8: default: ubrlcr = UBRLCR_WRDLEN8; break; } if (termios->c_cflag & CSTOPB) ubrlcr |= UBRLCR_XSTOP; if (termios->c_cflag & PARENB) { ubrlcr |= UBRLCR_PRTEN; if (!(termios->c_cflag & PARODD)) ubrlcr |= UBRLCR_EVENPRT; } /* Enable FIFO */ ubrlcr |= UBRLCR_FIFOEN; spin_lock_irqsave(&port->lock, flags); /* Set read status mask */ port->read_status_mask = UARTDR_OVERR; if (termios->c_iflag & INPCK) port->read_status_mask |= UARTDR_PARERR | UARTDR_FRMERR; /* Set status ignore mask */ port->ignore_status_mask = 0; if (!(termios->c_cflag & CREAD)) port->ignore_status_mask |= UARTDR_OVERR | UARTDR_PARERR | UARTDR_FRMERR; uart_update_timeout(port, termios->c_cflag, baud); clps_writel(ubrlcr | (quot - 1), UBRLCR(port)); spin_unlock_irqrestore(&port->lock, flags); }
static void sw_uart_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct sw_uart_port *sw_uport = UART_TO_SPORT(port); unsigned long flags; unsigned int baud, quot, lcr = 0, dll, dlh; unsigned int lcr_fail = 0; SERIAL_DBG("set termios ...\n"); switch (termios->c_cflag & CSIZE) { case CS5: lcr |= SW_UART_LCR_WLEN5; break; case CS6: lcr |= SW_UART_LCR_WLEN6; break; case CS7: lcr |= SW_UART_LCR_WLEN7; break; case CS8: default: lcr |= SW_UART_LCR_WLEN8; break; } if (termios->c_cflag & CSTOPB) lcr |= SW_UART_LCR_STOP; if (termios->c_cflag & PARENB) lcr |= SW_UART_LCR_PARITY; if (!(termios->c_cflag & PARODD)) lcr |= SW_UART_LCR_EPAR; /* set buadrate */ baud = uart_get_baud_rate(port, termios, old, port->uartclk / 16 / 0xffff, port->uartclk / 16); sw_uart_check_baudset(port, baud); quot = uart_get_divisor(port, baud); dll = quot & 0xff; dlh = quot >> 8; SERIAL_DBG("set baudrate %d, quot %d\n", baud, quot); spin_lock_irqsave(&port->lock, flags); uart_update_timeout(port, termios->c_cflag, baud); /* Update the per-port timeout. */ port->read_status_mask = SW_UART_LSR_OE | SW_UART_LSR_THRE | SW_UART_LSR_DR; if (termios->c_iflag & INPCK) port->read_status_mask |= SW_UART_LSR_FE | SW_UART_LSR_PE; if (termios->c_iflag & (BRKINT | PARMRK)) port->read_status_mask |= SW_UART_LSR_BI; /* Characteres to ignore */ port->ignore_status_mask = 0; if (termios->c_iflag & IGNPAR) port->ignore_status_mask |= SW_UART_LSR_PE | SW_UART_LSR_FE; if (termios->c_iflag & IGNBRK) { port->ignore_status_mask |= SW_UART_LSR_BI; /* * If we're ignoring parity and break indicators, * ignore overruns too (for real raw support). */ if (termios->c_iflag & IGNPAR) port->ignore_status_mask |= SW_UART_LSR_OE; } /* * ignore all characters if CREAD is not set */ if ((termios->c_cflag & CREAD) == 0) port->ignore_status_mask |= SW_UART_LSR_DR; /* * if lcr & baud are changed, reset controller to disable transfer */ if (lcr != sw_uport->lcr || dll != sw_uport->dll || dlh != sw_uport->dlh) { // SERIAL_DBG("LCR & BAUD changed, reset controller...\n"); sw_uart_reset(sw_uport); } sw_uport->dll = dll; sw_uport->dlh = dlh; /* flow control */ sw_uport->mcr &= ~SW_UART_MCR_AFE; if (termios->c_cflag & CRTSCTS) sw_uport->mcr |= SW_UART_MCR_AFE; serial_out(port, sw_uport->mcr, SW_UART_MCR); /* * CTS flow control flag and modem status interrupts */ sw_uport->ier &= ~SW_UART_IER_MSI; if (UART_ENABLE_MS(port, termios->c_cflag)) sw_uport->ier |= SW_UART_IER_MSI; serial_out(port, sw_uport->ier, SW_UART_IER); sw_uport->fcr = SW_UART_FCR_RXTRG_1_2 | SW_UART_FCR_TXTRG_1_2 | SW_UART_FCR_FIFO_EN; serial_out(port, sw_uport->fcr, SW_UART_FCR); sw_uport->lcr = lcr; serial_out(port, sw_uport->lcr|SW_UART_LCR_DLAB, SW_UART_LCR); if (serial_in(port, SW_UART_LCR) != (sw_uport->lcr|SW_UART_LCR_DLAB)) { lcr_fail = 1; } else { sw_uport->lcr = lcr; serial_out(port, sw_uport->dll, SW_UART_DLL); serial_out(port, sw_uport->dlh, SW_UART_DLH); serial_out(port, sw_uport->lcr, SW_UART_LCR); if (serial_in(port, SW_UART_LCR) != sw_uport->lcr) { lcr_fail = 2; } } #ifdef CONFIG_SW_UART_FORCE_LCR if (lcr_fail) { sw_uart_force_lcr(sw_uport, 50); serial_in(port, SW_UART_USR); } #endif /* clear rxfifo after set lcr & baud to discard redundant data */ serial_out(port, sw_uport->fcr|SW_UART_FCR_RXFIFO_RST, SW_UART_FCR); port->ops->set_mctrl(port, port->mctrl); /* Must save the current config for the resume of console(no tty user). */ if (sw_is_console_port(port)) port->cons->cflag = termios->c_cflag; spin_unlock_irqrestore(&port->lock, flags); /* lately output force lcr information */ if (lcr_fail == 1) { SERIAL_MSG("uart%d write LCR(pre-dlab) failed, lcr %x reg %x\n", sw_uport->id, sw_uport->lcr|(u32)SW_UART_LCR_DLAB, serial_in(port, SW_UART_LCR)); } else if (lcr_fail == 2) { SERIAL_MSG("uart%d write LCR(post-dlab) failed, lcr %x reg %x\n", sw_uport->id, sw_uport->lcr, serial_in(port, SW_UART_LCR)); } /* Don't rewrite B0 */ if (tty_termios_baud_rate(termios)) tty_termios_encode_baud_rate(termios, baud, baud); SERIAL_DBG("termios lcr 0x%x fcr 0x%x mcr 0x%x dll 0x%x dlh 0x%x\n", sw_uport->lcr, sw_uport->fcr, sw_uport->mcr, sw_uport->dll, sw_uport->dlh); }
/* * Change the port parameters */ static void atmel_set_termios(struct uart_port *port, struct ktermios * termios, struct ktermios * old) { struct atmel_uart_port *atmel_port = (struct atmel_uart_port *) port; unsigned long flags; unsigned int mode, imr, quot, baud; /* Get current mode register */ mode = UART_GET_MR(port) & ~(ATMEL_US_USCLKS | ATMEL_US_CHRL | ATMEL_US_NBSTOP | ATMEL_US_PAR); baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); quot = uart_get_divisor(port, baud); if (quot > 65535) { /* BRGR is 16-bit, so switch to slower clock */ quot /= 8; mode |= ATMEL_US_USCLKS_MCK_DIV8; } /* byte size */ switch (termios->c_cflag & CSIZE) { case CS5: mode |= ATMEL_US_CHRL_5; break; case CS6: mode |= ATMEL_US_CHRL_6; break; case CS7: mode |= ATMEL_US_CHRL_7; break; default: mode |= ATMEL_US_CHRL_8; break; } /* stop bits */ if (termios->c_cflag & CSTOPB) mode |= ATMEL_US_NBSTOP_2; /* parity */ if (termios->c_cflag & PARENB) { if (termios->c_cflag & CMSPAR) { /* Mark or Space parity */ if (termios->c_cflag & PARODD) mode |= ATMEL_US_PAR_MARK; else mode |= ATMEL_US_PAR_SPACE; } else if (termios->c_cflag & PARODD) mode |= ATMEL_US_PAR_ODD; else mode |= ATMEL_US_PAR_EVEN; } else mode |= ATMEL_US_PAR_NONE; spin_lock_irqsave(&port->lock, flags); port->read_status_mask = ATMEL_US_OVRE; if (termios->c_iflag & INPCK) port->read_status_mask |= (ATMEL_US_FRAME | ATMEL_US_PARE); if (termios->c_iflag & (BRKINT | PARMRK)) port->read_status_mask |= ATMEL_US_RXBRK; if (atmel_port->use_dma_rx) /* need to enable error interrupts */ UART_PUT_IER(port, port->read_status_mask); /* * Characters to ignore */ port->ignore_status_mask = 0; if (termios->c_iflag & IGNPAR) port->ignore_status_mask |= (ATMEL_US_FRAME | ATMEL_US_PARE); if (termios->c_iflag & IGNBRK) { port->ignore_status_mask |= ATMEL_US_RXBRK; /* * If we're ignoring parity and break indicators, * ignore overruns too (for real raw support). */ if (termios->c_iflag & IGNPAR) port->ignore_status_mask |= ATMEL_US_OVRE; } // TODO: Ignore all characters if CREAD is set. /* update the per-port timeout */ uart_update_timeout(port, termios->c_cflag, baud); /* disable interrupts and drain transmitter */ imr = UART_GET_IMR(port); /* get interrupt mask */ UART_PUT_IDR(port, -1); /* disable all interrupts */ while (!(UART_GET_CSR(port) & ATMEL_US_TXEMPTY)) cpu_relax(); /* disable receiver and transmitter */ UART_PUT_CR(port, ATMEL_US_TXDIS | ATMEL_US_RXDIS); /* set the parity, stop bits and data size */ UART_PUT_MR(port, mode); /* set the baud rate */ UART_PUT_BRGR(port, quot); UART_PUT_CR(port, ATMEL_US_RSTSTA | ATMEL_US_RSTRX); UART_PUT_CR(port, ATMEL_US_TXEN | ATMEL_US_RXEN); /* restore interrupts */ UART_PUT_IER(port, imr); /* CTS flow-control and modem-status interrupts */ if (UART_ENABLE_MS(port, termios->c_cflag)) port->ops->enable_ms(port); spin_unlock_irqrestore(&port->lock, flags); }
static void mtk8250_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct uart_8250_port *up = up_to_u8250p(port); unsigned long flags; unsigned int baud, quot; #ifdef CONFIG_SERIAL_8250_DMA if (up->dma) { if (uart_console(port)) { devm_kfree(up->port.dev, up->dma); up->dma = NULL; } else { mtk8250_dma_enable(up); } } #endif serial8250_do_set_termios(port, termios, old); /* * Mediatek UARTs use an extra highspeed register (UART_MTK_HIGHS) * * We need to recalcualte the quot register, as the claculation depends * on the vaule in the highspeed register. * * Some baudrates are not supported by the chip, so we use the next * lower rate supported and update termios c_flag. * * If highspeed register is set to 3, we need to specify sample count * and sample point to increase accuracy. If not, we reset the * registers to their default values. */ baud = uart_get_baud_rate(port, termios, old, port->uartclk / 16 / UART_DIV_MAX, port->uartclk); if (baud <= 115200) { serial_port_out(port, UART_MTK_HIGHS, 0x0); quot = uart_get_divisor(port, baud); } else if (baud <= 576000) { serial_port_out(port, UART_MTK_HIGHS, 0x2); /* Set to next lower baudrate supported */ if ((baud == 500000) || (baud == 576000)) baud = 460800; quot = DIV_ROUND_UP(port->uartclk, 4 * baud); } else { serial_port_out(port, UART_MTK_HIGHS, 0x3); quot = DIV_ROUND_UP(port->uartclk, 256 * baud); } /* * Ok, we're now changing the port state. Do it with * interrupts disabled. */ spin_lock_irqsave(&port->lock, flags); /* set DLAB we have cval saved in up->lcr from the call to the core */ serial_port_out(port, UART_LCR, up->lcr | UART_LCR_DLAB); serial_dl_write(up, quot); /* reset DLAB */ serial_port_out(port, UART_LCR, up->lcr); if (baud > 460800) { unsigned int tmp; tmp = DIV_ROUND_CLOSEST(port->uartclk, quot * baud); serial_port_out(port, UART_MTK_SAMPLE_COUNT, tmp - 1); serial_port_out(port, UART_MTK_SAMPLE_POINT, (tmp - 2) >> 1); } else {
static void lh7a40xuart_set_termios (struct uart_port* port, struct termios* termios, struct termios* old) { unsigned int con; unsigned int inten; unsigned int fcon; unsigned long flags; unsigned int baud; unsigned int quot; baud = uart_get_baud_rate (port, termios, old, 8, port->uartclk/16); quot = uart_get_divisor (port, baud); /* -1 performed elsewhere */ switch (termios->c_cflag & CSIZE) { case CS5: fcon = WLEN_5; break; case CS6: fcon = WLEN_6; break; case CS7: fcon = WLEN_7; break; case CS8: default: fcon = WLEN_8; break; } if (termios->c_cflag & CSTOPB) fcon |= STP2; if (termios->c_cflag & PARENB) { fcon |= PEN; if (!(termios->c_cflag & PARODD)) fcon |= EPS; } if (port->fifosize > 1) fcon |= FEN; spin_lock_irqsave (&port->lock, flags); uart_update_timeout (port, termios->c_cflag, baud); port->read_status_mask = RxOverrunError; if (termios->c_iflag & INPCK) port->read_status_mask |= RxFramingError | RxParityError; if (termios->c_iflag & (BRKINT | PARMRK)) port->read_status_mask |= RxBreak; /* Figure mask for status we ignore */ port->ignore_status_mask = 0; if (termios->c_iflag & IGNPAR) port->ignore_status_mask |= RxFramingError | RxParityError; if (termios->c_iflag & IGNBRK) { port->ignore_status_mask |= RxBreak; /* Ignore overrun when ignorning parity */ /* *** FIXME: is this in the right place? */ if (termios->c_iflag & IGNPAR) port->ignore_status_mask |= RxOverrunError; } /* Ignore all receive errors when receive disabled */ if ((termios->c_cflag & CREAD) == 0) port->ignore_status_mask |= RxError; con = UR (port, UART_R_CON); inten = (UR (port, UART_R_INTEN) & ~ModemInt); if (UART_ENABLE_MS (port, termios->c_cflag)) inten |= ModemInt; BIT_CLR (port, UART_R_CON, UARTEN); /* Disable UART */ UR (port, UART_R_INTEN) = 0; /* Disable interrupts */ UR (port, UART_R_BRCON) = quot - 1; /* Set baud rate divisor */ UR (port, UART_R_FCON) = fcon; /* Set FIFO and frame ctrl */ UR (port, UART_R_INTEN) = inten; /* Enable interrupts */ UR (port, UART_R_CON) = con; /* Restore UART mode */ spin_unlock_irqrestore(&port->lock, flags); }
static void serial_ambarella_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct ambarella_uart_port_info *port_info; unsigned int baud, quot; u32 lc = 0x0; port_info = (struct ambarella_uart_port_info *)(port->private_data); port->uartclk = port_info->get_pll(); switch (termios->c_cflag & CSIZE) { case CS5: lc |= UART_LC_CLS_5_BITS; break; case CS6: lc |= UART_LC_CLS_6_BITS; break; case CS7: lc |= UART_LC_CLS_7_BITS; break; case CS8: default: lc |= UART_LC_CLS_8_BITS; break; } if (termios->c_cflag & CSTOPB) lc |= UART_LC_STOP_2BIT; else lc |= UART_LC_STOP_1BIT; if (termios->c_cflag & PARENB) { if (termios->c_cflag & PARODD) lc |= (UART_LC_EPS | UART_LC_ODD_PARITY); else lc |= (UART_LC_EPS | UART_LC_EVEN_PARITY); } baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); quot = uart_get_divisor(port, baud); disable_irq(port->irq); uart_update_timeout(port, termios->c_cflag, baud); port->read_status_mask = UART_LSR_OE | UART_LSR_THRE | UART_LSR_DR; if (termios->c_iflag & INPCK) port->read_status_mask |= UART_LSR_FE | UART_LSR_PE; if (termios->c_iflag & (BRKINT | PARMRK)) port->read_status_mask |= UART_LSR_BI; port->ignore_status_mask = 0; if (termios->c_iflag & IGNPAR) port->ignore_status_mask |= UART_LSR_PE | UART_LSR_FE; if (termios->c_iflag & IGNBRK) { port->ignore_status_mask |= UART_LSR_BI; if (termios->c_iflag & IGNPAR) port->ignore_status_mask |= UART_LSR_OE; } if ((termios->c_cflag & CREAD) == 0) port->ignore_status_mask |= UART_LSR_DR; if ((termios->c_cflag & CRTSCTS) == 0) port_info->mcr &= ~UART_MC_AFCE; else port_info->mcr |= UART_MC_AFCE; amba_writel(port->membase + UART_LC_OFFSET, UART_LC_DLAB); amba_writel(port->membase + UART_DLL_OFFSET, quot & 0xff); amba_writel(port->membase + UART_DLH_OFFSET, (quot >> 8) & 0xff); amba_writel(port->membase + UART_LC_OFFSET, lc); if (UART_ENABLE_MS(port, termios->c_cflag)) __serial_ambarella_enable_ms(port); else __serial_ambarella_disable_ms(port); serial_ambarella_set_mctrl(port, port->mctrl); enable_irq(port->irq); }
static void ip3106_set_termios(struct uart_port *port, struct termios *termios, struct termios *old) { struct ip3106_port *sport = (struct ip3106_port *)port; unsigned long flags; unsigned int lcr_fcr, old_ien, baud, quot; unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8; /* * We only support CS7 and CS8. */ while ((termios->c_cflag & CSIZE) != CS7 && (termios->c_cflag & CSIZE) != CS8) { termios->c_cflag &= ~CSIZE; termios->c_cflag |= old_csize; old_csize = CS8; } if ((termios->c_cflag & CSIZE) == CS8) lcr_fcr = IP3106_UART_LCR_8BIT; else lcr_fcr = 0; if (termios->c_cflag & CSTOPB) lcr_fcr |= IP3106_UART_LCR_2STOPB; if (termios->c_cflag & PARENB) { lcr_fcr |= IP3106_UART_LCR_PAREN; if (!(termios->c_cflag & PARODD)) lcr_fcr |= IP3106_UART_LCR_PAREVN; } /* * 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); spin_lock_irqsave(&sport->port.lock, flags); #if 0 /* REVISIT */ sport->port.read_status_mask &= UTSR0_TO_SM(UTSR0_TFS); sport->port.read_status_mask |= UTSR1_TO_SM(UTSR1_ROR); if (termios->c_iflag & INPCK) sport->port.read_status_mask |= UTSR1_TO_SM(UTSR1_FRE | UTSR1_PRE); if (termios->c_iflag & (BRKINT | PARMRK)) sport->port.read_status_mask |= UTSR0_TO_SM(UTSR0_RBB | UTSR0_REB); /* * Characters to ignore */ sport->port.ignore_status_mask = 0; if (termios->c_iflag & IGNPAR) sport->port.ignore_status_mask |= UTSR1_TO_SM(UTSR1_FRE | UTSR1_PRE); if (termios->c_iflag & IGNBRK) { sport->port.ignore_status_mask |= UTSR0_TO_SM(UTSR0_RBB | UTSR0_REB); /* * If we're ignoring parity and break indicators, * ignore overruns too (for real raw support). */ if (termios->c_iflag & IGNPAR) sport->port.ignore_status_mask |= UTSR1_TO_SM(UTSR1_ROR); } #endif del_timer_sync(&sport->timer); /* * Update the per-port timeout. */ uart_update_timeout(port, termios->c_cflag, baud); /* * disable interrupts and drain transmitter */ old_ien = serial_in(sport, IP3106_IEN); serial_out(sport, IP3106_IEN, old_ien & ~(IP3106_UART_INT_ALLTX | IP3106_UART_INT_ALLRX)); while (serial_in(sport, IP3106_FIFO) & IP3106_UART_FIFO_TXFIFO_STA) barrier(); /* then, disable everything */ serial_out(sport, IP3106_IEN, 0); /* Reset the Rx and Tx FIFOs too */ lcr_fcr |= IP3106_UART_LCR_TX_RST; lcr_fcr |= IP3106_UART_LCR_RX_RST; /* set the parity, stop bits and data size */ serial_out(sport, IP3106_LCR, lcr_fcr); /* set the baud rate */ quot -= 1; serial_out(sport, IP3106_BAUD, quot); serial_out(sport, IP3106_ICLR, -1); serial_out(sport, IP3106_IEN, old_ien); if (UART_ENABLE_MS(&sport->port, termios->c_cflag)) ip3106_enable_ms(&sport->port); spin_unlock_irqrestore(&sport->port.lock, flags); }
static void serial_hsu_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct uart_hsu_port *up = container_of(port, struct uart_hsu_port, port); struct tty_struct *tty = port->state->port.tty; unsigned char cval, fcr = 0; unsigned long flags; unsigned int baud, quot; u32 ps, mul; switch (termios->c_cflag & CSIZE) { case CS5: cval = UART_LCR_WLEN5; break; case CS6: cval = UART_LCR_WLEN6; break; case CS7: cval = UART_LCR_WLEN7; break; default: case CS8: cval = UART_LCR_WLEN8; break; } /* CMSPAR isn't supported by this driver */ if (tty) tty->termios->c_cflag &= ~CMSPAR; if (termios->c_cflag & CSTOPB) cval |= UART_LCR_STOP; if (termios->c_cflag & PARENB) cval |= UART_LCR_PARITY; if (!(termios->c_cflag & PARODD)) cval |= UART_LCR_EPAR; /* * The base clk is 50Mhz, and the baud rate come from: * baud = 50M * MUL / (DIV * PS * DLAB) * * For those basic low baud rate we can get the direct * scalar from 2746800, like 115200 = 2746800/24. For those * higher baud rate, we handle them case by case, mainly by * adjusting the MUL/PS registers, and DIV register is kept * as default value 0x3d09 to make things simple */ baud = uart_get_baud_rate(port, termios, old, 0, 4000000); quot = 1; ps = 0x10; mul = 0x3600; switch (baud) { case 3500000: mul = 0x3345; ps = 0xC; break; case 1843200: mul = 0x2400; break; case 3000000: case 2500000: case 2000000: case 1500000: case 1000000: case 500000: /* mul/ps/quot = 0x9C4/0x10/0x1 will make a 500000 bps */ mul = baud / 500000 * 0x9C4; break; default: /* Use uart_get_divisor to get quot for other baud rates */ quot = 0; } if (!quot) quot = uart_get_divisor(port, baud); if ((up->port.uartclk / quot) < (2400 * 16)) fcr = UART_FCR_ENABLE_FIFO | UART_FCR_HSU_64_1B; else if ((up->port.uartclk / quot) < (230400 * 16)) fcr = UART_FCR_ENABLE_FIFO | UART_FCR_HSU_64_16B; else fcr = UART_FCR_ENABLE_FIFO | UART_FCR_HSU_64_32B; fcr |= UART_FCR_HSU_64B_FIFO; #ifdef MFD_HSU_A0_STEPPING /* A0 doesn't support half empty IRQ */ fcr |= UART_FCR_FULL_EMPT_TXI; #endif /* * 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; /* Characters 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, disable * MSI by default */ up->ier &= ~UART_IER_MSI; if (UART_ENABLE_MS(&up->port, termios->c_cflag)) up->ier |= UART_IER_MSI; serial_out(up, UART_IER, up->ier); if (termios->c_cflag & CRTSCTS) up->mcr |= UART_MCR_AFE | UART_MCR_RTS; else up->mcr &= ~UART_MCR_AFE; serial_out(up, UART_LCR, cval | UART_LCR_DLAB); /* set DLAB */ serial_out(up, UART_DLL, quot & 0xff); /* LS of divisor */ serial_out(up, UART_DLM, quot >> 8); /* MS of divisor */ serial_out(up, UART_LCR, cval); /* reset DLAB */ serial_out(up, UART_MUL, mul); /* set MUL */ serial_out(up, UART_PS, ps); /* set PS */ up->lcr = cval; /* Save LCR */ serial_hsu_set_mctrl(&up->port, up->port.mctrl); serial_out(up, UART_FCR, fcr); spin_unlock_irqrestore(&up->port.lock, flags); }
static void imx_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct imx_port *sport = (struct imx_port *)port; unsigned long flags; unsigned int ucr2, old_ucr1, old_txrxen, baud, quot; unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8; /* * If we don't support modem control lines, don't allow * these to be set. */ if (0) { termios->c_cflag &= ~(HUPCL | CRTSCTS | CMSPAR); termios->c_cflag |= CLOCAL; } /* * We only support CS7 and CS8. */ while ((termios->c_cflag & CSIZE) != CS7 && (termios->c_cflag & CSIZE) != CS8) { termios->c_cflag &= ~CSIZE; termios->c_cflag |= old_csize; old_csize = CS8; } if ((termios->c_cflag & CSIZE) == CS8) ucr2 = UCR2_WS | UCR2_SRST | UCR2_IRTS; else ucr2 = UCR2_SRST | UCR2_IRTS; if (termios->c_cflag & CRTSCTS) { if( sport->have_rtscts ) { ucr2 &= ~UCR2_IRTS; ucr2 |= UCR2_CTSC; } else { termios->c_cflag &= ~CRTSCTS; } } if (termios->c_cflag & CSTOPB) ucr2 |= UCR2_STPB; if (termios->c_cflag & PARENB) { ucr2 |= UCR2_PREN; if (termios->c_cflag & PARODD) ucr2 |= UCR2_PROE; } /* * 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); spin_lock_irqsave(&sport->port.lock, flags); sport->port.read_status_mask = 0; if (termios->c_iflag & INPCK) sport->port.read_status_mask |= (URXD_FRMERR | URXD_PRERR); if (termios->c_iflag & (BRKINT | PARMRK)) sport->port.read_status_mask |= URXD_BRK; /* * Characters to ignore */ sport->port.ignore_status_mask = 0; if (termios->c_iflag & IGNPAR) sport->port.ignore_status_mask |= URXD_PRERR; if (termios->c_iflag & IGNBRK) { sport->port.ignore_status_mask |= URXD_BRK; /* * If we're ignoring parity and break indicators, * ignore overruns too (for real raw support). */ if (termios->c_iflag & IGNPAR) sport->port.ignore_status_mask |= URXD_OVRRUN; } del_timer_sync(&sport->timer); /* * Update the per-port timeout. */ uart_update_timeout(port, termios->c_cflag, baud); /* * disable interrupts and drain transmitter */ old_ucr1 = readl(sport->port.membase + UCR1); writel(old_ucr1 & ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN), sport->port.membase + UCR1); while ( !(readl(sport->port.membase + USR2) & USR2_TXDC)) barrier(); /* then, disable everything */ old_txrxen = readl(sport->port.membase + UCR2); writel(old_txrxen & ~( UCR2_TXEN | UCR2_RXEN), sport->port.membase + UCR2); old_txrxen &= (UCR2_TXEN | UCR2_RXEN); /* set the baud rate. We assume uartclk = 16 MHz * * baud * 16 UBIR - 1 * --------- = -------- * uartclk UBMR - 1 */ writel((baud / 100) - 1, sport->port.membase + UBIR); writel(10000 - 1, sport->port.membase + UBMR); writel(old_ucr1, sport->port.membase + UCR1); /* set the parity, stop bits and data size */ writel(ucr2 | old_txrxen, sport->port.membase + UCR2); if (UART_ENABLE_MS(&sport->port, termios->c_cflag)) imx_enable_ms(&sport->port); spin_unlock_irqrestore(&sport->port.lock, flags); }
static void sa1100_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct sa1100_port *sport = (struct sa1100_port *)port; unsigned long flags; unsigned int utcr0, old_utcr3, baud, quot; unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8; /* * We only support CS7 and CS8. */ while ((termios->c_cflag & CSIZE) != CS7 && (termios->c_cflag & CSIZE) != CS8) { termios->c_cflag &= ~CSIZE; termios->c_cflag |= old_csize; old_csize = CS8; } if ((termios->c_cflag & CSIZE) == CS8) utcr0 = UTCR0_DSS; else utcr0 = 0; if (termios->c_cflag & CSTOPB) utcr0 |= UTCR0_SBS; if (termios->c_cflag & PARENB) { utcr0 |= UTCR0_PE; if (!(termios->c_cflag & PARODD)) utcr0 |= UTCR0_OES; } /* * 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); spin_lock_irqsave(&sport->port.lock, flags); sport->port.read_status_mask &= UTSR0_TO_SM(UTSR0_TFS); sport->port.read_status_mask |= UTSR1_TO_SM(UTSR1_ROR); if (termios->c_iflag & INPCK) sport->port.read_status_mask |= UTSR1_TO_SM(UTSR1_FRE | UTSR1_PRE); if (termios->c_iflag & (BRKINT | PARMRK)) sport->port.read_status_mask |= UTSR0_TO_SM(UTSR0_RBB | UTSR0_REB); /* * Characters to ignore */ sport->port.ignore_status_mask = 0; if (termios->c_iflag & IGNPAR) sport->port.ignore_status_mask |= UTSR1_TO_SM(UTSR1_FRE | UTSR1_PRE); if (termios->c_iflag & IGNBRK) { sport->port.ignore_status_mask |= UTSR0_TO_SM(UTSR0_RBB | UTSR0_REB); /* * If we're ignoring parity and break indicators, * ignore overruns too (for real raw support). */ if (termios->c_iflag & IGNPAR) sport->port.ignore_status_mask |= UTSR1_TO_SM(UTSR1_ROR); } del_timer_sync(&sport->timer); /* * Update the per-port timeout. */ uart_update_timeout(port, termios->c_cflag, baud); /* * disable interrupts and drain transmitter */ old_utcr3 = UART_GET_UTCR3(sport); UART_PUT_UTCR3(sport, old_utcr3 & ~(UTCR3_RIE | UTCR3_TIE)); while (UART_GET_UTSR1(sport) & UTSR1_TBY) barrier(); /* then, disable everything */ UART_PUT_UTCR3(sport, 0); /* set the parity, stop bits and data size */ UART_PUT_UTCR0(sport, utcr0); /* set the baud rate */ quot -= 1; UART_PUT_UTCR1(sport, ((quot & 0xf00) >> 8)); UART_PUT_UTCR2(sport, (quot & 0xff)); UART_PUT_UTSR0(sport, -1); UART_PUT_UTCR3(sport, old_utcr3); if (UART_ENABLE_MS(&sport->port, termios->c_cflag)) sa1100_enable_ms(&sport->port); spin_unlock_irqrestore(&sport->port.lock, flags); }
static void imx_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct imx_port *sport = (struct imx_port *)port; unsigned long flags; unsigned int ucr2, old_ucr1, old_txrxen, baud, quot; unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8; unsigned int div, num, denom, ufcr; /* * If we don't support modem control lines, don't allow * these to be set. */ if (0) { termios->c_cflag &= ~(HUPCL | CRTSCTS | CMSPAR); termios->c_cflag |= CLOCAL; } /* * We only support CS7 and CS8. */ while ((termios->c_cflag & CSIZE) != CS7 && (termios->c_cflag & CSIZE) != CS8) { termios->c_cflag &= ~CSIZE; termios->c_cflag |= old_csize; old_csize = CS8; } if ((termios->c_cflag & CSIZE) == CS8) ucr2 = UCR2_WS | UCR2_SRST | UCR2_IRTS; else ucr2 = UCR2_SRST | UCR2_IRTS; if (termios->c_cflag & CRTSCTS) { if( sport->have_rtscts ) { ucr2 &= ~UCR2_IRTS; ucr2 |= UCR2_CTSC; } else { termios->c_cflag &= ~CRTSCTS; } } if (termios->c_cflag & CSTOPB) ucr2 |= UCR2_STPB; if (termios->c_cflag & PARENB) { ucr2 |= UCR2_PREN; if (termios->c_cflag & PARODD) ucr2 |= UCR2_PROE; } /* * Ask the core to calculate the divisor for us. */ baud = uart_get_baud_rate(port, termios, old, 50, port->uartclk / 16); quot = uart_get_divisor(port, baud); spin_lock_irqsave(&sport->port.lock, flags); sport->port.read_status_mask = 0; if (termios->c_iflag & INPCK) sport->port.read_status_mask |= (URXD_FRMERR | URXD_PRERR); if (termios->c_iflag & (BRKINT | PARMRK)) sport->port.read_status_mask |= URXD_BRK; /* * Characters to ignore */ sport->port.ignore_status_mask = 0; if (termios->c_iflag & IGNPAR) sport->port.ignore_status_mask |= URXD_PRERR; if (termios->c_iflag & IGNBRK) { sport->port.ignore_status_mask |= URXD_BRK; /* * If we're ignoring parity and break indicators, * ignore overruns too (for real raw support). */ if (termios->c_iflag & IGNPAR) sport->port.ignore_status_mask |= URXD_OVRRUN; } del_timer_sync(&sport->timer); /* * Update the per-port timeout. */ uart_update_timeout(port, termios->c_cflag, baud); /* * disable interrupts and drain transmitter */ old_ucr1 = readl(sport->port.membase + UCR1); writel(old_ucr1 & ~(UCR1_TXMPTYEN | UCR1_RRDYEN | UCR1_RTSDEN), sport->port.membase + UCR1); while ( !(readl(sport->port.membase + USR2) & USR2_TXDC)) barrier(); /* then, disable everything */ old_txrxen = readl(sport->port.membase + UCR2); writel(old_txrxen & ~( UCR2_TXEN | UCR2_RXEN), sport->port.membase + UCR2); old_txrxen &= (UCR2_TXEN | UCR2_RXEN); div = sport->port.uartclk / (baud * 16); if (div > 7) div = 7; if (!div) div = 1; num = baud; denom = port->uartclk / div / 16; /* shift num and denom right until they fit into 16 bits */ while (num > 0x10000 || denom > 0x10000) { num >>= 1; denom >>= 1; } if (num > 0) num -= 1; if (denom > 0) denom -= 1; writel(num, sport->port.membase + UBIR); writel(denom, sport->port.membase + UBMR); if (div == 7) div = 6; /* 6 in RFDIV means divide by 7 */ else div = 6 - div; ufcr = readl(sport->port.membase + UFCR); ufcr = (ufcr & (~UFCR_RFDIV)) | (div << 7); writel(ufcr, sport->port.membase + UFCR); #ifdef ONEMS writel(sport->port.uartclk / div / 1000, sport->port.membase + ONEMS); #endif writel(old_ucr1, sport->port.membase + UCR1); /* set the parity, stop bits and data size */ writel(ucr2 | old_txrxen, sport->port.membase + UCR2); if (UART_ENABLE_MS(&sport->port, termios->c_cflag)) imx_enable_ms(&sport->port); spin_unlock_irqrestore(&sport->port.lock, flags); }
static void clps711xuart_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { unsigned int ubrlcr, baud, quot; unsigned long flags; /* * We don't implement CREAD. */ 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); switch (termios->c_cflag & CSIZE) { case CS5: ubrlcr = UBRLCR_WRDLEN5; break; case CS6: ubrlcr = UBRLCR_WRDLEN6; break; case CS7: ubrlcr = UBRLCR_WRDLEN7; break; default: // CS8 ubrlcr = UBRLCR_WRDLEN8; break; } if (termios->c_cflag & CSTOPB) ubrlcr |= UBRLCR_XSTOP; if (termios->c_cflag & PARENB) { ubrlcr |= UBRLCR_PRTEN; if (!(termios->c_cflag & PARODD)) ubrlcr |= UBRLCR_EVENPRT; } if (port->fifosize > 1) ubrlcr |= UBRLCR_FIFOEN; spin_lock_irqsave(&port->lock, flags); /* * Update the per-port timeout. */ uart_update_timeout(port, termios->c_cflag, baud); port->read_status_mask = UARTDR_OVERR; if (termios->c_iflag & INPCK) port->read_status_mask |= UARTDR_PARERR | UARTDR_FRMERR; /* * Characters to ignore */ port->ignore_status_mask = 0; if (termios->c_iflag & IGNPAR) port->ignore_status_mask |= UARTDR_FRMERR | UARTDR_PARERR; if (termios->c_iflag & IGNBRK) { /* * If we're ignoring parity and break indicators, * ignore overruns to (for real raw support). */ if (termios->c_iflag & IGNPAR) port->ignore_status_mask |= UARTDR_OVERR; } quot -= 1; clps_writel(ubrlcr | quot, UBRLCR(port)); spin_unlock_irqrestore(&port->lock, flags); }
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); }