diff mbox

[U-Boot,v2,6/9] dm: at91: Add driver model support for the serial driver

Message ID 1414609743-19092-7-git-send-email-sjg@chromium.org
State Accepted
Delegated to: Simon Glass
Headers show

Commit Message

Simon Glass Oct. 29, 2014, 7:09 p.m. UTC
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@chromium.org>
---

Changes in v2:
- Rename header to atmel_serial.h and use atmel instead of at91 throughout

 arch/arm/include/asm/arch-at91/atmel_serial.h | 15 +++++
 drivers/serial/atmel_usart.c                  | 84 +++++++++++++++++++++++++++
 2 files changed, 99 insertions(+)
 create mode 100644 arch/arm/include/asm/arch-at91/atmel_serial.h

Comments

Simon Glass Nov. 23, 2014, 12:55 p.m. UTC | #1
On 29 October 2014 at 20:09, Simon Glass <sjg@chromium.org> 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@chromium.org>
> ---
>
> Changes in v2:
> - Rename header to atmel_serial.h and use atmel instead of at91 throughout
>
>  arch/arm/include/asm/arch-at91/atmel_serial.h | 15 +++++
>  drivers/serial/atmel_usart.c                  | 84 +++++++++++++++++++++++++++
>  2 files changed, 99 insertions(+)
>  create mode 100644 arch/arm/include/asm/arch-at91/atmel_serial.h

Applied to u-boot-dm.
diff mbox

Patch

diff --git a/arch/arm/include/asm/arch-at91/atmel_serial.h b/arch/arm/include/asm/arch-at91/atmel_serial.h
new file mode 100644
index 0000000..5bc094b
--- /dev/null
+++ b/arch/arm/include/asm/arch-at91/atmel_serial.h
@@ -0,0 +1,15 @@ 
+/*
+ * Copyright (c) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier:     GPL-2.0+
+ */
+
+#ifndef _ATMEL_SERIAL_H
+#define _ATMEL_SERIAL_H
+
+/* Information about a serial port */
+struct atmel_serial_platdata {
+	uint32_t base_addr;
+};
+
+#endif
diff --git a/drivers/serial/atmel_usart.c b/drivers/serial/atmel_usart.c
index ce36e99..4fe992b 100644
--- a/drivers/serial/atmel_usart.c
+++ b/drivers/serial/atmel_usart.c
@@ -7,11 +7,16 @@ 
  * 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
+#include <asm/arch/atmel_serial.h>
+#endif
 #include <asm/arch/clk.h>
 #include <asm/arch/hardware.h>
 
@@ -60,6 +65,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 +129,81 @@  __weak struct serial_device *default_serial_console(void)
 {
 	return &atmel_serial_drv;
 }
+#endif
+
+#ifdef CONFIG_DM_SERIAL
+
+struct atmel_serial_priv {
+	atmel_usart3_t *usart;
+};
+
+int atmel_serial_setbrg(struct udevice *dev, int baudrate)
+{
+	struct atmel_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 atmel_serial_getc(struct udevice *dev)
+{
+	struct atmel_serial_priv *priv = dev_get_priv(dev);
+
+	if (!(readl(&priv->usart->csr) & USART3_BIT(RXRDY)))
+		return -EAGAIN;
+
+	return readl(&priv->usart->rhr);
+}
+
+static int atmel_serial_putc(struct udevice *dev, const char ch)
+{
+	struct atmel_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 atmel_serial_pending(struct udevice *dev, bool input)
+{
+	struct atmel_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 atmel_serial_ops = {
+	.putc = atmel_serial_putc,
+	.pending = atmel_serial_pending,
+	.getc = atmel_serial_getc,
+	.setbrg = atmel_serial_setbrg,
+};
+
+static int atmel_serial_probe(struct udevice *dev)
+{
+	struct atmel_serial_platdata *plat = dev->platdata;
+	struct atmel_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_atmel) = {
+	.name	= "serial_atmel",
+	.id	= UCLASS_SERIAL,
+	.probe = atmel_serial_probe,
+	.ops	= &atmel_serial_ops,
+	.flags = DM_FLAG_PRE_RELOC,
+	.priv_auto_alloc_size	= sizeof(struct atmel_serial_priv),
+};
+#endif