[U-Boot] [PATCH] serial: ns16550: fix different reg size access

Lei Wen
2011-03-31T15:52:54Z

Some hardware would dysfunctional if only access the register by
byte. This patch is tend to recover original access the responding
register according to CONFIG_SYS_NS16550_REG_SIZE.

Signed-off-by: Lei Wen <leiwen@marvell.com>
---
README | 5 ++++
drivers/serial/ns16550.c | 7 ------
include/ns16550.h | 51 +++++++++++++++++++++++++++++++++++++--------
3 files changed, 47 insertions(+), 16 deletions(-)

diff --git a/README b/README
index 21cd71b..45bc7dd 100644
--- a/README
+++ b/README
@@ -2660,6 +2660,11 @@ use the "saveenv" command to store a valid environment.
space for already greatly restricted images, including but not
limited to NAND_SPL configurations.

+- CONFIG_SYS_NS16550_MAX_REG_SIZE:
+ Define the ns16550 max register size,
+ if the CONFIG_SYS_NS16550_REG_SIZE is smaller than this value,
+ use padding to fill those gap.
+
Low Level (hardware related) configuration options:
---------------------------------------------------

diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index 8eeb48f..4956c7f 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -16,13 +16,6 @@
#define UART_FCRVAL (UART_FCR_FIFO_EN | \
UART_FCR_RXSR | \
UART_FCR_TXSR) /* Clear & enable FIFOs */
-#ifdef CONFIG_SYS_NS16550_PORT_MAPPED
-#define serial_out(x,y) outb(x,(ulong)y)
-#define serial_in(y) inb((ulong)y)
-#else
-#define serial_out(x,y) writeb(x,y)
-#define serial_in(y) readb(y)
-#endif

#ifndef CONFIG_SYS_NS16550_IER
#define CONFIG_SYS_NS16550_IER 0x00
diff --git a/include/ns16550.h b/include/ns16550.h
index 9ea81e9..a51b6e6 100644
--- a/include/ns16550.h
+++ b/include/ns16550.h
@@ -20,17 +20,50 @@
* Note that the following macro magic uses the fact that the compiler
* will not allocate storage for arrays of size 0
*/
-
-#if !defined(CONFIG_SYS_NS16550_REG_SIZE) || (CONFIG_SYS_NS16550_REG_SIZE == 0)
+#if (CONFIG_SYS_NS16550_REG_SIZE == 4) || (CONFIG_SYS_NS16550_REG_SIZE == -4)
+#ifdef CONFIG_SYS_NS16550_PORT_MAPPED
+#define serial_out(x, y) outl(x, y)
+#define serial_in(y) inl(y)
+#else
+#define serial_out(x, y) writel(x, y)
+#define serial_in(y) readl(y)
+#endif
+#define UART_REG_TYPE unsigned int
+#elif (CONFIG_SYS_NS16550_REG_SIZE == 2) || (CONFIG_SYS_NS16550_REG_SIZE == -2)
+#ifdef CONFIG_SYS_NS16550_PORT_MAPPED
+#define serial_out(x, y) outw(x, y)
+#define serial_in(y) inw(y)
+#else
+#define serial_out(x, y) writew(x, y)
+#define serial_in(y) readw(y)
+#endif
+#define UART_REG_TYPE unsigned short
+#elif (CONFIG_SYS_NS16550_REG_SIZE == 1) || (CONFIG_SYS_NS16550_REG_SIZE == -1)
+#ifdef CONFIG_SYS_NS16550_PORT_MAPPED
+#define serial_out(x, y) outb(x, y)
+#define serial_in(y) inb(y)
+#else
+#define serial_out(x, y) writeb(x, y)
+#define serial_in(y) readb(y)
+#endif
+#define UART_REG_TYPE unsigned char
+#else
#error "Please define NS16550 registers size."
-#elif (CONFIG_SYS_NS16550_REG_SIZE > 0)
-#define UART_REG(x) \
- unsigned char prepad_##x[CONFIG_SYS_NS16550_REG_SIZE - 1]; \
- unsigned char x;
-#elif (CONFIG_SYS_NS16550_REG_SIZE < 0)
+#endif
+
+#ifndef CONFIG_SYS_NS16550_MAX_REG_SIZE
+#define CONFIG_SYS_NS16550_MAX_REG_SIZE 4
+#endif
+#if (CONFIG_SYS_NS16550_REG_SIZE > 0)
+#define UART_REG(x) \
+ unsigned char prepad_##x[CONFIG_SYS_NS16550_MAX_REG_SIZE \
+ - CONFIG_SYS_NS16550_REG_SIZE]; \
+ UART_REG_TYPE x;
+#else
#define UART_REG(x) \
- unsigned char x; \
- unsigned char postpad_##x[-CONFIG_SYS_NS16550_REG_SIZE - 1];
+ UART_REG_TYPE x; \
+ unsigned char prepad_##x[CONFIG_SYS_NS16550_MAX_REG_SIZE \
+ + CONFIG_SYS_NS16550_REG_SIZE];
#endif

struct NS16550 {
--
1.7.0.4