static void sc26xx_disable_irq(struct uart_port *port, int mask) { struct uart_sc26xx_port *up; int line = port->line; port -= line; up = container_of(port, struct uart_sc26xx_port, port[0]); up->imr &= ~(mask << (line * 4)); WRITE_SC(port, IMR, up->imr); }
/* port->lock held by caller. */ static void sc26xx_set_mctrl(struct uart_port *port, unsigned int mctrl) { struct uart_sc26xx_port *up; int line = port->line; port -= line; up = container_of(port, struct uart_sc26xx_port, port[0]); if (up->dtr_mask[line]) { if (mctrl & TIOCM_DTR) WRITE_SC(port, OPR_SET, up->dtr_mask[line]); else WRITE_SC(port, OPR_CLR, up->dtr_mask[line]); } if (up->rts_mask[line]) { if (mctrl & TIOCM_RTS) WRITE_SC(port, OPR_SET, up->rts_mask[line]); else WRITE_SC(port, OPR_CLR, up->rts_mask[line]); } }
/* port->lock is not held. */ static int sc26xx_startup(struct uart_port *port) { sc26xx_disable_irq(port, IMR_TXRDY | IMR_RXRDY); WRITE_SC(port, OPCR, 0); /* reset tx and rx */ WRITE_SC_PORT(port, CR, CR_RES_RX); WRITE_SC_PORT(port, CR, CR_RES_TX); /* start rx/tx */ WRITE_SC_PORT(port, CR, CR_ENA_TX | CR_ENA_RX); /* enable irqs */ sc26xx_enable_irq(port, IMR_RXRDY); return 0; }
static int sc26xx_startup(struct uart_port *port) { sc26xx_disable_irq(port, IMR_TXRDY | IMR_RXRDY); WRITE_SC(port, OPCR, 0); 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); sc26xx_enable_irq(port, IMR_RXRDY); return 0; }
/* 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); }