diff options
Diffstat (limited to 'drivers/tty/serial/xilinx_uartps.c')
-rw-r--r-- | drivers/tty/serial/xilinx_uartps.c | 108 |
1 files changed, 42 insertions, 66 deletions
diff --git a/drivers/tty/serial/xilinx_uartps.c b/drivers/tty/serial/xilinx_uartps.c index bd72dd843338..8a3e34234e98 100644 --- a/drivers/tty/serial/xilinx_uartps.c +++ b/drivers/tty/serial/xilinx_uartps.c @@ -1097,45 +1097,6 @@ static const struct uart_ops cdns_uart_ops = { #endif }; -static struct uart_port cdns_uart_port[CDNS_UART_NR_PORTS]; - -/** - * cdns_uart_get_port - Configure the port from platform device resource info - * @id: Port id - * - * Return: a pointer to a uart_port or NULL for failure - */ -static struct uart_port *cdns_uart_get_port(int id) -{ - struct uart_port *port; - - /* Try the given port id if failed use default method */ - if (id < CDNS_UART_NR_PORTS && cdns_uart_port[id].mapbase != 0) { - /* Find the next unused port */ - for (id = 0; id < CDNS_UART_NR_PORTS; id++) - if (cdns_uart_port[id].mapbase == 0) - break; - } - - if (id >= CDNS_UART_NR_PORTS) - return NULL; - - port = &cdns_uart_port[id]; - - /* At this point, we've got an empty uart_port struct, initialize it */ - spin_lock_init(&port->lock); - port->membase = NULL; - port->irq = 0; - port->type = PORT_UNKNOWN; - port->iotype = UPIO_MEM32; - port->flags = UPF_BOOT_AUTOCONF; - port->ops = &cdns_uart_ops; - port->fifosize = CDNS_UART_FIFO_SIZE; - port->line = id; - port->dev = NULL; - return port; -} - #ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE /** * cdns_uart_console_wait_tx - Wait for the TX to be full @@ -1206,6 +1167,10 @@ OF_EARLYCON_DECLARE(cdns, "cdns,uart-r1p8", cdns_early_console_setup); OF_EARLYCON_DECLARE(cdns, "cdns,uart-r1p12", cdns_early_console_setup); OF_EARLYCON_DECLARE(cdns, "xlnx,zynqmp-uart", cdns_early_console_setup); + +/* Static pointer to console port */ +static struct uart_port *console_port; + /** * cdns_uart_console_write - perform write operation * @co: Console handle @@ -1215,7 +1180,7 @@ OF_EARLYCON_DECLARE(cdns, "xlnx,zynqmp-uart", cdns_early_console_setup); static void cdns_uart_console_write(struct console *co, const char *s, unsigned int count) { - struct uart_port *port = &cdns_uart_port[co->index]; + struct uart_port *port = console_port; unsigned long flags; unsigned int imr, ctrl; int locked = 1; @@ -1261,15 +1226,13 @@ static void cdns_uart_console_write(struct console *co, const char *s, */ static int __init cdns_uart_console_setup(struct console *co, char *options) { - struct uart_port *port = &cdns_uart_port[co->index]; + struct uart_port *port = console_port; + int baud = 9600; int bits = 8; int parity = 'n'; int flow = 'n'; - if (co->index < 0 || co->index >= CDNS_UART_NR_PORTS) - return -EINVAL; - if (!port->membase) { pr_debug("console on " CDNS_UART_TTY_NAME "%i not present\n", co->index); @@ -1293,20 +1256,6 @@ static struct console cdns_uart_console = { .index = -1, /* Specified on the cmdline (e.g. console=ttyPS ) */ .data = &cdns_uart_uart_driver, }; - -/** - * cdns_uart_console_init - Initialization call - * - * Return: 0 on success, negative errno otherwise - */ -static int __init cdns_uart_console_init(void) -{ - register_console(&cdns_uart_console); - return 0; -} - -console_initcall(cdns_uart_console_init); - #endif /* CONFIG_SERIAL_XILINX_PS_UART_CONSOLE */ static struct uart_driver cdns_uart_uart_driver = { @@ -1430,8 +1379,7 @@ static int cdns_uart_resume(struct device *device) #endif /* ! CONFIG_PM_SLEEP */ static int __maybe_unused cdns_runtime_suspend(struct device *dev) { - struct platform_device *pdev = to_platform_device(dev); - struct uart_port *port = platform_get_drvdata(pdev); + struct uart_port *port = dev_get_drvdata(dev); struct cdns_uart *cdns_uart = port->private_data; clk_disable(cdns_uart->uartclk); @@ -1441,8 +1389,7 @@ static int __maybe_unused cdns_runtime_suspend(struct device *dev) static int __maybe_unused cdns_runtime_resume(struct device *dev) { - struct platform_device *pdev = to_platform_device(dev); - struct uart_port *port = platform_get_drvdata(pdev); + struct uart_port *port = dev_get_drvdata(dev); struct cdns_uart *cdns_uart = port->private_data; clk_enable(cdns_uart->pclk); @@ -1487,6 +1434,9 @@ static int cdns_uart_probe(struct platform_device *pdev) GFP_KERNEL); if (!cdns_uart_data) return -ENOMEM; + port = devm_kzalloc(&pdev->dev, sizeof(*port), GFP_KERNEL); + if (!port) + return -ENOMEM; match = of_match_node(cdns_uart_of_match, pdev->dev.of_node); if (match && match->data) { @@ -1552,15 +1502,24 @@ static int cdns_uart_probe(struct platform_device *pdev) if (id < 0) id = 0; - /* Initialize the port structure */ - port = cdns_uart_get_port(id); - - if (!port) { + if (id >= CDNS_UART_NR_PORTS) { dev_err(&pdev->dev, "Cannot get uart_port structure\n"); rc = -ENODEV; goto err_out_notif_unreg; } + /* At this point, we've got an empty uart_port struct, initialize it */ + spin_lock_init(&port->lock); + port->membase = NULL; + port->irq = 0; + port->type = PORT_UNKNOWN; + port->iotype = UPIO_MEM32; + port->flags = UPF_BOOT_AUTOCONF; + port->ops = &cdns_uart_ops; + port->fifosize = CDNS_UART_FIFO_SIZE; + port->line = id; + port->dev = NULL; + /* * Register the port. * This function also registers this device with the tty layer @@ -1579,6 +1538,17 @@ static int cdns_uart_probe(struct platform_device *pdev) pm_runtime_set_active(&pdev->dev); pm_runtime_enable(&pdev->dev); +#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE + /* + * If console hasn't been found yet try to assign this port + * because it is required to be assigned for console setup function. + * If register_console() don't assign value, then console_port pointer + * is cleanup. + */ + if (cdns_uart_uart_driver.cons->index == -1) + console_port = port; +#endif + rc = uart_add_one_port(&cdns_uart_uart_driver, port); if (rc) { dev_err(&pdev->dev, @@ -1586,6 +1556,12 @@ static int cdns_uart_probe(struct platform_device *pdev) goto err_out_pm_disable; } +#ifdef CONFIG_SERIAL_XILINX_PS_UART_CONSOLE + /* This is not port which is used for console that's why clean it up */ + if (cdns_uart_uart_driver.cons->index == -1) + console_port = NULL; +#endif + return 0; err_out_pm_disable: |