static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id, struct pt_regs *regs) { struct s3c24xx_uart_port *ourport = id; struct uart_port *port = &ourport->port; struct circ_buf *xmit = &port->info->xmit; int count = 256; if (port->x_char) { wr_regb(port, S3C2410_UTXH, port->x_char); port->icount.tx++; port->x_char = 0; goto out; } /* if there isnt anything more to transmit, or the uart is now * stopped, disable the uart and exit */ if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { s3c24xx_serial_stop_tx(port, 0); goto out; } /* try and drain the buffer... */ while (!uart_circ_empty(xmit) && count-- > 0) { if (rd_regl(port, S3C2410_UFSTAT) & ourport->info->tx_fifofull) break; wr_regb(port, S3C2410_UTXH, xmit->buf[xmit->tail]); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); port->icount.tx++; } if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); if (uart_circ_empty(xmit)) s3c24xx_serial_stop_tx(port, 0); out: return IRQ_HANDLED; }
static void tegra_uart_tx_dma_complete(void *args) { struct tegra_uart_port *tup = args; struct circ_buf *xmit = &tup->uport.state->xmit; struct dma_tx_state state; unsigned long flags; unsigned int count; dmaengine_tx_status(tup->tx_dma_chan, tup->tx_cookie, &state); count = tup->tx_bytes_requested - state.residue; async_tx_ack(tup->tx_dma_desc); spin_lock_irqsave(&tup->uport.lock, flags); xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1); tup->tx_in_progress = 0; if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&tup->uport); tegra_uart_start_next_tx(tup); spin_unlock_irqrestore(&tup->uport.lock, flags); }
/** * xuartps_start_tx - Start transmitting bytes * @port: Handle to the uart port structure * **/ static void xuartps_start_tx(struct uart_port *port) { unsigned int status, numbytes = port->fifosize; if (uart_circ_empty(&port->state->xmit) || uart_tx_stopped(port)) return; status = xuartps_readl(XUARTPS_CR_OFFSET); /* Set the TX enable bit and clear the TX disable bit to enable the * transmitter. */ xuartps_writel((status & ~XUARTPS_CR_TX_DIS) | XUARTPS_CR_TX_EN, XUARTPS_CR_OFFSET); while (numbytes-- && ((xuartps_readl(XUARTPS_SR_OFFSET) & XUARTPS_SR_TXFULL)) != XUARTPS_SR_TXFULL) { /* Break if no more data available in the UART buffer */ if (uart_circ_empty(&port->state->xmit)) break; /* Get the data from the UART circular buffer and * write it to the xuartps's TX_FIFO register. */ xuartps_writel( port->state->xmit.buf[port->state->xmit.tail], XUARTPS_FIFO_OFFSET); port->icount.tx++; /* Adjust the tail of the UART buffer and wrap * the buffer if it reaches limit. */ port->state->xmit.tail = (port->state->xmit.tail + 1) & (UART_XMIT_SIZE - 1); } /* Enable the TX Empty interrupt */ xuartps_writel(XUARTPS_IXR_TXEMPTY, XUARTPS_IER_OFFSET); if (uart_circ_chars_pending(&port->state->xmit) < WAKEUP_CHARS) uart_write_wakeup(port); }
static inline void imx_transmit_buffer(struct imx_port *sport) { struct circ_buf *xmit = &sport->port.state->xmit; while (!(readl(sport->port.membase + UTS) & UTS_TXFULL)) { /* send xmit->buf[xmit->tail] * out the port here */ writel(xmit->buf[xmit->tail], sport->port.membase + URTX0); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); sport->port.icount.tx++; if (uart_circ_empty(xmit)) break; } if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&sport->port); if (uart_circ_empty(xmit)) imx_stop_tx(&sport->port); }
static void sirfsoc_uart_tx_dma_complete_callback(void *param) { struct sirfsoc_uart_port *sirfport = (struct sirfsoc_uart_port *)param; struct uart_port *port = &sirfport->port; struct circ_buf *xmit = &port->state->xmit; unsigned long flags; spin_lock_irqsave(&port->lock, flags); xmit->tail = (xmit->tail + sirfport->transfer_size) & (UART_XMIT_SIZE - 1); port->icount.tx += sirfport->transfer_size; if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); if (sirfport->tx_dma_addr) dma_unmap_single(port->dev, sirfport->tx_dma_addr, sirfport->transfer_size, DMA_TO_DEVICE); sirfport->tx_dma_state = TX_DMA_IDLE; sirfsoc_uart_tx_with_dma(sirfport); spin_unlock_irqrestore(&port->lock, flags); }
static void parrot5_serial_tx_chars(struct uart_port *port, u32 status) { int count; struct circ_buf *xmit = &port->info->xmit; struct uart_parrot5_port *up = (struct uart_parrot5_port *)port; if (port->x_char) { __raw_writel(port->x_char, port->membase+_UART_TRX); port->icount.tx++; port->x_char = 0; goto out; } if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { parrot5_serial_stop_tx(port); goto out; } count = up->tx_fifosize; /* on Parrot5+ chips TX fifo has a configurable IRQ threshold */ if (up->tx_threshold && (status & UART_STATUS_TXFILLED)) { count -= up->tx_threshold; } while (!uart_circ_empty(xmit) && (count-- > 0)) { __raw_writel(xmit->buf[xmit->tail], port->membase+_UART_TRX); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); port->icount.tx++; } if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) { uart_write_wakeup(port); } if (uart_circ_empty(xmit)) { parrot5_serial_stop_tx(port); } out: return; }
static irqreturn_t s3c24xx_serial_tx_chars(int irq, void *id) { struct s3c24xx_uart_port *ourport = id; struct uart_port *port = &ourport->port; struct circ_buf *xmit = &port->state->xmit; int count = 256; if (port->x_char) { wr_regb(port, S3C2410_UTXH, port->x_char); port->icount.tx++; port->x_char = 0; goto out; } if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { s3c24xx_serial_stop_tx(port); goto out; } while (!uart_circ_empty(xmit) && count-- > 0) { if (rd_regl(port, S3C2410_UFSTAT) & ourport->info->tx_fifofull) break; wr_regb(port, S3C2410_UTXH, xmit->buf[xmit->tail]); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); port->icount.tx++; } if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); if (uart_circ_empty(xmit)) s3c24xx_serial_stop_tx(port); out: return IRQ_HANDLED; }
static void transmit_chars(struct uart_omap_port *up) { struct circ_buf *xmit = &up->port.state->xmit; int count; if (up->port.x_char) { serial_out(up, UART_TX, up->port.x_char); up->port.icount.tx++; up->port.x_char = 0; return; } if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { serial_omap_stop_tx(&up->port); return; } count = up->port.fifosize / 4; do { #if defined(CONFIG_KEYBOARD_P1) if(!((up->port.line == 2)&&g_keyboard)) #endif { serial_out(up, UART_TX, xmit->buf[xmit->tail]); } xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); up->port.icount.tx++; if (uart_circ_empty(xmit)) { /* This wake lock has to moved out to use case drivers * which require these. */ if (up->plat_hold_wakelock) (up->plat_hold_wakelock(up, WAKELK_TX)); break; } } while (--count > 0); if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&up->port); if (uart_circ_empty(xmit)) serial_omap_stop_tx(&up->port); }
static void transmit_chars(struct uart_hsu_port *up) { struct circ_buf *xmit = &up->port.state->xmit; int count; if (up->port.x_char) { serial_out(up, UART_TX, up->port.x_char); up->port.icount.tx++; up->port.x_char = 0; return; } if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) { serial_hsu_stop_tx(&up->port); return; } #ifndef MFD_HSU_A0_STEPPING count = up->port.fifosize / 2; #else /* * A0 only supports fully empty IRQ, and the first char written * into it won't clear the EMPT bit, so we may need be cautious * by useing a shorter buffer */ count = up->port.fifosize - 4; #endif do { serial_out(up, UART_TX, xmit->buf[xmit->tail]); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); up->port.icount.tx++; if (uart_circ_empty(xmit)) break; } while (--count > 0); if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&up->port); if (uart_circ_empty(xmit)) serial_hsu_stop_tx(&up->port); }
static void sw_uart_handle_tx(struct sw_uart_port *sw_uport) { struct circ_buf *xmit = &sw_uport->port.state->xmit; int count; if (sw_uport->port.x_char) { serial_out(&sw_uport->port, sw_uport->port.x_char, SW_UART_THR); sw_uport->port.icount.tx++; sw_uport->port.x_char = 0; #ifdef CONFIG_SW_UART_DUMP_DATA sw_uport->dump_buff[sw_uport->dump_len++] = sw_uport->port.x_char; SERIAL_DUMP(sw_uport, "Tx"); #endif return; } if (uart_circ_empty(xmit) || uart_tx_stopped(&sw_uport->port)) { sw_uart_stop_tx(&sw_uport->port); return; } count = sw_uport->port.fifosize / 2; do { #ifdef CONFIG_SW_UART_DUMP_DATA sw_uport->dump_buff[sw_uport->dump_len++] = xmit->buf[xmit->tail]; #endif serial_out(&sw_uport->port, xmit->buf[xmit->tail], SW_UART_THR); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); sw_uport->port.icount.tx++; if (uart_circ_empty(xmit)) { break; } } while (--count > 0); SERIAL_DUMP(sw_uport, "Tx"); if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) { spin_unlock(&sw_uport->port.lock); uart_write_wakeup(&sw_uport->port); spin_lock(&sw_uport->port.lock); } if (uart_circ_empty(xmit)) sw_uart_stop_tx(&sw_uport->port); }
static void __dma_tx_complete(void *param) { struct uart_8250_port *p = param; struct uart_8250_dma *dma = p->dma; struct circ_buf *xmit = &p->port.state->xmit; dma->tx_running = 0; dma_sync_single_for_cpu(dma->txchan->device->dev, dma->tx_addr, UART_XMIT_SIZE, DMA_TO_DEVICE); xmit->tail += dma->tx_size; xmit->tail &= UART_XMIT_SIZE - 1; p->port.icount.tx += dma->tx_size; if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&p->port); if (!uart_circ_empty(xmit) && !uart_tx_stopped(&p->port)) serial8250_tx_dma(p); }
static void milkymist_uart_tx_char(struct uart_port *port) { struct circ_buf *xmit = &port->state->xmit; if (port->x_char) { iowrite32be(port->x_char, port->membase + UART_RXTX); port->x_char = 0; port->icount.tx++; return; } if (uart_circ_empty(xmit) || uart_tx_stopped(port)) return; iowrite32be(xmit->buf[xmit->tail], port->membase + UART_RXTX); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE-1); port->icount.tx++; if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); }
static void tegra_tx_dma_complete_callback(struct tegra_dma_req *req) { struct tegra_uart_port *t = req->dev; struct circ_buf *xmit = &t->uport.state->xmit; int count = req->bytes_transferred; unsigned long flags; dev_vdbg(t->uport.dev, "%s: %d\n", __func__, count); spin_lock_irqsave(&t->uport.lock, flags); xmit->tail = (xmit->tail + count) & (UART_XMIT_SIZE - 1); t->tx_in_progress = 0; if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&t->uport); if (req->status != -TEGRA_DMA_REQ_ERROR_ABORTED) tegra_start_next_tx(t); spin_unlock_irqrestore(&t->uport.lock, flags); }
/* * Kick the Tx side. * The port lock is held and interrupts are disabled. */ static void pmz_start_tx(struct uart_port *port) { struct uart_pmac_port *uap = to_pmz(port); unsigned char status; pmz_debug("pmz: start_tx()\n"); uap->flags |= PMACZILOG_FLAG_TX_ACTIVE; uap->flags &= ~PMACZILOG_FLAG_TX_STOPPED; if (ZS_IS_ASLEEP(uap) || uap->node == NULL) return; status = read_zsreg(uap, R0); /* TX busy? Just wait for the TX done interrupt. */ if (!(status & Tx_BUF_EMP)) return; /* Send the first character to jump-start the TX done * IRQ sending engine. */ if (port->x_char) { write_zsdata(uap, port->x_char); zssync(uap); port->icount.tx++; port->x_char = 0; } else { struct circ_buf *xmit = &port->info->xmit; write_zsdata(uap, xmit->buf[xmit->tail]); zssync(uap); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); port->icount.tx++; if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&uap->port); } pmz_debug("pmz: start_tx() done.\n"); }
static void sa1100_tx_chars(struct sa1100_port *sport) { struct circ_buf *xmit = &sport->port.state->xmit; if (sport->port.x_char) { UART_PUT_CHAR(sport, sport->port.x_char); sport->port.icount.tx++; sport->port.x_char = 0; return; } /* * Check the modem control lines before * transmitting anything. */ sa1100_mctrl_check(sport); if (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)) { sa1100_stop_tx(&sport->port); return; } /* * Tried using FIFO (not checking TNF) for fifo fill: * still had the '4 bytes repeated' problem. */ while (UART_GET_UTSR1(sport) & UTSR1_TNF) { UART_PUT_CHAR(sport, xmit->buf[xmit->tail]); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); sport->port.icount.tx++; if (uart_circ_empty(xmit)) break; } if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&sport->port); if (uart_circ_empty(xmit)) sa1100_stop_tx(&sport->port); }
static void btlinux_start_tx(struct uart_port *port /*, unsigned int tty_start*/) { struct circ_buf *xmit = &port->info->xmit; struct uart_btlinux_port *up = (struct uart_btlinux_port *)port; int c, count, d; unsigned char *buf; count = uart_circ_chars_pending(xmit); /* dbg("line %d - buf size = %d", port->line, uart_circ_chars_pending(xmit));*/ /* printk("btlinux_start_tx: line %d port %x\n", port->line, up);*/ if (!up->port_opened) { err("start_tx - port is not opened"); return; } if (!up->is_open) { err("start_tx - bt port is not opened"); btlinux_stop_tx(port/*, 0*/); return; } if (port->x_char) { info("x_char is transmitted"); port->icount.tx++; port->x_char = 0; return; } if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { info("tx buffer empty or tx stopped"); btlinux_stop_tx(port/*, 0*/); return; } send_tx_char(up); /* wake up application waiting in a poll */ wake_up_interruptible(&up->rx_wait_q); }
static void ip3106_tx_chars(struct ip3106_port *sport) { struct circ_buf *xmit = &sport->port.info->xmit; if (sport->port.x_char) { serial_out(sport, IP3106_FIFO, sport->port.x_char); sport->port.icount.tx++; sport->port.x_char = 0; return; } /* * Check the modem control lines before * transmitting anything. */ ip3106_mctrl_check(sport); if (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)) { ip3106_stop_tx(&sport->port, 0); return; } /* * TX while bytes available */ while (((serial_in(sport, IP3106_FIFO) & IP3106_UART_FIFO_TXFIFO) >> 16) < 16) { serial_out(sport, IP3106_FIFO, xmit->buf[xmit->tail]); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); sport->port.icount.tx++; if (uart_circ_empty(xmit)) break; } if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&sport->port); if (uart_circ_empty(xmit)) ip3106_stop_tx(&sport->port, 0); }
static void handle_tx(struct uart_port *port) { struct circ_buf *xmit = &port->state->xmit; struct msm_port *msm_port = UART_TO_MSM(port); int sent_tx; if (port->x_char) { if (msm_port->is_uartdm) reset_dm_count(port); msm_write(port, port->x_char, msm_port->is_uartdm ? UARTDM_TF : UART_TF); port->icount.tx++; port->x_char = 0; } if (msm_port->is_uartdm) reset_dm_count(port); while (msm_read(port, UART_SR) & UART_SR_TX_READY) { if (uart_circ_empty(xmit)) { /* disable tx interrupts */ msm_port->imr &= ~UART_IMR_TXLEV; msm_write(port, msm_port->imr, UART_IMR); break; } msm_write(port, xmit->buf[xmit->tail], msm_port->is_uartdm ? UARTDM_TF : UART_TF); if (msm_port->is_uartdm) reset_dm_count(port); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); port->icount.tx++; sent_tx = 1; } if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); }
/* The port lock is held and interrupts are disabled. */ static void ip22zilog_start_tx(struct uart_port *port) { struct uart_ip22zilog_port *up = (struct uart_ip22zilog_port *) port; struct zilog_channel *channel = ZILOG_CHANNEL_FROM_PORT(port); unsigned char status; up->flags |= IP22ZILOG_FLAG_TX_ACTIVE; up->flags &= ~IP22ZILOG_FLAG_TX_STOPPED; status = readb(&channel->control); ZSDELAY(); /* TX busy? Just wait for the TX done interrupt. */ if (!(status & Tx_BUF_EMP)) return; /* Send the first character to jump-start the TX done * IRQ sending engine. */ if (port->x_char) { writeb(port->x_char, &channel->data); ZSDELAY(); ZS_WSYNC(channel); port->icount.tx++; port->x_char = 0; } else { struct circ_buf *xmit = &port->state->xmit; writeb(xmit->buf[xmit->tail], &channel->data); ZSDELAY(); ZS_WSYNC(channel); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); port->icount.tx++; if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&up->port); } }
static bool ntv2_serial_transmit(struct ntv2_serial *ntv2_ser) { struct uart_port *port = &ntv2_ser->uart_port; struct circ_buf *xmit = &port->state->xmit; u32 full = NTV2_FLD_MASK(ntv2_kona_fld_serial_tx_full); u32 status; status = ntv2_reg_read(ntv2_ser->vid_reg, ntv2_kona_reg_serial_status, ntv2_ser->index); if (status & full) return false; /* tx xon/xoff */ if ((port->x_char) != 0) { NTV2_MSG_SERIAL_STREAM("%s: uart tx %02x\n", ntv2_ser->name, (u8)port->x_char); ntv2_reg_write(ntv2_ser->vid_reg, ntv2_kona_reg_serial_tx, ntv2_ser->index, (u32)port->x_char); port->x_char = 0; port->icount.tx++; return true; } if (uart_circ_empty(xmit) || uart_tx_stopped(port)) return false; /* tx data */ NTV2_MSG_SERIAL_STREAM("%s: uart tx %02x\n", ntv2_ser->name, (u8)xmit->buf[xmit->tail]); ntv2_reg_write(ntv2_ser->vid_reg, ntv2_kona_reg_serial_tx, ntv2_ser->index, (u32)xmit->buf[xmit->tail]); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE-1); port->icount.tx++; /* wake up */ if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); return true; }
static unsigned int sirfsoc_uart_pio_tx_chars(struct sirfsoc_uart_port *sirfport, int count) { struct uart_port *port = &sirfport->port; struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg; struct sirfsoc_fifo_status *ufifo_st = &sirfport->uart_reg->fifo_status; struct circ_buf *xmit = &port->state->xmit; unsigned int num_tx = 0; while (!uart_circ_empty(xmit) && !(rd_regl(port, ureg->sirfsoc_tx_fifo_status) & ufifo_st->ff_full(port->line)) && count--) { wr_regl(port, ureg->sirfsoc_tx_fifo_data, xmit->buf[xmit->tail]); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); port->icount.tx++; num_tx++; } if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); return num_tx; }
/* * ------------------------------------------------------------ * transmit_char () * * This routine deals with outputs to any lines. * ------------------------------------------------------------ */ static inline void dz_transmit_chars(struct dz_port *dport_in) { struct dz_port *dport; struct circ_buf *xmit; unsigned short status; unsigned char tmp; status = dz_in(dport_in, DZ_CSR); dport = &dz_ports[LINE(status)]; xmit = &dport->port.info->xmit; if (dport->port.x_char) { /* XON/XOFF chars */ dz_out(dport, DZ_TDR, dport->port.x_char); dport->port.icount.tx++; dport->port.x_char = 0; return; } /* If nothing to do or stopped or hardware stopped. */ if (uart_circ_empty(xmit) || uart_tx_stopped(&dport->port)) { dz_stop_tx(&dport->port); return; } /* * If something to do... (remember the dz has no output fifo, * so we go one char at a time) :-< */ tmp = xmit->buf[xmit->tail]; xmit->tail = (xmit->tail + 1) & (DZ_XMIT_SIZE - 1); dz_out(dport, DZ_TDR, tmp); dport->port.icount.tx++; if (uart_circ_chars_pending(xmit) < DZ_WAKEUP_CHARS) uart_write_wakeup(&dport->port); /* Are we are done. */ if (uart_circ_empty(xmit)) dz_stop_tx(&dport->port); }
static void l4ser_shm_tx_chars(struct uart_port *port) { struct l4ser_shm_uart_port *l4port = (struct l4ser_shm_uart_port *)port; struct circ_buf *xmit = &port->state->xmit; int c, do_trigger = 0; struct tty_struct *tty = port->state->port.tty; tty->hw_stopped = 0; tty->stopped = 0; if (port->x_char) { if (tx_buf(port, &port->x_char, 1)) { port->icount.tx++; port->x_char = 0; L4XV_FN_v(l4shmc_trigger(&l4port->tx_sig)); } return; } if (uart_circ_empty(xmit) || uart_tx_stopped(port)) { return; } while (!uart_circ_empty(xmit)) { unsigned long r; c = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE); if (!(r = tx_buf(port, &xmit->buf[xmit->tail], c))) break; xmit->tail = (xmit->tail + r) & (UART_XMIT_SIZE - 1); port->icount.tx += r; do_trigger = 1; } if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); if (do_trigger) L4XV_FN_v(l4shmc_trigger(&l4port->tx_sig)); }
static void s3c2440_tx_int(int irq, void *dev_id, struct pt_regs *regs) { struct uart_info *info = (struct uart_info*)dev_id; struct uart_port *port = info->port; struct circ_buf *xmit = &info->xmit; int count; if (port->x_char) { UART_PUT_CHAR(port, port->x_char); port->icount.tx++; port->x_char = 0; return; } /* * Check the modem control lines before * transmitting anything. */ if (uart_circ_empty(xmit) || uart_tx_stopped(info)) { s3c2440_stop_tx(port, 0); return; } count = port->fifosize >> 1; do { UART_PUT_CHAR (port, xmit->buf[xmit->tail]); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); port->icount.tx++; if (xmit->head == xmit->tail) break; } while (--count > 0); if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) tasklet_schedule(&info->tlet); if (uart_circ_empty(xmit)) s3c2440_stop_tx(port, 0); }
static irqreturn_t bfin_serial_dma_tx_int(int irq, void *dev_id) { struct bfin_serial_port *uart = dev_id; struct circ_buf *xmit = &uart->port.info->xmit; spin_lock(&uart->port.lock); if (!(get_dma_curr_irqstat(uart->tx_dma_channel)&DMA_RUN)) { disable_dma(uart->tx_dma_channel); clear_dma_irqstat(uart->tx_dma_channel); UART_CLEAR_IER(uart, ETBEI); xmit->tail = (xmit->tail + uart->tx_count) & (UART_XMIT_SIZE - 1); uart->port.icount.tx += uart->tx_count; if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(&uart->port); bfin_serial_dma_tx_chars(uart); } spin_unlock(&uart->port.lock); return IRQ_HANDLED; }
static void transmit_chars(struct am_uart_port *info) { am_uart_t *uart = uart_addr[info->line]; struct uart_port * up = &info->port; unsigned int ch; struct circ_buf *xmit = &up->state->xmit; int count = 256; if (up->x_char) { writel(up->x_char, &uart->wdata); up->x_char = 0; goto clear_and_return; } if (uart_circ_empty(xmit) || uart_tx_stopped(up)) goto clear_and_return; spin_lock(&info->wr_lock); while(!uart_circ_empty(xmit) && count-- > 0) { if((readl(&uart->status) & UART_TXFULL) ==0) { ch = xmit->buf[xmit->tail]; writel(ch, &uart->wdata); xmit->tail = (xmit->tail+1) & (SERIAL_XMIT_SIZE - 1); } else { break; } } spin_unlock(&info->wr_lock); clear_and_return: if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(up); return; }
static void handle_tx(struct uart_port *port) { struct circ_buf *xmit = &port->info->xmit; struct msm_port *msm_port = UART_TO_MSM(port); int sent_tx; if (port->x_char) { msm_write(port, port->x_char, UART_TF); port->icount.tx++; port->x_char = 0; } while (msm_read(port, UART_SR) & UART_SR_TX_READY) { if (uart_circ_empty(xmit)) { /* disable tx interrupts */ msm_port->imr &= ~UART_IMR_TXLEV; msm_write(port, msm_port->imr, UART_IMR); break; } msm_write(port, xmit->buf[xmit->tail], UART_TF); xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); port->icount.tx++; sent_tx = 1; } #ifdef CONFIG_SERIAL_MSM_CLOCK_CONTROL if (sent_tx && msm_port->clk_state == MSM_CLK_REQUEST_OFF) /* new TX - restart the timer */ if (hrtimer_try_to_cancel(&msm_port->clk_off_timer) == 1) hrtimer_start(&msm_port->clk_off_timer, msm_port->clk_off_delay, HRTIMER_MODE_REL); #endif if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); }
/** * cdns_uart_handle_tx - Handle the bytes to be Txed. * @dev_id: Id of the UART port * Return: None */ static void cdns_uart_handle_tx(void *dev_id) { struct uart_port *port = (struct uart_port *)dev_id; unsigned int numbytes; if (uart_circ_empty(&port->state->xmit)) { cdns_uart_writel(CDNS_UART_IXR_TXEMPTY, CDNS_UART_IDR_OFFSET); } else { numbytes = port->fifosize; /* Break if no more data available in the UART buffer */ while (numbytes--) { if (uart_circ_empty(&port->state->xmit)) break; /* * Get the data from the UART circular buffer * and write it to the cdns_uart's TX_FIFO * register. */ cdns_uart_writel( port->state->xmit.buf[port->state->xmit. tail], CDNS_UART_FIFO_OFFSET); port->icount.tx++; /* * Adjust the tail of the UART buffer and wrap * the buffer if it reaches limit. */ port->state->xmit.tail = (port->state->xmit.tail + 1) & (UART_XMIT_SIZE - 1); } if (uart_circ_chars_pending( &port->state->xmit) < WAKEUP_CHARS) uart_write_wakeup(port); } }
/* * Send chars to UART Write FIFO; called by interrupt handler. */ static void handle_transmit(struct tile_uart_port *tile_uart) { unsigned char ch; struct uart_port *port; struct circ_buf *xmit; gxio_uart_context_t *context = &tile_uart->context; /* First reset WFIFO_RE interrupt. */ gxio_uart_write(context, UART_INTERRUPT_STATUS, UART_INTERRUPT_MASK__WFIFO_RE_MASK); port = &tile_uart->uart; xmit = &port->state->xmit; if (port->x_char) { if (tilegx_putchar(context, port->x_char)) return; port->x_char = 0; port->icount.tx++; } if (uart_circ_empty(xmit) || uart_tx_stopped(port)) return; while (!uart_circ_empty(xmit)) { ch = xmit->buf[xmit->tail]; if (tilegx_putchar(context, ch)) break; xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); port->icount.tx++; } /* Reset WFIFO_RE interrupt. */ gxio_uart_write(context, UART_INTERRUPT_STATUS, UART_INTERRUPT_MASK__WFIFO_RE_MASK); if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); }
static void stm32_transmit_chars(struct uart_port *port) { struct stm32_port *stm32_port = to_stm32_port(port); struct stm32_usart_offsets *ofs = &stm32_port->info->ofs; struct circ_buf *xmit = &port->state->xmit; if (port->x_char) { if (stm32_port->tx_dma_busy) stm32_clr_bits(port, ofs->cr3, USART_CR3_DMAT); writel_relaxed(port->x_char, port->membase + ofs->tdr); port->x_char = 0; port->icount.tx++; if (stm32_port->tx_dma_busy) stm32_set_bits(port, ofs->cr3, USART_CR3_DMAT); return; } if (uart_tx_stopped(port)) { stm32_stop_tx(port); return; } if (uart_circ_empty(xmit)) { stm32_stop_tx(port); return; } if (stm32_port->tx_ch) stm32_transmit_chars_dma(port); else stm32_transmit_chars_pio(port); if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) uart_write_wakeup(port); if (uart_circ_empty(xmit)) stm32_stop_tx(port); }