static void ambauart_enable_ms(struct uart_port *port) { #if DEBUG printk("ambauart_enable_ms() called\n"); #endif UART_PUT_IER(port, UART_GET_IER(port) | KS8695_INT_ENABLE_MODEM); }
static int bfin_sir_is_receiving(struct net_device *dev) { struct bfin_sir_self *self = netdev_priv(dev); struct bfin_sir_port *port = self->sir_port; if (!(UART_GET_IER(port) & ERBFI)) return 0; return self->rx_buff.state != OUTSIDE_FRAME; }
static void ambauart_stop_rx(struct uart_port *port) { unsigned int ier; #if DEBUG printk("ambauart_stop_rx() called\n"); #endif ier = UART_GET_IER(port); ier &= ~KS8695_INT_ENABLE_RX; UART_PUT_IER(port, ier); }
static void ssauart_stop_rx (struct uart_port *port) { unsigned int ier; unsigned long flags; local_irq_save (flags); /* AMcCurdy: added paranoid irq protection */ ier = UART_GET_IER(port); ier &= ~(1 << 0); /* disable Rx interrupts */ UART_PUT_IER(port, ier); local_irq_restore (flags); }
static int ambauart_startup(struct uart_port *port) { int retval; #if DEBUG printk("ambauart_startup ier=%x\n",UART_GET_IER(port)); #endif /* * Allocate the IRQ, let IRQ KS8695_INT_UART_RX, KS8695_INT_UART_TX comes to same * routine */ UART_PUT_IER(port, UART_GET_IER(port) & 0xFFFFF0FF); retval = request_irq(KS8695_INT_UART_TX, ambauart_int, SA_SHIRQ | SA_INTERRUPT, "amba", port); if (retval) return retval; retval = request_irq(KS8695_INT_UART_RX, ambauart_int, SA_SHIRQ | SA_INTERRUPT, "amba", port); if (retval) return retval; retval = request_irq(KS8695_INT_UART_LINE_ERR, ambauart_int, SA_SHIRQ | SA_INTERRUPT, "amba", port); if (retval) return retval; retval = request_irq(KS8695_INT_UART_MODEMS, ambauart_int, SA_SHIRQ | SA_INTERRUPT, "amba", port); if (retval) return retval; /* * Finally, enable interrupts */ UART_PUT_IER(port, ((UART_GET_IER(port) & 0xFFFFF0FF) | KS8695_INT_ENABLE_RX | 0x800 | 0x400)); return 0; }
static void ssauart_start_tx (struct uart_port *port, unsigned int from_tty) { unsigned int ier; unsigned long flags; local_irq_save (flags); /* AMcCurdy: added paranoid irq protection */ ier = UART_GET_IER(port); ier |= (1 << 1); /* enable Tx interrupts */ UART_PUT_IER(port, ier); /* We may have something in the buffer already */ ssauart_tx_one_char (port); local_irq_restore (flags); }
static void ssauart_enable_ms (struct uart_port *port) { #if 0 unsigned int ier; unsigned long flags; local_irq_save (flags); /* AMcCurdy: added paranoid irq protection */ ier = UART_GET_IER(port); ier |= (1 << 3); /* enable Modem Status interrupts */ UART_PUT_IER(port, ier); local_irq_restore (flags); #endif }
static void ambauart_start_tx(struct uart_port *port, unsigned int tty_start) { unsigned int ier; #if DEBUG printk("ambauart_start_tx() called\n"); #endif ier = UART_GET_IER(port); if ( ier & KS8695_INT_ENABLE_TX ) return; else { ier |= KS8695_INT_ENABLE_TX; UART_PUT_IER(port, ier); } }
static void ambauart_shutdown(struct uart_port *port) { #if DEBUG printk("ambauart_shutdown\n"); #endif /* * disable all interrupts, disable the port */ UART_PUT_IER(port, UART_GET_IER(port) & 0xFFFFF0FF); /* disable break condition and fifos */ UART_PUT_LCR(port, UART_GET_LCR(port) & ~KS8695_UART_LINEC_BRK); UART_PUT_FCR(port, UART_GET_FCR(port) & ~KS8695_UART_FIFO_FEN); free_irq(KS8695_INT_UART_RX, port); free_irq(KS8695_INT_UART_TX, port); free_irq(KS8695_INT_UART_MODEMS, port); free_irq(KS8695_INT_UART_LINE_ERR, port); }
/* * If the port was already initialised (eg, by a boot loader), * try to determine the current setup. */ static void __init bfin_serial_console_get_options(struct bfin_serial_port *uart, int *baud, int *parity, int *bits) { unsigned short status; status = UART_GET_IER(uart) & (ERBFI | ETBEI); if (status == (ERBFI | ETBEI)) { /* ok, the port was enabled */ u16 lcr, dlh, dll; lcr = UART_GET_LCR(uart); *parity = 'n'; if (lcr & PEN) { if (lcr & EPS) *parity = 'e'; else *parity = 'o'; } switch (lcr & 0x03) { case 0: *bits = 5; break; case 1: *bits = 6; break; case 2: *bits = 7; break; case 3: *bits = 8; break; } /* Set DLAB in LCR to Access DLL and DLH */ UART_SET_DLAB(uart); dll = UART_GET_DLL(uart); dlh = UART_GET_DLH(uart); /* Clear DLAB in LCR to Access THR RBR IER */ UART_CLEAR_DLAB(uart); *baud = get_sclk() / (16*(dll | dlh << 8)); } pr_debug("%s:baud = %d, parity = %c, bits= %d\n", __func__, *baud, *parity, *bits); }
static void ambauart_change_speed(struct uart_port *port, u_int cflag, u_int iflag, u_int quot) { u_int lcr, old_ier, fcr=0; unsigned long flags; #if DEBUG printk("ambauart_set_cflag(0x%x) called\n", cflag); #endif //printk("ambauart_change_speed\n"); /* byte size and parity */ switch (cflag & CSIZE) { case CS5: lcr = KS8695_UART_LINEC_WLEN5; break; case CS6: lcr = KS8695_UART_LINEC_WLEN6; break; case CS7: lcr = KS8695_UART_LINEC_WLEN7; break; default: lcr = KS8695_UART_LINEC_WLEN8; break; // CS8 } if (cflag & CSTOPB) lcr |= KS8695_UART_LINEC_STP2; if (cflag & PARENB) { lcr |= KS8695_UART_LINEC_PEN; if (!(cflag & PARODD)) lcr |= KS8695_UART_LINEC_EPS; } if (port->fifosize > 1) fcr = KS8695_UART_FIFO_TRIG04 | KS8695_UART_FIFO_TXRST | KS8695_UART_FIFO_RXRST | KS8695_UART_FIFO_FEN; port->read_status_mask = KS8695_UART_LINES_OE; if (iflag & INPCK) port->read_status_mask |= (KS8695_UART_LINES_FE | KS8695_UART_LINES_PE); if (iflag & (BRKINT | PARMRK)) port->read_status_mask |= KS8695_UART_LINES_BE; /* * Characters to ignore */ port->ignore_status_mask = 0; if (iflag & IGNPAR) port->ignore_status_mask |= (KS8695_UART_LINES_FE | KS8695_UART_LINES_PE); if (iflag & IGNBRK) { port->ignore_status_mask |= KS8695_UART_LINES_BE; /* * If we're ignoring parity and break indicators, * ignore overruns too (for real raw support). */ if (iflag & IGNPAR) port->ignore_status_mask |= KS8695_UART_LINES_OE; } /* * Ignore all characters if CREAD is not set. */ if ((cflag & CREAD) == 0) port->ignore_status_mask |= UART_DUMMY_LSR_RX; /* first, disable everything */ save_flags(flags); cli(); old_ier = UART_GET_IER(port); UART_PUT_IER(port, old_ier & 0xFFFFF0FF); old_ier &= ~KS8695_INT_ENABLE_MODEM; if ((port->flags & ASYNC_HARDPPS_CD) || (cflag & CRTSCTS) || !(cflag & CLOCAL)) old_ier |= KS8695_INT_ENABLE_MODEM; /* Set baud rate */ // UART_PUT_BRDR(port, port->uartclk / quot); UART_PUT_BRDR(port, 0x28B); UART_PUT_LCR(port, lcr); UART_PUT_FCR(port, fcr); UART_PUT_IER(port, old_ier & 0xFFFFFEFF); restore_flags(flags); }
static void ambauart_int(int irq, void *dev_id, struct pt_regs *regs) { struct uart_port *port = dev_id; struct uart_info *info = port->info; unsigned int status, ier, old_ier, count, lsr; old_ier = UART_GET_IER(port); UART_PUT_IER(port, (old_ier & 0xFFFFF0FF)); status = UART_GET_INT_STATUS(port); lsr = UART_GET_LSR(port); /* KS8695_INTMASK_UART_RX is not set during breakpoint as it should (looks * like a HW bug), so we specifically check for a breakpoint condition in * the UART line status register. * Some bits from the UART line status register are cleared only when they * are read by CPU. That is why we cannot read the line status register * twice, and should pass the first read as argument to ambauart_rx_chars. * Refer to CENTAUR KS8695PX's Register Description document: * KS8695PX_REG_DESCP_v1.0.pdf, page 58: "UART Line Status Register". */ if (status & KS8695_INTMASK_UART_RX || lsr & KS8695_UART_LINES_BE) { #ifdef SUPPORT_SYSRQ ambauart_rx_chars(port, regs, lsr); #else ambauart_rx_chars(port, lsr); #endif } if (status & KS8695_INTMASK_UART_TX) { if (port->x_char) { UART_CLR_INT_STATUS(port, KS8695_INTMASK_UART_TX); UART_PUT_CHAR(port, (u_int) port->x_char); port->icount.tx++; port->x_char = 0; ier = UART_GET_IER(port); ier &= 0xFFFFFEFF; UART_PUT_IER(port, ier); printk("XOn/Off sent\n"); return; } for ( count = 0; count < 16; count++) { if (info->xmit.head == info->xmit.tail) { /*ier = UART_GET_IER(port); ier &= 0xFFFFFEFF; UART_PUT_IER(port, ier);*/ break; } UART_CLR_INT_STATUS(port, KS8695_INTMASK_UART_TX); UART_PUT_CHAR(port, (u_int) (info->xmit.buf[info->xmit.tail])); info->xmit.tail = (info->xmit.tail + 1) & (UART_XMIT_SIZE - 1); port->icount.tx++; }; if (CIRC_CNT(info->xmit.head, info->xmit.tail, UART_XMIT_SIZE) < WAKEUP_CHARS) uart_write_wakeup(port); if (info->xmit.head == info->xmit.tail) { ier = UART_GET_IER(port); ier &= 0xFFFFFEFF; UART_PUT_IER(port, ier); } } if (status & KS8695_INTMASK_UART_MODEMS) { ambauart_modem_status(port); } if (status & KS8695_INTMASK_UART_MODEMS) { ambauart_modem_status(port); } if ( status & KS8695_INTMASK_UART_LINE_ERR) { UART_GET_LSR(port); } if (info->xmit.head == info->xmit.tail) UART_PUT_IER(port, (old_ier & 0xFFFFFEFF)); else UART_PUT_IER(port, old_ier | KS8695_INTMASK_UART_TX); }
static void bfin_serial_set_termios(struct uart_port *port, struct ktermios *termios, struct ktermios *old) { struct bfin_serial_port *uart = (struct bfin_serial_port *)port; unsigned long flags; unsigned int baud, quot; unsigned short val, ier, lcr = 0; switch (termios->c_cflag & CSIZE) { case CS8: lcr = WLS(8); break; case CS7: lcr = WLS(7); break; case CS6: lcr = WLS(6); break; case CS5: lcr = WLS(5); break; default: printk(KERN_ERR "%s: word lengh not supported\n", __func__); } if (termios->c_cflag & CSTOPB) lcr |= STB; if (termios->c_cflag & PARENB) lcr |= PEN; if (!(termios->c_cflag & PARODD)) lcr |= EPS; if (termios->c_cflag & CMSPAR) lcr |= STP; port->read_status_mask = OE; if (termios->c_iflag & INPCK) port->read_status_mask |= (FE | PE); if (termios->c_iflag & (BRKINT | PARMRK)) port->read_status_mask |= BI; /* * Characters to ignore */ port->ignore_status_mask = 0; if (termios->c_iflag & IGNPAR) port->ignore_status_mask |= FE | PE; if (termios->c_iflag & IGNBRK) { port->ignore_status_mask |= BI; /* * If we're ignoring parity and break indicators, * ignore overruns too (for real raw support). */ if (termios->c_iflag & IGNPAR) port->ignore_status_mask |= OE; } baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16); quot = uart_get_divisor(port, baud); spin_lock_irqsave(&uart->port.lock, flags); UART_SET_ANOMALY_THRESHOLD(uart, USEC_PER_SEC / baud * 15); /* Disable UART */ ier = UART_GET_IER(uart); UART_DISABLE_INTS(uart); /* Set DLAB in LCR to Access DLL and DLH */ UART_SET_DLAB(uart); UART_PUT_DLL(uart, quot & 0xFF); UART_PUT_DLH(uart, (quot >> 8) & 0xFF); SSYNC(); /* Clear DLAB in LCR to Access THR RBR IER */ UART_CLEAR_DLAB(uart); UART_PUT_LCR(uart, lcr); /* Enable UART */ UART_ENABLE_INTS(uart, ier); val = UART_GET_GCTL(uart); val |= UCEN; UART_PUT_GCTL(uart, val); /* Port speed changed, update the per-port timeout. */ uart_update_timeout(port, termios->c_cflag, baud); spin_unlock_irqrestore(&uart->port.lock, flags); }