--- zzzz-none-000/linux-3.10.107/drivers/tty/serial/ar933x_uart.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/tty/serial/ar933x_uart.c 2021-02-04 17:41:59.000000000 +0000 @@ -17,6 +17,8 @@ #include #include #include +#include +#include #include #include #include @@ -24,11 +26,11 @@ #include #include #include +#include #include #include -#include #define DRIVER_NAME "ar933x-uart" @@ -47,8 +49,14 @@ unsigned int ier; /* shadow Interrupt Enable Register */ unsigned int min_baud; unsigned int max_baud; + struct clk *clk; }; +static inline bool ar933x_uart_console_enabled(void) +{ + return config_enabled(CONFIG_SERIAL_AR933X_CONSOLE); +} + static inline unsigned int ar933x_uart_read(struct ar933x_uart_port *up, int offset) { @@ -111,7 +119,8 @@ static unsigned int ar933x_uart_tx_empty(struct uart_port *port) { - struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; + struct ar933x_uart_port *up = + container_of(port, struct ar933x_uart_port, port); unsigned long flags; unsigned int rdata; @@ -133,21 +142,24 @@ static void ar933x_uart_start_tx(struct uart_port *port) { - struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; + struct ar933x_uart_port *up = + container_of(port, struct ar933x_uart_port, port); ar933x_uart_start_tx_interrupt(up); } static void ar933x_uart_stop_tx(struct uart_port *port) { - struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; + struct ar933x_uart_port *up = + container_of(port, struct ar933x_uart_port, port); ar933x_uart_stop_tx_interrupt(up); } static void ar933x_uart_stop_rx(struct uart_port *port) { - struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; + struct ar933x_uart_port *up = + container_of(port, struct ar933x_uart_port, port); up->ier &= ~AR933X_UART_INT_RX_VALID; ar933x_uart_write(up, AR933X_UART_INT_EN_REG, up->ier); @@ -155,7 +167,8 @@ static void ar933x_uart_break_ctl(struct uart_port *port, int break_state) { - struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; + struct ar933x_uart_port *up = + container_of(port, struct ar933x_uart_port, port); unsigned long flags; spin_lock_irqsave(&up->port.lock, flags); @@ -168,10 +181,6 @@ spin_unlock_irqrestore(&up->port.lock, flags); } -static void ar933x_uart_enable_ms(struct uart_port *port) -{ -} - /* * baudrate = (clk / (scale + 1)) * (step * (1 / 2^17)) */ @@ -227,7 +236,8 @@ struct ktermios *new, struct ktermios *old) { - struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; + struct ar933x_uart_port *up = + container_of(port, struct ar933x_uart_port, port); unsigned int cs; unsigned long flags; unsigned int baud, scale, step; @@ -322,7 +332,9 @@ tty_insert_flip_char(port, ch, TTY_NORMAL); } while (max_count-- > 0); + spin_unlock(&up->port.lock); tty_flip_buffer_push(port); + spin_lock(&up->port.lock); } static void ar933x_uart_tx_chars(struct ar933x_uart_port *up) @@ -398,7 +410,8 @@ static int ar933x_uart_startup(struct uart_port *port) { - struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; + struct ar933x_uart_port *up = + container_of(port, struct ar933x_uart_port, port); unsigned long flags; int ret; @@ -424,7 +437,8 @@ static void ar933x_uart_shutdown(struct uart_port *port) { - struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; + struct ar933x_uart_port *up = + container_of(port, struct ar933x_uart_port, port); /* Disable all interrupts */ up->ier = 0; @@ -462,7 +476,8 @@ static int ar933x_uart_verify_port(struct uart_port *port, struct serial_struct *ser) { - struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; + struct ar933x_uart_port *up = + container_of(port, struct ar933x_uart_port, port); if (ser->type != PORT_UNKNOWN && ser->type != PORT_AR933X) @@ -485,7 +500,6 @@ .stop_tx = ar933x_uart_stop_tx, .start_tx = ar933x_uart_start_tx, .stop_rx = ar933x_uart_stop_rx, - .enable_ms = ar933x_uart_enable_ms, .break_ctl = ar933x_uart_break_ctl, .startup = ar933x_uart_startup, .shutdown = ar933x_uart_shutdown, @@ -497,8 +511,6 @@ .verify_port = ar933x_uart_verify_port, }; -#ifdef CONFIG_SERIAL_AR933X_CONSOLE - static struct ar933x_uart_port * ar933x_console_ports[CONFIG_SERIAL_AR933X_NR_UARTS]; @@ -518,7 +530,8 @@ static void ar933x_uart_console_putchar(struct uart_port *port, int ch) { - struct ar933x_uart_port *up = (struct ar933x_uart_port *) port; + struct ar933x_uart_port *up = + container_of(port, struct ar933x_uart_port, port); ar933x_uart_wait_xmitr(up); ar933x_uart_putc(up, ch); @@ -597,54 +610,47 @@ static void ar933x_uart_add_console_port(struct ar933x_uart_port *up) { + if (!ar933x_uart_console_enabled()) + return; + ar933x_console_ports[up->port.line] = up; } -#define AR933X_SERIAL_CONSOLE (&ar933x_uart_console) - -#else - -static inline void ar933x_uart_add_console_port(struct ar933x_uart_port *up) {} - -#define AR933X_SERIAL_CONSOLE NULL - -#endif /* CONFIG_SERIAL_AR933X_CONSOLE */ - static struct uart_driver ar933x_uart_driver = { .owner = THIS_MODULE, .driver_name = DRIVER_NAME, .dev_name = "ttyATH", .nr = CONFIG_SERIAL_AR933X_NR_UARTS, - .cons = AR933X_SERIAL_CONSOLE, + .cons = NULL, /* filled in runtime */ }; static int ar933x_uart_probe(struct platform_device *pdev) { - struct ar933x_uart_platform_data *pdata; struct ar933x_uart_port *up; struct uart_port *port; struct resource *mem_res; struct resource *irq_res; + struct device_node *np; unsigned int baud; int id; int ret; - pdata = pdev->dev.platform_data; - if (!pdata) - return -EINVAL; - - id = pdev->id; - if (id == -1) - id = 0; - - if (id > CONFIG_SERIAL_AR933X_NR_UARTS) - return -EINVAL; + np = pdev->dev.of_node; + if (config_enabled(CONFIG_OF) && np) { + id = of_alias_get_id(np, "serial"); + if (id < 0) { + dev_err(&pdev->dev, "unable to get alias id, err=%d\n", + id); + return id; + } + } else { + id = pdev->id; + if (id == -1) + id = 0; + } - mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem_res) { - dev_err(&pdev->dev, "no MEM resource\n"); + if (id >= CONFIG_SERIAL_AR933X_NR_UARTS) return -EINVAL; - } irq_res = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (!irq_res) { @@ -652,25 +658,40 @@ return -EINVAL; } - up = kzalloc(sizeof(struct ar933x_uart_port), GFP_KERNEL); + up = devm_kzalloc(&pdev->dev, sizeof(struct ar933x_uart_port), + GFP_KERNEL); if (!up) return -ENOMEM; + up->clk = devm_clk_get(&pdev->dev, "uart"); + if (IS_ERR(up->clk)) { + dev_err(&pdev->dev, "unable to get UART clock\n"); + return PTR_ERR(up->clk); + } + port = &up->port; - port->mapbase = mem_res->start; - port->membase = ioremap(mem_res->start, AR933X_UART_REGS_SIZE); - if (!port->membase) { - ret = -ENOMEM; - goto err_free_up; + mem_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + port->membase = devm_ioremap_resource(&pdev->dev, mem_res); + if (IS_ERR(port->membase)) + return PTR_ERR(port->membase); + + ret = clk_prepare_enable(up->clk); + if (ret) + return ret; + + port->uartclk = clk_get_rate(up->clk); + if (!port->uartclk) { + ret = -EINVAL; + goto err_disable_clk; } + port->mapbase = mem_res->start; port->line = id; port->irq = irq_res->start; port->dev = &pdev->dev; port->type = PORT_AR933X; port->iotype = UPIO_MEM32; - port->uartclk = pdata->uartclk; port->regshift = 2; port->fifosize = AR933X_UART_FIFO_SIZE; @@ -686,15 +707,13 @@ ret = uart_add_one_port(&ar933x_uart_driver, &up->port); if (ret) - goto err_unmap; + goto err_disable_clk; platform_set_drvdata(pdev, up); return 0; -err_unmap: - iounmap(up->port.membase); -err_free_up: - kfree(up); +err_disable_clk: + clk_disable_unprepare(up->clk); return ret; } @@ -703,23 +722,29 @@ struct ar933x_uart_port *up; up = platform_get_drvdata(pdev); - platform_set_drvdata(pdev, NULL); if (up) { uart_remove_one_port(&ar933x_uart_driver, &up->port); - iounmap(up->port.membase); - kfree(up); + clk_disable_unprepare(up->clk); } return 0; } +#ifdef CONFIG_OF +static const struct of_device_id ar933x_uart_of_ids[] = { + { .compatible = "qca,ar9330-uart" }, + {}, +}; +MODULE_DEVICE_TABLE(of, ar933x_uart_of_ids); +#endif + static struct platform_driver ar933x_uart_platform_driver = { .probe = ar933x_uart_probe, .remove = ar933x_uart_remove, .driver = { .name = DRIVER_NAME, - .owner = THIS_MODULE, + .of_match_table = of_match_ptr(ar933x_uart_of_ids), }, }; @@ -727,7 +752,9 @@ { int ret; - ar933x_uart_driver.nr = CONFIG_SERIAL_AR933X_NR_UARTS; + if (ar933x_uart_console_enabled()) + ar933x_uart_driver.cons = &ar933x_uart_console; + ret = uart_register_driver(&ar933x_uart_driver); if (ret) goto err_out;