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
