aboutsummaryrefslogtreecommitdiff
path: root/core/drivers/serial8250_uart.c
diff options
context:
space:
mode:
authorYing-Chun Liu (PaulLiu) <paulliu@debian.org>2018-05-31 17:34:04 +0800
committerJérôme Forissier <jerome.forissier@linaro.org>2018-06-15 13:04:05 +0200
commitd276907c8c4f85c3227a28b81f34b74c324806c7 (patch)
treee04f842062d390563ec430ed190016f6159d18cf /core/drivers/serial8250_uart.c
parent940a24375ba5357d34fea7196dba48eadaee9abd (diff)
core: drivers: serial8250_uart: Add DT support
Add DT support for serial8250 uart driver. The matchtable currently supports allwinner H2+ SoC. Reviewed-by: Jens Wiklander <jens.wiklander@linaro.org> Reviewed-by: Jerome Forissier <jerome.forissier@linaro.org> Signed-off-by: Ying-Chun Liu (PaulLiu) <paulliu@debian.org>
Diffstat (limited to 'core/drivers/serial8250_uart.c')
-rw-r--r--core/drivers/serial8250_uart.c67
1 files changed, 67 insertions, 0 deletions
diff --git a/core/drivers/serial8250_uart.c b/core/drivers/serial8250_uart.c
index a29e8898..b4e9fcf8 100644
--- a/core/drivers/serial8250_uart.c
+++ b/core/drivers/serial8250_uart.c
@@ -9,6 +9,7 @@
#include <io.h>
#include <keep.h>
#include <util.h>
+#include <kernel/dt.h>
/* uart register defines */
#define UART_RHR 0x0
@@ -98,3 +99,69 @@ void serial8250_uart_init(struct serial8250_uart_data *pd, paddr_t base,
* everything for uart0 is ready now.
*/
}
+
+#ifdef CFG_DT
+
+static struct serial_chip *serial8250_uart_dev_alloc(void)
+{
+ struct serial8250_uart_data *pd = malloc(sizeof(*pd));
+
+ if (!pd)
+ return NULL;
+ return &pd->chip;
+}
+
+static int serial8250_uart_dev_init(struct serial_chip *chip,
+ const void *fdt,
+ int offs,
+ const char *parms)
+{
+ struct serial8250_uart_data *pd =
+ container_of(chip, struct serial8250_uart_data, chip);
+ vaddr_t vbase;
+ paddr_t pbase;
+ size_t size;
+
+ if (parms && parms[0])
+ IMSG("serial8250_uart: device parameters ignored (%s)", parms);
+
+ if (dt_map_dev(fdt, offs, &vbase, &size) < 0)
+ return -1;
+
+ if (size < SERIAL8250_UART_REG_SIZE) {
+ EMSG("serial8250_uart: register size too small: %zx", size);
+ return -1;
+ }
+
+ pbase = virt_to_phys((void *)vbase);
+ serial8250_uart_init(pd, pbase, 0, 0);
+
+ return 0;
+}
+
+static void serial8250_uart_dev_free(struct serial_chip *chip)
+{
+ struct serial8250_uart_data *pd =
+ container_of(chip, struct serial8250_uart_data, chip);
+
+ free(pd);
+}
+
+static const struct serial_driver serial8250_driver = {
+ .dev_alloc = serial8250_uart_dev_alloc,
+ .dev_init = serial8250_uart_dev_init,
+ .dev_free = serial8250_uart_dev_free,
+};
+
+static const struct dt_device_match serial8250_match_table[] = {
+ { .compatible = "snps,dw-apb-uart" },
+ { 0 }
+};
+
+const struct dt_driver serial8250_dt_driver __dt_driver = {
+ .name = "serial8250_uart",
+ .match_table = serial8250_match_table,
+ .driver = &serial8250_driver,
+};
+
+#endif /* CFG_DT */