Message ID | 20230705181833.16137-1-ddrokosov@sberdevices.ru |
---|---|
Headers | show |
Series | tty: serial: meson: support ttyS devname | expand |
On Wed, Jul 05, 2023 at 09:18:32PM +0300, Dmitry Rokosov wrote: > Introduce meson uart serial bindings for A1 SoC family. > > Signed-off-by: Dmitry Rokosov <ddrokosov@sberdevices.ru> Looks like there's a missing Ack here from Rob: https://lore.kernel.org/all/168858360022.1592604.9922710628917242811.robh@kernel.org/ Cheers, Conor. > --- > .../devicetree/bindings/serial/amlogic,meson-uart.yaml | 2 ++ > 1 file changed, 2 insertions(+) > > diff --git a/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml b/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml > index 01ec45b3b406..f1ae8c4934d9 100644 > --- a/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml > +++ b/Documentation/devicetree/bindings/serial/amlogic,meson-uart.yaml > @@ -33,6 +33,7 @@ properties: > - amlogic,meson8b-uart > - amlogic,meson-gx-uart > - amlogic,meson-s4-uart > + - amlogic,meson-a1-uart > - const: amlogic,meson-ao-uart > - description: Always-on power domain UART controller on G12A SoCs > items: > @@ -46,6 +47,7 @@ properties: > - amlogic,meson8b-uart > - amlogic,meson-gx-uart > - amlogic,meson-s4-uart > + - amlogic,meson-a1-uart > - description: Everything-Else power domain UART controller on G12A SoCs > items: > - const: amlogic,meson-g12a-uart > -- > 2.36.0 >
On 05/07/2023 20:18, Dmitry Rokosov wrote: > Actually, the meson_uart module is already a platform_driver, but it is > currently registered manually and the uart core registration is run > outside the probe() scope, which results in some restrictions. For > instance, it is not possible to communicate with the OF subsystem > because it requires an initialized device object. > > To address this issue, apply module_platform_driver() instead of direct > module init/exit routines. Additionally, move uart_register_driver() to > the driver probe(), and destroy manual console registration because it's > already run in the uart_register_driver() flow. > > Signed-off-by: Dmitry Rokosov <ddrokosov@sberdevices.ru> > --- > drivers/tty/serial/meson_uart.c | 51 ++++++++++----------------------- > 1 file changed, 15 insertions(+), 36 deletions(-) > > diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c > index bca54f3d92a1..dcf994a11a21 100644 > --- a/drivers/tty/serial/meson_uart.c > +++ b/drivers/tty/serial/meson_uart.c > @@ -621,12 +621,6 @@ static struct console meson_serial_console = { > .data = &meson_uart_driver, > }; > > -static int __init meson_serial_console_init(void) > -{ > - register_console(&meson_serial_console); > - return 0; > -} > - > static void meson_serial_early_console_write(struct console *co, > const char *s, > u_int count) > @@ -652,9 +646,6 @@ OF_EARLYCON_DECLARE(meson, "amlogic,meson-ao-uart", > > #define MESON_SERIAL_CONSOLE (&meson_serial_console) > #else > -static int __init meson_serial_console_init(void) { > - return 0; > -} > #define MESON_SERIAL_CONSOLE NULL > #endif > > @@ -738,6 +729,13 @@ static int meson_uart_probe(struct platform_device *pdev) > if (ret) > return ret; > > + if (!meson_uart_driver.state) { > + ret = uart_register_driver(&meson_uart_driver); > + if (ret) > + return dev_err_probe(&pdev->dev, ret, > + "can't register uart driver\n"); > + } > + > port->iotype = UPIO_MEM; > port->mapbase = res_mem->start; > port->mapsize = resource_size(res_mem); > @@ -776,6 +774,13 @@ static int meson_uart_remove(struct platform_device *pdev) > uart_remove_one_port(&meson_uart_driver, port); > meson_ports[pdev->id] = NULL; > > + for (int id = 0; id < AML_UART_PORT_NUM; id++) > + if (meson_ports[id]) > + return 0; > + > + /* No more available uart ports, unregister uart driver */ > + uart_unregister_driver(&meson_uart_driver); > + > return 0; > } > > @@ -809,33 +814,7 @@ static struct platform_driver meson_uart_platform_driver = { > }, > }; > > -static int __init meson_uart_init(void) > -{ > - int ret; > - > - ret = meson_serial_console_init(); > - if (ret) > - return ret; > - > - ret = uart_register_driver(&meson_uart_driver); > - if (ret) > - return ret; > - > - ret = platform_driver_register(&meson_uart_platform_driver); > - if (ret) > - uart_unregister_driver(&meson_uart_driver); > - > - return ret; > -} > - > -static void __exit meson_uart_exit(void) > -{ > - platform_driver_unregister(&meson_uart_platform_driver); > - uart_unregister_driver(&meson_uart_driver); > -} > - > -module_init(meson_uart_init); > -module_exit(meson_uart_exit); > +module_platform_driver(meson_uart_platform_driver); > > MODULE_AUTHOR("Carlo Caione <carlo@caione.org>"); > MODULE_DESCRIPTION("Amlogic Meson serial port driver"); Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
Hi, On 05/07/2023 20:18, Dmitry Rokosov wrote: > It is worth noting that the devname ttyS is a widely recognized tty name > and is commonly used by many uart device drivers. Given the established > usage and compatibility concerns, it may not be feasible to change the > devname for older SoCs. However, for new definitions, it is acceptable > and even recommended to use a new devname to help ensure clarity and > avoid any potential conflicts on lower or upper software levels. > > For more information please refer to IRC discussion at [1]. > > Links: > [1]: https://libera.irclog.whitequark.org/linux-amlogic/2023-07-03 > > Signed-off-by: Dmitry Rokosov <ddrokosov@sberdevices.ru> > --- > drivers/tty/serial/meson_uart.c | 82 ++++++++++++++++++++++----------- > 1 file changed, 56 insertions(+), 26 deletions(-) > > diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c > index dcf994a11a21..ad0748a10db7 100644 > --- a/drivers/tty/serial/meson_uart.c > +++ b/drivers/tty/serial/meson_uart.c > @@ -72,16 +72,22 @@ > > #define AML_UART_PORT_NUM 12 > #define AML_UART_PORT_OFFSET 6 > -#define AML_UART_DEV_NAME "ttyAML" > > #define AML_UART_POLL_USEC 5 > #define AML_UART_TIMEOUT_USEC 10000 > > -static struct uart_driver meson_uart_driver; > +#define MESON_UART_DRIVER(_devname) meson_uart_driver_##_devname > + > +#define MESON_UART_DRIVER_DECLARE(_devname) \ > + static struct uart_driver MESON_UART_DRIVER(_devname) > + > +MESON_UART_DRIVER_DECLARE(ttyAML); > +MESON_UART_DRIVER_DECLARE(ttyS); Not sure those macros are useful: MESON_UART_DRIVER_DECLARE(ttyAML) vs static struct uart_driver meson_uart_driver_ttyAML I prefer the second... > > static struct uart_port *meson_ports[AML_UART_PORT_NUM]; > > struct meson_uart_data { > + struct uart_driver *uart_driver; > bool has_xtal_div2; > }; > > @@ -611,15 +617,21 @@ static int meson_serial_console_setup(struct console *co, char *options) > return uart_set_options(port, co, baud, parity, bits, flow); > } I think the uart_driver meson_uart_driver_ttyXXX should be declared here instead or.. > > -static struct console meson_serial_console = { > - .name = AML_UART_DEV_NAME, > - .write = meson_serial_console_write, > - .device = uart_console_device, > - .setup = meson_serial_console_setup, > - .flags = CON_PRINTBUFFER, > - .index = -1, > - .data = &meson_uart_driver, > -}; > +#define MESON_SERIAL_CONSOLE(_devname) meson_serial_console_##_devname > + > +#define MESON_SERIAL_CONSOLE_DEFINE(_devname) \ > + static struct console MESON_SERIAL_CONSOLE(_devname) = { \ > + .name = __stringify(_devname), \ > + .write = meson_serial_console_write, \ > + .device = uart_console_device, \ > + .setup = meson_serial_console_setup, \ > + .flags = CON_PRINTBUFFER, \ > + .index = -1, \ > + .data = &MESON_UART_DRIVER(_devname), \ > + } ... you could even declare the meson_uart_driver_ttyXXX in this macro instead. > + > +MESON_SERIAL_CONSOLE_DEFINE(ttyAML); > +MESON_SERIAL_CONSOLE_DEFINE(ttyS); > > static void meson_serial_early_console_write(struct console *co, > const char *s, > @@ -644,18 +656,22 @@ meson_serial_early_console_setup(struct earlycon_device *device, const char *opt > OF_EARLYCON_DECLARE(meson, "amlogic,meson-ao-uart", > meson_serial_early_console_setup); > > -#define MESON_SERIAL_CONSOLE (&meson_serial_console) > +#define MESON_SERIAL_CONSOLE_PTR(_devname) (&MESON_SERIAL_CONSOLE(_devname)) > #else > -#define MESON_SERIAL_CONSOLE NULL > +#define MESON_SERIAL_CONSOLE_PTR(_devname) (NULL) > #endif > > -static struct uart_driver meson_uart_driver = { > - .owner = THIS_MODULE, > - .driver_name = "meson_uart", > - .dev_name = AML_UART_DEV_NAME, > - .nr = AML_UART_PORT_NUM, > - .cons = MESON_SERIAL_CONSOLE, > -}; > +#define MESON_UART_DRIVER_DEFINE(_devname) \ > + static struct uart_driver MESON_UART_DRIVER(_devname) = { \ > + .owner = THIS_MODULE, \ > + .driver_name = "meson_uart", \ > + .dev_name = __stringify(_devname), \ > + .nr = AML_UART_PORT_NUM, \ > + .cons = MESON_SERIAL_CONSOLE_PTR(_devname), \ > + } > + > +MESON_UART_DRIVER_DEFINE(ttyAML); > +MESON_UART_DRIVER_DEFINE(ttyS); Those macros are fine, but drop the MESON_UART_DRIVER & MESON_SERIAL_CONSOLE macros and drop the _DEFINE in those macros. > > static int meson_uart_probe_clocks(struct platform_device *pdev, > struct uart_port *port) > @@ -681,8 +697,16 @@ static int meson_uart_probe_clocks(struct platform_device *pdev, > return 0; > } > > +static struct uart_driver *meson_uart_current(const struct meson_uart_data *pd) > +{ > + return (pd && pd->uart_driver) ? > + pd->uart_driver : &MESON_UART_DRIVER(ttyAML); I'll definitely prefer if you use the real variable name everywhere and in the 2 following patches > +} > + > static int meson_uart_probe(struct platform_device *pdev) > { > + const struct meson_uart_data *priv_data; > + struct uart_driver *uart_driver; > struct resource *res_mem; > struct uart_port *port; > u32 fifosize = 64; /* Default is 64, 128 for EE UART_0 */ > @@ -729,8 +753,12 @@ static int meson_uart_probe(struct platform_device *pdev) > if (ret) > return ret; > > - if (!meson_uart_driver.state) { > - ret = uart_register_driver(&meson_uart_driver); > + priv_data = device_get_match_data(&pdev->dev); > + > + uart_driver = meson_uart_current(priv_data); > + > + if (!uart_driver->state) { > + ret = uart_register_driver(uart_driver); > if (ret) > return dev_err_probe(&pdev->dev, ret, > "can't register uart driver\n"); > @@ -748,7 +776,7 @@ static int meson_uart_probe(struct platform_device *pdev) > port->x_char = 0; > port->ops = &meson_uart_ops; > port->fifosize = fifosize; > - port->private_data = (void *)device_get_match_data(&pdev->dev); > + port->private_data = (void *)priv_data; > > meson_ports[pdev->id] = port; > platform_set_drvdata(pdev, port); > @@ -759,7 +787,7 @@ static int meson_uart_probe(struct platform_device *pdev) > meson_uart_release_port(port); > } > > - ret = uart_add_one_port(&meson_uart_driver, port); > + ret = uart_add_one_port(uart_driver, port); > if (ret) > meson_ports[pdev->id] = NULL; > > @@ -768,10 +796,12 @@ static int meson_uart_probe(struct platform_device *pdev) > > static int meson_uart_remove(struct platform_device *pdev) > { > + struct uart_driver *uart_driver; > struct uart_port *port; > > port = platform_get_drvdata(pdev); > - uart_remove_one_port(&meson_uart_driver, port); > + uart_driver = meson_uart_current(port->private_data); > + uart_remove_one_port(uart_driver, port); > meson_ports[pdev->id] = NULL; > > for (int id = 0; id < AML_UART_PORT_NUM; id++) > @@ -779,7 +809,7 @@ static int meson_uart_remove(struct platform_device *pdev) > return 0; > > /* No more available uart ports, unregister uart driver */ > - uart_unregister_driver(&meson_uart_driver); > + uart_unregister_driver(uart_driver); > > return 0; > } Anyway this looks much better :-) Thanks, Neil
On 05/07/2023 20:18, Dmitry Rokosov wrote: > In order to use the correct devname value for the S4 SoC family, it > is imperative that we implement separate uart_data. Unlike the legacy > g12a architecture, the S4 architecture should employ the use of 'ttyS' > devname. > > Signed-off-by: Dmitry Rokosov <ddrokosov@sberdevices.ru> > --- > drivers/tty/serial/meson_uart.c | 7 ++++++- > 1 file changed, 6 insertions(+), 1 deletion(-) > > diff --git a/drivers/tty/serial/meson_uart.c b/drivers/tty/serial/meson_uart.c > index ad0748a10db7..6a63184b8091 100644 > --- a/drivers/tty/serial/meson_uart.c > +++ b/drivers/tty/serial/meson_uart.c > @@ -818,6 +818,11 @@ static struct meson_uart_data meson_g12a_uart_data = { > .has_xtal_div2 = true, > }; > > +static struct meson_uart_data meson_s4_uart_data = { > + .uart_driver = &MESON_UART_DRIVER(ttyS), > + .has_xtal_div2 = true, > +}; > + > static const struct of_device_id meson_uart_dt_match[] = { > { .compatible = "amlogic,meson6-uart" }, > { .compatible = "amlogic,meson8-uart" }, > @@ -829,7 +834,7 @@ static const struct of_device_id meson_uart_dt_match[] = { > }, > { > .compatible = "amlogic,meson-s4-uart", > - .data = (void *)&meson_g12a_uart_data, > + .data = (void *)&meson_s4_uart_data, > }, > { /* sentinel */ }, > }; With the real struct name: Reviewed-by: Neil Armstrong <neil.armstrong@linaro.org>
On Wed, 05 Jul 2023 21:18:32 +0300, Dmitry Rokosov wrote: > Introduce meson uart serial bindings for A1 SoC family. > > Signed-off-by: Dmitry Rokosov <ddrokosov@sberdevices.ru> > --- > .../devicetree/bindings/serial/amlogic,meson-uart.yaml | 2 ++ > 1 file changed, 2 insertions(+) > Please add Acked-by/Reviewed-by tags when posting new versions. However, there's no need to repost patches *only* to add the tags. The upstream maintainer will do that for acks received on the version they apply. If a tag was not added on purpose, please state why and what changed. Missing tags: Acked-by: Rob Herring <robh@kernel.org>