* [PATCH v4 0/2] serial: add KEBA UART driver
@ 2025-10-23 15:12 Gerhard Engleder
2025-10-23 15:12 ` [PATCH v4 1/2] serial: Keep rs485 settings for devices without firmware node Gerhard Engleder
2025-10-23 15:12 ` [PATCH v4 2/2] serial: 8250: add driver for KEBA UART Gerhard Engleder
0 siblings, 2 replies; 16+ messages in thread
From: Gerhard Engleder @ 2025-10-23 15:12 UTC (permalink / raw)
To: linux-serial; +Cc: gregkh, jirislaby, lukas, Gerhard Engleder
First the serial subsystem is prepared to keep rs485 settings from the
driver if no firmware node exists. This enables drivers to configure a
default rs485 mode, which is set by the serial subsystem.
Second the driver for the KEBA UART is added. This driver supports
multiple rs485 modes and selects RS485 as default mode. This UART is
found in KEBA PLC devices. The auxiliary devices for this driver are
created by the cp500 driver.
v4:
- fix spelling, exist -> exists (Lukas Wunner)
- remove duplicate include (Lukas Wunner)
- order includes alphabetically (Lukas Wunner)
v3:
- add info to commit why device tree / ACPI is not possible (Lukas Wunner)
- separate if and comment for change in uart_get_rs485_mode() (Lukas Wunner)
v2:
- use BIT() for flag definition (Jiri Slaby)
- use enum for UART mode definition (Jiri Slaby)
- use BIT() for capability flag definition (Jiri Slaby)
- use GENMASK() for capability mask (Jiri Slaby)
- use unsigned int for serial line number (Jiri Slaby)
- use unsigned int for flags (Jiri Slaby)
Gerhard Engleder (2):
serial: Keep rs485 settings for devices without firmware node
serial: 8250: add driver for KEBA UART
drivers/tty/serial/8250/8250_keba.c | 280 ++++++++++++++++++++++++++++
drivers/tty/serial/8250/Kconfig | 13 ++
drivers/tty/serial/8250/Makefile | 1 +
drivers/tty/serial/serial_core.c | 8 +
4 files changed, 302 insertions(+)
create mode 100644 drivers/tty/serial/8250/8250_keba.c
--
2.39.5
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH v4 1/2] serial: Keep rs485 settings for devices without firmware node
2025-10-23 15:12 [PATCH v4 0/2] serial: add KEBA UART driver Gerhard Engleder
@ 2025-10-23 15:12 ` Gerhard Engleder
2025-10-26 9:25 ` Lukas Wunner
2025-11-26 13:10 ` Andy Shevchenko
2025-10-23 15:12 ` [PATCH v4 2/2] serial: 8250: add driver for KEBA UART Gerhard Engleder
1 sibling, 2 replies; 16+ messages in thread
From: Gerhard Engleder @ 2025-10-23 15:12 UTC (permalink / raw)
To: linux-serial; +Cc: gregkh, jirislaby, lukas, Gerhard Engleder, Gerhard Engleder
From: Gerhard Engleder <eg@keba.com>
Commit fe7f0fa43cef ("serial: 8250: Support rs485 devicetree properties")
retrieves rs485 properties for 8250 drivers. These properties are read
from the firmware node of the device within uart_get_rs485_mode(). If the
firmware node does not exist, then the rs485 flags are still reset. Thus,
8250 driver cannot set rs485 flags to enable a defined rs485 mode during
driver loading. This is no problem so far, as no 8250 driver sets the
rs485 flags.
The default rs485 mode can also be set by firmware nodes. But for some
devices a firmware node does not exist. E.g., for a PCIe based serial
interface on x86 no device tree is available and the ACPI information of
the BIOS often cannot by modified. In this case it shall be possible,
that a driver works out of the box by setting a reasonable default rs485
mode.
If no firmware node exists, then it should be possible for the driver to
set a reasonable default rs485 mode. Therefore, reset rs485 flags only
if a firmware node exists.
Signed-off-by: Gerhard Engleder <eg@keba.com>
Cc: Lukas Wunner <lukas@wunner.de>
---
drivers/tty/serial/serial_core.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 4757293ece8c..70cac77cac61 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -3536,6 +3536,14 @@ int uart_get_rs485_mode(struct uart_port *port)
if (!(port->rs485_supported.flags & SER_RS485_ENABLED))
return 0;
+ /*
+ * Retrieve properties only if a firmware node exists. If no firmware
+ * node exists, then don't touch rs485 config and keep initial rs485
+ * properties set by driver.
+ */
+ if (!dev_fwnode(dev))
+ return 0;
+
ret = device_property_read_u32_array(dev, "rs485-rts-delay",
rs485_delay, 2);
if (!ret) {
--
2.39.5
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH v4 2/2] serial: 8250: add driver for KEBA UART
2025-10-23 15:12 [PATCH v4 0/2] serial: add KEBA UART driver Gerhard Engleder
2025-10-23 15:12 ` [PATCH v4 1/2] serial: Keep rs485 settings for devices without firmware node Gerhard Engleder
@ 2025-10-23 15:12 ` Gerhard Engleder
2025-10-26 9:30 ` Lukas Wunner
` (2 more replies)
1 sibling, 3 replies; 16+ messages in thread
From: Gerhard Engleder @ 2025-10-23 15:12 UTC (permalink / raw)
To: linux-serial
Cc: gregkh, jirislaby, lukas, Gerhard Engleder, Gerhard Engleder,
Daniel Gierlinger
From: Gerhard Engleder <eg@keba.com>
The KEBA UART is found in the system FPGA of KEBA PLC devices. It is
mostly 8250 compatible with extension for some UART modes.
3 different variants exist. The simpliest variant supports only RS-232
and is used for debug interfaces. The next variant supports only RS-485
and is used mostly for communication with KEBA panel devices. The third
variant is able to support RS-232, RS-485 and RS-422. For this variant
not only the mode of the UART is configured, also the physics and
transceivers are switched according to the mode.
Signed-off-by: Gerhard Engleder <eg@keba.com>
Tested-by: Daniel Gierlinger <gida@keba.com>
---
drivers/tty/serial/8250/8250_keba.c | 280 ++++++++++++++++++++++++++++
drivers/tty/serial/8250/Kconfig | 13 ++
drivers/tty/serial/8250/Makefile | 1 +
3 files changed, 294 insertions(+)
create mode 100644 drivers/tty/serial/8250/8250_keba.c
diff --git a/drivers/tty/serial/8250/8250_keba.c b/drivers/tty/serial/8250/8250_keba.c
new file mode 100644
index 000000000000..c05b89551b12
--- /dev/null
+++ b/drivers/tty/serial/8250/8250_keba.c
@@ -0,0 +1,280 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2025 KEBA Industrial Automation GmbH
+ *
+ * Driver for KEBA UART FPGA IP core
+ */
+
+#include <linux/auxiliary_bus.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/misc/keba.h>
+#include <linux/module.h>
+
+#include "8250.h"
+
+#define KUART "kuart"
+
+/* flags */
+#define KUART_RS485 BIT(0)
+#define KUART_USE_CAPABILITY BIT(1)
+
+/* registers */
+#define KUART_VERSION 0x0000
+#define KUART_REVISION 0x0001
+#define KUART_CAPABILITY 0x0002
+#define KUART_CONTROL 0x0004
+#define KUART_BASE 0x000C
+#define KUART_REGSHIFT 2
+#define KUART_CLK 1843200
+
+/* mode flags */
+enum kuart_mode {
+ KUART_MODE_NONE = 0,
+ KUART_MODE_RS485,
+ KUART_MODE_RS422,
+ KUART_MODE_RS232
+};
+
+/* capability flags */
+#define KUART_CAPABILITY_NONE BIT(KUART_MODE_NONE)
+#define KUART_CAPABILITY_RS485 BIT(KUART_MODE_RS485)
+#define KUART_CAPABILITY_RS422 BIT(KUART_MODE_RS422)
+#define KUART_CAPABILITY_RS232 BIT(KUART_MODE_RS232)
+#define KUART_CAPABILITY_MASK GENMASK(3, 0)
+
+/* Additional Control Register DTR line configuration */
+#define UART_ACR_DTRLC_MASK 0x18
+#define UART_ACR_DTRLC_COMPAT 0x00
+#define UART_ACR_DTRLC_ENABLE_LOW 0x10
+
+struct kuart {
+ struct keba_uart_auxdev *auxdev;
+ void __iomem *base;
+ unsigned int line;
+
+ unsigned int flags;
+ u8 capability;
+ enum kuart_mode mode;
+};
+
+static void kuart_set_phy_mode(struct kuart *kuart, enum kuart_mode mode)
+{
+ iowrite8(mode, kuart->base + KUART_CONTROL);
+}
+
+static void kuart_enhanced_mode(struct uart_8250_port *up, bool enable)
+{
+ u8 lcr, efr;
+
+ /* backup LCR register */
+ lcr = serial_in(up, UART_LCR);
+
+ /* enable 650 compatible register set (EFR, ...) */
+ serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
+
+ /* enable/disable enhanced mode with indexed control registers */
+ efr = serial_in(up, UART_EFR);
+ if (enable)
+ efr |= UART_EFR_ECB;
+ else
+ efr &= ~UART_EFR_ECB;
+ serial_out(up, UART_EFR, efr);
+
+ /* disable 650 compatible register set, restore LCR */
+ serial_out(up, UART_LCR, lcr);
+}
+
+static void kuart_dtr_line_config(struct uart_8250_port *up, u8 dtrlc)
+{
+ u8 acr;
+
+ /* set index register to 0 to access ACR register */
+ serial_out(up, UART_SCR, UART_ACR);
+
+ /* set value register to 0x10 writing DTR mode (1,0) */
+ acr = serial_in(up, UART_LSR);
+ acr &= ~UART_ACR_DTRLC_MASK;
+ acr |= dtrlc;
+ serial_out(up, UART_LSR, acr);
+}
+
+static int kuart_rs485_config(struct uart_port *port, struct ktermios *termios,
+ struct serial_rs485 *rs485)
+{
+ struct uart_8250_port *up = up_to_u8250p(port);
+ struct kuart *kuart = port->private_data;
+ enum kuart_mode mode;
+ u8 dtrlc;
+
+ if (rs485->flags & SER_RS485_ENABLED) {
+ if (rs485->flags & SER_RS485_MODE_RS422)
+ mode = KUART_MODE_RS422;
+ else
+ mode = KUART_MODE_RS485;
+ } else {
+ mode = KUART_MODE_RS232;
+ }
+
+ if (mode == kuart->mode)
+ return 0;
+
+ if (kuart->flags & KUART_USE_CAPABILITY) {
+ /* deactivate physical interface, break before make */
+ kuart_set_phy_mode(kuart, KUART_MODE_NONE);
+ }
+
+ if (mode == KUART_MODE_RS485) {
+ /*
+ * Set DTR line configuration of 95x UART to DTR mode (1,0).
+ * In this mode the DTR pin drives the active-low enable pin of
+ * an external RS485 buffer. The DTR pin will be forced low
+ * whenever the transmitter is not empty, otherwise DTR pin is
+ * high.
+ */
+ dtrlc = UART_ACR_DTRLC_ENABLE_LOW;
+ } else {
+ /*
+ * Set DTR line configuration of 95x UART to DTR mode (0,0).
+ * In this mode the DTR pin is compatible with 16C450, 16C550,
+ * 16C650 and 16c670 (i.e. normal).
+ */
+ dtrlc = UART_ACR_DTRLC_COMPAT;
+ }
+
+ kuart_enhanced_mode(up, true);
+ kuart_dtr_line_config(up, dtrlc);
+ kuart_enhanced_mode(up, false);
+
+ if (kuart->flags & KUART_USE_CAPABILITY) {
+ /* activate selected physical interface */
+ kuart_set_phy_mode(kuart, mode);
+ }
+
+ kuart->mode = mode;
+
+ return 0;
+}
+
+static int kuart_probe(struct auxiliary_device *auxdev,
+ const struct auxiliary_device_id *id)
+{
+ struct device *dev = &auxdev->dev;
+ struct uart_8250_port uart = {};
+ struct resource res;
+ struct kuart *kuart;
+ int retval;
+
+ kuart = devm_kzalloc(dev, sizeof(*kuart), GFP_KERNEL);
+ if (!kuart)
+ return -ENOMEM;
+ kuart->auxdev = container_of(auxdev, struct keba_uart_auxdev, auxdev);
+ kuart->flags = id->driver_data;
+ auxiliary_set_drvdata(auxdev, kuart);
+
+ /*
+ * map only memory in front of UART registers, UART registers will be
+ * mapped by serial port
+ */
+ res = kuart->auxdev->io;
+ res.end = res.start + KUART_BASE - 1;
+ kuart->base = devm_ioremap_resource(dev, &res);
+ if (IS_ERR(kuart->base))
+ return PTR_ERR(kuart->base);
+
+ if (kuart->flags & KUART_USE_CAPABILITY) {
+ /*
+ * supported modes are read from capability register, at least
+ * one mode other than none must be supported
+ */
+ kuart->capability = ioread8(kuart->base + KUART_CAPABILITY) &
+ KUART_CAPABILITY_MASK;
+ if ((kuart->capability & ~KUART_CAPABILITY_NONE) == 0)
+ return -EIO;
+ }
+
+ spin_lock_init(&uart.port.lock);
+ uart.port.dev = dev;
+ uart.port.mapbase = kuart->auxdev->io.start + KUART_BASE;
+ uart.port.irq = kuart->auxdev->irq;
+ uart.port.uartclk = KUART_CLK;
+ uart.port.private_data = kuart;
+
+ /* 8 bit registers are 32 bit aligned => shift register offset */
+ uart.port.iotype = UPIO_MEM32;
+ uart.port.regshift = KUART_REGSHIFT;
+
+ /*
+ * UART mixes 16550, 16750 and 16C950 (for RS485) standard => auto
+ * configuration works best
+ */
+ uart.port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF | UPF_IOREMAP;
+
+ /*
+ * UART supports RS485, RS422 and RS232 with switching of physical
+ * interface
+ */
+ uart.port.rs485_config = kuart_rs485_config;
+ if (kuart->flags & KUART_RS485) {
+ uart.port.rs485_supported.flags = SER_RS485_ENABLED |
+ SER_RS485_RTS_ON_SEND;
+ uart.port.rs485.flags = SER_RS485_ENABLED |
+ SER_RS485_RTS_ON_SEND;
+ }
+ if (kuart->flags & KUART_USE_CAPABILITY) {
+ /* default mode priority is RS485 > RS422 > RS232 */
+ if (kuart->capability & KUART_CAPABILITY_RS422) {
+ uart.port.rs485_supported.flags |= SER_RS485_ENABLED |
+ SER_RS485_RTS_ON_SEND |
+ SER_RS485_MODE_RS422;
+ uart.port.rs485.flags = SER_RS485_ENABLED |
+ SER_RS485_RTS_ON_SEND |
+ SER_RS485_MODE_RS422;
+ }
+ if (kuart->capability & KUART_CAPABILITY_RS485) {
+ uart.port.rs485_supported.flags |= SER_RS485_ENABLED |
+ SER_RS485_RTS_ON_SEND;
+ uart.port.rs485.flags = SER_RS485_ENABLED |
+ SER_RS485_RTS_ON_SEND;
+ }
+ }
+
+ retval = serial8250_register_8250_port(&uart);
+ if (retval < 0) {
+ dev_err(&auxdev->dev, "UART registration failed!\n");
+ return retval;
+ }
+ kuart->line = retval;
+
+ return 0;
+}
+
+static void kuart_remove(struct auxiliary_device *auxdev)
+{
+ struct kuart *kuart = auxiliary_get_drvdata(auxdev);
+
+ if (kuart->flags & KUART_USE_CAPABILITY)
+ kuart_set_phy_mode(kuart, KUART_MODE_NONE);
+
+ serial8250_unregister_port(kuart->line);
+}
+
+static const struct auxiliary_device_id kuart_devtype_aux[] = {
+ { .name = "keba.rs485-uart", .driver_data = KUART_RS485 },
+ { .name = "keba.rs232-uart", .driver_data = 0 },
+ { .name = "keba.uart", .driver_data = KUART_USE_CAPABILITY },
+ {}
+};
+MODULE_DEVICE_TABLE(auxiliary, kuart_devtype_aux);
+
+static struct auxiliary_driver kuart_driver_aux = {
+ .name = KUART,
+ .id_table = kuart_devtype_aux,
+ .probe = kuart_probe,
+ .remove = kuart_remove,
+};
+module_auxiliary_driver(kuart_driver_aux);
+
+MODULE_AUTHOR("Gerhard Engleder <eg@keba.com>");
+MODULE_DESCRIPTION("KEBA 8250 serial port driver");
+MODULE_LICENSE("GPL");
diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
index f64ef0819cd4..5c3e4bcb3b93 100644
--- a/drivers/tty/serial/8250/Kconfig
+++ b/drivers/tty/serial/8250/Kconfig
@@ -430,6 +430,19 @@ config SERIAL_8250_IOC3
behind the IOC3 device on those systems. Maximum baud speed is
38400bps using this driver.
+config SERIAL_8250_KEBA
+ tristate "Support for KEBA 8250 UART"
+ depends on SERIAL_8250
+ depends on KEBA_CP500
+ help
+ Selecting this option will add support for KEBA UARTs. These UARTs
+ are used for the serial interfaces of KEBA PLCs.
+
+ This driver can also be built as a module. If so, the module will
+ be called 8250_keba.
+
+ If unsure, say N.
+
config SERIAL_8250_RT288X
bool "Ralink RT288x/RT305x/RT3662/RT3883 serial port support"
depends on SERIAL_8250
diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile
index 513a0941c284..f7a463c9860a 100644
--- a/drivers/tty/serial/8250/Makefile
+++ b/drivers/tty/serial/8250/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o
obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
obj-$(CONFIG_SERIAL_8250_INGENIC) += 8250_ingenic.o
obj-$(CONFIG_SERIAL_8250_IOC3) += 8250_ioc3.o
+obj-$(CONFIG_SERIAL_8250_KEBA) += 8250_keba.o
obj-$(CONFIG_SERIAL_8250_LPC18XX) += 8250_lpc18xx.o
obj-$(CONFIG_SERIAL_8250_LPSS) += 8250_lpss.o
obj-$(CONFIG_SERIAL_8250_MEN_MCB) += 8250_men_mcb.o
--
2.39.5
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH v4 1/2] serial: Keep rs485 settings for devices without firmware node
2025-10-23 15:12 ` [PATCH v4 1/2] serial: Keep rs485 settings for devices without firmware node Gerhard Engleder
@ 2025-10-26 9:25 ` Lukas Wunner
2025-11-26 13:10 ` Andy Shevchenko
1 sibling, 0 replies; 16+ messages in thread
From: Lukas Wunner @ 2025-10-26 9:25 UTC (permalink / raw)
To: Gerhard Engleder; +Cc: linux-serial, gregkh, jirislaby, Gerhard Engleder
On Thu, Oct 23, 2025 at 05:12:28PM +0200, Gerhard Engleder wrote:
> Commit fe7f0fa43cef ("serial: 8250: Support rs485 devicetree properties")
> retrieves rs485 properties for 8250 drivers. These properties are read
> from the firmware node of the device within uart_get_rs485_mode(). If the
> firmware node does not exist, then the rs485 flags are still reset. Thus,
> 8250 driver cannot set rs485 flags to enable a defined rs485 mode during
> driver loading. This is no problem so far, as no 8250 driver sets the
> rs485 flags.
>
> The default rs485 mode can also be set by firmware nodes. But for some
> devices a firmware node does not exist. E.g., for a PCIe based serial
> interface on x86 no device tree is available and the ACPI information of
> the BIOS often cannot by modified. In this case it shall be possible,
> that a driver works out of the box by setting a reasonable default rs485
> mode.
>
> If no firmware node exists, then it should be possible for the driver to
> set a reasonable default rs485 mode. Therefore, reset rs485 flags only
> if a firmware node exists.
>
> Signed-off-by: Gerhard Engleder <eg@keba.com>
Reviewed-by: Lukas Wunner <lukas@wunner.de>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v4 2/2] serial: 8250: add driver for KEBA UART
2025-10-23 15:12 ` [PATCH v4 2/2] serial: 8250: add driver for KEBA UART Gerhard Engleder
@ 2025-10-26 9:30 ` Lukas Wunner
2025-11-26 13:17 ` Andy Shevchenko
2025-11-26 15:46 ` Ilpo Järvinen
2 siblings, 0 replies; 16+ messages in thread
From: Lukas Wunner @ 2025-10-26 9:30 UTC (permalink / raw)
To: Gerhard Engleder
Cc: linux-serial, gregkh, jirislaby, Gerhard Engleder,
Daniel Gierlinger
On Thu, Oct 23, 2025 at 05:12:29PM +0200, Gerhard Engleder wrote:
> The KEBA UART is found in the system FPGA of KEBA PLC devices. It is
> mostly 8250 compatible with extension for some UART modes.
>
> 3 different variants exist. The simpliest variant supports only RS-232
> and is used for debug interfaces. The next variant supports only RS-485
> and is used mostly for communication with KEBA panel devices. The third
> variant is able to support RS-232, RS-485 and RS-422. For this variant
> not only the mode of the UART is configured, also the physics and
> transceivers are switched according to the mode.
>
> Signed-off-by: Gerhard Engleder <eg@keba.com>
> Tested-by: Daniel Gierlinger <gida@keba.com>
Reviewed-by: Lukas Wunner <lukas@wunner.de>
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v4 1/2] serial: Keep rs485 settings for devices without firmware node
2025-10-23 15:12 ` [PATCH v4 1/2] serial: Keep rs485 settings for devices without firmware node Gerhard Engleder
2025-10-26 9:25 ` Lukas Wunner
@ 2025-11-26 13:10 ` Andy Shevchenko
2025-11-26 20:42 ` Gerhard Engleder
1 sibling, 1 reply; 16+ messages in thread
From: Andy Shevchenko @ 2025-11-26 13:10 UTC (permalink / raw)
To: Gerhard Engleder; +Cc: linux-serial, gregkh, jirislaby, lukas, Gerhard Engleder
On Thu, Oct 23, 2025 at 05:12:28PM +0200, Gerhard Engleder wrote:
>
> Commit fe7f0fa43cef ("serial: 8250: Support rs485 devicetree properties")
> retrieves rs485 properties for 8250 drivers. These properties are read
> from the firmware node of the device within uart_get_rs485_mode(). If the
> firmware node does not exist, then the rs485 flags are still reset. Thus,
> 8250 driver cannot set rs485 flags to enable a defined rs485 mode during
> driver loading. This is no problem so far, as no 8250 driver sets the
> rs485 flags.
>
> The default rs485 mode can also be set by firmware nodes. But for some
> devices a firmware node does not exist. E.g., for a PCIe based serial
> interface on x86 no device tree is available and the ACPI information of
> the BIOS often cannot by modified.
While the code is okay per se, the above statement is not fully true.
We specifically have device properties and software nodes to provide
the missing bits.
> In this case it shall be possible,
> that a driver works out of the box by setting a reasonable default rs485
> mode.
>
> If no firmware node exists, then it should be possible for the driver to
> set a reasonable default rs485 mode. Therefore, reset rs485 flags only
> if a firmware node exists.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v4 2/2] serial: 8250: add driver for KEBA UART
2025-10-23 15:12 ` [PATCH v4 2/2] serial: 8250: add driver for KEBA UART Gerhard Engleder
2025-10-26 9:30 ` Lukas Wunner
@ 2025-11-26 13:17 ` Andy Shevchenko
2025-11-26 21:06 ` Gerhard Engleder
2025-11-26 15:46 ` Ilpo Järvinen
2 siblings, 1 reply; 16+ messages in thread
From: Andy Shevchenko @ 2025-11-26 13:17 UTC (permalink / raw)
To: Gerhard Engleder
Cc: linux-serial, gregkh, jirislaby, lukas, Gerhard Engleder,
Daniel Gierlinger
On Thu, Oct 23, 2025 at 05:12:29PM +0200, Gerhard Engleder wrote:
>
> The KEBA UART is found in the system FPGA of KEBA PLC devices. It is
> mostly 8250 compatible with extension for some UART modes.
>
> 3 different variants exist. The simpliest variant supports only RS-232
> and is used for debug interfaces. The next variant supports only RS-485
> and is used mostly for communication with KEBA panel devices. The third
> variant is able to support RS-232, RS-485 and RS-422. For this variant
> not only the mode of the UART is configured, also the physics and
> transceivers are switched according to the mode.
...
> +#include <linux/auxiliary_bus.h>
+ bits.h
+ container_of.h
> +#include <linux/device.h>
I don't see how it's being used.
What I see are
+ dev_printk.h
+ device/devres.h
+ err.h
> +#include <linux/io.h>
> +#include <linux/misc/keba.h>
+ mod_devicetable.h
> +#include <linux/module.h>
+ spinlock.h
+ types.h
...
> +static int kuart_probe(struct auxiliary_device *auxdev,
> + const struct auxiliary_device_id *id)
> +{
> + struct device *dev = &auxdev->dev;
> + struct uart_8250_port uart = {};
> + struct resource res;
> + struct kuart *kuart;
> + int retval;
> +
> + kuart = devm_kzalloc(dev, sizeof(*kuart), GFP_KERNEL);
> + if (!kuart)
> + return -ENOMEM;
> + kuart->auxdev = container_of(auxdev, struct keba_uart_auxdev, auxdev);
> + kuart->flags = id->driver_data;
> + auxiliary_set_drvdata(auxdev, kuart);
> +
> + /*
> + * map only memory in front of UART registers, UART registers will be
> + * mapped by serial port
> + */
> + res = kuart->auxdev->io;
> + res.end = res.start + KUART_BASE - 1;
> + kuart->base = devm_ioremap_resource(dev, &res);
> + if (IS_ERR(kuart->base))
> + return PTR_ERR(kuart->base);
> +
> + if (kuart->flags & KUART_USE_CAPABILITY) {
> + /*
> + * supported modes are read from capability register, at least
> + * one mode other than none must be supported
> + */
> + kuart->capability = ioread8(kuart->base + KUART_CAPABILITY) &
> + KUART_CAPABILITY_MASK;
> + if ((kuart->capability & ~KUART_CAPABILITY_NONE) == 0)
> + return -EIO;
> + }
> +
> + spin_lock_init(&uart.port.lock);
> + uart.port.dev = dev;
> + uart.port.mapbase = kuart->auxdev->io.start + KUART_BASE;
> + uart.port.irq = kuart->auxdev->irq;
> + uart.port.uartclk = KUART_CLK;
> + uart.port.private_data = kuart;
> +
> + /* 8 bit registers are 32 bit aligned => shift register offset */
> + uart.port.iotype = UPIO_MEM32;
> + uart.port.regshift = KUART_REGSHIFT;
Can't you call uart_read_port_properties()?
If ever you gain some properties either via FW description or via software
nodes, they will be automatically used without need to update the driver!
> + /*
> + * UART mixes 16550, 16750 and 16C950 (for RS485) standard => auto
> + * configuration works best
> + */
> + uart.port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF | UPF_IOREMAP;
> +
> + /*
> + * UART supports RS485, RS422 and RS232 with switching of physical
> + * interface
> + */
> + uart.port.rs485_config = kuart_rs485_config;
> + if (kuart->flags & KUART_RS485) {
> + uart.port.rs485_supported.flags = SER_RS485_ENABLED |
> + SER_RS485_RTS_ON_SEND;
> + uart.port.rs485.flags = SER_RS485_ENABLED |
> + SER_RS485_RTS_ON_SEND;
> + }
> + if (kuart->flags & KUART_USE_CAPABILITY) {
> + /* default mode priority is RS485 > RS422 > RS232 */
> + if (kuart->capability & KUART_CAPABILITY_RS422) {
> + uart.port.rs485_supported.flags |= SER_RS485_ENABLED |
> + SER_RS485_RTS_ON_SEND |
> + SER_RS485_MODE_RS422;
> + uart.port.rs485.flags = SER_RS485_ENABLED |
> + SER_RS485_RTS_ON_SEND |
> + SER_RS485_MODE_RS422;
> + }
> + if (kuart->capability & KUART_CAPABILITY_RS485) {
> + uart.port.rs485_supported.flags |= SER_RS485_ENABLED |
> + SER_RS485_RTS_ON_SEND;
> + uart.port.rs485.flags = SER_RS485_ENABLED |
> + SER_RS485_RTS_ON_SEND;
> + }
> + }
> +
> + retval = serial8250_register_8250_port(&uart);
> + if (retval < 0) {
> + dev_err(&auxdev->dev, "UART registration failed!\n");
> + return retval;
return dev_err_probe(...);
> + }
> + kuart->line = retval;
> +
> + return 0;
> +}
...
Since driver is about to be applied to serial-next, I suggest to send a
followup(s) to address my comments.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v4 2/2] serial: 8250: add driver for KEBA UART
2025-10-23 15:12 ` [PATCH v4 2/2] serial: 8250: add driver for KEBA UART Gerhard Engleder
2025-10-26 9:30 ` Lukas Wunner
2025-11-26 13:17 ` Andy Shevchenko
@ 2025-11-26 15:46 ` Ilpo Järvinen
2025-11-26 21:30 ` Gerhard Engleder
2 siblings, 1 reply; 16+ messages in thread
From: Ilpo Järvinen @ 2025-11-26 15:46 UTC (permalink / raw)
To: Gerhard Engleder
Cc: linux-serial, Greg Kroah-Hartman, Jiri Slaby, Lukas Wunner,
Gerhard Engleder, Daniel Gierlinger
On Thu, 23 Oct 2025, Gerhard Engleder wrote:
> From: Gerhard Engleder <eg@keba.com>
>
> The KEBA UART is found in the system FPGA of KEBA PLC devices. It is
> mostly 8250 compatible with extension for some UART modes.
>
> 3 different variants exist. The simpliest variant supports only RS-232
> and is used for debug interfaces. The next variant supports only RS-485
> and is used mostly for communication with KEBA panel devices. The third
> variant is able to support RS-232, RS-485 and RS-422. For this variant
> not only the mode of the UART is configured, also the physics and
> transceivers are switched according to the mode.
>
> Signed-off-by: Gerhard Engleder <eg@keba.com>
> Tested-by: Daniel Gierlinger <gida@keba.com>
> ---
> drivers/tty/serial/8250/8250_keba.c | 280 ++++++++++++++++++++++++++++
> drivers/tty/serial/8250/Kconfig | 13 ++
> drivers/tty/serial/8250/Makefile | 1 +
> 3 files changed, 294 insertions(+)
> create mode 100644 drivers/tty/serial/8250/8250_keba.c
>
> diff --git a/drivers/tty/serial/8250/8250_keba.c b/drivers/tty/serial/8250/8250_keba.c
> new file mode 100644
> index 000000000000..c05b89551b12
> --- /dev/null
> +++ b/drivers/tty/serial/8250/8250_keba.c
> @@ -0,0 +1,280 @@
> +// SPDX-License-Identifier: GPL-2.0
> +/*
> + * Copyright (C) 2025 KEBA Industrial Automation GmbH
> + *
> + * Driver for KEBA UART FPGA IP core
> + */
> +
> +#include <linux/auxiliary_bus.h>
> +#include <linux/device.h>
> +#include <linux/io.h>
> +#include <linux/misc/keba.h>
> +#include <linux/module.h>
+ linux/serial_core.h
> +
> +#include "8250.h"
> +
> +#define KUART "kuart"
> +
> +/* flags */
> +#define KUART_RS485 BIT(0)
> +#define KUART_USE_CAPABILITY BIT(1)
> +
> +/* registers */
> +#define KUART_VERSION 0x0000
> +#define KUART_REVISION 0x0001
> +#define KUART_CAPABILITY 0x0002
> +#define KUART_CONTROL 0x0004
> +#define KUART_BASE 0x000C
> +#define KUART_REGSHIFT 2
> +#define KUART_CLK 1843200
> +
> +/* mode flags */
> +enum kuart_mode {
> + KUART_MODE_NONE = 0,
> + KUART_MODE_RS485,
> + KUART_MODE_RS422,
> + KUART_MODE_RS232
> +};
> +
> +/* capability flags */
> +#define KUART_CAPABILITY_NONE BIT(KUART_MODE_NONE)
> +#define KUART_CAPABILITY_RS485 BIT(KUART_MODE_RS485)
> +#define KUART_CAPABILITY_RS422 BIT(KUART_MODE_RS422)
> +#define KUART_CAPABILITY_RS232 BIT(KUART_MODE_RS232)
> +#define KUART_CAPABILITY_MASK GENMASK(3, 0)
> +
> +/* Additional Control Register DTR line configuration */
> +#define UART_ACR_DTRLC_MASK 0x18
> +#define UART_ACR_DTRLC_COMPAT 0x00
> +#define UART_ACR_DTRLC_ENABLE_LOW 0x10
> +
> +struct kuart {
> + struct keba_uart_auxdev *auxdev;
> + void __iomem *base;
> + unsigned int line;
> +
> + unsigned int flags;
> + u8 capability;
> + enum kuart_mode mode;
> +};
> +
> +static void kuart_set_phy_mode(struct kuart *kuart, enum kuart_mode mode)
> +{
> + iowrite8(mode, kuart->base + KUART_CONTROL);
> +}
> +
> +static void kuart_enhanced_mode(struct uart_8250_port *up, bool enable)
> +{
> + u8 lcr, efr;
> +
> + /* backup LCR register */
Save + restore is quite obvious thing. IMO, no comment is needed about it.
> + lcr = serial_in(up, UART_LCR);
> +
> + /* enable 650 compatible register set (EFR, ...) */
> + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
> +
> + /* enable/disable enhanced mode with indexed control registers */
> + efr = serial_in(up, UART_EFR);
> + if (enable)
> + efr |= UART_EFR_ECB;
> + else
> + efr &= ~UART_EFR_ECB;
> + serial_out(up, UART_EFR, efr);
> +
> + /* disable 650 compatible register set, restore LCR */
> + serial_out(up, UART_LCR, lcr);
> +}
> +
> +static void kuart_dtr_line_config(struct uart_8250_port *up, u8 dtrlc)
> +{
> + u8 acr;
> +
> + /* set index register to 0 to access ACR register */
> + serial_out(up, UART_SCR, UART_ACR);
So the scratch register has some special use on this UART (register
multiplexer?), it would probably better name it with define, if that's the
case.
> +
> + /* set value register to 0x10 writing DTR mode (1,0) */
> + acr = serial_in(up, UART_LSR);
> + acr &= ~UART_ACR_DTRLC_MASK;
> + acr |= dtrlc;
> + serial_out(up, UART_LSR, acr);
> +}
> +
> +static int kuart_rs485_config(struct uart_port *port, struct ktermios *termios,
> + struct serial_rs485 *rs485)
> +{
> + struct uart_8250_port *up = up_to_u8250p(port);
> + struct kuart *kuart = port->private_data;
> + enum kuart_mode mode;
> + u8 dtrlc;
> +
> + if (rs485->flags & SER_RS485_ENABLED) {
> + if (rs485->flags & SER_RS485_MODE_RS422)
> + mode = KUART_MODE_RS422;
> + else
> + mode = KUART_MODE_RS485;
> + } else {
> + mode = KUART_MODE_RS232;
> + }
> +
> + if (mode == kuart->mode)
> + return 0;
> +
> + if (kuart->flags & KUART_USE_CAPABILITY) {
> + /* deactivate physical interface, break before make */
> + kuart_set_phy_mode(kuart, KUART_MODE_NONE);
> + }
> +
> + if (mode == KUART_MODE_RS485) {
> + /*
> + * Set DTR line configuration of 95x UART to DTR mode (1,0).
> + * In this mode the DTR pin drives the active-low enable pin of
> + * an external RS485 buffer. The DTR pin will be forced low
> + * whenever the transmitter is not empty, otherwise DTR pin is
> + * high.
> + */
> + dtrlc = UART_ACR_DTRLC_ENABLE_LOW;
> + } else {
> + /*
> + * Set DTR line configuration of 95x UART to DTR mode (0,0).
> + * In this mode the DTR pin is compatible with 16C450, 16C550,
> + * 16C650 and 16c670 (i.e. normal).
> + */
> + dtrlc = UART_ACR_DTRLC_COMPAT;
> + }
> +
> + kuart_enhanced_mode(up, true);
> + kuart_dtr_line_config(up, dtrlc);
> + kuart_enhanced_mode(up, false);
> +
> + if (kuart->flags & KUART_USE_CAPABILITY) {
> + /* activate selected physical interface */
> + kuart_set_phy_mode(kuart, mode);
> + }
> +
> + kuart->mode = mode;
> +
> + return 0;
> +}
> +
> +static int kuart_probe(struct auxiliary_device *auxdev,
> + const struct auxiliary_device_id *id)
> +{
> + struct device *dev = &auxdev->dev;
> + struct uart_8250_port uart = {};
> + struct resource res;
> + struct kuart *kuart;
> + int retval;
> +
> + kuart = devm_kzalloc(dev, sizeof(*kuart), GFP_KERNEL);
> + if (!kuart)
> + return -ENOMEM;
> + kuart->auxdev = container_of(auxdev, struct keba_uart_auxdev, auxdev);
> + kuart->flags = id->driver_data;
> + auxiliary_set_drvdata(auxdev, kuart);
> +
> + /*
> + * map only memory in front of UART registers, UART registers will be
> + * mapped by serial port
> + */
> + res = kuart->auxdev->io;
> + res.end = res.start + KUART_BASE - 1;
> + kuart->base = devm_ioremap_resource(dev, &res);
> + if (IS_ERR(kuart->base))
> + return PTR_ERR(kuart->base);
> +
> + if (kuart->flags & KUART_USE_CAPABILITY) {
> + /*
> + * supported modes are read from capability register, at least
> + * one mode other than none must be supported
> + */
> + kuart->capability = ioread8(kuart->base + KUART_CAPABILITY) &
> + KUART_CAPABILITY_MASK;
> + if ((kuart->capability & ~KUART_CAPABILITY_NONE) == 0)
> + return -EIO;
> + }
> +
> + spin_lock_init(&uart.port.lock);
> + uart.port.dev = dev;
> + uart.port.mapbase = kuart->auxdev->io.start + KUART_BASE;
> + uart.port.irq = kuart->auxdev->irq;
> + uart.port.uartclk = KUART_CLK;
> + uart.port.private_data = kuart;
> +
> + /* 8 bit registers are 32 bit aligned => shift register offset */
> + uart.port.iotype = UPIO_MEM32;
> + uart.port.regshift = KUART_REGSHIFT;
> +
> + /*
> + * UART mixes 16550, 16750 and 16C950 (for RS485) standard => auto
> + * configuration works best
> + */
> + uart.port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF | UPF_IOREMAP;
> +
> + /*
> + * UART supports RS485, RS422 and RS232 with switching of physical
> + * interface
> + */
> + uart.port.rs485_config = kuart_rs485_config;
> + if (kuart->flags & KUART_RS485) {
> + uart.port.rs485_supported.flags = SER_RS485_ENABLED |
> + SER_RS485_RTS_ON_SEND;
> + uart.port.rs485.flags = SER_RS485_ENABLED |
> + SER_RS485_RTS_ON_SEND;
> + }
> + if (kuart->flags & KUART_USE_CAPABILITY) {
> + /* default mode priority is RS485 > RS422 > RS232 */
> + if (kuart->capability & KUART_CAPABILITY_RS422) {
> + uart.port.rs485_supported.flags |= SER_RS485_ENABLED |
> + SER_RS485_RTS_ON_SEND |
> + SER_RS485_MODE_RS422;
> + uart.port.rs485.flags = SER_RS485_ENABLED |
> + SER_RS485_RTS_ON_SEND |
> + SER_RS485_MODE_RS422;
> + }
> + if (kuart->capability & KUART_CAPABILITY_RS485) {
> + uart.port.rs485_supported.flags |= SER_RS485_ENABLED |
> + SER_RS485_RTS_ON_SEND;
> + uart.port.rs485.flags = SER_RS485_ENABLED |
> + SER_RS485_RTS_ON_SEND;
> + }
> + }
Is it so that only one mode is supported or can that be changes using
kuart_rs485_config() in which case you should have all flags listed (you
seem to talk about priority so that sounds like all are supported)?
> +
> + retval = serial8250_register_8250_port(&uart);
> + if (retval < 0) {
> + dev_err(&auxdev->dev, "UART registration failed!\n");
Missing header.
> + return retval;
> + }
> + kuart->line = retval;
> +
> + return 0;
> +}
> +
> +static void kuart_remove(struct auxiliary_device *auxdev)
> +{
> + struct kuart *kuart = auxiliary_get_drvdata(auxdev);
> +
> + if (kuart->flags & KUART_USE_CAPABILITY)
> + kuart_set_phy_mode(kuart, KUART_MODE_NONE);
> +
> + serial8250_unregister_port(kuart->line);
> +}
> +
> +static const struct auxiliary_device_id kuart_devtype_aux[] = {
> + { .name = "keba.rs485-uart", .driver_data = KUART_RS485 },
> + { .name = "keba.rs232-uart", .driver_data = 0 },
> + { .name = "keba.uart", .driver_data = KUART_USE_CAPABILITY },
> + {}
> +};
> +MODULE_DEVICE_TABLE(auxiliary, kuart_devtype_aux);
> +
> +static struct auxiliary_driver kuart_driver_aux = {
> + .name = KUART,
> + .id_table = kuart_devtype_aux,
> + .probe = kuart_probe,
> + .remove = kuart_remove,
> +};
> +module_auxiliary_driver(kuart_driver_aux);
> +
> +MODULE_AUTHOR("Gerhard Engleder <eg@keba.com>");
> +MODULE_DESCRIPTION("KEBA 8250 serial port driver");
> +MODULE_LICENSE("GPL");
> diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
> index f64ef0819cd4..5c3e4bcb3b93 100644
> --- a/drivers/tty/serial/8250/Kconfig
> +++ b/drivers/tty/serial/8250/Kconfig
> @@ -430,6 +430,19 @@ config SERIAL_8250_IOC3
> behind the IOC3 device on those systems. Maximum baud speed is
> 38400bps using this driver.
>
> +config SERIAL_8250_KEBA
> + tristate "Support for KEBA 8250 UART"
> + depends on SERIAL_8250
> + depends on KEBA_CP500
> + help
> + Selecting this option will add support for KEBA UARTs. These UARTs
> + are used for the serial interfaces of KEBA PLCs.
> +
> + This driver can also be built as a module. If so, the module will
> + be called 8250_keba.
> +
> + If unsure, say N.
> +
> config SERIAL_8250_RT288X
> bool "Ralink RT288x/RT305x/RT3662/RT3883 serial port support"
> depends on SERIAL_8250
> diff --git a/drivers/tty/serial/8250/Makefile b/drivers/tty/serial/8250/Makefile
> index 513a0941c284..f7a463c9860a 100644
> --- a/drivers/tty/serial/8250/Makefile
> +++ b/drivers/tty/serial/8250/Makefile
> @@ -38,6 +38,7 @@ obj-$(CONFIG_SERIAL_8250_HP300) += 8250_hp300.o
> obj-$(CONFIG_SERIAL_8250_HUB6) += 8250_hub6.o
> obj-$(CONFIG_SERIAL_8250_INGENIC) += 8250_ingenic.o
> obj-$(CONFIG_SERIAL_8250_IOC3) += 8250_ioc3.o
> +obj-$(CONFIG_SERIAL_8250_KEBA) += 8250_keba.o
> obj-$(CONFIG_SERIAL_8250_LPC18XX) += 8250_lpc18xx.o
> obj-$(CONFIG_SERIAL_8250_LPSS) += 8250_lpss.o
> obj-$(CONFIG_SERIAL_8250_MEN_MCB) += 8250_men_mcb.o
>
--
i.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v4 1/2] serial: Keep rs485 settings for devices without firmware node
2025-11-26 13:10 ` Andy Shevchenko
@ 2025-11-26 20:42 ` Gerhard Engleder
0 siblings, 0 replies; 16+ messages in thread
From: Gerhard Engleder @ 2025-11-26 20:42 UTC (permalink / raw)
To: Andy Shevchenko; +Cc: linux-serial, gregkh, jirislaby, lukas, Gerhard Engleder
On 26.11.25 14:10, Andy Shevchenko wrote:
> On Thu, Oct 23, 2025 at 05:12:28PM +0200, Gerhard Engleder wrote:
>>
>> Commit fe7f0fa43cef ("serial: 8250: Support rs485 devicetree properties")
>> retrieves rs485 properties for 8250 drivers. These properties are read
>> from the firmware node of the device within uart_get_rs485_mode(). If the
>> firmware node does not exist, then the rs485 flags are still reset. Thus,
>> 8250 driver cannot set rs485 flags to enable a defined rs485 mode during
>> driver loading. This is no problem so far, as no 8250 driver sets the
>> rs485 flags.
>>
>> The default rs485 mode can also be set by firmware nodes. But for some
>> devices a firmware node does not exist. E.g., for a PCIe based serial
>> interface on x86 no device tree is available and the ACPI information of
>> the BIOS often cannot by modified.
>
> While the code is okay per se, the above statement is not fully true.
> We specifically have device properties and software nodes to provide
> the missing bits.
Yes, Lukas Wunner teached me that possibility. I did not mention this
alternative solution in the commit, because I did not use it.
Gerhard
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v4 2/2] serial: 8250: add driver for KEBA UART
2025-11-26 13:17 ` Andy Shevchenko
@ 2025-11-26 21:06 ` Gerhard Engleder
2025-11-26 21:33 ` Andy Shevchenko
0 siblings, 1 reply; 16+ messages in thread
From: Gerhard Engleder @ 2025-11-26 21:06 UTC (permalink / raw)
To: Andy Shevchenko
Cc: linux-serial, gregkh, jirislaby, lukas, Gerhard Engleder,
Daniel Gierlinger
On 26.11.25 14:17, Andy Shevchenko wrote:
> On Thu, Oct 23, 2025 at 05:12:29PM +0200, Gerhard Engleder wrote:
>>
>> The KEBA UART is found in the system FPGA of KEBA PLC devices. It is
>> mostly 8250 compatible with extension for some UART modes.
>>
>> 3 different variants exist. The simpliest variant supports only RS-232
>> and is used for debug interfaces. The next variant supports only RS-485
>> and is used mostly for communication with KEBA panel devices. The third
>> variant is able to support RS-232, RS-485 and RS-422. For this variant
>> not only the mode of the UART is configured, also the physics and
>> transceivers are switched according to the mode.
>
> ...
>
>> +#include <linux/auxiliary_bus.h>
>
> + bits.h
> + container_of.h
>
>> +#include <linux/device.h>
>
> I don't see how it's being used.
> What I see are
>
> + dev_printk.h
> + device/devres.h
>
> + err.h
>
>> +#include <linux/io.h>
>> +#include <linux/misc/keba.h>
>
> + mod_devicetable.h
>
>> +#include <linux/module.h>
>
> + spinlock.h
> + types.h
Is there any extra tool to check for missing headers? Or do I have to
check the header for every used function?
>> +static int kuart_probe(struct auxiliary_device *auxdev,
>> + const struct auxiliary_device_id *id)
>> +{
...
>> + spin_lock_init(&uart.port.lock);
>> + uart.port.dev = dev;
>> + uart.port.mapbase = kuart->auxdev->io.start + KUART_BASE;
>> + uart.port.irq = kuart->auxdev->irq;
>> + uart.port.uartclk = KUART_CLK;
>> + uart.port.private_data = kuart;
>> +
>> + /* 8 bit registers are 32 bit aligned => shift register offset */
>> + uart.port.iotype = UPIO_MEM32;
>> + uart.port.regshift = KUART_REGSHIFT;
>
> Can't you call uart_read_port_properties()?
>
> If ever you gain some properties either via FW description or via software
> nodes, they will be automatically used without need to update the driver!
Yes that would be some nice behavior. But __uart_read_properties()
sets some defaults even if no firmware node exist (UPF_SHARE_IRQ, 0 as
irq number or it fails if not irq number is found). So
__uart_read_properties() would need to be changed. IMO it makes no sense
to change __uart_read_properties() as this functionality is currently
not required.
>
>> + /*
>> + * UART mixes 16550, 16750 and 16C950 (for RS485) standard => auto
>> + * configuration works best
...
>> + }
>> +
>> + retval = serial8250_register_8250_port(&uart);
>> + if (retval < 0) {
>
>> + dev_err(&auxdev->dev, "UART registration failed!\n");
>> + return retval;
>
> return dev_err_probe(...);
Yes that's simpler.
>
>> + }
>> + kuart->line = retval;
>> +
>> + return 0;
>> +}
>
> ...
>
> Since driver is about to be applied to serial-next, I suggest to send a
> followup(s) to address my comments.
I will do a follow up.
Gerhard
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v4 2/2] serial: 8250: add driver for KEBA UART
2025-11-26 15:46 ` Ilpo Järvinen
@ 2025-11-26 21:30 ` Gerhard Engleder
2025-11-27 9:28 ` Ilpo Järvinen
0 siblings, 1 reply; 16+ messages in thread
From: Gerhard Engleder @ 2025-11-26 21:30 UTC (permalink / raw)
To: Ilpo Järvinen
Cc: linux-serial, Greg Kroah-Hartman, Jiri Slaby, Lukas Wunner,
Gerhard Engleder, Daniel Gierlinger
On 26.11.25 16:46, Ilpo Järvinen wrote:
> On Thu, 23 Oct 2025, Gerhard Engleder wrote:
>
>> From: Gerhard Engleder <eg@keba.com>
>>
>> The KEBA UART is found in the system FPGA of KEBA PLC devices. It is
>> mostly 8250 compatible with extension for some UART modes.
>>
>> 3 different variants exist. The simpliest variant supports only RS-232
>> and is used for debug interfaces. The next variant supports only RS-485
>> and is used mostly for communication with KEBA panel devices. The third
>> variant is able to support RS-232, RS-485 and RS-422. For this variant
>> not only the mode of the UART is configured, also the physics and
>> transceivers are switched according to the mode.
>>
>> Signed-off-by: Gerhard Engleder <eg@keba.com>
>> Tested-by: Daniel Gierlinger <gida@keba.com>
>> ---
>> drivers/tty/serial/8250/8250_keba.c | 280 ++++++++++++++++++++++++++++
>> drivers/tty/serial/8250/Kconfig | 13 ++
>> drivers/tty/serial/8250/Makefile | 1 +
>> 3 files changed, 294 insertions(+)
>> create mode 100644 drivers/tty/serial/8250/8250_keba.c
>>
>> diff --git a/drivers/tty/serial/8250/8250_keba.c b/drivers/tty/serial/8250/8250_keba.c
>> new file mode 100644
>> index 000000000000..c05b89551b12
>> --- /dev/null
>> +++ b/drivers/tty/serial/8250/8250_keba.c
>> @@ -0,0 +1,280 @@
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * Copyright (C) 2025 KEBA Industrial Automation GmbH
>> + *
>> + * Driver for KEBA UART FPGA IP core
>> + */
>> +
>> +#include <linux/auxiliary_bus.h>
>> +#include <linux/device.h>
>> +#include <linux/io.h>
>> +#include <linux/misc/keba.h>
>> +#include <linux/module.h>
>
> + linux/serial_core.h
Is this really necessary even with the include of 8250.h below?
>> +
>> +#include "8250.h"
>> +
>> +#define KUART "kuart"
...
>> +static void kuart_enhanced_mode(struct uart_8250_port *up, bool enable)
>> +{
>> + u8 lcr, efr;
>> +
>> + /* backup LCR register */
>
> Save + restore is quite obvious thing. IMO, no comment is needed about it.
Yes it could be ommited. The patch is already merged, so I would keep
it. Ok?
>> + lcr = serial_in(up, UART_LCR);
>> +
>> + /* enable 650 compatible register set (EFR, ...) */
>> + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
>> +
>> + /* enable/disable enhanced mode with indexed control registers */
>> + efr = serial_in(up, UART_EFR);
>> + if (enable)
>> + efr |= UART_EFR_ECB;
>> + else
>> + efr &= ~UART_EFR_ECB;
>> + serial_out(up, UART_EFR, efr);
>> +
>> + /* disable 650 compatible register set, restore LCR */
>> + serial_out(up, UART_LCR, lcr);
>> +}
>> +
>> +static void kuart_dtr_line_config(struct uart_8250_port *up, u8 dtrlc)
>> +{
>> + u8 acr;
>> +
>> + /* set index register to 0 to access ACR register */
>> + serial_out(up, UART_SCR, UART_ACR);
>
> So the scratch register has some special use on this UART (register
> multiplexer?), it would probably better name it with define, if that's the
> case.
This UART supports an enhanced mode, which changes the behavior of some
registers. But the register still have their normal use with enhanced
mode disabled. So I would keep the register name.
>> +
>> + /* set value register to 0x10 writing DTR mode (1,0) */
>> + acr = serial_in(up, UART_LSR);
>> + acr &= ~UART_ACR_DTRLC_MASK;
>> + acr |= dtrlc;
>> + serial_out(up, UART_LSR, acr);
>> +}
...
>> + /*
>> + * UART supports RS485, RS422 and RS232 with switching of physical
>> + * interface
>> + */
>> + uart.port.rs485_config = kuart_rs485_config;
>> + if (kuart->flags & KUART_RS485) {
>> + uart.port.rs485_supported.flags = SER_RS485_ENABLED |
>> + SER_RS485_RTS_ON_SEND;
>> + uart.port.rs485.flags = SER_RS485_ENABLED |
>> + SER_RS485_RTS_ON_SEND;
>> + }
>> + if (kuart->flags & KUART_USE_CAPABILITY) {
>> + /* default mode priority is RS485 > RS422 > RS232 */
>> + if (kuart->capability & KUART_CAPABILITY_RS422) {
>> + uart.port.rs485_supported.flags |= SER_RS485_ENABLED |
>> + SER_RS485_RTS_ON_SEND |
>> + SER_RS485_MODE_RS422;
>> + uart.port.rs485.flags = SER_RS485_ENABLED |
>> + SER_RS485_RTS_ON_SEND |
>> + SER_RS485_MODE_RS422;
>> + }
>> + if (kuart->capability & KUART_CAPABILITY_RS485) {
>> + uart.port.rs485_supported.flags |= SER_RS485_ENABLED |
>> + SER_RS485_RTS_ON_SEND;
>> + uart.port.rs485.flags = SER_RS485_ENABLED |
>> + SER_RS485_RTS_ON_SEND;
>> + }
>> + }
>
> Is it so that only one mode is supported or can that be changes using
> kuart_rs485_config() in which case you should have all flags listed (you
> seem to talk about priority so that sounds like all are supported)?
Both. As written in the commit message, there are 3 variants of the
device. 2 variants support only one mode and 1 variant supports up to
3 modes.
>> +
>> + retval = serial8250_register_8250_port(&uart);
>> + if (retval < 0) {
>> + dev_err(&auxdev->dev, "UART registration failed!\n");
>
> Missing header.
I will check for the header.
As this patch is already merged, I will do a follow up.
regards, gerhard
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v4 2/2] serial: 8250: add driver for KEBA UART
2025-11-26 21:06 ` Gerhard Engleder
@ 2025-11-26 21:33 ` Andy Shevchenko
2025-11-27 19:40 ` Gerhard Engleder
0 siblings, 1 reply; 16+ messages in thread
From: Andy Shevchenko @ 2025-11-26 21:33 UTC (permalink / raw)
To: Gerhard Engleder
Cc: linux-serial, gregkh, jirislaby, lukas, Gerhard Engleder,
Daniel Gierlinger
On Wed, Nov 26, 2025 at 10:06:17PM +0100, Gerhard Engleder wrote:
> On 26.11.25 14:17, Andy Shevchenko wrote:
> > On Thu, Oct 23, 2025 at 05:12:29PM +0200, Gerhard Engleder wrote:
...
> > > +#include <linux/auxiliary_bus.h>
> >
> > + bits.h
> > + container_of.h
> >
> > > +#include <linux/device.h>
> >
> > I don't see how it's being used.
> > What I see are
> >
> > + dev_printk.h
> > + device/devres.h
> >
> > + err.h
> >
> > > +#include <linux/io.h>
> > > +#include <linux/misc/keba.h>
> >
> > + mod_devicetable.h
> >
> > > +#include <linux/module.h>
> >
> > + spinlock.h
> > + types.h
>
> Is there any extra tool to check for missing headers? Or do I have to
> check the header for every used function?
There is iwyu, which is heavily tweaked by Jonathan Cameron for use in Linux
kernel and even though it gives some false positives.
I did this manually by reading the code of the driver and remembering which
header provides which API.
...
> > Can't you call uart_read_port_properties()?
> >
> > If ever you gain some properties either via FW description or via software
> > nodes, they will be automatically used without need to update the driver!
>
> Yes that would be some nice behavior. But __uart_read_properties()
> sets some defaults even if no firmware node exist (UPF_SHARE_IRQ,
Is it a problem? Even a single IRQ may be marked shared.
> 0 as irq number
It doesn't do that, it just skips setting it in that case.
> or it fails if not irq number is found).
Yeah, this is most "problematic" part in case of this driver. Why is it
auxiliary and not platform? With that the __uart_read_properties() needs
to be updated to also query IRQ from respective aux device, and aux dev
needs implementation of dev_is_auxiliary(). Not that big deal, though.
> So __uart_read_properties() would need to be changed. IMO it makes no sense
> to change __uart_read_properties() as this functionality is currently
> not required.
Yes, but as I said it will give you for free the possibility to use those
properties without future modifications of the driver. OTOH, driver is in
tree and modifications will be needed one way or another :-)
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v4 2/2] serial: 8250: add driver for KEBA UART
2025-11-26 21:30 ` Gerhard Engleder
@ 2025-11-27 9:28 ` Ilpo Järvinen
2025-11-27 19:43 ` Gerhard Engleder
0 siblings, 1 reply; 16+ messages in thread
From: Ilpo Järvinen @ 2025-11-27 9:28 UTC (permalink / raw)
To: Gerhard Engleder
Cc: linux-serial, Greg Kroah-Hartman, Jiri Slaby, Lukas Wunner,
Gerhard Engleder, Daniel Gierlinger
[-- Attachment #1: Type: text/plain, Size: 5998 bytes --]
On Wed, 26 Nov 2025, Gerhard Engleder wrote:
> On 26.11.25 16:46, Ilpo Järvinen wrote:
> > On Thu, 23 Oct 2025, Gerhard Engleder wrote:
> >
> > > From: Gerhard Engleder <eg@keba.com>
> > >
> > > The KEBA UART is found in the system FPGA of KEBA PLC devices. It is
> > > mostly 8250 compatible with extension for some UART modes.
> > >
> > > 3 different variants exist. The simpliest variant supports only RS-232
> > > and is used for debug interfaces. The next variant supports only RS-485
> > > and is used mostly for communication with KEBA panel devices. The third
> > > variant is able to support RS-232, RS-485 and RS-422. For this variant
> > > not only the mode of the UART is configured, also the physics and
> > > transceivers are switched according to the mode.
> > >
> > > Signed-off-by: Gerhard Engleder <eg@keba.com>
> > > Tested-by: Daniel Gierlinger <gida@keba.com>
> > > ---
> > > drivers/tty/serial/8250/8250_keba.c | 280 ++++++++++++++++++++++++++++
> > > drivers/tty/serial/8250/Kconfig | 13 ++
> > > drivers/tty/serial/8250/Makefile | 1 +
> > > 3 files changed, 294 insertions(+)
> > > create mode 100644 drivers/tty/serial/8250/8250_keba.c
> > >
> > > diff --git a/drivers/tty/serial/8250/8250_keba.c
> > > b/drivers/tty/serial/8250/8250_keba.c
> > > new file mode 100644
> > > index 000000000000..c05b89551b12
> > > --- /dev/null
> > > +++ b/drivers/tty/serial/8250/8250_keba.c
> > > @@ -0,0 +1,280 @@
> > > +// SPDX-License-Identifier: GPL-2.0
> > > +/*
> > > + * Copyright (C) 2025 KEBA Industrial Automation GmbH
> > > + *
> > > + * Driver for KEBA UART FPGA IP core
> > > + */
> > > +
> > > +#include <linux/auxiliary_bus.h>
> > > +#include <linux/device.h>
> > > +#include <linux/io.h>
> > > +#include <linux/misc/keba.h>
> > > +#include <linux/module.h>
> >
> > + linux/serial_core.h
>
> Is this really necessary even with the include of 8250.h below?
Yes. Generally don't rely on indirect includes.
> > > +
> > > +#include "8250.h"
> > > +
> > > +#define KUART "kuart"
>
> ...
>
> > > +static void kuart_enhanced_mode(struct uart_8250_port *up, bool enable)
> > > +{
> > > + u8 lcr, efr;
> > > +
> > > + /* backup LCR register */
> >
> > Save + restore is quite obvious thing. IMO, no comment is needed about it.
>
> Yes it could be ommited. The patch is already merged, so I would keep
> it. Ok?
Ah, I didn't realize this is already merged. Just leave them then, it's
not that big thing.
> > > + lcr = serial_in(up, UART_LCR);
> > > +
> > > + /* enable 650 compatible register set (EFR, ...) */
> > > + serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
> > > +
> > > + /* enable/disable enhanced mode with indexed control registers */
> > > + efr = serial_in(up, UART_EFR);
> > > + if (enable)
> > > + efr |= UART_EFR_ECB;
> > > + else
> > > + efr &= ~UART_EFR_ECB;
> > > + serial_out(up, UART_EFR, efr);
> > > +
> > > + /* disable 650 compatible register set, restore LCR */
> > > + serial_out(up, UART_LCR, lcr);
> > > +}
> > > +
> > > +static void kuart_dtr_line_config(struct uart_8250_port *up, u8 dtrlc)
> > > +{
> > > + u8 acr;
> > > +
> > > + /* set index register to 0 to access ACR register */
> > > + serial_out(up, UART_SCR, UART_ACR);
> >
> > So the scratch register has some special use on this UART (register
> > multiplexer?), it would probably better name it with define, if that's the
> > case.
>
> This UART supports an enhanced mode, which changes the behavior of some
> registers. But the register still have their normal use with enhanced
> mode disabled. So I would keep the register name.
But this code clearly assume UART is in enhanced mode. Same number can
have different names. You could of course reuse the other define in the
define:
#define KUART_EMODE_INDEX_REG UART_SCR
> > > + /* set value register to 0x10 writing DTR mode (1,0) */
> > > + acr = serial_in(up, UART_LSR);
> > > + acr &= ~UART_ACR_DTRLC_MASK;
> > > + acr |= dtrlc;
> > > + serial_out(up, UART_LSR, acr);
> > > +}
>
> ...
>
> > > + /*
> > > + * UART supports RS485, RS422 and RS232 with switching of physical
> > > + * interface
> > > + */
> > > + uart.port.rs485_config = kuart_rs485_config;
> > > + if (kuart->flags & KUART_RS485) {
> > > + uart.port.rs485_supported.flags = SER_RS485_ENABLED |
> > > + SER_RS485_RTS_ON_SEND;
> > > + uart.port.rs485.flags = SER_RS485_ENABLED |
> > > + SER_RS485_RTS_ON_SEND;
> > > + }
> > > + if (kuart->flags & KUART_USE_CAPABILITY) {
> > > + /* default mode priority is RS485 > RS422 > RS232 */
> > > + if (kuart->capability & KUART_CAPABILITY_RS422) {
> > > + uart.port.rs485_supported.flags |= SER_RS485_ENABLED |
> > > +
> > > SER_RS485_RTS_ON_SEND |
> > > +
> > > SER_RS485_MODE_RS422;
> > > + uart.port.rs485.flags = SER_RS485_ENABLED |
> > > + SER_RS485_RTS_ON_SEND |
> > > + SER_RS485_MODE_RS422;
> > > + }
> > > + if (kuart->capability & KUART_CAPABILITY_RS485) {
> > > + uart.port.rs485_supported.flags |= SER_RS485_ENABLED |
> > > +
> > > SER_RS485_RTS_ON_SEND;
> > > + uart.port.rs485.flags = SER_RS485_ENABLED |
> > > + SER_RS485_RTS_ON_SEND;
> > > + }
> > > + }
> >
> > Is it so that only one mode is supported or can that be changes using
> > kuart_rs485_config() in which case you should have all flags listed (you
> > seem to talk about priority so that sounds like all are supported)?
>
> Both. As written in the commit message, there are 3 variants of the
> device. 2 variants support only one mode and 1 variant supports up to
> 3 modes.
>
> > > +
> > > + retval = serial8250_register_8250_port(&uart);
> > > + if (retval < 0) {
> > > + dev_err(&auxdev->dev, "UART registration failed!\n");
> >
> > Missing header.
>
> I will check for the header.
>
> As this patch is already merged, I will do a follow up.
>
> regards, gerhard
>
--
i.
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v4 2/2] serial: 8250: add driver for KEBA UART
2025-11-26 21:33 ` Andy Shevchenko
@ 2025-11-27 19:40 ` Gerhard Engleder
2025-11-27 19:58 ` Andy Shevchenko
0 siblings, 1 reply; 16+ messages in thread
From: Gerhard Engleder @ 2025-11-27 19:40 UTC (permalink / raw)
To: Andy Shevchenko
Cc: linux-serial, gregkh, jirislaby, lukas, Gerhard Engleder,
Daniel Gierlinger
On 26.11.25 22:33, Andy Shevchenko wrote:
> On Wed, Nov 26, 2025 at 10:06:17PM +0100, Gerhard Engleder wrote:
>> On 26.11.25 14:17, Andy Shevchenko wrote:
>>> On Thu, Oct 23, 2025 at 05:12:29PM +0200, Gerhard Engleder wrote:
>
> ...
>
>>>> +#include <linux/auxiliary_bus.h>
>>>
>>> + bits.h
>>> + container_of.h
>>>
>>>> +#include <linux/device.h>
>>>
>>> I don't see how it's being used.
>>> What I see are
>>>
>>> + dev_printk.h
>>> + device/devres.h
>>>
>>> + err.h
>>>
>>>> +#include <linux/io.h>
>>>> +#include <linux/misc/keba.h>
>>>
>>> + mod_devicetable.h
>>>
>>>> +#include <linux/module.h>
>>>
>>> + spinlock.h
>>> + types.h
>>
>> Is there any extra tool to check for missing headers? Or do I have to
>> check the header for every used function?
>
> There is iwyu, which is heavily tweaked by Jonathan Cameron for use in Linux
> kernel and even though it gives some false positives.
>
> I did this manually by reading the code of the driver and remembering which
> header provides which API.
>
> ...
>
>>> Can't you call uart_read_port_properties()?
>>>
>>> If ever you gain some properties either via FW description or via software
>>> nodes, they will be automatically used without need to update the driver!
>>
>> Yes that would be some nice behavior. But __uart_read_properties()
>> sets some defaults even if no firmware node exist (UPF_SHARE_IRQ,
>
> Is it a problem? Even a single IRQ may be marked shared.
>
>> 0 as irq number
>
> It doesn't do that, it just skips setting it in that case.
>
>> or it fails if not irq number is found).
>
> Yeah, this is most "problematic" part in case of this driver. Why is it
> auxiliary and not platform? With that the __uart_read_properties() needs
> to be updated to also query IRQ from respective aux device, and aux dev
> needs implementation of dev_is_auxiliary(). Not that big deal, though.
It is auxiliary and not platform, because gregkh suggested to switch
from platform to auxiliary. IMO he is right and that is a better fit,
because auxiliary devices were introduced to split big devices into
sub devices, which results in smaller drivers with one job for the
sub device. That's actually what I tried to do with platform devices
first.
>> So __uart_read_properties() would need to be changed. IMO it makes no sense
>> to change __uart_read_properties() as this functionality is currently
>> not required.
>
> Yes, but as I said it will give you for free the possibility to use those
> properties without future modifications of the driver. OTOH, driver is in
> tree and modifications will be needed one way or another :-)
Yes, if the KEBA UART changes, then modifications would be needed. We
kept this UART stable now for over 10 years. As it is FPGA based, we
can keep it stable as long as FPGAs are on the market. In industrial
automation the products are in the field for 10 years, 20 years or even
more. We can only support the devices for that long time by keeping
them compatible. So I don't expect changes now and therefore I would
not prepare for them.
Gerhard
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v4 2/2] serial: 8250: add driver for KEBA UART
2025-11-27 9:28 ` Ilpo Järvinen
@ 2025-11-27 19:43 ` Gerhard Engleder
0 siblings, 0 replies; 16+ messages in thread
From: Gerhard Engleder @ 2025-11-27 19:43 UTC (permalink / raw)
To: Ilpo Järvinen
Cc: linux-serial, Greg Kroah-Hartman, Jiri Slaby, Lukas Wunner,
Gerhard Engleder, Daniel Gierlinger
On 27.11.25 10:28, Ilpo Järvinen wrote:
> On Wed, 26 Nov 2025, Gerhard Engleder wrote:
>
>> On 26.11.25 16:46, Ilpo Järvinen wrote:
>>> On Thu, 23 Oct 2025, Gerhard Engleder wrote:
>>>
>>>> From: Gerhard Engleder <eg@keba.com>
>>>>
>>>> The KEBA UART is found in the system FPGA of KEBA PLC devices. It is
>>>> mostly 8250 compatible with extension for some UART modes.
>>>>
>>>> 3 different variants exist. The simpliest variant supports only RS-232
>>>> and is used for debug interfaces. The next variant supports only RS-485
>>>> and is used mostly for communication with KEBA panel devices. The third
>>>> variant is able to support RS-232, RS-485 and RS-422. For this variant
>>>> not only the mode of the UART is configured, also the physics and
>>>> transceivers are switched according to the mode.
>>>>
>>>> Signed-off-by: Gerhard Engleder <eg@keba.com>
>>>> Tested-by: Daniel Gierlinger <gida@keba.com>
>>>> ---
>>>> drivers/tty/serial/8250/8250_keba.c | 280 ++++++++++++++++++++++++++++
>>>> drivers/tty/serial/8250/Kconfig | 13 ++
>>>> drivers/tty/serial/8250/Makefile | 1 +
>>>> 3 files changed, 294 insertions(+)
>>>> create mode 100644 drivers/tty/serial/8250/8250_keba.c
...
>>>> +#include <linux/auxiliary_bus.h>
>>>> +#include <linux/device.h>
>>>> +#include <linux/io.h>
>>>> +#include <linux/misc/keba.h>
>>>> +#include <linux/module.h>
>>>
>>> + linux/serial_core.h
>>
>> Is this really necessary even with the include of 8250.h below?
>
> Yes. Generally don't rely on indirect includes.
I will add it to the follow up.
>>>> +
>>>> +#include "8250.h"
>>>> +
>>>> +#define KUART "kuart"
...
>>>> +static void kuart_dtr_line_config(struct uart_8250_port *up, u8 dtrlc)
>>>> +{
>>>> + u8 acr;
>>>> +
>>>> + /* set index register to 0 to access ACR register */
>>>> + serial_out(up, UART_SCR, UART_ACR);
>>>
>>> So the scratch register has some special use on this UART (register
>>> multiplexer?), it would probably better name it with define, if that's the
>>> case.
>>
>> This UART supports an enhanced mode, which changes the behavior of some
>> registers. But the register still have their normal use with enhanced
>> mode disabled. So I would keep the register name.
>
> But this code clearly assume UART is in enhanced mode. Same number can
> have different names. You could of course reuse the other define in the
> define:
>
> #define KUART_EMODE_INDEX_REG UART_SCR
I will consider it for the follow up.
Thank you for your comments!
Gerhard
^ permalink raw reply [flat|nested] 16+ messages in thread
* Re: [PATCH v4 2/2] serial: 8250: add driver for KEBA UART
2025-11-27 19:40 ` Gerhard Engleder
@ 2025-11-27 19:58 ` Andy Shevchenko
0 siblings, 0 replies; 16+ messages in thread
From: Andy Shevchenko @ 2025-11-27 19:58 UTC (permalink / raw)
To: Gerhard Engleder
Cc: linux-serial, gregkh, jirislaby, lukas, Gerhard Engleder,
Daniel Gierlinger
On Thu, Nov 27, 2025 at 08:40:41PM +0100, Gerhard Engleder wrote:
> On 26.11.25 22:33, Andy Shevchenko wrote:
> > On Wed, Nov 26, 2025 at 10:06:17PM +0100, Gerhard Engleder wrote:
> > > On 26.11.25 14:17, Andy Shevchenko wrote:
> > > > On Thu, Oct 23, 2025 at 05:12:29PM +0200, Gerhard Engleder wrote:
...
> > > > Can't you call uart_read_port_properties()?
> > > >
> > > > If ever you gain some properties either via FW description or via software
> > > > nodes, they will be automatically used without need to update the driver!
> > >
> > > Yes that would be some nice behavior. But __uart_read_properties()
> > > sets some defaults even if no firmware node exist (UPF_SHARE_IRQ,
> >
> > Is it a problem? Even a single IRQ may be marked shared.
> >
> > > 0 as irq number
> >
> > It doesn't do that, it just skips setting it in that case.
> >
> > > or it fails if not irq number is found).
> >
> > Yeah, this is most "problematic" part in case of this driver. Why is it
> > auxiliary and not platform? With that the __uart_read_properties() needs
> > to be updated to also query IRQ from respective aux device, and aux dev
> > needs implementation of dev_is_auxiliary(). Not that big deal, though.
>
> It is auxiliary and not platform, because gregkh suggested to switch
> from platform to auxiliary. IMO he is right and that is a better fit,
> because auxiliary devices were introduced to split big devices into
> sub devices, which results in smaller drivers with one job for the
> sub device. That's actually what I tried to do with platform devices
> first.
>
> > > So __uart_read_properties() would need to be changed. IMO it makes no sense
> > > to change __uart_read_properties() as this functionality is currently
> > > not required.
> >
> > Yes, but as I said it will give you for free the possibility to use those
> > properties without future modifications of the driver. OTOH, driver is in
> > tree and modifications will be needed one way or another :-)
>
> Yes, if the KEBA UART changes, then modifications would be needed. We
> kept this UART stable now for over 10 years. As it is FPGA based, we
> can keep it stable as long as FPGAs are on the market. In industrial
> automation the products are in the field for 10 years, 20 years or even
> more. We can only support the devices for that long time by keeping
> them compatible. So I don't expect changes now and therefore I would
> not prepare for them.
Fair enough.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 16+ messages in thread
end of thread, other threads:[~2025-11-27 20:06 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-23 15:12 [PATCH v4 0/2] serial: add KEBA UART driver Gerhard Engleder
2025-10-23 15:12 ` [PATCH v4 1/2] serial: Keep rs485 settings for devices without firmware node Gerhard Engleder
2025-10-26 9:25 ` Lukas Wunner
2025-11-26 13:10 ` Andy Shevchenko
2025-11-26 20:42 ` Gerhard Engleder
2025-10-23 15:12 ` [PATCH v4 2/2] serial: 8250: add driver for KEBA UART Gerhard Engleder
2025-10-26 9:30 ` Lukas Wunner
2025-11-26 13:17 ` Andy Shevchenko
2025-11-26 21:06 ` Gerhard Engleder
2025-11-26 21:33 ` Andy Shevchenko
2025-11-27 19:40 ` Gerhard Engleder
2025-11-27 19:58 ` Andy Shevchenko
2025-11-26 15:46 ` Ilpo Järvinen
2025-11-26 21:30 ` Gerhard Engleder
2025-11-27 9:28 ` Ilpo Järvinen
2025-11-27 19:43 ` Gerhard Engleder
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox