* [PATCH 0/4] serial: 8250: Add AN7581 UART support
@ 2026-07-09 20:56 Christian Marangi
2026-07-09 20:56 ` [PATCH 1/4] dt-bindings: serial: 8250: Add Airoha compatibles Christian Marangi
` (3 more replies)
0 siblings, 4 replies; 16+ messages in thread
From: Christian Marangi @ 2026-07-09 20:56 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Ilpo Järvinen, Christian Marangi,
Andy Shevchenko, Benjamin Larsson, John Ogness, Marco Felsch,
Gerhard Engleder, Jiaxun Yang, Randy Dunlap, Binbin Zhou,
Rong Zhang, Lukas Wunner, Lubomir Rintel, devicetree,
linux-kernel, linux-serial
This is a new version of [1] to support UART driver for
Airoha SoC.
One additional function was needed serial8250_get_baud_rate()
for the driver to work correctly for baud rate calculation.
While at it also try to clarify a long standing issue with
new UART driver when adding new ids for uart_config[].
[1] https://lore.kernel.org/all/20250209210241.2622309-1-benjamin.larsson@genexis.eu/
Changes compared to [1]:
- Fix all formal error
- Use better compatible names
- Drop unneeded header
- Drop usage of irq (it's filled by the generic function)
- General code cleanup and reorg
- Split to patch and add the UAPI map patch
Benjamin Larsson (1):
dt-bindings: serial: 8250: Add Airoha compatibles
Christian Marangi (3):
serial: 8250: export serial8250_get_baud_rate()
serial: 8250: map UAPI port type to internal enum
serial: 8250: Add Airoha SoC UART and HSUART support
.../devicetree/bindings/serial/8250.yaml | 5 +
drivers/tty/serial/8250/8250.h | 126 ++++++++++++
drivers/tty/serial/8250/8250_airoha.c | 190 ++++++++++++++++++
drivers/tty/serial/8250/8250_port.c | 95 +++++----
drivers/tty/serial/8250/Kconfig | 11 +
drivers/tty/serial/8250/Makefile | 1 +
include/linux/serial_8250.h | 4 +
7 files changed, 393 insertions(+), 39 deletions(-)
create mode 100644 drivers/tty/serial/8250/8250_airoha.c
--
2.53.0
^ permalink raw reply [flat|nested] 16+ messages in thread* [PATCH 1/4] dt-bindings: serial: 8250: Add Airoha compatibles 2026-07-09 20:56 [PATCH 0/4] serial: 8250: Add AN7581 UART support Christian Marangi @ 2026-07-09 20:56 ` Christian Marangi 2026-07-10 16:43 ` Conor Dooley 2026-07-09 20:56 ` [PATCH 2/4] serial: 8250: export serial8250_get_baud_rate() Christian Marangi ` (2 subsequent siblings) 3 siblings, 1 reply; 16+ messages in thread From: Christian Marangi @ 2026-07-09 20:56 UTC (permalink / raw) To: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Ilpo Järvinen, Christian Marangi, Andy Shevchenko, Benjamin Larsson, John Ogness, Marco Felsch, Gerhard Engleder, Jiaxun Yang, Randy Dunlap, Binbin Zhou, Rong Zhang, Lukas Wunner, Lubomir Rintel, devicetree, linux-kernel, linux-serial From: Benjamin Larsson <benjamin.larsson@genexis.eu> The Airoha SoC family have a mostly 16550-compatible UART and High-Speed UART hardware with the exception of custom baud rate settings register. Signed-off-by: Benjamin Larsson <benjamin.larsson@genexis.eu> Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> --- Documentation/devicetree/bindings/serial/8250.yaml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/Documentation/devicetree/bindings/serial/8250.yaml b/Documentation/devicetree/bindings/serial/8250.yaml index bb7b9c87a807..b6f7e093d8d7 100644 --- a/Documentation/devicetree/bindings/serial/8250.yaml +++ b/Documentation/devicetree/bindings/serial/8250.yaml @@ -110,6 +110,11 @@ properties: - const: mrvl,pxa-uart - const: nuvoton,wpcm450-uart - const: nuvoton,npcm750-uart + - const: airoha,en7523-uart + - items: + - const: airoha,an7581-uart + - const: airoha,en7523-uart + - const: airoha,an7581-hsuart - const: nvidia,tegra20-uart - const: nxp,lpc3220-uart - items: -- 2.53.0 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH 1/4] dt-bindings: serial: 8250: Add Airoha compatibles 2026-07-09 20:56 ` [PATCH 1/4] dt-bindings: serial: 8250: Add Airoha compatibles Christian Marangi @ 2026-07-10 16:43 ` Conor Dooley 0 siblings, 0 replies; 16+ messages in thread From: Conor Dooley @ 2026-07-10 16:43 UTC (permalink / raw) To: Christian Marangi Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Ilpo Järvinen, Andy Shevchenko, Benjamin Larsson, John Ogness, Marco Felsch, Gerhard Engleder, Jiaxun Yang, Randy Dunlap, Binbin Zhou, Rong Zhang, Lukas Wunner, Lubomir Rintel, devicetree, linux-kernel, linux-serial [-- Attachment #1: Type: text/plain, Size: 1331 bytes --] On Thu, Jul 09, 2026 at 10:56:49PM +0200, Christian Marangi wrote: > From: Benjamin Larsson <benjamin.larsson@genexis.eu> > > The Airoha SoC family have a mostly 16550-compatible UART > and High-Speed UART hardware with the exception of custom > baud rate settings register. > > Signed-off-by: Benjamin Larsson <benjamin.larsson@genexis.eu> > Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> > --- > Documentation/devicetree/bindings/serial/8250.yaml | 5 +++++ > 1 file changed, 5 insertions(+) > > diff --git a/Documentation/devicetree/bindings/serial/8250.yaml b/Documentation/devicetree/bindings/serial/8250.yaml > index bb7b9c87a807..b6f7e093d8d7 100644 > --- a/Documentation/devicetree/bindings/serial/8250.yaml > +++ b/Documentation/devicetree/bindings/serial/8250.yaml > @@ -110,6 +110,11 @@ properties: > - const: mrvl,pxa-uart > - const: nuvoton,wpcm450-uart > - const: nuvoton,npcm750-uart > + - const: airoha,en7523-uart > + - items: > + - const: airoha,an7581-uart > + - const: airoha,en7523-uart Acked-by: Conor Dooley <conor.dooley@microchip.com> pw-bot: not-applicable > + - const: airoha,an7581-hsuart > - const: nvidia,tegra20-uart > - const: nxp,lpc3220-uart > - items: > -- > 2.53.0 > [-- Attachment #2: signature.asc --] [-- Type: application/pgp-signature, Size: 228 bytes --] ^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 2/4] serial: 8250: export serial8250_get_baud_rate() 2026-07-09 20:56 [PATCH 0/4] serial: 8250: Add AN7581 UART support Christian Marangi 2026-07-09 20:56 ` [PATCH 1/4] dt-bindings: serial: 8250: Add Airoha compatibles Christian Marangi @ 2026-07-09 20:56 ` Christian Marangi 2026-07-09 21:35 ` Andy Shevchenko 2026-07-10 8:19 ` Ilpo Järvinen 2026-07-09 20:56 ` [PATCH 3/4] serial: 8250: map UAPI port type to internal enum Christian Marangi 2026-07-09 20:56 ` [PATCH 4/4] serial: 8250: Add Airoha SoC UART and HSUART support Christian Marangi 3 siblings, 2 replies; 16+ messages in thread From: Christian Marangi @ 2026-07-09 20:56 UTC (permalink / raw) To: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Ilpo Järvinen, Christian Marangi, Andy Shevchenko, Benjamin Larsson, John Ogness, Marco Felsch, Gerhard Engleder, Jiaxun Yang, Randy Dunlap, Binbin Zhou, Rong Zhang, Lukas Wunner, Lubomir Rintel, devicetree, linux-kernel, linux-serial Some driver might need to access the current baud rate to correctly configure it. Export the serial8250_get_baud_rate() function to limit code duplication. Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> --- drivers/tty/serial/8250/8250_port.c | 7 ++++--- include/linux/serial_8250.h | 4 ++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index 630deb7dd344..033d8fb8bb23 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -2560,9 +2560,9 @@ static void serial8250_set_divisor(struct uart_port *port, unsigned int baud, serial8250_do_set_divisor(port, baud, quot); } -static unsigned int serial8250_get_baud_rate(struct uart_port *port, - struct ktermios *termios, - const struct ktermios *old) +unsigned int serial8250_get_baud_rate(struct uart_port *port, + struct ktermios *termios, + const struct ktermios *old) { unsigned int tolerance = port->uartclk / 100; unsigned int min; @@ -2589,6 +2589,7 @@ static unsigned int serial8250_get_baud_rate(struct uart_port *port, */ return uart_get_baud_rate(port, termios, old, min, max); } +EXPORT_SYMBOL_GPL(serial8250_get_baud_rate); /* * Note in order to avoid the tty port mutex deadlock don't use the next method diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h index a95b2d143d24..8d26fa2008b6 100644 --- a/include/linux/serial_8250.h +++ b/include/linux/serial_8250.h @@ -208,6 +208,10 @@ void serial8250_console_write(struct uart_8250_port *up, const char *s, int serial8250_console_setup(struct uart_port *port, char *options, bool probe); int serial8250_console_exit(struct uart_port *port); +unsigned int serial8250_get_baud_rate(struct uart_port *port, + struct ktermios *termios, + const struct ktermios *old); + void serial8250_set_isa_configurator(void (*v)(int port, struct uart_port *up, u32 *capabilities)); -- 2.53.0 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH 2/4] serial: 8250: export serial8250_get_baud_rate() 2026-07-09 20:56 ` [PATCH 2/4] serial: 8250: export serial8250_get_baud_rate() Christian Marangi @ 2026-07-09 21:35 ` Andy Shevchenko 2026-07-09 21:39 ` Christian Marangi 2026-07-10 8:19 ` Ilpo Järvinen 1 sibling, 1 reply; 16+ messages in thread From: Andy Shevchenko @ 2026-07-09 21:35 UTC (permalink / raw) To: Christian Marangi Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Ilpo Järvinen, Benjamin Larsson, John Ogness, Marco Felsch, Gerhard Engleder, Jiaxun Yang, Randy Dunlap, Binbin Zhou, Rong Zhang, Lukas Wunner, Lubomir Rintel, devicetree, linux-kernel, linux-serial On Thu, Jul 09, 2026 at 10:56:50PM +0200, Christian Marangi wrote: > Some driver might need to access the current baud rate to correctly > configure it. > > Export the serial8250_get_baud_rate() function to limit code duplication. Why? We have _get_divisor() / _set_divisor() for exactly that purpose, no? -- With Best Regards, Andy Shevchenko ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 2/4] serial: 8250: export serial8250_get_baud_rate() 2026-07-09 21:35 ` Andy Shevchenko @ 2026-07-09 21:39 ` Christian Marangi 2026-07-10 8:20 ` Andy Shevchenko 0 siblings, 1 reply; 16+ messages in thread From: Christian Marangi @ 2026-07-09 21:39 UTC (permalink / raw) To: Andy Shevchenko Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Ilpo Järvinen, Benjamin Larsson, John Ogness, Marco Felsch, Gerhard Engleder, Jiaxun Yang, Randy Dunlap, Binbin Zhou, Rong Zhang, Lukas Wunner, Lubomir Rintel, devicetree, linux-kernel, linux-serial On Fri, Jul 10, 2026 at 12:35:02AM +0300, Andy Shevchenko wrote: > On Thu, Jul 09, 2026 at 10:56:50PM +0200, Christian Marangi wrote: > > Some driver might need to access the current baud rate to correctly > > configure it. > > > > Export the serial8250_get_baud_rate() function to limit code duplication. > > Why? > > We have _get_divisor() / _set_divisor() for exactly that purpose, no? > I can only see set and I'm not following how that helps with any driver that needs to get the baud_rate? -- Ansuel ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 2/4] serial: 8250: export serial8250_get_baud_rate() 2026-07-09 21:39 ` Christian Marangi @ 2026-07-10 8:20 ` Andy Shevchenko 2026-07-10 8:49 ` Christian Marangi 0 siblings, 1 reply; 16+ messages in thread From: Andy Shevchenko @ 2026-07-10 8:20 UTC (permalink / raw) To: Christian Marangi Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Ilpo Järvinen, Benjamin Larsson, John Ogness, Marco Felsch, Gerhard Engleder, Jiaxun Yang, Randy Dunlap, Binbin Zhou, Rong Zhang, Lukas Wunner, Lubomir Rintel, devicetree, linux-kernel, linux-serial On Thu, Jul 09, 2026 at 11:39:32PM +0200, Christian Marangi wrote: > On Fri, Jul 10, 2026 at 12:35:02AM +0300, Andy Shevchenko wrote: > > On Thu, Jul 09, 2026 at 10:56:50PM +0200, Christian Marangi wrote: > > > Some driver might need to access the current baud rate to correctly > > > configure it. > > > > > > Export the serial8250_get_baud_rate() function to limit code duplication. > > > > Why? > > > > We have _get_divisor() / _set_divisor() for exactly that purpose, no? > > I can only see set and I'm not following how that helps with any driver > that needs to get the baud_rate? You operate on the divisor settings instead of baud rate. Otherwise, can you elaborate why no other (out of dozens!) driver needs this? What do you try to achieve with the baud rate settings exactly? -- With Best Regards, Andy Shevchenko ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 2/4] serial: 8250: export serial8250_get_baud_rate() 2026-07-10 8:20 ` Andy Shevchenko @ 2026-07-10 8:49 ` Christian Marangi 2026-07-10 9:14 ` Andy Shevchenko 0 siblings, 1 reply; 16+ messages in thread From: Christian Marangi @ 2026-07-10 8:49 UTC (permalink / raw) To: Andy Shevchenko Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Ilpo Järvinen, Benjamin Larsson, John Ogness, Marco Felsch, Gerhard Engleder, Jiaxun Yang, Randy Dunlap, Binbin Zhou, Rong Zhang, Lukas Wunner, Lubomir Rintel, devicetree, linux-kernel, linux-serial On Fri, Jul 10, 2026 at 11:20:48AM +0300, Andy Shevchenko wrote: > On Thu, Jul 09, 2026 at 11:39:32PM +0200, Christian Marangi wrote: > > On Fri, Jul 10, 2026 at 12:35:02AM +0300, Andy Shevchenko wrote: > > > On Thu, Jul 09, 2026 at 10:56:50PM +0200, Christian Marangi wrote: > > > > Some driver might need to access the current baud rate to correctly > > > > configure it. > > > > > > > > Export the serial8250_get_baud_rate() function to limit code duplication. > > > > > > Why? > > > > > > We have _get_divisor() / _set_divisor() for exactly that purpose, no? > > > > I can only see set and I'm not following how that helps with any driver > > that needs to get the baud_rate? > > You operate on the divisor settings instead of baud rate. Otherwise, can > you elaborate why no other (out of dozens!) driver needs this? What do > you try to achieve with the baud rate settings exactly? > Ok it wasn't easy to find but you were referring to the .set_divisor and .get_divisor. Now it's clear. Yes I guess I can use them instead of exporting this function. Sorry for the noise and thanks for the suggestion! -- Ansuel ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 2/4] serial: 8250: export serial8250_get_baud_rate() 2026-07-10 8:49 ` Christian Marangi @ 2026-07-10 9:14 ` Andy Shevchenko 0 siblings, 0 replies; 16+ messages in thread From: Andy Shevchenko @ 2026-07-10 9:14 UTC (permalink / raw) To: Christian Marangi Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Ilpo Järvinen, Benjamin Larsson, John Ogness, Marco Felsch, Gerhard Engleder, Jiaxun Yang, Randy Dunlap, Binbin Zhou, Rong Zhang, Lukas Wunner, Lubomir Rintel, devicetree, linux-kernel, linux-serial On Fri, Jul 10, 2026 at 10:49:27AM +0200, Christian Marangi wrote: > On Fri, Jul 10, 2026 at 11:20:48AM +0300, Andy Shevchenko wrote: > > On Thu, Jul 09, 2026 at 11:39:32PM +0200, Christian Marangi wrote: > > > On Fri, Jul 10, 2026 at 12:35:02AM +0300, Andy Shevchenko wrote: > > > > On Thu, Jul 09, 2026 at 10:56:50PM +0200, Christian Marangi wrote: > > > > > Some driver might need to access the current baud rate to correctly > > > > > configure it. > > > > > > > > > > Export the serial8250_get_baud_rate() function to limit code duplication. > > > > > > > > Why? > > > > > > > > We have _get_divisor() / _set_divisor() for exactly that purpose, no? > > > > > > I can only see set and I'm not following how that helps with any driver > > > that needs to get the baud_rate? > > > > You operate on the divisor settings instead of baud rate. Otherwise, can > > you elaborate why no other (out of dozens!) driver needs this? What do > > you try to achieve with the baud rate settings exactly? > > Ok it wasn't easy to find but you were referring to the .set_divisor and > .get_divisor. Now it's clear. Yes I guess I can use them instead of > exporting this function. > > Sorry for the noise and thanks for the suggestion! Ah, it was me a bit unclear, By _*_divisor() I referred to the wrappers on top of .set_divisor() and .get_divisor(), I should have spelled that more clearly. In any case the driver is suppose to fill callbacks and 8250 set_termios() will use that. -- With Best Regards, Andy Shevchenko ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 2/4] serial: 8250: export serial8250_get_baud_rate() 2026-07-09 20:56 ` [PATCH 2/4] serial: 8250: export serial8250_get_baud_rate() Christian Marangi 2026-07-09 21:35 ` Andy Shevchenko @ 2026-07-10 8:19 ` Ilpo Järvinen 1 sibling, 0 replies; 16+ messages in thread From: Ilpo Järvinen @ 2026-07-10 8:19 UTC (permalink / raw) To: Christian Marangi Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Andy Shevchenko, Benjamin Larsson, John Ogness, Marco Felsch, Gerhard Engleder, Jiaxun Yang, Randy Dunlap, Binbin Zhou, Rong Zhang, Lukas Wunner, Lubomir Rintel, devicetree, LKML, linux-serial On Thu, 9 Jul 2026, Christian Marangi wrote: > Some driver might need to access the current baud rate to correctly > configure it. > > Export the serial8250_get_baud_rate() function to limit code duplication. > > Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> > --- > drivers/tty/serial/8250/8250_port.c | 7 ++++--- > include/linux/serial_8250.h | 4 ++++ > 2 files changed, 8 insertions(+), 3 deletions(-) > > diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c > index 630deb7dd344..033d8fb8bb23 100644 > --- a/drivers/tty/serial/8250/8250_port.c > +++ b/drivers/tty/serial/8250/8250_port.c > @@ -2560,9 +2560,9 @@ static void serial8250_set_divisor(struct uart_port *port, unsigned int baud, > serial8250_do_set_divisor(port, baud, quot); > } > > -static unsigned int serial8250_get_baud_rate(struct uart_port *port, > - struct ktermios *termios, > - const struct ktermios *old) > +unsigned int serial8250_get_baud_rate(struct uart_port *port, > + struct ktermios *termios, > + const struct ktermios *old) > { > unsigned int tolerance = port->uartclk / 100; > unsigned int min; > @@ -2589,6 +2589,7 @@ static unsigned int serial8250_get_baud_rate(struct uart_port *port, > */ > return uart_get_baud_rate(port, termios, old, min, max); > } > +EXPORT_SYMBOL_GPL(serial8250_get_baud_rate); Please put newly exported things into SERIAL_8250 namespace. -- i. ^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 3/4] serial: 8250: map UAPI port type to internal enum 2026-07-09 20:56 [PATCH 0/4] serial: 8250: Add AN7581 UART support Christian Marangi 2026-07-09 20:56 ` [PATCH 1/4] dt-bindings: serial: 8250: Add Airoha compatibles Christian Marangi 2026-07-09 20:56 ` [PATCH 2/4] serial: 8250: export serial8250_get_baud_rate() Christian Marangi @ 2026-07-09 20:56 ` Christian Marangi 2026-07-09 21:37 ` Andy Shevchenko 2026-07-09 20:56 ` [PATCH 4/4] serial: 8250: Add Airoha SoC UART and HSUART support Christian Marangi 3 siblings, 1 reply; 16+ messages in thread From: Christian Marangi @ 2026-07-09 20:56 UTC (permalink / raw) To: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Ilpo Järvinen, Christian Marangi, Andy Shevchenko, Benjamin Larsson, John Ogness, Marco Felsch, Gerhard Engleder, Jiaxun Yang, Randy Dunlap, Binbin Zhou, Rong Zhang, Lukas Wunner, Lubomir Rintel, devicetree, linux-kernel, linux-serial There is currently some confusion when a new 8250 UART device needs to be defined with the related index for uart_config[] to be directly defined in UAPI header. There isn't any specific reason to define the index directly in UAPI header unless it's also needed to be defined for userspace usage. To try to address this confusion and making it clear how these specific index should be defined and where, create a dedicated enum in 8250.h with all the current defined values in UAPI header and document how these id should be defined. Rename the define in 8250_port.c with the new UART_ prefix. Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> --- drivers/tty/serial/8250/8250.h | 122 ++++++++++++++++++++++++++++ drivers/tty/serial/8250/8250_port.c | 72 ++++++++-------- 2 files changed, 158 insertions(+), 36 deletions(-) diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h index 77fe0588fd6b..3a45f957d3a9 100644 --- a/drivers/tty/serial/8250/8250.h +++ b/drivers/tty/serial/8250/8250.h @@ -73,6 +73,128 @@ struct serial8250_config { unsigned int flags; }; +/* + * The uart_config[] array index is referenced and defined from index + * in uapi/linux/serial.h and uapi/linux/serial_core.h. + * + * This was old practice and for anything that doesn't need to support + * userspace, new type should be limited and added only HERE. + * + * Any UART port that requires userspace support, should define the + * dedicated index in the UAPI header and reference it when added + * to this enum table. + */ +enum uart_port_type { + /* From uapi/linux/serial.h */ + UART_PORT_UNKNOWN = PORT_UNKNOWN, /* 0 */ + UART_PORT_8250 = PORT_8250, + UART_PORT_16450 = PORT_16450, + UART_PORT_16550 = PORT_16550, + UART_PORT_16550A = PORT_16550A, + UART_PORT_CIRRUS = PORT_CIRRUS, + UART_PORT_16650 = PORT_16650, + UART_PORT_16650V2 = PORT_16650V2, + UART_PORT_16750 = PORT_16750, + UART_PORT_STARTECH = PORT_STARTECH, + UART_PORT_16C950 = PORT_16C950, + UART_PORT_16654 = PORT_16654, + UART_PORT_16850 = PORT_16850, + UART_PORT_RSA = PORT_RSA, /* 13 */ + + /* From uapi/linux/serial_core.h (14-123) */ + UART_PORT_NS16550A = PORT_NS16550A, /* 14 */ + UART_PORT_XSCALE = PORT_XSCALE, + UART_PORT_RM9000 = PORT_RM9000, + UART_PORT_OCTEON = PORT_OCTEON, + UART_PORT_AR7 = PORT_AR7, + UART_PORT_U6_16550A = PORT_U6_16550A, + UART_PORT_TEGRA = PORT_TEGRA, + UART_PORT_XR17D15X = PORT_XR17D15X, + UART_PORT_LPC3220 = PORT_LPC3220, + UART_PORT_8250_CIR = PORT_8250_CIR, + UART_PORT_XR17V35X = PORT_XR17V35X, + UART_PORT_BRCM_TRUMANAGE = PORT_BRCM_TRUMANAGE, + UART_PORT_ALTR_16550_F32 = PORT_ALTR_16550_F32, + UART_PORT_ALTR_16550_F64 = PORT_ALTR_16550_F64, + UART_PORT_ALTR_16550_F128 = PORT_ALTR_16550_F128, + UART_PORT_RT2880 = PORT_RT2880, + UART_PORT_16550A_FSL64 = PORT_16550A_FSL64, + UART_PORT_PXA = PORT_PXA, + UART_PORT_AMBA = PORT_AMBA, + UART_PORT_CLPS711X = PORT_CLPS711X, + UART_PORT_SA1100 = PORT_SA1100, + UART_PORT_UART00 = PORT_UART00, + UART_PORT_OWL = PORT_OWL, + UART_PORT_21285 = PORT_21285, + UART_PORT_SUNZILOG = PORT_SUNZILOG, + UART_PORT_SUNSAB = PORT_SUNSAB, + UART_PORT_NPCM = PORT_NPCM, + UART_PORT_TEGRA_TCU = PORT_TEGRA_TCU, + UART_PORT_ASPEED_VUART = PORT_ASPEED_VUART, + UART_PORT_PCH_8LINE = PORT_PCH_8LINE, + UART_PORT_PCH_2LINE = PORT_PCH_2LINE, + UART_PORT_DZ = PORT_DZ, + UART_PORT_ZS = PORT_ZS, + UART_PORT_MUX = PORT_MUX, + UART_PORT_ATMEL = PORT_ATMEL, + UART_PORT_MAC_ZILOG = PORT_MAC_ZILOG, + UART_PORT_PMAC_ZILOG = PORT_PMAC_ZILOG, + UART_PORT_SCI = PORT_SCI, + UART_PORT_SCIF = PORT_SCIF, + UART_PORT_IRDA = PORT_IRDA, + UART_PORT_IP22ZILOG = PORT_IP22ZILOG, + UART_PORT_CPM = PORT_CPM, + UART_PORT_MPC52xx = PORT_MPC52xx, + UART_PORT_ICOM = PORT_ICOM, + UART_PORT_IMX = PORT_IMX, + UART_PORT_TXX9 = PORT_TXX9, + UART_PORT_JSM = PORT_JSM, + UART_PORT_SUNHV = PORT_SUNHV, + UART_PORT_UARTLITE = PORT_UARTLITE, + UART_PORT_BCM7271 = PORT_BCM7271, + UART_PORT_SB1250_DUART = PORT_SB1250_DUART, + UART_PORT_MCF = PORT_MCF, + UART_PORT_SC26XX = PORT_SC26XX, + UART_PORT_SCIFA = PORT_SCIFA, + UART_PORT_S3C6400 = PORT_S3C6400, + UART_PORT_MAX3100 = PORT_MAX3100, + UART_PORT_TIMBUART = PORT_TIMBUART, + UART_PORT_MSM = PORT_MSM, + UART_PORT_BCM63XX = PORT_BCM63XX, + UART_PORT_APBUART = PORT_APBUART, + UART_PORT_ALTERA_JTAGUART = PORT_ALTERA_JTAGUART, + UART_PORT_ALTERA_UART = PORT_ALTERA_UART, + UART_PORT_SCIFB = PORT_SCIFB, + UART_PORT_MAX310X = PORT_MAX310X, + UART_PORT_DA830 = PORT_DA830, + UART_PORT_OMAP = PORT_OMAP, + UART_PORT_VT8500 = PORT_VT8500, + UART_PORT_XUARTPS = PORT_XUARTPS, + UART_PORT_AR933X = PORT_AR933X, + UART_PORT_MCHP16550A = PORT_MCHP16550A, + UART_PORT_ARC = PORT_ARC, + UART_PORT_RP2 = PORT_RP2, + UART_PORT_LPUART = PORT_LPUART, + UART_PORT_HSCIF = PORT_HSCIF, + UART_PORT_ASC = PORT_ASC, + UART_PORT_MEN_Z135 = PORT_MEN_Z135, + UART_PORT_SC16IS7XX = PORT_SC16IS7XX, + UART_PORT_MESON = PORT_MESON, + UART_PORT_DIGICOLOR = PORT_DIGICOLOR, + UART_PORT_SPRD = PORT_SPRD, + UART_PORT_STM32 = PORT_STM32, + UART_PORT_MVEBU = PORT_MVEBU, + UART_PORT_PIC32 = PORT_PIC32, + UART_PORT_MPS2UART = PORT_MPS2UART, + UART_PORT_MTK_BTIF = PORT_MTK_BTIF, + UART_PORT_RDA = PORT_RDA, + UART_PORT_MLB_USIO = PORT_MLB_USIO, + UART_PORT_SIFIVE_V0 = PORT_SIFIVE_V0, + UART_PORT_SUNIX = PORT_SUNIX, + UART_PORT_LINFLEXUART = PORT_LINFLEXUART, + UART_PORT_SUNPLUS = PORT_SUNPLUS, /* 123 */ +}; + #define UART_CAP_FIFO BIT(8) /* UART has FIFO */ #define UART_CAP_EFR BIT(9) /* UART has EFR */ #define UART_CAP_SLEEP BIT(10) /* UART has IER sleep */ diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index 033d8fb8bb23..a0b80324a559 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -43,27 +43,27 @@ * Here we define the default xmit fifo size used for each type of UART. */ static const struct serial8250_config uart_config[] = { - [PORT_UNKNOWN] = { + [UART_PORT_UNKNOWN] = { .name = "unknown", .fifo_size = 1, .tx_loadsz = 1, }, - [PORT_8250] = { + [UART_PORT_8250] = { .name = "8250", .fifo_size = 1, .tx_loadsz = 1, }, - [PORT_16450] = { + [UART_PORT_16450] = { .name = "16450", .fifo_size = 1, .tx_loadsz = 1, }, - [PORT_16550] = { + [UART_PORT_16550] = { .name = "16550", .fifo_size = 1, .tx_loadsz = 1, }, - [PORT_16550A] = { + [UART_PORT_16550A] = { .name = "16550A", .fifo_size = 16, .tx_loadsz = 16, @@ -71,18 +71,18 @@ static const struct serial8250_config uart_config[] = { .rxtrig_bytes = {1, 4, 8, 14}, .flags = UART_CAP_FIFO, }, - [PORT_CIRRUS] = { + [UART_PORT_CIRRUS] = { .name = "Cirrus", .fifo_size = 1, .tx_loadsz = 1, }, - [PORT_16650] = { + [UART_PORT_16650] = { .name = "ST16650", .fifo_size = 1, .tx_loadsz = 1, .flags = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP, }, - [PORT_16650V2] = { + [UART_PORT_16650V2] = { .name = "ST16650V2", .fifo_size = 32, .tx_loadsz = 16, @@ -91,7 +91,7 @@ static const struct serial8250_config uart_config[] = { .rxtrig_bytes = {8, 16, 24, 28}, .flags = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP, }, - [PORT_16750] = { + [UART_PORT_16750] = { .name = "TI16750", .fifo_size = 64, .tx_loadsz = 64, @@ -100,12 +100,12 @@ static const struct serial8250_config uart_config[] = { .rxtrig_bytes = {1, 16, 32, 56}, .flags = UART_CAP_FIFO | UART_CAP_SLEEP | UART_CAP_AFE, }, - [PORT_STARTECH] = { + [UART_PORT_STARTECH] = { .name = "Startech", .fifo_size = 1, .tx_loadsz = 1, }, - [PORT_16C950] = { + [UART_PORT_16C950] = { .name = "16C950/954", .fifo_size = 128, .tx_loadsz = 128, @@ -114,7 +114,7 @@ static const struct serial8250_config uart_config[] = { /* UART_CAP_EFR breaks billionon CF bluetooth card. */ .flags = UART_CAP_FIFO | UART_CAP_SLEEP, }, - [PORT_16654] = { + [UART_PORT_16654] = { .name = "ST16654", .fifo_size = 64, .tx_loadsz = 32, @@ -123,49 +123,49 @@ static const struct serial8250_config uart_config[] = { .rxtrig_bytes = {8, 16, 56, 60}, .flags = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP, }, - [PORT_16850] = { + [UART_PORT_16850] = { .name = "XR16850", .fifo_size = 128, .tx_loadsz = 128, .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, .flags = UART_CAP_FIFO | UART_CAP_EFR | UART_CAP_SLEEP, }, - [PORT_RSA] = { + [UART_PORT_RSA] = { .name = "RSA", .fifo_size = 2048, .tx_loadsz = 2048, .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_11, .flags = UART_CAP_FIFO, }, - [PORT_NS16550A] = { + [UART_PORT_NS16550A] = { .name = "NS16550A", .fifo_size = 16, .tx_loadsz = 16, .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, .flags = UART_CAP_FIFO | UART_NATSEMI, }, - [PORT_XSCALE] = { + [UART_PORT_XSCALE] = { .name = "XScale", .fifo_size = 32, .tx_loadsz = 32, .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, .flags = UART_CAP_FIFO | UART_CAP_UUE | UART_CAP_RTOIE, }, - [PORT_OCTEON] = { + [UART_PORT_OCTEON] = { .name = "OCTEON", .fifo_size = 64, .tx_loadsz = 64, .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, .flags = UART_CAP_FIFO, }, - [PORT_U6_16550A] = { + [UART_PORT_U6_16550A] = { .name = "U6_16550A", .fifo_size = 64, .tx_loadsz = 64, .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10, .flags = UART_CAP_FIFO | UART_CAP_AFE, }, - [PORT_TEGRA] = { + [UART_PORT_TEGRA] = { .name = "Tegra", .fifo_size = 32, .tx_loadsz = 8, @@ -174,7 +174,7 @@ static const struct serial8250_config uart_config[] = { .rxtrig_bytes = {1, 4, 8, 14}, .flags = UART_CAP_FIFO | UART_CAP_RTOIE, }, - [PORT_XR17D15X] = { + [UART_PORT_XR17D15X] = { .name = "XR17D15X", .fifo_size = 64, .tx_loadsz = 64, @@ -182,7 +182,7 @@ static const struct serial8250_config uart_config[] = { .flags = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR | UART_CAP_SLEEP, }, - [PORT_XR17V35X] = { + [UART_PORT_XR17V35X] = { .name = "XR17V35X", .fifo_size = 256, .tx_loadsz = 256, @@ -191,7 +191,7 @@ static const struct serial8250_config uart_config[] = { .flags = UART_CAP_FIFO | UART_CAP_AFE | UART_CAP_EFR | UART_CAP_SLEEP, }, - [PORT_LPC3220] = { + [UART_PORT_LPC3220] = { .name = "LPC3220", .fifo_size = 64, .tx_loadsz = 32, @@ -199,16 +199,16 @@ static const struct serial8250_config uart_config[] = { UART_FCR_R_TRIG_00 | UART_FCR_T_TRIG_00, .flags = UART_CAP_FIFO, }, - [PORT_BRCM_TRUMANAGE] = { + [UART_PORT_BRCM_TRUMANAGE] = { .name = "TruManage", .fifo_size = 1, .tx_loadsz = 1024, .flags = UART_CAP_HFIFO, }, - [PORT_8250_CIR] = { + [UART_PORT_8250_CIR] = { .name = "CIR port" }, - [PORT_ALTR_16550_F32] = { + [UART_PORT_ALTR_16550_F32] = { .name = "Altera 16550 FIFO32", .fifo_size = 32, .tx_loadsz = 32, @@ -216,7 +216,7 @@ static const struct serial8250_config uart_config[] = { .rxtrig_bytes = {1, 8, 16, 30}, .flags = UART_CAP_FIFO | UART_CAP_AFE, }, - [PORT_ALTR_16550_F64] = { + [UART_PORT_ALTR_16550_F64] = { .name = "Altera 16550 FIFO64", .fifo_size = 64, .tx_loadsz = 64, @@ -224,7 +224,7 @@ static const struct serial8250_config uart_config[] = { .rxtrig_bytes = {1, 16, 32, 62}, .flags = UART_CAP_FIFO | UART_CAP_AFE, }, - [PORT_ALTR_16550_F128] = { + [UART_PORT_ALTR_16550_F128] = { .name = "Altera 16550 FIFO128", .fifo_size = 128, .tx_loadsz = 128, @@ -237,7 +237,7 @@ static const struct serial8250_config uart_config[] = { * workaround of errata A-008006 which states that tx_loadsz should * be configured less than Maximum supported fifo bytes. */ - [PORT_16550A_FSL64] = { + [UART_PORT_16550A_FSL64] = { .name = "16550A_FSL64", .fifo_size = 64, .tx_loadsz = 63, @@ -245,7 +245,7 @@ static const struct serial8250_config uart_config[] = { UART_FCR7_64BYTE, .flags = UART_CAP_FIFO | UART_CAP_NOTEMT, }, - [PORT_RT2880] = { + [UART_PORT_RT2880] = { .name = "Palmchip BK-3103", .fifo_size = 16, .tx_loadsz = 16, @@ -253,7 +253,7 @@ static const struct serial8250_config uart_config[] = { .rxtrig_bytes = {1, 4, 8, 14}, .flags = UART_CAP_FIFO, }, - [PORT_DA830] = { + [UART_PORT_DA830] = { .name = "TI DA8xx/66AK2x", .fifo_size = 16, .tx_loadsz = 16, @@ -262,7 +262,7 @@ static const struct serial8250_config uart_config[] = { .rxtrig_bytes = {1, 4, 8, 14}, .flags = UART_CAP_FIFO | UART_CAP_AFE, }, - [PORT_MTK_BTIF] = { + [UART_PORT_MTK_BTIF] = { .name = "MediaTek BTIF", .fifo_size = 16, .tx_loadsz = 16, @@ -270,7 +270,7 @@ static const struct serial8250_config uart_config[] = { UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT, .flags = UART_CAP_FIFO, }, - [PORT_NPCM] = { + [UART_PORT_NPCM] = { .name = "Nuvoton 16550", .fifo_size = 16, .tx_loadsz = 16, @@ -279,7 +279,7 @@ static const struct serial8250_config uart_config[] = { .rxtrig_bytes = {1, 4, 8, 14}, .flags = UART_CAP_FIFO, }, - [PORT_SUNIX] = { + [UART_PORT_SUNIX] = { .name = "Sunix", .fifo_size = 128, .tx_loadsz = 128, @@ -287,7 +287,7 @@ static const struct serial8250_config uart_config[] = { .rxtrig_bytes = {1, 32, 64, 112}, .flags = UART_CAP_FIFO | UART_CAP_SLEEP, }, - [PORT_ASPEED_VUART] = { + [UART_PORT_ASPEED_VUART] = { .name = "ASPEED VUART", .fifo_size = 16, .tx_loadsz = 16, @@ -295,7 +295,7 @@ static const struct serial8250_config uart_config[] = { .rxtrig_bytes = {1, 4, 8, 14}, .flags = UART_CAP_FIFO, }, - [PORT_MCHP16550A] = { + [UART_PORT_MCHP16550A] = { .name = "MCHP16550A", .fifo_size = 256, .tx_loadsz = 256, @@ -303,7 +303,7 @@ static const struct serial8250_config uart_config[] = { .rxtrig_bytes = {2, 66, 130, 194}, .flags = UART_CAP_FIFO, }, - [PORT_BCM7271] = { + [UART_PORT_BCM7271] = { .name = "Broadcom BCM7271 UART", .fifo_size = 32, .tx_loadsz = 32, -- 2.53.0 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH 3/4] serial: 8250: map UAPI port type to internal enum 2026-07-09 20:56 ` [PATCH 3/4] serial: 8250: map UAPI port type to internal enum Christian Marangi @ 2026-07-09 21:37 ` Andy Shevchenko 2026-07-09 21:46 ` Christian Marangi 0 siblings, 1 reply; 16+ messages in thread From: Andy Shevchenko @ 2026-07-09 21:37 UTC (permalink / raw) To: Christian Marangi Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Ilpo Järvinen, Benjamin Larsson, John Ogness, Marco Felsch, Gerhard Engleder, Jiaxun Yang, Randy Dunlap, Binbin Zhou, Rong Zhang, Lukas Wunner, Lubomir Rintel, devicetree, linux-kernel, linux-serial On Thu, Jul 09, 2026 at 10:56:51PM +0200, Christian Marangi wrote: > There is currently some confusion when a new 8250 UART device needs to be > defined with the related index for uart_config[] to be directly defined in > UAPI header. > > There isn't any specific reason to define the index directly in UAPI header > unless it's also needed to be defined for userspace usage. > > To try to address this confusion and making it clear how these specific > index should be defined and where, create a dedicated enum in 8250.h > with all the current defined values in UAPI header and document how these > id should be defined. > > Rename the define in 8250_port.c with the new UART_ prefix. This will bring a wide field for the all possible conflicts and doesn't really solve the issue. Why not simply kill the UAPI part of the definitions for good? (Move the all, except the first 13) to be internal to the kernel. -- With Best Regards, Andy Shevchenko ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 3/4] serial: 8250: map UAPI port type to internal enum 2026-07-09 21:37 ` Andy Shevchenko @ 2026-07-09 21:46 ` Christian Marangi 2026-07-10 10:09 ` Andy Shevchenko 0 siblings, 1 reply; 16+ messages in thread From: Christian Marangi @ 2026-07-09 21:46 UTC (permalink / raw) To: Andy Shevchenko Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Ilpo Järvinen, Benjamin Larsson, John Ogness, Marco Felsch, Gerhard Engleder, Jiaxun Yang, Randy Dunlap, Binbin Zhou, Rong Zhang, Lukas Wunner, Lubomir Rintel, devicetree, linux-kernel, linux-serial On Fri, Jul 10, 2026 at 12:37:48AM +0300, Andy Shevchenko wrote: > On Thu, Jul 09, 2026 at 10:56:51PM +0200, Christian Marangi wrote: > > There is currently some confusion when a new 8250 UART device needs to be > > defined with the related index for uart_config[] to be directly defined in > > UAPI header. > > > > There isn't any specific reason to define the index directly in UAPI header > > unless it's also needed to be defined for userspace usage. > > > > To try to address this confusion and making it clear how these specific > > index should be defined and where, create a dedicated enum in 8250.h > > with all the current defined values in UAPI header and document how these > > id should be defined. > > > > Rename the define in 8250_port.c with the new UART_ prefix. > > This will bring a wide field for the all possible conflicts and doesn't really > solve the issue. Why not simply kill the UAPI part of the definitions for good? > (Move the all, except the first 13) to be internal to the kernel. > I mean... With correct review from maintainers, conflict won't happen. I don't feel it's that easy to kill UAPI header... userspace stuff and we don't kill userspace. The previous suggested solution was to stop declaring stuff in UAPI header and start declaring in the internal header making the situation even worse and error prone with id conflict. This can really be prevent only by correct review of the change. (or keep using UAPI) Maybe other have better ideas on this. On net we have a similar problem and the implementation is mostly similar with duplicated reference and some BUILD_BUG magic. -- Ansuel ^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH 3/4] serial: 8250: map UAPI port type to internal enum 2026-07-09 21:46 ` Christian Marangi @ 2026-07-10 10:09 ` Andy Shevchenko 0 siblings, 0 replies; 16+ messages in thread From: Andy Shevchenko @ 2026-07-10 10:09 UTC (permalink / raw) To: Christian Marangi Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Ilpo Järvinen, Benjamin Larsson, John Ogness, Marco Felsch, Gerhard Engleder, Jiaxun Yang, Randy Dunlap, Binbin Zhou, Rong Zhang, Lukas Wunner, Lubomir Rintel, devicetree, linux-kernel, linux-serial On Thu, Jul 09, 2026 at 11:46:02PM +0200, Christian Marangi wrote: > On Fri, Jul 10, 2026 at 12:37:48AM +0300, Andy Shevchenko wrote: > > On Thu, Jul 09, 2026 at 10:56:51PM +0200, Christian Marangi wrote: > > > There is currently some confusion when a new 8250 UART device needs to be > > > defined with the related index for uart_config[] to be directly defined in > > > UAPI header. > > > > > > There isn't any specific reason to define the index directly in UAPI header > > > unless it's also needed to be defined for userspace usage. > > > > > > To try to address this confusion and making it clear how these specific > > > index should be defined and where, create a dedicated enum in 8250.h > > > with all the current defined values in UAPI header and document how these > > > id should be defined. > > > > > > Rename the define in 8250_port.c with the new UART_ prefix. > > > > This will bring a wide field for the all possible conflicts and doesn't really > > solve the issue. Why not simply kill the UAPI part of the definitions for good? > > (Move the all, except the first 13) to be internal to the kernel. > > I mean... With correct review from maintainers, conflict won't happen. I don't > feel it's that easy to kill UAPI header... userspace stuff and we don't > kill userspace. > > The previous suggested solution was to stop declaring stuff in UAPI header > and start declaring in the internal header making the situation even worse > and error prone with id conflict. This can really be prevent only by > correct review of the change. (or keep using UAPI) > > Maybe other have better ideas on this. On net we have a similar problem and > the implementation is mostly similar with duplicated reference and some > BUILD_BUG magic. The whole point of UAPI list of the supported types of the ports is busted from the very first case when we start re-using gaps. Meaning that if there is any current userspace software that relies on that information, it's already in a mess state. There is a Debian source code browser, you can check how many programs use that list for something real (behind the assigning types to the unknown ports). I believe none. And the assigning unknown port should not be considered valuable these days as we expect to have kernel drivers for most of the modern HW. That's why I just recommend to find a great common denominator and leave only those (and I think this split is exactly between the files in UAPI) in UAPI and hide the rest completely from the user space. Yes, big change on paper, but with 99.99% probability no functional change at all at the end of the day. Submit and RFC patch. -- With Best Regards, Andy Shevchenko ^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 4/4] serial: 8250: Add Airoha SoC UART and HSUART support 2026-07-09 20:56 [PATCH 0/4] serial: 8250: Add AN7581 UART support Christian Marangi ` (2 preceding siblings ...) 2026-07-09 20:56 ` [PATCH 3/4] serial: 8250: map UAPI port type to internal enum Christian Marangi @ 2026-07-09 20:56 ` Christian Marangi 2026-07-10 7:13 ` Jiri Slaby 3 siblings, 1 reply; 16+ messages in thread From: Christian Marangi @ 2026-07-09 20:56 UTC (permalink / raw) To: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Ilpo Järvinen, Christian Marangi, Andy Shevchenko, Benjamin Larsson, John Ogness, Marco Felsch, Gerhard Engleder, Jiaxun Yang, Randy Dunlap, Binbin Zhou, Rong Zhang, Lukas Wunner, Lubomir Rintel, devicetree, linux-kernel, linux-serial Add support for Airoha AN7523 UART and AN7581 HSUART. These implement a standard 16550 UART with only some custom logic for baud rate handling. Co-developed-by: Benjamin Larsson <benjamin.larsson@genexis.eu> Signed-off-by: Benjamin Larsson <benjamin.larsson@genexis.eu> Signed-off-by: Christian Marangi <ansuelsmth@gmail.com> --- drivers/tty/serial/8250/8250.h | 4 + drivers/tty/serial/8250/8250_airoha.c | 190 ++++++++++++++++++++++++++ drivers/tty/serial/8250/8250_port.c | 16 +++ drivers/tty/serial/8250/Kconfig | 11 ++ drivers/tty/serial/8250/Makefile | 1 + 5 files changed, 222 insertions(+) create mode 100644 drivers/tty/serial/8250/8250_airoha.c diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h index 3a45f957d3a9..a0dec4161240 100644 --- a/drivers/tty/serial/8250/8250.h +++ b/drivers/tty/serial/8250/8250.h @@ -193,6 +193,10 @@ enum uart_port_type { UART_PORT_SUNIX = PORT_SUNIX, UART_PORT_LINFLEXUART = PORT_LINFLEXUART, UART_PORT_SUNPLUS = PORT_SUNPLUS, /* 123 */ + + /* Internal 8250 only */ + UART_PORT_AIROHA = 124, + UART_PORT_AIROHA_HS = 125, }; #define UART_CAP_FIFO BIT(8) /* UART has FIFO */ diff --git a/drivers/tty/serial/8250/8250_airoha.c b/drivers/tty/serial/8250/8250_airoha.c new file mode 100644 index 000000000000..9ec98cd8de43 --- /dev/null +++ b/drivers/tty/serial/8250/8250_airoha.c @@ -0,0 +1,190 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Airoha UART driver + * + * Copyright (c) 2025 Genexis Sweden AB + * Author: Benjamin Larsson <benjamin.larsson@genexis.eu> + * Christian Marangi <ansuelsmth@gmail.com> + */ + +#include <linux/property.h> +#include <linux/serial_reg.h> +#include <linux/serial_8250.h> + +#include "8250.h" + +#define UART_AIROHA_BRDL 0 +#define UART_AIROHA_BRDH 1 +#define UART_AIROHA_XINCLKDR 10 +#define UART_AIROHA_XYD 11 + +struct airoha_8250_priv { + int line; +}; + +struct airoha_8250_data { + unsigned int type; +}; + +struct airoha_8250_clk_div_info { + int div; + int mask; +}; + +#define UART_BRDL_20M 0x01 +#define UART_BRDH_20M 0x00 + +#define XINDIV_CLOCK 20000000 +#define XYD_Y 65000 + +static const struct airoha_8250_clk_div_info airoha_clk_div_info[] = { + { .div = 10, .mask = BIT(2) }, + { .div = 4, .mask = BIT(1) }, + { .div = 2, .mask = BIT(0) }, +}; + +static const int clock_div_tab[] = { 10, 4, 2}; +static const int clock_div_reg[] = { 4, 2, 1}; + +/* + * Airoha UART baud rate calculation logic + * + * crystal_clock = 20 MHz (fixed frequency) + * xindiv_clock = crystal_clock / clock_div + * (x/y) = XYD, 32 bit register with 16 bits of x and then 16 bits of y + * clock_div = XINCLK_DIVCNT (default set to 10 (0x4)), + * - 3 bit register [ 1, 2, 4, 8, 10, 12, 16, 20 ] + * + * baud_rate = ((xindiv_clock) * (x/y)) / ([BRDH,BRDL] * 16) + * + * Selecting divider needs to fulfill + * 1.8432 MHz <= xindiv_clk <= APB clock / 2 + * The clocks are unknown but a divider of value 1 did not result in a valid + * waveform. + * + * XYD_y seems to need to be larger then XYD_x for proper waveform generation. + * Setting [BRDH,BRDL] to [0,1] and XYD_y to 65000 gives even values + * for usual baud rates. + */ +static void airoha_set_termios(struct uart_port *port, struct ktermios *termios, + const struct ktermios *old) +{ + const struct airoha_8250_clk_div_info *clk_div_info; + struct uart_8250_port *up = up_to_u8250p(port); + unsigned int xyd_x, nom, denom; + unsigned int baud; + int i; + + serial8250_do_set_termios(port, termios, old); + + baud = serial8250_get_baud_rate(port, termios, old); + + /* Set DLAB to access the baud rate divider registers (BRDH, BRDL) */ + serial_port_out(port, UART_LCR, up->lcr | UART_LCR_DLAB); + + /* Set baud rate calculation defaults (BRDIV ([BRDH,BRDL]) to 1) */ + serial_port_out(port, UART_AIROHA_BRDL, UART_BRDL_20M); + serial_port_out(port, UART_AIROHA_BRDH, UART_BRDH_20M); + + /* + * Calculate XYD_x and XINCLKDR register by searching + * through a table of crystal_clock divisors. + */ + for (i = 0 ; i < ARRAY_SIZE(airoha_clk_div_info) ; i++) { + clk_div_info = &airoha_clk_div_info[i]; + + denom = (XINDIV_CLOCK / 40) / clk_div_info->div; + nom = baud * (XYD_Y / 40); + xyd_x = ((nom / denom) << 4); + /* For the HSUART xyd_x needs to be scaled by a factor of 2 */ + if (port->type == UART_PORT_AIROHA_HS) + xyd_x = xyd_x >> 1; + if (xyd_x < XYD_Y) + break; + } + + serial_port_out(port, UART_AIROHA_XINCLKDR, clk_div_info->mask); + serial_port_out(port, UART_AIROHA_XYD, (xyd_x << 16) | XYD_Y); + + /* unset DLAB */ + serial_port_out(port, UART_LCR, up->lcr); +} + +static int airoha_8250_probe(struct platform_device *pdev) +{ + const struct airoha_8250_data *data; + struct uart_8250_port uart = { }; + struct device *dev = &pdev->dev; + struct airoha_8250_priv *priv; + struct resource *res; + int ret; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return dev_err_probe(dev, -EINVAL, "invalid address\n"); + + priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + data = device_get_match_data(dev); + + uart.port.dev = dev; + uart.port.type = data->type; + uart.port.flags = UPF_BOOT_AUTOCONF | UPF_FIXED_PORT | + UPF_FIXED_TYPE | UPF_IOREMAP; + uart.port.set_termios = airoha_set_termios; + uart.port.mapbase = res->start; + uart.port.mapsize = resource_size(res); + + ret = uart_read_and_validate_port_properties(&uart.port); + if (ret) + return ret; + + ret = serial8250_register_8250_port(&uart); + if (ret < 0) + return ret; + + priv->line = ret; + platform_set_drvdata(pdev, priv); + + return 0; +} + +static void airoha_8250_remove(struct platform_device *ofdev) +{ + struct airoha_8250_priv *priv = platform_get_drvdata(ofdev); + + serial8250_unregister_port(priv->line); +} + +static const struct airoha_8250_data en7523_data = { + .type = UART_PORT_AIROHA, +}; + +static const struct airoha_8250_data an7581_hs_data = { + .type = UART_PORT_AIROHA_HS, +}; + +static const struct of_device_id airoha_8250_dt_ids[] = { + { .compatible = "airoha,en7523-uart", .data = &en7523_data, }, + { .compatible = "airoha,an7581-hsuart", .data = &an7581_hs_data, }, + { }, +}; +MODULE_DEVICE_TABLE(of, airoha_8250_dt_ids); + +static struct platform_driver airoha_8250_driver = { + .driver = { + .name = "8250_airoha", + .of_match_table = airoha_8250_dt_ids, + }, + .probe = airoha_8250_probe, + .remove = airoha_8250_remove, +}; + +module_platform_driver(airoha_8250_driver); + +MODULE_LICENSE("GPL"); +MODULE_DESCRIPTION("Airoha UART driver"); +MODULE_AUTHOR("Benjamin Larsson <benjamin.larsson@genexis.eu>"); +MODULE_AUTHOR("Christian Marangi <ansuelsmth@gmail.com>"); diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c index a0b80324a559..29f0245264ec 100644 --- a/drivers/tty/serial/8250/8250_port.c +++ b/drivers/tty/serial/8250/8250_port.c @@ -311,6 +311,22 @@ static const struct serial8250_config uart_config[] = { .rxtrig_bytes = {1, 8, 16, 30}, .flags = UART_CAP_FIFO | UART_CAP_AFE, }, + [UART_PORT_AIROHA] = { + .name = "Airoha UART", + .fifo_size = 8, + .tx_loadsz = 1, + .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 | UART_FCR_CLEAR_RCVR, + .rxtrig_bytes = {1, 4}, + .flags = UART_CAP_FIFO, + }, + [UART_PORT_AIROHA_HS] = { + .name = "Airoha HSUART", + .fifo_size = 128, + .tx_loadsz = 128, + .fcr = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_01 | UART_FCR_CLEAR_RCVR, + .rxtrig_bytes = {1, 4}, + .flags = UART_CAP_FIFO, + }, }; /* Uart divisor latch read */ diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig index fc3e58d62233..310da7af7a49 100644 --- a/drivers/tty/serial/8250/Kconfig +++ b/drivers/tty/serial/8250/Kconfig @@ -337,6 +337,17 @@ config SERIAL_8250_ACORN system, say Y to this option. The driver can handle 1, 2, or 3 port cards. If unsure, say N. +config SERIAL_8250_AIROHA + tristate "Airoha UART support" + depends on ARCH_AIROHA || COMPILE_TEST + depends on SERIAL_8250 + help + Selecting this option enables an Airoha SoC specific baud rate + calculation routine on an otherwise 16550 compatible UART hardware. + + If you have an Airoha based board and want to use the serial port, + say Y to this option. If unsure, say N. + config SERIAL_8250_BCM2835AUX tristate "BCM2835 auxiliar mini UART support" depends on ARCH_BCM2835 || COMPILE_TEST diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile index 6d21402b4435..83257696ea8a 100644 --- a/drivers/tty/serial/8250/Makefile +++ b/drivers/tty/serial/8250/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_SERIAL_8250_CONSOLE) += 8250_early.o obj-$(CONFIG_SERIAL_8250_ACCENT) += 8250_accent.o obj-$(CONFIG_SERIAL_8250_ACORN) += 8250_acorn.o +obj-$(CONFIG_SERIAL_8250_AIROHA) += 8250_airoha.o obj-$(CONFIG_SERIAL_8250_ASPEED_VUART) += 8250_aspeed_vuart.o obj-$(CONFIG_SERIAL_8250_BCM2835AUX) += 8250_bcm2835aux.o obj-$(CONFIG_SERIAL_8250_BCM7271) += 8250_bcm7271.o -- 2.53.0 ^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH 4/4] serial: 8250: Add Airoha SoC UART and HSUART support 2026-07-09 20:56 ` [PATCH 4/4] serial: 8250: Add Airoha SoC UART and HSUART support Christian Marangi @ 2026-07-10 7:13 ` Jiri Slaby 0 siblings, 0 replies; 16+ messages in thread From: Jiri Slaby @ 2026-07-10 7:13 UTC (permalink / raw) To: Christian Marangi, Greg Kroah-Hartman, Rob Herring, Krzysztof Kozlowski, Conor Dooley, Ilpo Järvinen, Andy Shevchenko, Benjamin Larsson, John Ogness, Marco Felsch, Gerhard Engleder, Jiaxun Yang, Randy Dunlap, Binbin Zhou, Rong Zhang, Lukas Wunner, Lubomir Rintel, devicetree, linux-kernel, linux-serial On 09. 07. 26, 22:56, Christian Marangi wrote: ... > --- /dev/null > +++ b/drivers/tty/serial/8250/8250_airoha.c > @@ -0,0 +1,190 @@ ... > +struct airoha_8250_priv { > + int line; > +}; > + > +struct airoha_8250_data { Do you need this struct at all? Can't you pass the type as data directly (using cast)? > + unsigned int type; > +}; > + > +struct airoha_8250_clk_div_info { > + int div; > + int mask; Perhaps make them unsigned to avoid signed arithmetics? > +}; > + > +#define UART_BRDL_20M 0x01 > +#define UART_BRDH_20M 0x00 > + > +#define XINDIV_CLOCK 20000000 > +#define XYD_Y 65000 > + > +static const struct airoha_8250_clk_div_info airoha_clk_div_info[] = { > + { .div = 10, .mask = BIT(2) }, > + { .div = 4, .mask = BIT(1) }, > + { .div = 2, .mask = BIT(0) }, > +}; > + > +static const int clock_div_tab[] = { 10, 4, 2}; > +static const int clock_div_reg[] = { 4, 2, 1}; unsigned? > + > +/* > + * Airoha UART baud rate calculation logic > + * > + * crystal_clock = 20 MHz (fixed frequency) > + * xindiv_clock = crystal_clock / clock_div > + * (x/y) = XYD, 32 bit register with 16 bits of x and then 16 bits of y > + * clock_div = XINCLK_DIVCNT (default set to 10 (0x4)), > + * - 3 bit register [ 1, 2, 4, 8, 10, 12, 16, 20 ] > + * > + * baud_rate = ((xindiv_clock) * (x/y)) / ([BRDH,BRDL] * 16) > + * > + * Selecting divider needs to fulfill > + * 1.8432 MHz <= xindiv_clk <= APB clock / 2 > + * The clocks are unknown but a divider of value 1 did not result in a valid > + * waveform. > + * > + * XYD_y seems to need to be larger then XYD_x for proper waveform generation. > + * Setting [BRDH,BRDL] to [0,1] and XYD_y to 65000 gives even values > + * for usual baud rates. > + */ > +static void airoha_set_termios(struct uart_port *port, struct ktermios *termios, > + const struct ktermios *old) > +{ > + const struct airoha_8250_clk_div_info *clk_div_info; > + struct uart_8250_port *up = up_to_u8250p(port); > + unsigned int xyd_x, nom, denom; > + unsigned int baud; > + int i; > + > + serial8250_do_set_termios(port, termios, old); > + > + baud = serial8250_get_baud_rate(port, termios, old); > + > + /* Set DLAB to access the baud rate divider registers (BRDH, BRDL) */ > + serial_port_out(port, UART_LCR, up->lcr | UART_LCR_DLAB); > + > + /* Set baud rate calculation defaults (BRDIV ([BRDH,BRDL]) to 1) */ > + serial_port_out(port, UART_AIROHA_BRDL, UART_BRDL_20M); > + serial_port_out(port, UART_AIROHA_BRDH, UART_BRDH_20M); > + > + /* > + * Calculate XYD_x and XINCLKDR register by searching > + * through a table of crystal_clock divisors. > + */ > + for (i = 0 ; i < ARRAY_SIZE(airoha_clk_div_info) ; i++) { > + clk_div_info = &airoha_clk_div_info[i]; > + > + denom = (XINDIV_CLOCK / 40) / clk_div_info->div; > + nom = baud * (XYD_Y / 40); Are these "/ 40" to avoid overflow? Add a comment. > + xyd_x = ((nom / denom) << 4); * don't you want to round to closest instead of down? * I don't understand the purpose of the shift though. > + /* For the HSUART xyd_x needs to be scaled by a factor of 2 */ > + if (port->type == UART_PORT_AIROHA_HS) > + xyd_x = xyd_x >> 1; Do not use shifts for div/mul. > + if (xyd_x < XYD_Y) > + break; > + } > + > + serial_port_out(port, UART_AIROHA_XINCLKDR, clk_div_info->mask); > + serial_port_out(port, UART_AIROHA_XYD, (xyd_x << 16) | XYD_Y); > + > + /* unset DLAB */ > + serial_port_out(port, UART_LCR, up->lcr); > +} thanks, -- js suse labs ^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2026-07-10 16:43 UTC | newest] Thread overview: 16+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-07-09 20:56 [PATCH 0/4] serial: 8250: Add AN7581 UART support Christian Marangi 2026-07-09 20:56 ` [PATCH 1/4] dt-bindings: serial: 8250: Add Airoha compatibles Christian Marangi 2026-07-10 16:43 ` Conor Dooley 2026-07-09 20:56 ` [PATCH 2/4] serial: 8250: export serial8250_get_baud_rate() Christian Marangi 2026-07-09 21:35 ` Andy Shevchenko 2026-07-09 21:39 ` Christian Marangi 2026-07-10 8:20 ` Andy Shevchenko 2026-07-10 8:49 ` Christian Marangi 2026-07-10 9:14 ` Andy Shevchenko 2026-07-10 8:19 ` Ilpo Järvinen 2026-07-09 20:56 ` [PATCH 3/4] serial: 8250: map UAPI port type to internal enum Christian Marangi 2026-07-09 21:37 ` Andy Shevchenko 2026-07-09 21:46 ` Christian Marangi 2026-07-10 10:09 ` Andy Shevchenko 2026-07-09 20:56 ` [PATCH 4/4] serial: 8250: Add Airoha SoC UART and HSUART support Christian Marangi 2026-07-10 7:13 ` Jiri Slaby
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox