static void s3c_serial_shutdown(struct uart_port *port) { struct s3c_uart_port *ourport = to_ourport(port); #ifdef UART_HAS_INTMSK if (ourport->tx_claimed || ourport->rx_claimed) { free_irq(UART_IRQ(port), ourport); ourport->tx_claimed = 0; ourport->rx_claimed = 0; tx_enabled(port) = 0; rx_enabled(port) = 0; } #else if (ourport->tx_claimed) { free_irq(TX_IRQ(port), ourport); tx_enabled(port) = 0; ourport->tx_claimed = 0; } if (ourport->rx_claimed) { free_irq(RX_IRQ(port), ourport); ourport->rx_claimed = 0; rx_enabled(port) = 0; } #endif }
static void s3c24xx_serial_stop_rx(struct uart_port *port) { struct s3c24xx_uart_port *ourport = to_ourport(port); struct s3c24xx_uart_dma *dma = ourport->dma; struct tty_port *t = &port->state->port; struct dma_tx_state state; enum dma_status dma_status; unsigned int received; if (rx_enabled(port)) { dbg("s3c24xx_serial_stop_rx: port=%p\n", port); if (s3c24xx_serial_has_interrupt_mask(port)) s3c24xx_set_bit(port, S3C64XX_UINTM_RXD, S3C64XX_UINTM); else disable_irq_nosync(ourport->rx_irq); rx_enabled(port) = 0; } if (dma && dma->rx_chan) { dmaengine_pause(dma->tx_chan); dma_status = dmaengine_tx_status(dma->rx_chan, dma->rx_cookie, &state); if (dma_status == DMA_IN_PROGRESS || dma_status == DMA_PAUSED) { received = dma->rx_bytes_requested - state.residue; dmaengine_terminate_all(dma->rx_chan); s3c24xx_uart_copy_rx_to_tty(ourport, t, received); } } }
static void s3c24xx_serial_stop_rx(struct uart_port *port) { if (rx_enabled(port)) { dbg("s3c24xx_serial_stop_rx: port=%p\n", port); disable_irq(RX_IRQ(port)); rx_enabled(port) = 0; } }
static void s3c24xx_serial_stop_rx(struct uart_port *port) { struct s3c24xx_uart_port *ourport = to_ourport(port); if (rx_enabled(port)) { dbg("s3c24xx_serial_stop_rx: port=%p\n", port); disable_irq_nosync(ourport->rx_irq); rx_enabled(port) = 0; } }
static void s3c_serial_stop_rx(struct uart_port *port) { if (rx_enabled(port)) { #ifdef UART_HAS_INTMSK uart_disable_irq(port, UART_RX_INT); #else disable_irq(RX_IRQ(port)); #endif rx_enabled(port) = 0; } }
static void imapx200_serial_stop_rx(struct uart_port *port) { struct imapx200_uart_port *ourport = to_ourport(port); if (rx_enabled(port)) { dbg("imapx200_serial_stop_rx: port=%p\n", port); disable_irq_nosync(ourport->rx_irq); #if 1 uart_disable_irq(port, UART_RX_INT); uart_disable_irq(port, UART_ERR_INT); #endif rx_enabled(port) = 0; } }
static void ks8695uart_stop_rx(struct uart_port *port) { if (rx_enabled(port)) { disable_irq(KS8695_IRQ_UART_RX); rx_enable(port, 0); } }
static void imapx200_serial_rx_disable(struct uart_port *port) { unsigned long flags; spin_lock_irqsave(&port->lock, flags); rx_enabled(port) = 0; spin_unlock_irqrestore(&port->lock, flags); }
static int s3c24xx_serial_startup(struct uart_port *port) { struct s3c24xx_uart_port *ourport = to_ourport(port); int ret; dbg("s3c24xx_serial_startup: port=%p (%08lx,%p)\n", port->mapbase, port->membase); if (port->line == 2) { s3c2410_gpio_cfgpin(S3C2410_GPH6, S3C2410_GPH6_TXD2); s3c2410_gpio_pullup(S3C2410_GPH6, 1); s3c2410_gpio_cfgpin(S3C2410_GPH7, S3C2410_GPH7_RXD2); s3c2410_gpio_pullup(S3C2410_GPH7, 1); } rx_enabled(port) = 1; ret = request_irq(RX_IRQ(port), s3c24xx_serial_rx_chars, 0, s3c24xx_serial_portname(port), ourport); if (ret != 0) { printk(KERN_ERR "cannot get irq %d\n", RX_IRQ(port)); return ret; } ourport->rx_claimed = 1; dbg("requesting tx irq...\n"); tx_enabled(port) = 1; ret = request_irq(TX_IRQ(port), s3c24xx_serial_tx_chars, 0, s3c24xx_serial_portname(port), ourport); if (ret) { printk(KERN_ERR "cannot get irq %d\n", TX_IRQ(port)); goto err; } ourport->tx_claimed = 1; dbg("s3c24xx_serial_startup ok\n"); /* the port reset code should have done the correct * register setup for the port controls */ return ret; err: s3c24xx_serial_shutdown(port); return ret; }
static int s3c_serial_startup(struct uart_port *port) { struct s3c_uart_port *ourport = to_ourport(port); unsigned long flags; int ret; dbg("s3c_serial_startup: port=%p (%08lx,%p)\n", port->mapbase, port->membase); local_irq_save(flags); rx_enabled(port) = 1; tx_enabled(port) = 1; #ifdef UART_HAS_INTMSK uart_enable_irq(port, UART_TX_INT | UART_RX_INT); ret = request_irq(UART_IRQ(port), s3c_serial_interrupt, 0, s3c_serial_portname(port), ourport); if (ret != 0) { printk(KERN_ERR "cannot get irq %d\n", UART_IRQ(port)); return ret; } #else ret = request_irq(RX_IRQ(port), s3c_serial_rx_chars, 0, s3c_serial_portname(port), ourport); if (ret != 0) { printk(KERN_ERR "cannot get irq %d\n", RX_IRQ(port)); return ret; } ret = request_irq(TX_IRQ(port), s3c_serial_tx_chars, 0, s3c_serial_portname(port), ourport); if (ret) { printk(KERN_ERR "cannot get irq %d\n", TX_IRQ(port)); s3c_serial_shutdown(port); local_irq_restore(flags); return ret; } #endif ourport->rx_claimed = 1; ourport->tx_claimed = 1; dbg("s3c_serial_startup ok\n"); /* the port reset code should have done the correct * register setup for the port controls */ local_irq_restore(flags); return ret; }
static int s3c24xx_serial_startup(struct uart_port *port) { struct s3c24xx_uart_port *ourport = to_ourport(port); unsigned long flags; int ret; dbg("s3c24xx_serial_startup: port=%p (%08lx,%p)\n", port->mapbase, port->membase); local_irq_save(flags); rx_enabled(port) = 1; ret = request_irq(RX_IRQ(port), s3c24xx_serial_rx_chars, 0, s3c24xx_serial_portname(port), ourport); if (ret != 0) { printk(KERN_ERR "cannot get irq %d\n", RX_IRQ(port)); return ret; } ourport->rx_claimed = 1; dbg("requesting tx irq...\n"); tx_enabled(port) = 1; ret = request_irq(TX_IRQ(port), s3c24xx_serial_tx_chars, 0, s3c24xx_serial_portname(port), ourport); if (ret) { printk(KERN_ERR "cannot get irq %d\n", TX_IRQ(port)); goto err; } ourport->tx_claimed = 1; dbg("s3c24xx_serial_startup ok\n"); /* the port reset code should have done the correct * register setup for the port controls */ local_irq_restore(flags); return ret; err: s3c24xx_serial_shutdown(port); local_irq_restore(flags); return ret; }
static void imapx200_serial_shutdown(struct uart_port *port) { struct imapx200_uart_port *ourport = to_ourport(port); if (ourport->tx_claimed || ourport->rx_claimed) { free_irq(UART_IRQ(port), ourport); ourport->tx_claimed = 0; ourport->rx_claimed = 0; tx_enabled(port) = 0; rx_enabled(port) = 0; } }
static void s3c24xx_serial_rx_disable(struct uart_port *port) { unsigned long flags; unsigned int ucon; spin_lock_irqsave(&port->lock, flags); ucon = rd_regl(port, S3C2410_UCON); ucon &= ~S3C2410_UCON_RXIRQMODE; wr_regl(port, S3C2410_UCON, ucon); rx_enabled(port) = 0; spin_unlock_irqrestore(&port->lock, flags); }
static int s3c24xx_serial_startup(struct uart_port *port) { struct s3c24xx_uart_port *ourport = to_ourport(port); struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port); int ret; dbg("s3c24xx_serial_startup: port=%p (%08lx,%p)\n", port->mapbase, port->membase); /* runstate should be 1 before request_irq is called */ if (cfg->set_runstate) cfg->set_runstate(1); rx_enabled(port) = 1; ret = request_irq(ourport->rx_irq, s3c24xx_serial_rx_chars, 0, s3c24xx_serial_portname(port), ourport); if (ret != 0) { printk(KERN_ERR "cannot get irq %d\n", ourport->rx_irq); goto err; } ourport->rx_claimed = 1; dbg("requesting tx irq...\n"); tx_enabled(port) = 1; ret = request_irq(ourport->tx_irq, s3c24xx_serial_tx_chars, 0, s3c24xx_serial_portname(port), ourport); if (ret) { printk(KERN_ERR "cannot get irq %d\n", ourport->tx_irq); goto err; } ourport->tx_claimed = 1; dbg("s3c24xx_serial_startup ok\n"); /* the port reset code should have done the correct * register setup for the port controls */ return ret; err: s3c24xx_serial_shutdown(port); return ret; }
static void s3c24xx_serial_shutdown(struct uart_port *port) { struct s3c24xx_uart_port *ourport = to_ourport(port); if (ourport->tx_claimed) { free_irq(ourport->tx_irq, ourport); tx_enabled(port) = 0; ourport->tx_claimed = 0; } if (ourport->rx_claimed) { free_irq(ourport->rx_irq, ourport); ourport->rx_claimed = 0; rx_enabled(port) = 0; } }
static void imapx200_serial_rx_enable(struct uart_port *port) { unsigned long flags; unsigned int fcr; int count = 10000; spin_lock_irqsave(&port->lock, flags); while (--count && !imapx200_serial_txempty_nofifo(port)) udelay(100); fcr |= IMAPX200_FCR_RFIFOR_RX_FIFO_RESET | IMAPX200_FCR_FIFOE_FIFO_ENABLE; wr_regl(port, IMAPX200_FCR, fcr); rx_enabled(port) = 1; spin_unlock_irqrestore(&port->lock, flags); }
static int s3c24xx_serial_startup(struct uart_port *port) { struct s3c24xx_uart_port *ourport = to_ourport(port); int ret; dbg("s3c24xx_serial_startup: port=%p (%08lx,%p)\n", port->mapbase, port->membase); rx_enabled(port) = 1; ret = request_irq(ourport->rx_irq, s3c24xx_serial_rx_chars, 0, s3c24xx_serial_portname(port), ourport); if (ret != 0) { printk(KERN_ERR "cannot get irq %d\n", ourport->rx_irq); return ret; } ourport->rx_claimed = 1; dbg("requesting tx irq...\n"); tx_enabled(port) = 1; ret = request_irq(ourport->tx_irq, s3c24xx_serial_tx_chars, 0, s3c24xx_serial_portname(port), ourport); if (ret) { printk(KERN_ERR "cannot get irq %d\n", ourport->tx_irq); goto err; } ourport->tx_claimed = 1; dbg("s3c24xx_serial_startup ok\n"); return ret; err: s3c24xx_serial_shutdown(port); return ret; }
static int imapx200_serial_startup(struct uart_port *port) { struct imapx200_uart_port *ourport = to_ourport(port); int ret; unsigned long flags; dbg("imapx200_serial_startup: port=%p (%08lx,%p)\n", port->mapbase, port->membase); // local_irq_save(flags); rx_enabled(port) = 1; // tx_enabled(port) = 1; uart_enable_irq(port, UART_RX_INT); uart_enable_irq(port, UART_ERR_INT); // uart_enable_irq(port, UART_THRE_INT); ret = request_irq(UART_IRQ(port), imapx200_serial_interrupt, IRQF_DISABLED, imapx200_serial_portname(port), ourport); if (ret != 0) { printk(KERN_ERR "cannot get irq %d\n", UART_IRQ(port)); goto err; } ourport->tx_claimed = 1; ourport->rx_claimed = 1; dbg("imapx200_serial_startup ok\n"); /* the port reset code should have done the correct * register setup for the port controls */ // local_irq_restore(flags); return ret; err: imapx200_serial_shutdown(port); return ret; }
static void s3c24xx_serial_rx_enable(struct uart_port *port) { unsigned long flags; unsigned int ucon, ufcon; int count = 10000; spin_lock_irqsave(&port->lock, flags); while (--count && !s3c24xx_serial_txempty_nofifo(port)) udelay(100); ufcon = rd_regl(port, S3C2410_UFCON); ufcon |= S3C2410_UFCON_RESETRX; wr_regl(port, S3C2410_UFCON, ufcon); ucon = rd_regl(port, S3C2410_UCON); ucon |= S3C2410_UCON_RXIRQMODE; wr_regl(port, S3C2410_UCON, ucon); rx_enabled(port) = 1; spin_unlock_irqrestore(&port->lock, flags); }
static void s3c24xx_serial_shutdown(struct uart_port *port) { struct s3c24xx_uart_port *ourport = to_ourport(port); struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port); if (ourport->tx_claimed) { disable_irq(ourport->tx_irq); free_irq(ourport->tx_irq, ourport); tx_enabled(port) = 0; ourport->tx_claimed = 0; } if (ourport->rx_claimed) { disable_irq(ourport->rx_irq); free_irq(ourport->rx_irq, ourport); ourport->rx_claimed = 0; rx_enabled(port) = 0; } if (cfg->set_runstate) cfg->set_runstate(0); }
static irqreturn_t s3c24xx_serial_rx_chars(int irq, void *dev_id) { struct s3c24xx_uart_port *ourport = dev_id; struct uart_port *port = &ourport->port; struct tty_struct *tty = port->state->port.tty; unsigned int ufcon, ch, flag, ufstat, uerstat; int max_count = 64; while (max_count-- > 0) { ufcon = rd_regl(port, S3C2410_UFCON); ufstat = rd_regl(port, S3C2410_UFSTAT); if (s3c24xx_serial_rx_fifocnt(ourport, ufstat) == 0) break; uerstat = rd_regl(port, S3C2410_UERSTAT); ch = rd_regb(port, S3C2410_URXH); if (port->flags & UPF_CONS_FLOW) { int txe = s3c24xx_serial_txempty_nofifo(port); if (rx_enabled(port)) { if (!txe) { rx_enabled(port) = 0; continue; } } else { if (txe) { ufcon |= S3C2410_UFCON_RESETRX; wr_regl(port, S3C2410_UFCON, ufcon); rx_enabled(port) = 1; goto out; } continue; } } /* insert the character into the buffer */ flag = TTY_NORMAL; port->icount.rx++; if (unlikely(uerstat & S3C2410_UERSTAT_ANY)) { dbg("rxerr: port ch=0x%02x, rxs=0x%08x\n", ch, uerstat); /* check for break */ if (uerstat & S3C2410_UERSTAT_BREAK) { dbg("break!\n"); port->icount.brk++; if (uart_handle_break(port)) goto ignore_char; } if (uerstat & S3C2410_UERSTAT_FRAME) port->icount.frame++; if (uerstat & S3C2410_UERSTAT_OVERRUN) port->icount.overrun++; uerstat &= port->read_status_mask; if (uerstat & S3C2410_UERSTAT_BREAK) flag = TTY_BREAK; else if (uerstat & S3C2410_UERSTAT_PARITY) flag = TTY_PARITY; else if (uerstat & (S3C2410_UERSTAT_FRAME | S3C2410_UERSTAT_OVERRUN)) flag = TTY_FRAME; } if (uart_handle_sysrq_char(port, ch)) goto ignore_char; uart_insert_char(port, uerstat, S3C2410_UERSTAT_OVERRUN, ch, flag); ignore_char: continue; } tty_flip_buffer_push(tty); out: return IRQ_HANDLED; }
static irqreturn_t s3c24xx_serial_rx_chars(int irq, void *dev_id, struct pt_regs *regs) { struct s3c24xx_uart_port *ourport = dev_id; struct uart_port *port = &ourport->port; struct tty_struct *tty = port->info->tty; unsigned int ufcon, ch, flag, ufstat, uerstat; int max_count = 64; while (max_count-- > 0) { ufcon = rd_regl(port, S3C2410_UFCON); ufstat = rd_regl(port, S3C2410_UFSTAT); if (s3c24xx_serial_rx_fifocnt(ourport, ufstat) == 0) break; if (tty->flip.count >= TTY_FLIPBUF_SIZE) { if (tty->low_latency) tty_flip_buffer_push(tty); /* * If this failed then we will throw away the * bytes but must do so to clear interrupts */ } uerstat = rd_regl(port, S3C2410_UERSTAT); ch = rd_regb(port, S3C2410_URXH); if (port->flags & UPF_CONS_FLOW) { int txe = s3c24xx_serial_txempty_nofifo(port); if (rx_enabled(port)) { if (!txe) { rx_enabled(port) = 0; continue; } } else { if (txe) { ufcon |= S3C2410_UFCON_RESETRX; wr_regl(port, S3C2410_UFCON, ufcon); rx_enabled(port) = 1; goto out; } continue; } } /* insert the character into the buffer */ flag = TTY_NORMAL; port->icount.rx++; if (uerstat & S3C2410_UERSTAT_ANY) { dbg("rxerr: port ch=0x%02x, rxs=0x%08x\n", ch, uerstat); /* check for break */ if (uerstat & S3C2410_UERSTAT_BREAK) { dbg("break!\n"); port->icount.brk++; if (uart_handle_break(port)) goto ignore_char; } if (uerstat & S3C2410_UERSTAT_FRAME) port->icount.frame++; if (uerstat & S3C2410_UERSTAT_OVERRUN) port->icount.overrun++; uerstat &= port->read_status_mask; if (uerstat & S3C2410_UERSTAT_BREAK) flag = TTY_BREAK; else if (uerstat & S3C2410_UERSTAT_PARITY) flag = TTY_PARITY; else if (uerstat & ( S3C2410_UERSTAT_FRAME | S3C2410_UERSTAT_OVERRUN)) flag = TTY_FRAME; } if (uart_handle_sysrq_char(port, ch, regs)) goto ignore_char; if ((uerstat & port->ignore_status_mask) == 0) { tty_insert_flip_char(tty, ch, flag); } if ((uerstat & S3C2410_UERSTAT_OVERRUN) && tty->flip.count < TTY_FLIPBUF_SIZE) { /* * Overrun is special, since it's reported * immediately, and doesn't affect the current * character. */ tty_insert_flip_char(tty, 0, TTY_OVERRUN); } ignore_char: continue; } tty_flip_buffer_push(tty); out: return IRQ_HANDLED; }
static void s3c24xx_serial_rx_drain_fifo(struct s3c24xx_uart_port *ourport) { struct uart_port *port = &ourport->port; unsigned int ufcon, ch, flag, ufstat, uerstat; unsigned int fifocnt = 0; int max_count = port->fifosize; while (max_count-- > 0) { /* * Receive all characters known to be in FIFO * before reading FIFO level again */ if (fifocnt == 0) { ufstat = rd_regl(port, S3C2410_UFSTAT); fifocnt = s3c24xx_serial_rx_fifocnt(ourport, ufstat); if (fifocnt == 0) break; } fifocnt--; uerstat = rd_regl(port, S3C2410_UERSTAT); ch = rd_regb(port, S3C2410_URXH); if (port->flags & UPF_CONS_FLOW) { int txe = s3c24xx_serial_txempty_nofifo(port); if (rx_enabled(port)) { if (!txe) { rx_enabled(port) = 0; continue; } } else { if (txe) { ufcon = rd_regl(port, S3C2410_UFCON); ufcon |= S3C2410_UFCON_RESETRX; wr_regl(port, S3C2410_UFCON, ufcon); rx_enabled(port) = 1; return; } continue; } } /* insert the character into the buffer */ flag = TTY_NORMAL; port->icount.rx++; if (unlikely(uerstat & S3C2410_UERSTAT_ANY)) { dbg("rxerr: port ch=0x%02x, rxs=0x%08x\n", ch, uerstat); /* check for break */ if (uerstat & S3C2410_UERSTAT_BREAK) { dbg("break!\n"); port->icount.brk++; if (uart_handle_break(port)) continue; /* Ignore character */ } if (uerstat & S3C2410_UERSTAT_FRAME) port->icount.frame++; if (uerstat & S3C2410_UERSTAT_OVERRUN) port->icount.overrun++; uerstat &= port->read_status_mask; if (uerstat & S3C2410_UERSTAT_BREAK) flag = TTY_BREAK; else if (uerstat & S3C2410_UERSTAT_PARITY) flag = TTY_PARITY; else if (uerstat & (S3C2410_UERSTAT_FRAME | S3C2410_UERSTAT_OVERRUN)) flag = TTY_FRAME; } if (uart_handle_sysrq_char(port, ch)) continue; /* Ignore character */ uart_insert_char(port, uerstat, S3C2410_UERSTAT_OVERRUN, ch, flag); } tty_flip_buffer_push(&port->state->port); }
static irqreturn_t imapx200_serial_rx_chars(int irq, void *dev_id) { struct imapx200_uart_port *ourport = dev_id; struct uart_port *port = &ourport->port; struct tty_struct *tty = port->state->port.tty; unsigned int ch, flag; unsigned int usr, rfl, lsr, fcr; int max_count = 64; while (max_count-- > 0) { usr = rd_regl(port, IMAPX200_USR); rfl = rd_regl(port, IMAPX200_RFL); if (imapx200_serial_rx_fifocnt(ourport, usr, rfl) == 0) break; lsr = rd_regl(port, IMAPX200_LSR); ch = rd_regl(port, IMAPX200_RBR); if (port->flags & UPF_CONS_FLOW) { int txe = imapx200_serial_txempty_nofifo(port); if (rx_enabled(port)) { if (!txe) { rx_enabled(port) = 0; continue; } } else { if (txe) { fcr |= IMAPX200_FCR_RFIFOR_RX_FIFO_RESET | IMAPX200_FCR_FIFOE_FIFO_ENABLE; wr_regl(port, IMAPX200_FCR, fcr); rx_enabled(port) = 1; goto out; } continue; } } /* insert the character into the buffer */ flag = TTY_NORMAL; port->icount.rx++; if (unlikely(lsr & IMAPX200_LSR_ANY)) { dbg("rxerr: port ch=0x%02x, rxs=0x%08x\n", ch, lsr); /* check for break */ if (lsr & IMAPX200_LSR_BI_Break_INT) { dbg("break!\n"); port->icount.brk++; if (uart_handle_break(port)) goto ignore_char; } if (lsr & IMAPX200_LSR_FE_FRAME_ERR) port->icount.frame++; if (lsr & IMAPX200_LSR_OE_OVERRUN_ERR) port->icount.overrun++; lsr &= port->read_status_mask; if (lsr & IMAPX200_LSR_BI_Break_INT) flag = TTY_BREAK; else if (lsr & IMAPX200_LSR_PE_PARITY_ERR) flag = TTY_PARITY; else if (lsr & (IMAPX200_LSR_FE_FRAME_ERR | IMAPX200_LSR_OE_OVERRUN_ERR)) flag = TTY_FRAME; } if (uart_handle_sysrq_char(port, ch)) goto ignore_char; uart_insert_char(port, lsr, IMAPX200_LSR_OE_OVERRUN_ERR, ch, flag); ignore_char: continue; } tty_flip_buffer_push(tty); out: return IRQ_HANDLED; }