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); if (port->state && port->state->port.tty) { tdiv64 = sport->port.uartclk; tdiv64 *= num; do_div(tdiv64, denom * 16 * div); tty_encode_baud_rate(sport->port.state->port.tty, (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); }
/* * Change the port parameters */ static void atmel_set_termios(struct uart_port *port, struct ktermios * termios, struct ktermios * old) { 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; /* * 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)) { barrier(); } /* 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 serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct uart_omap_port *up = (struct uart_omap_port *)port; unsigned char cval = 0; unsigned char efr = 0; unsigned long flags = 0; 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/13); quot = serial_omap_get_divisor(port, baud); /* calculate wakeup latency constraint */ up->calc_latency = (USEC_PER_SEC * up->port.fifosize) / (baud / 8); up->latency = up->calc_latency; schedule_work(&up->qos_work); up->dll = quot & 0xff; up->dlh = quot >> 8; up->mdr1 = UART_OMAP_MDR1_DISABLE; up->fcr = UART_FCR_R_TRIG_01 | UART_FCR_T_TRIG_01 | UART_FCR_ENABLE_FIFO; if (up->use_dma) up->fcr |= UART_FCR_DMA_SELECT; /* * Ok, we're now changing the port state. Do it with * interrupts disabled. */ pm_runtime_get_sync(&up->pdev->dev); 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; /* * 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); /* reset DLAB */ up->lcr = cval; up->scr = OMAP_UART_SCR_TX_EMPTY; /* FIFOs and DMA Settings */ /* FCR can be changed only when the * baud clock is not running * DLL_REG and DLH_REG set to 0. */ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); serial_out(up, UART_DLL, 0); serial_out(up, UART_DLM, 0); serial_out(up, UART_LCR, 0); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); up->efr = serial_in(up, UART_EFR); serial_out(up, UART_EFR, up->efr | UART_EFR_ECB); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); up->mcr = serial_in(up, UART_MCR); serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR); /* FIFO ENABLE, DMA MODE */ up->scr |= OMAP_UART_SCR_RX_TRIG_GRANU1_MASK; if (up->use_dma) { serial_out(up, UART_TI752_TLR, 0); up->scr |= UART_FCR_TRIGGER_4; } else { /* Set receive FIFO threshold to 1 byte */ up->fcr &= ~OMAP_UART_FCR_RX_FIFO_TRIG_MASK; up->fcr |= (0x1 << OMAP_UART_FCR_RX_FIFO_TRIG_SHIFT); } serial_out(up, UART_FCR, up->fcr); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); serial_out(up, UART_OMAP_SCR, up->scr); serial_out(up, UART_EFR, up->efr); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); serial_out(up, UART_MCR, up->mcr); /* Protocol, Baud Rate, and Interrupt Settings */ if (up->errata & UART_ERRATA_i202_MDR1_ACCESS) serial_omap_mdr1_errataset(up, up->mdr1); else serial_out(up, UART_OMAP_MDR1, up->mdr1); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); up->efr = serial_in(up, UART_EFR); serial_out(up, UART_EFR, up->efr | UART_EFR_ECB); serial_out(up, UART_LCR, 0); serial_out(up, UART_IER, 0); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); serial_out(up, UART_DLL, up->dll); /* LS of divisor */ serial_out(up, UART_DLM, up->dlh); /* MS of divisor */ serial_out(up, UART_LCR, 0); serial_out(up, UART_IER, up->ier); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); serial_out(up, UART_EFR, up->efr); serial_out(up, UART_LCR, cval); if (baud > 230400 && baud != 3000000) up->mdr1 = UART_OMAP_MDR1_13X_MODE; else up->mdr1 = UART_OMAP_MDR1_16X_MODE; if (up->errata & UART_ERRATA_i202_MDR1_ACCESS) serial_omap_mdr1_errataset(up, up->mdr1); else serial_out(up, UART_OMAP_MDR1, up->mdr1); /* Hardware Flow Control Configuration */ if (termios->c_cflag & CRTSCTS) { efr |= (UART_EFR_CTS | UART_EFR_RTS); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); up->mcr = serial_in(up, UART_MCR); serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); up->efr = serial_in(up, UART_EFR); serial_out(up, UART_EFR, up->efr | UART_EFR_ECB); serial_out(up, UART_TI752_TCR, OMAP_UART_TCR_TRIG); serial_out(up, UART_EFR, efr); /* Enable AUTORTS and AUTOCTS */ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); serial_out(up, UART_MCR, up->mcr | UART_MCR_RTS); serial_out(up, UART_LCR, cval); } serial_omap_set_mctrl(&up->port, up->port.mctrl); /* Software Flow Control Configuration */ serial_omap_configure_xonxoff(up, termios); spin_unlock_irqrestore(&up->port.lock, flags); pm_runtime_put(&up->pdev->dev); dev_dbg(up->port.dev, "serial_omap_set_termios+%d\n", up->port.line); }
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 sirfsoc_uart_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct sirfsoc_uart_port *sirfport = to_sirfport(port); struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en; unsigned long config_reg = 0; unsigned long baud_rate; unsigned long set_baud; unsigned long flags; unsigned long ic; unsigned int clk_div_reg = 0; unsigned long txfifo_op_reg, ioclk_rate; unsigned long rx_time_out; int threshold_div; u32 data_bit_len, stop_bit_len, len_val; unsigned long sample_div_reg = 0xf; ioclk_rate = port->uartclk; switch (termios->c_cflag & CSIZE) { default: case CS8: data_bit_len = 8; config_reg |= SIRFUART_DATA_BIT_LEN_8; break; case CS7: data_bit_len = 7; config_reg |= SIRFUART_DATA_BIT_LEN_7; break; case CS6: data_bit_len = 6; config_reg |= SIRFUART_DATA_BIT_LEN_6; break; case CS5: data_bit_len = 5; config_reg |= SIRFUART_DATA_BIT_LEN_5; break; } if (termios->c_cflag & CSTOPB) { config_reg |= SIRFUART_STOP_BIT_LEN_2; stop_bit_len = 2; } else stop_bit_len = 1; spin_lock_irqsave(&port->lock, flags); port->read_status_mask = uint_en->sirfsoc_rx_oflow_en; port->ignore_status_mask = 0; if (sirfport->uart_reg->uart_type == SIRF_REAL_UART) { if (termios->c_iflag & INPCK) port->read_status_mask |= uint_en->sirfsoc_frm_err_en | uint_en->sirfsoc_parity_err_en; } else { if (termios->c_iflag & INPCK) port->read_status_mask |= uint_en->sirfsoc_frm_err_en; } if (termios->c_iflag & (BRKINT | PARMRK)) port->read_status_mask |= uint_en->sirfsoc_rxd_brk_en; if (sirfport->uart_reg->uart_type == SIRF_REAL_UART) { if (termios->c_iflag & IGNPAR) port->ignore_status_mask |= uint_en->sirfsoc_frm_err_en | uint_en->sirfsoc_parity_err_en; if (termios->c_cflag & PARENB) { if (termios->c_cflag & CMSPAR) { if (termios->c_cflag & PARODD) config_reg |= SIRFUART_STICK_BIT_MARK; else config_reg |= SIRFUART_STICK_BIT_SPACE; } else if (termios->c_cflag & PARODD) { config_reg |= SIRFUART_STICK_BIT_ODD; } else { config_reg |= SIRFUART_STICK_BIT_EVEN; } } } else { if (termios->c_iflag & IGNPAR) port->ignore_status_mask |= uint_en->sirfsoc_frm_err_en; if (termios->c_cflag & PARENB) dev_warn(port->dev, "USP-UART not support parity err\n"); } if (termios->c_iflag & IGNBRK) { port->ignore_status_mask |= uint_en->sirfsoc_rxd_brk_en; if (termios->c_iflag & IGNPAR) port->ignore_status_mask |= uint_en->sirfsoc_rx_oflow_en; } if ((termios->c_cflag & CREAD) == 0) port->ignore_status_mask |= SIRFUART_DUMMY_READ; /* Hardware Flow Control Settings */ if (UART_ENABLE_MS(port, termios->c_cflag)) { if (!sirfport->ms_enabled) sirfsoc_uart_enable_ms(port); } else { if (sirfport->ms_enabled) sirfsoc_uart_disable_ms(port); } baud_rate = uart_get_baud_rate(port, termios, old, 0, 4000000); if (ioclk_rate == 150000000) { for (ic = 0; ic < SIRF_BAUD_RATE_SUPPORT_NR; ic++) if (baud_rate == baudrate_to_regv[ic].baud_rate) clk_div_reg = baudrate_to_regv[ic].reg_val; } set_baud = baud_rate; if (sirfport->uart_reg->uart_type == SIRF_REAL_UART) { if (unlikely(clk_div_reg == 0)) clk_div_reg = sirfsoc_uart_calc_sample_div(baud_rate, ioclk_rate, &set_baud); wr_regl(port, ureg->sirfsoc_divisor, clk_div_reg); } else { clk_div_reg = sirfsoc_usp_calc_sample_div(baud_rate, ioclk_rate, &sample_div_reg); sample_div_reg--; set_baud = ((ioclk_rate / (clk_div_reg+1) - 1) / (sample_div_reg + 1)); /* setting usp mode 2 */ len_val = ((1 << SIRFSOC_USP_MODE2_RXD_DELAY_OFFSET) | (1 << SIRFSOC_USP_MODE2_TXD_DELAY_OFFSET)); len_val |= ((clk_div_reg & SIRFSOC_USP_MODE2_CLK_DIVISOR_MASK) << SIRFSOC_USP_MODE2_CLK_DIVISOR_OFFSET); wr_regl(port, ureg->sirfsoc_mode2, len_val); } if (tty_termios_baud_rate(termios)) tty_termios_encode_baud_rate(termios, set_baud, set_baud); /* set receive timeout && data bits len */ rx_time_out = SIRFSOC_UART_RX_TIMEOUT(set_baud, 20000); rx_time_out = SIRFUART_RECV_TIMEOUT_VALUE(rx_time_out); txfifo_op_reg = rd_regl(port, ureg->sirfsoc_tx_fifo_op); wr_regl(port, ureg->sirfsoc_rx_fifo_op, SIRFUART_FIFO_STOP); wr_regl(port, ureg->sirfsoc_tx_fifo_op, (txfifo_op_reg & ~SIRFUART_FIFO_START)); if (sirfport->uart_reg->uart_type == SIRF_REAL_UART) { config_reg |= SIRFUART_RECV_TIMEOUT(port, rx_time_out); wr_regl(port, ureg->sirfsoc_line_ctrl, config_reg); } else { /*tx frame ctrl*/ len_val = (data_bit_len - 1) << SIRFSOC_USP_TX_DATA_LEN_OFFSET; len_val |= (data_bit_len + 1 + stop_bit_len - 1) << SIRFSOC_USP_TX_FRAME_LEN_OFFSET; len_val |= ((data_bit_len - 1) << SIRFSOC_USP_TX_SHIFTER_LEN_OFFSET); len_val |= (((clk_div_reg & 0xc00) >> 10) << SIRFSOC_USP_TX_CLK_DIVISOR_OFFSET); wr_regl(port, ureg->sirfsoc_tx_frame_ctrl, len_val); /*rx frame ctrl*/ len_val = (data_bit_len - 1) << SIRFSOC_USP_RX_DATA_LEN_OFFSET; len_val |= (data_bit_len + 1 + stop_bit_len - 1) << SIRFSOC_USP_RX_FRAME_LEN_OFFSET; len_val |= (data_bit_len - 1) << SIRFSOC_USP_RX_SHIFTER_LEN_OFFSET; len_val |= (((clk_div_reg & 0xf000) >> 12) << SIRFSOC_USP_RX_CLK_DIVISOR_OFFSET); wr_regl(port, ureg->sirfsoc_rx_frame_ctrl, len_val); /*async param*/ wr_regl(port, ureg->sirfsoc_async_param_reg, (SIRFUART_RECV_TIMEOUT(port, rx_time_out)) | (sample_div_reg & SIRFSOC_USP_ASYNC_DIV2_MASK) << SIRFSOC_USP_ASYNC_DIV2_OFFSET); } if (IS_DMA_CHAN_VALID(sirfport->tx_dma_no)) wr_regl(port, ureg->sirfsoc_tx_dma_io_ctrl, SIRFUART_DMA_MODE); else wr_regl(port, ureg->sirfsoc_tx_dma_io_ctrl, SIRFUART_IO_MODE); if (IS_DMA_CHAN_VALID(sirfport->rx_dma_no)) wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, SIRFUART_DMA_MODE); else wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl, SIRFUART_IO_MODE); /* Reset Rx/Tx FIFO Threshold level for proper baudrate */ if (set_baud < 1000000) threshold_div = 1; else threshold_div = 2; wr_regl(port, ureg->sirfsoc_tx_fifo_ctrl, SIRFUART_FIFO_THD(port) / threshold_div); wr_regl(port, ureg->sirfsoc_rx_fifo_ctrl, SIRFUART_FIFO_THD(port) / threshold_div); txfifo_op_reg |= SIRFUART_FIFO_START; wr_regl(port, ureg->sirfsoc_tx_fifo_op, txfifo_op_reg); uart_update_timeout(port, termios->c_cflag, set_baud); sirfsoc_uart_start_rx(port); wr_regl(port, ureg->sirfsoc_tx_rx_en, SIRFUART_TX_EN | SIRFUART_RX_EN); spin_unlock_irqrestore(&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; /* * 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 = 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; } /* * 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 = 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); /* * Characters to ignore */ 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 we're ignoring parity and break indicators, * ignore overruns too (for real raw support). */ if (termios->c_iflag & IGNPAR) sport->port.ignore_status_mask |= ISTAT_TO_SM(PNX8XXX_UART_INT_RXOVRN); } /* * ignore all characters if CREAD is not set */ if ((termios->c_cflag & CREAD) == 0) sport->port.ignore_status_mask |= ISTAT_TO_SM(PNX8XXX_UART_INT_RX); 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, 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(); /* then, disable everything */ serial_out(sport, PNX8XXX_IEN, 0); /* Reset the Rx and Tx FIFOs too */ lcr_fcr |= PNX8XXX_UART_LCR_TX_RST; lcr_fcr |= PNX8XXX_UART_LCR_RX_RST; /* set the parity, stop bits and data size */ serial_out(sport, PNX8XXX_LCR, lcr_fcr); /* set the baud rate */ 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 void max310x_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { unsigned int lcr, flow = 0; int baud; /* Mask termios capabilities we don't support */ termios->c_cflag &= ~CMSPAR; /* Word size */ switch (termios->c_cflag & CSIZE) { case CS5: lcr = MAX310X_LCR_WORD_LEN_5; break; case CS6: lcr = MAX310X_LCR_WORD_LEN_6; break; case CS7: lcr = MAX310X_LCR_WORD_LEN_7; break; case CS8: default: lcr = MAX310X_LCR_WORD_LEN_8; break; } /* Parity */ if (termios->c_cflag & PARENB) { lcr |= MAX310X_LCR_PARITY_BIT; if (!(termios->c_cflag & PARODD)) lcr |= MAX310X_LCR_EVENPARITY_BIT; } /* Stop bits */ if (termios->c_cflag & CSTOPB) lcr |= MAX310X_LCR_STOPLEN_BIT; /* 2 stops */ /* Update LCR register */ max310x_port_write(port, MAX310X_LCR_REG, lcr); /* Set read status mask */ port->read_status_mask = MAX310X_LSR_RXOVR_BIT; if (termios->c_iflag & INPCK) port->read_status_mask |= MAX310X_LSR_RXPAR_BIT | MAX310X_LSR_FRERR_BIT; if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK)) port->read_status_mask |= MAX310X_LSR_RXBRK_BIT; /* Set status ignore mask */ port->ignore_status_mask = 0; if (termios->c_iflag & IGNBRK) port->ignore_status_mask |= MAX310X_LSR_RXBRK_BIT; if (!(termios->c_cflag & CREAD)) port->ignore_status_mask |= MAX310X_LSR_RXPAR_BIT | MAX310X_LSR_RXOVR_BIT | MAX310X_LSR_FRERR_BIT | MAX310X_LSR_RXBRK_BIT; /* Configure flow control */ max310x_port_write(port, MAX310X_XON1_REG, termios->c_cc[VSTART]); max310x_port_write(port, MAX310X_XOFF1_REG, termios->c_cc[VSTOP]); if (termios->c_cflag & CRTSCTS) flow |= MAX310X_FLOWCTRL_AUTOCTS_BIT | MAX310X_FLOWCTRL_AUTORTS_BIT; if (termios->c_iflag & IXON) flow |= MAX310X_FLOWCTRL_SWFLOW3_BIT | MAX310X_FLOWCTRL_SWFLOWEN_BIT; if (termios->c_iflag & IXOFF) flow |= MAX310X_FLOWCTRL_SWFLOW1_BIT | MAX310X_FLOWCTRL_SWFLOWEN_BIT; max310x_port_write(port, MAX310X_FLOWCTRL_REG, flow); /* Get baud rate generator configuration */ baud = uart_get_baud_rate(port, termios, old, port->uartclk / 16 / 0xffff, port->uartclk / 4); /* Setup baudrate generator */ baud = max310x_set_baud(port, baud); /* Update timeout according to new baud rate */ uart_update_timeout(port, termios->c_cflag, baud); }
static void sc16is7xx_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct sc16is7xx_port *s = dev_get_drvdata(port->dev); unsigned int lcr, flow = 0; int baud; /* Mask termios capabilities we don't support */ termios->c_cflag &= ~CMSPAR; /* Word size */ switch (termios->c_cflag & CSIZE) { case CS5: lcr = SC16IS7XX_LCR_WORD_LEN_5; break; case CS6: lcr = SC16IS7XX_LCR_WORD_LEN_6; break; case CS7: lcr = SC16IS7XX_LCR_WORD_LEN_7; break; case CS8: lcr = SC16IS7XX_LCR_WORD_LEN_8; break; default: lcr = SC16IS7XX_LCR_WORD_LEN_8; termios->c_cflag &= ~CSIZE; termios->c_cflag |= CS8; break; } /* Parity */ if (termios->c_cflag & PARENB) { lcr |= SC16IS7XX_LCR_PARITY_BIT; if (!(termios->c_cflag & PARODD)) lcr |= SC16IS7XX_LCR_EVENPARITY_BIT; } /* Stop bits */ if (termios->c_cflag & CSTOPB) lcr |= SC16IS7XX_LCR_STOPLEN_BIT; /* 2 stops */ /* Set read status mask */ port->read_status_mask = SC16IS7XX_LSR_OE_BIT; if (termios->c_iflag & INPCK) port->read_status_mask |= SC16IS7XX_LSR_PE_BIT | SC16IS7XX_LSR_FE_BIT; if (termios->c_iflag & (BRKINT | PARMRK)) port->read_status_mask |= SC16IS7XX_LSR_BI_BIT; /* Set status ignore mask */ port->ignore_status_mask = 0; if (termios->c_iflag & IGNBRK) port->ignore_status_mask |= SC16IS7XX_LSR_BI_BIT; if (!(termios->c_cflag & CREAD)) port->ignore_status_mask |= SC16IS7XX_LSR_BRK_ERROR_MASK; sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, SC16IS7XX_LCR_CONF_MODE_B); /* Configure flow control */ regcache_cache_bypass(s->regmap, true); sc16is7xx_port_write(port, SC16IS7XX_XON1_REG, termios->c_cc[VSTART]); sc16is7xx_port_write(port, SC16IS7XX_XOFF1_REG, termios->c_cc[VSTOP]); if (termios->c_cflag & CRTSCTS) flow |= SC16IS7XX_EFR_AUTOCTS_BIT | SC16IS7XX_EFR_AUTORTS_BIT; if (termios->c_iflag & IXON) flow |= SC16IS7XX_EFR_SWFLOW3_BIT; if (termios->c_iflag & IXOFF) flow |= SC16IS7XX_EFR_SWFLOW1_BIT; sc16is7xx_port_write(port, SC16IS7XX_EFR_REG, flow); regcache_cache_bypass(s->regmap, false); /* Update LCR register */ sc16is7xx_port_write(port, SC16IS7XX_LCR_REG, lcr); /* Get baud rate generator configuration */ baud = uart_get_baud_rate(port, termios, old, port->uartclk / 16 / 4 / 0xffff, port->uartclk / 16); /* Setup baudrate generator */ baud = sc16is7xx_set_baud(port, baud); /* Update timeout according to new baud rate */ uart_update_timeout(port, termios->c_cflag, baud); }
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 & (IGNBRK | 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 msm_hsl_set_termios_cir(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { unsigned long flags; unsigned int baud, mr; unsigned int vid; spin_lock_irqsave(&port->lock, flags); baud = uart_get_baud_rate(port, termios, old, 300, 460800); msm_hsl_set_baud_rate(port, baud); vid = UART_TO_MSM(port)->ver_id; mr = msm_hsl_read(port, regmap[vid][UARTDM_MR2]); mr &= ~UARTDM_MR2_PARITY_MODE_BMSK; if (termios->c_cflag & PARENB) { if (termios->c_cflag & PARODD) mr |= ODD_PARITY; else if (termios->c_cflag & CMSPAR) mr |= SPACE_PARITY; else mr |= EVEN_PARITY; } mr &= ~UARTDM_MR2_BITS_PER_CHAR_BMSK; switch (termios->c_cflag & CSIZE) { case CS5: mr |= FIVE_BPC; break; case CS6: mr |= SIX_BPC; break; case CS7: mr |= SEVEN_BPC; break; case CS8: default: mr |= EIGHT_BPC; break; } mr &= ~(STOP_BIT_ONE | STOP_BIT_TWO); if (termios->c_cflag & CSTOPB) mr |= STOP_BIT_TWO; else mr |= STOP_BIT_ONE; msm_hsl_write(port, mr, regmap[vid][UARTDM_MR2]); mr = msm_hsl_read(port, regmap[vid][UARTDM_MR1]); mr &= ~(UARTDM_MR1_CTS_CTL_BMSK | UARTDM_MR1_RX_RDY_CTL_BMSK); if (termios->c_cflag & CRTSCTS) { mr |= UARTDM_MR1_CTS_CTL_BMSK; mr |= UARTDM_MR1_RX_RDY_CTL_BMSK; } msm_hsl_write(port, mr, regmap[vid][UARTDM_MR1]); port->read_status_mask = 0; if (termios->c_iflag & INPCK) port->read_status_mask |= UARTDM_SR_PAR_FRAME_BMSK; if (termios->c_iflag & (BRKINT | PARMRK)) port->read_status_mask |= UARTDM_SR_RX_BREAK_BMSK; uart_update_timeout(port, termios->c_cflag, baud); spin_unlock_irqrestore(&port->lock, flags); D("%s: cir MR is 0x%x\n", __func__, mr); D("%s: cir baud is %d\n", __func__, baud); }
static void sbd_set_termios(struct uart_port *uport, struct ktermios *termios, struct ktermios *old_termios) { struct sbd_port *sport = to_sport(uport); unsigned int mode1 = 0, mode2 = 0, aux = 0; unsigned int mode1mask = 0, mode2mask = 0, auxmask = 0; unsigned int oldmode1, oldmode2, oldaux; unsigned int baud, brg; unsigned int command; mode1mask |= ~(M_DUART_PARITY_MODE | M_DUART_PARITY_TYPE_ODD | M_DUART_BITS_PER_CHAR); mode2mask |= ~M_DUART_STOP_BIT_LEN_2; auxmask |= ~M_DUART_CTS_CHNG_ENA; /* Byte size. */ switch (termios->c_cflag & CSIZE) { case CS5: case CS6: /* Unsupported, leave unchanged. */ mode1mask |= M_DUART_PARITY_MODE; break; case CS7: mode1 |= V_DUART_BITS_PER_CHAR_7; break; case CS8: default: mode1 |= V_DUART_BITS_PER_CHAR_8; break; } /* Parity and stop bits. */ if (termios->c_cflag & CSTOPB) mode2 |= M_DUART_STOP_BIT_LEN_2; else mode2 |= M_DUART_STOP_BIT_LEN_1; if (termios->c_cflag & PARENB) mode1 |= V_DUART_PARITY_MODE_ADD; else mode1 |= V_DUART_PARITY_MODE_NONE; if (termios->c_cflag & PARODD) mode1 |= M_DUART_PARITY_TYPE_ODD; else mode1 |= M_DUART_PARITY_TYPE_EVEN; baud = uart_get_baud_rate(uport, termios, old_termios, 1200, 5000000); brg = V_DUART_BAUD_RATE(baud); /* The actual lower bound is 1221bps, so compensate. */ if (brg > M_DUART_CLK_COUNTER) brg = M_DUART_CLK_COUNTER; uart_update_timeout(uport, termios->c_cflag, baud); uport->read_status_mask = M_DUART_OVRUN_ERR; if (termios->c_iflag & INPCK) uport->read_status_mask |= M_DUART_FRM_ERR | M_DUART_PARITY_ERR; if (termios->c_iflag & (BRKINT | PARMRK)) uport->read_status_mask |= M_DUART_RCVD_BRK; uport->ignore_status_mask = 0; if (termios->c_iflag & IGNPAR) uport->ignore_status_mask |= M_DUART_FRM_ERR | M_DUART_PARITY_ERR; if (termios->c_iflag & IGNBRK) { uport->ignore_status_mask |= M_DUART_RCVD_BRK; if (termios->c_iflag & IGNPAR) uport->ignore_status_mask |= M_DUART_OVRUN_ERR; } if (termios->c_cflag & CREAD) command = M_DUART_RX_EN; else command = M_DUART_RX_DIS; if (termios->c_cflag & CRTSCTS) aux |= M_DUART_CTS_CHNG_ENA; else aux &= ~M_DUART_CTS_CHNG_ENA; spin_lock(&uport->lock); if (sport->tx_stopped) command |= M_DUART_TX_DIS; else command |= M_DUART_TX_EN; oldmode1 = read_sbdchn(sport, R_DUART_MODE_REG_1) & mode1mask; oldmode2 = read_sbdchn(sport, R_DUART_MODE_REG_2) & mode2mask; oldaux = read_sbdchn(sport, R_DUART_AUXCTL_X) & auxmask; if (!sport->tx_stopped) sbd_line_drain(sport); write_sbdchn(sport, R_DUART_CMD, M_DUART_TX_DIS | M_DUART_RX_DIS); write_sbdchn(sport, R_DUART_MODE_REG_1, mode1 | oldmode1); write_sbdchn(sport, R_DUART_MODE_REG_2, mode2 | oldmode2); write_sbdchn(sport, R_DUART_CLK_SEL, brg); write_sbdchn(sport, R_DUART_AUXCTL_X, aux | oldaux); write_sbdchn(sport, R_DUART_CMD, command); spin_unlock(&uport->lock); }
static void mcf_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { unsigned long flags; unsigned int baud, baudclk; #if defined(CONFIG_M5272) unsigned int baudfr; #endif unsigned char mr1, mr2; baud = uart_get_baud_rate(port, termios, old, 0, 230400); #if defined(CONFIG_M5272) baudclk = (MCF_BUSCLK / baud) / 32; baudfr = (((MCF_BUSCLK / baud) + 1) / 2) % 16; #else baudclk = ((MCF_BUSCLK / baud) + 16) / 32; #endif mr1 = MCFUART_MR1_RXIRQRDY | MCFUART_MR1_RXERRCHAR; mr2 = 0; switch (termios->c_cflag & CSIZE) { case CS5: mr1 |= MCFUART_MR1_CS5; break; case CS6: mr1 |= MCFUART_MR1_CS6; break; case CS7: mr1 |= MCFUART_MR1_CS7; break; case CS8: default: mr1 |= MCFUART_MR1_CS8; break; } if (termios->c_cflag & PARENB) { if (termios->c_cflag & CMSPAR) { if (termios->c_cflag & PARODD) mr1 |= MCFUART_MR1_PARITYMARK; else mr1 |= MCFUART_MR1_PARITYSPACE; } else { if (termios->c_cflag & PARODD) mr1 |= MCFUART_MR1_PARITYODD; else mr1 |= MCFUART_MR1_PARITYEVEN; } } else { mr1 |= MCFUART_MR1_PARITYNONE; } if (termios->c_cflag & CSTOPB) mr2 |= MCFUART_MR2_STOP2; else mr2 |= MCFUART_MR2_STOP1; if (termios->c_cflag & CRTSCTS) { mr1 |= MCFUART_MR1_RXRTS; mr2 |= MCFUART_MR2_TXCTS; } spin_lock_irqsave(&port->lock, flags); uart_update_timeout(port, termios->c_cflag, baud); writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR); writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR); writeb(MCFUART_UCR_CMDRESETMRPTR, port->membase + MCFUART_UCR); writeb(mr1, port->membase + MCFUART_UMR); writeb(mr2, port->membase + MCFUART_UMR); writeb((baudclk & 0xff00) >> 8, port->membase + MCFUART_UBG1); writeb((baudclk & 0xff), port->membase + MCFUART_UBG2); #if defined(CONFIG_M5272) writeb((baudfr & 0x0f), port->membase + MCFUART_UFPD); #endif writeb(MCFUART_UCSR_RXCLKTIMER | MCFUART_UCSR_TXCLKTIMER, port->membase + MCFUART_UCSR); writeb(MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE, port->membase + MCFUART_UCR); spin_unlock_irqrestore(&port->lock, flags); }
static void am_uart_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { unsigned int baud; struct meson_uart_port * mup = &am_ports[port->line]; am_uart_t *uart = mup->uart; unsigned tmp; tmp = readl(&uart->mode); switch (termios->c_cflag & CSIZE) { case CS8: printk(KERN_DEBUG "config %s: Character length 8bits/char\n", mup->name); tmp &= ~(0x3 << 20); break; case CS7: printk(KERN_DEBUG "config %s: Character length 7bits/char\n", mup->name); tmp &= ~(0x1 << 21); tmp |= (0x1 << 20); break; case CS6: printk(KERN_DEBUG "config %s: Character length 6bits/char\n", mup->name); tmp |= 0x1 << 21; tmp &= ~(0x1 << 20); break; case CS5: printk(KERN_DEBUG "config %s: Character length 5bits/char\n", mup->name); tmp |= 0x3 << 20; break; default: printk(KERN_DEBUG "default config %s: Character length 8bits/char\n", mup->name); tmp &= ~(0x3 << 20); break; } if(PARENB & termios->c_cflag) { tmp |= 0x1 << 19; if(PARODD & termios->c_cflag) { tmp |= 0x1<<18; } else { tmp &=~(0x1 << 18); } } else { tmp &=~(0x1 << 19); } if(termios->c_cflag & CSTOPB) { tmp |= 0x1 << 16 ; tmp &=~(0x1 << 17); } else { tmp &=~(0x3 << 16); } if(termios->c_cflag & CRTSCTS) { tmp &= ~(0x1 << 15); } else { tmp |= (0x1 << 15); } writel(tmp, &uart->mode); baud = tty_termios_baud_rate(termios); if(baud){ meson_uart_change_speed(mup, baud); uart_update_timeout(port, termios->c_cflag, baud); } return; }
static void sirfsoc_uart_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct sirfsoc_uart_port *sirfport = to_sirfport(port); unsigned long ioclk_rate; unsigned long config_reg = 0; unsigned long baud_rate; unsigned long setted_baud; unsigned long flags; unsigned long ic; unsigned int clk_div_reg = 0; unsigned long temp_reg_val; unsigned long rx_time_out; int threshold_div; int temp; ioclk_rate = 150000000; switch (termios->c_cflag & CSIZE) { default: case CS8: config_reg |= SIRFUART_DATA_BIT_LEN_8; break; case CS7: config_reg |= SIRFUART_DATA_BIT_LEN_7; break; case CS6: config_reg |= SIRFUART_DATA_BIT_LEN_6; break; case CS5: config_reg |= SIRFUART_DATA_BIT_LEN_5; break; } if (termios->c_cflag & CSTOPB) config_reg |= SIRFUART_STOP_BIT_LEN_2; baud_rate = uart_get_baud_rate(port, termios, old, 0, 4000000); spin_lock_irqsave(&port->lock, flags); port->read_status_mask = SIRFUART_RX_OFLOW_INT; port->ignore_status_mask = 0; /* read flags */ if (termios->c_iflag & INPCK) port->read_status_mask |= SIRFUART_FRM_ERR_INT | SIRFUART_PARITY_ERR_INT; if (termios->c_iflag & (BRKINT | PARMRK)) port->read_status_mask |= SIRFUART_RXD_BREAK_INT; /* ignore flags */ if (termios->c_iflag & IGNPAR) port->ignore_status_mask |= SIRFUART_FRM_ERR_INT | SIRFUART_PARITY_ERR_INT; if ((termios->c_cflag & CREAD) == 0) port->ignore_status_mask |= SIRFUART_DUMMY_READ; /* enable parity if PARENB is set*/ if (termios->c_cflag & PARENB) { if (termios->c_cflag & CMSPAR) { if (termios->c_cflag & PARODD) config_reg |= SIRFUART_STICK_BIT_MARK; else config_reg |= SIRFUART_STICK_BIT_SPACE; } else if (termios->c_cflag & PARODD) { config_reg |= SIRFUART_STICK_BIT_ODD; } else { config_reg |= SIRFUART_STICK_BIT_EVEN; } } /* Hardware Flow Control Settings */ if (UART_ENABLE_MS(port, termios->c_cflag)) { if (!sirfport->ms_enabled) sirfsoc_uart_enable_ms(port); } else { if (sirfport->ms_enabled) sirfsoc_uart_disable_ms(port); } /* common rate: fast calculation */ for (ic = 0; ic < SIRF_BAUD_RATE_SUPPORT_NR; ic++) if (baud_rate == baudrate_to_regv[ic].baud_rate) clk_div_reg = baudrate_to_regv[ic].reg_val; setted_baud = baud_rate; /* arbitary rate setting */ if (unlikely(clk_div_reg == 0)) clk_div_reg = sirfsoc_calc_sample_div(baud_rate, ioclk_rate, &setted_baud); wr_regl(port, SIRFUART_DIVISOR, clk_div_reg); if (tty_termios_baud_rate(termios)) tty_termios_encode_baud_rate(termios, setted_baud, setted_baud); /* set receive timeout */ rx_time_out = SIRFSOC_UART_RX_TIMEOUT(baud_rate, 20000); rx_time_out = (rx_time_out > 0xFFFF) ? 0xFFFF : rx_time_out; config_reg |= SIRFUART_RECV_TIMEOUT(rx_time_out); temp_reg_val = rd_regl(port, SIRFUART_TX_FIFO_OP); wr_regl(port, SIRFUART_RX_FIFO_OP, 0); wr_regl(port, SIRFUART_TX_FIFO_OP, temp_reg_val & ~SIRFUART_TX_FIFO_START); wr_regl(port, SIRFUART_TX_DMA_IO_CTRL, SIRFUART_TX_MODE_IO); wr_regl(port, SIRFUART_RX_DMA_IO_CTRL, SIRFUART_RX_MODE_IO); wr_regl(port, SIRFUART_LINE_CTRL, config_reg); /* Reset Rx/Tx FIFO Threshold level for proper baudrate */ if (baud_rate < 1000000) threshold_div = 1; else threshold_div = 2; temp = port->line == 1 ? 16 : 64; wr_regl(port, SIRFUART_TX_FIFO_CTRL, temp / threshold_div); wr_regl(port, SIRFUART_RX_FIFO_CTRL, temp / threshold_div); temp_reg_val |= SIRFUART_TX_FIFO_START; wr_regl(port, SIRFUART_TX_FIFO_OP, temp_reg_val); uart_update_timeout(port, termios->c_cflag, baud_rate); sirfsoc_uart_start_rx(port); wr_regl(port, SIRFUART_TX_RX_EN, SIRFUART_TX_EN | SIRFUART_RX_EN); spin_unlock_irqrestore(&port->lock, flags); }
static void serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct uart_omap_port *up = (struct uart_omap_port *)port; unsigned char cval; unsigned char efr = 0; unsigned long flags; unsigned int baud, quot; serial_out(up, UART_LCR, UART_LCR_DLAB); serial_out(up, UART_DLL, 0); serial_out(up, UART_DLM, 0); serial_out(up, UART_LCR, 0); serial_out(up, UART_OMAP_MDR1, OMAP_MDR1_DISABLE); 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/13); quot = serial_omap_get_divisor(port, baud); if (up->use_dma) fcr[up->pdev->id - 1] = UART_FCR_ENABLE_FIFO | 0x1 << 6 | 0x1 << 4 | UART_FCR_DMA_SELECT; else fcr[up->pdev->id - 1] = UART_FCR_ENABLE_FIFO | 0x1 << 6 | 0x1 << 4; /* * 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 */ 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) efr |= (UART_EFR_CTS | UART_EFR_RTS); 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 */ if (up->use_dma) serial_out(up, UART_OMAP_SCR , ((1 << 6) | (1 << 7))); serial_out(up, UART_LCR, 0xbf); /* Access EFR */ serial_out(up, UART_EFR, UART_EFR_ECB); serial_out(up, UART_LCR, 0x0); /* Access FCR */ serial_out(up, UART_FCR, fcr[up->pdev->id - 1]); serial_out(up, UART_LCR, 0xbf); /* Access EFR */ serial_out(up, UART_EFR, efr); serial_out(up, UART_LCR, cval); /* Access FCR */ serial_omap_set_mctrl(&up->port, up->port.mctrl); /* * Clear all the status registers and RX register before * enabling UART */ (void) serial_in(up, UART_LSR); (void) serial_in(up, UART_RX); (void) serial_in(up, UART_IIR); (void) serial_in(up, UART_MSR); if (baud > 230400 && baud != 3000000) serial_out(up, UART_OMAP_MDR1, OMAP_MDR1_MODE13X); else serial_out(up, UART_OMAP_MDR1, OMAP_MDR1_MODE16X); spin_unlock_irqrestore(&up->port.lock, flags); DPRINTK("serial_omap_set_termios+%d\n",up->pdev->id); serial_omap_display_reg(port); }
/* * OMAP can use "CLK / (16 or 13) / div" for baud rate. And then we have have * some differences in how we want to handle flow control. */ static void omap_8250_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct uart_8250_port *up = container_of(port, struct uart_8250_port, port); struct omap8250_priv *priv = up->port.private_data; unsigned char cval = 0; unsigned int baud; 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; if (termios->c_cflag & CMSPAR) cval |= UART_LCR_SPAR; /* * Ask the core to calculate the divisor for us. */ baud = uart_get_baud_rate(port, termios, old, port->uartclk / 16 / 0xffff, port->uartclk / 13); omap_8250_get_divisor(port, baud, priv); /* * Ok, we're now changing the port state. Do it with * interrupts disabled. */ pm_runtime_get_sync(port->dev); spin_lock_irq(&port->lock); /* * 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 & (IGNBRK | 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; /* * Modem status interrupts */ up->ier &= ~UART_IER_MSI; if (UART_ENABLE_MS(&up->port, termios->c_cflag)) up->ier |= UART_IER_MSI; up->lcr = cval; /* Up to here it was mostly serial8250_do_set_termios() */ /* * We enable TRIG_GRANU for RX and TX and additionaly we set * SCR_TX_EMPTY bit. The result is the following: * - RX_TRIGGER amount of bytes in the FIFO will cause an interrupt. * - less than RX_TRIGGER number of bytes will also cause an interrupt * once the UART decides that there no new bytes arriving. * - Once THRE is enabled, the interrupt will be fired once the FIFO is * empty - the trigger level is ignored here. * * Once DMA is enabled: * - UART will assert the TX DMA line once there is room for TX_TRIGGER * bytes in the TX FIFO. On each assert the DMA engine will move * TX_TRIGGER bytes into the FIFO. * - UART will assert the RX DMA line once there are RX_TRIGGER bytes in * the FIFO and move RX_TRIGGER bytes. * This is because threshold and trigger values are the same. */ up->fcr = UART_FCR_ENABLE_FIFO; up->fcr |= TRIGGER_FCR_MASK(TX_TRIGGER) << OMAP_UART_FCR_TX_TRIG; up->fcr |= TRIGGER_FCR_MASK(RX_TRIGGER) << OMAP_UART_FCR_RX_TRIG; priv->scr = OMAP_UART_SCR_RX_TRIG_GRANU1_MASK | OMAP_UART_SCR_TX_EMPTY | OMAP_UART_SCR_TX_TRIG_GRANU1_MASK; if (up->dma) priv->scr |= OMAP_UART_SCR_DMAMODE_1 | OMAP_UART_SCR_DMAMODE_CTL; priv->xon = termios->c_cc[VSTART]; priv->xoff = termios->c_cc[VSTOP]; priv->efr = 0; up->mcr &= ~(UART_MCR_RTS | UART_MCR_XONANY); if (termios->c_cflag & CRTSCTS && up->port.flags & UPF_HARD_FLOW) { /* Enable AUTORTS and AUTOCTS */ priv->efr |= UART_EFR_CTS | UART_EFR_RTS; /* Ensure MCR RTS is asserted */ up->mcr |= UART_MCR_RTS; } else if (up->port.flags & UPF_SOFT_FLOW) { /* * IXON Flag: * Enable XON/XOFF flow control on input. * Receiver compares XON1, XOFF1. */ if (termios->c_iflag & IXON) priv->efr |= OMAP_UART_SW_RX; /* * IXOFF Flag: * Enable XON/XOFF flow control on output. * Transmit XON1, XOFF1 */ if (termios->c_iflag & IXOFF) priv->efr |= OMAP_UART_SW_TX; /* * IXANY Flag: * Enable any character to restart output. * Operation resumes after receiving any * character after recognition of the XOFF character */ if (termios->c_iflag & IXANY) up->mcr |= UART_MCR_XONANY; } omap8250_restore_regs(up); spin_unlock_irq(&up->port.lock); pm_runtime_mark_last_busy(port->dev); pm_runtime_put_autosuspend(port->dev); /* calculate wakeup latency constraint */ priv->calc_latency = USEC_PER_SEC * 64 * 8 / baud; priv->latency = priv->calc_latency; schedule_work(&priv->qos_work); /* Don't rewrite B0 */ if (tty_termios_baud_rate(termios)) tty_termios_encode_baud_rate(termios, baud, baud); }
static void mcf_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct mcf_uart *pp = container_of(port, struct mcf_uart, port); unsigned long flags; unsigned int baud, baudclk; #if defined(CONFIG_M5272) unsigned int baudfr; #endif unsigned char mr1, mr2; baud = uart_get_baud_rate(port, termios, old, 0, 230400); #if defined(CONFIG_M5272) baudclk = (MCF_BUSCLK / baud) / 32; baudfr = (((MCF_BUSCLK / baud) + 1) / 2) % 16; #else baudclk = ((MCF_BUSCLK / baud) + 16) / 32; #endif mr1 = MCFUART_MR1_RXIRQRDY | MCFUART_MR1_RXERRCHAR; mr2 = 0; switch (termios->c_cflag & CSIZE) { case CS5: mr1 |= MCFUART_MR1_CS5; break; case CS6: mr1 |= MCFUART_MR1_CS6; break; case CS7: mr1 |= MCFUART_MR1_CS7; break; case CS8: default: mr1 |= MCFUART_MR1_CS8; break; } if (termios->c_cflag & PARENB) { if (termios->c_cflag & CMSPAR) { if (termios->c_cflag & PARODD) mr1 |= MCFUART_MR1_PARITYMARK; else mr1 |= MCFUART_MR1_PARITYSPACE; } else { if (termios->c_cflag & PARODD) mr1 |= MCFUART_MR1_PARITYODD; else mr1 |= MCFUART_MR1_PARITYEVEN; } } else { mr1 |= MCFUART_MR1_PARITYNONE; } /* * FIXME: port->read_status_mask and port->ignore_status_mask * need to be initialized based on termios settings for * INPCK, IGNBRK, IGNPAR, PARMRK, BRKINT */ if (termios->c_cflag & CSTOPB) mr2 |= MCFUART_MR2_STOP2; else mr2 |= MCFUART_MR2_STOP1; if (termios->c_cflag & CRTSCTS) { mr1 |= MCFUART_MR1_RXRTS; mr2 |= MCFUART_MR2_TXCTS; } if (pp->rs485.flags & SER_RS485_ENABLED) { dev_dbg(port->dev, "Setting UART to RS485\n"); mr2 |= MCFUART_MR2_TXRTS; } spin_lock_irqsave(&port->lock, flags); uart_update_timeout(port, termios->c_cflag, baud); writeb(MCFUART_UCR_CMDRESETRX, port->membase + MCFUART_UCR); writeb(MCFUART_UCR_CMDRESETTX, port->membase + MCFUART_UCR); writeb(MCFUART_UCR_CMDRESETMRPTR, port->membase + MCFUART_UCR); writeb(mr1, port->membase + MCFUART_UMR); writeb(mr2, port->membase + MCFUART_UMR); writeb((baudclk & 0xff00) >> 8, port->membase + MCFUART_UBG1); writeb((baudclk & 0xff), port->membase + MCFUART_UBG2); #if defined(CONFIG_M5272) writeb((baudfr & 0x0f), port->membase + MCFUART_UFPD); #endif writeb(MCFUART_UCSR_RXCLKTIMER | MCFUART_UCSR_TXCLKTIMER, port->membase + MCFUART_UCSR); writeb(MCFUART_UCR_RXENABLE | MCFUART_UCR_TXENABLE, port->membase + MCFUART_UCR); spin_unlock_irqrestore(&port->lock, flags); }
static void msm_hsl_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { unsigned long flags; unsigned int baud, mr; spin_lock_irqsave(&port->lock, flags); clk_en(port, 1); /* calculate and set baud rate */ baud = uart_get_baud_rate(port, termios, old, 300, 115200); /* Workaround required for UART download feature. set_termios is getting called while opening port and while setting required baud rate using Ioctl. Adding delay allows this feature to work. Reason is still unknown. */ udelay(1000); msm_hsl_set_baud_rate(port, baud); /* calculate parity */ mr = msm_hsl_read(port, UARTDM_MR2_ADDR); mr &= ~UARTDM_MR2_PARITY_MODE_BMSK; if (termios->c_cflag & PARENB) { if (termios->c_cflag & PARODD) mr |= ODD_PARITY; else if (termios->c_cflag & CMSPAR) mr |= SPACE_PARITY; else mr |= EVEN_PARITY; } /* calculate bits per char */ mr &= ~UARTDM_MR2_BITS_PER_CHAR_BMSK; switch (termios->c_cflag & CSIZE) { case CS5: mr |= FIVE_BPC; break; case CS6: mr |= SIX_BPC; break; case CS7: mr |= SEVEN_BPC; break; case CS8: default: mr |= EIGHT_BPC; break; } /* calculate stop bits */ mr &= ~(STOP_BIT_ONE | STOP_BIT_TWO); if (termios->c_cflag & CSTOPB) mr |= STOP_BIT_TWO; else mr |= STOP_BIT_ONE; /* set parity, bits per char, and stop bit */ msm_hsl_write(port, mr, UARTDM_MR2_ADDR); /* calculate and set hardware flow control */ mr = msm_hsl_read(port, UARTDM_MR1_ADDR); mr &= ~(UARTDM_MR1_CTS_CTL_BMSK | UARTDM_MR1_RX_RDY_CTL_BMSK); if (termios->c_cflag & CRTSCTS) { mr |= UARTDM_MR1_CTS_CTL_BMSK; mr |= UARTDM_MR1_RX_RDY_CTL_BMSK; } msm_hsl_write(port, mr, UARTDM_MR1_ADDR); /* Configure status bits to ignore based on termio flags. */ port->read_status_mask = 0; if (termios->c_iflag & INPCK) port->read_status_mask |= UARTDM_SR_PAR_FRAME_BMSK; if (termios->c_iflag & (BRKINT | PARMRK)) port->read_status_mask |= UARTDM_SR_RX_BREAK_BMSK; uart_update_timeout(port, termios->c_cflag, baud); clk_en(port, 0); spin_unlock_irqrestore(&port->lock, flags); }
static void pl011_set_termios(struct uart_port *port, struct termios *termios, struct termios *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 = port->uartclk * 4 / 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; if (UART_ENABLE_MS(port, termios->c_cflag)) pl011_enable_ms(port); /* first, disable everything */ old_cr = readw(port->membase + UART011_CR); writew(0, port->membase + UART011_CR); /* Set baud rate */ writew(quot & 0x3f, port->membase + UART011_FBRD); writew(quot >> 6, port->membase + UART011_IBRD); /* * ----------v----------v----------v----------v----- * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L * ----------^----------^----------^----------^----- */ writew(lcr_h, port->membase + UART011_LCRH); writew(old_cr, port->membase + UART011_CR); spin_unlock_irqrestore(&port->lock, flags); }
static void clps711xuart_set_termios(struct uart_port *port, struct termios *termios, struct termios *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); }
/** * xuartps_set_termios - termios operations, handling data length, parity, * stop bits, flow control, baud rate * @port: Handle to the uart port structure * @termios: Handle to the input termios structure * @old: Values of the previously saved termios structure * **/ static void xuartps_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { unsigned int cval = 0; unsigned int baud; unsigned long flags; unsigned int ctrl_reg, mode_reg; spin_lock_irqsave(&port->lock, flags); /* Empty the receive FIFO 1st before making changes */ while ((xuartps_readl(XUARTPS_SR_OFFSET) & XUARTPS_SR_RXEMPTY) != XUARTPS_SR_RXEMPTY) { xuartps_readl(XUARTPS_FIFO_OFFSET); } /* Disable the TX and RX to set baud rate */ xuartps_writel(xuartps_readl(XUARTPS_CR_OFFSET) | (XUARTPS_CR_TX_DIS | XUARTPS_CR_RX_DIS), XUARTPS_CR_OFFSET); /* Min baud rate = 6bps and Max Baud Rate is 10Mbps for 100Mhz clk */ baud = uart_get_baud_rate(port, termios, old, 0, 10000000); baud = xuartps_set_baud_rate(port, baud); if (tty_termios_baud_rate(termios)) tty_termios_encode_baud_rate(termios, baud, baud); /* * Update the per-port timeout. */ uart_update_timeout(port, termios->c_cflag, baud); /* Set TX/RX Reset */ xuartps_writel(xuartps_readl(XUARTPS_CR_OFFSET) | (XUARTPS_CR_TXRST | XUARTPS_CR_RXRST), XUARTPS_CR_OFFSET); ctrl_reg = xuartps_readl(XUARTPS_CR_OFFSET); /* Clear the RX disable and TX disable bits and then set the TX enable * bit and RX enable bit to enable the transmitter and receiver. */ xuartps_writel( (ctrl_reg & ~(XUARTPS_CR_TX_DIS | XUARTPS_CR_RX_DIS)) | (XUARTPS_CR_TX_EN | XUARTPS_CR_RX_EN), XUARTPS_CR_OFFSET); xuartps_writel(10, XUARTPS_RXTOUT_OFFSET); port->read_status_mask = XUARTPS_IXR_TXEMPTY | XUARTPS_IXR_RXTRIG | XUARTPS_IXR_OVERRUN | XUARTPS_IXR_TOUT; port->ignore_status_mask = 0; if (termios->c_iflag & INPCK) port->read_status_mask |= XUARTPS_IXR_PARITY | XUARTPS_IXR_FRAMING; if (termios->c_iflag & IGNPAR) port->ignore_status_mask |= XUARTPS_IXR_PARITY | XUARTPS_IXR_FRAMING | XUARTPS_IXR_OVERRUN; /* ignore all characters if CREAD is not set */ if ((termios->c_cflag & CREAD) == 0) port->ignore_status_mask |= XUARTPS_IXR_RXTRIG | XUARTPS_IXR_TOUT | XUARTPS_IXR_PARITY | XUARTPS_IXR_FRAMING | XUARTPS_IXR_OVERRUN; mode_reg = xuartps_readl(XUARTPS_MR_OFFSET); /* Handling Data Size */ switch (termios->c_cflag & CSIZE) { case CS6: cval |= XUARTPS_MR_CHARLEN_6_BIT; break; case CS7: cval |= XUARTPS_MR_CHARLEN_7_BIT; break; default: case CS8: cval |= XUARTPS_MR_CHARLEN_8_BIT; termios->c_cflag &= ~CSIZE; termios->c_cflag |= CS8; break; } /* Handling Parity and Stop Bits length */ if (termios->c_cflag & CSTOPB) cval |= XUARTPS_MR_STOPMODE_2_BIT; /* 2 STOP bits */ else cval |= XUARTPS_MR_STOPMODE_1_BIT; /* 1 STOP bit */ if (termios->c_cflag & PARENB) { /* Mark or Space parity */ if (termios->c_cflag & CMSPAR) { if (termios->c_cflag & PARODD) cval |= XUARTPS_MR_PARITY_MARK; else cval |= XUARTPS_MR_PARITY_SPACE; } else if (termios->c_cflag & PARODD) cval |= XUARTPS_MR_PARITY_ODD; else cval |= XUARTPS_MR_PARITY_EVEN; } else cval |= XUARTPS_MR_PARITY_NONE; xuartps_writel(cval , XUARTPS_MR_OFFSET); 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); }
static void serial_pxa_set_termios(struct uart_port *port, struct termios *termios, struct termios *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 fcr = UART_FCR_ENABLE_FIFO | UART_FCR_PXAR8; /* * Ok, we're now changing the port state. Do it with * interrupts disabled. */ spin_lock_irqsave(&up->port.lock, flags); up->isConsole=1; up->consoleBaud=baud; /* used in dpm/fscale*/ /* * 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); }
static void cpm_uart_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { int baud; unsigned long flags; u16 cval, scval, prev_mode; int bits, sbits; struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port; smc_t __iomem *smcp = pinfo->smcp; scc_t __iomem *sccp = pinfo->sccp; pr_debug("CPM uart[%d]:set_termios\n", port->line); baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16); /* Character length programmed into the mode register is the * sum of: 1 start bit, number of data bits, 0 or 1 parity bit, * 1 or 2 stop bits, minus 1. * The value 'bits' counts this for us. */ cval = 0; scval = 0; /* byte size */ switch (termios->c_cflag & CSIZE) { case CS5: bits = 5; break; case CS6: bits = 6; break; case CS7: bits = 7; break; case CS8: bits = 8; break; /* Never happens, but GCC is too dumb to figure it out */ default: bits = 8; break; } sbits = bits - 5; if (termios->c_cflag & CSTOPB) { cval |= SMCMR_SL; /* Two stops */ scval |= SCU_PSMR_SL; bits++; } if (termios->c_cflag & PARENB) { cval |= SMCMR_PEN; scval |= SCU_PSMR_PEN; bits++; if (!(termios->c_cflag & PARODD)) { cval |= SMCMR_PM_EVEN; scval |= (SCU_PSMR_REVP | SCU_PSMR_TEVP); } } /* * Update the timeout */ uart_update_timeout(port, termios->c_cflag, baud); /* * Set up parity check flag */ #define RELEVANT_IFLAG(iflag) (iflag & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK)) port->read_status_mask = (BD_SC_EMPTY | BD_SC_OV); if (termios->c_iflag & INPCK) port->read_status_mask |= BD_SC_FR | BD_SC_PR; if ((termios->c_iflag & BRKINT) || (termios->c_iflag & PARMRK)) port->read_status_mask |= BD_SC_BR; /* * Characters to ignore */ port->ignore_status_mask = 0; if (termios->c_iflag & IGNPAR) port->ignore_status_mask |= BD_SC_PR | BD_SC_FR; if (termios->c_iflag & IGNBRK) { port->ignore_status_mask |= BD_SC_BR; /* * If we're ignore parity and break indicators, ignore * overruns too. (For real raw support). */ if (termios->c_iflag & IGNPAR) port->ignore_status_mask |= BD_SC_OV; } /* * !!! ignore all characters if CREAD is not set */ if ((termios->c_cflag & CREAD) == 0) port->read_status_mask &= ~BD_SC_EMPTY; spin_lock_irqsave(&port->lock, flags); /* Start bit has not been added (so don't, because we would just * subtract it later), and we need to add one for the number of * stops bits (there is always at least one). */ bits++; if (IS_SMC(pinfo)) { /* Set the mode register. We want to keep a copy of the * enables, because we want to put them back if they were * present. */ prev_mode = in_be16(&smcp->smc_smcmr) & (SMCMR_REN | SMCMR_TEN); /* Output in *one* operation, so we don't interrupt RX/TX if they * were already enabled. */ out_be16(&smcp->smc_smcmr, smcr_mk_clen(bits) | cval | SMCMR_SM_UART | prev_mode); } else { out_be16(&sccp->scc_psmr, (sbits << 12) | scval); } if (pinfo->clk) clk_set_rate(pinfo->clk, baud); else cpm_set_brg(pinfo->brg - 1, baud); spin_unlock_irqrestore(&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 s3c24xx_serial_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port); struct s3c24xx_uart_port *ourport = to_ourport(port); struct s3c24xx_uart_clksrc *clksrc = NULL; struct clk *clk = NULL; unsigned long flags; unsigned int baud, quot; unsigned int ulcon; unsigned int umcon; /* * We don't support modem control lines. */ termios->c_cflag &= ~(HUPCL | CMSPAR); termios->c_cflag |= CLOCAL; /* * Ask the core to calculate the divisor for us. */ baud = uart_get_baud_rate(port, termios, old, 0, 115200*8); if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST) quot = port->custom_divisor; else quot = s3c24xx_serial_getclk(port, &clksrc, &clk, baud); /* check to see if we need to change clock source */ if (ourport->clksrc != clksrc || ourport->baudclk != clk) { s3c24xx_serial_setsource(port, clksrc); if (ourport->baudclk != NULL && !IS_ERR(ourport->baudclk)) { clk_disable(ourport->baudclk); ourport->baudclk = NULL; } clk_enable(clk); ourport->clksrc = clksrc; ourport->baudclk = clk; } switch (termios->c_cflag & CSIZE) { case CS5: dbg("config: 5bits/char\n"); ulcon = S3C2410_LCON_CS5; break; case CS6: dbg("config: 6bits/char\n"); ulcon = S3C2410_LCON_CS6; break; case CS7: dbg("config: 7bits/char\n"); ulcon = S3C2410_LCON_CS7; break; case CS8: default: dbg("config: 8bits/char\n"); ulcon = S3C2410_LCON_CS8; break; } /* preserve original lcon IR settings */ ulcon |= (cfg->ulcon & S3C2410_LCON_IRM); if (termios->c_cflag & CSTOPB) ulcon |= S3C2410_LCON_STOPB; umcon = (termios->c_cflag & CRTSCTS) ? S3C2410_UMCOM_AFC : 0; if (termios->c_cflag & PARENB) { if (termios->c_cflag & PARODD) ulcon |= S3C2410_LCON_PODD; else ulcon |= S3C2410_LCON_PEVEN; } else { ulcon |= S3C2410_LCON_PNONE; } spin_lock_irqsave(&port->lock, flags); dbg("setting ulcon to %08x, brddiv to %d\n", ulcon, quot); wr_regl(port, S3C2410_ULCON, ulcon); wr_regl(port, S3C2410_UBRDIV, quot); wr_regl(port, S3C2410_UMCON, umcon); dbg("uart: ulcon = 0x%08x, ucon = 0x%08x, ufcon = 0x%08x\n", rd_regl(port, S3C2410_ULCON), rd_regl(port, S3C2410_UCON), rd_regl(port, S3C2410_UFCON)); /* * Update the per-port timeout. */ uart_update_timeout(port, termios->c_cflag, baud); /* * Which character status flags are we interested in? */ port->read_status_mask = S3C2410_UERSTAT_OVERRUN; if (termios->c_iflag & INPCK) port->read_status_mask |= S3C2410_UERSTAT_FRAME | S3C2410_UERSTAT_PARITY; /* * Which character status flags should we ignore? */ port->ignore_status_mask = 0; if (termios->c_iflag & IGNPAR) port->ignore_status_mask |= S3C2410_UERSTAT_OVERRUN; if (termios->c_iflag & IGNBRK && termios->c_iflag & IGNPAR) port->ignore_status_mask |= S3C2410_UERSTAT_FRAME; /* * Ignore all characters if CREAD is not set. */ if ((termios->c_cflag & CREAD) == 0) port->ignore_status_mask |= RXSTAT_DUMMY_READ; spin_unlock_irqrestore(&port->lock, flags); }
static void msm_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { unsigned long flags; unsigned int baud, mr; if (!termios->c_cflag) return; spin_lock_irqsave(&port->lock, flags); /* calculate and set baud rate */ baud = uart_get_baud_rate(port, termios, old, 300, 115200); msm_set_baud_rate(port, baud); /* calculate parity */ mr = msm_read(port, UART_MR2); mr &= ~UART_MR2_PARITY_MODE; if (termios->c_cflag & PARENB) { if (termios->c_cflag & PARODD) mr |= UART_MR2_PARITY_MODE_ODD; else if (termios->c_cflag & CMSPAR) mr |= UART_MR2_PARITY_MODE_SPACE; else mr |= UART_MR2_PARITY_MODE_EVEN; } /* calculate bits per char */ mr &= ~UART_MR2_BITS_PER_CHAR; switch (termios->c_cflag & CSIZE) { case CS5: mr |= UART_MR2_BITS_PER_CHAR_5; break; case CS6: mr |= UART_MR2_BITS_PER_CHAR_6; break; case CS7: mr |= UART_MR2_BITS_PER_CHAR_7; break; case CS8: default: mr |= UART_MR2_BITS_PER_CHAR_8; break; } /* calculate stop bits */ mr &= ~(UART_MR2_STOP_BIT_LEN_ONE | UART_MR2_STOP_BIT_LEN_TWO); if (termios->c_cflag & CSTOPB) mr |= UART_MR2_STOP_BIT_LEN_TWO; else mr |= UART_MR2_STOP_BIT_LEN_ONE; /* set parity, bits per char, and stop bit */ msm_write(port, mr, UART_MR2); /* calculate and set hardware flow control */ mr = msm_read(port, UART_MR1); mr &= ~(UART_MR1_CTS_CTL | UART_MR1_RX_RDY_CTL); if (termios->c_cflag & CRTSCTS) { mr |= UART_MR1_CTS_CTL; mr |= UART_MR1_RX_RDY_CTL; } msm_write(port, mr, UART_MR1); /* Configure status bits to ignore based on termio flags. */ port->read_status_mask = 0; if (termios->c_iflag & INPCK) port->read_status_mask |= UART_SR_PAR_FRAME_ERR; if (termios->c_iflag & (BRKINT | PARMRK)) port->read_status_mask |= UART_SR_RX_BREAK; uart_update_timeout(port, termios->c_cflag, baud); 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; /* * 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 serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct uart_omap_port *up = (struct uart_omap_port *)port; unsigned char cval = 0; unsigned char efr = 0; unsigned long flags = 0; 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/13); quot = serial_omap_get_divisor(port, baud); up->dll = quot & 0xff; up->dlh = quot >> 8; up->mdr1 = UART_OMAP_MDR1_DISABLE; up->fcr = UART_FCR_R_TRIG_01 | UART_FCR_T_TRIG_01 | UART_FCR_ENABLE_FIFO; if (up->use_dma) up->fcr |= UART_FCR_DMA_SELECT; /* * Ok, we're now changing the port state. Do it with * interrupts disabled. */ serial_omap_port_enable(up); 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; /* * 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); /* reset DLAB */ up->lcr = cval; /* FIFOs and DMA Settings */ /* FCR can be changed only when the * baud clock is not running * DLL_REG and DLH_REG set to 0. */ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); serial_out(up, UART_DLL, 0); serial_out(up, UART_DLM, 0); serial_out(up, UART_LCR, 0); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); up->efr = serial_in(up, UART_EFR); serial_out(up, UART_EFR, up->efr | UART_EFR_ECB); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); up->mcr = serial_in(up, UART_MCR); serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR); /* FIFO ENABLE, DMA MODE */ serial_out(up, UART_FCR, up->fcr); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); if (up->use_dma) { if (up->errata & OMAP4_UART_ERRATA_i659_TX_THR) { serial_out(up, UART_MDR3, SET_DMA_TX_THRESHOLD); serial_out(up, UART_TX_DMA_THRESHOLD, TX_FIFO_THR_LVL); } serial_out(up, UART_TI752_TLR, 0); serial_out(up, UART_OMAP_SCR, (UART_FCR_TRIGGER_4 | UART_FCR_TRIGGER_8)); } serial_out(up, UART_EFR, up->efr); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); serial_out(up, UART_MCR, up->mcr); /* Protocol, Baud Rate, and Interrupt Settings */ if (up->errata & UART_ERRATA_i202_MDR1_ACCESS) omap_uart_mdr1_errataset(up, up->mdr1); else serial_out(up, UART_OMAP_MDR1, up->mdr1); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); up->efr = serial_in(up, UART_EFR); serial_out(up, UART_EFR, up->efr | UART_EFR_ECB); serial_out(up, UART_LCR, 0); serial_out(up, UART_IER, 0); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); serial_out(up, UART_DLL, up->dll); /* LS of divisor */ serial_out(up, UART_DLM, up->dlh); /* MS of divisor */ serial_out(up, UART_LCR, 0); serial_out(up, UART_IER, up->ier); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); serial_out(up, UART_EFR, up->efr); serial_out(up, UART_LCR, cval); if (baud > 230400 && baud != 3000000) up->mdr1 = UART_OMAP_MDR1_13X_MODE; else up->mdr1 = UART_OMAP_MDR1_16X_MODE; if (up->errata & UART_ERRATA_i202_MDR1_ACCESS) omap_uart_mdr1_errataset(up, up->mdr1); else serial_out(up, UART_OMAP_MDR1, up->mdr1); /* Hardware Flow Control Configuration */ if (termios->c_cflag & CRTSCTS) { serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); up->mcr = serial_in(up, UART_MCR); serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR); serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); up->efr = serial_in(up, UART_EFR); serial_out(up, UART_EFR, up->efr | UART_EFR_ECB); serial_out(up, UART_TI752_TCR, OMAP_UART_TCR_TRIG); up->efr |= (UART_EFR_CTS | UART_EFR_RTS); serial_out(up, UART_EFR, up->efr); /* Enable AUTORTS and AUTOCTS */ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A); up->mcr |= UART_MCR_RTS; serial_out(up, UART_MCR, up->mcr); serial_out(up, UART_LCR, cval); } else { serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); up->efr = serial_in(up, UART_EFR); up->efr &= ~(UART_EFR_CTS | UART_EFR_RTS); serial_out(up, UART_EFR, up->efr); /* Disable AUTORTS and AUTOCTS */ serial_out(up, UART_LCR, cval); } serial_omap_set_mctrl(&up->port, up->port.mctrl); /* Software Flow Control Configuration */ serial_omap_configure_xonxoff(up, termios); /* Now we are ready for RX data: enable rts line */ if (up->rts_mux_driver_control && up->rts_pullup_in_suspend) { omap_rts_mux_write(0, up->port.line); up->rts_pullup_in_suspend = 0; } spin_unlock_irqrestore(&up->port.lock, flags); serial_omap_port_disable(up); dev_dbg(up->port.dev, "serial_omap_set_termios+%d\n", up->pdev->id); }
static void serial_omap_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct uart_omap_port *up = (struct uart_omap_port *)port; unsigned char cval = 0; unsigned char efr = 0; unsigned long flags = 0; 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/13); /* Added for the suporrt of DPLL, frequency changes * This value can be used to recalculate the DLLand * DLH values. If this function is not called for * particulate UART it would remain as 0. */ up->baud_rate = baud; quot = serial_omap_get_divisor(port, baud); up->fcr = UART_FCR_R_TRIG_01 | UART_FCR_T_TRIG_01 | UART_FCR_ENABLE_FIFO; if (up->use_dma) up->fcr |= UART_FCR_DMA_SELECT; /* * 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; /* * 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); /* reset DLAB */ /* FIFOs and DMA Settings */ /* FCR can be changed only when the * baud clock is not running * DLL_REG and DLH_REG set to 0. */ serial_out(up, UART_LCR, UART_LCR_DLAB); serial_out(up, UART_DLL, 0); serial_out(up, UART_DLM, 0); serial_out(up, UART_LCR, 0); serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB); up->efr = serial_in(up, UART_EFR); serial_out(up, UART_EFR, up->efr | UART_EFR_ECB); serial_out(up, UART_LCR, 0); up->mcr = serial_in(up, UART_MCR); serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR); /* FIFO ENABLE, DMA MODE */ serial_out(up, UART_FCR, up->fcr); serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB); if (up->use_dma) { if (up->uart_dma.tx_threshold) { serial_out(up, UART_MDR3, SET_DMA_TX_THRESHOLD); serial_out(up, UART_TX_DMA_THRESHOLD, TX_FIFO_THR_LVL); } serial_out(up, UART_TI752_TLR, 0); serial_out(up, UART_OMAP_SCR, (UART_FCR_TRIGGER_4 | UART_FCR_TRIGGER_8)); } serial_out(up, UART_EFR, up->efr); serial_out(up, UART_LCR, UART_LCR_DLAB); serial_out(up, UART_MCR, up->mcr); /* Protocol, Baud Rate, and Interrupt Settings */ serial_out(up, UART_OMAP_MDR1, OMAP_MDR1_DISABLE); serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB); up->efr = serial_in(up, UART_EFR); serial_out(up, UART_EFR, up->efr | UART_EFR_ECB); serial_out(up, UART_LCR, 0); serial_out(up, UART_IER, 0); serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB); 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, 0); serial_out(up, UART_IER, up->ier); serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB); serial_out(up, UART_EFR, up->efr); serial_out(up, UART_LCR, cval); if (baud > 230400 && baud != 3000000) serial_out(up, UART_OMAP_MDR1, OMAP_MDR1_MODE13X); else serial_out(up, UART_OMAP_MDR1, OMAP_MDR1_MODE16X); /* Hardware Flow Control Configuration */ if (termios->c_cflag & CRTSCTS) { efr |= (UART_EFR_CTS | UART_EFR_RTS); serial_out(up, UART_LCR, UART_LCR_DLAB); up->mcr = serial_in(up, UART_MCR); serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR); serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB); up->efr = serial_in(up, UART_EFR); serial_out(up, UART_EFR, up->efr | UART_EFR_ECB); serial_out(up, UART_TI752_TCR, OMAP_UART_TCR_TRIG); serial_out(up, UART_EFR, efr); /* Enable AUTORTS and AUTOCTS */ serial_out(up, UART_LCR, UART_LCR_DLAB); serial_out(up, UART_MCR, up->mcr | UART_MCR_RTS); serial_out(up, UART_LCR, cval); } serial_omap_set_mctrl(&up->port, up->port.mctrl); /* Software Flow Control Configuration */ if (termios->c_iflag & (IXON | IXOFF)) serial_omap_configure_xonxoff(up, termios); spin_unlock_irqrestore(&up->port.lock, flags); dev_dbg(up->port.dev, "serial_omap_set_termios+%d\n", up->pdev->id); }