static int pnx8xxx_startup(struct uart_port *port) { struct pnx8xxx_port *sport = (struct pnx8xxx_port *)port; int retval; /* * Allocate the IRQ */ retval = request_irq(sport->port.irq, pnx8xxx_int, 0, "pnx8xxx-uart", sport); if (retval) return retval; /* * Finally, clear and enable interrupts */ serial_out(sport, PNX8XXX_ICLR, PNX8XXX_UART_INT_ALLRX | PNX8XXX_UART_INT_ALLTX); serial_out(sport, PNX8XXX_IEN, serial_in(sport, PNX8XXX_IEN) | PNX8XXX_UART_INT_ALLRX | PNX8XXX_UART_INT_ALLTX); /* * Enable modem status interrupts */ spin_lock_irq(&sport->port.lock); pnx8xxx_enable_ms(&sport->port); spin_unlock_irq(&sport->port.lock); return 0; }
static int pnx8xxx_startup(struct uart_port *port) { struct pnx8xxx_port *sport = (struct pnx8xxx_port *)port; int retval; retval = request_irq(sport->port.irq, pnx8xxx_int, 0, "pnx8xxx-uart", sport); if (retval) return retval; serial_out(sport, PNX8XXX_ICLR, PNX8XXX_UART_INT_ALLRX | PNX8XXX_UART_INT_ALLTX); serial_out(sport, PNX8XXX_IEN, serial_in(sport, PNX8XXX_IEN) | PNX8XXX_UART_INT_ALLRX | PNX8XXX_UART_INT_ALLTX); spin_lock_irq(&sport->port.lock); pnx8xxx_enable_ms(&sport->port); spin_unlock_irq(&sport->port.lock); return 0; }
static void pnx8xxx_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct pnx8xxx_port *sport = (struct pnx8xxx_port *)port; unsigned long flags; unsigned int lcr_fcr, old_ien, baud, quot; unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8; while ((termios->c_cflag & CSIZE) != CS7 && (termios->c_cflag & CSIZE) != CS8) { termios->c_cflag &= ~CSIZE; termios->c_cflag |= old_csize; old_csize = CS8; } if ((termios->c_cflag & CSIZE) == CS8) lcr_fcr = PNX8XXX_UART_LCR_8BIT; else lcr_fcr = 0; if (termios->c_cflag & CSTOPB) lcr_fcr |= PNX8XXX_UART_LCR_2STOPB; if (termios->c_cflag & PARENB) { lcr_fcr |= PNX8XXX_UART_LCR_PAREN; if (!(termios->c_cflag & PARODD)) lcr_fcr |= PNX8XXX_UART_LCR_PAREVN; } baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); quot = uart_get_divisor(port, baud); spin_lock_irqsave(&sport->port.lock, flags); sport->port.read_status_mask = ISTAT_TO_SM(PNX8XXX_UART_INT_RXOVRN) | ISTAT_TO_SM(PNX8XXX_UART_INT_EMPTY) | ISTAT_TO_SM(PNX8XXX_UART_INT_RX); if (termios->c_iflag & INPCK) sport->port.read_status_mask |= FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFE) | FIFO_TO_SM(PNX8XXX_UART_FIFO_RXPAR); if (termios->c_iflag & (BRKINT | PARMRK)) sport->port.read_status_mask |= ISTAT_TO_SM(PNX8XXX_UART_INT_BREAK); sport->port.ignore_status_mask = 0; if (termios->c_iflag & IGNPAR) sport->port.ignore_status_mask |= FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFE) | FIFO_TO_SM(PNX8XXX_UART_FIFO_RXPAR); if (termios->c_iflag & IGNBRK) { sport->port.ignore_status_mask |= ISTAT_TO_SM(PNX8XXX_UART_INT_BREAK); if (termios->c_iflag & IGNPAR) sport->port.ignore_status_mask |= ISTAT_TO_SM(PNX8XXX_UART_INT_RXOVRN); } if ((termios->c_cflag & CREAD) == 0) sport->port.ignore_status_mask |= ISTAT_TO_SM(PNX8XXX_UART_INT_RX); del_timer_sync(&sport->timer); uart_update_timeout(port, termios->c_cflag, baud); old_ien = serial_in(sport, PNX8XXX_IEN); serial_out(sport, PNX8XXX_IEN, old_ien & ~(PNX8XXX_UART_INT_ALLTX | PNX8XXX_UART_INT_ALLRX)); while (serial_in(sport, PNX8XXX_FIFO) & PNX8XXX_UART_FIFO_TXFIFO_STA) barrier(); serial_out(sport, PNX8XXX_IEN, 0); lcr_fcr |= PNX8XXX_UART_LCR_TX_RST; lcr_fcr |= PNX8XXX_UART_LCR_RX_RST; serial_out(sport, PNX8XXX_LCR, lcr_fcr); quot -= 1; serial_out(sport, PNX8XXX_BAUD, quot); serial_out(sport, PNX8XXX_ICLR, -1); serial_out(sport, PNX8XXX_IEN, old_ien); if (UART_ENABLE_MS(&sport->port, termios->c_cflag)) pnx8xxx_enable_ms(&sport->port); spin_unlock_irqrestore(&sport->port.lock, flags); }
static 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); }