[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <20251130104222.63077-21-crescentcy.hsieh@moxa.com>
Date: Sun, 30 Nov 2025 18:42:11 +0800
From: Crescent Hsieh <crescentcy.hsieh@...a.com>
To: gregkh@...uxfoundation.org,
jirislaby@...nel.org,
ilpo.jarvinen@...ux.intel.com,
andy.shevchenko@...il.com
Cc: linux-kernel@...r.kernel.org,
linux-serial@...r.kernel.org,
crescentcy.hsieh@...a.com
Subject: [PATCH v1 20/31] serial: 8250: add optional callbacks for rx_trig_bytes
The rx_trig_bytes sysfs attribute adjusts the UART RX FIFO trigger
level. Some modern 8250 variants require programming device-specific
registers to change this threshold, which the generic (FCR-based) path
does not cover.
This patch adds two optional uart_port callbacks:
- set_rxtrig(port, bytes): program a device-specific RX trigger threshold
- get_rxtrig(port): read back the current RX trigger threshold
When these callbacks are provided, the 8250 core will use them to
set/read the hardware-specific threshold. If the callbacks are not
implemented, the code falls back to the legacy generic path, so existing
drivers keep their current behavior.
No functional change for drivers that do not implement the new
callbacks.
Signed-off-by: Crescent Hsieh <crescentcy.hsieh@...a.com>
---
drivers/tty/serial/8250/8250_core.c | 4 ++++
drivers/tty/serial/8250/8250_port.c | 16 ++++++++++++++--
include/linux/serial_core.h | 2 ++
3 files changed, 20 insertions(+), 2 deletions(-)
diff --git a/drivers/tty/serial/8250/8250_core.c b/drivers/tty/serial/8250/8250_core.c
index f642e8c77911..3d8575874759 100644
--- a/drivers/tty/serial/8250/8250_core.c
+++ b/drivers/tty/serial/8250/8250_core.c
@@ -808,6 +808,10 @@ int serial8250_register_8250_port(const struct uart_8250_port *up)
uart->port.pm = up->port.pm;
if (up->port.handle_break)
uart->port.handle_break = up->port.handle_break;
+ if (up->port.set_rxtrig)
+ uart->port.set_rxtrig = up->port.set_rxtrig;
+ if (up->port.get_rxtrig)
+ uart->port.get_rxtrig = up->port.get_rxtrig;
if (up->dl_read)
uart->dl_read = up->dl_read;
if (up->dl_write)
diff --git a/drivers/tty/serial/8250/8250_port.c b/drivers/tty/serial/8250/8250_port.c
index 64896f37b75d..d7baceacd4ff 100644
--- a/drivers/tty/serial/8250/8250_port.c
+++ b/drivers/tty/serial/8250/8250_port.c
@@ -3104,9 +3104,15 @@ static ssize_t rx_trig_bytes_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct tty_port *port = dev_get_drvdata(dev);
+ struct uart_state *state = container_of(port, struct uart_state, port);
+ struct uart_port *uport = state->uart_port;
int rxtrig_bytes;
- rxtrig_bytes = do_serial8250_get_rxtrig(port);
+ if (uport->get_rxtrig)
+ rxtrig_bytes = uport->get_rxtrig(uport);
+ else
+ rxtrig_bytes = do_serial8250_get_rxtrig(port);
+
if (rxtrig_bytes < 0)
return rxtrig_bytes;
@@ -3149,6 +3155,8 @@ static ssize_t rx_trig_bytes_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct tty_port *port = dev_get_drvdata(dev);
+ struct uart_state *state = container_of(port, struct uart_state, port);
+ struct uart_port *uport = state->uart_port;
unsigned char bytes;
int ret;
@@ -3159,7 +3167,11 @@ static ssize_t rx_trig_bytes_store(struct device *dev,
if (ret < 0)
return ret;
- ret = do_serial8250_set_rxtrig(port, bytes);
+ if (uport->set_rxtrig)
+ ret = uport->set_rxtrig(uport, bytes);
+ else
+ ret = do_serial8250_set_rxtrig(port, bytes);
+
if (ret < 0)
return ret;
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 1aa07c5187d8..96646d3f2943 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -456,6 +456,8 @@ struct uart_port {
void (*pm)(struct uart_port *, unsigned int state,
unsigned int old);
void (*handle_break)(struct uart_port *);
+ int (*set_rxtrig)(struct uart_port *, unsigned char);
+ int (*get_rxtrig)(struct uart_port *);
int (*rs485_config)(struct uart_port *,
struct ktermios *termios,
struct serial_rs485 *rs485);
--
2.45.2
Powered by blists - more mailing lists