* [PATCH 0/2] serial: 8250_of: RS-485 on Microchip Core16550
@ 2026-11-03 0:11 Kohei Otsuka via B4 Relay
2026-11-03 0:11 ` [PATCH 1/2] dt-bindings: serial: 8250: add " Kohei Otsuka via B4 Relay
2026-11-03 0:11 ` [PATCH 2/2] serial: 8250_of: drop RS-485 RTS on " Kohei Otsuka via B4 Relay
0 siblings, 2 replies; 6+ messages in thread
From: Kohei Otsuka via B4 Relay @ 2026-11-03 0:11 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Lubomir Rintel, devicetree
Cc: linux-kernel, linux-serial, conor.dooley, Kohei Otsuka
Core16550 is a 16550-compatible UART soft IP for Microchip FPGAs. We use
four of them in the fabric of a PolarFire SoC Icicle Kit as RS-485
ports, described as "ns16550a" with linux,rs485-enabled-at-boot-time.
With RS-485 enabled, RTS (the transceiver's driver enable) goes high at
the start of the first transmission and never drops, and the port stops
receiving. Core16550, like the original 16550A, raises no interrupt on
TEMT, so __stop_tx() waits for one forever unless the port has
UART_CAP_NOTEMT, which 8250_of never sets.
Testing, on a PolarFire SoC Icicle Kit with four Core16550 instances
on FIC3 (PCLK 50 MHz), linux-mchp 6.18.17 with this series applied,
115200 8N1, against USB-RS485 (2-wire, half duplex) and USB-RS422
(4-wire) converters:
- All four ports transmit and receive correctly with both converters.
- On RS-485, each port keeps receiving after transmitting, across
repeated request/response exchanges in both directions.
- Without the series, RTS stays high after the first transmission and
nothing more is received.
This series was prepared with the help of an AI coding assistant
(Claude, Anthropic): the analysis of __stop_tx(), both patches and
these messages. I reviewed and tested the result and take
responsibility for it.
Link: https://github.com/linux4microchip/meta-mchp/issues/5
Signed-off-by: Kohei Otsuka <kohei@spacemachines.com>
---
Kohei Otsuka (2):
dt-bindings: serial: 8250: add Microchip Core16550
serial: 8250_of: drop RS-485 RTS on Microchip Core16550
Documentation/devicetree/bindings/serial/8250.yaml | 1 +
drivers/tty/serial/8250/8250_of.c | 9 +++++++++
2 files changed, 10 insertions(+)
---
base-commit: c339f4010dea8b0d754f84ace70cd1b089878ef8
change-id: 20261103-core16550-rs485-505af0ffaeeb
Best regards,
--
Kohei Otsuka <kohei@spacemachines.com>
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/2] dt-bindings: serial: 8250: add Microchip Core16550
2026-11-03 0:11 [PATCH 0/2] serial: 8250_of: RS-485 on Microchip Core16550 Kohei Otsuka via B4 Relay
@ 2026-11-03 0:11 ` Kohei Otsuka via B4 Relay
2026-11-04 14:00 ` Krzysztof Kozlowski
2026-11-04 16:20 ` Conor Dooley
2026-11-03 0:11 ` [PATCH 2/2] serial: 8250_of: drop RS-485 RTS on " Kohei Otsuka via B4 Relay
1 sibling, 2 replies; 6+ messages in thread
From: Kohei Otsuka via B4 Relay @ 2026-11-03 0:11 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Lubomir Rintel, devicetree
Cc: linux-kernel, linux-serial, conor.dooley, Kohei Otsuka
From: Kohei Otsuka <kohei@spacemachines.com>
Core16550 is a 16550-compatible UART soft IP core for Microchip FPGAs,
including the fabric of PolarFire SoC. Its registers follow the 16550A,
so ns16550a stays the fallback, but it raises no interrupt on TEMT,
which the driver has to know about to support RS-485 on it.
Add microchip,core16550 with ns16550a as the fallback.
Link: https://github.com/linux4microchip/meta-mchp/issues/5
Signed-off-by: Kohei Otsuka <kohei@spacemachines.com>
---
Documentation/devicetree/bindings/serial/8250.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/serial/8250.yaml b/Documentation/devicetree/bindings/serial/8250.yaml
index 50d5c977afa3..33a5929bdaa6 100644
--- a/Documentation/devicetree/bindings/serial/8250.yaml
+++ b/Documentation/devicetree/bindings/serial/8250.yaml
@@ -137,6 +137,7 @@ properties:
- ti,da830-uart
- loongson,ls2k0500-uart
- loongson,ls2k1500-uart
+ - microchip,core16550
- const: ns16550a
- items:
- enum:
--
2.53.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 2/2] serial: 8250_of: drop RS-485 RTS on Microchip Core16550
2026-11-03 0:11 [PATCH 0/2] serial: 8250_of: RS-485 on Microchip Core16550 Kohei Otsuka via B4 Relay
2026-11-03 0:11 ` [PATCH 1/2] dt-bindings: serial: 8250: add " Kohei Otsuka via B4 Relay
@ 2026-11-03 0:11 ` Kohei Otsuka via B4 Relay
2026-11-04 16:28 ` Conor Dooley
1 sibling, 1 reply; 6+ messages in thread
From: Kohei Otsuka via B4 Relay @ 2026-11-03 0:11 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Lubomir Rintel, devicetree
Cc: linux-kernel, linux-serial, conor.dooley, Kohei Otsuka
From: Kohei Otsuka <kohei@spacemachines.com>
Core16550, a 16550-compatible UART for Microchip FPGAs, interrupts on
THRE but not on TEMT. When the last character moves from the FIFO into
the shift register, the THRE interrupt calls __stop_tx(), which finds
TEMT clear and, without UART_CAP_NOTEMT, returns to wait for a TEMT
interrupt that never comes. RTS, and with it the RS-485 driver enable,
then stays asserted after the frame, and receive interrupts, disabled
for the half-duplex transmission, stay off.
Set UART_CAP_NOTEMT for nodes compatible with "microchip,core16550",
so em485 drops RTS from its stop timer one frame time (plus 1/7) after
THRE, as it does for DesignWare UARTs.
Set UART_CAP_FIFO as well: with the capabilities already non-zero,
serial8250_do_startup() no longer fills in the PORT_16550A default,
and without UART_CAP_FIFO serial8250_clear_fifos() does nothing, so
the RX FIFO is not flushed at the end of a half-duplex transmission.
Link: https://github.com/linux4microchip/meta-mchp/issues/5
Signed-off-by: Kohei Otsuka <kohei@spacemachines.com>
---
drivers/tty/serial/8250/8250_of.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/drivers/tty/serial/8250/8250_of.c b/drivers/tty/serial/8250/8250_of.c
index b41ca604083f..2f1f505501a2 100644
--- a/drivers/tty/serial/8250/8250_of.c
+++ b/drivers/tty/serial/8250/8250_of.c
@@ -278,6 +278,15 @@ static int of_platform_serial_probe(struct platform_device *ofdev)
if (port8250.port.fifosize)
port8250.capabilities = UART_CAP_FIFO;
+ /*
+ * Core16550 has no TEMT interrupt: without UART_CAP_NOTEMT the em485
+ * code waits for one after the last THRE interrupt and never drops RTS.
+ * Set UART_CAP_FIFO too, because a non-zero value stops
+ * serial8250_do_startup() filling in the PORT_16550A default.
+ */
+ if (of_device_is_compatible(ofdev->dev.of_node, "microchip,core16550"))
+ port8250.capabilities |= UART_CAP_FIFO | UART_CAP_NOTEMT;
+
/* Check for TX FIFO threshold & set tx_loadsz */
if ((of_property_read_u32(ofdev->dev.of_node, "tx-threshold",
&tx_threshold) == 0) &&
--
2.53.0
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] dt-bindings: serial: 8250: add Microchip Core16550
2026-11-03 0:11 ` [PATCH 1/2] dt-bindings: serial: 8250: add " Kohei Otsuka via B4 Relay
@ 2026-11-04 14:00 ` Krzysztof Kozlowski
2026-11-04 16:20 ` Conor Dooley
1 sibling, 0 replies; 6+ messages in thread
From: Krzysztof Kozlowski @ 2026-11-04 14:00 UTC (permalink / raw)
To: Kohei Otsuka
Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Lubomir Rintel, devicetree, linux-kernel,
linux-serial, conor.dooley
On Tue, Nov 03, 2026 at 11:11:31AM +1100, Kohei Otsuka wrote:
> Core16550 is a 16550-compatible UART soft IP core for Microchip FPGAs,
> including the fabric of PolarFire SoC. Its registers follow the 16550A,
> so ns16550a stays the fallback, but it raises no interrupt on TEMT,
> which the driver has to know about to support RS-485 on it.
>
> Add microchip,core16550 with ns16550a as the fallback.
>
> Link: https://github.com/linux4microchip/meta-mchp/issues/5
> Signed-off-by: Kohei Otsuka <kohei@spacemachines.com>
> ---
> Documentation/devicetree/bindings/serial/8250.yaml | 1 +
> 1 file changed, 1 insertion(+)
>
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] dt-bindings: serial: 8250: add Microchip Core16550
2026-11-03 0:11 ` [PATCH 1/2] dt-bindings: serial: 8250: add " Kohei Otsuka via B4 Relay
2026-11-04 14:00 ` Krzysztof Kozlowski
@ 2026-11-04 16:20 ` Conor Dooley
1 sibling, 0 replies; 6+ messages in thread
From: Conor Dooley @ 2026-11-04 16:20 UTC (permalink / raw)
To: Kohei Otsuka
Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Lubomir Rintel, devicetree, linux-kernel,
linux-serial, conor.dooley
[-- Attachment #1: Type: text/plain, Size: 1499 bytes --]
On Tue, Nov 03, 2026 at 11:11:31AM +1100, Kohei Otsuka wrote:
> Core16550 is a 16550-compatible UART soft IP core for Microchip FPGAs,
> including the fabric of PolarFire SoC. Its registers follow the 16550A,
> so ns16550a stays the fallback, but
> it raises no interrupt on TEMT,
> which the driver has to know about to support RS-485 on it.
Doesn't this exclude using the fallback to ns16550a, since it requires
specific interrupt handling?
>
> Add microchip,core16550 with ns16550a as the fallback.
>
> Link: https://github.com/linux4microchip/meta-mchp/issues/5
> Signed-off-by: Kohei Otsuka <kohei@spacemachines.com>
> ---
> Documentation/devicetree/bindings/serial/8250.yaml | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/Documentation/devicetree/bindings/serial/8250.yaml b/Documentation/devicetree/bindings/serial/8250.yaml
> index 50d5c977afa3..33a5929bdaa6 100644
> --- a/Documentation/devicetree/bindings/serial/8250.yaml
> +++ b/Documentation/devicetree/bindings/serial/8250.yaml
> @@ -137,6 +137,7 @@ properties:
> - ti,da830-uart
> - loongson,ls2k0500-uart
> - loongson,ls2k1500-uart
> + - microchip,core16550
This needs a -rtl-vX suffix on the end, as is used for other fabric
cores - see microchip,corei2c.yaml for an example.
pw-bot: changes-requested
Thanks,
Conor.
> - const: ns16550a
> - items:
> - enum:
>
> --
> 2.53.0
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] serial: 8250_of: drop RS-485 RTS on Microchip Core16550
2026-11-03 0:11 ` [PATCH 2/2] serial: 8250_of: drop RS-485 RTS on " Kohei Otsuka via B4 Relay
@ 2026-11-04 16:28 ` Conor Dooley
0 siblings, 0 replies; 6+ messages in thread
From: Conor Dooley @ 2026-11-04 16:28 UTC (permalink / raw)
To: Kohei Otsuka
Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Lubomir Rintel, devicetree, linux-kernel,
linux-serial, conor.dooley
[-- Attachment #1: Type: text/plain, Size: 3193 bytes --]
On Tue, Nov 03, 2026 at 11:11:32AM +1100, Kohei Otsuka wrote:
> Core16550, a 16550-compatible UART for Microchip FPGAs, interrupts on
> THRE but not on TEMT. When the last character moves from the FIFO into
> the shift register, the THRE interrupt calls __stop_tx(), which finds
> TEMT clear and, without UART_CAP_NOTEMT, returns to wait for a TEMT
> interrupt that never comes. RTS, and with it the RS-485 driver enable,
> then stays asserted after the frame, and receive interrupts, disabled
> for the half-duplex transmission, stay off.
>
> Set UART_CAP_NOTEMT for nodes compatible with "microchip,core16550",
> so em485 drops RTS from its stop timer one frame time (plus 1/7) after
> THRE, as it does for DesignWare UARTs.
>
> Set UART_CAP_FIFO as well: with the capabilities already non-zero,
> serial8250_do_startup() no longer fills in the PORT_16550A default,
> and without UART_CAP_FIFO serial8250_clear_fifos() does nothing, so
> the RX FIFO is not flushed at the end of a half-duplex transmission.
>
> Link: https://github.com/linux4microchip/meta-mchp/issues/5
It's worth noting that in that GitHub link I pointed out that the time I
recall this core being used they required changes to the baud rate logic
in the driver and that there were differences between how the baud rate
is actually determined from the input clock:
| The docs for core16550 say:
|
| This block takes the input PCLK and divides it by a programmed value (from 1 to 216 – 1). The result
| is divided by 16 to create the transmission clock (BAUDOUT)
|
| whereas ns16550a docs say:
|
| The UART includes a programmable baud rate generator
| that is capable of dividing the timing reference clock input
| by divisors of 1 to (216-1 ), and producing a 16 x clock for
| driving the internal transmitter logic. Provisions are also included to use this 16 x clock to drive the receiver logic.
Kohei reported not being affected by this, but I figured it was worth
mentioning.
Cheers,
Conor.
> Signed-off-by: Kohei Otsuka <kohei@spacemachines.com>
> ---
> drivers/tty/serial/8250/8250_of.c | 9 +++++++++
> 1 file changed, 9 insertions(+)
>
> diff --git a/drivers/tty/serial/8250/8250_of.c b/drivers/tty/serial/8250/8250_of.c
> index b41ca604083f..2f1f505501a2 100644
> --- a/drivers/tty/serial/8250/8250_of.c
> +++ b/drivers/tty/serial/8250/8250_of.c
> @@ -278,6 +278,15 @@ static int of_platform_serial_probe(struct platform_device *ofdev)
> if (port8250.port.fifosize)
> port8250.capabilities = UART_CAP_FIFO;
>
> + /*
> + * Core16550 has no TEMT interrupt: without UART_CAP_NOTEMT the em485
> + * code waits for one after the last THRE interrupt and never drops RTS.
> + * Set UART_CAP_FIFO too, because a non-zero value stops
> + * serial8250_do_startup() filling in the PORT_16550A default.
> + */
> + if (of_device_is_compatible(ofdev->dev.of_node, "microchip,core16550"))
> + port8250.capabilities |= UART_CAP_FIFO | UART_CAP_NOTEMT;
> +
> /* Check for TX FIFO threshold & set tx_loadsz */
> if ((of_property_read_u32(ofdev->dev.of_node, "tx-threshold",
> &tx_threshold) == 0) &&
>
> --
> 2.53.0
>
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-11-04 16:28 UTC | newest]
Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-03 0:11 [PATCH 0/2] serial: 8250_of: RS-485 on Microchip Core16550 Kohei Otsuka via B4 Relay
2026-11-03 0:11 ` [PATCH 1/2] dt-bindings: serial: 8250: add " Kohei Otsuka via B4 Relay
2026-11-04 14:00 ` Krzysztof Kozlowski
2026-11-04 16:20 ` Conor Dooley
2026-11-03 0:11 ` [PATCH 2/2] serial: 8250_of: drop RS-485 RTS on " Kohei Otsuka via B4 Relay
2026-11-04 16:28 ` Conor Dooley
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®