On 5/1/07, John Williams <[EMAIL PROTECTED]> wrote:
Grant Likely wrote:
> However, the uartlite is *not* an 8250.  The 8250 turns up all over
> the place and it's registers are defined as 8 bit wide.  The
> offset-by-3 stuff is part of the plat_serial8250_port structure which
> is also used to specify .regshift (increment between registers).
> Whereas the UARTLITE is defined as a 32 bit device and it doesn't show
> up in anywhere near as many designs.  Registers are always 4 bytes
> wide and are always located at multiples of 4 bytes off the base

Hmm, I think I was smoking something last night.  Address used for 8
bit access should not be affected by CPU endianess.  After David's
comments, I reread the uartlite documentation.  The current design is
definately for 32bit OPB bus connections, but it looks like there is a
posibility for xilinx to add a 16 or 8 bit attachment.  Since the
uartlite design explicitly supports 8, 16 and 32 bit access, sticking
with 8 bit io may be the safest.  However, I still think the
application of the 3 byte offset should be done in the driver, and not
in the platform bus registration.

I've reworked the patch with the following changes
- remove 3 byte offset from platform bus registration.
- added ulite_in/ulite_out macros to make changing bus attachment
details simpler if xilinx changes the uartlite design.
- stick with 8 bit IO.

Tested on PPC.  John, can you please test on microblaze?

Cheers,
g.

--
Grant Likely, B.Sc. P.Eng.
Secret Lab Technologies Ltd.
[EMAIL PROTECTED]
(403) 399-0195
From fd14939b570511cd57dc5d3efa1145976706c6ad Mon Sep 17 00:00:00 2001
From: Grant Likely <[email protected]>
Date: Mon, 30 Apr 2007 23:53:03 -0600
Subject: [PATCH] [POWERPC] Fix UARTLITE driver to add a 3 byte offset when accessing registers

Also, replace direct calls to readb/writeb with ulite_in/ulite_out macros
so any future register access changes are simpler to apply.

Signed-off-by: Grant Likely <[email protected]>
---
 arch/ppc/syslib/virtex_devices.c |    2 +-
 drivers/serial/uartlite.c        |   35 +++++++++++++++++++----------------
 2 files changed, 20 insertions(+), 17 deletions(-)

diff --git a/arch/ppc/syslib/virtex_devices.c b/arch/ppc/syslib/virtex_devices.c
index 52e2ebb..6c3e31b 100644
--- a/arch/ppc/syslib/virtex_devices.c
+++ b/arch/ppc/syslib/virtex_devices.c
@@ -31,7 +31,7 @@
 	.num_resources = 2, \
 	.resource = (struct resource[]) { \
 		{ \
-			.start = XPAR_UARTLITE_##num##_BASEADDR + 3, \
+			.start = XPAR_UARTLITE_##num##_BASEADDR, \
 			.end = XPAR_UARTLITE_##num##_HIGHADDR, \
 			.flags = IORESOURCE_MEM, \
 		}, \
diff --git a/drivers/serial/uartlite.c b/drivers/serial/uartlite.c
index f5051cf..67a8bc7 100644
--- a/drivers/serial/uartlite.c
+++ b/drivers/serial/uartlite.c
@@ -48,6 +48,9 @@
 
 static struct uart_port ports[ULITE_NR_UARTS];
 
+#define ulite_in(p,r)		in_8(p->membase + (r) + 3)
+#define ulite_out(p,r,v)	out_8(p->membase + (r) + 3, v)
+
 static int ulite_receive(struct uart_port *port, int stat)
 {
 	struct tty_struct *tty = port->info->tty;
@@ -61,7 +64,7 @@ static int ulite_receive(struct uart_port *port, int stat)
 	/* stats */
 	if (stat & ULITE_STATUS_RXVALID) {
 		port->icount.rx++;
-		ch = readb(port->membase + ULITE_RX);
+		ch = ulite_in(port, ULITE_RX);
 
 		if (stat & ULITE_STATUS_PARITY)
 			port->icount.parity++;
@@ -106,7 +109,7 @@ static int ulite_transmit(struct uart_port *port, int stat)
 		return 0;
 
 	if (port->x_char) {
-		writeb(port->x_char, port->membase + ULITE_TX);
+		ulite_out(port, ULITE_TX, port->x_char);
 		port->x_char = 0;
 		port->icount.tx++;
 		return 1;
@@ -115,7 +118,7 @@ static int ulite_transmit(struct uart_port *port, int stat)
 	if (uart_circ_empty(xmit) || uart_tx_stopped(port))
 		return 0;
 
-	writeb(xmit->buf[xmit->tail], port->membase + ULITE_TX);
+	ulite_out(port, ULITE_TX, xmit->buf[xmit->tail]);
 	xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE-1);
 	port->icount.tx++;
 
@@ -132,7 +135,7 @@ static irqreturn_t ulite_isr(int irq, void *dev_id)
 	int busy;
 
 	do {
-		int stat = readb(port->membase + ULITE_STATUS);
+		int stat = ulite_in(port, ULITE_STATUS);
 		busy  = ulite_receive(port, stat);
 		busy |= ulite_transmit(port, stat);
 	} while (busy);
@@ -148,7 +151,7 @@ static unsigned int ulite_tx_empty(struct uart_port *port)
 	unsigned int ret;
 
 	spin_lock_irqsave(&port->lock, flags);
-	ret = readb(port->membase + ULITE_STATUS);
+	ret = ulite_in(port, ULITE_STATUS);
 	spin_unlock_irqrestore(&port->lock, flags);
 
 	return ret & ULITE_STATUS_TXEMPTY ? TIOCSER_TEMT : 0;
@@ -171,7 +174,7 @@ static void ulite_stop_tx(struct uart_port *port)
 
 static void ulite_start_tx(struct uart_port *port)
 {
-	ulite_transmit(port, readb(port->membase + ULITE_STATUS));
+	ulite_transmit(port, ulite_in(port, ULITE_STATUS));
 }
 
 static void ulite_stop_rx(struct uart_port *port)
@@ -200,17 +203,17 @@ static int ulite_startup(struct uart_port *port)
 	if (ret)
 		return ret;
 
-	writeb(ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX,
-	       port->membase + ULITE_CONTROL);
-	writeb(ULITE_CONTROL_IE, port->membase + ULITE_CONTROL);
+	ulite_out(port, ULITE_CONTROL,
+	          ULITE_CONTROL_RST_RX | ULITE_CONTROL_RST_TX);
+	ulite_out(port, ULITE_CONTROL, ULITE_CONTROL_IE);
 
 	return 0;
 }
 
 static void ulite_shutdown(struct uart_port *port)
 {
-	writeb(0, port->membase + ULITE_CONTROL);
-	readb(port->membase + ULITE_CONTROL); /* dummy */
+	ulite_out(port, ULITE_CONTROL, 0);
+	ulite_in(port, ULITE_CONTROL); /* dummy */
 	free_irq(port->irq, port);
 }
 
@@ -314,7 +317,7 @@ static void ulite_console_wait_tx(struct uart_port *port)
 
 	/* wait up to 10ms for the character(s) to be sent */
 	for (i = 0; i < 10000; i++) {
-		if (readb(port->membase + ULITE_STATUS) & ULITE_STATUS_TXEMPTY)
+		if (ulite_in(port, ULITE_STATUS) & ULITE_STATUS_TXEMPTY)
 			break;
 		udelay(1);
 	}
@@ -323,7 +326,7 @@ static void ulite_console_wait_tx(struct uart_port *port)
 static void ulite_console_putchar(struct uart_port *port, int ch)
 {
 	ulite_console_wait_tx(port);
-	writeb(ch, port->membase + ULITE_TX);
+	ulite_out(port, ULITE_TX, ch);
 }
 
 static void ulite_console_write(struct console *co, const char *s,
@@ -340,8 +343,8 @@ static void ulite_console_write(struct console *co, const char *s,
 		spin_lock_irqsave(&port->lock, flags);
 
 	/* save and disable interrupt */
-	ier = readb(port->membase + ULITE_STATUS) & ULITE_STATUS_IE;
-	writeb(0, port->membase + ULITE_CONTROL);
+	ier = ulite_in(port, ULITE_STATUS) & ULITE_STATUS_IE;
+	ulite_out(port, ULITE_CONTROL, 0);
 
 	uart_console_write(port, s, count, ulite_console_putchar);
 
@@ -349,7 +352,7 @@ static void ulite_console_write(struct console *co, const char *s,
 
 	/* restore interrupt state */
 	if (ier)
-		writeb(ULITE_CONTROL_IE, port->membase + ULITE_CONTROL);
+		ulite_out(port, ULITE_CONTROL, ULITE_CONTROL_IE);
 
 	if (locked)
 		spin_unlock_irqrestore(&port->lock, flags);
-- 
1.5.1

_______________________________________________
Linuxppc-embedded mailing list
[email protected]
https://ozlabs.org/mailman/listinfo/linuxppc-embedded

Reply via email to