diff mbox

[U-Boot,v4] serial: uartlite: Support for SERIAL_MULTI

Message ID 1316094600-13633-1-git-send-email-monstr@monstr.eu
State Changes Requested
Headers show

Commit Message

Michal Simek Sept. 15, 2011, 1:50 p.m. UTC
Add support for SERIAL MULTI for uartlite.

Signed-off-by: Michal Simek <monstr@monstr.eu>

---
v2: Use in/out_be32 functions

v3: Clean coding style

v4: Simplify userial_ports array initialization
---
 common/serial.c                   |   14 ++++
 drivers/serial/serial_xuartlite.c |  134 ++++++++++++++++++++++++++++++++-----
 include/serial.h                  |    7 ++
 3 files changed, 137 insertions(+), 18 deletions(-)

Comments

Michal Simek Sept. 20, 2011, 7:19 a.m. UTC | #1
Michal Simek wrote:
> Add support for SERIAL MULTI for uartlite.
> 
> Signed-off-by: Michal Simek <monstr@monstr.eu>
> 
> ---
> v2: Use in/out_be32 functions
> 
> v3: Clean coding style
> 
> v4: Simplify userial_ports array initialization
> ---
>  common/serial.c                   |   14 ++++
>  drivers/serial/serial_xuartlite.c |  134 ++++++++++++++++++++++++++++++++-----
>  include/serial.h                  |    7 ++
>  3 files changed, 137 insertions(+), 18 deletions(-)

Any comment?

Michal
Marek Vasut Sept. 20, 2011, 7:33 a.m. UTC | #2
On Tuesday, September 20, 2011 09:19:23 AM Michal Simek wrote:
> Michal Simek wrote:
> > Add support for SERIAL MULTI for uartlite.
> > 
> > Signed-off-by: Michal Simek <monstr@monstr.eu>
> > 
> > ---
> > v2: Use in/out_be32 functions
> > 
> > v3: Clean coding style
> > 
> > v4: Simplify userial_ports array initialization
> > ---
> > 
> >  common/serial.c                   |   14 ++++
> >  drivers/serial/serial_xuartlite.c |  134
> >  ++++++++++++++++++++++++++++++++----- include/serial.h                 
> >  |    7 ++
> >  3 files changed, 137 insertions(+), 18 deletions(-)
> 
> Any comment?

Avoid endless loops

> 
> Michal
Mike Frysinger Sept. 20, 2011, 5:03 p.m. UTC | #3
On Thursday, September 15, 2011 09:50:00 Michal Simek wrote:
> --- a/drivers/serial/serial_xuartlite.c
> +++ b/drivers/serial/serial_xuartlite.c
> 
> +static struct uartlite *userial_ports[4] = {

i think you missed my previous feedback here.  pretty sure this should be:
        static struct uartlite * const userial_ports[4] = {
-mike
Michal Simek Sept. 21, 2011, 11:31 a.m. UTC | #4
Mike Frysinger wrote:
> On Thursday, September 15, 2011 09:50:00 Michal Simek wrote:
>> --- a/drivers/serial/serial_xuartlite.c
>> +++ b/drivers/serial/serial_xuartlite.c
>>
>> +static struct uartlite *userial_ports[4] = {
> 
> i think you missed my previous feedback here.  pretty sure this should be:
>         static struct uartlite * const userial_ports[4] = {

yeah - just read the second message not the first one.

Michal
Michal Simek Sept. 21, 2011, 12:21 p.m. UTC | #5
Marek Vasut wrote:
> On Tuesday, September 20, 2011 09:19:23 AM Michal Simek wrote:
>> Michal Simek wrote:
>>> Add support for SERIAL MULTI for uartlite.
>>>
>>> Signed-off-by: Michal Simek <monstr@monstr.eu>
>>>
>>> ---
>>> v2: Use in/out_be32 functions
>>>
>>> v3: Clean coding style
>>>
>>> v4: Simplify userial_ports array initialization
>>> ---
>>>
>>>  common/serial.c                   |   14 ++++
>>>  drivers/serial/serial_xuartlite.c |  134
>>>  ++++++++++++++++++++++++++++++++----- include/serial.h                 
>>>  |    7 ++
>>>  3 files changed, 137 insertions(+), 18 deletions(-)
>> Any comment?
> 
> Avoid endless loops

No problem to do it for putc but for getc?
What would you like to return if there is no character available?

If generic code always checked if there is any character available through tstc
and then call getc I can keep there just reading buffer but from my test I see that
it doesn't do that.

Please point me to any existing u-boot serial driver which does it in way you like.
I wasn't able to find it out.

Thanks,
Michal
Mike Frysinger Sept. 21, 2011, 2:15 p.m. UTC | #6
On Wednesday, September 21, 2011 08:21:35 Michal Simek wrote:
> Marek Vasut wrote:
> > On Tuesday, September 20, 2011 09:19:23 AM Michal Simek wrote:
> >> Michal Simek wrote:
> >>> Add support for SERIAL MULTI for uartlite.
> >> 
> >> Any comment?
> > 
> > Avoid endless loops
> 
> No problem to do it for putc but for getc?
> What would you like to return if there is no character available?

getc() is allowed to loop forever.  pretty much most drivers also wait forever 
with putc().  i dont think serial drivers really matter as if the hardware 
breaks, u-boot itself isn't terribly useful anymore.  just make sure flow 
control doesn't bite you (CTS/RTS).
-mike
diff mbox

Patch

diff --git a/common/serial.c b/common/serial.c
index 995d268..df02fa5 100644
--- a/common/serial.c
+++ b/common/serial.c
@@ -108,6 +108,20 @@  void serial_initialize (void)
 #if defined(CONFIG_SYS_BFIN_UART)
 	serial_register_bfin_uart();
 #endif
+#if defined(CONFIG_XILINX_UARTLITE)
+# 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 */
+#endif /* CONFIG_XILINX_UARTLITE */
 	serial_assign (default_serial_console ()->name);
 }
 
diff --git a/drivers/serial/serial_xuartlite.c b/drivers/serial/serial_xuartlite.c
index 00d0eaa..9e272ef 100644
--- a/drivers/serial/serial_xuartlite.c
+++ b/drivers/serial/serial_xuartlite.c
@@ -25,20 +25,67 @@ 
  */
 
 #include <config.h>
+#include <common.h>
 #include <asm/io.h>
-
-#define RX_FIFO_OFFSET		0 /* receive FIFO, read only */
-#define TX_FIFO_OFFSET		4 /* transmit FIFO, write only */
-#define STATUS_REG_OFFSET	8 /* status register, read only */
+#include <linux/compiler.h>
+#include <serial.h>
 
 #define SR_TX_FIFO_FULL		0x08 /* transmit FIFO full */
 #define SR_RX_FIFO_VALID_DATA	0x01 /* data in receive FIFO */
 #define SR_RX_FIFO_FULL		0x02 /* receive FIFO full */
 
-#define UARTLITE_STATUS		(CONFIG_SERIAL_BASE + STATUS_REG_OFFSET)
-#define UARTLITE_TX_FIFO	(CONFIG_SERIAL_BASE + TX_FIFO_OFFSET)
-#define UARTLITE_RX_FIFO	(CONFIG_SERIAL_BASE + RX_FIFO_OFFSET)
+struct uartlite {
+	u32 rx_fifo;
+	u32 tx_fifo;
+	u32 status;
+};
+
+static struct uartlite *userial_ports[4] = {
+#ifdef XILINX_UARTLITE_BASEADDR
+	[0] = (struct uartlite *)XILINX_UARTLITE_BASEADDR,
+#endif
+#ifdef XILINX_UARTLITE_BASEADDR1
+	[1] = (struct uartlite *)XILINX_UARTLITE_BASEADDR1,
+#endif
+#ifdef XILINX_UARTLITE_BASEADDR2
+	[2] = (struct uartlite *)XILINX_UARTLITE_BASEADDR2,
+#endif
+#ifdef XILINX_UARTLITE_BASEADDR3
+	[3] = (struct uartlite *)XILINX_UARTLITE_BASEADDR3
+#endif
+};
+
+void uartlite_serial_putc(const char c, const int port)
+{
+	struct uartlite *regs = userial_ports[port];
+	if (c == '\n')
+		uartlite_serial_putc('\r', port);
+	while (in_be32(&regs->status) & SR_TX_FIFO_FULL)
+		;
+	out_be32(&regs->tx_fifo, c & 0xff);
+}
+
+void uartlite_serial_puts(const char *s, const int port)
+{
+	while (*s)
+		uartlite_serial_putc(*s++, port);
+}
+
+int uartlite_serial_getc(const int port)
+{
+	struct uartlite *regs = userial_ports[port];
+	while (!(in_be32(&regs->status) & SR_RX_FIFO_VALID_DATA))
+		;
+	return in_be32(&regs->rx_fifo) & 0xff;
+}
+
+int uartlite_serial_tstc(const int port)
+{
+	struct uartlite *regs = userial_ports[port];
+	return in_be32(&regs->status) & SR_RX_FIFO_VALID_DATA;
+}
 
+#if !defined(CONFIG_SERIAL_MULTI)
 int serial_init(void)
 {
 	/* FIXME: Nothing for now. We should initialize fifo, etc */
@@ -52,26 +99,77 @@  void serial_setbrg(void)
 
 void serial_putc(const char c)
 {
-	if (c == '\n')
-		serial_putc('\r');
-	while (in_be32((u32 *) UARTLITE_STATUS) & SR_TX_FIFO_FULL);
-	out_be32((u32 *) UARTLITE_TX_FIFO, (unsigned char) (c & 0xff));
+	uartlite_serial_putc(c, 0);
 }
 
-void serial_puts(const char * s)
+void serial_puts(const char *s)
 {
-	while (*s) {
-		serial_putc(*s++);
-	}
+	uartlite_serial_puts(s, 0);
 }
 
 int serial_getc(void)
 {
-	while (!(in_be32((u32 *) UARTLITE_STATUS) & SR_RX_FIFO_VALID_DATA));
-	return in_be32((u32 *) UARTLITE_RX_FIFO) & 0xff;
+	return uartlite_serial_getc(0);
 }
 
 int serial_tstc(void)
 {
-	return (in_be32((u32 *) UARTLITE_STATUS) & SR_RX_FIFO_VALID_DATA);
+	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) \
+				{ return(0); } \
+	void userial##port##_setbrg(void) {} \
+	int userial##port##_getc(void) \
+				{ return uartlite_serial_getc(port); } \
+	int userial##port##_tstc(void) \
+				{ return uartlite_serial_tstc(port); } \
+	void userial##port##_putc(const char c) \
+				{ uartlite_serial_putc(c, port); } \
+	void userial##port##_puts(const char *s) \
+				{ 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, }
+
+DECLARE_ESERIAL_FUNCTIONS(0);
+struct serial_device uartlite_serial0_device =
+	INIT_ESERIAL_STRUCTURE(0, "ttyUL0");
+DECLARE_ESERIAL_FUNCTIONS(1);
+struct serial_device uartlite_serial1_device =
+	INIT_ESERIAL_STRUCTURE(1, "ttyUL1");
+DECLARE_ESERIAL_FUNCTIONS(2);
+struct serial_device uartlite_serial2_device =
+	INIT_ESERIAL_STRUCTURE(2, "ttyUL2");
+DECLARE_ESERIAL_FUNCTIONS(3);
+struct serial_device uartlite_serial3_device =
+	INIT_ESERIAL_STRUCTURE(3, "ttyUL3");
+
+__weak struct serial_device *default_serial_console(void)
+{
+# ifdef XILINX_UARTLITE_BASEADDR
+	return &uartlite_serial0_device;
+# endif /* XILINX_UARTLITE_BASEADDR */
+# ifdef XILINX_UARTLITE_BASEADDR1
+	return &uartlite_serial1_device;
+# endif /* XILINX_UARTLITE_BASEADDR1 */
+# ifdef XILINX_UARTLITE_BASEADDR2
+	return &uartlite_serial2_device;
+# endif /* XILINX_UARTLITE_BASEADDR2 */
+# ifdef XILINX_UARTLITE_BASEADDR3
+	return &uartlite_serial3_device;
+# endif /* XILINX_UARTLITE_BASEADDR3 */
 }
+#endif /* CONFIG_SERIAL_MULTI */
diff --git a/include/serial.h b/include/serial.h
index ff1ce99..5926244 100644
--- a/include/serial.h
+++ b/include/serial.h
@@ -50,6 +50,13 @@  extern struct serial_device serial4_device;
 extern struct serial_device serial6_device;
 #endif
 
+#if defined(CONFIG_XILINX_UARTLITE)
+extern struct serial_device uartlite_serial0_device;
+extern struct serial_device uartlite_serial1_device;
+extern struct serial_device uartlite_serial2_device;
+extern struct serial_device uartlite_serial3_device;
+#endif
+
 #if defined(CONFIG_S3C2410)
 extern struct serial_device s3c24xx_serial0_device;
 extern struct serial_device s3c24xx_serial1_device;