summaryrefslogtreecommitdiff
path: root/include/linux/serial_core.h
diff options
context:
space:
mode:
authorIlpo Järvinen <ilpo.jarvinen@linux.intel.com>2022-06-13 14:39:05 +0300
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2022-06-27 14:34:45 +0200
commitf9008285bb69e4713918a665250ab2d356b731ba (patch)
treedd37d533edbf6b5fb962959ecc1484054e932903 /include/linux/serial_core.h
parentab24a01b276508dc884761bcb8e2759c36702377 (diff)
serial: Drop timeout from uart_port
Since commit 31f6bd7fad3b ("serial: Store character timing information to uart_port"), per frame timing information is available on uart_port. Uart port's timeout can be derived from frame_time by multiplying with fifosize. Most callers of uart_poll_timeout are not made under port's lock. To be on the safe side, make sure frame_time is only accessed once. As fifo_size is effectively a constant, it shouldn't cause any issues. Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com> Link: https://lore.kernel.org/r/20220613113905.22962-1-ilpo.jarvinen@linux.intel.com Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'include/linux/serial_core.h')
-rw-r--r--include/linux/serial_core.h16
1 files changed, 14 insertions, 2 deletions
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 8032ffa741ed..faaf2372c60d 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -232,7 +232,6 @@ struct uart_port {
int hw_stopped; /* sw-assisted CTS flow state */
unsigned int mctrl; /* current modem ctrl settings */
- unsigned int timeout; /* character-based timeout */
unsigned int frame_time; /* frame timing in ns */
unsigned int type; /* port type */
const struct uart_ops *ops;
@@ -335,10 +334,23 @@ unsigned int uart_get_baud_rate(struct uart_port *port, struct ktermios *termios
unsigned int max);
unsigned int uart_get_divisor(struct uart_port *port, unsigned int baud);
+/*
+ * Calculates FIFO drain time.
+ */
+static inline unsigned long uart_fifo_timeout(struct uart_port *port)
+{
+ u64 fifo_timeout = (u64)READ_ONCE(port->frame_time) * port->fifosize;
+
+ /* Add .02 seconds of slop */
+ fifo_timeout += 20 * NSEC_PER_MSEC;
+
+ return max(nsecs_to_jiffies(fifo_timeout), 1UL);
+}
+
/* Base timer interval for polling */
static inline int uart_poll_timeout(struct uart_port *port)
{
- int timeout = port->timeout;
+ int timeout = uart_fifo_timeout(port);
return timeout > 6 ? (timeout / 2 - 2) : 1;
}