Example #1
0
static int s3c2410_serial_getsource(struct uart_port *port,
                    struct s3c24xx_uart_clksrc *clk)
{
    unsigned long ucon = rd_regl(port, S3C2410_UCON);

    clk->divisor = 1;
    clk->name = (ucon & S3C2410_UCON_UCLK) ? "uclk" : "pclk";

    return 0;
}
Example #2
0
static void sirfsoc_uart_console_putchar(struct uart_port *port, int ch)
{
	struct sirfsoc_uart_port *sirfport = to_sirfport(port);
	struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg;
	struct sirfsoc_fifo_status *ufifo_st = &sirfport->uart_reg->fifo_status;
	while (rd_regl(port, ureg->sirfsoc_tx_fifo_status) &
		ufifo_st->ff_full(port))
		cpu_relax();
	wr_regl(port, ureg->sirfsoc_tx_fifo_data, ch);
}
/* getchar routine in polling mode. Added to support KGDB */
static int s3c24xx_serial_getchar(struct uart_port *port)
{
	unsigned long ufstat, utrstat;
	unsigned int ufcon = rd_regl(port, S3C2410_UFCON);

	if (ufcon & S3C2410_UFCON_FIFOMODE) {
		/* fifo mode - check ammount of data in fifo registers... */
		do {
			ufstat = rd_regl(port, S3C2410_UFSTAT);
		} while (!(ufstat & S3C2410_UFSTAT_RXMASK));
		/* blocked until there is data in the fifo */
	} else {
		/* non fifo mode - check just the rx buffer register */
		do {
			utrstat = rd_regl(port, S3C2410_UTRSTAT);
		} while (!(utrstat & S3C2410_UTRSTAT_RXDR));
		/* blocked until there is data in the RX register */
	}
	return (rd_regb(port, S3C2410_URXH));
}
Example #4
0
static void s3c24xx_serial_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
	unsigned int umcon = rd_regl(port, S3C2410_UMCON);

	if (mctrl & TIOCM_RTS)
		umcon |= S3C2410_UMCOM_RTS_LOW;
	else
		umcon &= ~S3C2410_UMCOM_RTS_LOW;

	wr_regl(port, S3C2410_UMCON, umcon);
}
Example #5
0
static void sirfsoc_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
	struct sirfsoc_uart_port *sirfport = to_sirfport(port);
	struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg;
	unsigned int assert = mctrl & TIOCM_RTS;
	unsigned int val = assert ? SIRFUART_AFC_CTRL_RX_THD : 0x0;
	unsigned int current_val;

	if (mctrl & TIOCM_LOOP) {
		if (sirfport->uart_reg->uart_type == SIRF_REAL_UART)
			wr_regl(port, ureg->sirfsoc_line_ctrl,
				rd_regl(port, ureg->sirfsoc_line_ctrl) |
				SIRFUART_LOOP_BACK);
		else
			wr_regl(port, ureg->sirfsoc_mode1,
				rd_regl(port, ureg->sirfsoc_mode1) |
				SIRFSOC_USP_LOOP_BACK_CTRL);
	} else {
		if (sirfport->uart_reg->uart_type == SIRF_REAL_UART)
			wr_regl(port, ureg->sirfsoc_line_ctrl,
				rd_regl(port, ureg->sirfsoc_line_ctrl) &
				~SIRFUART_LOOP_BACK);
		else
			wr_regl(port, ureg->sirfsoc_mode1,
				rd_regl(port, ureg->sirfsoc_mode1) &
				~SIRFSOC_USP_LOOP_BACK_CTRL);
	}

	if (!sirfport->hw_flow_ctrl || !sirfport->ms_enabled)
		return;
	if (sirfport->uart_reg->uart_type == SIRF_REAL_UART) {
		current_val = rd_regl(port, ureg->sirfsoc_afc_ctrl) & ~0xFF;
		val |= current_val;
		wr_regl(port, ureg->sirfsoc_afc_ctrl, val);
	} else {
		if (!val)
			gpio_set_value(sirfport->rts_gpio, 1);
		else
			gpio_set_value(sirfport->rts_gpio, 0);
	}
}
Example #6
0
static unsigned int imapx200_serial_tx_empty(struct uart_port *port)
{
	struct imapx200_uart_info *info = imapx200_port_to_info(port);
	unsigned long usr, iir;
	int ret = 0;

	iir = rd_regl(port, IMAPX200_IIR);
	if ((iir & IMAPX200_IIR_FIFOSE_MASK) == IMAPX200_IIR_FIFOSE_ENABLE)
	{
		/* fifo mode - check ammount of data in fifo registers... */
		usr = rd_regl(port, IMAPX200_USR);
		ret = (usr & info->tx_fifoempty) ? 1 : 0;
	}
	else
	{
		/* in non-fifo mode, we go and use the tx buffer empty */
		ret = imapx200_serial_txempty_nofifo(port);
	}
	
	return ret;
}
Example #7
0
/* submit rx dma task into dmaengine */
static void sirfsoc_uart_start_next_rx_dma(struct uart_port *port)
{
	struct sirfsoc_uart_port *sirfport = to_sirfport(port);
	struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg;
	struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en;
	int i;
	sirfport->rx_io_count = 0;
	wr_regl(port, ureg->sirfsoc_rx_dma_io_ctrl,
		rd_regl(port, ureg->sirfsoc_rx_dma_io_ctrl) &
		~SIRFUART_IO_MODE);
	for (i = 0; i < SIRFSOC_RX_LOOP_BUF_CNT; i++)
		sirfsoc_rx_submit_one_dma_desc(port, i);
	sirfport->rx_completed = sirfport->rx_issued = 0;
	if (!sirfport->is_atlas7)
		wr_regl(port, ureg->sirfsoc_int_en_reg,
				rd_regl(port, ureg->sirfsoc_int_en_reg) |
				SIRFUART_RX_DMA_INT_EN(port, uint_en));
	else
		wr_regl(port, ureg->sirfsoc_int_en_reg,
			SIRFUART_RX_DMA_INT_EN(port, uint_en));
}
Example #8
0
static void sirfsoc_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
	struct sirfsoc_uart_port *sirfport = to_sirfport(port);
	unsigned int assert = mctrl & TIOCM_RTS;
	unsigned int val = assert ? SIRFUART_AFC_CTRL_RX_THD : 0x0;
	unsigned int current_val;
	if (sirfport->hw_flow_ctrl) {
		current_val = rd_regl(port, SIRFUART_AFC_CTRL) & ~0xFF;
		val |= current_val;
		wr_regl(port, SIRFUART_AFC_CTRL, val);
	}
}
Example #9
0
static unsigned int
sirfsoc_uart_pio_rx_chars(struct uart_port *port, unsigned int max_rx_count)
{
	unsigned int ch, rx_count = 0;

	while (!(rd_regl(port, SIRFUART_RX_FIFO_STATUS) &
					SIRFUART_FIFOEMPTY_MASK(port))) {
		ch = rd_regl(port, SIRFUART_RX_FIFO_DATA) | SIRFUART_DUMMY_READ;
		if (unlikely(uart_handle_sysrq_char(port, ch)))
			continue;
		uart_insert_char(port, 0, 0, ch, TTY_NORMAL);
		rx_count++;
		if (rx_count >= max_rx_count)
			break;
	}

	port->icount.rx += rx_count;
	tty_flip_buffer_push(&port->state->port);

	return rx_count;
}
Example #10
0
static void sirfsoc_uart_break_ctl(struct uart_port *port, int break_state)
{
	struct sirfsoc_uart_port *sirfport = to_sirfport(port);
	struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg;
	if (sirfport->uart_reg->uart_type == SIRF_REAL_UART) {
		unsigned long ulcon = rd_regl(port, ureg->sirfsoc_line_ctrl);
		if (break_state)
			ulcon |= SIRFUART_SET_BREAK;
		else
			ulcon &= ~SIRFUART_SET_BREAK;
		wr_regl(port, ureg->sirfsoc_line_ctrl, ulcon);
	}
}
Example #11
0
static void sirfsoc_uart_disable_ms(struct uart_port *port)
{
	struct sirfsoc_uart_port *sirfport = to_sirfport(port);
	struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg;
	struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en;

	if (!sirfport->hw_flow_ctrl)
		return;
	sirfport->ms_enabled = false;
	if (sirfport->uart_reg->uart_type == SIRF_REAL_UART) {
		wr_regl(port, ureg->sirfsoc_afc_ctrl,
				rd_regl(port, ureg->sirfsoc_afc_ctrl) & ~0x3FF);
		if (!sirfport->is_atlas7)
			wr_regl(port, ureg->sirfsoc_int_en_reg,
					rd_regl(port, ureg->sirfsoc_int_en_reg)&
					~uint_en->sirfsoc_cts_en);
		else
			wr_regl(port, SIRFUART_INT_EN_CLR,
					uint_en->sirfsoc_cts_en);
	} else
		disable_irq(gpio_to_irq(sirfport->cts_gpio));
}
Example #12
0
static int s3c2410_serial_setsource(struct uart_port *port,
				    struct s3c24xx_uart_clksrc *clk)
{
	unsigned long ucon = rd_regl(port, S3C2410_UCON);

	if (strcmp(clk->name, "uclk") == 0)
		ucon |= S3C2410_UCON_UCLK;
	else
		ucon &= ~S3C2410_UCON_UCLK;

	wr_regl(port, S3C2410_UCON, ucon);
	return 0;
}
Example #13
0
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);
}
Example #14
0
static void sirfsoc_uart_start_tx(struct uart_port *port)
{
	struct sirfsoc_uart_port *sirfport = to_sirfport(port);
	struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg;
	struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en;
	if (sirfport->tx_dma_chan)
		sirfsoc_uart_tx_with_dma(sirfport);
	else {
		if (sirfport->uart_reg->uart_type == SIRF_USP_UART)
			wr_regl(port, ureg->sirfsoc_tx_rx_en, rd_regl(port,
				ureg->sirfsoc_tx_rx_en) | SIRFUART_TX_EN);
		wr_regl(port, ureg->sirfsoc_tx_fifo_op, SIRFUART_FIFO_STOP);
		sirfsoc_uart_pio_tx_chars(sirfport, port->fifosize);
		wr_regl(port, ureg->sirfsoc_tx_fifo_op, SIRFUART_FIFO_START);
		if (!sirfport->is_atlas7)
			wr_regl(port, ureg->sirfsoc_int_en_reg,
					rd_regl(port, ureg->sirfsoc_int_en_reg)|
					uint_en->sirfsoc_txfifo_empty_en);
		else
			wr_regl(port, ureg->sirfsoc_int_en_reg,
					uint_en->sirfsoc_txfifo_empty_en);
	}
}
Example #15
0
static void sirfsoc_uart_enable_ms(struct uart_port *port)
{
	struct sirfsoc_uart_port *sirfport = to_sirfport(port);
	struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg;
	struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en;

	if (!sirfport->hw_flow_ctrl)
		return;
	sirfport->ms_enabled = true;
	if (sirfport->uart_reg->uart_type == SIRF_REAL_UART) {
		wr_regl(port, ureg->sirfsoc_afc_ctrl,
				rd_regl(port, ureg->sirfsoc_afc_ctrl) |
				SIRFUART_AFC_TX_EN | SIRFUART_AFC_RX_EN);
		if (!sirfport->is_atlas7)
			wr_regl(port, ureg->sirfsoc_int_en_reg,
					rd_regl(port, ureg->sirfsoc_int_en_reg)
					| uint_en->sirfsoc_cts_en);
		else
			wr_regl(port, ureg->sirfsoc_int_en_reg,
					uint_en->sirfsoc_cts_en);
	} else
		enable_irq(gpio_to_irq(sirfport->cts_gpio));
}
Example #16
0
static void s3c24xx_serial_set_mctrl(struct uart_port *port, unsigned int mctrl)
{
	/* todo - possibly remove AFC and do manual CTS */
	if(port->line == 0){
        unsigned int umcon = 0;
	umcon = rd_regl(port, S3C2410_UMCON);
	if (mctrl & TIOCM_RTS)
		umcon |= S3C2410_UMCOM_AFC;
	else
		umcon &= ~S3C2410_UMCOM_AFC;

	wr_regl(port, S3C2410_UMCON, umcon);
        }
}
Example #17
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);
}
Example #18
0
static irqreturn_t
s3c_serial_interrupt(int irq, void *dev_id)
{
        struct s3c_uart_port *ourport = dev_id;
        struct uart_port *port = &ourport->port;
        uint intpnd;

	intpnd = rd_regl(port, S3C_UINTPND);

        if (intpnd & UART_RX_INT) {
		wr_regl(port, S3C_UINTPND, UART_RX_INT);
		rd_regl(port, S3C_UINTPND); /*clearing the interrupt*/

		return s3c_serial_rx_chars( irq, dev_id);
        }
        else if (intpnd & UART_TX_INT) {
		wr_regl(port, S3C_UINTPND, UART_TX_INT);
		rd_regl(port, S3C_UINTPND); /*clearing the interrupt*/
		return s3c_serial_tx_chars(irq, dev_id);
        }
        else if (intpnd & UART_ERR_INT) {
		printk("UART err int.\n");
		wr_regl(port, S3C_UINTPND, UART_ERR_INT);
		rd_regl(port, S3C_UINTPND); /*clearing the interrupt*/
		return IRQ_HANDLED;
        }
        else if (intpnd & UART_MODEM_INT) {
		printk("In Modem ... other case\n");
		wr_regl(port, S3C_UINTPND, UART_MODEM_INT);
		rd_regl(port, S3C_UINTPND); /*clearing the interrupt*/
		return IRQ_HANDLED;
	}
	// work around h/w problem : interrupt status bit update delay
	//return IRQ_NONE;
	return IRQ_HANDLED;

}
Example #19
0
static int s5pv210_serial_resetport(struct uart_port *port,
					struct s3c2410_uartcfg *cfg)
{
	unsigned long ucon = rd_regl(port, S3C2410_UCON);

	ucon &= S5PV210_UCON_CLKMASK;
	wr_regl(port, S3C2410_UCON,  ucon | cfg->ucon);
	wr_regl(port, S3C2410_ULCON, cfg->ulcon);

	/* reset both fifos */
	wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
	wr_regl(port, S3C2410_UFCON, cfg->ufcon);

	return 0;
}
Example #20
0
/* interrupt handler for s3c64xx and later SoC's.*/
static irqreturn_t s3c64xx_serial_handle_irq(int irq, void *id)
{
	struct s3c24xx_uart_port *ourport = id;
	struct uart_port *port = &ourport->port;
	unsigned int pend = rd_regl(port, S3C64XX_UINTP);
	irqreturn_t ret = IRQ_HANDLED;

	if (pend & S3C64XX_UINTM_RXD_MSK) {
		ret = s3c24xx_serial_rx_chars(irq, id);
		wr_regl(port, S3C64XX_UINTP, S3C64XX_UINTM_RXD_MSK);
	}
	if (pend & S3C64XX_UINTM_TXD_MSK) {
		ret = s3c24xx_serial_tx_chars(irq, id);
		wr_regl(port, S3C64XX_UINTP, S3C64XX_UINTM_TXD_MSK);
	}
	return ret;
}
Example #21
0
static int s5pv210_serial_setsource(struct uart_port *port,
					struct s3c24xx_uart_clksrc *clk)
{
	unsigned long ucon = rd_regl(port, S3C2410_UCON);

	if (strcmp(clk->name, "pclk") == 0)
		ucon &= ~S5PV210_UCON_CLKMASK;
	else if (strcmp(clk->name, "uclk1") == 0)
		ucon |= S5PV210_UCON_CLKMASK;
	else {
		printk(KERN_ERR "unknown clock source %s\n", clk->name);
		return -EINVAL;
	}

	wr_regl(port, S3C2410_UCON, ucon);
	return 0;
}
Example #22
0
static unsigned int sirfsoc_uart_get_mctrl(struct uart_port *port)
{
	struct sirfsoc_uart_port *sirfport = to_sirfport(port);
	if (!(sirfport->ms_enabled)) {
		goto cts_asserted;
	} else if (sirfport->hw_flow_ctrl) {
		if (!(rd_regl(port, SIRFUART_AFC_CTRL) &
						SIRFUART_CTS_IN_STATUS))
			goto cts_asserted;
		else
			goto cts_deasserted;
	}
cts_deasserted:
	return TIOCM_CAR | TIOCM_DSR;
cts_asserted:
	return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
}
Example #23
0
static void s3c24xx_serial_break_ctl(struct uart_port *port, int break_state)
{
	unsigned long flags;
	unsigned int ucon;

	spin_lock_irqsave(&port->lock, flags);

	ucon = rd_regl(port, S3C2410_UCON);

	if (break_state)
		ucon |= S3C2410_UCON_SBREAK;
	else
		ucon &= ~S3C2410_UCON_SBREAK;

	wr_regl(port, S3C2410_UCON, ucon);

	spin_unlock_irqrestore(&port->lock, flags);
}
Example #24
0
static int s5pv210_serial_getsource(struct uart_port *port,
					struct s3c24xx_uart_clksrc *clk)
{
	u32 ucon = rd_regl(port, S3C2410_UCON);

	clk->divisor = 1;

	switch (ucon & S5PV210_UCON_CLKMASK) {
	case S5PV210_UCON_PCLK:
		clk->name = "pclk";
		break;
	case S5PV210_UCON_UCLK:
		clk->name = "uclk1";
		break;
	}

	return 0;
}
Example #25
0
static void imapx200_serial_break_ctl(struct uart_port *port, int break_state)
{
	unsigned long flags;
	unsigned int lcr;

	spin_lock_irqsave(&port->lock, flags);

	lcr = rd_regl(port, IMAPX200_LCR);

	if (break_state)
		lcr |= IMAPX200_LCR_Break_ENABLE;
	else
		lcr &= ~IMAPX200_LCR_Break_ENABLE;

	wr_regl(port, IMAPX200_LCR, lcr);

	spin_unlock_irqrestore(&port->lock, flags);
}
Example #26
0
static irqreturn_t s3c_serial_tx_chars(int irq, void *id)
{
	struct s3c_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, S3C_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)) {
		s3c_serial_stop_tx(port);
		goto out;
	}

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

	while (!uart_circ_empty(xmit) && count-- > 0) {
		if (rd_regl(port, S3C_UFSTAT) & ourport->info->tx_fifofull)
			break;

		wr_regb(port, S3C_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))
		s3c_serial_stop_tx(port);

 out:
	wake_lock_timeout(&uart_wakelock, HZ / 2);
	return IRQ_HANDLED;
}
Example #27
0
static void enable_rx_pio(struct s3c24xx_uart_port *ourport)
{
	struct uart_port *port = &ourport->port;
	unsigned int ucon;

	/* set Rx mode to DMA mode */
	ucon = rd_regl(port, S3C2410_UCON);
	ucon &= ~(S3C64XX_UCON_TIMEOUT_MASK |
			S3C64XX_UCON_EMPTYINT_EN |
			S3C64XX_UCON_DMASUS_EN |
			S3C64XX_UCON_TIMEOUT_EN |
			S3C64XX_UCON_RXMODE_MASK);
	ucon |= 0xf << S3C64XX_UCON_TIMEOUT_SHIFT |
			S3C64XX_UCON_TIMEOUT_EN |
			S3C64XX_UCON_RXMODE_CPU;
	wr_regl(port, S3C2410_UCON, ucon);

	ourport->rx_mode = S3C24XX_RX_PIO;
}
static void sirfsoc_uart_start_tx(struct uart_port *port)
{
	struct sirfsoc_uart_port *sirfport = to_sirfport(port);
	struct sirfsoc_register *ureg = &sirfport->uart_reg->uart_reg;
	struct sirfsoc_int_en *uint_en = &sirfport->uart_reg->uart_int_en;
	if (IS_DMA_CHAN_VALID(sirfport->tx_dma_no))
		sirfsoc_uart_tx_with_dma(sirfport);
	else {
		sirfsoc_uart_pio_tx_chars(sirfport, 1);
		wr_regl(port, ureg->sirfsoc_tx_fifo_op, SIRFUART_FIFO_START);
		if (!sirfport->is_marco)
			wr_regl(port, ureg->sirfsoc_int_en_reg,
					rd_regl(port, ureg->sirfsoc_int_en_reg)|
					uint_en->sirfsoc_txfifo_empty_en);
		else
			wr_regl(port, ureg->sirfsoc_int_en_reg,
					uint_en->sirfsoc_txfifo_empty_en);
	}
}
Example #29
0
static unsigned int
sirfsoc_uart_pio_tx_chars(struct sirfsoc_uart_port *sirfport, int count)
{
	struct uart_port *port = &sirfport->port;
	struct circ_buf *xmit = &port->state->xmit;
	unsigned int num_tx = 0;
	while (!uart_circ_empty(xmit) &&
		!(rd_regl(port, SIRFUART_TX_FIFO_STATUS) &
					SIRFUART_FIFOFULL_MASK(port)) &&
		count--) {
		wr_regl(port, SIRFUART_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;
}
Example #30
0
static int s3c6400_serial_resetport(struct uart_port *port,
				    struct s3c2410_uartcfg *cfg)
{
	unsigned long ucon = rd_regl(port, S3C2410_UCON);

	dbg("s3c6400_serial_resetport: port=%p (%08lx), cfg=%p\n",
	    port, port->mapbase, cfg);

	ucon &= S3C6400_UCON_CLKMASK;

	wr_regl(port, S3C2410_UCON,  ucon | cfg->ucon);
	wr_regl(port, S3C2410_ULCON, cfg->ulcon);

	/* reset both fifos */

	wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
	wr_regl(port, S3C2410_UFCON, cfg->ufcon);

	return 0;
}