* Register definitions
*
* For register details see datasheet:
- * http://www.xilinx.com/support/documentation/ip_documentation/opb_uartlite.pdf
+ * http://www.xilinx.com/support/documentation/ip_documentation/opb_uartlite.pdf
*/
#define ULITE_RX 0x00
#define ULITE_CONTROL_RST_RX 0x02
#define ULITE_CONTROL_IE 0x10
+struct uartlite_reg_ops {
+ u32 (*in)(void __iomem *addr);
+ void (*out)(u32 val, void __iomem *addr);
+};
+
+static u32 uartlite_inbe32(void __iomem *addr)
+{
+ return ioread32be(addr);
+}
+
+static void uartlite_outbe32(u32 val, void __iomem *addr)
+{
+ iowrite32be(val, addr);
+}
+
+static struct uartlite_reg_ops uartlite_be = {
+ .in = uartlite_inbe32,
+ .out = uartlite_outbe32,
+};
+
+static u32 uartlite_inle32(void __iomem *addr)
+{
+ return ioread32(addr);
+}
+
+static void uartlite_outle32(u32 val, void __iomem *addr)
+{
+ iowrite32(val, addr);
+}
+
+static struct uartlite_reg_ops uartlite_le = {
+ .in = uartlite_inle32,
+ .out = uartlite_outle32,
+};
+
+static inline u32 uart_in32(u32 offset, struct uart_port *port)
+{
+ struct uartlite_reg_ops *reg_ops = port->private_data;
+
+ return reg_ops->in(port->membase + offset);
+}
+
+static inline void uart_out32(u32 val, u32 offset, struct uart_port *port)
+{
+ struct uartlite_reg_ops *reg_ops = port->private_data;
+
+ reg_ops->out(val, port->membase + offset);
+}
static struct uart_port ulite_ports[ULITE_NR_UARTS];
/* stats */
if (stat & ULITE_STATUS_RXVALID) {
port->icount.rx++;
- ch = ioread32be(port->membase + ULITE_RX);
+ ch = uart_in32(ULITE_RX, port);
if (stat & ULITE_STATUS_PARITY)
port->icount.parity++;
return 0;
if (port->x_char) {
- iowrite32be(port->x_char, port->membase + ULITE_TX);
+ uart_out32(port->x_char, ULITE_TX, port);
port->x_char = 0;
port->icount.tx++;
return 1;
if (uart_circ_empty(xmit) || uart_tx_stopped(port))
return 0;
- iowrite32be(xmit->buf[xmit->tail], port->membase + ULITE_TX);
+ uart_out32(xmit->buf[xmit->tail], ULITE_TX, port);
xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE-1);
port->icount.tx++;
int busy, n = 0;
do {
- int stat = ioread32be(port->membase + ULITE_STATUS);
+ int stat = uart_in32(ULITE_STATUS, port);
busy = ulite_receive(port, stat);
busy |= ulite_transmit(port, stat);
n++;
unsigned int ret;
spin_lock_irqsave(&port->lock, flags);
- ret = ioread32be(port->membase + ULITE_STATUS);
+ ret = uart_in32(ULITE_STATUS, port);
spin_unlock_irqrestore(&port->lock, flags);
return ret & ULITE_STATUS_TXEMPTY ? TIOCSER_TEMT : 0;
static void ulite_start_tx(struct uart_port *port)
{
- ulite_transmit(port, ioread32be(port->membase + ULITE_STATUS));
+ ulite_transmit(port, uart_in32(ULITE_STATUS, port));
}
static void ulite_stop_rx(struct uart_port *port)
if (ret)
return ret;
- iowrite32be(ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX,
- port->membase + ULITE_CONTROL);
- iowrite32be(ULITE_CONTROL_IE, port->membase + ULITE_CONTROL);
+ uart_out32(ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX,
+ ULITE_CONTROL, port);
+ uart_out32(ULITE_CONTROL_IE, ULITE_CONTROL, port);
return 0;
}
static void ulite_shutdown(struct uart_port *port)
{
- iowrite32be(0, port->membase + ULITE_CONTROL);
- ioread32be(port->membase + ULITE_CONTROL); /* dummy */
+ uart_out32(0, ULITE_CONTROL, port);
+ uart_in32(ULITE_CONTROL, port); /* dummy */
free_irq(port->irq, port);
}
static int ulite_request_port(struct uart_port *port)
{
+ int ret;
+
pr_debug("ulite console: port=%p; port->mapbase=%llx\n",
port, (unsigned long long) port->mapbase);
return -EBUSY;
}
+ port->private_data = &uartlite_be;
+ ret = uart_in32(ULITE_CONTROL, port);
+ uart_out32(ULITE_CONTROL_RST_TX, ULITE_CONTROL, port);
+ ret = uart_in32(ULITE_STATUS, port);
+ /* Endianess detection */
+ if ((ret & ULITE_STATUS_TXEMPTY) != ULITE_STATUS_TXEMPTY)
+ port->private_data = &uartlite_le;
+
return 0;
}
#ifdef CONFIG_CONSOLE_POLL
static int ulite_get_poll_char(struct uart_port *port)
{
- if (!(ioread32be(port->membase + ULITE_STATUS)
- & ULITE_STATUS_RXVALID))
+ if (!(uart_in32(ULITE_STATUS, port) & ULITE_STATUS_RXVALID))
return NO_POLL_CHAR;
- return ioread32be(port->membase + ULITE_RX);
+ return uart_in32(ULITE_RX, port);
}
static void ulite_put_poll_char(struct uart_port *port, unsigned char ch)
{
- while (ioread32be(port->membase + ULITE_STATUS) & ULITE_STATUS_TXFULL)
+ while (uart_in32(ULITE_STATUS, port) & ULITE_STATUS_TXFULL)
cpu_relax();
/* write char to device */
- iowrite32be(ch, port->membase + ULITE_TX);
+ uart_out32(ch, ULITE_TX, port);
}
#endif
/* Spin waiting for TX fifo to have space available */
for (i = 0; i < 100000; i++) {
- val = ioread32be(port->membase + ULITE_STATUS);
+ val = uart_in32(ULITE_STATUS, port);
if ((val & ULITE_STATUS_TXFULL) == 0)
break;
cpu_relax();
static void ulite_console_putchar(struct uart_port *port, int ch)
{
ulite_console_wait_tx(port);
- iowrite32be(ch, port->membase + ULITE_TX);
+ uart_out32(ch, ULITE_TX, port);
}
static void ulite_console_write(struct console *co, const char *s,
spin_lock_irqsave(&port->lock, flags);
/* save and disable interrupt */
- ier = ioread32be(port->membase + ULITE_STATUS) & ULITE_STATUS_IE;
- iowrite32be(0, port->membase + ULITE_CONTROL);
+ ier = uart_in32(ULITE_STATUS, port) & ULITE_STATUS_IE;
+ uart_out32(0, ULITE_CONTROL, port);
uart_console_write(port, s, count, ulite_console_putchar);
/* restore interrupt state */
if (ier)
- iowrite32be(ULITE_CONTROL_IE, port->membase + ULITE_CONTROL);
+ uart_out32(ULITE_CONTROL_IE, ULITE_CONTROL, port);
if (locked)
spin_unlock_irqrestore(&port->lock, flags);