serial: 8250: add serial_in_poll_timeout helper

A patch from »serial: 8250: Add rs485 emulation to 8250_dw« in state Mainline for linux-kernel

From: Heiko Stuebner <heiko.stuebner@...> Date: Wed, 18 Mar 2020 15:08:34 +0100

Commit-Message

In cases where a serial register needs to be polled until a specific state, this should have a timeout as noted in the thread bringing em485 support to 8250_dw. To not re-implement timeout handling in each case, add a helper modelled after readx_poll_timeout / regmap_read_poll_timeout to facilitate this. Signed-off-by: Heiko Stuebner <heiko.stuebner@...>

Patch-Comment

drivers/tty/serial/8250/8250.h | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+)

Statistics

  • 34 lines added
  • 0 lines removed

Changes

------------------------ drivers/tty/serial/8250/8250.h ------------------------
index 33ad9d6de532..50a4c174410d 100644
@@ -118,6 +118,40 @@ static inline void serial_out(struct uart_8250_port *up, int offset, int value)
up->port.serial_out(&up->port, offset, value);
}
+/**
+ * serial_in_poll_timeout - Poll until a condition is met or a timeout occurs
+ *
+ * @port: uart_8250_port to read from
+ * @offs: Offset to poll
+ * @val: Integer variable to read the value into
+ * @cond: Break condition (usually involving @val)
+ * @timeout_us: Timeout in us, 0 means never timeout
+ *
+ * Returns 0 on success and -ETIMEDOUT upon a timeout or the serial_in
+ * error return value in case of a error read.
+ *
+ * This is modelled after the readx_poll_timeout macros in linux/iopoll.h.
+ */
+#define serial_in_poll_timeout(port, offs, val, cond, timeout_us) \
+({ \
+ u64 __timeout_us = (timeout_us); \
+ ktime_t __timeout = ktime_add_us(ktime_get(), __timeout_us); \
+ for (;;) { \
+ val = serial_in((port), (offs)); \
+ if (val < 0) \
+ break; \
+ if (cond) \
+ break; \
+ if ((__timeout_us) && \
+ ktime_compare(ktime_get(), __timeout) > 0) { \
+ val = serial_in((port), (offs)); \
+ break; \
+ } \
+ cpu_relax(); \
+ } \
+ (val < 0) ? val : ((cond) ? 0 : -ETIMEDOUT); \
+})
+
void serial8250_clear_and_reinit_fifos(struct uart_8250_port *p);
static inline int serial_dl_read(struct uart_8250_port *up)
 
 

Recent Patches

About Us

Sed lacus. Donec lectus. Nullam pretium nibh ut turpis. Nam bibendum. In nulla tortor, elementum vel, tempor at, varius non, purus. Mauris vitae nisl nec metus placerat consectetuer.

Read More...