* [PATCH v4 0/5] serial: 8250_dw: describe the Allwinner H616 UART configuration
@ 2026-10-27 23:05 James Hilliard
2026-10-27 23:05 ` [PATCH v4 1/5] serial: 8250_dw: select port setup through platform data James Hilliard
` (5 more replies)
0 siblings, 6 replies; 19+ messages in thread
From: James Hilliard @ 2026-10-27 23:05 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Andy Shevchenko, Ilpo Järvinen, Chen-Yu Tsai,
Jernej Skrabec, Samuel Holland
Cc: linux-kernel, linux-serial, devicetree, linux-arm-kernel,
linux-sunxi, James Hilliard
H616 has 256-byte UART FIFOs, but lacks the DesignWare component parameter
register used to discover their capacity. Its debug-divisor and RS485
registers also overlap offsets used to probe optional DesignWare features.
Add an H616 compatible for the integration-specific setup. Keep the
existing 16550A port type and describe its fixed FIFO depth in platform
data. Use common Allwinner helpers to configure the transmit load and
receive thresholds from that depth. Configure automatic flow control,
preserve the BUSY-safe integer divisor path and keep the UART gate enabled
during termios changes. The H616 configuration uses PIO.
The series first introduces platform setup callbacks and a shared RX
trigger conversion helper, then adds the binding, H616 setup and SoC DTS
changes. Based on tty-next at 6b4b543fa187 with the posted RX
trigger callback-lifetime fix [0] and DW BUSY-safe divisor fix v4 [1].
Platform setup runs before installing the BUSY-safe divisor setter.
[0] https://lore.kernel.org/r/20261024-submit-serial-8250-rxtrig-lifetime-v1-v1-1-731b78d5003d@gmail.com
[1] https://lore.kernel.org/r/20261027-submit-serial-8250-dw-divisor-v1-v4-1-41714a75e15a@gmail.com
Assisted-by: Codex:gpt-6-astra
Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
---
Changes in v4:
- Introduce common Allwinner setup helpers with the fixed FIFO depth
supplied by compatible-specific platform data.
- Rebase onto tty-next at 6b4b543fa187 and the posted DW divisor v4 fix,
installing the BUSY-safe setter after platform setup.
- Use an early return for FIFO-less DMA setup, following Andy's review.
- Default to generic setup when platform data has no setup callback.
- Select Octeon's optional-register discovery with IS_ENABLED() in its
setup helper, preserving the existing 32-bit and 64-bit behavior.
- Extract the shared 8250 bytes-to-FCR conversion, including the
unsupported-table check, into a preparatory patch and use it for
H616, following Andy's review.
- Set the fixed 256-byte FIFO depth in H616 platform data and omit
fifo-size from its binding and DTS, following Krzysztof's review.
- Precompute the Allwinner RX thresholds during setup and retain the
sunxi FIFO-depth helper for filling the table. Use named FCR encodings
in the helper, following Jiri's review.
- Share threshold-table initialization and callback assignment through
a sunxi RX trigger setup helper.
- Group and comment the H616 trigger and RS485 setup.
- Link to v3: https://patch.msgid.link/20261024-submit-h616-uart-fifo-v1-v3-0-286fc1b8c3c1@gmail.com
Changes in v3:
- Introduce a platform-data setup callback in a preparatory patch,
replacing skip_autocfg and preserving the existing Octeon setup.
- Describe each H616 UART's FIFO capacity with the standard fifo-size DT
property and use the value already read by uart_read_port_properties().
- Derive the Allwinner RX trigger thresholds from the FIFO depth.
- Use an unsigned trigger index and conditional runtime PM guard,
preserving error propagation when the device cannot resume.
- Rebase onto tty-next, replacing the earlier DMA prerequisites with the
posted RX trigger callback-lifetime fix.
- Separate DMA enablement into follow-up work, retaining PIO operation
for the H616 FIFO configuration.
- Link to v2: https://lore.kernel.org/r/20261023-submit-h616-uart-fifo-v1-v2-0-af0593504635@gmail.com
Changes in v2:
- Keep PORT_16550A and set the FIFO size, transmit load and capabilities
during setup, following Andy's review.
- Select H616 setup through the matched platform-data pointer and remove
the type and DMA burst-size platform-data members.
- Use get_rxtrig/set_rxtrig for the 1/64/128/254-byte receive thresholds,
with port locking and runtime PM around register updates. Keep the
standard half-full FCR default, selecting 128 bytes on H616.
- Advertise UART_CAP_AFE so CRTSCTS enables hardware automatic flow control.
- Rebase onto next-20261023 and declare the posted sun6i pause/lifetime
fixes and their prerequisites for DMA enablement.
- Link to v1: https://lore.kernel.org/r/20261023-submit-h616-uart-fifo-v1-v1-0-e4a3bae2eba8@gmail.com
To: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
To: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: Jiri Slaby <jirislaby@kernel.org>
To: Rob Herring <robh@kernel.org>
To: Krzysztof Kozlowski <krzk+dt@kernel.org>
To: Conor Dooley <conor+dt@kernel.org>
To: Chen-Yu Tsai <wens@kernel.org>
To: Jernej Skrabec <jernej.skrabec@gmail.com>
To: Samuel Holland <samuel@sholland.org>
Cc: linux-kernel@vger.kernel.org
Cc: linux-serial@vger.kernel.org
Cc: devicetree@vger.kernel.org
Cc: linux-arm-kernel@lists.infradead.org
Cc: linux-sunxi@lists.linux.dev
---
James Hilliard (5):
serial: 8250_dw: select port setup through platform data
serial: 8250: share the RX trigger conversion helper
dt-bindings: serial: snps-dw-apb-uart: add Allwinner H616
serial: 8250_dw: configure the Allwinner H616 UART
arm64: dts: allwinner: h616: describe the UART integration
.../bindings/serial/snps-dw-apb-uart.yaml | 1 +
arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi | 12 +-
drivers/tty/serial/8250/8250.h | 16 +++
drivers/tty/serial/8250/8250_dw.c | 138 +++++++++++++++++++--
drivers/tty/serial/8250/8250_port.c | 12 +-
5 files changed, 151 insertions(+), 28 deletions(-)
---
base-commit: 6b4b543fa18757297ac756a6fe6e64f506b7844a
change-id: 20261022-submit-h616-uart-fifo-v1-c5afcdfe5cb0
prerequisite-message-id: <20261027-submit-serial-8250-dw-divisor-v1-v4-1-41714a75e15a@gmail.com>
prerequisite-patch-id: d8219673210dac82d3adab41578ff2f76f5862c9
prerequisite-message-id: <20261024-submit-serial-8250-rxtrig-lifetime-v1-v1-1-731b78d5003d@gmail.com>
prerequisite-patch-id: 9a9395c715c2bf7bbcae5bdd16a339d7f2af6269
Best regards,
--
James Hilliard <james.hilliard1@gmail.com>
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v4 1/5] serial: 8250_dw: select port setup through platform data
2026-10-27 23:05 [PATCH v4 0/5] serial: 8250_dw: describe the Allwinner H616 UART configuration James Hilliard
@ 2026-10-27 23:05 ` James Hilliard
2026-10-28 8:56 ` Andy Shevchenko
2026-10-27 23:05 ` [PATCH v4 2/5] serial: 8250: share the RX trigger conversion helper James Hilliard
` (4 subsequent siblings)
5 siblings, 1 reply; 19+ messages in thread
From: James Hilliard @ 2026-10-27 23:05 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Andy Shevchenko, Ilpo Järvinen, Chen-Yu Tsai,
Jernej Skrabec, Samuel Holland
Cc: linux-kernel, linux-serial, devicetree, linux-arm-kernel,
linux-sunxi, James Hilliard
Select feature discovery and DMA attachment through a platform-data setup
callback. The generic callback probes the optional registers and attaches
DMA when a FIFO size is available. Integrations with a fixed configuration
can supply their own setup before the port is registered.
Replace skip_autocfg with the Octeon setup selection. On 64-bit builds,
Octeon continues to skip optional-register probing while retaining its DMA
setup; on 32-bit builds it retains the generic setup. Keep generic setup
for devices without matched platform data as well.
Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
---
drivers/tty/serial/8250/8250_dw.c | 44 +++++++++++++++++++++++++++++----------
1 file changed, 33 insertions(+), 11 deletions(-)
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
index 9cbe076463e0..1351523f0c47 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -64,6 +64,7 @@ struct dw8250_platform_data {
u8 usr_reg;
u32 cpr_value;
unsigned int quirks;
+ void (*setup)(struct uart_port *p);
};
struct dw8250_data {
@@ -76,7 +77,6 @@ struct dw8250_data {
struct clk *pclk;
struct reset_control *rst;
- unsigned int skip_autocfg:1;
unsigned int uart_16550_compatible:1;
unsigned int in_idle:1;
@@ -596,7 +596,6 @@ static void dw8250_quirks(struct uart_port *p, struct dw8250_data *data)
p->serial_out = dw8250_serial_outq;
p->flags = UPF_SKIP_TEST | UPF_SHARE_IRQ | UPF_FIXED_TYPE;
p->type = PORT_OCTEON;
- data->skip_autocfg = true;
}
#endif
@@ -631,6 +630,33 @@ static void dw8250_shutdown(struct uart_port *port)
d->no_int_count = 0;
}
+static void dw8250_setup_dma(struct uart_port *p)
+{
+ struct dw8250_data *data = to_dw8250_data(p->private_data);
+ struct uart_8250_port *up = up_to_u8250p(p);
+
+ /* DMA setup requires a FIFO. */
+ if (!p->fifosize)
+ return;
+
+ data->data.dma.rxconf.src_maxburst = p->fifosize / 4;
+ data->data.dma.txconf.dst_maxburst = p->fifosize / 4;
+ up->dma = &data->data.dma;
+}
+
+static void dw8250_setup(struct uart_port *p)
+{
+ dw8250_setup_port(p);
+ dw8250_setup_dma(p);
+}
+
+static void dw8250_octeon_setup(struct uart_port *p)
+{
+ if (!IS_ENABLED(CONFIG_64BIT))
+ dw8250_setup_port(p);
+ dw8250_setup_dma(p);
+}
+
static int dw8250_probe(struct platform_device *pdev)
{
struct uart_8250_port uart = {}, *up = &uart;
@@ -765,19 +791,14 @@ static int dw8250_probe(struct platform_device *pdev)
dw8250_setup_dma_filter(p, data);
- if (!data->skip_autocfg)
- dw8250_setup_port(p);
+ if (data->pdata && data->pdata->setup)
+ data->pdata->setup(p);
+ else
+ dw8250_setup(p);
/* Use the BUSY-safe sequence for both integer and fractional divisors. */
p->set_divisor = dw8250_set_divisor;
- /* If we have a valid fifosize, try hooking up DMA */
- if (p->fifosize) {
- data->data.dma.rxconf.src_maxburst = p->fifosize / 4;
- data->data.dma.txconf.dst_maxburst = p->fifosize / 4;
- up->dma = &data->data.dma;
- }
-
data->data.uport = serial8250_register_8250_port(up);
if (IS_ERR(data->data.uport))
return PTR_ERR(data->data.uport);
@@ -860,6 +881,7 @@ static const struct dw8250_platform_data dw8250_dw_apb = {
static const struct dw8250_platform_data dw8250_octeon_3860_data = {
.usr_reg = OCTEON_UART_USR,
.quirks = DW_UART_QUIRK_OCTEON,
+ .setup = dw8250_octeon_setup,
};
static const struct dw8250_platform_data dw8250_armada_38x_data = {
--
2.53.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v4 2/5] serial: 8250: share the RX trigger conversion helper
2026-10-27 23:05 [PATCH v4 0/5] serial: 8250_dw: describe the Allwinner H616 UART configuration James Hilliard
2026-10-27 23:05 ` [PATCH v4 1/5] serial: 8250_dw: select port setup through platform data James Hilliard
@ 2026-10-27 23:05 ` James Hilliard
2026-10-28 8:30 ` Ilpo Järvinen
2026-10-28 9:37 ` Andy Shevchenko
2026-10-27 23:05 ` [PATCH v4 3/5] dt-bindings: serial: snps-dw-apb-uart: add Allwinner H616 James Hilliard
` (3 subsequent siblings)
5 siblings, 2 replies; 19+ messages in thread
From: James Hilliard @ 2026-10-27 23:05 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Andy Shevchenko, Ilpo Järvinen, Chen-Yu Tsai,
Jernej Skrabec, Samuel Holland
Cc: linux-kernel, linux-serial, devicetree, linux-arm-kernel,
linux-sunxi, James Hilliard
Extract the receive-trigger threshold search into serial8250_bytes_to_fcr()
so drivers with per-port threshold tables can use the same conversion as
the generic 8250 implementation.
Include the unsupported-table check in the helper and preserve the existing
nearest-lower selection and highest-encoding fallback.
Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
---
drivers/tty/serial/8250/8250.h | 16 ++++++++++++++++
drivers/tty/serial/8250/8250_port.c | 12 +-----------
2 files changed, 17 insertions(+), 11 deletions(-)
diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h
index 21ed9c41b751..195ed58a2231 100644
--- a/drivers/tty/serial/8250/8250.h
+++ b/drivers/tty/serial/8250/8250.h
@@ -8,6 +8,7 @@
*/
#include <linux/bits.h>
+#include <linux/errno.h>
#include <linux/serial_8250.h>
#include <linux/serial_core.h>
#include <linux/dmaengine.h>
@@ -73,6 +74,21 @@ struct serial8250_config {
unsigned int flags;
};
+static inline int serial8250_bytes_to_fcr(const unsigned char *rxtrig_bytes,
+ unsigned char bytes)
+{
+ if (!rxtrig_bytes[UART_FCR_R_TRIG_BITS(UART_FCR_R_TRIG_00)])
+ return -EOPNOTSUPP;
+
+ for (unsigned int i = 1; i < UART_FCR_R_TRIG_MAX_STATE; i++) {
+ if (bytes < rxtrig_bytes[i])
+ /* Use the nearest lower value */
+ return (i - 1) << UART_FCR_R_TRIG_SHIFT;
+ }
+
+ return UART_FCR_R_TRIG_11;
+}
+
enum uart_port_type {
/* Internal 8250 only */
UART_PORT_AIROHA = 124,
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index 36b2b0a2c05c..c332963dc2ed 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -3018,18 +3018,8 @@ static int fcr_get_rxtrig_bytes(struct uart_8250_port *up)
static int bytes_to_fcr_rxtrig(struct uart_8250_port *up, unsigned char bytes)
{
const struct serial8250_config *conf_type = &uart_config[up->port.type];
- int i;
- if (!conf_type->rxtrig_bytes[UART_FCR_R_TRIG_BITS(UART_FCR_R_TRIG_00)])
- return -EOPNOTSUPP;
-
- for (i = 1; i < UART_FCR_R_TRIG_MAX_STATE; i++) {
- if (bytes < conf_type->rxtrig_bytes[i])
- /* Use the nearest lower value */
- return (--i) << UART_FCR_R_TRIG_SHIFT;
- }
-
- return UART_FCR_R_TRIG_11;
+ return serial8250_bytes_to_fcr(conf_type->rxtrig_bytes, bytes);
}
static int do_get_rxtrig(struct tty_port *port)
--
2.53.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v4 3/5] dt-bindings: serial: snps-dw-apb-uart: add Allwinner H616
2026-10-27 23:05 [PATCH v4 0/5] serial: 8250_dw: describe the Allwinner H616 UART configuration James Hilliard
2026-10-27 23:05 ` [PATCH v4 1/5] serial: 8250_dw: select port setup through platform data James Hilliard
2026-10-27 23:05 ` [PATCH v4 2/5] serial: 8250: share the RX trigger conversion helper James Hilliard
@ 2026-10-27 23:05 ` James Hilliard
2026-10-28 8:06 ` Krzysztof Kozlowski
2026-10-27 23:05 ` [PATCH v4 4/5] serial: 8250_dw: configure the Allwinner H616 UART James Hilliard
` (2 subsequent siblings)
5 siblings, 1 reply; 19+ messages in thread
From: James Hilliard @ 2026-10-27 23:05 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Andy Shevchenko, Ilpo Järvinen, Chen-Yu Tsai,
Jernej Skrabec, Samuel Holland
Cc: linux-kernel, linux-serial, devicetree, linux-arm-kernel,
linux-sunxi, James Hilliard
The H616 UART has 256-byte transmit and receive FIFOs, but its DesignWare
component parameter register does not report the FIFO depth. Its optional
register layout also differs from the generic DesignWare integration.
Add a specific compatible to identify this fixed configuration, retaining
snps,dw-apb-uart as a fallback.
Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
---
Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml | 1 +
1 file changed, 1 insertion(+)
diff --git a/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml b/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml
index e2ca126d58ba..fc1289073241 100644
--- a/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml
+++ b/Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml
@@ -60,6 +60,7 @@ properties:
- const: renesas,rzn1-uart
- items:
- enum:
+ - allwinner,sun50i-h616-uart
- anlogic,dr1v90-uart
- brcm,bcm11351-dw-apb-uart
- brcm,bcm21664-dw-apb-uart
--
2.53.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v4 4/5] serial: 8250_dw: configure the Allwinner H616 UART
2026-10-27 23:05 [PATCH v4 0/5] serial: 8250_dw: describe the Allwinner H616 UART configuration James Hilliard
` (2 preceding siblings ...)
2026-10-27 23:05 ` [PATCH v4 3/5] dt-bindings: serial: snps-dw-apb-uart: add Allwinner H616 James Hilliard
@ 2026-10-27 23:05 ` James Hilliard
2026-10-28 8:39 ` Ilpo Järvinen
2026-10-28 11:05 ` Andy Shevchenko
2026-10-27 23:05 ` [PATCH v4 5/5] arm64: dts: allwinner: h616: describe the UART integration James Hilliard
2026-10-28 8:57 ` [PATCH v4 0/5] serial: 8250_dw: describe the Allwinner H616 UART configuration Andre Przywara
5 siblings, 2 replies; 19+ messages in thread
From: James Hilliard @ 2026-10-27 23:05 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Andy Shevchenko, Ilpo Järvinen, Chen-Yu Tsai,
Jernej Skrabec, Samuel Holland
Cc: linux-kernel, linux-serial, devicetree, linux-arm-kernel,
linux-sunxi, James Hilliard
H616 has 256-byte transmit and receive FIFOs, but its optional DesignWare
component parameter register reads as zero. Generic 16550 probing leaves
the port using the 16-byte FIFO configuration and its trigger-level table.
Keep PORT_16550A and describe H616's fixed 256-byte FIFO depth in platform
data. Use common Allwinner setup helpers to configure the transmit load
and receive trigger table from that depth.
Derive the receive thresholds from the documented 1-byte, quarter-full,
half-full and FIFO-depth-minus-two mapping. On H616 these are 1, 64, 128
and 254 bytes; the normal 16550A half-full FCR setting selects 128 bytes.
Build the threshold table during setup and use the shared 8250 conversion
helper to select the nearest lower threshold for sysfs writes.
Serialize trigger changes with termios and hold a runtime PM reference
while programming FCR, preserving the FIFO contents. Propagate runtime
resume errors before changing either the FCR shadow or the hardware.
Advertise automatic flow control so CRTSCTS enables MCR.AFCE. The
DesignWare termios path selects hardware CTS handling, so the capability
must be present for the corresponding hardware control to be enabled.
Select the fixed configuration through the platform setup callback.
H616 has debug-divisor and RS485 control registers at the offsets used to
detect DesignWare hardware RS485 and fractional-divisor support. Avoid
those probes and retain the BUSY-safe integer divisor hook and software
RS485 handling.
Use the existing SKIP_SET_RATE quirk to keep the UART clock enabled during
termios changes. Its clock is a gate on the shared APB2 source, rather than
an independent baud-rate generator.
Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
---
drivers/tty/serial/8250/8250_dw.c | 94 +++++++++++++++++++++++++++++++++++++++
1 file changed, 94 insertions(+)
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
index 1351523f0c47..2f156c01c5a1 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -19,6 +19,7 @@
#include <linux/io.h>
#include <linux/lockdep.h>
#include <linux/module.h>
+#include <linux/mutex.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
#include <linux/property.h>
@@ -63,6 +64,7 @@
struct dw8250_platform_data {
u8 usr_reg;
u32 cpr_value;
+ unsigned int fifo_size;
unsigned int quirks;
void (*setup)(struct uart_port *p);
};
@@ -81,6 +83,7 @@ struct dw8250_data {
unsigned int in_idle:1;
u8 no_int_count;
+ u8 rxtrig_bytes[UART_FCR_R_TRIG_MAX_STATE];
};
static inline struct dw8250_data *to_dw8250_data(struct dw8250_port_data *data)
@@ -657,6 +660,89 @@ static void dw8250_octeon_setup(struct uart_port *p)
dw8250_setup_dma(p);
}
+/* The trigger is the masked, unshifted FCR receive trigger field. */
+static unsigned int dw8250_sunxi_rxtrig_bytes(struct uart_port *p, unsigned int trigger)
+{
+ switch (trigger) {
+ case UART_FCR_TRIGGER_1:
+ return 1;
+ case UART_FCR_TRIGGER_4:
+ return p->fifosize / 4;
+ case UART_FCR_TRIGGER_8:
+ return p->fifosize / 2;
+ default:
+ return p->fifosize - 2;
+ }
+}
+
+static int dw8250_sunxi_get_rxtrig(struct uart_port *p)
+{
+ struct dw8250_data *data = to_dw8250_data(p->private_data);
+ struct uart_8250_port *up = up_to_u8250p(p);
+
+ guard(uart_port_lock_irqsave)(p);
+
+ return data->rxtrig_bytes[UART_FCR_R_TRIG_BITS(up->fcr)];
+}
+
+static int dw8250_sunxi_set_rxtrig(struct uart_port *p, unsigned char bytes)
+{
+ struct dw8250_data *data = to_dw8250_data(p->private_data);
+ struct uart_8250_port *up = up_to_u8250p(p);
+ int fcr, ret;
+
+ fcr = serial8250_bytes_to_fcr(data->rxtrig_bytes, bytes);
+ if (fcr < 0)
+ return fcr;
+
+ guard(mutex)(&p->state->port.mutex);
+
+ PM_RUNTIME_ACQUIRE_IF_ENABLED(p->dev, pm);
+ ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
+ if (ret)
+ return ret;
+
+ guard(uart_port_lock_irqsave)(p);
+
+ up->fcr &= ~UART_FCR_TRIGGER_MASK;
+ up->fcr |= fcr;
+ /* Changing the trigger alone preserves the FIFO contents. */
+ serial_port_out(p, UART_FCR, up->fcr);
+
+ return 0;
+}
+
+static void dw8250_sunxi_setup_rxtrig(struct uart_port *p)
+{
+ struct dw8250_data *data = to_dw8250_data(p->private_data);
+
+ /* Allwinner RX thresholds differ from the standard 16550A table. */
+ for (unsigned int i = 0; i < ARRAY_SIZE(data->rxtrig_bytes); i++)
+ data->rxtrig_bytes[i] = dw8250_sunxi_rxtrig_bytes(p, i << UART_FCR_R_TRIG_SHIFT);
+ p->get_rxtrig = dw8250_sunxi_get_rxtrig;
+ p->set_rxtrig = dw8250_sunxi_set_rxtrig;
+}
+
+static void dw8250_sunxi_setup(struct uart_port *p)
+{
+ struct dw8250_data *data = to_dw8250_data(p->private_data);
+ struct uart_8250_port *up = up_to_u8250p(p);
+
+ p->type = PORT_16550A;
+ p->flags |= UPF_FIXED_TYPE;
+ p->fifosize = data->pdata->fifo_size;
+ up->tx_loadsz = p->fifosize;
+ up->capabilities = UART_CAP_FIFO | UART_CAP_NOTEMT | UART_CAP_AFE;
+
+ dw8250_sunxi_setup_rxtrig(p);
+
+ /* Use software RS485 with the Allwinner register layout. */
+ p->rs485_config = serial8250_em485_config;
+ p->rs485_supported = serial8250_em485_supported;
+ up->rs485_start_tx = serial8250_em485_start_tx;
+ up->rs485_stop_tx = serial8250_em485_stop_tx;
+}
+
static int dw8250_probe(struct platform_device *pdev)
{
struct uart_8250_port uart = {}, *up = &uart;
@@ -878,6 +964,13 @@ static const struct dw8250_platform_data dw8250_dw_apb = {
.usr_reg = DW_UART_USR,
};
+static const struct dw8250_platform_data dw8250_h616_data = {
+ .usr_reg = DW_UART_USR,
+ .fifo_size = 256,
+ .quirks = DW_UART_QUIRK_SKIP_SET_RATE,
+ .setup = dw8250_sunxi_setup,
+};
+
static const struct dw8250_platform_data dw8250_octeon_3860_data = {
.usr_reg = OCTEON_UART_USR,
.quirks = DW_UART_QUIRK_OCTEON,
@@ -929,6 +1022,7 @@ static const struct dw8250_platform_data dw8250_tda54 = {
static const struct of_device_id dw8250_of_match[] = {
{ .compatible = "snps,dw-apb-uart", .data = &dw8250_dw_apb },
+ { .compatible = "allwinner,sun50i-h616-uart", .data = &dw8250_h616_data },
{ .compatible = "cavium,octeon-3860-uart", .data = &dw8250_octeon_3860_data },
{ .compatible = "marvell,armada-38x-uart", .data = &dw8250_armada_38x_data },
{ .compatible = "renesas,rzn1-uart", .data = &dw8250_renesas_rzn1_data },
--
2.53.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* [PATCH v4 5/5] arm64: dts: allwinner: h616: describe the UART integration
2026-10-27 23:05 [PATCH v4 0/5] serial: 8250_dw: describe the Allwinner H616 UART configuration James Hilliard
` (3 preceding siblings ...)
2026-10-27 23:05 ` [PATCH v4 4/5] serial: 8250_dw: configure the Allwinner H616 UART James Hilliard
@ 2026-10-27 23:05 ` James Hilliard
2026-10-28 8:57 ` [PATCH v4 0/5] serial: 8250_dw: describe the Allwinner H616 UART configuration Andre Przywara
5 siblings, 0 replies; 19+ messages in thread
From: James Hilliard @ 2026-10-27 23:05 UTC (permalink / raw)
To: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Andy Shevchenko, Ilpo Järvinen, Chen-Yu Tsai,
Jernej Skrabec, Samuel Holland
Cc: linux-kernel, linux-serial, devicetree, linux-arm-kernel,
linux-sunxi, James Hilliard
Identify the H616 UART integration on each of the six controllers. The
specific compatible describes the fixed FIFO capacity, register layout
and receive-trigger mapping.
Retain snps,dw-apb-uart as the generic fallback. H618 includes this DTSI
and uses the same UART integration.
Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
---
arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
index c6b3a3f8359a..b4b2f85726e0 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi
@@ -550,7 +550,7 @@ mmc2: mmc@4022000 {
};
uart0: serial@5000000 {
- compatible = "snps,dw-apb-uart";
+ compatible = "allwinner,sun50i-h616-uart", "snps,dw-apb-uart";
reg = <0x05000000 0x400>;
interrupts = <GIC_SPI 0 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
@@ -563,7 +563,7 @@ uart0: serial@5000000 {
};
uart1: serial@5000400 {
- compatible = "snps,dw-apb-uart";
+ compatible = "allwinner,sun50i-h616-uart", "snps,dw-apb-uart";
reg = <0x05000400 0x400>;
interrupts = <GIC_SPI 1 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
@@ -576,7 +576,7 @@ uart1: serial@5000400 {
};
uart2: serial@5000800 {
- compatible = "snps,dw-apb-uart";
+ compatible = "allwinner,sun50i-h616-uart", "snps,dw-apb-uart";
reg = <0x05000800 0x400>;
interrupts = <GIC_SPI 2 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
@@ -589,7 +589,7 @@ uart2: serial@5000800 {
};
uart3: serial@5000c00 {
- compatible = "snps,dw-apb-uart";
+ compatible = "allwinner,sun50i-h616-uart", "snps,dw-apb-uart";
reg = <0x05000c00 0x400>;
interrupts = <GIC_SPI 3 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
@@ -602,7 +602,7 @@ uart3: serial@5000c00 {
};
uart4: serial@5001000 {
- compatible = "snps,dw-apb-uart";
+ compatible = "allwinner,sun50i-h616-uart", "snps,dw-apb-uart";
reg = <0x05001000 0x400>;
interrupts = <GIC_SPI 4 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
@@ -615,7 +615,7 @@ uart4: serial@5001000 {
};
uart5: serial@5001400 {
- compatible = "snps,dw-apb-uart";
+ compatible = "allwinner,sun50i-h616-uart", "snps,dw-apb-uart";
reg = <0x05001400 0x400>;
interrupts = <GIC_SPI 5 IRQ_TYPE_LEVEL_HIGH>;
reg-shift = <2>;
--
2.53.0
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v4 3/5] dt-bindings: serial: snps-dw-apb-uart: add Allwinner H616
2026-10-27 23:05 ` [PATCH v4 3/5] dt-bindings: serial: snps-dw-apb-uart: add Allwinner H616 James Hilliard
@ 2026-10-28 8:06 ` Krzysztof Kozlowski
0 siblings, 0 replies; 19+ messages in thread
From: Krzysztof Kozlowski @ 2026-10-28 8:06 UTC (permalink / raw)
To: James Hilliard
Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Andy Shevchenko, Ilpo Järvinen, Chen-Yu Tsai,
Jernej Skrabec, Samuel Holland, linux-kernel, linux-serial,
devicetree, linux-arm-kernel, linux-sunxi
On Tue, Oct 27, 2026 at 05:05:31PM -0600, James Hilliard wrote:
> The H616 UART has 256-byte transmit and receive FIFOs, but its DesignWare
> component parameter register does not report the FIFO depth. Its optional
> register layout also differs from the generic DesignWare integration.
>
> Add a specific compatible to identify this fixed configuration, retaining
> snps,dw-apb-uart as a fallback.
>
> Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
> ---
> Documentation/devicetree/bindings/serial/snps-dw-apb-uart.yaml | 1 +
> 1 file changed, 1 insertion(+)
Acked-by: Krzysztof Kozlowski <krzysztof.kozlowski@oss.qualcomm.com>
Best regards,
Krzysztof
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v4 2/5] serial: 8250: share the RX trigger conversion helper
2026-10-27 23:05 ` [PATCH v4 2/5] serial: 8250: share the RX trigger conversion helper James Hilliard
@ 2026-10-28 8:30 ` Ilpo Järvinen
2026-10-28 9:38 ` Andy Shevchenko
2026-10-28 9:37 ` Andy Shevchenko
1 sibling, 1 reply; 19+ messages in thread
From: Ilpo Järvinen @ 2026-10-28 8:30 UTC (permalink / raw)
To: James Hilliard
Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Andy Shevchenko, Chen-Yu Tsai, Jernej Skrabec,
Samuel Holland, LKML, linux-serial, devicetree, linux-arm-kernel,
linux-sunxi
On Tue, 27 Oct 2026, James Hilliard wrote:
> Extract the receive-trigger threshold search into serial8250_bytes_to_fcr()
> so drivers with per-port threshold tables can use the same conversion as
> the generic 8250 implementation.
>
> Include the unsupported-table check in the helper and preserve the existing
> nearest-lower selection and highest-encoding fallback.
>
> Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
> ---
> drivers/tty/serial/8250/8250.h | 16 ++++++++++++++++
> drivers/tty/serial/8250/8250_port.c | 12 +-----------
> 2 files changed, 17 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h
> index 21ed9c41b751..195ed58a2231 100644
> --- a/drivers/tty/serial/8250/8250.h
> +++ b/drivers/tty/serial/8250/8250.h
> @@ -8,6 +8,7 @@
> */
>
> #include <linux/bits.h>
> +#include <linux/errno.h>
> #include <linux/serial_8250.h>
> #include <linux/serial_core.h>
> #include <linux/dmaengine.h>
> @@ -73,6 +74,21 @@ struct serial8250_config {
> unsigned int flags;
> };
>
> +static inline int serial8250_bytes_to_fcr(const unsigned char *rxtrig_bytes,
This looks way to complicated to be inline function so I think it should
be kept in 8250_port and exported from there.
> + unsigned char bytes)
> +{
> + if (!rxtrig_bytes[UART_FCR_R_TRIG_BITS(UART_FCR_R_TRIG_00)])
> + return -EOPNOTSUPP;
> +
> + for (unsigned int i = 1; i < UART_FCR_R_TRIG_MAX_STATE; i++) {
> + if (bytes < rxtrig_bytes[i])
> + /* Use the nearest lower value */
> + return (i - 1) << UART_FCR_R_TRIG_SHIFT;
> + }
> +
> + return UART_FCR_R_TRIG_11;
> +}
> +
> enum uart_port_type {
> /* Internal 8250 only */
> UART_PORT_AIROHA = 124,
> diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
> index 36b2b0a2c05c..c332963dc2ed 100644
> --- a/drivers/tty/serial/8250/8250_port.c
> +++ b/drivers/tty/serial/8250/8250_port.c
> @@ -3018,18 +3018,8 @@ static int fcr_get_rxtrig_bytes(struct uart_8250_port *up)
> static int bytes_to_fcr_rxtrig(struct uart_8250_port *up, unsigned char bytes)
> {
> const struct serial8250_config *conf_type = &uart_config[up->port.type];
> - int i;
>
> - if (!conf_type->rxtrig_bytes[UART_FCR_R_TRIG_BITS(UART_FCR_R_TRIG_00)])
> - return -EOPNOTSUPP;
> -
> - for (i = 1; i < UART_FCR_R_TRIG_MAX_STATE; i++) {
> - if (bytes < conf_type->rxtrig_bytes[i])
> - /* Use the nearest lower value */
> - return (--i) << UART_FCR_R_TRIG_SHIFT;
> - }
> -
> - return UART_FCR_R_TRIG_11;
> + return serial8250_bytes_to_fcr(conf_type->rxtrig_bytes, bytes);
> }
>
> static int do_get_rxtrig(struct tty_port *port)
>
>
--
i.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v4 4/5] serial: 8250_dw: configure the Allwinner H616 UART
2026-10-27 23:05 ` [PATCH v4 4/5] serial: 8250_dw: configure the Allwinner H616 UART James Hilliard
@ 2026-10-28 8:39 ` Ilpo Järvinen
2026-10-28 8:53 ` James Hilliard
2026-10-28 11:05 ` Andy Shevchenko
1 sibling, 1 reply; 19+ messages in thread
From: Ilpo Järvinen @ 2026-10-28 8:39 UTC (permalink / raw)
To: James Hilliard
Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Andy Shevchenko, Chen-Yu Tsai, Jernej Skrabec,
Samuel Holland, LKML, linux-serial, devicetree, linux-arm-kernel,
linux-sunxi
On Tue, 27 Oct 2026, James Hilliard wrote:
> H616 has 256-byte transmit and receive FIFOs, but its optional DesignWare
> component parameter register reads as zero. Generic 16550 probing leaves
> the port using the 16-byte FIFO configuration and its trigger-level table.
>
> Keep PORT_16550A and describe H616's fixed 256-byte FIFO depth in platform
> data. Use common Allwinner setup helpers to configure the transmit load
> and receive trigger table from that depth.
>
> Derive the receive thresholds from the documented 1-byte, quarter-full,
> half-full and FIFO-depth-minus-two mapping. On H616 these are 1, 64, 128
> and 254 bytes; the normal 16550A half-full FCR setting selects 128 bytes.
>
> Build the threshold table during setup and use the shared 8250 conversion
> helper to select the nearest lower threshold for sysfs writes.
You do that, I can see from the patch, but I came to read this changelog
to understand "why"?? You provide zero reasoning for this design decision.
Since you fifosize is constant as well, so what benefit building it on the
fly servers?
> Serialize trigger changes with termios and hold a runtime PM reference
> while programming FCR, preserving the FIFO contents. Propagate runtime
> resume errors before changing either the FCR shadow or the hardware.
>
> Advertise automatic flow control so CRTSCTS enables MCR.AFCE. The
> DesignWare termios path selects hardware CTS handling, so the capability
> must be present for the corresponding hardware control to be enabled.
>
> Select the fixed configuration through the platform setup callback.
> H616 has debug-divisor and RS485 control registers at the offsets used to
> detect DesignWare hardware RS485 and fractional-divisor support. Avoid
> those probes and retain the BUSY-safe integer divisor hook and software
> RS485 handling.
>
> Use the existing SKIP_SET_RATE quirk to keep the UART clock enabled during
> termios changes. Its clock is a gate on the shared APB2 source, rather than
> an independent baud-rate generator.
>
> Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
> ---
> drivers/tty/serial/8250/8250_dw.c | 94 +++++++++++++++++++++++++++++++++++++++
> 1 file changed, 94 insertions(+)
>
> diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
> index 1351523f0c47..2f156c01c5a1 100644
> --- a/drivers/tty/serial/8250/8250_dw.c
> +++ b/drivers/tty/serial/8250/8250_dw.c
> @@ -19,6 +19,7 @@
> #include <linux/io.h>
> #include <linux/lockdep.h>
> #include <linux/module.h>
> +#include <linux/mutex.h>
> #include <linux/platform_device.h>
> #include <linux/pm_runtime.h>
> #include <linux/property.h>
> @@ -63,6 +64,7 @@
> struct dw8250_platform_data {
> u8 usr_reg;
> u32 cpr_value;
> + unsigned int fifo_size;
> unsigned int quirks;
> void (*setup)(struct uart_port *p);
> };
> @@ -81,6 +83,7 @@ struct dw8250_data {
> unsigned int in_idle:1;
>
> u8 no_int_count;
> + u8 rxtrig_bytes[UART_FCR_R_TRIG_MAX_STATE];
> };
>
> static inline struct dw8250_data *to_dw8250_data(struct dw8250_port_data *data)
> @@ -657,6 +660,89 @@ static void dw8250_octeon_setup(struct uart_port *p)
> dw8250_setup_dma(p);
> }
>
> +/* The trigger is the masked, unshifted FCR receive trigger field. */
> +static unsigned int dw8250_sunxi_rxtrig_bytes(struct uart_port *p, unsigned int trigger)
> +{
> + switch (trigger) {
> + case UART_FCR_TRIGGER_1:
> + return 1;
> + case UART_FCR_TRIGGER_4:
> + return p->fifosize / 4;
> + case UART_FCR_TRIGGER_8:
> + return p->fifosize / 2;
> + default:
> + return p->fifosize - 2;
> + }
> +}
> +
> +static int dw8250_sunxi_get_rxtrig(struct uart_port *p)
> +{
> + struct dw8250_data *data = to_dw8250_data(p->private_data);
> + struct uart_8250_port *up = up_to_u8250p(p);
> +
> + guard(uart_port_lock_irqsave)(p);
> +
> + return data->rxtrig_bytes[UART_FCR_R_TRIG_BITS(up->fcr)];
> +}
> +
> +static int dw8250_sunxi_set_rxtrig(struct uart_port *p, unsigned char bytes)
> +{
> + struct dw8250_data *data = to_dw8250_data(p->private_data);
> + struct uart_8250_port *up = up_to_u8250p(p);
> + int fcr, ret;
> +
> + fcr = serial8250_bytes_to_fcr(data->rxtrig_bytes, bytes);
> + if (fcr < 0)
> + return fcr;
> +
> + guard(mutex)(&p->state->port.mutex);
> +
> + PM_RUNTIME_ACQUIRE_IF_ENABLED(p->dev, pm);
> + ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
> + if (ret)
> + return ret;
> +
> + guard(uart_port_lock_irqsave)(p);
> +
> + up->fcr &= ~UART_FCR_TRIGGER_MASK;
> + up->fcr |= fcr;
> + /* Changing the trigger alone preserves the FIFO contents. */
> + serial_port_out(p, UART_FCR, up->fcr);
> +
> + return 0;
> +}
> +
> +static void dw8250_sunxi_setup_rxtrig(struct uart_port *p)
> +{
> + struct dw8250_data *data = to_dw8250_data(p->private_data);
> +
> + /* Allwinner RX thresholds differ from the standard 16550A table. */
> + for (unsigned int i = 0; i < ARRAY_SIZE(data->rxtrig_bytes); i++)
> + data->rxtrig_bytes[i] = dw8250_sunxi_rxtrig_bytes(p, i << UART_FCR_R_TRIG_SHIFT);
FIELD_PREP(UART_FCR_TRIGGER_MASK, i)
For clarity, it might be useful to split it into two lines using an
intermediate variable.
> + p->get_rxtrig = dw8250_sunxi_get_rxtrig;
> + p->set_rxtrig = dw8250_sunxi_set_rxtrig;
> +}
> +
> +static void dw8250_sunxi_setup(struct uart_port *p)
> +{
> + struct dw8250_data *data = to_dw8250_data(p->private_data);
> + struct uart_8250_port *up = up_to_u8250p(p);
> +
> + p->type = PORT_16550A;
> + p->flags |= UPF_FIXED_TYPE;
> + p->fifosize = data->pdata->fifo_size;
> + up->tx_loadsz = p->fifosize;
> + up->capabilities = UART_CAP_FIFO | UART_CAP_NOTEMT | UART_CAP_AFE;
> +
> + dw8250_sunxi_setup_rxtrig(p);
> +
> + /* Use software RS485 with the Allwinner register layout. */
> + p->rs485_config = serial8250_em485_config;
> + p->rs485_supported = serial8250_em485_supported;
> + up->rs485_start_tx = serial8250_em485_start_tx;
> + up->rs485_stop_tx = serial8250_em485_stop_tx;
> +}
> +
> static int dw8250_probe(struct platform_device *pdev)
> {
> struct uart_8250_port uart = {}, *up = &uart;
> @@ -878,6 +964,13 @@ static const struct dw8250_platform_data dw8250_dw_apb = {
> .usr_reg = DW_UART_USR,
> };
>
> +static const struct dw8250_platform_data dw8250_h616_data = {
> + .usr_reg = DW_UART_USR,
> + .fifo_size = 256,
> + .quirks = DW_UART_QUIRK_SKIP_SET_RATE,
> + .setup = dw8250_sunxi_setup,
> +};
> +
> static const struct dw8250_platform_data dw8250_octeon_3860_data = {
> .usr_reg = OCTEON_UART_USR,
> .quirks = DW_UART_QUIRK_OCTEON,
> @@ -929,6 +1022,7 @@ static const struct dw8250_platform_data dw8250_tda54 = {
>
> static const struct of_device_id dw8250_of_match[] = {
> { .compatible = "snps,dw-apb-uart", .data = &dw8250_dw_apb },
> + { .compatible = "allwinner,sun50i-h616-uart", .data = &dw8250_h616_data },
> { .compatible = "cavium,octeon-3860-uart", .data = &dw8250_octeon_3860_data },
> { .compatible = "marvell,armada-38x-uart", .data = &dw8250_armada_38x_data },
> { .compatible = "renesas,rzn1-uart", .data = &dw8250_renesas_rzn1_data },
>
>
--
i.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v4 4/5] serial: 8250_dw: configure the Allwinner H616 UART
2026-10-28 8:39 ` Ilpo Järvinen
@ 2026-10-28 8:53 ` James Hilliard
2026-10-28 8:57 ` Ilpo Järvinen
0 siblings, 1 reply; 19+ messages in thread
From: James Hilliard @ 2026-10-28 8:53 UTC (permalink / raw)
To: Ilpo Järvinen
Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Andy Shevchenko, Chen-Yu Tsai, Jernej Skrabec,
Samuel Holland, LKML, linux-serial, devicetree, linux-arm-kernel,
linux-sunxi
On Wed, Oct 28, 2026 at 2:39 AM Ilpo Järvinen
<ilpo.jarvinen@linux.intel.com> wrote:
>
> On Tue, 27 Oct 2026, James Hilliard wrote:
>
> > H616 has 256-byte transmit and receive FIFOs, but its optional DesignWare
> > component parameter register reads as zero. Generic 16550 probing leaves
> > the port using the 16-byte FIFO configuration and its trigger-level table.
> >
> > Keep PORT_16550A and describe H616's fixed 256-byte FIFO depth in platform
> > data. Use common Allwinner setup helpers to configure the transmit load
> > and receive trigger table from that depth.
> >
> > Derive the receive thresholds from the documented 1-byte, quarter-full,
> > half-full and FIFO-depth-minus-two mapping. On H616 these are 1, 64, 128
> > and 254 bytes; the normal 16550A half-full FCR setting selects 128 bytes.
> >
> > Build the threshold table during setup and use the shared 8250 conversion
> > helper to select the nearest lower threshold for sysfs writes.
>
> You do that, I can see from the patch, but I came to read this changelog
> to understand "why"?? You provide zero reasoning for this design decision.
>
> Since you fifosize is constant as well, so what benefit building it on the
> fly servers?
The intent is to keep the FIFO depth as the single platform-data input
and derive the thresholds from the common Allwinner mapping. Other sunxi
integrations using that mapping could then supply a different FIFO depth
without duplicating the threshold table.
Building the table once also lets get_rxtrig() and the shared
bytes-to-FCR helper use the same derived values.
>
> > Serialize trigger changes with termios and hold a runtime PM reference
> > while programming FCR, preserving the FIFO contents. Propagate runtime
> > resume errors before changing either the FCR shadow or the hardware.
> >
> > Advertise automatic flow control so CRTSCTS enables MCR.AFCE. The
> > DesignWare termios path selects hardware CTS handling, so the capability
> > must be present for the corresponding hardware control to be enabled.
> >
> > Select the fixed configuration through the platform setup callback.
> > H616 has debug-divisor and RS485 control registers at the offsets used to
> > detect DesignWare hardware RS485 and fractional-divisor support. Avoid
> > those probes and retain the BUSY-safe integer divisor hook and software
> > RS485 handling.
> >
> > Use the existing SKIP_SET_RATE quirk to keep the UART clock enabled during
> > termios changes. Its clock is a gate on the shared APB2 source, rather than
> > an independent baud-rate generator.
> >
> > Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
> > ---
> > drivers/tty/serial/8250/8250_dw.c | 94 +++++++++++++++++++++++++++++++++++++++
> > 1 file changed, 94 insertions(+)
> >
> > diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
> > index 1351523f0c47..2f156c01c5a1 100644
> > --- a/drivers/tty/serial/8250/8250_dw.c
> > +++ b/drivers/tty/serial/8250/8250_dw.c
> > @@ -19,6 +19,7 @@
> > #include <linux/io.h>
> > #include <linux/lockdep.h>
> > #include <linux/module.h>
> > +#include <linux/mutex.h>
> > #include <linux/platform_device.h>
> > #include <linux/pm_runtime.h>
> > #include <linux/property.h>
> > @@ -63,6 +64,7 @@
> > struct dw8250_platform_data {
> > u8 usr_reg;
> > u32 cpr_value;
> > + unsigned int fifo_size;
> > unsigned int quirks;
> > void (*setup)(struct uart_port *p);
> > };
> > @@ -81,6 +83,7 @@ struct dw8250_data {
> > unsigned int in_idle:1;
> >
> > u8 no_int_count;
> > + u8 rxtrig_bytes[UART_FCR_R_TRIG_MAX_STATE];
> > };
> >
> > static inline struct dw8250_data *to_dw8250_data(struct dw8250_port_data *data)
> > @@ -657,6 +660,89 @@ static void dw8250_octeon_setup(struct uart_port *p)
> > dw8250_setup_dma(p);
> > }
> >
> > +/* The trigger is the masked, unshifted FCR receive trigger field. */
> > +static unsigned int dw8250_sunxi_rxtrig_bytes(struct uart_port *p, unsigned int trigger)
> > +{
> > + switch (trigger) {
> > + case UART_FCR_TRIGGER_1:
> > + return 1;
> > + case UART_FCR_TRIGGER_4:
> > + return p->fifosize / 4;
> > + case UART_FCR_TRIGGER_8:
> > + return p->fifosize / 2;
> > + default:
> > + return p->fifosize - 2;
> > + }
> > +}
> > +
> > +static int dw8250_sunxi_get_rxtrig(struct uart_port *p)
> > +{
> > + struct dw8250_data *data = to_dw8250_data(p->private_data);
> > + struct uart_8250_port *up = up_to_u8250p(p);
> > +
> > + guard(uart_port_lock_irqsave)(p);
> > +
> > + return data->rxtrig_bytes[UART_FCR_R_TRIG_BITS(up->fcr)];
> > +}
> > +
> > +static int dw8250_sunxi_set_rxtrig(struct uart_port *p, unsigned char bytes)
> > +{
> > + struct dw8250_data *data = to_dw8250_data(p->private_data);
> > + struct uart_8250_port *up = up_to_u8250p(p);
> > + int fcr, ret;
> > +
> > + fcr = serial8250_bytes_to_fcr(data->rxtrig_bytes, bytes);
> > + if (fcr < 0)
> > + return fcr;
> > +
> > + guard(mutex)(&p->state->port.mutex);
> > +
> > + PM_RUNTIME_ACQUIRE_IF_ENABLED(p->dev, pm);
> > + ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
> > + if (ret)
> > + return ret;
> > +
> > + guard(uart_port_lock_irqsave)(p);
> > +
> > + up->fcr &= ~UART_FCR_TRIGGER_MASK;
> > + up->fcr |= fcr;
> > + /* Changing the trigger alone preserves the FIFO contents. */
> > + serial_port_out(p, UART_FCR, up->fcr);
> > +
> > + return 0;
> > +}
> > +
> > +static void dw8250_sunxi_setup_rxtrig(struct uart_port *p)
> > +{
> > + struct dw8250_data *data = to_dw8250_data(p->private_data);
> > +
> > + /* Allwinner RX thresholds differ from the standard 16550A table. */
> > + for (unsigned int i = 0; i < ARRAY_SIZE(data->rxtrig_bytes); i++)
> > + data->rxtrig_bytes[i] = dw8250_sunxi_rxtrig_bytes(p, i << UART_FCR_R_TRIG_SHIFT);
>
> FIELD_PREP(UART_FCR_TRIGGER_MASK, i)
>
> For clarity, it might be useful to split it into two lines using an
> intermediate variable.
>
> > + p->get_rxtrig = dw8250_sunxi_get_rxtrig;
> > + p->set_rxtrig = dw8250_sunxi_set_rxtrig;
> > +}
> > +
> > +static void dw8250_sunxi_setup(struct uart_port *p)
> > +{
> > + struct dw8250_data *data = to_dw8250_data(p->private_data);
> > + struct uart_8250_port *up = up_to_u8250p(p);
> > +
> > + p->type = PORT_16550A;
> > + p->flags |= UPF_FIXED_TYPE;
> > + p->fifosize = data->pdata->fifo_size;
> > + up->tx_loadsz = p->fifosize;
> > + up->capabilities = UART_CAP_FIFO | UART_CAP_NOTEMT | UART_CAP_AFE;
> > +
> > + dw8250_sunxi_setup_rxtrig(p);
> > +
> > + /* Use software RS485 with the Allwinner register layout. */
> > + p->rs485_config = serial8250_em485_config;
> > + p->rs485_supported = serial8250_em485_supported;
> > + up->rs485_start_tx = serial8250_em485_start_tx;
> > + up->rs485_stop_tx = serial8250_em485_stop_tx;
> > +}
> > +
> > static int dw8250_probe(struct platform_device *pdev)
> > {
> > struct uart_8250_port uart = {}, *up = &uart;
> > @@ -878,6 +964,13 @@ static const struct dw8250_platform_data dw8250_dw_apb = {
> > .usr_reg = DW_UART_USR,
> > };
> >
> > +static const struct dw8250_platform_data dw8250_h616_data = {
> > + .usr_reg = DW_UART_USR,
> > + .fifo_size = 256,
> > + .quirks = DW_UART_QUIRK_SKIP_SET_RATE,
> > + .setup = dw8250_sunxi_setup,
> > +};
> > +
> > static const struct dw8250_platform_data dw8250_octeon_3860_data = {
> > .usr_reg = OCTEON_UART_USR,
> > .quirks = DW_UART_QUIRK_OCTEON,
> > @@ -929,6 +1022,7 @@ static const struct dw8250_platform_data dw8250_tda54 = {
> >
> > static const struct of_device_id dw8250_of_match[] = {
> > { .compatible = "snps,dw-apb-uart", .data = &dw8250_dw_apb },
> > + { .compatible = "allwinner,sun50i-h616-uart", .data = &dw8250_h616_data },
> > { .compatible = "cavium,octeon-3860-uart", .data = &dw8250_octeon_3860_data },
> > { .compatible = "marvell,armada-38x-uart", .data = &dw8250_armada_38x_data },
> > { .compatible = "renesas,rzn1-uart", .data = &dw8250_renesas_rzn1_data },
> >
> >
>
> --
> i.
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v4 1/5] serial: 8250_dw: select port setup through platform data
2026-10-27 23:05 ` [PATCH v4 1/5] serial: 8250_dw: select port setup through platform data James Hilliard
@ 2026-10-28 8:56 ` Andy Shevchenko
2026-10-28 9:40 ` Andy Shevchenko
0 siblings, 1 reply; 19+ messages in thread
From: Andy Shevchenko @ 2026-10-28 8:56 UTC (permalink / raw)
To: James Hilliard
Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Ilpo Järvinen, Chen-Yu Tsai, Jernej Skrabec,
Samuel Holland, linux-kernel, linux-serial, devicetree,
linux-arm-kernel, linux-sunxi
On Tue, Oct 27, 2026 at 05:05:29PM -0600, James Hilliard wrote:
> Select feature discovery and DMA attachment through a platform-data setup
> callback. The generic callback probes the optional registers and attaches
> DMA when a FIFO size is available. Integrations with a fixed configuration
> can supply their own setup before the port is registered.
>
> Replace skip_autocfg with the Octeon setup selection. On 64-bit builds,
> Octeon continues to skip optional-register probing while retaining its DMA
> setup; on 32-bit builds it retains the generic setup. Keep generic setup
> for devices without matched platform data as well.
...
> +static void dw8250_setup_dma(struct uart_port *p)
> +{
> + struct dw8250_data *data = to_dw8250_data(p->private_data);
> + struct uart_8250_port *up = up_to_u8250p(p);
> + /* DMA setup requires a FIFO. */
The style of the single-line comment in this file is without period at the end.
> + if (!p->fifosize)
> + return;
> +
> + data->data.dma.rxconf.src_maxburst = p->fifosize / 4;
> + data->data.dma.txconf.dst_maxburst = p->fifosize / 4;
> + up->dma = &data->data.dma;
> +}
...
> +static void dw8250_octeon_setup(struct uart_port *p)
> +{
> + if (!IS_ENABLED(CONFIG_64BIT))
> + dw8250_setup_port(p);
I believe the Cavium OCTEON is 64-bit only platform, so you can just drop this
conditional altogether.
> + dw8250_setup_dma(p);
> +}
With this being done, you can kill the entire helper ad use dw8250_setup_dma()
directly in dw8250_octeon_3860_data.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v4 0/5] serial: 8250_dw: describe the Allwinner H616 UART configuration
2026-10-27 23:05 [PATCH v4 0/5] serial: 8250_dw: describe the Allwinner H616 UART configuration James Hilliard
` (4 preceding siblings ...)
2026-10-27 23:05 ` [PATCH v4 5/5] arm64: dts: allwinner: h616: describe the UART integration James Hilliard
@ 2026-10-28 8:57 ` Andre Przywara
2026-10-28 9:04 ` James Hilliard
2026-10-28 9:04 ` Chen-Yu Tsai
5 siblings, 2 replies; 19+ messages in thread
From: Andre Przywara @ 2026-10-28 8:57 UTC (permalink / raw)
To: James Hilliard, Greg Kroah-Hartman, Jiri Slaby, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Andy Shevchenko,
Ilpo Järvinen, Chen-Yu Tsai, Jernej Skrabec, Samuel Holland
Cc: linux-kernel, linux-serial, devicetree, linux-arm-kernel, linux-sunxi
Hi,
On 10/28/26 00:05, James Hilliard wrote:
> H616 has 256-byte UART FIFOs, but lacks the DesignWare component parameter
> register used to discover their capacity. Its debug-divisor and RS485
> registers also overlap offsets used to probe optional DesignWare features.
that affects almost all Allwinner SoCs, not just the H616, so should be
solved universally, not just for one SoC.
IIUC Chen-Yu has a patch to attribute the right FIFO size, in each
.dtsi, which I consider the best solution to this problem.
I'd say we wait for -rc1 and then work on top of his patch.
Cheers,
Andre
>
> Add an H616 compatible for the integration-specific setup. Keep the
> existing 16550A port type and describe its fixed FIFO depth in platform
> data. Use common Allwinner helpers to configure the transmit load and
> receive thresholds from that depth. Configure automatic flow control,
> preserve the BUSY-safe integer divisor path and keep the UART gate enabled
> during termios changes. The H616 configuration uses PIO.
>
> The series first introduces platform setup callbacks and a shared RX
> trigger conversion helper, then adds the binding, H616 setup and SoC DTS
> changes. Based on tty-next at 6b4b543fa187 with the posted RX
> trigger callback-lifetime fix [0] and DW BUSY-safe divisor fix v4 [1].
> Platform setup runs before installing the BUSY-safe divisor setter.
>
> [0] https://lore.kernel.org/r/20261024-submit-serial-8250-rxtrig-lifetime-v1-v1-1-731b78d5003d@gmail.com
> [1] https://lore.kernel.org/r/20261027-submit-serial-8250-dw-divisor-v1-v4-1-41714a75e15a@gmail.com
>
> Assisted-by: Codex:gpt-6-astra
> Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
> ---
> Changes in v4:
> - Introduce common Allwinner setup helpers with the fixed FIFO depth
> supplied by compatible-specific platform data.
> - Rebase onto tty-next at 6b4b543fa187 and the posted DW divisor v4 fix,
> installing the BUSY-safe setter after platform setup.
> - Use an early return for FIFO-less DMA setup, following Andy's review.
> - Default to generic setup when platform data has no setup callback.
> - Select Octeon's optional-register discovery with IS_ENABLED() in its
> setup helper, preserving the existing 32-bit and 64-bit behavior.
> - Extract the shared 8250 bytes-to-FCR conversion, including the
> unsupported-table check, into a preparatory patch and use it for
> H616, following Andy's review.
> - Set the fixed 256-byte FIFO depth in H616 platform data and omit
> fifo-size from its binding and DTS, following Krzysztof's review.
> - Precompute the Allwinner RX thresholds during setup and retain the
> sunxi FIFO-depth helper for filling the table. Use named FCR encodings
> in the helper, following Jiri's review.
> - Share threshold-table initialization and callback assignment through
> a sunxi RX trigger setup helper.
> - Group and comment the H616 trigger and RS485 setup.
> - Link to v3: https://patch.msgid.link/20261024-submit-h616-uart-fifo-v1-v3-0-286fc1b8c3c1@gmail.com
>
> Changes in v3:
> - Introduce a platform-data setup callback in a preparatory patch,
> replacing skip_autocfg and preserving the existing Octeon setup.
> - Describe each H616 UART's FIFO capacity with the standard fifo-size DT
> property and use the value already read by uart_read_port_properties().
> - Derive the Allwinner RX trigger thresholds from the FIFO depth.
> - Use an unsigned trigger index and conditional runtime PM guard,
> preserving error propagation when the device cannot resume.
> - Rebase onto tty-next, replacing the earlier DMA prerequisites with the
> posted RX trigger callback-lifetime fix.
> - Separate DMA enablement into follow-up work, retaining PIO operation
> for the H616 FIFO configuration.
> - Link to v2: https://lore.kernel.org/r/20261023-submit-h616-uart-fifo-v1-v2-0-af0593504635@gmail.com
>
> Changes in v2:
> - Keep PORT_16550A and set the FIFO size, transmit load and capabilities
> during setup, following Andy's review.
> - Select H616 setup through the matched platform-data pointer and remove
> the type and DMA burst-size platform-data members.
> - Use get_rxtrig/set_rxtrig for the 1/64/128/254-byte receive thresholds,
> with port locking and runtime PM around register updates. Keep the
> standard half-full FCR default, selecting 128 bytes on H616.
> - Advertise UART_CAP_AFE so CRTSCTS enables hardware automatic flow control.
> - Rebase onto next-20261023 and declare the posted sun6i pause/lifetime
> fixes and their prerequisites for DMA enablement.
> - Link to v1: https://lore.kernel.org/r/20261023-submit-h616-uart-fifo-v1-v1-0-e4a3bae2eba8@gmail.com
>
> To: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> To: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> To: Jiri Slaby <jirislaby@kernel.org>
> To: Rob Herring <robh@kernel.org>
> To: Krzysztof Kozlowski <krzk+dt@kernel.org>
> To: Conor Dooley <conor+dt@kernel.org>
> To: Chen-Yu Tsai <wens@kernel.org>
> To: Jernej Skrabec <jernej.skrabec@gmail.com>
> To: Samuel Holland <samuel@sholland.org>
> Cc: linux-kernel@vger.kernel.org
> Cc: linux-serial@vger.kernel.org
> Cc: devicetree@vger.kernel.org
> Cc: linux-arm-kernel@lists.infradead.org
> Cc: linux-sunxi@lists.linux.dev
>
> ---
> James Hilliard (5):
> serial: 8250_dw: select port setup through platform data
> serial: 8250: share the RX trigger conversion helper
> dt-bindings: serial: snps-dw-apb-uart: add Allwinner H616
> serial: 8250_dw: configure the Allwinner H616 UART
> arm64: dts: allwinner: h616: describe the UART integration
>
> .../bindings/serial/snps-dw-apb-uart.yaml | 1 +
> arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi | 12 +-
> drivers/tty/serial/8250/8250.h | 16 +++
> drivers/tty/serial/8250/8250_dw.c | 138 +++++++++++++++++++--
> drivers/tty/serial/8250/8250_port.c | 12 +-
> 5 files changed, 151 insertions(+), 28 deletions(-)
> ---
> base-commit: 6b4b543fa18757297ac756a6fe6e64f506b7844a
> change-id: 20261022-submit-h616-uart-fifo-v1-c5afcdfe5cb0
> prerequisite-message-id: <20261027-submit-serial-8250-dw-divisor-v1-v4-1-41714a75e15a@gmail.com>
> prerequisite-patch-id: d8219673210dac82d3adab41578ff2f76f5862c9
> prerequisite-message-id: <20261024-submit-serial-8250-rxtrig-lifetime-v1-v1-1-731b78d5003d@gmail.com>
> prerequisite-patch-id: 9a9395c715c2bf7bbcae5bdd16a339d7f2af6269
>
> Best regards,
> --
> James Hilliard <james.hilliard1@gmail.com>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v4 4/5] serial: 8250_dw: configure the Allwinner H616 UART
2026-10-28 8:53 ` James Hilliard
@ 2026-10-28 8:57 ` Ilpo Järvinen
0 siblings, 0 replies; 19+ messages in thread
From: Ilpo Järvinen @ 2026-10-28 8:57 UTC (permalink / raw)
To: James Hilliard
Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Andy Shevchenko, Chen-Yu Tsai, Jernej Skrabec,
Samuel Holland, LKML, linux-serial, devicetree, linux-arm-kernel,
linux-sunxi
[-- Attachment #1: Type: text/plain, Size: 9029 bytes --]
On Wed, 28 Oct 2026, James Hilliard wrote:
> On Wed, Oct 28, 2026 at 2:39 AM Ilpo Järvinen
> <ilpo.jarvinen@linux.intel.com> wrote:
> >
> > On Tue, 27 Oct 2026, James Hilliard wrote:
> >
> > > H616 has 256-byte transmit and receive FIFOs, but its optional DesignWare
> > > component parameter register reads as zero. Generic 16550 probing leaves
> > > the port using the 16-byte FIFO configuration and its trigger-level table.
> > >
> > > Keep PORT_16550A and describe H616's fixed 256-byte FIFO depth in platform
> > > data. Use common Allwinner setup helpers to configure the transmit load
> > > and receive trigger table from that depth.
> > >
> > > Derive the receive thresholds from the documented 1-byte, quarter-full,
> > > half-full and FIFO-depth-minus-two mapping. On H616 these are 1, 64, 128
> > > and 254 bytes; the normal 16550A half-full FCR setting selects 128 bytes.
> > >
> > > Build the threshold table during setup and use the shared 8250 conversion
> > > helper to select the nearest lower threshold for sysfs writes.
> >
> > You do that, I can see from the patch, but I came to read this changelog
> > to understand "why"?? You provide zero reasoning for this design decision.
> >
> > Since you fifosize is constant as well, so what benefit building it on the
> > fly servers?
>
> The intent is to keep the FIFO depth as the single platform-data input
> and derive the thresholds from the common Allwinner mapping. Other sunxi
> integrations using that mapping could then supply a different FIFO depth
> without duplicating the threshold table.
>
> Building the table once also lets get_rxtrig() and the shared
> bytes-to-FCR helper use the same derived values.
Okay, but it would be nice to mention that then in the changelog as the
justification.
> > > Serialize trigger changes with termios and hold a runtime PM reference
> > > while programming FCR, preserving the FIFO contents. Propagate runtime
> > > resume errors before changing either the FCR shadow or the hardware.
> > >
> > > Advertise automatic flow control so CRTSCTS enables MCR.AFCE. The
> > > DesignWare termios path selects hardware CTS handling, so the capability
> > > must be present for the corresponding hardware control to be enabled.
> > >
> > > Select the fixed configuration through the platform setup callback.
> > > H616 has debug-divisor and RS485 control registers at the offsets used to
> > > detect DesignWare hardware RS485 and fractional-divisor support. Avoid
> > > those probes and retain the BUSY-safe integer divisor hook and software
> > > RS485 handling.
> > >
> > > Use the existing SKIP_SET_RATE quirk to keep the UART clock enabled during
> > > termios changes. Its clock is a gate on the shared APB2 source, rather than
> > > an independent baud-rate generator.
> > >
> > > Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
> > > ---
> > > drivers/tty/serial/8250/8250_dw.c | 94 +++++++++++++++++++++++++++++++++++++++
> > > 1 file changed, 94 insertions(+)
> > >
> > > diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
> > > index 1351523f0c47..2f156c01c5a1 100644
> > > --- a/drivers/tty/serial/8250/8250_dw.c
> > > +++ b/drivers/tty/serial/8250/8250_dw.c
> > > @@ -19,6 +19,7 @@
> > > #include <linux/io.h>
> > > #include <linux/lockdep.h>
> > > #include <linux/module.h>
> > > +#include <linux/mutex.h>
> > > #include <linux/platform_device.h>
> > > #include <linux/pm_runtime.h>
> > > #include <linux/property.h>
> > > @@ -63,6 +64,7 @@
> > > struct dw8250_platform_data {
> > > u8 usr_reg;
> > > u32 cpr_value;
> > > + unsigned int fifo_size;
> > > unsigned int quirks;
> > > void (*setup)(struct uart_port *p);
> > > };
> > > @@ -81,6 +83,7 @@ struct dw8250_data {
> > > unsigned int in_idle:1;
> > >
> > > u8 no_int_count;
> > > + u8 rxtrig_bytes[UART_FCR_R_TRIG_MAX_STATE];
> > > };
> > >
> > > static inline struct dw8250_data *to_dw8250_data(struct dw8250_port_data *data)
> > > @@ -657,6 +660,89 @@ static void dw8250_octeon_setup(struct uart_port *p)
> > > dw8250_setup_dma(p);
> > > }
> > >
> > > +/* The trigger is the masked, unshifted FCR receive trigger field. */
> > > +static unsigned int dw8250_sunxi_rxtrig_bytes(struct uart_port *p, unsigned int trigger)
> > > +{
> > > + switch (trigger) {
> > > + case UART_FCR_TRIGGER_1:
> > > + return 1;
> > > + case UART_FCR_TRIGGER_4:
> > > + return p->fifosize / 4;
> > > + case UART_FCR_TRIGGER_8:
> > > + return p->fifosize / 2;
> > > + default:
> > > + return p->fifosize - 2;
> > > + }
> > > +}
> > > +
> > > +static int dw8250_sunxi_get_rxtrig(struct uart_port *p)
> > > +{
> > > + struct dw8250_data *data = to_dw8250_data(p->private_data);
> > > + struct uart_8250_port *up = up_to_u8250p(p);
> > > +
> > > + guard(uart_port_lock_irqsave)(p);
> > > +
> > > + return data->rxtrig_bytes[UART_FCR_R_TRIG_BITS(up->fcr)];
> > > +}
> > > +
> > > +static int dw8250_sunxi_set_rxtrig(struct uart_port *p, unsigned char bytes)
> > > +{
> > > + struct dw8250_data *data = to_dw8250_data(p->private_data);
> > > + struct uart_8250_port *up = up_to_u8250p(p);
> > > + int fcr, ret;
> > > +
> > > + fcr = serial8250_bytes_to_fcr(data->rxtrig_bytes, bytes);
> > > + if (fcr < 0)
> > > + return fcr;
> > > +
> > > + guard(mutex)(&p->state->port.mutex);
> > > +
> > > + PM_RUNTIME_ACQUIRE_IF_ENABLED(p->dev, pm);
> > > + ret = PM_RUNTIME_ACQUIRE_ERR(&pm);
> > > + if (ret)
> > > + return ret;
> > > +
> > > + guard(uart_port_lock_irqsave)(p);
> > > +
> > > + up->fcr &= ~UART_FCR_TRIGGER_MASK;
> > > + up->fcr |= fcr;
> > > + /* Changing the trigger alone preserves the FIFO contents. */
> > > + serial_port_out(p, UART_FCR, up->fcr);
> > > +
> > > + return 0;
> > > +}
> > > +
> > > +static void dw8250_sunxi_setup_rxtrig(struct uart_port *p)
> > > +{
> > > + struct dw8250_data *data = to_dw8250_data(p->private_data);
> > > +
> > > + /* Allwinner RX thresholds differ from the standard 16550A table. */
> > > + for (unsigned int i = 0; i < ARRAY_SIZE(data->rxtrig_bytes); i++)
> > > + data->rxtrig_bytes[i] = dw8250_sunxi_rxtrig_bytes(p, i << UART_FCR_R_TRIG_SHIFT);
> >
> > FIELD_PREP(UART_FCR_TRIGGER_MASK, i)
> >
> > For clarity, it might be useful to split it into two lines using an
> > intermediate variable.
> >
> > > + p->get_rxtrig = dw8250_sunxi_get_rxtrig;
> > > + p->set_rxtrig = dw8250_sunxi_set_rxtrig;
> > > +}
> > > +
> > > +static void dw8250_sunxi_setup(struct uart_port *p)
> > > +{
> > > + struct dw8250_data *data = to_dw8250_data(p->private_data);
> > > + struct uart_8250_port *up = up_to_u8250p(p);
> > > +
> > > + p->type = PORT_16550A;
> > > + p->flags |= UPF_FIXED_TYPE;
> > > + p->fifosize = data->pdata->fifo_size;
> > > + up->tx_loadsz = p->fifosize;
> > > + up->capabilities = UART_CAP_FIFO | UART_CAP_NOTEMT | UART_CAP_AFE;
> > > +
> > > + dw8250_sunxi_setup_rxtrig(p);
> > > +
> > > + /* Use software RS485 with the Allwinner register layout. */
> > > + p->rs485_config = serial8250_em485_config;
> > > + p->rs485_supported = serial8250_em485_supported;
> > > + up->rs485_start_tx = serial8250_em485_start_tx;
> > > + up->rs485_stop_tx = serial8250_em485_stop_tx;
> > > +}
> > > +
> > > static int dw8250_probe(struct platform_device *pdev)
> > > {
> > > struct uart_8250_port uart = {}, *up = &uart;
> > > @@ -878,6 +964,13 @@ static const struct dw8250_platform_data dw8250_dw_apb = {
> > > .usr_reg = DW_UART_USR,
> > > };
> > >
> > > +static const struct dw8250_platform_data dw8250_h616_data = {
> > > + .usr_reg = DW_UART_USR,
> > > + .fifo_size = 256,
> > > + .quirks = DW_UART_QUIRK_SKIP_SET_RATE,
> > > + .setup = dw8250_sunxi_setup,
> > > +};
> > > +
> > > static const struct dw8250_platform_data dw8250_octeon_3860_data = {
> > > .usr_reg = OCTEON_UART_USR,
> > > .quirks = DW_UART_QUIRK_OCTEON,
> > > @@ -929,6 +1022,7 @@ static const struct dw8250_platform_data dw8250_tda54 = {
> > >
> > > static const struct of_device_id dw8250_of_match[] = {
> > > { .compatible = "snps,dw-apb-uart", .data = &dw8250_dw_apb },
> > > + { .compatible = "allwinner,sun50i-h616-uart", .data = &dw8250_h616_data },
> > > { .compatible = "cavium,octeon-3860-uart", .data = &dw8250_octeon_3860_data },
> > > { .compatible = "marvell,armada-38x-uart", .data = &dw8250_armada_38x_data },
> > > { .compatible = "renesas,rzn1-uart", .data = &dw8250_renesas_rzn1_data },
> > >
> > >
> >
> > --
> > i.
> >
>
--
i.
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v4 0/5] serial: 8250_dw: describe the Allwinner H616 UART configuration
2026-10-28 8:57 ` [PATCH v4 0/5] serial: 8250_dw: describe the Allwinner H616 UART configuration Andre Przywara
@ 2026-10-28 9:04 ` James Hilliard
2026-10-28 9:04 ` Chen-Yu Tsai
1 sibling, 0 replies; 19+ messages in thread
From: James Hilliard @ 2026-10-28 9:04 UTC (permalink / raw)
To: Andre Przywara
Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Andy Shevchenko, Ilpo Järvinen, Chen-Yu Tsai,
Jernej Skrabec, Samuel Holland, linux-kernel, linux-serial,
devicetree, linux-arm-kernel, linux-sunxi
On Wed, Oct 28, 2026 at 2:57 AM Andre Przywara <andre.przywara@arm.com> wrote:
>
> Hi,
>
> On 10/28/26 00:05, James Hilliard wrote:
> > H616 has 256-byte UART FIFOs, but lacks the DesignWare component parameter
> > register used to discover their capacity. Its debug-divisor and RS485
> > registers also overlap offsets used to probe optional DesignWare features.
>
> that affects almost all Allwinner SoCs, not just the H616, so should be
> solved universally, not just for one SoC.
Some Allwinner SoC's can read fifo size from a non-standard
register from the looks of it.
This approach at least allows for just adding SoC appropriate
compatibles with their fifo-size tied to the compatible. Or the
fifo-size can be pulled via that FCC register on the fly and
reuse the code paths here probably by tying that logic to
the compatibles as well.
>
> IIUC Chen-Yu has a patch to attribute the right FIFO size, in each
> .dtsi, which I consider the best solution to this problem.
>
> I'd say we wait for -rc1 and then work on top of his patch.
>
> Cheers,
> Andre
>
> >
> > Add an H616 compatible for the integration-specific setup. Keep the
> > existing 16550A port type and describe its fixed FIFO depth in platform
> > data. Use common Allwinner helpers to configure the transmit load and
> > receive thresholds from that depth. Configure automatic flow control,
> > preserve the BUSY-safe integer divisor path and keep the UART gate enabled
> > during termios changes. The H616 configuration uses PIO.
> >
> > The series first introduces platform setup callbacks and a shared RX
> > trigger conversion helper, then adds the binding, H616 setup and SoC DTS
> > changes. Based on tty-next at 6b4b543fa187 with the posted RX
> > trigger callback-lifetime fix [0] and DW BUSY-safe divisor fix v4 [1].
> > Platform setup runs before installing the BUSY-safe divisor setter.
> >
> > [0] https://lore.kernel.org/r/20261024-submit-serial-8250-rxtrig-lifetime-v1-v1-1-731b78d5003d@gmail.com
> > [1] https://lore.kernel.org/r/20261027-submit-serial-8250-dw-divisor-v1-v4-1-41714a75e15a@gmail.com
> >
> > Assisted-by: Codex:gpt-6-astra
> > Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
> > ---
> > Changes in v4:
> > - Introduce common Allwinner setup helpers with the fixed FIFO depth
> > supplied by compatible-specific platform data.
> > - Rebase onto tty-next at 6b4b543fa187 and the posted DW divisor v4 fix,
> > installing the BUSY-safe setter after platform setup.
> > - Use an early return for FIFO-less DMA setup, following Andy's review.
> > - Default to generic setup when platform data has no setup callback.
> > - Select Octeon's optional-register discovery with IS_ENABLED() in its
> > setup helper, preserving the existing 32-bit and 64-bit behavior.
> > - Extract the shared 8250 bytes-to-FCR conversion, including the
> > unsupported-table check, into a preparatory patch and use it for
> > H616, following Andy's review.
> > - Set the fixed 256-byte FIFO depth in H616 platform data and omit
> > fifo-size from its binding and DTS, following Krzysztof's review.
> > - Precompute the Allwinner RX thresholds during setup and retain the
> > sunxi FIFO-depth helper for filling the table. Use named FCR encodings
> > in the helper, following Jiri's review.
> > - Share threshold-table initialization and callback assignment through
> > a sunxi RX trigger setup helper.
> > - Group and comment the H616 trigger and RS485 setup.
> > - Link to v3: https://patch.msgid.link/20261024-submit-h616-uart-fifo-v1-v3-0-286fc1b8c3c1@gmail.com
> >
> > Changes in v3:
> > - Introduce a platform-data setup callback in a preparatory patch,
> > replacing skip_autocfg and preserving the existing Octeon setup.
> > - Describe each H616 UART's FIFO capacity with the standard fifo-size DT
> > property and use the value already read by uart_read_port_properties().
> > - Derive the Allwinner RX trigger thresholds from the FIFO depth.
> > - Use an unsigned trigger index and conditional runtime PM guard,
> > preserving error propagation when the device cannot resume.
> > - Rebase onto tty-next, replacing the earlier DMA prerequisites with the
> > posted RX trigger callback-lifetime fix.
> > - Separate DMA enablement into follow-up work, retaining PIO operation
> > for the H616 FIFO configuration.
> > - Link to v2: https://lore.kernel.org/r/20261023-submit-h616-uart-fifo-v1-v2-0-af0593504635@gmail.com
> >
> > Changes in v2:
> > - Keep PORT_16550A and set the FIFO size, transmit load and capabilities
> > during setup, following Andy's review.
> > - Select H616 setup through the matched platform-data pointer and remove
> > the type and DMA burst-size platform-data members.
> > - Use get_rxtrig/set_rxtrig for the 1/64/128/254-byte receive thresholds,
> > with port locking and runtime PM around register updates. Keep the
> > standard half-full FCR default, selecting 128 bytes on H616.
> > - Advertise UART_CAP_AFE so CRTSCTS enables hardware automatic flow control.
> > - Rebase onto next-20261023 and declare the posted sun6i pause/lifetime
> > fixes and their prerequisites for DMA enablement.
> > - Link to v1: https://lore.kernel.org/r/20261023-submit-h616-uart-fifo-v1-v1-0-e4a3bae2eba8@gmail.com
> >
> > To: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> > To: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> > To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > To: Jiri Slaby <jirislaby@kernel.org>
> > To: Rob Herring <robh@kernel.org>
> > To: Krzysztof Kozlowski <krzk+dt@kernel.org>
> > To: Conor Dooley <conor+dt@kernel.org>
> > To: Chen-Yu Tsai <wens@kernel.org>
> > To: Jernej Skrabec <jernej.skrabec@gmail.com>
> > To: Samuel Holland <samuel@sholland.org>
> > Cc: linux-kernel@vger.kernel.org
> > Cc: linux-serial@vger.kernel.org
> > Cc: devicetree@vger.kernel.org
> > Cc: linux-arm-kernel@lists.infradead.org
> > Cc: linux-sunxi@lists.linux.dev
> >
> > ---
> > James Hilliard (5):
> > serial: 8250_dw: select port setup through platform data
> > serial: 8250: share the RX trigger conversion helper
> > dt-bindings: serial: snps-dw-apb-uart: add Allwinner H616
> > serial: 8250_dw: configure the Allwinner H616 UART
> > arm64: dts: allwinner: h616: describe the UART integration
> >
> > .../bindings/serial/snps-dw-apb-uart.yaml | 1 +
> > arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi | 12 +-
> > drivers/tty/serial/8250/8250.h | 16 +++
> > drivers/tty/serial/8250/8250_dw.c | 138 +++++++++++++++++++--
> > drivers/tty/serial/8250/8250_port.c | 12 +-
> > 5 files changed, 151 insertions(+), 28 deletions(-)
> > ---
> > base-commit: 6b4b543fa18757297ac756a6fe6e64f506b7844a
> > change-id: 20261022-submit-h616-uart-fifo-v1-c5afcdfe5cb0
> > prerequisite-message-id: <20261027-submit-serial-8250-dw-divisor-v1-v4-1-41714a75e15a@gmail.com>
> > prerequisite-patch-id: d8219673210dac82d3adab41578ff2f76f5862c9
> > prerequisite-message-id: <20261024-submit-serial-8250-rxtrig-lifetime-v1-v1-1-731b78d5003d@gmail.com>
> > prerequisite-patch-id: 9a9395c715c2bf7bbcae5bdd16a339d7f2af6269
> >
> > Best regards,
> > --
> > James Hilliard <james.hilliard1@gmail.com>
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v4 0/5] serial: 8250_dw: describe the Allwinner H616 UART configuration
2026-10-28 8:57 ` [PATCH v4 0/5] serial: 8250_dw: describe the Allwinner H616 UART configuration Andre Przywara
2026-10-28 9:04 ` James Hilliard
@ 2026-10-28 9:04 ` Chen-Yu Tsai
1 sibling, 0 replies; 19+ messages in thread
From: Chen-Yu Tsai @ 2026-10-28 9:04 UTC (permalink / raw)
To: Andre Przywara
Cc: James Hilliard, Greg Kroah-Hartman, Jiri Slaby, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Andy Shevchenko,
Ilpo Järvinen, Jernej Skrabec, Samuel Holland, linux-kernel,
linux-serial, devicetree, linux-arm-kernel, linux-sunxi
On Wed, Oct 28, 2026 at 4:57 PM Andre Przywara <andre.przywara@arm.com> wrote:
>
> Hi,
>
> On 10/28/26 00:05, James Hilliard wrote:
> > H616 has 256-byte UART FIFOs, but lacks the DesignWare component parameter
> > register used to discover their capacity. Its debug-divisor and RS485
> > registers also overlap offsets used to probe optional DesignWare features.
>
> that affects almost all Allwinner SoCs, not just the H616, so should be
> solved universally, not just for one SoC.
>
> IIUC Chen-Yu has a patch to attribute the right FIFO size, in each
> .dtsi, which I consider the best solution to this problem.
It only covers the recent ones, and Krzysztof didn't seem to like adding
the fifo-size property when it could be inferred from the compatible
string.
Otherwise, it is probably time to go through all the main SoCs we support
and check the differences :/
ChenYu
> I'd say we wait for -rc1 and then work on top of his patch.
>
> Cheers,
> Andre
>
> >
> > Add an H616 compatible for the integration-specific setup. Keep the
> > existing 16550A port type and describe its fixed FIFO depth in platform
> > data. Use common Allwinner helpers to configure the transmit load and
> > receive thresholds from that depth. Configure automatic flow control,
> > preserve the BUSY-safe integer divisor path and keep the UART gate enabled
> > during termios changes. The H616 configuration uses PIO.
> >
> > The series first introduces platform setup callbacks and a shared RX
> > trigger conversion helper, then adds the binding, H616 setup and SoC DTS
> > changes. Based on tty-next at 6b4b543fa187 with the posted RX
> > trigger callback-lifetime fix [0] and DW BUSY-safe divisor fix v4 [1].
> > Platform setup runs before installing the BUSY-safe divisor setter.
> >
> > [0] https://lore.kernel.org/r/20261024-submit-serial-8250-rxtrig-lifetime-v1-v1-1-731b78d5003d@gmail.com
> > [1] https://lore.kernel.org/r/20261027-submit-serial-8250-dw-divisor-v1-v4-1-41714a75e15a@gmail.com
> >
> > Assisted-by: Codex:gpt-6-astra
> > Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
> > ---
> > Changes in v4:
> > - Introduce common Allwinner setup helpers with the fixed FIFO depth
> > supplied by compatible-specific platform data.
> > - Rebase onto tty-next at 6b4b543fa187 and the posted DW divisor v4 fix,
> > installing the BUSY-safe setter after platform setup.
> > - Use an early return for FIFO-less DMA setup, following Andy's review.
> > - Default to generic setup when platform data has no setup callback.
> > - Select Octeon's optional-register discovery with IS_ENABLED() in its
> > setup helper, preserving the existing 32-bit and 64-bit behavior.
> > - Extract the shared 8250 bytes-to-FCR conversion, including the
> > unsupported-table check, into a preparatory patch and use it for
> > H616, following Andy's review.
> > - Set the fixed 256-byte FIFO depth in H616 platform data and omit
> > fifo-size from its binding and DTS, following Krzysztof's review.
> > - Precompute the Allwinner RX thresholds during setup and retain the
> > sunxi FIFO-depth helper for filling the table. Use named FCR encodings
> > in the helper, following Jiri's review.
> > - Share threshold-table initialization and callback assignment through
> > a sunxi RX trigger setup helper.
> > - Group and comment the H616 trigger and RS485 setup.
> > - Link to v3: https://patch.msgid.link/20261024-submit-h616-uart-fifo-v1-v3-0-286fc1b8c3c1@gmail.com
> >
> > Changes in v3:
> > - Introduce a platform-data setup callback in a preparatory patch,
> > replacing skip_autocfg and preserving the existing Octeon setup.
> > - Describe each H616 UART's FIFO capacity with the standard fifo-size DT
> > property and use the value already read by uart_read_port_properties().
> > - Derive the Allwinner RX trigger thresholds from the FIFO depth.
> > - Use an unsigned trigger index and conditional runtime PM guard,
> > preserving error propagation when the device cannot resume.
> > - Rebase onto tty-next, replacing the earlier DMA prerequisites with the
> > posted RX trigger callback-lifetime fix.
> > - Separate DMA enablement into follow-up work, retaining PIO operation
> > for the H616 FIFO configuration.
> > - Link to v2: https://lore.kernel.org/r/20261023-submit-h616-uart-fifo-v1-v2-0-af0593504635@gmail.com
> >
> > Changes in v2:
> > - Keep PORT_16550A and set the FIFO size, transmit load and capabilities
> > during setup, following Andy's review.
> > - Select H616 setup through the matched platform-data pointer and remove
> > the type and DMA burst-size platform-data members.
> > - Use get_rxtrig/set_rxtrig for the 1/64/128/254-byte receive thresholds,
> > with port locking and runtime PM around register updates. Keep the
> > standard half-full FCR default, selecting 128 bytes on H616.
> > - Advertise UART_CAP_AFE so CRTSCTS enables hardware automatic flow control.
> > - Rebase onto next-20261023 and declare the posted sun6i pause/lifetime
> > fixes and their prerequisites for DMA enablement.
> > - Link to v1: https://lore.kernel.org/r/20261023-submit-h616-uart-fifo-v1-v1-0-e4a3bae2eba8@gmail.com
> >
> > To: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
> > To: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
> > To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
> > To: Jiri Slaby <jirislaby@kernel.org>
> > To: Rob Herring <robh@kernel.org>
> > To: Krzysztof Kozlowski <krzk+dt@kernel.org>
> > To: Conor Dooley <conor+dt@kernel.org>
> > To: Chen-Yu Tsai <wens@kernel.org>
> > To: Jernej Skrabec <jernej.skrabec@gmail.com>
> > To: Samuel Holland <samuel@sholland.org>
> > Cc: linux-kernel@vger.kernel.org
> > Cc: linux-serial@vger.kernel.org
> > Cc: devicetree@vger.kernel.org
> > Cc: linux-arm-kernel@lists.infradead.org
> > Cc: linux-sunxi@lists.linux.dev
> >
> > ---
> > James Hilliard (5):
> > serial: 8250_dw: select port setup through platform data
> > serial: 8250: share the RX trigger conversion helper
> > dt-bindings: serial: snps-dw-apb-uart: add Allwinner H616
> > serial: 8250_dw: configure the Allwinner H616 UART
> > arm64: dts: allwinner: h616: describe the UART integration
> >
> > .../bindings/serial/snps-dw-apb-uart.yaml | 1 +
> > arch/arm64/boot/dts/allwinner/sun50i-h616.dtsi | 12 +-
> > drivers/tty/serial/8250/8250.h | 16 +++
> > drivers/tty/serial/8250/8250_dw.c | 138 +++++++++++++++++++--
> > drivers/tty/serial/8250/8250_port.c | 12 +-
> > 5 files changed, 151 insertions(+), 28 deletions(-)
> > ---
> > base-commit: 6b4b543fa18757297ac756a6fe6e64f506b7844a
> > change-id: 20261022-submit-h616-uart-fifo-v1-c5afcdfe5cb0
> > prerequisite-message-id: <20261027-submit-serial-8250-dw-divisor-v1-v4-1-41714a75e15a@gmail.com>
> > prerequisite-patch-id: d8219673210dac82d3adab41578ff2f76f5862c9
> > prerequisite-message-id: <20261024-submit-serial-8250-rxtrig-lifetime-v1-v1-1-731b78d5003d@gmail.com>
> > prerequisite-patch-id: 9a9395c715c2bf7bbcae5bdd16a339d7f2af6269
> >
> > Best regards,
> > --
> > James Hilliard <james.hilliard1@gmail.com>
>
>
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v4 2/5] serial: 8250: share the RX trigger conversion helper
2026-10-27 23:05 ` [PATCH v4 2/5] serial: 8250: share the RX trigger conversion helper James Hilliard
2026-10-28 8:30 ` Ilpo Järvinen
@ 2026-10-28 9:37 ` Andy Shevchenko
1 sibling, 0 replies; 19+ messages in thread
From: Andy Shevchenko @ 2026-10-28 9:37 UTC (permalink / raw)
To: James Hilliard
Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Ilpo Järvinen, Chen-Yu Tsai, Jernej Skrabec,
Samuel Holland, linux-kernel, linux-serial, devicetree,
linux-arm-kernel, linux-sunxi
On Tue, Oct 27, 2026 at 05:05:30PM -0600, James Hilliard wrote:
> Extract the receive-trigger threshold search into serial8250_bytes_to_fcr()
> so drivers with per-port threshold tables can use the same conversion as
> the generic 8250 implementation.
>
> Include the unsupported-table check in the helper and preserve the existing
> nearest-lower selection and highest-encoding fallback.
Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v4 2/5] serial: 8250: share the RX trigger conversion helper
2026-10-28 8:30 ` Ilpo Järvinen
@ 2026-10-28 9:38 ` Andy Shevchenko
0 siblings, 0 replies; 19+ messages in thread
From: Andy Shevchenko @ 2026-10-28 9:38 UTC (permalink / raw)
To: Ilpo Järvinen
Cc: James Hilliard, Greg Kroah-Hartman, Jiri Slaby, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Chen-Yu Tsai, Jernej Skrabec,
Samuel Holland, LKML, linux-serial, devicetree, linux-arm-kernel,
linux-sunxi
On Wed, Oct 28, 2026 at 10:30:07AM +0200, Ilpo Järvinen wrote:
> On Tue, 27 Oct 2026, James Hilliard wrote:
...
> > +static inline int serial8250_bytes_to_fcr(const unsigned char *rxtrig_bytes,
>
> This looks way to complicated to be inline function so I think it should
> be kept in 8250_port and exported from there.
Fine by me! James, my tags I gave in another reply stays if you move to
exported function.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v4 1/5] serial: 8250_dw: select port setup through platform data
2026-10-28 8:56 ` Andy Shevchenko
@ 2026-10-28 9:40 ` Andy Shevchenko
0 siblings, 0 replies; 19+ messages in thread
From: Andy Shevchenko @ 2026-10-28 9:40 UTC (permalink / raw)
To: James Hilliard
Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Ilpo Järvinen, Chen-Yu Tsai, Jernej Skrabec,
Samuel Holland, linux-kernel, linux-serial, devicetree,
linux-arm-kernel, linux-sunxi
On Wed, Oct 28, 2026 at 10:56:20AM +0200, Andy Shevchenko wrote:
> On Tue, Oct 27, 2026 at 05:05:29PM -0600, James Hilliard wrote:
...
> > + if (!IS_ENABLED(CONFIG_64BIT))
> > + dw8250_setup_port(p);
>
> I believe the Cavium OCTEON is 64-bit only platform, so you can just drop this
> conditional altogether.
Yes, confirmed. The only single ifdef is required when we use __raw_readq().
The second can be dropped. I will send a patch for that.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 19+ messages in thread
* Re: [PATCH v4 4/5] serial: 8250_dw: configure the Allwinner H616 UART
2026-10-27 23:05 ` [PATCH v4 4/5] serial: 8250_dw: configure the Allwinner H616 UART James Hilliard
2026-10-28 8:39 ` Ilpo Järvinen
@ 2026-10-28 11:05 ` Andy Shevchenko
1 sibling, 0 replies; 19+ messages in thread
From: Andy Shevchenko @ 2026-10-28 11:05 UTC (permalink / raw)
To: James Hilliard
Cc: Greg Kroah-Hartman, Jiri Slaby, Rob Herring, Krzysztof Kozlowski,
Conor Dooley, Ilpo Järvinen, Chen-Yu Tsai, Jernej Skrabec,
Samuel Holland, linux-kernel, linux-serial, devicetree,
linux-arm-kernel, linux-sunxi
On Tue, Oct 27, 2026 at 05:05:32PM -0600, James Hilliard wrote:
> H616 has 256-byte transmit and receive FIFOs, but its optional DesignWare
> component parameter register reads as zero. Generic 16550 probing leaves
> the port using the 16-byte FIFO configuration and its trigger-level table.
>
> Keep PORT_16550A and describe H616's fixed 256-byte FIFO depth in platform
> data. Use common Allwinner setup helpers to configure the transmit load
> and receive trigger table from that depth.
>
> Derive the receive thresholds from the documented 1-byte, quarter-full,
> half-full and FIFO-depth-minus-two mapping. On H616 these are 1, 64, 128
> and 254 bytes; the normal 16550A half-full FCR setting selects 128 bytes.
>
> Build the threshold table during setup and use the shared 8250 conversion
> helper to select the nearest lower threshold for sysfs writes.
>
> Serialize trigger changes with termios and hold a runtime PM reference
> while programming FCR, preserving the FIFO contents. Propagate runtime
> resume errors before changing either the FCR shadow or the hardware.
>
> Advertise automatic flow control so CRTSCTS enables MCR.AFCE. The
> DesignWare termios path selects hardware CTS handling, so the capability
> must be present for the corresponding hardware control to be enabled.
>
> Select the fixed configuration through the platform setup callback.
> H616 has debug-divisor and RS485 control registers at the offsets used to
> detect DesignWare hardware RS485 and fractional-divisor support. Avoid
> those probes and retain the BUSY-safe integer divisor hook and software
> RS485 handling.
>
> Use the existing SKIP_SET_RATE quirk to keep the UART clock enabled during
> termios changes. Its clock is a gate on the shared APB2 source, rather than
> an independent baud-rate generator.
...
> + unsigned int fifo_size;
This is should come from DT (based on the property or compatible),
...
> u8 no_int_count;
> + u8 rxtrig_bytes[UART_FCR_R_TRIG_MAX_STATE];
Why do you need it here? Can it be provided via driver_data?
...
> +/* The trigger is the masked, unshifted FCR receive trigger field. */
> +static unsigned int dw8250_sunxi_rxtrig_bytes(struct uart_port *p, unsigned int trigger)
> +{
> + switch (trigger) {
> + case UART_FCR_TRIGGER_1:
> + return 1;
> + case UART_FCR_TRIGGER_4:
> + return p->fifosize / 4;
> + case UART_FCR_TRIGGER_8:
> + return p->fifosize / 2;
> + default:
> + return p->fifosize - 2;
> + }
> +}
You don't need this, just provide a set of numbers directly.
--
With Best Regards,
Andy Shevchenko
^ permalink raw reply [flat|nested] 19+ messages in thread
end of thread, other threads:[~2026-10-28 11:05 UTC | newest]
Thread overview: 19+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-27 23:05 [PATCH v4 0/5] serial: 8250_dw: describe the Allwinner H616 UART configuration James Hilliard
2026-10-27 23:05 ` [PATCH v4 1/5] serial: 8250_dw: select port setup through platform data James Hilliard
2026-10-28 8:56 ` Andy Shevchenko
2026-10-28 9:40 ` Andy Shevchenko
2026-10-27 23:05 ` [PATCH v4 2/5] serial: 8250: share the RX trigger conversion helper James Hilliard
2026-10-28 8:30 ` Ilpo Järvinen
2026-10-28 9:38 ` Andy Shevchenko
2026-10-28 9:37 ` Andy Shevchenko
2026-10-27 23:05 ` [PATCH v4 3/5] dt-bindings: serial: snps-dw-apb-uart: add Allwinner H616 James Hilliard
2026-10-28 8:06 ` Krzysztof Kozlowski
2026-10-27 23:05 ` [PATCH v4 4/5] serial: 8250_dw: configure the Allwinner H616 UART James Hilliard
2026-10-28 8:39 ` Ilpo Järvinen
2026-10-28 8:53 ` James Hilliard
2026-10-28 8:57 ` Ilpo Järvinen
2026-10-28 11:05 ` Andy Shevchenko
2026-10-27 23:05 ` [PATCH v4 5/5] arm64: dts: allwinner: h616: describe the UART integration James Hilliard
2026-10-28 8:57 ` [PATCH v4 0/5] serial: 8250_dw: describe the Allwinner H616 UART configuration Andre Przywara
2026-10-28 9:04 ` James Hilliard
2026-10-28 9:04 ` Chen-Yu Tsai
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®