[U-Boot] [PATCH 6/7] dm: at91: Add driver model support for the serial driver
Andreas Bießmann
andreas.devel at googlemail.com
Thu Oct 23 22:04:15 CEST 2014
Hi Simon,
On 06.10.14 20:14, Simon Glass wrote:
> Add driver model support while retaining the existing legacy code. This
> allows the driver to support boards that have converted to driver model
> as well as those that have not.
>
> Signed-off-by: Simon Glass <sjg at chromium.org>
> ---
>
> arch/arm/include/asm/arch-at91/at91_serial.h | 15 +++++
> drivers/serial/atmel_usart.c | 85 ++++++++++++++++++++++++++++
> 2 files changed, 100 insertions(+)
> create mode 100644 arch/arm/include/asm/arch-at91/at91_serial.h
>
> diff --git a/arch/arm/include/asm/arch-at91/at91_serial.h b/arch/arm/include/asm/arch-at91/at91_serial.h
> new file mode 100644
> index 0000000..9f78ed4
> --- /dev/null
> +++ b/arch/arm/include/asm/arch-at91/at91_serial.h
> @@ -0,0 +1,15 @@
> +/*
> + * Copyright (c) 2014 Google, Inc
> + *
> + * SPDX-License-Identifier: GPL-2.0+
> + */
> +
> +#ifndef _AT91_SERIAL_H
> +#define _AT91_SERIAL_H
> +
> +/* Information about a serial port */
> +struct at91_serial_platdata {
> + uint32_t base_addr;
> +};
> +
> +#endif
> diff --git a/drivers/serial/atmel_usart.c b/drivers/serial/atmel_usart.c
> index ce36e99..d3e2ade 100644
> --- a/drivers/serial/atmel_usart.c
> +++ b/drivers/serial/atmel_usart.c
> @@ -7,11 +7,17 @@
> * SPDX-License-Identifier: GPL-2.0+
> */
> #include <common.h>
> +#include <dm.h>
> +#include <errno.h>
> #include <watchdog.h>
> #include <serial.h>
> #include <linux/compiler.h>
>
> #include <asm/io.h>
> +#ifdef CONFIG_DM_SERIAL
> +/* Should this be made common with avr32? */
yes, we should do so. Therefore I vote for atmel_serial.h.
> +#include <asm/arch/at91_serial.h>
> +#endif
> #include <asm/arch/clk.h>
> #include <asm/arch/hardware.h>
>
> @@ -60,6 +66,7 @@ static void atmel_serial_activate(atmel_usart3_t *usart)
> __udelay(100);
> }
>
> +#ifndef CONFIG_DM_SERIAL
> static void atmel_serial_setbrg(void)
> {
> atmel_serial_setbrg_internal((atmel_usart3_t *)CONFIG_USART_BASE,
> @@ -123,3 +130,81 @@ __weak struct serial_device *default_serial_console(void)
> {
> return &atmel_serial_drv;
> }
> +#endif
> +
> +#ifdef CONFIG_DM_SERIAL
> +
> +struct at91_serial_priv {
> + atmel_usart3_t *usart;
> +};
> +
> +int at91_serial_setbrg(struct udevice *dev, int baudrate)
> +{
> + struct at91_serial_priv *priv = dev_get_priv(dev);
> +
> + atmel_serial_setbrg_internal(priv->usart, 0 /* ignored */, baudrate);
> + atmel_serial_activate(priv->usart);
> +
> + return 0;
> +}
> +
> +static int at91_serial_getc(struct udevice *dev)
> +{
> + struct at91_serial_priv *priv = dev_get_priv(dev);
> +
> + if (!(readl(&priv->usart->csr) & USART3_BIT(RXRDY)))
> + return -EAGAIN;
> +
> + return readl(&priv->usart->rhr);
> +}
> +
> +static int at91_serial_putc(struct udevice *dev, const char ch)
> +{
> + struct at91_serial_priv *priv = dev_get_priv(dev);
> +
> + if (!(readl(&priv->usart->csr) & USART3_BIT(TXRDY)))
> + return -EAGAIN;
> +
> + writel(ch, &priv->usart->thr);
> +
> + return 0;
> +}
> +
> +static int at91_serial_pending(struct udevice *dev, bool input)
> +{
> + struct at91_serial_priv *priv = dev_get_priv(dev);
> + uint32_t csr = readl(&priv->usart->csr);
> +
> + if (input)
> + return csr & USART3_BIT(RXRDY) ? 1 : 0;
> + else
> + return csr & USART3_BIT(TXEMPTY) ? 0 : 1;
> +}
> +
> +static const struct dm_serial_ops at91_serial_ops = {
> + .putc = at91_serial_putc,
> + .pending = at91_serial_pending,
> + .getc = at91_serial_getc,
> + .setbrg = at91_serial_setbrg,
> +};
> +
> +static int at91_serial_probe(struct udevice *dev)
> +{
> + struct at91_serial_platdata *plat = dev->platdata;
> + struct at91_serial_priv *priv = dev_get_priv(dev);
> +
> + priv->usart = (atmel_usart3_t *)plat->base_addr;
> + atmel_serial_init_internal(priv->usart);
> +
> + return 0;
> +}
> +
> +U_BOOT_DRIVER(serial_at91) = {
Please name it 'atmel' rather than 'at91' at91 is just one (legacy)
product family, there is also avr32 (ok, outdated) but new and growing
'sama5'.
> + .name = "serial_at91",
> + .id = UCLASS_SERIAL,
> + .probe = at91_serial_probe,
> + .ops = &at91_serial_ops,
> + .flags = DM_FLAG_PRE_RELOC,
> + .priv_auto_alloc_size = sizeof(struct at91_serial_priv),
> +};
> +#endif
>
The patch looks good to me, but I wonder if changing the baudrate is
working as expected. Did you test this?
Best regards
Andreas Bießmann
More information about the U-Boot
mailing list