[U-Boot] [PATCH 13/13] arm: zynq: Move serial driver to driver model

Michal Simek
2015-09-01T15:42:24Z

On 08/29/2015 05:10 PM, Simon Glass wrote:
> Update this driver to use driver model and change all users.
>
> Signed-off-by: Simon Glass <sjg@chromium.org>
> ---
>
> arch/arm/Kconfig | 1 +
> drivers/serial/serial_zynq.c | 162 ++++++++++++++++------------------------
> include/configs/zynq_microzed.h | 1 -
> include/configs/zynq_picozed.h | 1 -
> include/configs/zynq_zc70x.h | 1 -
> include/configs/zynq_zc770.h | 6 --
> include/configs/zynq_zed.h | 1 -
> include/configs/zynq_zybo.h | 1 -
> 8 files changed, 65 insertions(+), 109 deletions(-)
>
> diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
> index a82306e..7705e03 100644
> --- a/arch/arm/Kconfig
> +++ b/arch/arm/Kconfig
> @@ -687,6 +687,7 @@ config ARCH_ZYNQ
> select DM
> select SPL_DM
> select DM_SPI
> + select DM_SERIAL

Can you please keep DM_SPI and DM_SPI_FLASH together?

> select DM_SPI_FLASH
> select SPL_SEPARATE_BSS
>
> diff --git a/drivers/serial/serial_zynq.c b/drivers/serial/serial_zynq.c
> index c39c1a9..7069afe 100644
> --- a/drivers/serial/serial_zynq.c
> +++ b/drivers/serial/serial_zynq.c
> @@ -6,6 +6,8 @@
> */
>
> #include <common.h>
> +#include <debug_uart.h>
> +#include <dm.h>
> #include <errno.h>
> #include <fdtdec.h>
> #include <watchdog.h>
> @@ -18,6 +20,7 @@
> DECLARE_GLOBAL_DATA_PTR;
>
> #define ZYNQ_UART_SR_TXFULL 0x00000010 /* TX FIFO full */
> +#define ZYNQ_UART_SR_TXACTIVE (1 << 11) /* TX active */
> #define ZYNQ_UART_SR_RXEMPTY 0x00000002 /* RX FIFO empty */
>
> #define ZYNQ_UART_CR_TX_EN 0x00000010 /* TX enabled */
> @@ -38,9 +41,8 @@ struct uart_zynq {
> u32 baud_rate_divider; /* 0x34 - Baud Rate Divider [7:0] */
> };
>
> -static struct uart_zynq *uart_zynq_ports[2] = {
> - [0] = (struct uart_zynq *)ZYNQ_SERIAL_BASEADDR0,
> - [1] = (struct uart_zynq *)ZYNQ_SERIAL_BASEADDR1,
> +struct zynq_uart_priv {
> + struct uart_zynq *regs;
> };
>
> /* Set up the baud rate in gd struct */
> @@ -84,15 +86,6 @@ static void _uart_zynq_serial_setbrg(struct uart_zynq *regs,
> writel(bgen, &regs->baud_rate_gen);
> }
>
> -/* Set up the baud rate in gd struct */
> -static void uart_zynq_serial_setbrg(const int port)
> -{
> - unsigned long clock = get_uart_clk(port);
> - struct uart_zynq *regs = uart_zynq_ports[port];
> -
> - return _uart_zynq_serial_setbrg(regs, clock, gd->baudrate);
> -}
> -
> /* Initialize the UART, with...some settings. */
> static void _uart_zynq_serial_init(struct uart_zynq *regs)
> {
> @@ -102,20 +95,6 @@ static void _uart_zynq_serial_init(struct uart_zynq *regs)
> writel(ZYNQ_UART_MR_PARITY_NONE, &regs->mode); /* 8 bit, no parity */
> }
>
> -/* 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;
> -
> - _uart_zynq_serial_init(regs);
> - uart_zynq_serial_setbrg(port);
> -
> - return 0;
> -}
> -
> static int _uart_zynq_serial_putc(struct uart_zynq *regs, const char c)
> {
> if (readl(&regs->channel_sts) & ZYNQ_UART_SR_TXFULL)
> @@ -126,103 +105,90 @@ static int _uart_zynq_serial_putc(struct uart_zynq *regs, const char c)
> return 0;
> }
>
> -static void uart_zynq_serial_putc(const char c, const int port)
> +int zynq_serial_setbrg(struct udevice *dev, int baudrate)
> {
> - struct uart_zynq *regs = uart_zynq_ports[port];
> + struct zynq_uart_priv *priv = dev_get_priv(dev);
> + unsigned long clock = get_uart_clk(0);
>
> - while (_uart_zynq_serial_putc(regs, c) == -EAGAIN)
> - WATCHDOG_RESET();
> + _uart_zynq_serial_setbrg(priv->regs, clock, baudrate);
>
> - if (c == '\n') {
> - while (_uart_zynq_serial_putc(regs, '\r') == -EAGAIN)
> - WATCHDOG_RESET();
> - }
> + return 0;
> }
>
> -static void uart_zynq_serial_puts(const char *s, const int port)
> +static int zynq_serial_probe(struct udevice *dev)
> {
> - while (*s)
> - uart_zynq_serial_putc(*s++, port);
> -}
> + struct zynq_uart_priv *priv = dev_get_priv(dev);
>
> -static int uart_zynq_serial_tstc(const int port)
> -{
> - struct uart_zynq *regs = uart_zynq_ports[port];
> + _uart_zynq_serial_init(priv->regs);
>
> - return (readl(&regs->channel_sts) & ZYNQ_UART_SR_RXEMPTY) == 0;
> + return 0;
> }
>
> -static int uart_zynq_serial_getc(const int port)
> +static int zynq_serial_getc(struct udevice *dev)
> {
> - struct uart_zynq *regs = uart_zynq_ports[port];
> + struct zynq_uart_priv *priv = dev_get_priv(dev);
> + struct uart_zynq *regs = priv->regs;
> +
> + if (readl(&regs->channel_sts) & ZYNQ_UART_SR_RXEMPTY)
> + return -EAGAIN;
>
> - while (!uart_zynq_serial_tstc(port))
> - WATCHDOG_RESET();
> return readl(&regs->tx_rx_fifo);
> }
>
> -/* Multi serial device functions */
> -#define DECLARE_PSSERIAL_FUNCTIONS(port) \
> - static int uart_zynq##port##_init(void) \
> - { return uart_zynq_serial_init(port); } \
> - static void uart_zynq##port##_setbrg(void) \
> - { return uart_zynq_serial_setbrg(port); } \
> - static int uart_zynq##port##_getc(void) \
> - { return uart_zynq_serial_getc(port); } \
> - static int uart_zynq##port##_tstc(void) \
> - { return uart_zynq_serial_tstc(port); } \
> - static void uart_zynq##port##_putc(const char c) \
> - { uart_zynq_serial_putc(c, port); } \
> - static 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, \
> -}
> +static int zynq_serial_putc(struct udevice *dev, const char ch)
> +{
> + struct zynq_uart_priv *priv = dev_get_priv(dev);
>
> -DECLARE_PSSERIAL_FUNCTIONS(0);
> -static struct serial_device uart_zynq_serial0_device =
> - INIT_PSSERIAL_STRUCTURE(0, "ttyPS0");
> -DECLARE_PSSERIAL_FUNCTIONS(1);
> -static struct serial_device uart_zynq_serial1_device =
> - INIT_PSSERIAL_STRUCTURE(1, "ttyPS1");
> + return _uart_zynq_serial_putc(priv->regs, ch);
> +}
>
> -__weak struct serial_device *default_serial_console(void)
> +static int zynq_serial_pending(struct udevice *dev, bool input)
> {
> - const void *blob = gd->fdt_blob;
> - int node;
> - unsigned int base_addr;
> + struct zynq_uart_priv *priv = dev_get_priv(dev);
> + struct uart_zynq *regs = priv->regs;
>
> - node = fdt_path_offset(blob, "serial0");
> - if (node < 0)
> - return NULL;
> + if (input)
> + return !(readl(&regs->channel_sts) & ZYNQ_UART_SR_RXEMPTY);
> + else
> + return !!(readl(&regs->channel_sts) & ZYNQ_UART_SR_TXACTIVE);
> +}
>
> - base_addr = fdtdec_get_addr(blob, node, "reg");
> - if (base_addr == FDT_ADDR_T_NONE)
> - return NULL;
> +static int zynq_serial_ofdata_to_platdata(struct udevice *dev)
> +{
> + struct zynq_uart_priv *priv = dev_get_priv(dev);
> + fdt_addr_t addr;
>
> - if (base_addr == ZYNQ_SERIAL_BASEADDR0)
> - return &uart_zynq_serial0_device;
> + addr = fdtdec_get_addr(gd->fdt_blob, dev->of_offset, "reg");
> + if (addr == FDT_ADDR_T_NONE)
> + return -EINVAL;
>
> - if (base_addr == ZYNQ_SERIAL_BASEADDR1)
> - return &uart_zynq_serial1_device;
> + priv->regs = (struct uart_zynq *)addr;
>
> - return NULL;
> + return 0;
> }
>
> -void zynq_serial_initialize(void)
> -{
> - serial_register(&uart_zynq_serial0_device);
> - serial_register(&uart_zynq_serial1_device);
> -}
> +static const struct dm_serial_ops zynq_serial_ops = {
> + .putc = zynq_serial_putc,
> + .pending = zynq_serial_pending,
> + .getc = zynq_serial_getc,
> + .setbrg = zynq_serial_setbrg,
> +};
> +
> +static const struct udevice_id zynq_serial_ids[] = {
> + { .compatible = "xlnx,xuartps" },

I would prefer to use
{ .compatible = "cdns,uart-r1p8" },
instead.
Or both.

The reason is that xlnx,xuartps compatible string is deprecated.
We switch to cadence compatible string.

> + { }
> +};
> +
> +U_BOOT_DRIVER(serial_s5p) = {

serial_zynq here

Thanks,
Michal

--
Michal Simek, Ing. (M.Eng), OpenPGP -> KeyID: FE3D1F91
w: www.monstr.eu p: +42-0-721842854
Maintainer of Linux kernel - Microblaze cpu - http://www.monstr.eu/fdt/
Maintainer of Linux kernel - Xilinx Zynq ARM architecture
Microblaze U-BOOT custodian and responsible for u-boot arm zynq platform

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 198 bytes
Desc: OpenPGP digital signature
URL: <http://lists.denx.de/pipermail/u-boot/attachments/20150901/81fd229e/attachment.sig>