summaryrefslogtreecommitdiff
path: root/drivers/serial
diff options
context:
space:
mode:
authorTom Rini <trini@ti.com>2014-10-26 14:03:08 -0400
committerTom Rini <trini@ti.com>2014-10-26 14:03:08 -0400
commit84a6df09c78bc9e9cbc6265d99c9097f5f1079f2 (patch)
tree3b2bf1b3689e9aad0d20f5a69ada168cae3cc769 /drivers/serial
parentc69ecd9722af22d50295eff81d0b9cd5b8adc2e0 (diff)
parentc2ded962d4703a3f9522553004db4a6fe540f7e6 (diff)
downloadu-boot-imx-84a6df09c78bc9e9cbc6265d99c9097f5f1079f2.zip
u-boot-imx-84a6df09c78bc9e9cbc6265d99c9097f5f1079f2.tar.gz
u-boot-imx-84a6df09c78bc9e9cbc6265d99c9097f5f1079f2.tar.bz2
Merge git://git.denx.de/u-boot-dm
Fix a trivial conflict over adding <dm.h> Conflicts: arch/arm/cpu/armv7/omap3/board.c Signed-off-by: Tom Rini <trini@ti.com>
Diffstat (limited to 'drivers/serial')
-rw-r--r--drivers/serial/Kconfig12
-rw-r--r--drivers/serial/Makefile2
-rw-r--r--drivers/serial/ns16550.c17
-rw-r--r--drivers/serial/serial-uclass.c99
-rw-r--r--drivers/serial/serial.c2
-rw-r--r--drivers/serial/serial_coreboot.c38
-rw-r--r--drivers/serial/serial_mxc.c2
-rw-r--r--drivers/serial/serial_ns16550.c21
-rw-r--r--drivers/serial/serial_omap.c47
-rw-r--r--drivers/serial/serial_pl01x.c2
-rw-r--r--drivers/serial/serial_s3c24x0.c10
-rw-r--r--drivers/serial/serial_uniphier.c199
12 files changed, 251 insertions, 200 deletions
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index e69de29..a0b6e02 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -0,0 +1,12 @@
+config DM_SERIAL
+ bool "Enable Driver Model for serial drivers"
+ depends on DM
+ help
+ If you want to use driver model for serial drivers, say Y.
+ To use legacy serial drivers, say N.
+
+config UNIPHIER_SERIAL
+ bool "UniPhier on-chip UART support"
+ depends on ARCH_UNIPHIER && DM_SERIAL
+ help
+ Support for the on-chip UARTs on the Panasonic UniPhier platform.
diff --git a/drivers/serial/Makefile b/drivers/serial/Makefile
index 17c56ea..2c19ebc 100644
--- a/drivers/serial/Makefile
+++ b/drivers/serial/Makefile
@@ -41,6 +41,8 @@ obj-$(CONFIG_MXS_AUART) += mxs_auart.o
obj-$(CONFIG_ARC_SERIAL) += serial_arc.o
obj-$(CONFIG_TEGRA_SERIAL) += serial_tegra.o
obj-$(CONFIG_UNIPHIER_SERIAL) += serial_uniphier.o
+obj-$(CONFIG_OMAP_SERIAL) += serial_omap.o
+obj-$(CONFIG_COREBOOT_SERIAL) += serial_coreboot.o
ifndef CONFIG_SPL_BUILD
obj-$(CONFIG_USB_TTY) += usbtty.o
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index 63a9ef6..8f05191 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -61,13 +61,13 @@ static void ns16550_writeb(NS16550_t port, int offset, int value)
unsigned char *addr;
offset *= 1 << plat->reg_shift;
- addr = plat->base + offset;
+ addr = map_sysmem(plat->base, 0) + offset;
/*
* As far as we know it doesn't make sense to support selection of
* these options at run-time, so use the existing CONFIG options.
*/
#ifdef CONFIG_SYS_NS16550_PORT_MAPPED
- outb(value, addr);
+ outb(value, (ulong)addr);
#elif defined(CONFIG_SYS_NS16550_MEM32) && !defined(CONFIG_SYS_BIG_ENDIAN)
out_le32(addr, value);
#elif defined(CONFIG_SYS_NS16550_MEM32) && defined(CONFIG_SYS_BIG_ENDIAN)
@@ -85,9 +85,9 @@ static int ns16550_readb(NS16550_t port, int offset)
unsigned char *addr;
offset *= 1 << plat->reg_shift;
- addr = plat->base + offset;
+ addr = map_sysmem(plat->base, 0) + offset;
#ifdef CONFIG_SYS_NS16550_PORT_MAPPED
- return inb(addr);
+ return inb((ulong)addr);
#elif defined(CONFIG_SYS_NS16550_MEM32) && !defined(CONFIG_SYS_BIG_ENDIAN)
return in_le32(addr);
#elif defined(CONFIG_SYS_NS16550_MEM32) && defined(CONFIG_SYS_BIG_ENDIAN)
@@ -253,7 +253,7 @@ static int ns16550_serial_getc(struct udevice *dev)
{
struct NS16550 *const com_port = dev_get_priv(dev);
- if (!serial_in(&com_port->lsr) & UART_LSR_DR)
+ if (!(serial_in(&com_port->lsr) & UART_LSR_DR))
return -EAGAIN;
return serial_in(&com_port->rbr);
@@ -276,14 +276,15 @@ int ns16550_serial_probe(struct udevice *dev)
{
struct NS16550 *const com_port = dev_get_priv(dev);
+ com_port->plat = dev_get_platdata(dev);
NS16550_init(com_port, -1);
return 0;
}
+#ifdef CONFIG_OF_CONTROL
int ns16550_serial_ofdata_to_platdata(struct udevice *dev)
{
- struct NS16550 *const com_port = dev_get_priv(dev);
struct ns16550_platdata *plat = dev->platdata;
fdt_addr_t addr;
@@ -291,13 +292,13 @@ int ns16550_serial_ofdata_to_platdata(struct udevice *dev)
if (addr == FDT_ADDR_T_NONE)
return -EINVAL;
- plat->base = (unsigned char *)addr;
+ plat->base = addr;
plat->reg_shift = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
"reg-shift", 1);
- com_port->plat = plat;
return 0;
}
+#endif
const struct dm_serial_ops ns16550_serial_ops = {
.putc = ns16550_serial_putc,
diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
index 1a75950..71f1a5c 100644
--- a/drivers/serial/serial-uclass.c
+++ b/drivers/serial/serial-uclass.c
@@ -11,9 +11,12 @@
#include <os.h>
#include <serial.h>
#include <stdio_dev.h>
+#include <watchdog.h>
#include <dm/lists.h>
#include <dm/device-internal.h>
+#include <ns16550.h>
+
DECLARE_GLOBAL_DATA_PTR;
/* The currently-selected console serial device */
@@ -47,13 +50,22 @@ static void serial_find_console_or_panic(void)
}
#endif
/*
+ * Try to use CONFIG_CONS_INDEX if available (it is numbered from 1!).
+ *
* Failing that, get the device with sequence number 0, or in extremis
* just the first serial device we can find. But we insist on having
* a console (even if it is silent).
*/
- if (uclass_get_device_by_seq(UCLASS_SERIAL, 0, &cur_dev) &&
+#ifdef CONFIG_CONS_INDEX
+#define INDEX (CONFIG_CONS_INDEX - 1)
+#else
+#define INDEX 0
+#endif
+ if (uclass_get_device_by_seq(UCLASS_SERIAL, INDEX, &cur_dev) &&
+ uclass_get_device(UCLASS_SERIAL, INDEX, &cur_dev) &&
(uclass_first_device(UCLASS_SERIAL, &cur_dev) || !cur_dev))
panic("No serial driver found");
+#undef INDEX
}
/* Called prior to relocation */
@@ -71,62 +83,74 @@ void serial_initialize(void)
serial_find_console_or_panic();
}
-static void serial_putc_dev(struct udevice *dev, char ch)
+static void _serial_putc(struct udevice *dev, char ch)
{
- struct dm_serial_ops *ops = serial_get_ops(cur_dev);
+ struct dm_serial_ops *ops = serial_get_ops(dev);
int err;
do {
- err = ops->putc(cur_dev, ch);
+ err = ops->putc(dev, ch);
} while (err == -EAGAIN);
if (ch == '\n')
- serial_putc('\r');
+ _serial_putc(dev, '\r');
}
-void serial_putc(char ch)
+static void _serial_puts(struct udevice *dev, const char *str)
{
- serial_putc_dev(cur_dev, ch);
+ while (*str)
+ _serial_putc(dev, *str++);
}
-void serial_setbrg(void)
+static int _serial_getc(struct udevice *dev)
{
- struct dm_serial_ops *ops = serial_get_ops(cur_dev);
+ struct dm_serial_ops *ops = serial_get_ops(dev);
+ int err;
- if (ops->setbrg)
- ops->setbrg(cur_dev, gd->baudrate);
-}
+ do {
+ err = ops->getc(dev);
+ if (err == -EAGAIN)
+ WATCHDOG_RESET();
+ } while (err == -EAGAIN);
-void serial_puts(const char *str)
-{
- while (*str)
- serial_putc(*str++);
+ return err >= 0 ? err : 0;
}
-int serial_tstc(void)
+static int _serial_tstc(struct udevice *dev)
{
- struct dm_serial_ops *ops = serial_get_ops(cur_dev);
+ struct dm_serial_ops *ops = serial_get_ops(dev);
if (ops->pending)
- return ops->pending(cur_dev, true);
+ return ops->pending(dev, true);
return 1;
}
-static int serial_getc_dev(struct udevice *dev)
+void serial_putc(char ch)
{
- struct dm_serial_ops *ops = serial_get_ops(dev);
- int err;
-
- do {
- err = ops->getc(dev);
- } while (err == -EAGAIN);
+ _serial_putc(cur_dev, ch);
+}
- return err >= 0 ? err : 0;
+void serial_puts(const char *str)
+{
+ _serial_puts(cur_dev, str);
}
int serial_getc(void)
{
- return serial_getc_dev(cur_dev);
+ return _serial_getc(cur_dev);
+}
+
+int serial_tstc(void)
+{
+ return _serial_tstc(cur_dev);
+}
+
+void serial_setbrg(void)
+{
+ struct dm_serial_ops *ops = serial_get_ops(cur_dev);
+
+ if (ops->setbrg)
+ ops->setbrg(cur_dev, gd->baudrate);
}
void serial_stdio_init(void)
@@ -135,33 +159,22 @@ void serial_stdio_init(void)
static void serial_stub_putc(struct stdio_dev *sdev, const char ch)
{
- struct udevice *dev = sdev->priv;
-
- serial_putc_dev(dev, ch);
+ _serial_putc(sdev->priv, ch);
}
void serial_stub_puts(struct stdio_dev *sdev, const char *str)
{
- while (*str)
- serial_stub_putc(sdev, *str++);
+ _serial_puts(sdev->priv, str);
}
int serial_stub_getc(struct stdio_dev *sdev)
{
- struct udevice *dev = sdev->priv;
-
- return serial_getc_dev(dev);
+ return _serial_getc(sdev->priv);
}
int serial_stub_tstc(struct stdio_dev *sdev)
{
- struct udevice *dev = sdev->priv;
- struct dm_serial_ops *ops = serial_get_ops(dev);
-
- if (ops->pending)
- return ops->pending(dev, true);
-
- return 1;
+ return _serial_tstc(sdev->priv);
}
static int serial_post_probe(struct udevice *dev)
diff --git a/drivers/serial/serial.c b/drivers/serial/serial.c
index 71cb97d..18e41b2 100644
--- a/drivers/serial/serial.c
+++ b/drivers/serial/serial.c
@@ -157,7 +157,6 @@ serial_initfunc(sh_serial_initialize);
serial_initfunc(arm_dcc_initialize);
serial_initfunc(mxs_auart_initialize);
serial_initfunc(arc_serial_initialize);
-serial_initfunc(uniphier_serial_initialize);
/**
* serial_register() - Register serial driver with serial driver core
@@ -251,7 +250,6 @@ void serial_initialize(void)
arm_dcc_initialize();
mxs_auart_initialize();
arc_serial_initialize();
- uniphier_serial_initialize();
serial_assign(default_serial_console()->name);
}
diff --git a/drivers/serial/serial_coreboot.c b/drivers/serial/serial_coreboot.c
new file mode 100644
index 0000000..5c6a76c
--- /dev/null
+++ b/drivers/serial/serial_coreboot.c
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <ns16550.h>
+#include <serial.h>
+
+static const struct udevice_id coreboot_serial_ids[] = {
+ { .compatible = "coreboot-uart" },
+ { }
+};
+
+static int coreboot_serial_ofdata_to_platdata(struct udevice *dev)
+{
+ struct ns16550_platdata *plat = dev_get_platdata(dev);
+ int ret;
+
+ ret = ns16550_serial_ofdata_to_platdata(dev);
+ if (ret)
+ return ret;
+ plat->clock = 1843200;
+
+ return 0;
+}
+U_BOOT_DRIVER(serial_ns16550) = {
+ .name = "serial_coreboot",
+ .id = UCLASS_SERIAL,
+ .of_match = coreboot_serial_ids,
+ .ofdata_to_platdata = coreboot_serial_ofdata_to_platdata,
+ .platdata_auto_alloc_size = sizeof(struct ns16550_platdata),
+ .priv_auto_alloc_size = sizeof(struct NS16550),
+ .probe = ns16550_serial_probe,
+ .ops = &ns16550_serial_ops,
+};
diff --git a/drivers/serial/serial_mxc.c b/drivers/serial/serial_mxc.c
index 9ce24f9..d6cf1d8 100644
--- a/drivers/serial/serial_mxc.c
+++ b/drivers/serial/serial_mxc.c
@@ -7,10 +7,10 @@
#include <common.h>
#include <dm.h>
#include <errno.h>
-#include <serial_mxc.h>
#include <watchdog.h>
#include <asm/arch/imx-regs.h>
#include <asm/arch/clock.h>
+#include <dm/platform_data/serial_mxc.h>
#include <serial.h>
#include <linux/compiler.h>
diff --git a/drivers/serial/serial_ns16550.c b/drivers/serial/serial_ns16550.c
index 632da4c..799ef6a 100644
--- a/drivers/serial/serial_ns16550.c
+++ b/drivers/serial/serial_ns16550.c
@@ -119,8 +119,7 @@ static NS16550_t serial_ports[6] = {
.puts = eserial##port##_puts, \
}
-void
-_serial_putc(const char c,const int port)
+static void _serial_putc(const char c, const int port)
{
if (c == '\n')
NS16550_putc(PORT, '\r');
@@ -128,35 +127,29 @@ _serial_putc(const char c,const int port)
NS16550_putc(PORT, c);
}
-void
-_serial_putc_raw(const char c,const int port)
+static void _serial_putc_raw(const char c, const int port)
{
NS16550_putc(PORT, c);
}
-void
-_serial_puts (const char *s,const int port)
+static void _serial_puts(const char *s, const int port)
{
while (*s) {
- _serial_putc (*s++,port);
+ _serial_putc(*s++, port);
}
}
-
-int
-_serial_getc(const int port)
+static int _serial_getc(const int port)
{
return NS16550_getc(PORT);
}
-int
-_serial_tstc(const int port)
+static int _serial_tstc(const int port)
{
return NS16550_tstc(PORT);
}
-void
-_serial_setbrg (const int port)
+static void _serial_setbrg(const int port)
{
int clock_divisor;
diff --git a/drivers/serial/serial_omap.c b/drivers/serial/serial_omap.c
new file mode 100644
index 0000000..265fe00
--- /dev/null
+++ b/drivers/serial/serial_omap.c
@@ -0,0 +1,47 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <ns16550.h>
+#include <serial.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#ifdef CONFIG_OF_CONTROL
+static const struct udevice_id omap_serial_ids[] = {
+ { .compatible = "ti,omap3-uart" },
+ { }
+};
+
+static int omap_serial_ofdata_to_platdata(struct udevice *dev)
+{
+ struct ns16550_platdata *plat = dev_get_platdata(dev);
+ int ret;
+
+ ret = ns16550_serial_ofdata_to_platdata(dev);
+ if (ret)
+ return ret;
+ plat->clock = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
+ "clock-frequency", -1);
+ plat->reg_shift = 2;
+
+ return 0;
+}
+#endif
+
+U_BOOT_DRIVER(serial_omap_ns16550) = {
+ .name = "serial_omap",
+ .id = UCLASS_SERIAL,
+ .of_match = of_match_ptr(omap_serial_ids),
+ .ofdata_to_platdata = of_match_ptr(omap_serial_ofdata_to_platdata),
+ .platdata_auto_alloc_size = sizeof(struct ns16550_platdata),
+ .priv_auto_alloc_size = sizeof(struct NS16550),
+ .probe = ns16550_serial_probe,
+ .ops = &ns16550_serial_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};
diff --git a/drivers/serial/serial_pl01x.c b/drivers/serial/serial_pl01x.c
index e6313ad..38dda91 100644
--- a/drivers/serial/serial_pl01x.c
+++ b/drivers/serial/serial_pl01x.c
@@ -17,7 +17,7 @@
#include <watchdog.h>
#include <asm/io.h>
#include <serial.h>
-#include <serial_pl01x.h>
+#include <dm/platform_data/serial_pl01x.h>
#include <linux/compiler.h>
#include "serial_pl01x_internal.h"
diff --git a/drivers/serial/serial_s3c24x0.c b/drivers/serial/serial_s3c24x0.c
index c07f4c9..7afc504 100644
--- a/drivers/serial/serial_s3c24x0.c
+++ b/drivers/serial/serial_s3c24x0.c
@@ -69,7 +69,7 @@ DECLARE_GLOBAL_DATA_PTR;
static int hwflow;
#endif
-void _serial_setbrg(const int dev_index)
+static void _serial_setbrg(const int dev_index)
{
struct s3c24x0_uart *uart = s3c24x0_get_base_uart(dev_index);
unsigned int reg = 0;
@@ -131,7 +131,7 @@ static int serial_init_dev(const int dev_index)
* otherwise. When the function is succesfull, the character read is
* written into its argument c.
*/
-int _serial_getc(const int dev_index)
+static int _serial_getc(const int dev_index)
{
struct s3c24x0_uart *uart = s3c24x0_get_base_uart(dev_index);
@@ -181,7 +181,7 @@ void enable_putc(void)
/*
* Output a single byte to the serial port.
*/
-void _serial_putc(const char c, const int dev_index)
+static void _serial_putc(const char c, const int dev_index)
{
struct s3c24x0_uart *uart = s3c24x0_get_base_uart(dev_index);
#ifdef CONFIG_MODEM_SUPPORT
@@ -212,7 +212,7 @@ static inline void serial_putc_dev(unsigned int dev_index, const char c)
/*
* Test whether a character is in the RX buffer
*/
-int _serial_tstc(const int dev_index)
+static int _serial_tstc(const int dev_index)
{
struct s3c24x0_uart *uart = s3c24x0_get_base_uart(dev_index);
@@ -224,7 +224,7 @@ static inline int serial_tstc_dev(unsigned int dev_index)
return _serial_tstc(dev_index);
}
-void _serial_puts(const char *s, const int dev_index)
+static void _serial_puts(const char *s, const int dev_index)
{
while (*s) {
_serial_putc(*s++, dev_index);
diff --git a/drivers/serial/serial_uniphier.c b/drivers/serial/serial_uniphier.c
index f8c9d92..9114b3e 100644
--- a/drivers/serial/serial_uniphier.c
+++ b/drivers/serial/serial_uniphier.c
@@ -2,14 +2,14 @@
* Copyright (C) 2012-2014 Panasonic Corporation
* Author: Masahiro Yamada <yamada.m@jp.panasonic.com>
*
- * Based on serial_ns16550.c
- * (C) Copyright 2000
- * Rob Taylor, Flying Pig Systems. robt@flyingpig.com.
- *
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
+#include <asm/io.h>
+#include <asm/errno.h>
+#include <dm/device.h>
+#include <dm/platform_data/serial-uniphier.h>
#include <serial.h>
#define UART_REG(x) \
@@ -48,157 +48,104 @@ struct uniphier_serial {
#define UART_LSR_DR 0x01 /* Data ready */
#define UART_LSR_THRE 0x20 /* Xmit holding register empty */
-DECLARE_GLOBAL_DATA_PTR;
+struct uniphier_serial_private_data {
+ struct uniphier_serial __iomem *membase;
+};
+
+#define uniphier_serial_port(dev) \
+ ((struct uniphier_serial_private_data *)dev_get_priv(dev))->membase
-static void uniphier_serial_init(struct uniphier_serial *port)
+int uniphier_serial_setbrg(struct udevice *dev, int baudrate)
{
+ struct uniphier_serial_platform_data *plat = dev_get_platdata(dev);
+ struct uniphier_serial __iomem *port = uniphier_serial_port(dev);
const unsigned int mode_x_div = 16;
unsigned int divisor;
writeb(UART_LCR_WLS_8, &port->lcr);
- divisor = DIV_ROUND_CLOSEST(CONFIG_SYS_UNIPHIER_UART_CLK,
- mode_x_div * gd->baudrate);
+ divisor = DIV_ROUND_CLOSEST(plat->uartclk, mode_x_div * baudrate);
writew(divisor, &port->dlr);
-}
-static void uniphier_serial_setbrg(struct uniphier_serial *port)
-{
- uniphier_serial_init(port);
+ return 0;
}
-static int uniphier_serial_tstc(struct uniphier_serial *port)
+static int uniphier_serial_getc(struct udevice *dev)
{
- return (readb(&port->lsr) & UART_LSR_DR) != 0;
-}
+ struct uniphier_serial __iomem *port = uniphier_serial_port(dev);
-static int uniphier_serial_getc(struct uniphier_serial *port)
-{
- while (!uniphier_serial_tstc(port))
- ;
+ if (!(readb(&port->lsr) & UART_LSR_DR))
+ return -EAGAIN;
return readb(&port->rbr);
}
-static void uniphier_serial_putc(struct uniphier_serial *port, const char c)
+static int uniphier_serial_putc(struct udevice *dev, const char c)
{
- if (c == '\n')
- uniphier_serial_putc(port, '\r');
+ struct uniphier_serial __iomem *port = uniphier_serial_port(dev);
- while (!(readb(&port->lsr) & UART_LSR_THRE))
- ;
+ if (!(readb(&port->lsr) & UART_LSR_THRE))
+ return -EAGAIN;
writeb(c, &port->thr);
+
+ return 0;
}
-static struct uniphier_serial *serial_ports[4] = {
-#ifdef CONFIG_SYS_UNIPHIER_SERIAL_BASE0
- (struct uniphier_serial *)CONFIG_SYS_UNIPHIER_SERIAL_BASE0,
-#else
- NULL,
-#endif
-#ifdef CONFIG_SYS_UNIPHIER_SERIAL_BASE1
- (struct uniphier_serial *)CONFIG_SYS_UNIPHIER_SERIAL_BASE1,
-#else
- NULL,
-#endif
-#ifdef CONFIG_SYS_UNIPHIER_SERIAL_BASE2
- (struct uniphier_serial *)CONFIG_SYS_UNIPHIER_SERIAL_BASE2,
-#else
- NULL,
-#endif
-#ifdef CONFIG_SYS_UNIPHIER_SERIAL_BASE3
- (struct uniphier_serial *)CONFIG_SYS_UNIPHIER_SERIAL_BASE3,
-#else
- NULL,
-#endif
-};
+int uniphier_serial_probe(struct udevice *dev)
+{
+ struct uniphier_serial_private_data *priv = dev_get_priv(dev);
+ struct uniphier_serial_platform_data *plat = dev_get_platdata(dev);
-/* Multi serial device functions */
-#define DECLARE_ESERIAL_FUNCTIONS(port) \
- static int eserial##port##_init(void) \
- { \
- uniphier_serial_init(serial_ports[port]); \
- return 0 ; \
- } \
- static void eserial##port##_setbrg(void) \
- { \
- uniphier_serial_setbrg(serial_ports[port]); \
- } \
- static int eserial##port##_getc(void) \
- { \
- return uniphier_serial_getc(serial_ports[port]); \
- } \
- static int eserial##port##_tstc(void) \
- { \
- return uniphier_serial_tstc(serial_ports[port]); \
- } \
- static void eserial##port##_putc(const char c) \
- { \
- uniphier_serial_putc(serial_ports[port], c); \
- }
-
-/* Serial device descriptor */
-#define INIT_ESERIAL_STRUCTURE(port, __name) { \
- .name = __name, \
- .start = eserial##port##_init, \
- .stop = NULL, \
- .setbrg = eserial##port##_setbrg, \
- .getc = eserial##port##_getc, \
- .tstc = eserial##port##_tstc, \
- .putc = eserial##port##_putc, \
- .puts = default_serial_puts, \
-}
+ priv->membase = map_sysmem(plat->base, sizeof(struct uniphier_serial));
-#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE0)
-DECLARE_ESERIAL_FUNCTIONS(0);
-struct serial_device uniphier_serial0_device =
- INIT_ESERIAL_STRUCTURE(0, "ttyS0");
-#endif
-#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE1)
-DECLARE_ESERIAL_FUNCTIONS(1);
-struct serial_device uniphier_serial1_device =
- INIT_ESERIAL_STRUCTURE(1, "ttyS1");
-#endif
-#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE2)
-DECLARE_ESERIAL_FUNCTIONS(2);
-struct serial_device uniphier_serial2_device =
- INIT_ESERIAL_STRUCTURE(2, "ttyS2");
-#endif
-#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE3)
-DECLARE_ESERIAL_FUNCTIONS(3);
-struct serial_device uniphier_serial3_device =
- INIT_ESERIAL_STRUCTURE(3, "ttyS3");
-#endif
+ if (!priv->membase)
+ return -ENOMEM;
-__weak struct serial_device *default_serial_console(void)
+ return 0;
+}
+
+int uniphier_serial_remove(struct udevice *dev)
{
-#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE0)
- return &uniphier_serial0_device;
-#elif defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE1)
- return &uniphier_serial1_device;
-#elif defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE2)
- return &uniphier_serial2_device;
-#elif defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE3)
- return &uniphier_serial3_device;
-#else
-#error "No uniphier serial ports configured."
-#endif
+ unmap_sysmem(uniphier_serial_port(dev));
+
+ return 0;
}
-void uniphier_serial_initialize(void)
+#ifdef CONFIG_OF_CONTROL
+static const struct udevice_id uniphier_uart_of_match = {
+ { .compatible = "panasonic,uniphier-uart"},
+ {},
+};
+
+static int uniphier_serial_ofdata_to_platdata(struct udevice *dev)
{
-#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE0)
- serial_register(&uniphier_serial0_device);
-#endif
-#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE1)
- serial_register(&uniphier_serial1_device);
-#endif
-#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE2)
- serial_register(&uniphier_serial2_device);
-#endif
-#if defined(CONFIG_SYS_UNIPHIER_SERIAL_BASE3)
- serial_register(&uniphier_serial3_device);
-#endif
+ /*
+ * TODO: Masahiro Yamada (yamada.m@jp.panasonic.com)
+ *
+ * Implement conversion code from DTB to platform data
+ * when supporting CONFIG_OF_CONTROL on UniPhir platform.
+ */
}
+#endif
+
+static const struct dm_serial_ops uniphier_serial_ops = {
+ .setbrg = uniphier_serial_setbrg,
+ .getc = uniphier_serial_getc,
+ .putc = uniphier_serial_putc,
+};
+
+U_BOOT_DRIVER(uniphier_serial) = {
+ .name = DRIVER_NAME,
+ .id = UCLASS_SERIAL,
+ .of_match = of_match_ptr(uniphier_uart_of_match),
+ .ofdata_to_platdata = of_match_ptr(uniphier_serial_ofdata_to_platdata),
+ .probe = uniphier_serial_probe,
+ .remove = uniphier_serial_remove,
+ .priv_auto_alloc_size = sizeof(struct uniphier_serial_private_data),
+ .platdata_auto_alloc_size =
+ sizeof(struct uniphier_serial_platform_data),
+ .ops = &uniphier_serial_ops,
+ .flags = DM_FLAG_PRE_RELOC,
+};