diff options
author | Ying-Chun Liu (PaulLiu) <paulliu@debian.org> | 2018-05-31 17:34:04 +0800 |
---|---|---|
committer | Jérôme Forissier <jerome.forissier@linaro.org> | 2018-06-15 13:04:05 +0200 |
commit | d276907c8c4f85c3227a28b81f34b74c324806c7 (patch) | |
tree | e04f842062d390563ec430ed190016f6159d18cf /core/drivers/serial8250_uart.c | |
parent | 940a24375ba5357d34fea7196dba48eadaee9abd (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.c | 67 |
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 */ |