Convert lpuart driver to driver model and remove the legacy code. Signed-off-by: Bhuvanchandra DV <bhuvanchandra...@toradex.com> --- arch/arm/include/asm/arch-vf610/serial.h | 16 ++++ drivers/serial/Kconfig | 6 ++ drivers/serial/serial_lpuart.c | 148 ++++++++++++++++--------------- 3 files changed, 97 insertions(+), 73 deletions(-) create mode 100644 arch/arm/include/asm/arch-vf610/serial.h
diff --git a/arch/arm/include/asm/arch-vf610/serial.h b/arch/arm/include/asm/arch-vf610/serial.h new file mode 100644 index 0000000..e9ab552 --- /dev/null +++ b/arch/arm/include/asm/arch-vf610/serial.h @@ -0,0 +1,16 @@ +/* + * Copyright (C) 2016 Toradex, Inc. + * + * Author: Bhuvanchandra DV <bhuvanchandra...@toradex.com> + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#ifndef _LPUART_SERIAL_H +#define _LPUART_SERIAL_H + +struct lpuart_serial_platdata { + uint32_t base_addr; +}; + +#endif diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig index 1fc287e..56a06a7 100644 --- a/drivers/serial/Kconfig +++ b/drivers/serial/Kconfig @@ -223,4 +223,10 @@ config UNIPHIER_SERIAL If you have a UniPhier based board and want to use the on-chip serial ports, say Y to this option. If unsure, say N. +config FSL_LPUART + bool "Freescale lpuart serial port support" + depends on DM_SERIAL + help + Support for the on-chip lpuart on some Freescale SOCs. + endmenu diff --git a/drivers/serial/serial_lpuart.c b/drivers/serial/serial_lpuart.c index 63fc388..4724f42 100644 --- a/drivers/serial/serial_lpuart.c +++ b/drivers/serial/serial_lpuart.c @@ -5,12 +5,14 @@ */ #include <common.h> +#include <dm.h> #include <watchdog.h> #include <asm/io.h> #include <serial.h> #include <linux/compiler.h> #include <asm/arch/imx-regs.h> #include <asm/arch/clock.h> +#include <asm/arch/serial.h> #define US1_TDRE (1 << 7) #define US1_RDRF (1 << 5) @@ -47,26 +49,35 @@ DECLARE_GLOBAL_DATA_PTR; -struct lpuart_fsl *base = (struct lpuart_fsl *)LPUART_BASE; +struct lpuart_serial_priv { + struct lpuart_fsl *lpuart_base; +}; #ifndef CONFIG_LPUART_32B_REG -static void lpuart_serial_setbrg(void) +int lpuart_serial_setbrg(struct udevice *dev, int baudrate) { + struct lpuart_serial_priv *priv = dev_get_priv(dev); + struct lpuart_fsl *base = priv->lpuart_base; u32 clk = mxc_get_clock(MXC_UART_CLK); u16 sbr; if (!gd->baudrate) - gd->baudrate = CONFIG_BAUDRATE; + gd->baudrate = baudrate; sbr = (u16)(clk / (16 * gd->baudrate)); /* place adjustment later - n/32 BRFA */ __raw_writeb(sbr >> 8, &base->ubdh); __raw_writeb(sbr & 0xff, &base->ubdl); + + return 0; } -static int lpuart_serial_getc(void) +static int lpuart_serial_getc(struct udevice *dev) { + struct lpuart_serial_priv *priv = dev_get_priv(dev); + struct lpuart_fsl *base = priv->lpuart_base; + while (!(__raw_readb(&base->us1) & (US1_RDRF | US1_OR))) WATCHDOG_RESET(); @@ -75,8 +86,11 @@ static int lpuart_serial_getc(void) return __raw_readb(&base->ud); } -static void lpuart_serial_putc(const char c) +static int lpuart_serial_putc(struct udevice *dev, const char c) { + struct lpuart_serial_priv *priv = dev_get_priv(dev); + struct lpuart_fsl *base = priv->lpuart_base; + if (c == '\n') serial_putc('\r'); @@ -84,24 +98,15 @@ static void lpuart_serial_putc(const char c) WATCHDOG_RESET(); __raw_writeb(c, &base->ud); -} - -/* - * Test whether a character is in the RX buffer - */ -static int lpuart_serial_tstc(void) -{ - if (__raw_readb(&base->urcfifo) == 0) - return 0; - return 1; + return 0; } /* * Initialise the serial port with the given baudrate. The settings * are always 8 data bits, no parity, 1 stop bit, no start bits. */ -static int lpuart_serial_init(void) +static int lpuart_serial_init(struct lpuart_fsl *base) { u8 ctrl; @@ -118,29 +123,15 @@ static int lpuart_serial_init(void) __raw_writeb(0x0, &base->utwfifo); __raw_writeb(0x1, &base->urwfifo); __raw_writeb(CFIFO_TXFLUSH | CFIFO_RXFLUSH, &base->ucfifo); - - /* provide data bits, parity, stop bit, etc */ - - serial_setbrg(); - __raw_writeb(UC2_RE | UC2_TE, &base->uc2); return 0; } - -static struct serial_device lpuart_serial_drv = { - .name = "lpuart_serial", - .start = lpuart_serial_init, - .stop = NULL, - .setbrg = lpuart_serial_setbrg, - .putc = lpuart_serial_putc, - .puts = default_serial_puts, - .getc = lpuart_serial_getc, - .tstc = lpuart_serial_tstc, -}; -#else -static void lpuart32_serial_setbrg(void) +#else /* CONFIG_LPUART_32B_REG */ +int lpuart32_serial_setbrg(struct udevice *dev, int baudrate) { + struct lpuart_serial_priv *priv = dev_get_priv(dev); + struct lpuart_fsl *base = priv->lpuart_base; u32 clk = CONFIG_SYS_CLK_FREQ; u32 sbr; @@ -151,10 +142,14 @@ static void lpuart32_serial_setbrg(void) /* place adjustment later - n/32 BRFA */ out_be32(&base->baud, sbr); + + return 0; } -static int lpuart32_serial_getc(void) +static int lpuart32_serial_getc(struct udevice *dev) { + struct lpuart_serial_priv *priv = dev_get_priv(dev); + struct lpuart_fsl *base = priv->lpuart_base; u32 stat; while (((stat = in_be32(&base->stat)) & STAT_RDRF) == 0) { @@ -165,8 +160,11 @@ static int lpuart32_serial_getc(void) return in_be32(&base->data) & 0x3ff; } -static void lpuart32_serial_putc(const char c) +static int lpuart32_serial_putc(struct udevice *dev, const char c) { + struct lpuart_serial_priv *priv = dev_get_priv(dev); + struct lpuart_fsl *base = priv->lpuart_base; + if (c == '\n') serial_putc('\r'); @@ -174,24 +172,15 @@ static void lpuart32_serial_putc(const char c) WATCHDOG_RESET(); out_be32(&base->data, c); -} -/* - * Test whether a character is in the RX buffer - */ -static int lpuart32_serial_tstc(void) -{ - if ((in_be32(&base->water) >> 24) == 0) - return 0; - - return 1; + return 0; } /* * Initialise the serial port with the given baudrate. The settings * are always 8 data bits, no parity, 1 stop bit, no start bits. */ -static int lpuart32_serial_init(void) +static int lpuart32_serial_init(struct lpuart_fsl *base) { u8 ctrl; @@ -204,41 +193,54 @@ static int lpuart32_serial_init(void) out_be32(&base->fifo, ~(FIFO_TXFE | FIFO_RXFE)); out_be32(&base->match, 0); - /* provide data bits, parity, stop bit, etc */ - - serial_setbrg(); - out_be32(&base->ctrl, CTRL_RE | CTRL_TE); return 0; } +#endif /* CONFIG_LPUART_32B_REG */ -static struct serial_device lpuart32_serial_drv = { - .name = "lpuart32_serial", - .start = lpuart32_serial_init, - .stop = NULL, - .setbrg = lpuart32_serial_setbrg, - .putc = lpuart32_serial_putc, - .puts = default_serial_puts, - .getc = lpuart32_serial_getc, - .tstc = lpuart32_serial_tstc, -}; -#endif - -void lpuart_serial_initialize(void) +static int lpuart_serial_probe(struct udevice *dev) { -#ifdef CONFIG_LPUART_32B_REG - serial_register(&lpuart32_serial_drv); + struct lpuart_serial_platdata *plat = dev->platdata; + struct lpuart_serial_priv *priv = dev_get_priv(dev); + + priv->lpuart_base = (struct lpuart_fsl *)plat->base_addr; +#ifndef CONFIG_LPUART_32B_REG + lpuart_serial_init(priv->lpuart_base); #else - serial_register(&lpuart_serial_drv); + lpuart32_serial_init(priv->lpuart_base); #endif + return 0; } -__weak struct serial_device *default_serial_console(void) -{ -#ifdef CONFIG_LPUART_32B_REG - return &lpuart32_serial_drv; +#ifndef CONFIG_LPUART_32B_REG +static const struct dm_serial_ops lpuart_serial_ops = { + .putc = lpuart_serial_putc, + .getc = lpuart_serial_getc, + .setbrg = lpuart_serial_setbrg, +}; + +U_BOOT_DRIVER(serial_lpuart) = { + .name = "serial_lpuart", + .id = UCLASS_SERIAL, + .probe = lpuart_serial_probe, + .ops = &lpuart_serial_ops, + .flags = DM_FLAG_PRE_RELOC, + .priv_auto_alloc_size = sizeof(struct lpuart_serial_priv), +}; #else - return &lpuart_serial_drv; +static const struct dm_serial_ops lpuart32_serial_ops = { + .putc = lpuart32_serial_putc, + .getc = lpuart32_serial_getc, + .setbrg = lpuart32_serial_setbrg, +}; + +U_BOOT_DRIVER(serial_lpuart32) = { + .name = "serial_lpuart32", + .id = UCLASS_SERIAL, + .probe = lpuart_serial_probe, + .ops = &lpuart32_serial_ops, + .flags = DM_FLAG_PRE_RELOC, + .priv_auto_alloc_size = sizeof(struct lpuart_serial_priv), +}; #endif -} -- 2.7.0 _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot