Here is the whole changes of "\linux-3.3.8\drivers\tty\serial\ar933x_uart.c" to enable ar9341 second uart.
I wish it is helpful, since it is much more simple and easy to use!
#define AR933X_UART_MAX_STEP 0x3333
#undef AR933X_UART_FIFO_SIZE
#define AR933X_UART_FIFO_SIZE 4
static void ar933x_uart_set_termios(struct uart_port *port,
struct ktermios *new,
struct ktermios *old)
{
struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
unsigned int cs;
unsigned long flags;
unsigned int baud, scale, step;
/* Only CS8 is supported */
new->c_cflag &= ~CSIZE;
new->c_cflag |= CS8;
/* Only one stop bit is supported */
new->c_cflag &= ~CSTOPB;
cs = 0;
if (new->c_cflag & PARENB) {
if (!(new->c_cflag & PARODD))
cs |= AR933X_UART_CS_PARITY_EVEN;
else
cs |= AR933X_UART_CS_PARITY_ODD;
} else {
cs |= AR933X_UART_CS_PARITY_NONE;
}
/* Mark/space parity is not supported */
new->c_cflag &= ~CMSPAR;
baud = uart_get_baud_rate(port, new, old, up->min_baud, up->max_baud);
ar933x_uart_get_scale_step(port->uartclk, baud, &scale, &step);
/*
* Ok, we're now changing the port state. Do it with
* interrupts disabled.
*/
spin_lock_irqsave(&up->port.lock, flags);
/* disable the UART */
ar933x_uart_rmw_clear(up, AR933X_UART_CS_REG,
AR933X_UART_CS_IF_MODE_M << AR933X_UART_CS_IF_MODE_S);
/* Update the per-port timeout. */
uart_update_timeout(port, new->c_cflag, baud);
up->port.ignore_status_mask = 0;
/* ignore all characters if CREAD is not set */
if ((new->c_cflag & CREAD) == 0)
up->port.ignore_status_mask |= AR933X_DUMMY_STATUS_RD;
ar933x_uart_write(up, AR933X_UART_CLOCK_REG,
scale << AR933X_UART_CLOCK_SCALE_S | step);
/* setup configuration register */
ar933x_uart_rmw(up, AR933X_UART_CS_REG, AR933X_UART_CS_PARITY_M, cs);
/* enable host interrupt */
ar933x_uart_rmw_set(up, AR933X_UART_CS_REG,
AR933X_UART_CS_HOST_INT_EN);
/* enable TX ready overide */
ar933x_uart_rmw_set(up, AR933X_UART_CS_REG,
AR933X_UART_CS_TX_READY_ORIDE);
/* enable RX ready overide */
ar933x_uart_rmw_set(up, AR933X_UART_CS_REG,
AR933X_UART_CS_RX_READY_ORIDE);
/* reenable the UART */
ar933x_uart_rmw(up, AR933X_UART_CS_REG,
AR933X_UART_CS_IF_MODE_M << AR933X_UART_CS_IF_MODE_S,
AR933X_UART_CS_IF_MODE_DCE << AR933X_UART_CS_IF_MODE_S);
spin_unlock_irqrestore(&up->port.lock, flags);
if (tty_termios_baud_rate(new))
tty_termios_encode_baud_rate(new, baud, baud);
}
static int ar933x_uart_startup(struct uart_port *port)
{
struct ar933x_uart_port *up = (struct ar933x_uart_port *) port;
unsigned long flags;
int ret;
ret = request_irq(up->port.irq, ar933x_uart_interrupt,
up->port.irqflags, dev_name(up->port.dev), up);
if (ret)
return ret;
spin_lock_irqsave(&up->port.lock, flags);
/* Enable HOST interrupts */
ar933x_uart_rmw_set(up, AR933X_UART_CS_REG,
AR933X_UART_CS_HOST_INT_EN);
/* enable TX ready overide */
ar933x_uart_rmw_set(up, AR933X_UART_CS_REG,
AR933X_UART_CS_TX_READY_ORIDE);
/* Enable RX interrupts */
up->ier = AR933X_UART_INT_RX_VALID;
ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier);
spin_unlock_irqrestore(&up->port.lock, flags);
return 0;
}