static void timbuart_tx_chars(struct uart_port *port)
{
	struct circ_buf *xmit = &port->state->xmit;

	while (!(ioread32(port->membase + TIMBUART_ISR) & TXBF) &&
		!uart_circ_empty(xmit)) {
		iowrite8(xmit->buf[xmit->tail],
			port->membase + TIMBUART_TXFIFO);
		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
		port->icount.tx++;
	}

	dev_dbg(port->dev,
		"%s - total written %d bytes, CTL: %x, RTS: %x, baud: %x\n",
		 __func__,
		port->icount.tx,
		ioread8(port->membase + TIMBUART_CTRL),
		port->mctrl & TIOCM_RTS,
		ioread8(port->membase + TIMBUART_BAUDRATE));
}
Exemple #2
0
static void fill_tx_fifo(struct tegra_uart_port *t, int max_bytes)
{
	int i;
	struct circ_buf *xmit = &t->uport.state->xmit;
#ifndef CONFIG_ARCH_TEGRA_2x_SOC
	unsigned long lsr;
#endif

	for (i = 0; i < max_bytes; i++) {
		BUG_ON(uart_circ_empty(xmit));
#ifndef CONFIG_ARCH_TEGRA_2x_SOC
		lsr = uart_readl(t, UART_LSR);
		if ((lsr & UART_LSR_TXFIFO_FULL))
			break;
#endif
		uart_writeb(t, xmit->buf[xmit->tail], UART_TX);
		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
		t->uport.icount.tx++;
	}
}
Exemple #3
0
int omap_uart_active(int num, u32 timeout)
{
	struct uart_omap_port *up = ui[num];
	struct circ_buf *xmit;
	unsigned int status;

	/* Though when UART's initialised this can never happen,
	 * but during initialisation, it can happen the "ui"
	 * structure is not initialized and the timer kicks
	 * in. This would result in a NULL value, resulting
	 * in crash.
	 */
	if (up == NULL)
		return 0;

	/* Check for recent driver activity. If time delta from now
	 * to last activty < "uart idle timeout" second keep clocks on.
	 */
	if (((jiffies - up->port_activity) < timeout))
		return 1;

	xmit = &up->port.state->xmit;
	if (!(uart_circ_empty(xmit) || uart_tx_stopped(&up->port)))
		return 1;

	status = serial_in(up, UART_LSR);
	/* TX hardware not empty */
	if (!(status & (UART_LSR_TEMT | UART_LSR_THRE)))
		return 1;

	/* Any rx activity? */
	if (status & UART_LSR_DR)
		return 1;

	/* Check if DMA channels are active */
	if (up->use_dma && (up->uart_dma.rx_dma_channel != OMAP_UART_DMA_CH_FREE ||
		up->uart_dma.tx_dma_channel != OMAP_UART_DMA_CH_FREE))
		return 1;

	return 0;
}
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);
}
Exemple #6
0
static void sc16is7xx_stop_tx(struct uart_port* port)
{
	struct sc16is7xx_one *one = to_sc16is7xx_one(port, port);
	struct circ_buf *xmit = &one->port.state->xmit;

	/* handle rs485 */
	if (one->rs485.flags & SER_RS485_ENABLED) {
		/* do nothing if current tx not yet completed */
		int lsr = sc16is7xx_port_read(port, SC16IS7XX_LSR_REG);
		if (!(lsr & SC16IS7XX_LSR_TEMT_BIT))
			return;

		if (uart_circ_empty(xmit) &&
		    (one->rs485.delay_rts_after_send > 0))
			mdelay(one->rs485.delay_rts_after_send);
	}

	sc16is7xx_port_update(port, SC16IS7XX_IER_REG,
			      SC16IS7XX_IER_THRI_BIT,
			      0);
}
Exemple #7
0
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);

}
Exemple #8
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);
}
static unsigned int
sdp_serial_tx_chars(struct uart_port *port)
{
	struct circ_buf *xmit = &port->info->xmit;
	int count = 0;


        if (port->x_char) {
                UART_PUT_CHAR(port, port->x_char);
                port->icount.tx++;
                port->x_char = 0;
                return 0;
        }

        if (uart_circ_empty(xmit) || uart_tx_stopped(port)){
			sdp_serial_stop_tx(port);
		   	return 0;
		}

		if (port->fifosize > 1)
	   	 	count = (port->fifosize - (((UART_GET_UFSTAT(port) >> 4) & 0xF) + 1));	// avoid to overflow , fifo size
		else
Exemple #10
0
static void sc16is7xx_handle_tx(struct uart_port *port)
{
	struct sc16is7xx_port *s = dev_get_drvdata(port->dev);
	struct circ_buf *xmit = &port->state->xmit;
	unsigned int txlen, to_send, i;

	if (unlikely(port->x_char)) {
		sc16is7xx_port_write(port, SC16IS7XX_THR_REG, port->x_char);
		port->icount.tx++;
		port->x_char = 0;
		return;
	}

	if (uart_circ_empty(xmit) || uart_tx_stopped(port))
		return;

	/* Get length of data pending in circular buffer */
	to_send = uart_circ_chars_pending(xmit);
	if (likely(to_send)) {
		/* Limit to size of TX FIFO */
		txlen = sc16is7xx_port_read(port, SC16IS7XX_TXLVL_REG);
		to_send = (to_send > txlen) ? txlen : to_send;

		/* Add data to send */
		port->icount.tx += to_send;

		/* Convert to linear buffer */
		for (i = 0; i < to_send; ++i) {
			s->buf[i] = xmit->buf[xmit->tail];
			xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
		}
		regcache_cache_bypass(s->regmap, true);
		regmap_raw_write(s->regmap, SC16IS7XX_THR_REG, s->buf, to_send);
		regcache_cache_bypass(s->regmap, false);
	}

	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
		uart_write_wakeup(port);
}
Exemple #11
0
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;
}
Exemple #12
0
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;
}
Exemple #13
0
/**********************************************************************************************************
* Description: 	This function is used to start transfer data.
*
* Arguments  : 	port			is the uart port
*
* Returns    :
**********************************************************************************************************/
void tls_uart_tx_chars_start(struct tls_uart_port *port)
{
    struct tls_uart_circ_buf *xmit = &port->xmit;
    int tx_count;
    u32 cpu_sr;

    /* send some chars */
    tx_count = 32;
    cpu_sr = tls_os_set_critical();
    while (!uart_circ_empty(xmit) && tx_count-- > 0) {
        /* 检查tx fifo是否已满 */
        if ((port->regs->UR_FIFOS & UFS_TX_FIFO_CNT_MASK) ==
                port->tx_fifofull)
            break;

        port->regs->UR_TXW = xmit->buf[xmit->tail];
        xmit->tail = (xmit->tail + 1) & (TLS_UART_TX_BUF_SIZE - 1);
        port->icount.tx++;
    }
    tls_os_release_critical(cpu_sr);
    return;
}
Exemple #14
0
static void am_uart_start_tx(struct uart_port *port)
{
	unsigned int ch;
	struct meson_uart_port * mup = &am_ports[port->line];
	am_uart_t *uart = mup->uart;
	struct uart_port * up = &mup->port;
	struct circ_buf *xmit = &up->state->xmit;
    unsigned long flags;

	spin_lock_irqsave(&mup->wr_lock, flags);
	while(!uart_circ_empty(xmit)){
		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;
	}
	//mutex_unlock(&info->info_mutex);
	spin_unlock_irqrestore(&mup->wr_lock, flags);
}
Exemple #15
0
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);
}
Exemple #16
0
static void uart_tx_dma_callback(int lch, u16 ch_status, void *data)
{
	struct uart_omap_port *up = (struct uart_omap_port *)data;
	struct circ_buf *xmit = &up->port.state->xmit;

	xmit->tail = (xmit->tail + up->uart_dma.tx_buf_size) & \
			(UART_XMIT_SIZE - 1);
	up->port.icount.tx += up->uart_dma.tx_buf_size;

	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
		uart_write_wakeup(&up->port);

	if (uart_circ_empty(xmit)) {
		spin_lock(&(up->uart_dma.tx_lock));
		serial_omap_stop_tx(&up->port);
		up->uart_dma.tx_dma_used = false;
		spin_unlock(&(up->uart_dma.tx_lock));
			if (up->plat_hold_wakelock)
				(up->plat_hold_wakelock(up, WAKELK_TX));
	} else {

#ifdef CONFIG_PM
		/*
		 * This will enable the clock for some reason if the
		 * clocks get disabled. This would enable the ICK also
		 * in case if the Idle state is set and the PRCM modul
		 * just shutdown the ICK because of inactivity.
		 */
		omap_uart_enable_clock_from_irq(up->pdev->id);
#endif

		omap_stop_dma(up->uart_dma.tx_dma_channel);
		serial_omap_continue_tx(up);
	}
	up->port_activity = jiffies;
	return;
}
Exemple #17
0
static inline void send_circ_buf(struct uart_max3110 *max,
				struct circ_buf *xmit)
{
	int len, left = 0;
	u16 obuf[WORDS_PER_XFER], ibuf[WORDS_PER_XFER];
	u8 valid_str[WORDS_PER_XFER];
	int i, j;

	while (!uart_circ_empty(xmit)) {
		left = uart_circ_chars_pending(xmit);
		while (left) {
			len = (left >= WORDS_PER_XFER) ? WORDS_PER_XFER : left;

			memset(obuf, 0, len * 2);
			memset(ibuf, 0, len * 2);
			for (i = 0; i < len; i++) {
				obuf[i] = (u8)xmit->buf[xmit->tail] | WD_TAG;
				xmit->tail = (xmit->tail + 1) &
						(UART_XMIT_SIZE - 1);
			}
			max3110_write_then_read(max, (u8 *)obuf,
						(u8 *)ibuf, len * 2, 0);

			for (i = 0, j = 0; i < len; i++) {
				if (ibuf[i] & MAX3110_READ_DATA_AVAILABLE)
					valid_str[j++] = (u8)(ibuf[i] & 0xff);
			}

			if (j)
				receive_chars(max, valid_str, j);

			max->port.icount.tx += len;
			left -= len;
		}
	}
}
Exemple #18
0
static void fm3_transmit(struct uart_port *port)
{
    struct circ_buf *xmit;
    volatile struct fm3_uart_regs *uart_regs = uart_regs_by_port(port);

    if (port->x_char) {
        fm3_tx_char(uart_regs, port->x_char);
        port->x_char = 0;
        port->icount.tx++;
        return;
    }
    xmit = &port->state->xmit;
    if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
        fm3_port_stop_tx(port);
        return;
    }
    fm3_tx_char(uart_regs, 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);
    return;
}
Exemple #19
0
static void sprd_complete_tx_dma(void *data)
{
	struct uart_port *port = (struct uart_port *)data;
	struct sprd_uart_port *sp =
		container_of(port, struct sprd_uart_port, port);
	struct circ_buf *xmit = &port->state->xmit;
	unsigned long flags;

	spin_lock_irqsave(&port->lock, flags);
	dma_unmap_single(port->dev, sp->tx_dma.phys_addr,
			 sp->tx_dma.trans_len, DMA_TO_DEVICE);

	xmit->tail = (xmit->tail + sp->tx_dma.trans_len) & (UART_XMIT_SIZE - 1);
	port->icount.tx += sp->tx_dma.trans_len;

	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
		uart_write_wakeup(port);

	if (uart_circ_empty(xmit) || sprd_tx_buf_remap(port) ||
	    sprd_tx_dma_config(port))
		sp->tx_dma.trans_len = 0;

	spin_unlock_irqrestore(&port->lock, flags);
}
Exemple #20
0
static unsigned int
sdp_serial_tx_chars(struct uart_port *port)
{
	SDP_UART_REG_T * reg = (SDP_UART_REG_T*) port->membase;
	struct circ_buf *xmit = &port->state->xmit;
//	unsigned long flags;
	int count = 0;

#if defined(CONFIG_SERIAL_SDP_CONSOLE) && defined(SDP_CONSOLE_IRQ)
	SDP_UART_PRIV_T * p_uart_priv;

	if(!DEBUG_PORT(port)) {
		p_uart_priv = (SDP_UART_PRIV_T *) UART_PRIV(port);
		if(p_uart_priv->console) {
			if(sdp_cons_print(port)) {
				return 0;
			}
		}
	}
#endif
//	spin_lock_irqsave(&port->lock, flags);

        if (port->x_char) {
                reg->utxh =  port->x_char;
                port->icount.tx++;
                port->x_char = 0;
                goto __exit_tx_chars;
        }

        if (uart_circ_empty(xmit) || uart_tx_stopped(port)){
               	goto __exit_tx_chars;
	}

	if (port->fifosize > 1)
   	 	count = (port->fifosize - (((reg->ufstat >> 4) & 0xF) + 1));	// avoid to overflow , fifo size
	else
Exemple #21
0
static void genode_serial_tx_chars(struct uart_port *port) {
	struct genode_uart_port *l4port = (struct genode_uart_port *)port;
	struct circ_buf         *xmit   = &port->state->xmit;
	unsigned long            flags;
	unsigned                 c;

	if (port->x_char) {
		local_irq_save(flags);
		genode_terminal_writechar(l4port->idx, &port->x_char, sizeof(char));
		local_irq_restore(flags);
		port->icount.tx++;
		port->x_char = 0;
		return;
	}

	while (!uart_circ_empty(xmit)) {
		c = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
		local_irq_save(flags);
		genode_terminal_writechar(l4port->idx, &xmit->buf[xmit->tail], c);
		local_irq_restore(flags);
		xmit->tail = (xmit->tail + c) & (UART_XMIT_SIZE - 1);
		port->icount.tx += c;
	}
}
static void uart_tx_dma_callback(int lch, u16 ch_status, void *data)
{
	struct uart_omap_port *up = (struct uart_omap_port *)data;
	struct circ_buf *xmit = &up->port.state->xmit;

	xmit->tail = (xmit->tail + up->uart_dma.tx_buf_size) & \
			(UART_XMIT_SIZE - 1);
	up->port.icount.tx += up->uart_dma.tx_buf_size;

	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
		uart_write_wakeup(&up->port);

	if (uart_circ_empty(xmit)) {
		spin_lock(&(up->uart_dma.tx_lock));
		serial_omap_stop_tx(&up->port);
		up->uart_dma.tx_dma_used = false;
		spin_unlock(&(up->uart_dma.tx_lock));
	} else {
		omap_stop_dma(up->uart_dma.tx_dma_channel);
		serial_omap_continue_tx(up);
	}
	up->port_activity = jiffies;
	return;
}
Exemple #23
0
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;
	unsigned long flags;
	int count, dma_count = 0;

	spin_lock_irqsave(&port->lock, flags);

	count = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);

	if (ourport->dma && ourport->dma->tx_chan &&
	    count >= ourport->min_dma_size) {
		int align = dma_get_cache_alignment() -
			(xmit->tail & (dma_get_cache_alignment() - 1));
		if (count-align >= ourport->min_dma_size) {
			dma_count = count-align;
			count = align;
		}
	}

	if (port->x_char) {
		wr_regb(port, S3C2410_UTXH, port->x_char);
		port->icount.tx++;
		port->x_char = 0;
		goto out;
	}

	/* if there isn't 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);
		goto out;
	}

	/* try and drain the buffer... */

	if (count > port->fifosize) {
		count = port->fifosize;
		dma_count = 0;
	}

	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++;
		count--;
	}

	if (!count && dma_count) {
		s3c24xx_serial_start_tx_dma(ourport, dma_count);
		goto out;
	}

	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) {
		spin_unlock(&port->lock);
		uart_write_wakeup(port);
		spin_lock(&port->lock);
	}

	if (uart_circ_empty(xmit))
		s3c24xx_serial_stop_tx(port);

out:
	spin_unlock_irqrestore(&port->lock, flags);
	return IRQ_HANDLED;
}
Exemple #24
0
/*
 * Transmit characters, refill buffer descriptor, if possible
 */
static int cpm_uart_tx_pump(struct uart_port *port)
{
	volatile cbd_t *bdp;
	unsigned char *p;
	int count;
	struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
	struct circ_buf *xmit = &port->info->xmit;

	/* Handle xon/xoff */
	if (port->x_char) {
		/* Pick next descriptor and fill from buffer */
		bdp = pinfo->tx_cur;

		p = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo);

		*p++ = port->x_char;
		bdp->cbd_datlen = 1;
		bdp->cbd_sc |= BD_SC_READY;
		/* Get next BD. */
		if (bdp->cbd_sc & BD_SC_WRAP)
			bdp = pinfo->tx_bd_base;
		else
			bdp++;
		pinfo->tx_cur = bdp;

		port->icount.tx++;
		port->x_char = 0;
		return 1;
	}

	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
		cpm_uart_stop_tx(port);
		return 0;
	}

	/* Pick next descriptor and fill from buffer */
	bdp = pinfo->tx_cur;

	while (!(bdp->cbd_sc & BD_SC_READY) && (xmit->tail != xmit->head)) {
		count = 0;
		p = cpm2cpu_addr(bdp->cbd_bufaddr, pinfo);
		while (count < pinfo->tx_fifosize) {
			*p++ = xmit->buf[xmit->tail];
			xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
			port->icount.tx++;
			count++;
			if (xmit->head == xmit->tail)
				break;
		}
		bdp->cbd_datlen = count;
		bdp->cbd_sc |= BD_SC_READY;
		__asm__("eieio");
		/* Get next BD. */
		if (bdp->cbd_sc & BD_SC_WRAP)
			bdp = pinfo->tx_bd_base;
		else
			bdp++;
	}
	pinfo->tx_cur = bdp;

	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
		uart_write_wakeup(port);

	if (uart_circ_empty(xmit)) {
		cpm_uart_stop_tx(port);
		return 0;
	}

	return 1;
}
Exemple #25
0
static void handle_tx(struct uart_port *port)
{
	struct circ_buf *xmit = &port->state->xmit;
	int sent_tx;
	int tx_count;
	int x;
	unsigned int tf_pointer = 0;

	tx_count = uart_circ_chars_pending(xmit);

	if (tx_count > (UART_XMIT_SIZE - xmit->tail))
		tx_count = UART_XMIT_SIZE - xmit->tail;
	if (tx_count >= port->fifosize)
		tx_count = port->fifosize;

	/* Handle x_char */
	if (port->x_char) {
		wait_for_xmitr(port, UARTDM_ISR_TX_READY_BMSK);
		msm_hsl_write(port, tx_count + 1, UARTDM_NCF_TX_ADDR);
		msm_hsl_write(port, port->x_char, UARTDM_TF_ADDR);
		port->icount.tx++;
		port->x_char = 0;
	} else if (tx_count) {
		wait_for_xmitr(port, UARTDM_ISR_TX_READY_BMSK);
		msm_hsl_write(port, tx_count, UARTDM_NCF_TX_ADDR);
	}
	if (!tx_count) {
		msm_hsl_stop_tx(port);
		return;
	}

#ifdef FELICA_DEBUG
    if (port->line == 3) pr_info("%s: count=%d\n", __func__, tx_count);
#endif
	while (tf_pointer < tx_count)  {
		if (unlikely(!(msm_hsl_read(port, UARTDM_SR_ADDR) &
			       UARTDM_SR_TXRDY_BMSK)))
			continue;
		switch (tx_count - tf_pointer) {
		case 1: {
			x = xmit->buf[xmit->tail];
			port->icount.tx++;
			break;
		}
		case 2: {
			x = xmit->buf[xmit->tail]
				| xmit->buf[xmit->tail+1] << 8;
			port->icount.tx += 2;
			break;
		}
		case 3: {
			x = xmit->buf[xmit->tail]
				| xmit->buf[xmit->tail+1] << 8
				| xmit->buf[xmit->tail + 2] << 16;
			port->icount.tx += 3;
			break;
		}
		default: {
			x = *((int *)&(xmit->buf[xmit->tail]));
			port->icount.tx += 4;
			break;
		}
		}
#ifdef FELICA_DEBUG
        if (port->line == 3) pr_info("%s: 0x%08X\n", __func__, x);
#endif
		msm_hsl_write(port, x, UARTDM_TF_ADDR);
		xmit->tail = ((tx_count - tf_pointer < 4) ?
			      (tx_count - tf_pointer + xmit->tail) :
			      (xmit->tail + 4)) & (UART_XMIT_SIZE - 1);
		tf_pointer += 4;
		sent_tx = 1;
	}

	if (uart_circ_empty(xmit))
		msm_hsl_stop_tx(port);

	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
		uart_write_wakeup(port);

}
Exemple #26
0
/**
 * xuartps_isr - Interrupt handler
 * @irq: Irq number
 * @dev_id: Id of the port
 *
 * Returns IRQHANDLED
 **/
static irqreturn_t xuartps_isr(int irq, void *dev_id)
{
    struct uart_port *port = (struct uart_port *)dev_id;
    unsigned long flags;
    unsigned int isrstatus, numbytes;
    unsigned int data;
    char status = TTY_NORMAL;

    spin_lock_irqsave(&port->lock, flags);

    /* Read the interrupt status register to determine which
     * interrupt(s) is/are active.
     */
    isrstatus = xuartps_readl(XUARTPS_ISR_OFFSET);

    /* drop byte with parity error if IGNPAR specified */
    if (isrstatus & port->ignore_status_mask & XUARTPS_IXR_PARITY)
        isrstatus &= ~(XUARTPS_IXR_RXTRIG | XUARTPS_IXR_TOUT);

    isrstatus &= port->read_status_mask;
    isrstatus &= ~port->ignore_status_mask;

    if ((isrstatus & XUARTPS_IXR_TOUT) ||
            (isrstatus & XUARTPS_IXR_RXTRIG)) {
        /* Receive Timeout Interrupt */
        while ((xuartps_readl(XUARTPS_SR_OFFSET) &
                XUARTPS_SR_RXEMPTY) != XUARTPS_SR_RXEMPTY) {
            data = xuartps_readl(XUARTPS_FIFO_OFFSET);
            port->icount.rx++;

            if (isrstatus & XUARTPS_IXR_PARITY) {
                port->icount.parity++;
                status = TTY_PARITY;
            } else if (isrstatus & XUARTPS_IXR_FRAMING) {
                port->icount.frame++;
                status = TTY_FRAME;
            } else if (isrstatus & XUARTPS_IXR_OVERRUN)
                port->icount.overrun++;

            uart_insert_char(port, isrstatus, XUARTPS_IXR_OVERRUN,
                             data, status);
        }
        spin_unlock(&port->lock);
        tty_flip_buffer_push(&port->state->port);
        spin_lock(&port->lock);
    }

    /* Dispatch an appropriate handler */
    if ((isrstatus & XUARTPS_IXR_TXEMPTY) == XUARTPS_IXR_TXEMPTY) {
        if (uart_circ_empty(&port->state->xmit)) {
            xuartps_writel(XUARTPS_IXR_TXEMPTY,
                           XUARTPS_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 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);
            }

            if (uart_circ_chars_pending(
                        &port->state->xmit) < WAKEUP_CHARS)
                uart_write_wakeup(port);
        }
    }

    xuartps_writel(isrstatus, XUARTPS_ISR_OFFSET);

    /* be sure to release the lock and tty before leaving */
    spin_unlock_irqrestore(&port->lock, flags);

    return IRQ_HANDLED;
}
Exemple #27
0
/*
 * Transmit characters, refill buffer descriptor, if possible
 */
static int cpm_uart_tx_pump(struct uart_port *port)
{
	cbd_t __iomem *bdp;
	u8 *p;
	int count;
	struct uart_cpm_port *pinfo = (struct uart_cpm_port *)port;
	struct circ_buf *xmit = &port->info->xmit;

	/* Handle xon/xoff */
	if (port->x_char) {
		/* Pick next descriptor and fill from buffer */
		bdp = pinfo->tx_cur;

		p = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo);

		*p++ = port->x_char;

		out_be16(&bdp->cbd_datlen, 1);
		setbits16(&bdp->cbd_sc, BD_SC_READY);
		/* Get next BD. */
		if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP)
			bdp = pinfo->tx_bd_base;
		else
			bdp++;
		pinfo->tx_cur = bdp;

		port->icount.tx++;
		port->x_char = 0;
		return 1;
	}

	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
		cpm_uart_stop_tx(port);
		return 0;
	}

	/* Pick next descriptor and fill from buffer */
	bdp = pinfo->tx_cur;

	while (!(in_be16(&bdp->cbd_sc) & BD_SC_READY) &&
	       xmit->tail != xmit->head) {
		count = 0;
		p = cpm2cpu_addr(in_be32(&bdp->cbd_bufaddr), pinfo);
		while (count < pinfo->tx_fifosize) {
			*p++ = xmit->buf[xmit->tail];
			xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
			port->icount.tx++;
			count++;
			if (xmit->head == xmit->tail)
				break;
		}
		out_be16(&bdp->cbd_datlen, count);
		setbits16(&bdp->cbd_sc, BD_SC_READY);
		/* Get next BD. */
		if (in_be16(&bdp->cbd_sc) & BD_SC_WRAP)
			bdp = pinfo->tx_bd_base;
		else
			bdp++;
	}
	pinfo->tx_cur = bdp;

	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
		uart_write_wakeup(port);

	if (uart_circ_empty(xmit)) {
		cpm_uart_stop_tx(port);
		return 0;
	}

	return 1;
}
static void ip22zilog_transmit_chars(struct uart_ip22zilog_port *up,
				    struct zilog_channel *channel)
{
	struct circ_buf *xmit;

	if (ZS_IS_CONS(up)) {
		unsigned char status = readb(&channel->control);
		ZSDELAY();

		/* TX still busy?  Just wait for the next TX done interrupt.
		 *
		 * It can occur because of how we do serial console writes.  It would
		 * be nice to transmit console writes just like we normally would for
		 * a TTY line. (ie. buffered and TX interrupt driven).  That is not
		 * easy because console writes cannot sleep.  One solution might be
		 * to poll on enough port->xmit space becoming free.  -DaveM
		 */
		if (!(status & Tx_BUF_EMP))
			return;
	}

	up->flags &= ~IP22ZILOG_FLAG_TX_ACTIVE;

	if (ZS_REGS_HELD(up)) {
		__load_zsregs(channel, up->curregs);
		up->flags &= ~IP22ZILOG_FLAG_REGS_HELD;
	}

	if (ZS_TX_STOPPED(up)) {
		up->flags &= ~IP22ZILOG_FLAG_TX_STOPPED;
		goto ack_tx_int;
	}

	if (up->port.x_char) {
		up->flags |= IP22ZILOG_FLAG_TX_ACTIVE;
		writeb(up->port.x_char, &channel->data);
		ZSDELAY();
		ZS_WSYNC(channel);

		up->port.icount.tx++;
		up->port.x_char = 0;
		return;
	}

	if (up->port.state == NULL)
		goto ack_tx_int;
	xmit = &up->port.state->xmit;
	if (uart_circ_empty(xmit))
		goto ack_tx_int;
	if (uart_tx_stopped(&up->port))
		goto ack_tx_int;

	up->flags |= IP22ZILOG_FLAG_TX_ACTIVE;
	writeb(xmit->buf[xmit->tail], &channel->data);
	ZSDELAY();
	ZS_WSYNC(channel);

	xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
	up->port.icount.tx++;

	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
		uart_write_wakeup(&up->port);

	return;

ack_tx_int:
	writeb(RES_Tx_P, &channel->control);
	ZSDELAY();
	ZS_WSYNC(channel);
}
Exemple #29
0
static void
transmit_chars_no_dma(struct uart_cris_port *up)
{
	int max_count;
	struct circ_buf *xmit = &up->port.state->xmit;

	void __iomem *regi_ser = up->regi_ser;
	reg_ser_r_stat_din rstat;
	reg_ser_rw_ack_intr ack_intr = { .tr_rdy = regk_ser_yes };

	if (uart_circ_empty(xmit) || uart_tx_stopped(&up->port)) {
		/* No more to send, so disable the interrupt. */
		reg_ser_rw_intr_mask intr_mask;

		intr_mask = REG_RD(ser, regi_ser, rw_intr_mask);
		intr_mask.tr_rdy = 0;
		intr_mask.tr_empty = 0;
		REG_WR(ser, regi_ser, rw_intr_mask, intr_mask);
		up->write_ongoing = 0;
		return;
	}

	/* If the serport is fast, we send up to max_count bytes before
	   exiting the loop.  */
	max_count = 64;
	do {
		reg_ser_rw_dout dout = { .data = xmit->buf[xmit->tail] };

		REG_WR(ser, regi_ser, rw_dout, dout);
		REG_WR(ser, regi_ser, rw_ack_intr, ack_intr);
		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE-1);
		up->port.icount.tx++;
		if (xmit->head == xmit->tail)
			break;
		rstat = REG_RD(ser, regi_ser, r_stat_din);
	} while ((--max_count > 0) && rstat.tr_rdy);

	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
		uart_write_wakeup(&up->port);
}

static void receive_chars_no_dma(struct uart_cris_port *up)
{
	reg_ser_rs_stat_din stat_din;
	reg_ser_r_stat_din rstat;
	struct tty_port *port;
	struct uart_icount *icount;
	int max_count = 16;
	char flag;
	reg_ser_rw_ack_intr ack_intr = { 0 };

	rstat = REG_RD(ser, up->regi_ser, r_stat_din);
	icount = &up->port.icount;
	port = &up->port.state->port;

	do {
		stat_din = REG_RD(ser, up->regi_ser, rs_stat_din);

		flag = TTY_NORMAL;
		ack_intr.dav = 1;
		REG_WR(ser, up->regi_ser, rw_ack_intr, ack_intr);
		icount->rx++;

		if (stat_din.framing_err | stat_din.par_err | stat_din.orun) {
			if (stat_din.data == 0x00 &&
			    stat_din.framing_err) {
				/* Most likely a break. */
				flag = TTY_BREAK;
				icount->brk++;
			} else if (stat_din.par_err) {
				flag = TTY_PARITY;
				icount->parity++;
			} else if (stat_din.orun) {
				flag = TTY_OVERRUN;
				icount->overrun++;
			} else if (stat_din.framing_err) {
				flag = TTY_FRAME;
				icount->frame++;
			}
		}

		/*
		 * If this becomes important, we probably *could* handle this
		 * gracefully by keeping track of the unhandled character.
		 */
		if (!tty_insert_flip_char(port, stat_din.data, flag))
			panic("%s: No tty buffer space", __func__);
		rstat = REG_RD(ser, up->regi_ser, r_stat_din);
	} while (rstat.dav && (max_count-- > 0));
	spin_unlock(&up->port.lock);
	tty_flip_buffer_push(port);
	spin_lock(&up->port.lock);
}
Exemple #30
0
static void pmz_transmit_chars(struct uart_pmac_port *uap)
{
	struct circ_buf *xmit;

	if (ZS_IS_ASLEEP(uap))
		return;
	if (ZS_IS_CONS(uap)) {
		unsigned char status = read_zsreg(uap, R0);

		/* TX still busy?  Just wait for the next TX done interrupt.
		 *
		 * It can occur because of how we do serial console writes.  It would
		 * be nice to transmit console writes just like we normally would for
		 * a TTY line. (ie. buffered and TX interrupt driven).  That is not
		 * easy because console writes cannot sleep.  One solution might be
		 * to poll on enough port->xmit space becomming free.  -DaveM
		 */
		if (!(status & Tx_BUF_EMP))
			return;
	}

	uap->flags &= ~PMACZILOG_FLAG_TX_ACTIVE;

	if (ZS_REGS_HELD(uap)) {
		pmz_load_zsregs(uap, uap->curregs);
		uap->flags &= ~PMACZILOG_FLAG_REGS_HELD;
	}

	if (ZS_TX_STOPPED(uap)) {
		uap->flags &= ~PMACZILOG_FLAG_TX_STOPPED;
		goto ack_tx_int;
	}

	if (uap->port.x_char) {
		uap->flags |= PMACZILOG_FLAG_TX_ACTIVE;
		write_zsdata(uap, uap->port.x_char);
		zssync(uap);
		uap->port.icount.tx++;
		uap->port.x_char = 0;
		return;
	}

	if (uap->port.info == NULL)
		goto ack_tx_int;
	xmit = &uap->port.info->xmit;
	if (uart_circ_empty(xmit)) {
		uart_write_wakeup(&uap->port);
		goto ack_tx_int;
	}
	if (uart_tx_stopped(&uap->port))
		goto ack_tx_int;

	uap->flags |= PMACZILOG_FLAG_TX_ACTIVE;
	write_zsdata(uap, xmit->buf[xmit->tail]);
	zssync(uap);

	xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
	uap->port.icount.tx++;

	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
		uart_write_wakeup(&uap->port);

	return;

ack_tx_int:
	write_zsreg(uap, R0, RES_Tx_P);
	zssync(uap);
}