/* * port locked and interrupts disabled */ static void sa1100_start_tx(struct uart_port *port) { struct sa1100_port *sport = (struct sa1100_port *)port; u32 utcr3; utcr3 = UART_GET_UTCR3(sport); sport->port.read_status_mask |= UTSR0_TO_SM(UTSR0_TFS); UART_PUT_UTCR3(sport, utcr3 | UTCR3_TIE); }
/* * Interrupts always disabled. */ static void sa1100_break_ctl(struct uart_port *port, int break_state) { u_int utcr3; utcr3 = UART_GET_UTCR3(port); if (break_state == -1) utcr3 |= UTCR3_BRK; else utcr3 &= ~UTCR3_BRK; UART_PUT_UTCR3(port, utcr3); }
/* * interrupts may not be disabled on entry */ static void sa1100_start_tx(struct uart_port *port, unsigned int tty_start) { struct sa1100_port *sport = (struct sa1100_port *)port; unsigned long flags; u32 utcr3; spin_lock_irqsave(&sport->port.lock, flags); utcr3 = UART_GET_UTCR3(sport); sport->port.read_status_mask |= UTSR0_TO_SM(UTSR0_TFS); UART_PUT_UTCR3(sport, utcr3 | UTCR3_TIE); spin_unlock_irqrestore(&sport->port.lock, flags); }
/* * interrupts may not be disabled on entry */ static void sa1100_start_tx(struct uart_port *port, u_int nonempty, u_int from_tty) { if (nonempty) { unsigned long flags; u32 utcr3; local_irq_save(flags); utcr3 = UART_GET_UTCR3(port); port->read_status_mask |= UTSR0_TO_SM(UTSR0_TFS); UART_PUT_UTCR3(port, utcr3 | UTCR3_TIE); local_irq_restore(flags); } }
/* * Interrupts always disabled. */ static void sa1100_break_ctl(struct uart_port *port, int break_state) { struct sa1100_port *sport = (struct sa1100_port *)port; unsigned long flags; unsigned int utcr3; spin_lock_irqsave(&sport->port.lock, flags); utcr3 = UART_GET_UTCR3(sport); if (break_state == -1) utcr3 |= UTCR3_BRK; else utcr3 &= ~UTCR3_BRK; UART_PUT_UTCR3(sport, utcr3); spin_unlock_irqrestore(&sport->port.lock, flags); }
static void sa1100_console_write(struct console *co, const char *s, unsigned int count) { struct sa1100_port *sport = &sa1100_ports[co->index]; unsigned int old_utcr3, status; old_utcr3 = UART_GET_UTCR3(sport); UART_PUT_UTCR3(sport, (old_utcr3 & ~(UTCR3_RIE | UTCR3_TIE)) | UTCR3_TXE); uart_console_write(&sport->port, s, count, sa1100_console_putchar); do { status = UART_GET_UTSR1(sport); } while (status & UTSR1_TBY); UART_PUT_UTCR3(sport, old_utcr3); }
/* * Interrupts are disabled on entering */ static void sa1100_console_write(struct console *co, const char *s, unsigned int count) { struct sa1100_port *sport = &sa1100_ports[co->index]; unsigned int old_utcr3, status, i; /* * First, save UTCR3 and then disable interrupts */ old_utcr3 = UART_GET_UTCR3(sport); UART_PUT_UTCR3(sport, (old_utcr3 & ~(UTCR3_RIE | UTCR3_TIE)) | UTCR3_TXE); /* * Now, do each character */ for (i = 0; i < count; i++) { do { status = UART_GET_UTSR1(sport); } while (!(status & UTSR1_TNF)); UART_PUT_CHAR(sport, s[i]); if (s[i] == '\n') { do { status = UART_GET_UTSR1(sport); } while (!(status & UTSR1_TNF)); UART_PUT_CHAR(sport, '\r'); } } /* * Finally, wait for transmitter to become empty * and restore UTCR3 */ do { status = UART_GET_UTSR1(sport); } while (status & UTSR1_TBY); UART_PUT_UTCR3(sport, old_utcr3); }
/* * Interrupts are disabled on entering */ static void sa1100_console_write(struct console *co, const char *s, unsigned int count) { struct sa1100_port *sport = &sa1100_ports[co->index]; unsigned int old_utcr3, status; /* * First, save UTCR3 and then disable interrupts */ old_utcr3 = UART_GET_UTCR3(sport); UART_PUT_UTCR3(sport, (old_utcr3 & ~(UTCR3_RIE | UTCR3_TIE)) | UTCR3_TXE); uart_console_write(&sport->port, s, count, sa1100_console_putchar); /* * Finally, wait for transmitter to become empty * and restore UTCR3 */ do { status = UART_GET_UTSR1(sport); } while (status & UTSR1_TBY); UART_PUT_UTCR3(sport, old_utcr3); }
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 sa1100_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct sa1100_port *sport = (struct sa1100_port *)port; unsigned long flags; unsigned int utcr0, old_utcr3, baud, quot; unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8; while ((termios->c_cflag & CSIZE) != CS7 && (termios->c_cflag & CSIZE) != CS8) { termios->c_cflag &= ~CSIZE; termios->c_cflag |= old_csize; old_csize = CS8; } if ((termios->c_cflag & CSIZE) == CS8) utcr0 = UTCR0_DSS; else utcr0 = 0; if (termios->c_cflag & CSTOPB) utcr0 |= UTCR0_SBS; if (termios->c_cflag & PARENB) { utcr0 |= UTCR0_PE; if (!(termios->c_cflag & PARODD)) utcr0 |= UTCR0_OES; } baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); quot = uart_get_divisor(port, baud); spin_lock_irqsave(&sport->port.lock, flags); sport->port.read_status_mask &= UTSR0_TO_SM(UTSR0_TFS); sport->port.read_status_mask |= UTSR1_TO_SM(UTSR1_ROR); if (termios->c_iflag & INPCK) sport->port.read_status_mask |= UTSR1_TO_SM(UTSR1_FRE | UTSR1_PRE); if (termios->c_iflag & (BRKINT | PARMRK)) sport->port.read_status_mask |= UTSR0_TO_SM(UTSR0_RBB | UTSR0_REB); sport->port.ignore_status_mask = 0; if (termios->c_iflag & IGNPAR) sport->port.ignore_status_mask |= UTSR1_TO_SM(UTSR1_FRE | UTSR1_PRE); if (termios->c_iflag & IGNBRK) { sport->port.ignore_status_mask |= UTSR0_TO_SM(UTSR0_RBB | UTSR0_REB); if (termios->c_iflag & IGNPAR) sport->port.ignore_status_mask |= UTSR1_TO_SM(UTSR1_ROR); } del_timer_sync(&sport->timer); uart_update_timeout(port, termios->c_cflag, baud); old_utcr3 = UART_GET_UTCR3(sport); UART_PUT_UTCR3(sport, old_utcr3 & ~(UTCR3_RIE | UTCR3_TIE)); while (UART_GET_UTSR1(sport) & UTSR1_TBY) barrier(); UART_PUT_UTCR3(sport, 0); UART_PUT_UTCR0(sport, utcr0); quot -= 1; UART_PUT_UTCR1(sport, ((quot & 0xf00) >> 8)); UART_PUT_UTCR2(sport, (quot & 0xff)); UART_PUT_UTSR0(sport, -1); UART_PUT_UTCR3(sport, old_utcr3); if (UART_ENABLE_MS(&sport->port, termios->c_cflag)) sa1100_enable_ms(&sport->port); spin_unlock_irqrestore(&sport->port.lock, flags); }
static void sa1100_change_speed(struct uart_port *port, unsigned int cflag, unsigned int iflag, unsigned int quot) { struct sa1100_port *sport = (struct sa1100_port *)port; unsigned long flags; unsigned int utcr0, old_utcr3; if ((cflag & CSIZE) == CS8) utcr0 = UTCR0_DSS; else utcr0 = 0; if (cflag & CSTOPB) utcr0 |= UTCR0_SBS; if (cflag & PARENB) { utcr0 |= UTCR0_PE; if (!(cflag & PARODD)) utcr0 |= UTCR0_OES; } 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 (iflag & INPCK) sport->port.read_status_mask |= UTSR1_TO_SM(UTSR1_FRE | UTSR1_PRE); if (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 (iflag & IGNPAR) sport->port.ignore_status_mask |= UTSR1_TO_SM(UTSR1_FRE | UTSR1_PRE); if (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 (iflag & IGNPAR) sport->port.ignore_status_mask |= UTSR1_TO_SM(UTSR1_ROR); } del_timer_sync(&sport->timer); /* * 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, cflag)) sa1100_enable_ms(&sport->port); spin_unlock_irqrestore(&sport->port.lock, flags); }
static void sa1100_change_speed(struct uart_port *port, u_int cflag, u_int iflag, u_int quot) { unsigned long flags; u_int utcr0, old_utcr3; /* byte size and parity */ switch (cflag & CSIZE) { case CS7: utcr0 = 0; break; default: utcr0 = UTCR0_DSS; break; } if (cflag & CSTOPB) utcr0 |= UTCR0_SBS; if (cflag & PARENB) { utcr0 |= UTCR0_PE; if (!(cflag & PARODD)) utcr0 |= UTCR0_OES; } port->read_status_mask &= UTSR0_TO_SM(UTSR0_TFS); port->read_status_mask |= UTSR1_TO_SM(UTSR1_ROR); if (iflag & INPCK) port->read_status_mask |= UTSR1_TO_SM(UTSR1_FRE | UTSR1_PRE); if (iflag & (BRKINT | PARMRK)) port->read_status_mask |= UTSR0_TO_SM(UTSR0_RBB | UTSR0_REB); /* * Characters to ignore */ port->ignore_status_mask = 0; if (iflag & IGNPAR) port->ignore_status_mask |= UTSR1_TO_SM(UTSR1_FRE | UTSR1_PRE); if (iflag & IGNBRK) { 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 (iflag & IGNPAR) port->ignore_status_mask |= UTSR1_TO_SM(UTSR1_ROR); } /* first, disable interrupts and drain transmitter */ local_irq_save(flags); old_utcr3 = UART_GET_UTCR3(port); UART_PUT_UTCR3(port, old_utcr3 & ~(UTCR3_RIE | UTCR3_TIE)); local_irq_restore(flags); while (UART_GET_UTSR1(port) & UTSR1_TBY); /* then, disable everything */ UART_PUT_UTCR3(port, 0); /* set the parity, stop bits and data size */ UART_PUT_UTCR0(port, utcr0); /* set the baud rate */ quot -= 1; UART_PUT_UTCR1(port, ((quot & 0xf00) >> 8)); UART_PUT_UTCR2(port, (quot & 0xff)); UART_PUT_UTSR0(port, -1); UART_PUT_UTCR3(port, old_utcr3); }
/* * Interrupts enabled */ static void sa1100_stop_rx(struct uart_port *port) { u32 utcr3 = UART_GET_UTCR3(port); UART_PUT_UTCR3(port, utcr3 & ~UTCR3_RIE); }
/* * interrupts disabled on entry */ static void sa1100_stop_tx(struct uart_port *port, u_int from_tty) { u32 utcr3 = UART_GET_UTCR3(port); UART_PUT_UTCR3(port, utcr3 & ~UTCR3_TIE); port->read_status_mask &= ~UTSR0_TO_SM(UTSR0_TFS); }