summaryrefslogtreecommitdiff
path: root/drivers/serial
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/Makefile5
-rw-r--r--drivers/serial/altera_jtag_uart.c41
-rw-r--r--drivers/serial/altera_uart.c53
-rw-r--r--drivers/serial/atmel_usart.c35
-rw-r--r--drivers/serial/lpc32xx_hsuart.c57
-rw-r--r--drivers/serial/mcfuart.c33
-rw-r--r--drivers/serial/ns16550.c2
-rw-r--r--drivers/serial/ns9750_serial.c33
-rw-r--r--drivers/serial/opencores_yanu.c35
-rw-r--r--drivers/serial/s3c4510b_uart.c33
-rw-r--r--drivers/serial/s3c64xx.c33
-rw-r--r--drivers/serial/sandbox.c35
-rw-r--r--drivers/serial/serial.c552
-rw-r--r--drivers/serial/serial_clps7111.c34
-rw-r--r--drivers/serial/serial_imx.c36
-rw-r--r--drivers/serial/serial_ixp.c36
-rw-r--r--drivers/serial/serial_ks8695.c41
-rw-r--r--drivers/serial/serial_lh7a40x.c34
-rw-r--r--drivers/serial/serial_lpc2292.c34
-rw-r--r--drivers/serial/serial_max3100.c42
-rw-r--r--drivers/serial/serial_mxc.c40
-rw-r--r--drivers/serial/serial_netarm.c33
-rw-r--r--drivers/serial/serial_ns16550.c264
-rw-r--r--drivers/serial/serial_pl01x.c37
-rw-r--r--drivers/serial/serial_pxa.c65
-rw-r--r--drivers/serial/serial_s3c24x0.c78
-rw-r--r--drivers/serial/serial_s3c44b0.c36
-rw-r--r--drivers/serial/serial_s5p.c27
-rw-r--r--drivers/serial/serial_sa1100.c36
-rw-r--r--drivers/serial/serial_sh.c35
-rw-r--r--drivers/serial/serial_xuartlite.c69
-rw-r--r--drivers/serial/serial_zynq.c225
32 files changed, 1543 insertions, 606 deletions
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 65d0f23..3c32f97 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -25,6 +25,8 @@ include $(TOPDIR)/config.mk
LIB := $(obj)libserial.o
+COBJS-y += serial.o
+
COBJS-$(CONFIG_ALTERA_UART) += altera_uart.o
COBJS-$(CONFIG_ALTERA_JTAG_UART) += altera_jtag_uart.o
COBJS-$(CONFIG_ARM_DCC) += arm_dcc.o
@@ -37,7 +39,7 @@ COBJS-$(CONFIG_SYS_NS16550) += ns16550.o
COBJS-$(CONFIG_DRIVER_S3C4510_UART) += s3c4510b_uart.o
COBJS-$(CONFIG_S3C64XX) += s3c64xx.o
COBJS-$(CONFIG_S5P) += serial_s5p.o
-COBJS-$(CONFIG_SYS_NS16550_SERIAL) += serial.o
+COBJS-$(CONFIG_SYS_NS16550_SERIAL) += serial_ns16550.o
COBJS-$(CONFIG_CLPS7111_SERIAL) += serial_clps7111.o
COBJS-$(CONFIG_IMX_SERIAL) += serial_imx.o
COBJS-$(CONFIG_IXP_SERIAL) += serial_ixp.o
@@ -56,6 +58,7 @@ COBJS-$(CONFIG_S3C44B0_SERIAL) += serial_s3c44b0.o
COBJS-$(CONFIG_XILINX_UARTLITE) += serial_xuartlite.o
COBJS-$(CONFIG_SANDBOX_SERIAL) += sandbox.o
COBJS-$(CONFIG_SCIF_CONSOLE) += serial_sh.o
+COBJS-$(CONFIG_ZYNQ_SERIAL) += serial_zynq.o
ifndef CONFIG_SPL_BUILD
COBJS-$(CONFIG_USB_TTY) += usbtty.o
diff --git a/drivers/serial/altera_jtag_uart.c b/drivers/serial/altera_jtag_uart.c
index 2980e4d..654b501 100644
--- a/drivers/serial/altera_jtag_uart.c
+++ b/drivers/serial/altera_jtag_uart.c
@@ -25,6 +25,8 @@
#include <watchdog.h>
#include <asm/io.h>
#include <nios2-io.h>
+#include <linux/compiler.h>
+#include <serial.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -33,10 +35,16 @@ DECLARE_GLOBAL_DATA_PTR;
*-----------------------------------------------------------------*/
static nios_jtag_t *jtag = (nios_jtag_t *)CONFIG_SYS_NIOS_CONSOLE;
-void serial_setbrg( void ){ return; }
-int serial_init( void ) { return(0);}
+static void altera_jtag_serial_setbrg(void)
+{
+}
+
+static int altera_jtag_serial_init(void)
+{
+ return 0;
+}
-void serial_putc (char c)
+static void altera_jtag_serial_putc(char c)
{
while (1) {
unsigned st = readl(&jtag->control);
@@ -51,18 +59,18 @@ void serial_putc (char c)
writel ((unsigned char)c, &jtag->data);
}
-void serial_puts (const char *s)
+static void altera_jtag_serial_puts(const char *s)
{
while (*s != 0)
serial_putc (*s++);
}
-int serial_tstc (void)
+static int altera_jtag_serial_tstc(void)
{
return ( readl (&jtag->control) & NIOS_JTAG_RRDY);
}
-int serial_getc (void)
+static int altera_jtag_serial_getc(void)
{
int c;
unsigned val;
@@ -76,3 +84,24 @@ int serial_getc (void)
c = val & 0x0ff;
return (c);
}
+
+static struct serial_device altera_jtag_serial_drv = {
+ .name = "altera_jtag_uart",
+ .start = altera_jtag_serial_init,
+ .stop = NULL,
+ .setbrg = altera_jtag_serial_setbrg,
+ .putc = altera_jtag_serial_putc,
+ .puts = altera_jtag_serial_puts,
+ .getc = altera_jtag_serial_getc,
+ .tstc = altera_jtag_serial_tstc,
+};
+
+void altera_jtag_serial_initialize(void)
+{
+ serial_register(&altera_jtag_serial_drv);
+}
+
+__weak struct serial_device *default_serial_console(void)
+{
+ return &altera_jtag_serial_drv;
+}
diff --git a/drivers/serial/altera_uart.c b/drivers/serial/altera_uart.c
index 045f119..27550ed 100644
--- a/drivers/serial/altera_uart.c
+++ b/drivers/serial/altera_uart.c
@@ -26,6 +26,8 @@
#include <watchdog.h>
#include <asm/io.h>
#include <nios2-io.h>
+#include <linux/compiler.h>
+#include <serial.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -37,27 +39,33 @@ static nios_uart_t *uart = (nios_uart_t *) CONFIG_SYS_NIOS_CONSOLE;
#if defined(CONFIG_SYS_NIOS_FIXEDBAUD)
-/* Everything's already setup for fixed-baud PTF
+/*
+ * Everything's already setup for fixed-baud PTF
* assignment
*/
-void serial_setbrg (void){ return; }
-int serial_init (void) { return (0);}
+static void altera_serial_setbrg(void)
+{
+}
+
+static int altera_serial_init(void)
+{
+ return 0;
+}
#else
-void serial_setbrg (void)
+static void altera_serial_setbrg(void)
{
unsigned div;
div = (CONFIG_SYS_CLK_FREQ/gd->baudrate)-1;
writel (div, &uart->divisor);
- return;
}
-int serial_init (void)
+static int altera_serial_init(void)
{
- serial_setbrg ();
- return (0);
+ serial_setbrg();
+ return 0;
}
#endif /* CONFIG_SYS_NIOS_FIXEDBAUD */
@@ -65,7 +73,7 @@ int serial_init (void)
/*-----------------------------------------------------------------------
* UART CONSOLE
*---------------------------------------------------------------------*/
-void serial_putc (char c)
+static void altera_serial_putc(char c)
{
if (c == '\n')
serial_putc ('\r');
@@ -74,21 +82,42 @@ void serial_putc (char c)
writel ((unsigned char)c, &uart->txdata);
}
-void serial_puts (const char *s)
+static void altera_serial_puts(const char *s)
{
while (*s != 0) {
serial_putc (*s++);
}
}
-int serial_tstc (void)
+static int altera_serial_tstc(void)
{
return (readl (&uart->status) & NIOS_UART_RRDY);
}
-int serial_getc (void)
+static int altera_serial_getc(void)
{
while (serial_tstc () == 0)
WATCHDOG_RESET ();
return (readl (&uart->rxdata) & 0x00ff );
}
+
+static struct serial_device altera_serial_drv = {
+ .name = "altera_serial",
+ .start = altera_serial_init,
+ .stop = NULL,
+ .setbrg = altera_serial_setbrg,
+ .putc = altera_serial_putc,
+ .puts = altera_serial_puts,
+ .getc = altera_serial_getc,
+ .tstc = altera_serial_tstc,
+};
+
+void altera_serial_initialize(void)
+{
+ serial_register(&altera_serial_drv);
+}
+
+__weak struct serial_device *default_serial_console(void)
+{
+ return &altera_serial_drv;
+}
diff --git a/drivers/serial/atmel_usart.c b/drivers/serial/atmel_usart.c
index 943ef70..1303031 100644
--- a/drivers/serial/atmel_usart.c
+++ b/drivers/serial/atmel_usart.c
@@ -20,6 +20,8 @@
*/
#include <common.h>
#include <watchdog.h>
+#include <serial.h>
+#include <linux/compiler.h>
#include <asm/io.h>
#include <asm/arch/clk.h>
@@ -29,7 +31,7 @@
DECLARE_GLOBAL_DATA_PTR;
-void serial_setbrg(void)
+static void atmel_serial_setbrg(void)
{
atmel_usart3_t *usart = (atmel_usart3_t *)CONFIG_USART_BASE;
unsigned long divisor;
@@ -45,7 +47,7 @@ void serial_setbrg(void)
writel(USART3_BF(CD, divisor), &usart->brgr);
}
-int serial_init(void)
+static int atmel_serial_init(void)
{
atmel_usart3_t *usart = (atmel_usart3_t *)CONFIG_USART_BASE;
@@ -73,7 +75,7 @@ int serial_init(void)
return 0;
}
-void serial_putc(char c)
+static void atmel_serial_putc(char c)
{
atmel_usart3_t *usart = (atmel_usart3_t *)CONFIG_USART_BASE;
@@ -84,13 +86,13 @@ void serial_putc(char c)
writel(c, &usart->thr);
}
-void serial_puts(const char *s)
+static void atmel_serial_puts(const char *s)
{
while (*s)
serial_putc(*s++);
}
-int serial_getc(void)
+static int atmel_serial_getc(void)
{
atmel_usart3_t *usart = (atmel_usart3_t *)CONFIG_USART_BASE;
@@ -99,8 +101,29 @@ int serial_getc(void)
return readl(&usart->rhr);
}
-int serial_tstc(void)
+static int atmel_serial_tstc(void)
{
atmel_usart3_t *usart = (atmel_usart3_t *)CONFIG_USART_BASE;
return (readl(&usart->csr) & USART3_BIT(RXRDY)) != 0;
}
+
+static struct serial_device atmel_serial_drv = {
+ .name = "atmel_serial",
+ .start = atmel_serial_init,
+ .stop = NULL,
+ .setbrg = atmel_serial_setbrg,
+ .putc = atmel_serial_putc,
+ .puts = atmel_serial_puts,
+ .getc = atmel_serial_getc,
+ .tstc = atmel_serial_tstc,
+};
+
+void atmel_serial_initialize(void)
+{
+ serial_register(&atmel_serial_drv);
+}
+
+__weak struct serial_device *default_serial_console(void)
+{
+ return &atmel_serial_drv;
+}
diff --git a/drivers/serial/lpc32xx_hsuart.c b/drivers/serial/lpc32xx_hsuart.c
index 8ce3382..02429b5 100644
--- a/drivers/serial/lpc32xx_hsuart.c
+++ b/drivers/serial/lpc32xx_hsuart.c
@@ -22,12 +22,14 @@
#include <asm/arch/clk.h>
#include <asm/arch/uart.h>
#include <asm/io.h>
+#include <serial.h>
+#include <linux/compiler.h>
DECLARE_GLOBAL_DATA_PTR;
static struct hsuart_regs *hsuart = (struct hsuart_regs *)HS_UART_BASE;
-static void lpc32xx_hsuart_set_baudrate(void)
+static void lpc32xx_serial_setbrg(void)
{
u32 div;
@@ -39,7 +41,7 @@ static void lpc32xx_hsuart_set_baudrate(void)
writel(div, &hsuart->rate);
}
-static int lpc32xx_hsuart_getc(void)
+static int lpc32xx_serial_getc(void)
{
while (!(readl(&hsuart->level) & HSUART_LEVEL_RX))
/* NOP */;
@@ -47,7 +49,7 @@ static int lpc32xx_hsuart_getc(void)
return readl(&hsuart->rx) & HSUART_RX_DATA;
}
-static void lpc32xx_hsuart_putc(const char c)
+static void lpc32xx_serial_putc(const char c)
{
writel(c, &hsuart->tx);
@@ -56,7 +58,7 @@ static void lpc32xx_hsuart_putc(const char c)
/* NOP */;
}
-static int lpc32xx_hsuart_tstc(void)
+static int lpc32xx_serial_tstc(void)
{
if (readl(&hsuart->level) & HSUART_LEVEL_RX)
return 1;
@@ -64,49 +66,40 @@ static int lpc32xx_hsuart_tstc(void)
return 0;
}
-static void lpc32xx_hsuart_init(void)
+static int lpc32xx_serial_init(void)
{
- lpc32xx_hsuart_set_baudrate();
+ lpc32xx_serial_setbrg();
/* Disable hardware RTS and CTS flow control, set up RX and TX FIFO */
writel(HSUART_CTRL_TMO_16 | HSUART_CTRL_HSU_OFFSET(20) |
HSUART_CTRL_HSU_RX_TRIG_32 | HSUART_CTRL_HSU_TX_TRIG_0,
&hsuart->ctrl);
+ return 0;
}
-void serial_setbrg(void)
-{
- return lpc32xx_hsuart_set_baudrate();
-}
-
-void serial_putc(const char c)
-{
- lpc32xx_hsuart_putc(c);
-
- /* If \n, also do \r */
- if (c == '\n')
- lpc32xx_hsuart_putc('\r');
-}
-
-int serial_getc(void)
-{
- return lpc32xx_hsuart_getc();
-}
-
-void serial_puts(const char *s)
+static void lpc32xx_serial_puts(const char *s)
{
while (*s)
serial_putc(*s++);
}
-int serial_tstc(void)
+static struct serial_device lpc32xx_serial_drv = {
+ .name = "lpc32xx_serial",
+ .start = lpc32xx_serial_init,
+ .stop = NULL,
+ .setbrg = lpc32xx_serial_setbrg,
+ .putc = lpc32xx_serial_putc,
+ .puts = lpc32xx_serial_puts,
+ .getc = lpc32xx_serial_getc,
+ .tstc = lpc32xx_serial_tstc,
+};
+
+void lpc32xx_serial_initialize(void)
{
- return lpc32xx_hsuart_tstc();
+ serial_register(&lpc32xx_serial_drv);
}
-int serial_init(void)
+__weak struct serial_device *default_serial_console(void)
{
- lpc32xx_hsuart_init();
-
- return 0;
+ return &lpc32xx_serial_drv;
}
diff --git a/drivers/serial/mcfuart.c b/drivers/serial/mcfuart.c
index d93b24b..00a7114 100644
--- a/drivers/serial/mcfuart.c
+++ b/drivers/serial/mcfuart.c
@@ -36,7 +36,7 @@ DECLARE_GLOBAL_DATA_PTR;
extern void uart_port_conf(int port);
-int serial_init(void)
+static int mcf_serial_init(void)
{
volatile uart_t *uart;
u32 counter;
@@ -74,7 +74,7 @@ int serial_init(void)
return (0);
}
-void serial_putc(const char c)
+static void mcf_serial_putc(const char c)
{
volatile uart_t *uart = (volatile uart_t *)(CONFIG_SYS_UART_BASE);
@@ -87,14 +87,14 @@ void serial_putc(const char c)
uart->utb = c;
}
-void serial_puts(const char *s)
+static void mcf_serial_puts(const char *s)
{
while (*s) {
serial_putc(*s++);
}
}
-int serial_getc(void)
+static int mcf_serial_getc(void)
{
volatile uart_t *uart = (volatile uart_t *)(CONFIG_SYS_UART_BASE);
@@ -103,14 +103,14 @@ int serial_getc(void)
return uart->urb;
}
-int serial_tstc(void)
+static int mcf_serial_tstc(void)
{
volatile uart_t *uart = (volatile uart_t *)(CONFIG_SYS_UART_BASE);
return (uart->usr & UART_USR_RXRDY);
}
-void serial_setbrg(void)
+static void mcf_serial_setbrg(void)
{
volatile uart_t *uart = (volatile uart_t *)(CONFIG_SYS_UART_BASE);
u32 counter;
@@ -129,3 +129,24 @@ void serial_setbrg(void)
uart->ucr = UART_UCR_RX_ENABLED | UART_UCR_TX_ENABLED;
}
+
+static struct serial_device mcf_serial_drv = {
+ .name = "mcf_serial",
+ .start = mcf_serial_init,
+ .stop = NULL,
+ .setbrg = mcf_serial_setbrg,
+ .putc = mcf_serial_putc,
+ .puts = mcf_serial_puts,
+ .getc = mcf_serial_getc,
+ .tstc = mcf_serial_tstc,
+};
+
+void mcf_serial_initialize(void)
+{
+ serial_register(&mcf_serial_drv);
+}
+
+__weak struct serial_device *default_serial_console(void)
+{
+ return &mcf_serial_drv;
+}
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index facadd2..9027781 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -101,7 +101,7 @@ void NS16550_putc(NS16550_t com_port, char c)
char NS16550_getc(NS16550_t com_port)
{
while ((serial_in(&com_port->lsr) & UART_LSR_DR) == 0) {
-#ifdef CONFIG_USB_TTY
+#if !defined(CONFIG_SPL_BUILD) && defined(CONFIG_USB_TTY)
extern void usbtty_poll(void);
usbtty_poll();
#endif
diff --git a/drivers/serial/ns9750_serial.c b/drivers/serial/ns9750_serial.c
index e9645a0..cb545c4 100644
--- a/drivers/serial/ns9750_serial.c
+++ b/drivers/serial/ns9750_serial.c
@@ -52,7 +52,7 @@ static unsigned int unCharCache; /* unCharCache is only valid if
* @Descr: configures GPIOs and UART. Requires BBUS Master Reset turned off
***********************************************************************/
-int serial_init( void )
+static int ns9750_serial_init(void)
{
unsigned int aunGPIOTxD[] = { 0, 8, 40, 44 };
unsigned int aunGPIORxD[] = { 1, 9, 41, 45 };
@@ -85,7 +85,7 @@ int serial_init( void )
* @Descr: writes one character to the FIFO. Blocks until FIFO is not full
***********************************************************************/
-void serial_putc( const char c )
+static void ns9750_serial_putc(const char c)
{
if (c == '\n')
serial_putc( '\r' );
@@ -105,7 +105,7 @@ void serial_putc( const char c )
* @Descr: writes non-zero string to the FIFO.
***********************************************************************/
-void serial_puts( const char *s )
+static void ns9750_serial_puts(const char *s)
{
while (*s) {
serial_putc( *s++ );
@@ -118,7 +118,7 @@ void serial_puts( const char *s )
* @Descr: performs only 8bit accesses to the FIFO. No error handling
***********************************************************************/
-int serial_getc( void )
+static int ns9750_serial_getc(void)
{
int i;
@@ -142,7 +142,7 @@ int serial_getc( void )
* unCharCache and the numbers of characters in cCharsAvailable
***********************************************************************/
-int serial_tstc( void )
+static int ns9750_serial_tstc(void)
{
unsigned int unRegCache;
@@ -171,7 +171,7 @@ int serial_tstc( void )
return 0;
}
-void serial_setbrg( void )
+static void ns9750_serial_setbrg(void)
{
*get_ser_reg_addr_channel( NS9750_SER_BITRATE, CONSOLE ) =
calcBitrateRegister();
@@ -208,3 +208,24 @@ static unsigned int calcRxCharGapRegister( void )
{
return NS9750_SER_RX_CHAR_TIMER_TRUN;
}
+
+static struct serial_device ns9750_serial_drv = {
+ .name = "ns9750_serial",
+ .start = ns9750_serial_init,
+ .stop = NULL,
+ .setbrg = ns9750_serial_setbrg,
+ .putc = ns9750_serial_putc,
+ .puts = ns9750_serial_puts,
+ .getc = ns9750_serial_getc,
+ .tstc = ns9750_serial_tstc,
+};
+
+void ns9750_serial_initialize(void)
+{
+ serial_register(&ns9750_serial_drv);
+}
+
+__weak struct serial_device *default_serial_console(void)
+{
+ return &ns9750_serial_drv;
+}
diff --git a/drivers/serial/opencores_yanu.c b/drivers/serial/opencores_yanu.c
index f383011..49bccf3 100644
--- a/drivers/serial/opencores_yanu.c
+++ b/drivers/serial/opencores_yanu.c
@@ -37,7 +37,7 @@ static yanu_uart_t *uart = (yanu_uart_t *)CONFIG_SYS_NIOS_CONSOLE;
/* Everything's already setup for fixed-baud PTF assignment*/
-void serial_setbrg (void)
+static void oc_serial_setbrg(void)
{
int n, k;
const unsigned max_uns = 0xFFFFFFFF;
@@ -68,7 +68,7 @@ void serial_setbrg (void)
#else
-void serial_setbrg (void)
+static void oc_serial_setbrg(void)
{
int n, k;
const unsigned max_uns = 0xFFFFFFFF;
@@ -100,7 +100,7 @@ void serial_setbrg (void)
#endif /* CONFIG_SYS_NIOS_FIXEDBAUD */
-int serial_init (void)
+static int oc_serial_init(void)
{
unsigned action,control;
@@ -141,7 +141,7 @@ int serial_init (void)
/*-----------------------------------------------------------------------
* YANU CONSOLE
*---------------------------------------------------------------------*/
-void serial_putc (char c)
+static void oc_serial_putc(char c)
{
int tx_chars;
unsigned status;
@@ -161,7 +161,7 @@ void serial_putc (char c)
writel((unsigned char)c, &uart->data);
}
-void serial_puts (const char *s)
+static void oc_serial_puts(const char *s)
{
while (*s != 0) {
serial_putc (*s++);
@@ -169,7 +169,7 @@ void serial_puts (const char *s)
}
-int serial_tstc(void)
+static int oc_serial_tstc(void)
{
unsigned status ;
@@ -178,7 +178,7 @@ int serial_tstc(void)
((1 << YANU_RFIFO_CHARS_N) - 1)) > 0);
}
-int serial_getc (void)
+statoc int oc_serial_getc(void)
{
while (serial_tstc() == 0)
WATCHDOG_RESET ();
@@ -188,3 +188,24 @@ int serial_getc (void)
return(readl(&uart->data) & YANU_DATA_CHAR_MASK);
}
+
+static struct serial_device oc_serial_drv = {
+ .name = "oc_serial",
+ .start = oc_serial_init,
+ .stop = NULL,
+ .setbrg = oc_serial_setbrg,
+ .putc = oc_serial_putc,
+ .puts = oc_serial_puts,
+ .getc = oc_serial_getc,
+ .tstc = oc_serial_tstc,
+};
+
+void oc_serial_initialize(void)
+{
+ serial_register(&oc_serial_drv);
+}
+
+__weak struct serial_device *default_serial_console(void)
+{
+ return &oc_serial_drv;
+}
diff --git a/drivers/serial/s3c4510b_uart.c b/drivers/serial/s3c4510b_uart.c
index aa378e1..423d26e6 100644
--- a/drivers/serial/s3c4510b_uart.c
+++ b/drivers/serial/s3c4510b_uart.c
@@ -80,7 +80,7 @@ static int serial_flush_output(void)
}
-void serial_setbrg (void)
+static void s3c4510b_serial_setbrg(void)
{
UART_LINE_CTRL ulctrl;
UART_CTRL uctrl;
@@ -135,7 +135,7 @@ void serial_setbrg (void)
* are always 8 data bits, no parity, 1 stop bit, no start bits.
*
*/
-int serial_init (void)
+static int s3c4510b_serial_init(void)
{
#if CONFIG_SERIAL1 == 1
@@ -155,7 +155,7 @@ int serial_init (void)
/*
* Output a single byte to the serial port.
*/
-void serial_putc (const char c)
+static void s3c4510_serial_putc(const char c)
{
/* wait for room in the transmit FIFO */
while( !uart->m_stat.bf.txBufEmpty);
@@ -174,7 +174,7 @@ void serial_putc (const char c)
* Test if an input byte is ready from the serial port. Returns non-zero on
* success, 0 otherwise.
*/
-int serial_tstc (void)
+static int s3c4510b_serial_tstc(void)
{
return uart->m_stat.bf.rxReady;
}
@@ -184,7 +184,7 @@ int serial_tstc (void)
* otherwise. When the function is succesfull, the character read is
* written into its argument c.
*/
-int serial_getc (void)
+static int s3c4510b_serial_getc(void)
{
int rv;
@@ -197,7 +197,7 @@ int serial_getc (void)
}
}
-void serial_puts (const char *s)
+static void s3c4510b_serial_puts(const char *s)
{
while (*s) {
serial_putc (*s++);
@@ -210,3 +210,24 @@ void serial_puts (const char *s)
uart->m_ctrl.bf.sendBreak = 0;
}
+
+static struct serial_device s3c4510b_serial_drv = {
+ .name = "s3c4510b_serial",
+ .start = s3c4510b_serial_init,
+ .stop = NULL,
+ .setbrg = s3c4510b_serial_setbrg,
+ .putc = s3c4510b_serial_putc,
+ .puts = s3c4510b_serial_puts,
+ .getc = s3c4510b_serial_getc,
+ .tstc = s3c4510b_serial_tstc,
+};
+
+void s3c4510b_serial_initialize(void)
+{
+ serial_register(&s3c4510b_serial_drv);
+}
+
+__weak struct serial_device *default_serial_console(void)
+{
+ return &s3c4510b_serial_drv;
+}
diff --git a/drivers/serial/s3c64xx.c b/drivers/serial/s3c64xx.c
index a88e930..9ab8a28 100644
--- a/drivers/serial/s3c64xx.c
+++ b/drivers/serial/s3c64xx.c
@@ -68,7 +68,7 @@ static const int udivslot[] = {
0xffdf,
};
-void serial_setbrg(void)
+static void s3c64xx_serial_setbrg(void)
{
s3c64xx_uart *const uart = s3c64xx_get_base_uart(UART_NR);
u32 pclk = get_PCLK();
@@ -88,7 +88,7 @@ void serial_setbrg(void)
* Initialise the serial port with the given baudrate. The settings
* are always 8 data bits, no parity, 1 stop bit, no start bits.
*/
-int serial_init(void)
+static int s3c64xx_serial_init(void)
{
s3c64xx_uart *const uart = s3c64xx_get_base_uart(UART_NR);
@@ -110,7 +110,7 @@ int serial_init(void)
* otherwise. When the function is succesfull, the character read is
* written into its argument c.
*/
-int serial_getc(void)
+static int s3c64xx_serial_getc(void)
{
s3c64xx_uart *const uart = s3c64xx_get_base_uart(UART_NR);
@@ -137,7 +137,7 @@ void enable_putc(void)
/*
* Output a single byte to the serial port.
*/
-void serial_putc(const char c)
+static void s3c64xx_serial_putc(const char c)
{
s3c64xx_uart *const uart = s3c64xx_get_base_uart(UART_NR);
@@ -159,15 +159,36 @@ void serial_putc(const char c)
/*
* Test whether a character is in the RX buffer
*/
-int serial_tstc(void)
+static int s3c64xx_serial_tstc(void)
{
s3c64xx_uart *const uart = s3c64xx_get_base_uart(UART_NR);
return uart->UTRSTAT & 0x1;
}
-void serial_puts(const char *s)
+static void s3c64xx_serial_puts(const char *s)
{
while (*s)
serial_putc(*s++);
}
+
+static struct serial_device s3c64xx_serial_drv = {
+ .name = "s3c64xx_serial",
+ .start = s3c64xx_serial_init,
+ .stop = NULL,
+ .setbrg = s3c64xx_serial_setbrg,
+ .putc = s3c64xx_serial_putc,
+ .puts = s3c64xx_serial_puts,
+ .getc = s3c64xx_serial_getc,
+ .tstc = s3c64xx_serial_tstc,
+};
+
+void s3c64xx_serial_initialize(void)
+{
+ serial_register(&s3c64xx_serial_drv);
+}
+
+__weak struct serial_device *default_serial_console(void)
+{
+ return &s3c64xx_serial_drv;
+}
diff --git a/drivers/serial/sandbox.c b/drivers/serial/sandbox.c
index 1927c16..cb19401 100644
--- a/drivers/serial/sandbox.c
+++ b/drivers/serial/sandbox.c
@@ -27,28 +27,30 @@
#include <common.h>
#include <os.h>
+#include <serial.h>
+#include <linux/compiler.h>
-int serial_init(void)
+static int sandbox_serial_init(void)
{
os_tty_raw(0);
return 0;
}
-void serial_setbrg(void)
+static void sandbox_serial_setbrg(void)
{
}
-void serial_putc(const char ch)
+static void sandbox_serial_putc(const char ch)
{
os_write(1, &ch, 1);
}
-void serial_puts(const char *str)
+static void sandbox_serial_puts(const char *str)
{
os_write(1, str, strlen(str));
}
-int serial_getc(void)
+static int sandbox_serial_getc(void)
{
char buf;
ssize_t count;
@@ -57,7 +59,28 @@ int serial_getc(void)
return count == 1 ? buf : 0;
}
-int serial_tstc(void)
+static int sandbox_serial_tstc(void)
{
return 0;
}
+
+static struct serial_device sandbox_serial_drv = {
+ .name = "sandbox_serial",
+ .start = sandbox_serial_init,
+ .stop = NULL,
+ .setbrg = sandbox_serial_setbrg,
+ .putc = sandbox_serial_putc,
+ .puts = sandbox_serial_puts,
+ .getc = sandbox_serial_getc,
+ .tstc = sandbox_serial_tstc,
+};
+
+void sandbox_serial_initialize(void)
+{
+ serial_register(&sandbox_serial_drv);
+}
+
+__weak struct serial_device *default_serial_console(void)
+{
+ return &sandbox_serial_drv;
+}
diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c
index b10bab7..5bbf3ae 100644
--- a/drivers/serial/serial.c
+++ b/drivers/serial/serial.c
@@ -1,6 +1,6 @@
/*
- * (C) Copyright 2000
- * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
+ * (C) Copyright 2004
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
*
* See file CREDITS for list of people who contributed to this
* project.
@@ -22,321 +22,341 @@
*/
#include <common.h>
-#include <linux/compiler.h>
-
-#include <ns16550.h>
-#ifdef CONFIG_NS87308
-#include <ns87308.h>
-#endif
-
-#if defined (CONFIG_SERIAL_MULTI)
#include <serial.h>
-#endif
+#include <stdio_dev.h>
+#include <post.h>
+#include <linux/compiler.h>
DECLARE_GLOBAL_DATA_PTR;
-#if !defined(CONFIG_CONS_INDEX)
-#if defined (CONFIG_SERIAL_MULTI)
-/* with CONFIG_SERIAL_MULTI we might have no console
- * on these devices
- */
-#else
-#error "No console index specified."
-#endif /* CONFIG_SERIAL_MULTI */
-#elif (CONFIG_CONS_INDEX < 1) || (CONFIG_CONS_INDEX > 4)
-#error "Invalid console index value."
-#endif
+static struct serial_device *serial_devices;
+static struct serial_device *serial_current;
-#if CONFIG_CONS_INDEX == 1 && !defined(CONFIG_SYS_NS16550_COM1)
-#error "Console port 1 defined but not configured."
-#elif CONFIG_CONS_INDEX == 2 && !defined(CONFIG_SYS_NS16550_COM2)
-#error "Console port 2 defined but not configured."
-#elif CONFIG_CONS_INDEX == 3 && !defined(CONFIG_SYS_NS16550_COM3)
-#error "Console port 3 defined but not configured."
-#elif CONFIG_CONS_INDEX == 4 && !defined(CONFIG_SYS_NS16550_COM4)
-#error "Console port 4 defined but not configured."
-#endif
+static void serial_null(void)
+{
+}
-/* Note: The port number specified in the functions is 1 based.
- * the array is 0 based.
- */
-static NS16550_t serial_ports[4] = {
-#ifdef CONFIG_SYS_NS16550_COM1
- (NS16550_t)CONFIG_SYS_NS16550_COM1,
-#else
- NULL,
-#endif
-#ifdef CONFIG_SYS_NS16550_COM2
- (NS16550_t)CONFIG_SYS_NS16550_COM2,
-#else
- NULL,
-#endif
-#ifdef CONFIG_SYS_NS16550_COM3
- (NS16550_t)CONFIG_SYS_NS16550_COM3,
-#else
- NULL,
-#endif
-#ifdef CONFIG_SYS_NS16550_COM4
- (NS16550_t)CONFIG_SYS_NS16550_COM4
-#else
- NULL
-#endif
-};
-
-#define PORT serial_ports[port-1]
-
-#if defined(CONFIG_SERIAL_MULTI)
-
-/* Multi serial device functions */
-#define DECLARE_ESERIAL_FUNCTIONS(port) \
- int eserial##port##_init (void) {\
- int clock_divisor; \
- clock_divisor = calc_divisor(serial_ports[port-1]); \
- NS16550_init(serial_ports[port-1], clock_divisor); \
- return(0);}\
- void eserial##port##_setbrg (void) {\
- serial_setbrg_dev(port);}\
- int eserial##port##_getc (void) {\
- return serial_getc_dev(port);}\
- int eserial##port##_tstc (void) {\
- return serial_tstc_dev(port);}\
- void eserial##port##_putc (const char c) {\
- serial_putc_dev(port, c);}\
- void eserial##port##_puts (const char *s) {\
- serial_puts_dev(port, s);}
-
-/* Serial device descriptor */
-#define INIT_ESERIAL_STRUCTURE(port, name) {\
- name,\
- eserial##port##_init,\
- NULL,\
- eserial##port##_setbrg,\
- eserial##port##_getc,\
- eserial##port##_tstc,\
- eserial##port##_putc,\
- eserial##port##_puts, }
-
-#endif /* CONFIG_SERIAL_MULTI */
-
-static int calc_divisor (NS16550_t port)
+#define serial_initfunc(name) \
+ void name(void) \
+ __attribute__((weak, alias("serial_null")));
+
+serial_initfunc(mpc8xx_serial_initialize);
+serial_initfunc(ns16550_serial_initialize);
+serial_initfunc(pxa_serial_initialize);
+serial_initfunc(s3c24xx_serial_initialize);
+serial_initfunc(s5p_serial_initialize);
+serial_initfunc(zynq_serial_initalize);
+serial_initfunc(bfin_serial_initialize);
+serial_initfunc(bfin_jtag_initialize);
+serial_initfunc(mpc512x_serial_initialize);
+serial_initfunc(uartlite_serial_initialize);
+serial_initfunc(au1x00_serial_initialize);
+serial_initfunc(asc_serial_initialize);
+serial_initfunc(jz_serial_initialize);
+serial_initfunc(mpc5xx_serial_initialize);
+serial_initfunc(mpc8220_serial_initialize);
+serial_initfunc(mpc8260_scc_serial_initialize);
+serial_initfunc(mpc8260_smc_serial_initialize);
+serial_initfunc(mpc85xx_serial_initialize);
+serial_initfunc(iop480_serial_initialize);
+serial_initfunc(leon2_serial_initialize);
+serial_initfunc(leon3_serial_initialize);
+serial_initfunc(marvell_serial_initialize);
+serial_initfunc(amirix_serial_initialize);
+serial_initfunc(bmw_serial_initialize);
+serial_initfunc(cogent_serial_initialize);
+serial_initfunc(cpci750_serial_initialize);
+serial_initfunc(evb64260_serial_initialize);
+serial_initfunc(ml2_serial_initialize);
+serial_initfunc(sconsole_serial_initialize);
+serial_initfunc(p3mx_serial_initialize);
+serial_initfunc(altera_jtag_serial_initialize);
+serial_initfunc(altera_serial_initialize);
+serial_initfunc(atmel_serial_initialize);
+serial_initfunc(lpc32xx_serial_initialize);
+serial_initfunc(mcf_serial_initialize);
+serial_initfunc(ns9750_serial_initialize);
+serial_initfunc(oc_serial_initialize);
+serial_initfunc(s3c4510b_serial_initialize);
+serial_initfunc(s3c64xx_serial_initialize);
+serial_initfunc(sandbox_serial_initialize);
+serial_initfunc(clps7111_serial_initialize);
+serial_initfunc(imx_serial_initialize);
+serial_initfunc(ixp_serial_initialize);
+serial_initfunc(ks8695_serial_initialize);
+serial_initfunc(lh7a40x_serial_initialize);
+serial_initfunc(lpc2292_serial_initialize);
+serial_initfunc(max3100_serial_initialize);
+serial_initfunc(mxc_serial_initialize);
+serial_initfunc(netarm_serial_initialize);
+serial_initfunc(pl01x_serial_initialize);
+serial_initfunc(s3c44b0_serial_initialize);
+serial_initfunc(sa1100_serial_initialize);
+serial_initfunc(sh_serial_initialize);
+
+void serial_register(struct serial_device *dev)
{
-#ifdef CONFIG_OMAP1510
- /* If can't cleanly clock 115200 set div to 1 */
- if ((CONFIG_SYS_NS16550_CLK == 12000000) && (gd->baudrate == 115200)) {
- port->osc_12m_sel = OSC_12M_SEL; /* enable 6.5 * divisor */
- return (1); /* return 1 for base divisor */
- }
- port->osc_12m_sel = 0; /* clear if previsouly set */
-#endif
-#ifdef CONFIG_OMAP1610
- /* If can't cleanly clock 115200 set div to 1 */
- if ((CONFIG_SYS_NS16550_CLK == 48000000) && (gd->baudrate == 115200)) {
- return (26); /* return 26 for base divisor */
- }
+#ifdef CONFIG_NEEDS_MANUAL_RELOC
+ if (dev->start)
+ dev->start += gd->reloc_off;
+ if (dev->stop)
+ dev->stop += gd->reloc_off;
+ if (dev->setbrg)
+ dev->setbrg += gd->reloc_off;
+ if (dev->getc)
+ dev->getc += gd->reloc_off;
+ if (dev->tstc)
+ dev->tstc += gd->reloc_off;
+ if (dev->putc)
+ dev->putc += gd->reloc_off;
+ if (dev->puts)
+ dev->puts += gd->reloc_off;
#endif
-#ifdef CONFIG_APTIX
-#define MODE_X_DIV 13
-#else
-#define MODE_X_DIV 16
-#endif
+ dev->next = serial_devices;
+ serial_devices = dev;
+}
- /* Compute divisor value. Normally, we should simply return:
- * CONFIG_SYS_NS16550_CLK) / MODE_X_DIV / gd->baudrate
- * but we need to round that value by adding 0.5.
- * Rounding is especially important at high baud rates.
- */
- return (CONFIG_SYS_NS16550_CLK + (gd->baudrate * (MODE_X_DIV / 2))) /
- (MODE_X_DIV * gd->baudrate);
+void serial_initialize(void)
+{
+ mpc8xx_serial_initialize();
+ ns16550_serial_initialize();
+ pxa_serial_initialize();
+ s3c24xx_serial_initialize();
+ s5p_serial_initialize();
+ mpc512x_serial_initialize();
+ bfin_serial_initialize();
+ bfin_jtag_initialize();
+ uartlite_serial_initialize();
+ zynq_serial_initalize();
+ au1x00_serial_initialize();
+ asc_serial_initialize();
+ jz_serial_initialize();
+ mpc5xx_serial_initialize();
+ mpc8220_serial_initialize();
+ mpc8260_scc_serial_initialize();
+ mpc8260_smc_serial_initialize();
+ mpc85xx_serial_initialize();
+ iop480_serial_initialize();
+ leon2_serial_initialize();
+ leon3_serial_initialize();
+ marvell_serial_initialize();
+ amirix_serial_initialize();
+ bmw_serial_initialize();
+ cogent_serial_initialize();
+ cpci750_serial_initialize();
+ evb64260_serial_initialize();
+ ml2_serial_initialize();
+ sconsole_serial_initialize();
+ p3mx_serial_initialize();
+ altera_jtag_serial_initialize();
+ altera_serial_initialize();
+ atmel_serial_initialize();
+ lpc32xx_serial_initialize();
+ mcf_serial_initialize();
+ ns9750_serial_initialize();
+ oc_serial_initialize();
+ s3c4510b_serial_initialize();
+ s3c64xx_serial_initialize();
+ sandbox_serial_initialize();
+ clps7111_serial_initialize();
+ imx_serial_initialize();
+ ixp_serial_initialize();
+ ks8695_serial_initialize();
+ lh7a40x_serial_initialize();
+ lpc2292_serial_initialize();
+ max3100_serial_initialize();
+ mxc_serial_initialize();
+ netarm_serial_initialize();
+ pl01x_serial_initialize();
+ s3c44b0_serial_initialize();
+ sa1100_serial_initialize();
+ sh_serial_initialize();
+
+ serial_assign(default_serial_console()->name);
}
-#if !defined(CONFIG_SERIAL_MULTI)
-int serial_init (void)
+void serial_stdio_init(void)
{
- int clock_divisor;
+ struct stdio_dev dev;
+ struct serial_device *s = serial_devices;
-#ifdef CONFIG_NS87308
- initialise_ns87308();
-#endif
+ while (s) {
+ memset(&dev, 0, sizeof(dev));
-#ifdef CONFIG_SYS_NS16550_COM1
- clock_divisor = calc_divisor(serial_ports[0]);
- NS16550_init(serial_ports[0], clock_divisor);
-#endif
-#ifdef CONFIG_SYS_NS16550_COM2
- clock_divisor = calc_divisor(serial_ports[1]);
- NS16550_init(serial_ports[1], clock_divisor);
-#endif
-#ifdef CONFIG_SYS_NS16550_COM3
- clock_divisor = calc_divisor(serial_ports[2]);
- NS16550_init(serial_ports[2], clock_divisor);
-#endif
-#ifdef CONFIG_SYS_NS16550_COM4
- clock_divisor = calc_divisor(serial_ports[3]);
- NS16550_init(serial_ports[3], clock_divisor);
-#endif
+ strcpy(dev.name, s->name);
+ dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT;
- return (0);
-}
-#endif
+ dev.start = s->start;
+ dev.stop = s->stop;
+ dev.putc = s->putc;
+ dev.puts = s->puts;
+ dev.getc = s->getc;
+ dev.tstc = s->tstc;
-void
-_serial_putc(const char c,const int port)
-{
- if (c == '\n')
- NS16550_putc(PORT, '\r');
+ stdio_register(&dev);
- NS16550_putc(PORT, c);
+ s = s->next;
+ }
}
-void
-_serial_putc_raw(const char c,const int port)
+int serial_assign(const char *name)
{
- NS16550_putc(PORT, c);
-}
+ struct serial_device *s;
-void
-_serial_puts (const char *s,const int port)
-{
- while (*s) {
- _serial_putc (*s++,port);
+ for (s = serial_devices; s; s = s->next) {
+ if (strcmp(s->name, name) == 0) {
+ serial_current = s;
+ return 0;
+ }
}
-}
-
-int
-_serial_getc(const int port)
-{
- return NS16550_getc(PORT);
+ return 1;
}
-int
-_serial_tstc(const int port)
+void serial_reinit_all(void)
{
- return NS16550_tstc(PORT);
+ struct serial_device *s;
+
+ for (s = serial_devices; s; s = s->next)
+ s->start();
}
-void
-_serial_setbrg (const int port)
+static struct serial_device *get_current(void)
{
- int clock_divisor;
+ struct serial_device *dev;
- clock_divisor = calc_divisor(PORT);
- NS16550_reinit(PORT, clock_divisor);
-}
+ if (!(gd->flags & GD_FLG_RELOC) || !serial_current) {
+ dev = default_serial_console();
-#if defined(CONFIG_SERIAL_MULTI)
-static inline void
-serial_putc_dev(unsigned int dev_index,const char c)
-{
- _serial_putc(c,dev_index);
-}
+ /* We must have a console device */
+ if (!dev) {
+#ifdef CONFIG_SPL_BUILD
+ puts("Cannot find console\n");
+ hang();
#else
-void
-serial_putc(const char c)
-{
- _serial_putc(c,CONFIG_CONS_INDEX);
-}
+ panic("Cannot find console\n");
#endif
-
-#if defined(CONFIG_SERIAL_MULTI)
-static inline void
-serial_putc_raw_dev(unsigned int dev_index,const char c)
-{
- _serial_putc_raw(c,dev_index);
-}
-#else
-void
-serial_putc_raw(const char c)
-{
- _serial_putc_raw(c,CONFIG_CONS_INDEX);
+ }
+ } else
+ dev = serial_current;
+ return dev;
}
-#endif
-#if defined(CONFIG_SERIAL_MULTI)
-static inline void
-serial_puts_dev(unsigned int dev_index,const char *s)
-{
- _serial_puts(s,dev_index);
-}
-#else
-void
-serial_puts(const char *s)
+int serial_init(void)
{
- _serial_puts(s,CONFIG_CONS_INDEX);
+ return get_current()->start();
}
-#endif
-#if defined(CONFIG_SERIAL_MULTI)
-static inline int
-serial_getc_dev(unsigned int dev_index)
+void serial_setbrg(void)
{
- return _serial_getc(dev_index);
+ get_current()->setbrg();
}
-#else
-int
-serial_getc(void)
-{
- return _serial_getc(CONFIG_CONS_INDEX);
-}
-#endif
-#if defined(CONFIG_SERIAL_MULTI)
-static inline int
-serial_tstc_dev(unsigned int dev_index)
+int serial_getc(void)
{
- return _serial_tstc(dev_index);
+ return get_current()->getc();
}
-#else
-int
-serial_tstc(void)
+
+int serial_tstc(void)
{
- return _serial_tstc(CONFIG_CONS_INDEX);
+ return get_current()->tstc();
}
-#endif
-#if defined(CONFIG_SERIAL_MULTI)
-static inline void
-serial_setbrg_dev(unsigned int dev_index)
+void serial_putc(const char c)
{
- _serial_setbrg(dev_index);
+ get_current()->putc(c);
}
-#else
-void
-serial_setbrg(void)
+
+void serial_puts(const char *s)
{
- _serial_setbrg(CONFIG_CONS_INDEX);
+ get_current()->puts(s);
}
-#endif
-#if defined(CONFIG_SERIAL_MULTI)
-
-DECLARE_ESERIAL_FUNCTIONS(1);
-struct serial_device eserial1_device =
- INIT_ESERIAL_STRUCTURE(1, "eserial0");
-DECLARE_ESERIAL_FUNCTIONS(2);
-struct serial_device eserial2_device =
- INIT_ESERIAL_STRUCTURE(2, "eserial1");
-DECLARE_ESERIAL_FUNCTIONS(3);
-struct serial_device eserial3_device =
- INIT_ESERIAL_STRUCTURE(3, "eserial2");
-DECLARE_ESERIAL_FUNCTIONS(4);
-struct serial_device eserial4_device =
- INIT_ESERIAL_STRUCTURE(4, "eserial3");
-
-__weak struct serial_device *default_serial_console(void)
+#if CONFIG_POST & CONFIG_SYS_POST_UART
+static const int bauds[] = CONFIG_SYS_BAUDRATE_TABLE;
+
+/* Mark weak until post/cpu/.../uart.c migrate over */
+__weak
+int uart_post_test(int flags)
{
-#if CONFIG_CONS_INDEX == 1
- return &eserial1_device;
-#elif CONFIG_CONS_INDEX == 2
- return &eserial2_device;
-#elif CONFIG_CONS_INDEX == 3
- return &eserial3_device;
-#elif CONFIG_CONS_INDEX == 4
- return &eserial4_device;
-#else
-#error "Bad CONFIG_CONS_INDEX."
-#endif
-}
+ unsigned char c;
+ int ret, saved_baud, b;
+ struct serial_device *saved_dev, *s;
+ bd_t *bd = gd->bd;
+
+ /* Save current serial state */
+ ret = 0;
+ saved_dev = serial_current;
+ saved_baud = bd->bi_baudrate;
+
+ for (s = serial_devices; s; s = s->next) {
+ /* If this driver doesn't support loop back, skip it */
+ if (!s->loop)
+ continue;
+
+ /* Test the next device */
+ serial_current = s;
+
+ ret = serial_init();
+ if (ret)
+ goto done;
+
+ /* Consume anything that happens to be queued */
+ while (serial_tstc())
+ serial_getc();
+
+ /* Enable loop back */
+ s->loop(1);
+
+ /* Test every available baud rate */
+ for (b = 0; b < ARRAY_SIZE(bauds); ++b) {
+ bd->bi_baudrate = bauds[b];
+ serial_setbrg();
+
+ /*
+ * Stick to printable chars to avoid issues:
+ * - terminal corruption
+ * - serial program reacting to sequences and sending
+ * back random extra data
+ * - most serial drivers add in extra chars (like \r\n)
+ */
+ for (c = 0x20; c < 0x7f; ++c) {
+ /* Send it out */
+ serial_putc(c);
+
+ /* Make sure it's the same one */
+ ret = (c != serial_getc());
+ if (ret) {
+ s->loop(0);
+ goto done;
+ }
+
+ /* Clean up the output in case it was sent */
+ serial_putc('\b');
+ ret = ('\b' != serial_getc());
+ if (ret) {
+ s->loop(0);
+ goto done;
+ }
+ }
+ }
+
+ /* Disable loop back */
+ s->loop(0);
+
+ /* XXX: There is no serial_stop() !? */
+ if (s->stop)
+ s->stop();
+ }
+
+ done:
+ /* Restore previous serial state */
+ serial_current = saved_dev;
+ bd->bi_baudrate = saved_baud;
+ serial_reinit_all();
+ serial_setbrg();
-#endif /* CONFIG_SERIAL_MULTI */
+ return ret;
+}
+#endif
diff --git a/drivers/serial/serial_clps7111.c b/drivers/serial/serial_clps7111.c
index a6aecad..65473e8 100644
--- a/drivers/serial/serial_clps7111.c
+++ b/drivers/serial/serial_clps7111.c
@@ -33,7 +33,7 @@
DECLARE_GLOBAL_DATA_PTR;
-void serial_setbrg (void)
+static void clps7111_serial_setbrg(void)
{
unsigned int reg = 0;
@@ -63,7 +63,7 @@ void serial_setbrg (void)
* are always 8 data bits, no parity, 1 stop bit, no start bits.
*
*/
-int serial_init (void)
+static int clps7111_serial_init(void)
{
serial_setbrg ();
@@ -74,7 +74,7 @@ int serial_init (void)
/*
* Output a single byte to the serial port.
*/
-void serial_putc (const char c)
+static void clps7111_serial_putc(const char c)
{
int tmo;
@@ -95,7 +95,7 @@ void serial_putc (const char c)
* otherwise. When the function is succesfull, the character read is
* written into its argument c.
*/
-int serial_tstc (void)
+static int clps7111_serial_tstc(void)
{
return !(IO_SYSFLG1 & SYSFLG1_URXFE);
}
@@ -105,17 +105,37 @@ int serial_tstc (void)
* otherwise. When the function is succesfull, the character read is
* written into its argument c.
*/
-int serial_getc (void)
+static int clps7111_serial_getc(void)
{
while (IO_SYSFLG1 & SYSFLG1_URXFE);
return IO_UARTDR1 & 0xff;
}
-void
-serial_puts (const char *s)
+static void clps7111_serial_puts(const char *s)
{
while (*s) {
serial_putc (*s++);
}
}
+
+static struct serial_device clps7111_serial_drv = {
+ .name = "clps7111_serial",
+ .start = clps7111_serial_init,
+ .stop = NULL,
+ .setbrg = clps7111_serial_setbrg,
+ .putc = clps7111_serial_putc,
+ .puts = clps7111_serial_puts,
+ .getc = clps7111_serial_getc,
+ .tstc = clps7111_serial_tstc,
+};
+
+void clps7111_serial_initialize(void)
+{
+ serial_register(&clps7111_serial_drv);
+}
+
+__weak struct serial_device *default_serial_console(void)
+{
+ return &clps7111_serial_drv;
+}
diff --git a/drivers/serial/serial_imx.c b/drivers/serial/serial_imx.c
index b9ca748..6c075b5 100644
--- a/drivers/serial/serial_imx.c
+++ b/drivers/serial/serial_imx.c
@@ -19,6 +19,8 @@
#include <common.h>
#include <asm/arch/imx-regs.h>
+#include <serial.h>
+#include <linux/compiler.h>
#if defined CONFIG_IMX_SERIAL1
#define UART_BASE IMX_UART1_BASE
@@ -50,7 +52,7 @@ struct imx_serial {
DECLARE_GLOBAL_DATA_PTR;
-void serial_setbrg (void)
+static void imx_serial_setbrg(void)
{
serial_init();
}
@@ -62,7 +64,7 @@ extern void imx_gpio_mode(int gpio_mode);
* are always 8 data bits, no parity, 1 stop bit, no start bits.
*
*/
-int serial_init (void)
+static int imx_serial_init(void)
{
volatile struct imx_serial* base = (struct imx_serial *)UART_BASE;
unsigned int ufcr_rfdiv;
@@ -163,7 +165,7 @@ int serial_init (void)
* otherwise. When the function is successful, the character read is
* written into its argument c.
*/
-int serial_getc (void)
+static int imx_serial_getc(void)
{
volatile struct imx_serial* base = (struct imx_serial *)UART_BASE;
unsigned char ch;
@@ -185,7 +187,7 @@ int hwflow_onoff(int on)
/*
* Output a single byte to the serial port.
*/
-void serial_putc (const char c)
+static void imx_serial_putc(const char c)
{
volatile struct imx_serial* base = (struct imx_serial *)UART_BASE;
@@ -202,7 +204,7 @@ void serial_putc (const char c)
/*
* Test whether a character is in the RX buffer
*/
-int serial_tstc (void)
+static int imx_serial_tstc(void)
{
volatile struct imx_serial* base = (struct imx_serial *)UART_BASE;
@@ -212,10 +214,30 @@ int serial_tstc (void)
return 1;
}
-void
-serial_puts (const char *s)
+static void imx_serial_puts(const char *s)
{
while (*s) {
serial_putc (*s++);
}
}
+
+static struct serial_device imx_serial_drv = {
+ .name = "imx_serial",
+ .start = imx_serial_init,
+ .stop = NULL,
+ .setbrg = imx_serial_setbrg,
+ .putc = imx_serial_putc,
+ .puts = imx_serial_puts,
+ .getc = imx_serial_getc,
+ .tstc = imx_serial_tstc,
+};
+
+void imx_serial_initialize(void)
+{
+ serial_register(&imx_serial_drv);
+}
+
+__weak struct serial_device *default_serial_console(void)
+{
+ return &imx_serial_drv;
+}
diff --git a/drivers/serial/serial_ixp.c b/drivers/serial/serial_ixp.c
index a9acd47..c8b3658 100644
--- a/drivers/serial/serial_ixp.c
+++ b/drivers/serial/serial_ixp.c
@@ -31,6 +31,8 @@
#include <common.h>
#include <asm/arch/ixp425.h>
#include <watchdog.h>
+#include <serial.h>
+#include <linux/compiler.h>
/*
* 14.7456 MHz
@@ -41,7 +43,7 @@
DECLARE_GLOBAL_DATA_PTR;
-void serial_setbrg (void)
+static void ixp_serial_setbrg(void)
{
unsigned int quot = 0;
int uart = CONFIG_SYS_IXP425_CONSOLE;
@@ -72,7 +74,7 @@ void serial_setbrg (void)
* are always 8 data bits, no parity, 1 stop bit, no start bits.
*
*/
-int serial_init (void)
+static int ixp_serial_init(void)
{
serial_setbrg ();
@@ -83,7 +85,7 @@ int serial_init (void)
/*
* Output a single byte to the serial port.
*/
-void serial_putc (const char c)
+static void ixp_serial_putc(const char c)
{
/* wait for room in the tx FIFO on UART */
while ((LSR(CONFIG_SYS_IXP425_CONSOLE) & LSR_TEMT) == 0)
@@ -101,7 +103,7 @@ void serial_putc (const char c)
* otherwise. When the function is succesfull, the character read is
* written into its argument c.
*/
-int serial_tstc (void)
+static int ixp_serial_tstc(void)
{
return LSR(CONFIG_SYS_IXP425_CONSOLE) & LSR_DR;
}
@@ -111,7 +113,7 @@ int serial_tstc (void)
* otherwise. When the function is succesfull, the character read is
* written into its argument c.
*/
-int serial_getc (void)
+static int ixp_serial_getc(void)
{
while (!(LSR(CONFIG_SYS_IXP425_CONSOLE) & LSR_DR))
WATCHDOG_RESET(); /* Reset HW Watchdog, if needed */
@@ -119,10 +121,30 @@ int serial_getc (void)
return (char) RBR(CONFIG_SYS_IXP425_CONSOLE) & 0xff;
}
-void
-serial_puts (const char *s)
+static void ixp_serial_puts(const char *s)
{
while (*s) {
serial_putc (*s++);
}
}
+
+static struct serial_device ixp_serial_drv = {
+ .name = "ixp_serial",
+ .start = ixp_serial_init,
+ .stop = NULL,
+ .setbrg = ixp_serial_setbrg,
+ .putc = ixp_serial_putc,
+ .puts = ixp_serial_puts,
+ .getc = ixp_serial_getc,
+ .tstc = ixp_serial_tstc,
+};
+
+void ixp_serial_initialize(void)
+{
+ serial_register(&ixp_serial_drv);
+}
+
+__weak struct serial_device *default_serial_console(void)
+{
+ return &ixp_serial_drv;
+}
diff --git a/drivers/serial/serial_ks8695.c b/drivers/serial/serial_ks8695.c
index aacd1be..60e8007 100644
--- a/drivers/serial/serial_ks8695.c
+++ b/drivers/serial/serial_ks8695.c
@@ -20,6 +20,8 @@
#include <common.h>
#include <asm/arch/platform.h>
+#include <serial.h>
+#include <linux/compiler.h>
#ifndef CONFIG_SERIAL1
#error "Bad: you didn't configure serial ..."
@@ -54,7 +56,7 @@ struct ks8695uart {
int serial_console = 1;
-void serial_setbrg(void)
+static void ks8695_serial_setbrg(void)
{
volatile struct ks8695uart *uartp = KS8695_UART_ADDR;
@@ -63,14 +65,14 @@ void serial_setbrg(void)
uartp->LCR = KS8695_UART_LINEC_WLEN8;
}
-int serial_init(void)
+static int ks8695_serial_init(void)
{
serial_console = 1;
serial_setbrg();
return 0;
}
-void serial_raw_putc(const char c)
+static void ks8695_serial_raw_putc(const char c)
{
volatile struct ks8695uart *uartp = KS8695_UART_ADDR;
int i;
@@ -83,16 +85,16 @@ void serial_raw_putc(const char c)
uartp->TX = c;
}
-void serial_putc(const char c)
+static void ks8695_serial_putc(const char c)
{
if (serial_console) {
- serial_raw_putc(c);
+ ks8695_serial_raw_putc(c);
if (c == '\n')
- serial_raw_putc('\r');
+ ks8695_serial_raw_putc('\r');
}
}
-int serial_tstc(void)
+static int ks8695_serial_tstc(void)
{
volatile struct ks8695uart *uartp = KS8695_UART_ADDR;
if (serial_console)
@@ -100,14 +102,14 @@ int serial_tstc(void)
return 0;
}
-void serial_puts(const char *s)
+static void ks8695_serial_puts(const char *s)
{
char c;
while ((c = *s++) != 0)
serial_putc(c);
}
-int serial_getc(void)
+static int ks8695_serial_getc(void)
{
volatile struct ks8695uart *uartp = KS8695_UART_ADDR;
@@ -115,3 +117,24 @@ int serial_getc(void)
;
return (uartp->RX);
}
+
+static struct serial_device ks8695_serial_drv = {
+ .name = "ks8695_serial",
+ .start = ks8695_serial_init,
+ .stop = NULL,
+ .setbrg = ks8695_serial_setbrg,
+ .putc = ks8695_serial_putc,
+ .puts = ks8695_serial_puts,
+ .getc = ks8695_serial_getc,
+ .tstc = ks8695_serial_tstc,
+};
+
+void ks8695_serial_initialize(void)
+{
+ serial_register(&ks8695_serial_drv);
+}
+
+__weak struct serial_device *default_serial_console(void)
+{
+ return &ks8695_serial_drv;
+}
diff --git a/drivers/serial/serial_lh7a40x.c b/drivers/serial/serial_lh7a40x.c
index 4767489..6c96285 100644
--- a/drivers/serial/serial_lh7a40x.c
+++ b/drivers/serial/serial_lh7a40x.c
@@ -33,7 +33,7 @@ DECLARE_GLOBAL_DATA_PTR;
# error "No console configured ... "
#endif
-void serial_setbrg (void)
+static void lh7a40x_serial_setbrg(void)
{
lh7a40x_uart_t* uart = LH7A40X_UART_PTR(UART_CONSOLE);
int i;
@@ -61,7 +61,7 @@ void serial_setbrg (void)
* are always 8 data bits, no parity, 1 stop bit, no start bits.
*
*/
-int serial_init (void)
+static int lh7a40x_serial_init(void)
{
lh7a40x_uart_t* uart = LH7A40X_UART_PTR(UART_CONSOLE);
@@ -95,7 +95,7 @@ int serial_init (void)
* otherwise. When the function is succesfull, the character read is
* written into its argument c.
*/
-int serial_getc (void)
+static int lh7a40x_serial_getc(void)
{
lh7a40x_uart_t* uart = LH7A40X_UART_PTR(UART_CONSOLE);
@@ -141,7 +141,7 @@ void enable_putc(void)
/*
* Output a single byte to the serial port.
*/
-void serial_putc (const char c)
+static void lh7a40x_serial_putc(const char c)
{
lh7a40x_uart_t* uart = LH7A40X_UART_PTR(UART_CONSOLE);
@@ -168,17 +168,37 @@ void serial_putc (const char c)
/*
* Test whether a character is in the RX buffer
*/
-int serial_tstc (void)
+static int lh7a40x_serial_tstc(void)
{
lh7a40x_uart_t* uart = LH7A40X_UART_PTR(UART_CONSOLE);
return(!(uart->status & UART_RXFE));
}
-void
-serial_puts (const char *s)
+static void lh7a40x_serial_puts(const char *s)
{
while (*s) {
serial_putc (*s++);
}
}
+
+static struct serial_device lh7a40x_serial_drv = {
+ .name = "lh7a40x_serial",
+ .start = lh7a40x_serial_init,
+ .stop = NULL,
+ .setbrg = lh7a40x_serial_setbrg,
+ .putc = lh7a40x_serial_putc,
+ .puts = lh7a40x_serial_puts,
+ .getc = lh7a40x_serial_getc,
+ .tstc = lh7a40x_serial_tstc,
+};
+
+void lh7a40x_serial_initialize(void)
+{
+ serial_register(&lh7a40x_serial_drv);
+}
+
+__weak struct serial_device *default_serial_console(void)
+{
+ return &lh7a40x_serial_drv;
+}
diff --git a/drivers/serial/serial_lpc2292.c b/drivers/serial/serial_lpc2292.c
index e3a60b6..fcab202 100644
--- a/drivers/serial/serial_lpc2292.c
+++ b/drivers/serial/serial_lpc2292.c
@@ -33,7 +33,7 @@
DECLARE_GLOBAL_DATA_PTR;
-void serial_setbrg (void)
+static void lpc2292_serial_setbrg(void)
{
unsigned short divisor = 0;
@@ -57,7 +57,7 @@ void serial_setbrg (void)
PUT8(U0FCR, 1); /* Enable RX and TX FIFOs */
}
-int serial_init (void)
+static int lpc2292_serial_init(void)
{
unsigned long pinsel0;
@@ -71,7 +71,7 @@ int serial_init (void)
return (0);
}
-void serial_putc (const char c)
+static void lpc2292_serial_putc(const char c)
{
if (c == '\n')
{
@@ -83,14 +83,13 @@ void serial_putc (const char c)
PUT8(U0THR, c);
}
-int serial_getc (void)
+static int lpc2292_serial_getc(void)
{
while((GET8(U0LSR) & 1) == 0);
return GET8(U0RBR);
}
-void
-serial_puts (const char *s)
+static void lpc2292_serial_puts(const char *s)
{
while (*s) {
serial_putc (*s++);
@@ -98,7 +97,28 @@ serial_puts (const char *s)
}
/* Test if there is a byte to read */
-int serial_tstc (void)
+static int lpc2292_serial_tstc(void)
{
return (GET8(U0LSR) & 1);
}
+
+static struct serial_device lpc2292_serial_drv = {
+ .name = "lpc2292_serial",
+ .start = lpc2292_serial_init,
+ .stop = NULL,
+ .setbrg = lpc2292_serial_setbrg,
+ .putc = lpc2292_serial_putc,
+ .puts = lpc2292_serial_puts,
+ .getc = lpc2292_serial_getc,
+ .tstc = lpc2292_serial_tstc,
+};
+
+void lpc2292_serial_initialize(void)
+{
+ serial_register(&lpc2292_serial_drv);
+}
+
+__weak struct serial_device *default_serial_console(void)
+{
+ return &lpc2292_serial_drv;
+}
diff --git a/drivers/serial/serial_max3100.c b/drivers/serial/serial_max3100.c
index 4abc271..3533cfc 100644
--- a/drivers/serial/serial_max3100.c
+++ b/drivers/serial/serial_max3100.c
@@ -25,6 +25,8 @@
#include <common.h>
#include <watchdog.h>
+#include <serial.h>
+#include <linux/compiler.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -149,7 +151,7 @@ static int rxfifo_in;
static int rxfifo_out;
static unsigned char rxfifo_buf[16];
-static void max3100_putc(int c)
+static void max3100_serial_putc_raw(int c)
{
unsigned int rx;
@@ -164,7 +166,7 @@ static void max3100_putc(int c)
}
}
-static int max3100_getc(void)
+static int max3100_serial_getc(void)
{
int c;
unsigned int rx;
@@ -190,7 +192,7 @@ static int max3100_getc(void)
return c;
}
-static int max3100_tstc(void)
+static int max3100_serial_tstc(void)
{
unsigned int rx;
@@ -213,7 +215,7 @@ static int max3100_tstc(void)
return 1;
}
-int serial_init(void)
+static int max3100_serial_init(void)
{
unsigned int wconf, rconf;
int i;
@@ -268,31 +270,41 @@ int serial_init(void)
return (0);
}
-void serial_putc(const char c)
+static void max3100_serial_putc(const char c)
{
if (c == '\n')
- max3100_putc('\r');
+ max3100_serial_putc_raw('\r');
- max3100_putc(c);
+ max3100_serial_putc_raw(c);
}
-void serial_puts(const char *s)
+static void max3100_serial_puts(const char *s)
{
while (*s)
- serial_putc (*s++);
+ max3100_serial_putc_raw(*s++);
}
-int serial_getc(void)
+static void max3100_serial_setbrg(void)
{
- return max3100_getc();
}
-int serial_tstc(void)
+static struct serial_device max3100_serial_drv = {
+ .name = "max3100_serial",
+ .start = max3100_serial_init,
+ .stop = NULL,
+ .setbrg = max3100_serial_setbrg,
+ .putc = max3100_serial_putc,
+ .puts = max3100_serial_puts,
+ .getc = max3100_serial_getc,
+ .tstc = max3100_serial_tstc,
+};
+
+void max3100_serial_initialize(void)
{
- return max3100_tstc();
+ serial_register(&max3100_serial_drv);
}
-/* XXX WTF? */
-void serial_setbrg(void)
+__weak struct serial_device *default_serial_console(void)
{
+ return &max3100_serial_drv;
}
diff --git a/drivers/serial/serial_mxc.c b/drivers/serial/serial_mxc.c
index af00b9c..b0612f5 100644
--- a/drivers/serial/serial_mxc.c
+++ b/drivers/serial/serial_mxc.c
@@ -21,6 +21,8 @@
#include <watchdog.h>
#include <asm/arch/imx-regs.h>
#include <asm/arch/clock.h>
+#include <serial.h>
+#include <linux/compiler.h>
#define __REG(x) (*((volatile u32 *)(x)))
@@ -30,10 +32,6 @@
#define UART_PHYS CONFIG_MXC_UART_BASE
-#ifdef CONFIG_SERIAL_MULTI
-#warning "MXC driver does not support MULTI serials."
-#endif
-
/* Register definitions */
#define URXD 0x0 /* Receiver Register */
#define UTXD 0x40 /* Transmitter Register */
@@ -145,7 +143,7 @@
DECLARE_GLOBAL_DATA_PTR;
-void serial_setbrg (void)
+static void mxc_serial_setbrg(void)
{
u32 clk = imx_get_uartclk();
@@ -158,14 +156,14 @@ void serial_setbrg (void)
}
-int serial_getc (void)
+static int mxc_serial_getc(void)
{
while (__REG(UART_PHYS + UTS) & UTS_RXEMPTY)
WATCHDOG_RESET();
return (__REG(UART_PHYS + URXD) & URXD_RX_DATA); /* mask out status from upper word */
}
-void serial_putc (const char c)
+static void mxc_serial_putc(const char c)
{
__REG(UART_PHYS + UTXD) = c;
@@ -181,7 +179,7 @@ void serial_putc (const char c)
/*
* Test whether a character is in the RX buffer
*/
-int serial_tstc (void)
+static int mxc_serial_tstc(void)
{
/* If receive fifo is empty, return false */
if (__REG(UART_PHYS + UTS) & UTS_RXEMPTY)
@@ -189,8 +187,7 @@ int serial_tstc (void)
return 1;
}
-void
-serial_puts (const char *s)
+static void mxc_serial_puts(const char *s)
{
while (*s) {
serial_putc (*s++);
@@ -202,7 +199,7 @@ serial_puts (const char *s)
* are always 8 data bits, no parity, 1 stop bit, no start bits.
*
*/
-int serial_init (void)
+static int mxc_serial_init(void)
{
__REG(UART_PHYS + UCR1) = 0x0;
__REG(UART_PHYS + UCR2) = 0x0;
@@ -224,3 +221,24 @@ int serial_init (void)
return 0;
}
+
+static struct serial_device mxc_serial_drv = {
+ .name = "mxc_serial",
+ .start = mxc_serial_init,
+ .stop = NULL,
+ .setbrg = mxc_serial_setbrg,
+ .putc = mxc_serial_putc,
+ .puts = mxc_serial_puts,
+ .getc = mxc_serial_getc,
+ .tstc = mxc_serial_tstc,
+};
+
+void mxc_serial_initialize(void)
+{
+ serial_register(&mxc_serial_drv);
+}
+
+__weak struct serial_device *default_serial_console(void)
+{
+ return &mxc_serial_drv;
+}
diff --git a/drivers/serial/serial_netarm.c b/drivers/serial/serial_netarm.c
index d04790d..d30adc3 100644
--- a/drivers/serial/serial_netarm.c
+++ b/drivers/serial/serial_netarm.c
@@ -59,7 +59,7 @@ extern void _netarm_led_FAIL1(void);
/*
* Setup both serial i/f with given baudrate
*/
-void serial_setbrg (void)
+static void netarm_serial_setbrg(void)
{
/* set 0 ... make sure pins are configured for serial */
#if !defined(CONFIG_NETARM_NS7520)
@@ -108,7 +108,7 @@ void serial_setbrg (void)
* Initialise the serial port with the given baudrate. The settings
* are always 8 data bits, no parity, 1 stop bit, no start bits.
*/
-int serial_init (void)
+static int netarm_serial_init(void)
{
serial_setbrg ();
return 0;
@@ -118,7 +118,7 @@ int serial_init (void)
/*
* Output a single byte to the serial port.
*/
-void serial_putc (const char c)
+static void netarm_serial_putc(const char c)
{
volatile unsigned char *fifo;
@@ -135,7 +135,7 @@ void serial_putc (const char c)
* Test of a single byte from the serial port. Returns 1 on success, 0
* otherwise.
*/
-int serial_tstc(void)
+static int netarm_serial_tstc(void)
{
return serial_reg_ch1->status_a & NETARM_SER_STATA_RX_RDY;
}
@@ -144,7 +144,7 @@ int serial_tstc(void)
* Read a single byte from the serial port. Returns 1 on success, 0
* otherwise.
*/
-int serial_getc (void)
+static int netarm_serial_getc(void)
{
unsigned int ch_uint;
volatile unsigned int *fifo;
@@ -182,9 +182,30 @@ int serial_getc (void)
return ch_uint & 0xff;
}
-void serial_puts (const char *s)
+static void netarm_serial_puts(const char *s)
{
while (*s) {
serial_putc (*s++);
}
}
+
+static struct serial_device netarm_serial_drv = {
+ .name = "netarm_serial",
+ .start = netarm_serial_init,
+ .stop = NULL,
+ .setbrg = netarm_serial_setbrg,
+ .putc = netarm_serial_putc,
+ .puts = netarm_serial_puts,
+ .getc = netarm_serial_getc,
+ .tstc = netarm_serial_tstc,
+};
+
+void netarm_serial_initialize(void)
+{
+ serial_register(&netarm_serial_drv);
+}
+
+__weak struct serial_device *default_serial_console(void)
+{
+ return &netarm_serial_drv;
+}
diff --git a/drivers/serial/serial_ns16550.c b/drivers/serial/serial_ns16550.c
new file mode 100644
index 0000000..b5d1248
--- /dev/null
+++ b/drivers/serial/serial_ns16550.c
@@ -0,0 +1,264 @@
+/*
+ * (C) Copyright 2000
+ * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <linux/compiler.h>
+
+#include <ns16550.h>
+#ifdef CONFIG_NS87308
+#include <ns87308.h>
+#endif
+
+#include <serial.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#if !defined(CONFIG_CONS_INDEX)
+#elif (CONFIG_CONS_INDEX < 1) || (CONFIG_CONS_INDEX > 4)
+#error "Invalid console index value."
+#endif
+
+#if CONFIG_CONS_INDEX == 1 && !defined(CONFIG_SYS_NS16550_COM1)
+#error "Console port 1 defined but not configured."
+#elif CONFIG_CONS_INDEX == 2 && !defined(CONFIG_SYS_NS16550_COM2)
+#error "Console port 2 defined but not configured."
+#elif CONFIG_CONS_INDEX == 3 && !defined(CONFIG_SYS_NS16550_COM3)
+#error "Console port 3 defined but not configured."
+#elif CONFIG_CONS_INDEX == 4 && !defined(CONFIG_SYS_NS16550_COM4)
+#error "Console port 4 defined but not configured."
+#endif
+
+/* Note: The port number specified in the functions is 1 based.
+ * the array is 0 based.
+ */
+static NS16550_t serial_ports[4] = {
+#ifdef CONFIG_SYS_NS16550_COM1
+ (NS16550_t)CONFIG_SYS_NS16550_COM1,
+#else
+ NULL,
+#endif
+#ifdef CONFIG_SYS_NS16550_COM2
+ (NS16550_t)CONFIG_SYS_NS16550_COM2,
+#else
+ NULL,
+#endif
+#ifdef CONFIG_SYS_NS16550_COM3
+ (NS16550_t)CONFIG_SYS_NS16550_COM3,
+#else
+ NULL,
+#endif
+#ifdef CONFIG_SYS_NS16550_COM4
+ (NS16550_t)CONFIG_SYS_NS16550_COM4
+#else
+ NULL
+#endif
+};
+
+#define PORT serial_ports[port-1]
+
+/* Multi serial device functions */
+#define DECLARE_ESERIAL_FUNCTIONS(port) \
+ int eserial##port##_init (void) {\
+ int clock_divisor; \
+ clock_divisor = calc_divisor(serial_ports[port-1]); \
+ NS16550_init(serial_ports[port-1], clock_divisor); \
+ return(0);}\
+ void eserial##port##_setbrg (void) {\
+ serial_setbrg_dev(port);}\
+ int eserial##port##_getc (void) {\
+ return serial_getc_dev(port);}\
+ int eserial##port##_tstc (void) {\
+ return serial_tstc_dev(port);}\
+ void eserial##port##_putc (const char c) {\
+ serial_putc_dev(port, c);}\
+ void eserial##port##_puts (const char *s) {\
+ serial_puts_dev(port, s);}
+
+/* Serial device descriptor */
+#define INIT_ESERIAL_STRUCTURE(port, __name) { \
+ .name = __name, \
+ .start = eserial##port##_init, \
+ .stop = NULL, \
+ .setbrg = eserial##port##_setbrg, \
+ .getc = eserial##port##_getc, \
+ .tstc = eserial##port##_tstc, \
+ .putc = eserial##port##_putc, \
+ .puts = eserial##port##_puts, \
+}
+
+static int calc_divisor (NS16550_t port)
+{
+#ifdef CONFIG_OMAP1510
+ /* If can't cleanly clock 115200 set div to 1 */
+ if ((CONFIG_SYS_NS16550_CLK == 12000000) && (gd->baudrate == 115200)) {
+ port->osc_12m_sel = OSC_12M_SEL; /* enable 6.5 * divisor */
+ return (1); /* return 1 for base divisor */
+ }
+ port->osc_12m_sel = 0; /* clear if previsouly set */
+#endif
+#ifdef CONFIG_OMAP1610
+ /* If can't cleanly clock 115200 set div to 1 */
+ if ((CONFIG_SYS_NS16550_CLK == 48000000) && (gd->baudrate == 115200)) {
+ return (26); /* return 26 for base divisor */
+ }
+#endif
+
+#ifdef CONFIG_APTIX
+#define MODE_X_DIV 13
+#else
+#define MODE_X_DIV 16
+#endif
+
+ /* Compute divisor value. Normally, we should simply return:
+ * CONFIG_SYS_NS16550_CLK) / MODE_X_DIV / gd->baudrate
+ * but we need to round that value by adding 0.5.
+ * Rounding is especially important at high baud rates.
+ */
+ return (CONFIG_SYS_NS16550_CLK + (gd->baudrate * (MODE_X_DIV / 2))) /
+ (MODE_X_DIV * gd->baudrate);
+}
+
+void
+_serial_putc(const char c,const int port)
+{
+ if (c == '\n')
+ NS16550_putc(PORT, '\r');
+
+ NS16550_putc(PORT, c);
+}
+
+void
+_serial_putc_raw(const char c,const int port)
+{
+ NS16550_putc(PORT, c);
+}
+
+void
+_serial_puts (const char *s,const int port)
+{
+ while (*s) {
+ _serial_putc (*s++,port);
+ }
+}
+
+
+int
+_serial_getc(const int port)
+{
+ return NS16550_getc(PORT);
+}
+
+int
+_serial_tstc(const int port)
+{
+ return NS16550_tstc(PORT);
+}
+
+void
+_serial_setbrg (const int port)
+{
+ int clock_divisor;
+
+ clock_divisor = calc_divisor(PORT);
+ NS16550_reinit(PORT, clock_divisor);
+}
+
+static inline void
+serial_putc_dev(unsigned int dev_index,const char c)
+{
+ _serial_putc(c,dev_index);
+}
+
+static inline void
+serial_putc_raw_dev(unsigned int dev_index,const char c)
+{
+ _serial_putc_raw(c,dev_index);
+}
+
+static inline void
+serial_puts_dev(unsigned int dev_index,const char *s)
+{
+ _serial_puts(s,dev_index);
+}
+
+static inline int
+serial_getc_dev(unsigned int dev_index)
+{
+ return _serial_getc(dev_index);
+}
+
+static inline int
+serial_tstc_dev(unsigned int dev_index)
+{
+ return _serial_tstc(dev_index);
+}
+
+static inline void
+serial_setbrg_dev(unsigned int dev_index)
+{
+ _serial_setbrg(dev_index);
+}
+
+DECLARE_ESERIAL_FUNCTIONS(1);
+struct serial_device eserial1_device =
+ INIT_ESERIAL_STRUCTURE(1, "eserial0");
+DECLARE_ESERIAL_FUNCTIONS(2);
+struct serial_device eserial2_device =
+ INIT_ESERIAL_STRUCTURE(2, "eserial1");
+DECLARE_ESERIAL_FUNCTIONS(3);
+struct serial_device eserial3_device =
+ INIT_ESERIAL_STRUCTURE(3, "eserial2");
+DECLARE_ESERIAL_FUNCTIONS(4);
+struct serial_device eserial4_device =
+ INIT_ESERIAL_STRUCTURE(4, "eserial3");
+
+__weak struct serial_device *default_serial_console(void)
+{
+#if CONFIG_CONS_INDEX == 1
+ return &eserial1_device;
+#elif CONFIG_CONS_INDEX == 2
+ return &eserial2_device;
+#elif CONFIG_CONS_INDEX == 3
+ return &eserial3_device;
+#elif CONFIG_CONS_INDEX == 4
+ return &eserial4_device;
+#else
+#error "Bad CONFIG_CONS_INDEX."
+#endif
+}
+
+void ns16550_serial_initialize(void)
+{
+#if defined(CONFIG_SYS_NS16550_COM1)
+ serial_register(&eserial1_device);
+#endif
+#if defined(CONFIG_SYS_NS16550_COM2)
+ serial_register(&eserial2_device);
+#endif
+#if defined(CONFIG_SYS_NS16550_COM3)
+ serial_register(&eserial3_device);
+#endif
+#if defined(CONFIG_SYS_NS16550_COM4)
+ serial_register(&eserial4_device);
+#endif
+}
diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c
index d4c5137..7db7b65 100644
--- a/drivers/serial/serial_pl01x.c
+++ b/drivers/serial/serial_pl01x.c
@@ -30,6 +30,8 @@
#include <common.h>
#include <watchdog.h>
#include <asm/io.h>
+#include <serial.h>
+#include <linux/compiler.h>
#include "serial_pl01x.h"
/*
@@ -54,7 +56,7 @@ static struct pl01x_regs *pl01x_get_regs(int portnum)
#ifdef CONFIG_PL010_SERIAL
-int serial_init (void)
+static int pl01x_serial_init(void)
{
struct pl01x_regs *regs = pl01x_get_regs(CONSOLE_PORT);
unsigned int divisor;
@@ -104,7 +106,7 @@ int serial_init (void)
#ifdef CONFIG_PL011_SERIAL
-int serial_init (void)
+static int pl01x_serial_init(void)
{
struct pl01x_regs *regs = pl01x_get_regs(CONSOLE_PORT);
unsigned int temp;
@@ -169,7 +171,7 @@ int serial_init (void)
#endif /* CONFIG_PL011_SERIAL */
-void serial_putc (const char c)
+static void pl01x_serial_putc(const char c)
{
if (c == '\n')
pl01x_putc (CONSOLE_PORT, '\r');
@@ -177,24 +179,24 @@ void serial_putc (const char c)
pl01x_putc (CONSOLE_PORT, c);
}
-void serial_puts (const char *s)
+static void pl01x_serial_puts(const char *s)
{
while (*s) {
serial_putc (*s++);
}
}
-int serial_getc (void)
+static int pl01x_serial_getc(void)
{
return pl01x_getc (CONSOLE_PORT);
}
-int serial_tstc (void)
+static int pl01x_serial_tstc(void)
{
return pl01x_tstc (CONSOLE_PORT);
}
-void serial_setbrg (void)
+static void pl01x_serial_setbrg(void)
{
struct pl01x_regs *regs = pl01x_get_regs(CONSOLE_PORT);
@@ -250,3 +252,24 @@ static int pl01x_tstc (int portnum)
WATCHDOG_RESET();
return !(readl(&regs->fr) & UART_PL01x_FR_RXFE);
}
+
+static struct serial_device pl01x_serial_drv = {
+ .name = "pl01x_serial",
+ .start = pl01x_serial_init,
+ .stop = NULL,
+ .setbrg = pl01x_serial_setbrg,
+ .putc = pl01x_serial_putc,
+ .puts = pl01x_serial_puts,
+ .getc = pl01x_serial_getc,
+ .tstc = pl01x_serial_tstc,
+};
+
+void pl01x_serial_initialize(void)
+{
+ serial_register(&pl01x_serial_drv);
+}
+
+__weak struct serial_device *default_serial_console(void)
+{
+ return &pl01x_serial_drv;
+}
diff --git a/drivers/serial/serial_pxa.c b/drivers/serial/serial_pxa.c
index a9976d7..ad39100 100644
--- a/drivers/serial/serial_pxa.c
+++ b/drivers/serial/serial_pxa.c
@@ -36,6 +36,7 @@
#include <asm/arch/pxa-regs.h>
#include <asm/arch/regs-uart.h>
#include <asm/io.h>
+#include <linux/compiler.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -72,21 +73,7 @@ DECLARE_GLOBAL_DATA_PTR;
#define HWUART_INDEX 0xff
#endif
-#ifndef CONFIG_SERIAL_MULTI
-#if defined(CONFIG_FFUART)
-#define UART_INDEX FFUART_INDEX
-#elif defined(CONFIG_BTUART)
-#define UART_INDEX BTUART_INDEX
-#elif defined(CONFIG_STUART)
-#define UART_INDEX STUART_INDEX
-#elif defined(CONFIG_HWUART)
-#define UART_INDEX HWUART_INDEX
-#else
-#error "Please select CONFIG_(FF|BT|ST|HW)UART in board config file."
-#endif
-#endif
-
-uint32_t pxa_uart_get_baud_divider(void)
+static uint32_t pxa_uart_get_baud_divider(void)
{
if (gd->baudrate == 1200)
return 768;
@@ -104,7 +91,7 @@ uint32_t pxa_uart_get_baud_divider(void)
return 0;
}
-struct pxa_uart_regs *pxa_uart_index_to_regs(uint32_t uart_index)
+static struct pxa_uart_regs *pxa_uart_index_to_regs(uint32_t uart_index)
{
switch (uart_index) {
case FFUART_INDEX: return (struct pxa_uart_regs *)FFUART_BASE;
@@ -116,7 +103,7 @@ struct pxa_uart_regs *pxa_uart_index_to_regs(uint32_t uart_index)
}
}
-void pxa_uart_toggle_clock(uint32_t uart_index, int enable)
+static void pxa_uart_toggle_clock(uint32_t uart_index, int enable)
{
uint32_t clk_reg, clk_offset, reg;
@@ -269,14 +256,14 @@ void pxa_puts_dev(unsigned int uart_index, const char *s)
#define pxa_uart_desc(uart) \
struct serial_device serial_##uart##_device = \
{ \
- "serial_"#uart, \
- uart##_init, \
- NULL, \
- uart##_setbrg, \
- uart##_getc, \
- uart##_tstc, \
- uart##_putc, \
- uart##_puts, \
+ .name = "serial_"#uart, \
+ .start = uart##_init, \
+ .stop = NULL, \
+ .setbrg = uart##_setbrg, \
+ .getc = uart##_getc, \
+ .tstc = uart##_tstc, \
+ .putc = uart##_putc, \
+ .puts = uart##_puts, \
};
#define pxa_uart_multi(uart, UART) \
@@ -296,6 +283,30 @@ void pxa_puts_dev(unsigned int uart_index, const char *s)
pxa_uart_multi(btuart, BTUART)
#endif
-#ifndef CONFIG_SERIAL_MULTI
- pxa_uart(serial, UART)
+__weak struct serial_device *default_serial_console(void)
+{
+#if CONFIG_CONS_INDEX == 1
+ return &serial_hwuart_device;
+#elif CONFIG_CONS_INDEX == 2
+ return &serial_stuart_device;
+#elif CONFIG_CONS_INDEX == 3
+ return &serial_ffuart_device;
+#elif CONFIG_CONS_INDEX == 4
+ return &serial_btuart_device;
+#else
+#error "Bad CONFIG_CONS_INDEX."
#endif
+}
+
+void pxa_serial_initialize(void)
+{
+#if defined(CONFIG_FFUART)
+ serial_register(&serial_ffuart_device);
+#endif
+#if defined(CONFIG_BTUART)
+ serial_register(&serial_btuart_device);
+#endif
+#if defined(CONFIG_STUART)
+ serial_register(&serial_stuart_device);
+#endif
+}
diff --git a/drivers/serial/serial_s3c24x0.c b/drivers/serial/serial_s3c24x0.c
index 12bcdd3..4d214c3 100644
--- a/drivers/serial/serial_s3c24x0.c
+++ b/drivers/serial/serial_s3c24x0.c
@@ -38,8 +38,6 @@ DECLARE_GLOBAL_DATA_PTR;
#endif
#include <asm/io.h>
-
-#if defined(CONFIG_SERIAL_MULTI)
#include <serial.h>
/* Multi serial device functions */
@@ -69,19 +67,17 @@ DECLARE_GLOBAL_DATA_PTR;
serial_puts_dev(port, s); \
}
-#define INIT_S3C_SERIAL_STRUCTURE(port, name) { \
- name, \
- s3serial##port##_init, \
- NULL,\
- s3serial##port##_setbrg, \
- s3serial##port##_getc, \
- s3serial##port##_tstc, \
- s3serial##port##_putc, \
- s3serial##port##_puts, \
+#define INIT_S3C_SERIAL_STRUCTURE(port, __name) { \
+ .name = __name, \
+ .start = s3serial##port##_init, \
+ .stop = NULL, \
+ .setbrg = s3serial##port##_setbrg, \
+ .getc = s3serial##port##_getc, \
+ .tstc = s3serial##port##_tstc, \
+ .putc = s3serial##port##_putc, \
+ .puts = s3serial##port##_puts, \
}
-#endif /* CONFIG_SERIAL_MULTI */
-
#ifdef CONFIG_HWFLOW
static int hwflow;
#endif
@@ -100,18 +96,10 @@ void _serial_setbrg(const int dev_index)
/* Delay */ ;
}
-#if defined(CONFIG_SERIAL_MULTI)
static inline void serial_setbrg_dev(unsigned int dev_index)
{
_serial_setbrg(dev_index);
}
-#else
-void serial_setbrg(void)
-{
- _serial_setbrg(UART_NR);
-}
-#endif
-
/* Initialise the serial port. The settings are always 8 data bits, no parity,
* 1 stop bit, no start bits.
@@ -151,16 +139,6 @@ static int serial_init_dev(const int dev_index)
return (0);
}
-#if !defined(CONFIG_SERIAL_MULTI)
-/* Initialise the serial port. The settings are always 8 data bits, no parity,
- * 1 stop bit, no start bits.
- */
-int serial_init(void)
-{
- return serial_init_dev(UART_NR);
-}
-#endif
-
/*
* Read a single byte from the serial port. Returns 1 on success, 0
* otherwise. When the function is succesfull, the character read is
@@ -176,17 +154,10 @@ int _serial_getc(const int dev_index)
return readb(&uart->urxh) & 0xff;
}
-#if defined(CONFIG_SERIAL_MULTI)
static inline int serial_getc_dev(unsigned int dev_index)
{
return _serial_getc(dev_index);
}
-#else
-int serial_getc(void)
-{
- return _serial_getc(UART_NR);
-}
-#endif
#ifdef CONFIG_HWFLOW
int hwflow_onoff(int on)
@@ -246,18 +217,10 @@ void _serial_putc(const char c, const int dev_index)
serial_putc('\r');
}
-#if defined(CONFIG_SERIAL_MULTI)
static inline void serial_putc_dev(unsigned int dev_index, const char c)
{
_serial_putc(c, dev_index);
}
-#else
-void serial_putc(const char c)
-{
- _serial_putc(c, UART_NR);
-}
-#endif
-
/*
* Test whether a character is in the RX buffer
@@ -269,17 +232,10 @@ int _serial_tstc(const int dev_index)
return readl(&uart->utrstat) & 0x1;
}
-#if defined(CONFIG_SERIAL_MULTI)
static inline int serial_tstc_dev(unsigned int dev_index)
{
return _serial_tstc(dev_index);
}
-#else
-int serial_tstc(void)
-{
- return _serial_tstc(UART_NR);
-}
-#endif
void _serial_puts(const char *s, const int dev_index)
{
@@ -288,19 +244,11 @@ void _serial_puts(const char *s, const int dev_index)
}
}
-#if defined(CONFIG_SERIAL_MULTI)
static inline void serial_puts_dev(int dev_index, const char *s)
{
_serial_puts(s, dev_index);
}
-#else
-void serial_puts(const char *s)
-{
- _serial_puts(s, UART_NR);
-}
-#endif
-#if defined(CONFIG_SERIAL_MULTI)
DECLARE_S3C_SERIAL_FUNCTIONS(0);
struct serial_device s3c24xx_serial0_device =
INIT_S3C_SERIAL_STRUCTURE(0, "s3ser0");
@@ -323,4 +271,10 @@ __weak struct serial_device *default_serial_console(void)
#error "CONFIG_SERIAL? missing."
#endif
}
-#endif /* CONFIG_SERIAL_MULTI */
+
+void s3c24xx_serial_initialize(void)
+{
+ serial_register(&s3c24xx_serial0_device);
+ serial_register(&s3c24xx_serial1_device);
+ serial_register(&s3c24xx_serial2_device);
+}
diff --git a/drivers/serial/serial_s3c44b0.c b/drivers/serial/serial_s3c44b0.c
index 95d0266..a4428e0 100644
--- a/drivers/serial/serial_s3c44b0.c
+++ b/drivers/serial/serial_s3c44b0.c
@@ -68,7 +68,7 @@ static int serial_flush_output(void)
}
-void serial_setbrg (void)
+static void s3c44b0_serial_setbrg(void)
{
u32 divisor = 0;
@@ -156,7 +156,7 @@ void serial_setbrg (void)
* are always 8 data bits, no parity, 1 stop bit, no start bits.
*
*/
-int serial_init (void)
+static int s3c44b0_serial_init(void)
{
serial_setbrg ();
@@ -167,7 +167,7 @@ int serial_init (void)
/*
* Output a single byte to the serial port.
*/
-void serial_putc (const char c)
+static void s3c44b0_serial_putc(const char c)
{
/* wait for room in the transmit FIFO */
while(!(UTRSTAT0 & 0x02));
@@ -187,7 +187,7 @@ void serial_putc (const char c)
* otherwise. When the function is succesfull, the character read is
* written into its argument c.
*/
-int serial_tstc (void)
+static int s3c44b0_serial_tstc(void)
{
return (UTRSTAT0 & 0x01);
}
@@ -197,22 +197,42 @@ int serial_tstc (void)
* otherwise. When the function is succesfull, the character read is
* written into its argument c.
*/
-int serial_getc (void)
+static int s3c44b0_serial_getc(void)
{
int rv;
for(;;) {
- rv = serial_tstc();
+ rv = s3c44b0_serial_tstc();
if(rv > 0)
return URXH0;
}
}
-void
-serial_puts (const char *s)
+static void s3c44b0_serial_puts(const char *s)
{
while (*s) {
serial_putc (*s++);
}
}
+
+static struct serial_device s3c44b0_serial_drv = {
+ .name = "s3c44b0_serial",
+ .start = s3c44b0_serial_init,
+ .stop = NULL,
+ .setbrg = s3c44b0_serial_setbrg,
+ .putc = s3c44b0_serial_putc,
+ .puts = s3c44b0_serial_puts,
+ .getc = s3c44b0_serial_getc,
+ .tstc = s3c44b0_serial_tstc,
+};
+
+void s3c44b0_serial_initialize(void)
+{
+ serial_register(&s3c44b0_serial_drv);
+}
+
+__weak struct serial_device *default_serial_console(void)
+{
+ return &s3c44b0_serial_drv;
+}
diff --git a/drivers/serial/serial_s5p.c b/drivers/serial/serial_s5p.c
index 6819bb0..3c41242 100644
--- a/drivers/serial/serial_s5p.c
+++ b/drivers/serial/serial_s5p.c
@@ -183,15 +183,16 @@ int s5p_serial##port##_tstc(void) { return serial_tstc_dev(port); } \
void s5p_serial##port##_putc(const char c) { serial_putc_dev(c, port); } \
void s5p_serial##port##_puts(const char *s) { serial_puts_dev(s, port); }
-#define INIT_S5P_SERIAL_STRUCTURE(port, name) { \
- name, \
- s5p_serial##port##_init, \
- NULL, \
- s5p_serial##port##_setbrg, \
- s5p_serial##port##_getc, \
- s5p_serial##port##_tstc, \
- s5p_serial##port##_putc, \
- s5p_serial##port##_puts, }
+#define INIT_S5P_SERIAL_STRUCTURE(port, __name) { \
+ .name = __name, \
+ .start = s5p_serial##port##_init, \
+ .stop = NULL, \
+ .setbrg = s5p_serial##port##_setbrg, \
+ .getc = s5p_serial##port##_getc, \
+ .tstc = s5p_serial##port##_tstc, \
+ .putc = s5p_serial##port##_putc, \
+ .puts = s5p_serial##port##_puts, \
+}
DECLARE_S5P_SERIAL_FUNCTIONS(0);
struct serial_device s5p_serial0_device =
@@ -220,3 +221,11 @@ __weak struct serial_device *default_serial_console(void)
#error "CONFIG_SERIAL? missing."
#endif
}
+
+void s5p_serial_initialize(void)
+{
+ serial_register(&s5p_serial0_device);
+ serial_register(&s5p_serial1_device);
+ serial_register(&s5p_serial2_device);
+ serial_register(&s5p_serial3_device);
+}
diff --git a/drivers/serial/serial_sa1100.c b/drivers/serial/serial_sa1100.c
index 5d18875..c6b34db 100644
--- a/drivers/serial/serial_sa1100.c
+++ b/drivers/serial/serial_sa1100.c
@@ -30,10 +30,12 @@
#include <common.h>
#include <SA-1100.h>
+#include <serial.h>
+#include <linux/compiler.h>
DECLARE_GLOBAL_DATA_PTR;
-void serial_setbrg (void)
+static void sa1100_serial_setbrg(void)
{
unsigned int reg = 0;
@@ -89,7 +91,7 @@ void serial_setbrg (void)
* are always 8 data bits, no parity, 1 stop bit, no start bits.
*
*/
-int serial_init (void)
+static int sa1100_serial_init(void)
{
serial_setbrg ();
@@ -100,7 +102,7 @@ int serial_init (void)
/*
* Output a single byte to the serial port.
*/
-void serial_putc (const char c)
+static void sa1100_serial_putc(const char c)
{
#ifdef CONFIG_SERIAL1
/* wait for room in the tx FIFO on SERIAL1 */
@@ -124,7 +126,7 @@ void serial_putc (const char c)
* otherwise. When the function is succesfull, the character read is
* written into its argument c.
*/
-int serial_tstc (void)
+static int sa1100_serial_tstc(void)
{
#ifdef CONFIG_SERIAL1
return Ser1UTSR1 & UTSR1_RNE;
@@ -138,7 +140,7 @@ int serial_tstc (void)
* otherwise. When the function is succesfull, the character read is
* written into its argument c.
*/
-int serial_getc (void)
+static int sa1100_serial_getc(void)
{
#ifdef CONFIG_SERIAL1
while (!(Ser1UTSR1 & UTSR1_RNE));
@@ -151,10 +153,30 @@ int serial_getc (void)
#endif
}
-void
-serial_puts (const char *s)
+static void sa1100_serial_puts(const char *s)
{
while (*s) {
serial_putc (*s++);
}
}
+
+static struct serial_device sa1100_serial_drv = {
+ .name = "sa1100_serial",
+ .start = sa1100_serial_init,
+ .stop = NULL,
+ .setbrg = sa1100_serial_setbrg,
+ .putc = sa1100_serial_putc,
+ .puts = sa1100_serial_puts,
+ .getc = sa1100_serial_getc,
+ .tstc = sa1100_serial_tstc,
+};
+
+void sa1100_serial_initialize(void)
+{
+ serial_register(&sa1100_serial_drv);
+}
+
+__weak struct serial_device *default_serial_console(void)
+{
+ return &sa1100_serial_drv;
+}
diff --git a/drivers/serial/serial_sh.c b/drivers/serial/serial_sh.c
index 13919c6..1ddfc7d 100644
--- a/drivers/serial/serial_sh.c
+++ b/drivers/serial/serial_sh.c
@@ -22,6 +22,8 @@
#include <asm/io.h>
#include <asm/processor.h>
#include "serial_sh.h"
+#include <serial.h>
+#include <linux/compiler.h>
#if defined(CONFIG_CONS_SCIF0)
# define SCIF_BASE SCIF0_BASE
@@ -55,13 +57,13 @@ static struct uart_port sh_sci = {
.type = SCIF_BASE_PORT,
};
-void serial_setbrg(void)
+static void sh_serial_setbrg(void)
{
DECLARE_GLOBAL_DATA_PTR;
sci_out(&sh_sci, SCBRR, SCBRR_VALUE(gd->baudrate, CONFIG_SYS_CLK_FREQ));
}
-int serial_init(void)
+static int sh_serial_init(void)
{
sci_out(&sh_sci, SCSCR , SCSCR_INIT(&sh_sci));
sci_out(&sh_sci, SCSCR , SCSCR_INIT(&sh_sci));
@@ -127,21 +129,21 @@ void serial_raw_putc(const char c)
sci_out(&sh_sci, SCxSR, sci_in(&sh_sci, SCxSR) & ~SCxSR_TEND(&sh_sci));
}
-void serial_putc(const char c)
+static void sh_serial_putc(const char c)
{
if (c == '\n')
serial_raw_putc('\r');
serial_raw_putc(c);
}
-void serial_puts(const char *s)
+static void sh_serial_puts(const char *s)
{
char c;
while ((c = *s++) != 0)
serial_putc(c);
}
-int serial_tstc(void)
+static int sh_serial_tstc(void)
{
return serial_rx_fifo_level() ? 1 : 0;
}
@@ -167,7 +169,7 @@ int serial_getc_check(void)
return status & (SCIF_DR | SCxSR_RDxF(&sh_sci));
}
-int serial_getc(void)
+static int sh_serial_getc(void)
{
unsigned short status;
char ch;
@@ -187,3 +189,24 @@ int serial_getc(void)
handle_error();
return ch;
}
+
+static struct serial_device sh_serial_drv = {
+ .name = "sh_serial",
+ .start = sh_serial_init,
+ .stop = NULL,
+ .setbrg = sh_serial_setbrg,
+ .putc = sh_serial_putc,
+ .puts = sh_serial_puts,
+ .getc = sh_serial_getc,
+ .tstc = sh_serial_tstc,
+};
+
+void sh_serial_initialize(void)
+{
+ serial_register(&sh_serial_drv);
+}
+
+__weak struct serial_device *default_serial_console(void)
+{
+ return &sh_serial_drv;
+}
diff --git a/drivers/serial/serial_xuartlite.c b/drivers/serial/serial_xuartlite.c
index 2bdb68b..9cc0b7f 100644
--- a/drivers/serial/serial_xuartlite.c
+++ b/drivers/serial/serial_xuartlite.c
@@ -96,39 +96,6 @@ static int uartlite_serial_init(const int port)
return -1;
}
-#if !defined(CONFIG_SERIAL_MULTI)
-int serial_init(void)
-{
- return uartlite_serial_init(0);
-}
-
-void serial_setbrg(void)
-{
- /* FIXME: what's this for? */
-}
-
-void serial_putc(const char c)
-{
- uartlite_serial_putc(c, 0);
-}
-
-void serial_puts(const char *s)
-{
- uartlite_serial_puts(s, 0);
-}
-
-int serial_getc(void)
-{
- return uartlite_serial_getc(0);
-}
-
-int serial_tstc(void)
-{
- return uartlite_serial_tstc(0);
-}
-#endif
-
-#if defined(CONFIG_SERIAL_MULTI)
/* Multi serial device functions */
#define DECLARE_ESERIAL_FUNCTIONS(port) \
int userial##port##_init(void) \
@@ -144,15 +111,16 @@ int serial_tstc(void)
{ uartlite_serial_puts(s, port); }
/* Serial device descriptor */
-#define INIT_ESERIAL_STRUCTURE(port, name) {\
- name,\
- userial##port##_init,\
- NULL,\
- userial##port##_setbrg,\
- userial##port##_getc,\
- userial##port##_tstc,\
- userial##port##_putc,\
- userial##port##_puts, }
+#define INIT_ESERIAL_STRUCTURE(port, __name) { \
+ .name = __name, \
+ .start = userial##port##_init, \
+ .stop = NULL, \
+ .setbrg = userial##port##_setbrg, \
+ .getc = userial##port##_getc, \
+ .tstc = userial##port##_tstc, \
+ .putc = userial##port##_putc, \
+ .puts = userial##port##_puts, \
+}
DECLARE_ESERIAL_FUNCTIONS(0);
struct serial_device uartlite_serial0_device =
@@ -180,4 +148,19 @@ __weak struct serial_device *default_serial_console(void)
return NULL;
}
-#endif /* CONFIG_SERIAL_MULTI */
+
+void uartlite_serial_initialize(void)
+{
+#ifdef XILINX_UARTLITE_BASEADDR
+ serial_register(&uartlite_serial0_device);
+#endif /* XILINX_UARTLITE_BASEADDR */
+#ifdef XILINX_UARTLITE_BASEADDR1
+ serial_register(&uartlite_serial1_device);
+#endif /* XILINX_UARTLITE_BASEADDR1 */
+#ifdef XILINX_UARTLITE_BASEADDR2
+ serial_register(&uartlite_serial2_device);
+#endif /* XILINX_UARTLITE_BASEADDR2 */
+#ifdef XILINX_UARTLITE_BASEADDR3
+ serial_register(&uartlite_serial3_device);
+#endif /* XILINX_UARTLITE_BASEADDR3 */
+}
diff --git a/drivers/serial/serial_zynq.c b/drivers/serial/serial_zynq.c
new file mode 100644
index 0000000..c09aa27
--- /dev/null
+++ b/drivers/serial/serial_zynq.c
@@ -0,0 +1,225 @@
+/*
+ * Copyright (C) 2012 Michal Simek <monstr@monstr.eu>
+ * Copyright (C) 2011-2012 Xilinx, Inc. All rights reserved.
+ *
+ * See file CREDITS for list of people who contributed to this
+ * project.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ */
+
+#include <common.h>
+#include <watchdog.h>
+#include <asm/io.h>
+#include <linux/compiler.h>
+#include <serial.h>
+
+#define ZYNQ_UART_SR_TXFULL 0x00000010 /* TX FIFO full */
+#define ZYNQ_UART_SR_RXEMPTY 0x00000002 /* RX FIFO empty */
+
+#define ZYNQ_UART_CR_TX_EN 0x00000010 /* TX enabled */
+#define ZYNQ_UART_CR_RX_EN 0x00000004 /* RX enabled */
+#define ZYNQ_UART_CR_TXRST 0x00000002 /* TX logic reset */
+#define ZYNQ_UART_CR_RXRST 0x00000001 /* RX logic reset */
+
+#define ZYNQ_UART_MR_PARITY_NONE 0x00000020 /* No parity mode */
+
+/* Some clock/baud constants */
+#define ZYNQ_UART_BDIV 15 /* Default/reset BDIV value */
+#define ZYNQ_UART_BASECLK 3125000L /* master / (bdiv + 1) */
+
+struct uart_zynq {
+ u32 control; /* Control Register [8:0] */
+ u32 mode; /* Mode Register [10:0] */
+ u32 reserved1[4];
+ u32 baud_rate_gen; /* Baud Rate Generator [15:0] */
+ u32 reserved2[4];
+ u32 channel_sts; /* Channel Status [11:0] */
+ u32 tx_rx_fifo; /* FIFO [15:0] or [7:0] */
+ u32 baud_rate_divider; /* Baud Rate Divider [7:0] */
+};
+
+static struct uart_zynq *uart_zynq_ports[2] = {
+#ifdef CONFIG_ZYNQ_SERIAL_BASEADDR0
+ [0] = (struct uart_zynq *)CONFIG_ZYNQ_SERIAL_BASEADDR0,
+#endif
+#ifdef CONFIG_ZYNQ_SERIAL_BASEADDR1
+ [1] = (struct uart_zynq *)CONFIG_ZYNQ_SERIAL_BASEADDR1,
+#endif
+};
+
+struct uart_zynq_params {
+ u32 baudrate;
+ u32 clock;
+};
+
+static struct uart_zynq_params uart_zynq_ports_param[2] = {
+#if defined(CONFIG_ZYNQ_SERIAL_BAUDRATE0) && defined(CONFIG_ZYNQ_SERIAL_CLOCK0)
+ [0].baudrate = CONFIG_ZYNQ_SERIAL_BAUDRATE0,
+ [0].clock = CONFIG_ZYNQ_SERIAL_CLOCK0,
+#endif
+#if defined(CONFIG_ZYNQ_SERIAL_BAUDRATE1) && defined(CONFIG_ZYNQ_SERIAL_CLOCK1)
+ [1].baudrate = CONFIG_ZYNQ_SERIAL_BAUDRATE1,
+ [1].clock = CONFIG_ZYNQ_SERIAL_CLOCK1,
+#endif
+};
+
+/* Set up the baud rate in gd struct */
+static void uart_zynq_serial_setbrg(const int port)
+{
+ /* Calculation results. */
+ unsigned int calc_bauderror, bdiv, bgen;
+ unsigned long calc_baud = 0;
+ unsigned long baud = uart_zynq_ports_param[port].baudrate;
+ unsigned long clock = uart_zynq_ports_param[port].clock;
+ struct uart_zynq *regs = uart_zynq_ports[port];
+
+ /* master clock
+ * Baud rate = ------------------
+ * bgen * (bdiv + 1)
+ *
+ * Find acceptable values for baud generation.
+ */
+ for (bdiv = 4; bdiv < 255; bdiv++) {
+ bgen = clock / (baud * (bdiv + 1));
+ if (bgen < 2 || bgen > 65535)
+ continue;
+
+ calc_baud = clock / (bgen * (bdiv + 1));
+
+ /*
+ * Use first calculated baudrate with
+ * an acceptable (<3%) error
+ */
+ if (baud > calc_baud)
+ calc_bauderror = baud - calc_baud;
+ else
+ calc_bauderror = calc_baud - baud;
+ if (((calc_bauderror * 100) / baud) < 3)
+ break;
+ }
+
+ writel(bdiv, &regs->baud_rate_divider);
+ writel(bgen, &regs->baud_rate_gen);
+}
+
+/* Initialize the UART, with...some settings. */
+static int uart_zynq_serial_init(const int port)
+{
+ struct uart_zynq *regs = uart_zynq_ports[port];
+
+ if (!regs)
+ return -1;
+
+ /* RX/TX enabled & reset */
+ writel(ZYNQ_UART_CR_TX_EN | ZYNQ_UART_CR_RX_EN | ZYNQ_UART_CR_TXRST | \
+ ZYNQ_UART_CR_RXRST, &regs->control);
+ writel(ZYNQ_UART_MR_PARITY_NONE, &regs->mode); /* 8 bit, no parity */
+ uart_zynq_serial_setbrg(port);
+
+ return 0;
+}
+
+static void uart_zynq_serial_putc(const char c, const int port)
+{
+ struct uart_zynq *regs = uart_zynq_ports[port];
+
+ while ((readl(&regs->channel_sts) & ZYNQ_UART_SR_TXFULL) != 0)
+ WATCHDOG_RESET();
+
+ if (c == '\n') {
+ writel('\r', &regs->tx_rx_fifo);
+ while ((readl(&regs->channel_sts) & ZYNQ_UART_SR_TXFULL) != 0)
+ WATCHDOG_RESET();
+ }
+ writel(c, &regs->tx_rx_fifo);
+}
+
+static void uart_zynq_serial_puts(const char *s, const int port)
+{
+ while (*s)
+ uart_zynq_serial_putc(*s++, port);
+}
+
+static int uart_zynq_serial_tstc(const int port)
+{
+ struct uart_zynq *regs = uart_zynq_ports[port];
+
+ return (readl(&regs->channel_sts) & ZYNQ_UART_SR_RXEMPTY) == 0;
+}
+
+static int uart_zynq_serial_getc(const int port)
+{
+ struct uart_zynq *regs = uart_zynq_ports[port];
+
+ while (!uart_zynq_serial_tstc(port))
+ WATCHDOG_RESET();
+ return readl(&regs->tx_rx_fifo);
+}
+
+/* Multi serial device functions */
+#define DECLARE_PSSERIAL_FUNCTIONS(port) \
+ int uart_zynq##port##_init(void) \
+ { return uart_zynq_serial_init(port); } \
+ void uart_zynq##port##_setbrg(void) \
+ { return uart_zynq_serial_setbrg(port); } \
+ int uart_zynq##port##_getc(void) \
+ { return uart_zynq_serial_getc(port); } \
+ int uart_zynq##port##_tstc(void) \
+ { return uart_zynq_serial_tstc(port); } \
+ void uart_zynq##port##_putc(const char c) \
+ { uart_zynq_serial_putc(c, port); } \
+ void uart_zynq##port##_puts(const char *s) \
+ { uart_zynq_serial_puts(s, port); }
+
+/* Serial device descriptor */
+#define INIT_PSSERIAL_STRUCTURE(port, __name) { \
+ .name = __name, \
+ .start = uart_zynq##port##_init, \
+ .stop = NULL, \
+ .setbrg = uart_zynq##port##_setbrg, \
+ .getc = uart_zynq##port##_getc, \
+ .tstc = uart_zynq##port##_tstc, \
+ .putc = uart_zynq##port##_putc, \
+ .puts = uart_zynq##port##_puts, \
+}
+
+DECLARE_PSSERIAL_FUNCTIONS(0);
+struct serial_device uart_zynq_serial0_device =
+ INIT_PSSERIAL_STRUCTURE(0, "ttyPS0");
+DECLARE_PSSERIAL_FUNCTIONS(1);
+struct serial_device uart_zynq_serial1_device =
+ INIT_PSSERIAL_STRUCTURE(1, "ttyPS1");
+
+__weak struct serial_device *default_serial_console(void)
+{
+ if (uart_zynq_ports[0])
+ return &uart_zynq_serial0_device;
+ if (uart_zynq_ports[1])
+ return &uart_zynq_serial1_device;
+
+ return NULL;
+}
+
+void zynq_serial_initalize(void)
+{
+#ifdef CONFIG_ZYNQ_SERIAL_BASEADDR0
+ serial_register(&uart_zynq_serial0_device);
+#endif
+#ifdef CONFIG_ZYNQ_SERIAL_BASEADDR1
+ serial_register(&uart_zynq_serial1_device);
+#endif
+}