From: Michael Zaidman <michael.zaidman@gmail.com>
To: chrysh@christina-quast.de, daniel.beer@igorinstitute.com,
jikos@kernel.org
Cc: linux-kernel@vger.kernel.org, linux-input@vger.kernel.org,
linux-serial@vger.kernel.org, ilpo.jarvinen@linux.intel.com,
johan@kernel.org, gregkh@linuxfoundation.org, equinox@diac24.net,
michael.zaidman@gmail.com
Subject: [PATCH v1 18/19] hid-ft260: uart: fix rx data loss after device reopening
Date: Sat, 10 Feb 2024 23:51:46 +0200 [thread overview]
Message-ID: <20240210215147.77629-19-michael.zaidman@gmail.com> (raw)
In-Reply-To: <20240210215147.77629-1-michael.zaidman@gmail.com>
The port setting may remain intact after session termination. Then, when
reopening the port without configuring the port setting, the wakeup
mechanism is not activated, and UART Rx loses the data at speeds greater
than 4800 bauds. To fix it, retrieve the baud rate from the device in the
ft260_uart_port_activate to reactivate the wakeup workaround if needed.
Example:
1. Configure the baud rate to 115200:
$ sudo picocom -f n -p n -d 8 -b 115200 /dev/ttyFT0
2. Quit the picocom without resetting port setting by entering:
C-a and C-q
It deactivates the wakeup workaround:
[31677.005464] ft260_uart_close:
[31677.005466] ft260_uart_chars_in_buffer:
[31677.005467] ft260_uart_port_shutdown:
[31677.005468] ft260_uart_wakeup_workaraund_enable: deactivate wakeup workaround
[31677.005476] ft260_uart_cleanup:
[31677.005477] ft260_uart_port_put:
3. Reopen the ttyFT0 port, but do not configure it. The fix retrieves the port
baud rate from the device, compares it against the threshold, and activates
the wakeup mechanism when needed.
$ sudo bash -c "cat < /dev/ttyFT0"
[31693.304991] ft260_uart_port_get:
[31693.304995] ft260_uart_install:
[31693.305000] ft260_uart_open:
[31693.305001] ft260_uart_port_activate:
[31693.309842] ft260_uart_wakeup_workaraund_enable: activate wakeup workaround
[31693.309847] ft260_uart_port_activate: configurd baudrate = 115200
[31698.132650] ft260_uart_start_wakeup:
[31698.132809] ft260_uart_do_wakeup:
[31698.132817] ft260_uart_wakeup:
[31702.996905] ft260_uart_start_wakeup:
[31702.996916] ft260_uart_do_wakeup:
Signed-off-by: Michael Zaidman <michael.zaidman@gmail.com>
---
drivers/hid/hid-ft260.c | 56 ++++++++++++++++++++++++++++++++++-------
1 file changed, 47 insertions(+), 9 deletions(-)
diff --git a/drivers/hid/hid-ft260.c b/drivers/hid/hid-ft260.c
index 7f3ef4f20075..6b172bfa4f98 100644
--- a/drivers/hid/hid-ft260.c
+++ b/drivers/hid/hid-ft260.c
@@ -90,7 +90,7 @@ enum {
FT260_I2C_REPORT_MAX = 0xDE,
FT260_GPIO = 0xB0,
FT260_UART_INTERRUPT_STATUS = 0xB1,
- FT260_UART_STATUS = 0xE0,
+ FT260_UART_SETTINGS = 0xE0,
FT260_UART_RI_DCD_STATUS = 0xE1,
FT260_UART_REPORT_MIN = 0xF0,
FT260_UART_REPORT_MAX = 0xFE,
@@ -190,6 +190,18 @@ struct ft260_get_i2c_status_report {
u8 reserved;
} __packed;
+struct ft260_get_uart_settings_report {
+ u8 report; /* FT260_UART_SETTINGS */
+ u8 flow_ctrl; /* 0 - OFF; 1 - RTS_CTS, 2 - DTR_DSR, */
+ /* 3 - XON_XOFF, 4 - No flow control */
+ /* The baudrate field is unaligned */
+ __le32 baudrate; /* little endian, 9600 = 0x2580, 19200 = 0x4B00 */
+ u8 data_bit; /* 7 or 8 */
+ u8 parity; /* 0: no parity, 1: odd, 2: even, 3: high, 4: low */
+ u8 stop_bit; /* 0: one stop bit, 2: 2 stop bits */
+ u8 breaking; /* 0: no break */
+} __packed;
+
/* Feature Out reports */
struct ft260_set_system_clock_report {
@@ -1050,6 +1062,21 @@ static LIST_HEAD(ft260_uart_device_list);
static void ft260_uart_wakeup(struct ft260_device *dev);
+static int ft260_get_uart_settings(struct hid_device *hdev,
+ struct ft260_get_uart_settings_report *cfg)
+{
+ int ret;
+ int len = sizeof(struct ft260_get_uart_settings_report);
+
+ ret = ft260_hid_feature_report_get(hdev, FT260_UART_SETTINGS,
+ (u8 *)cfg, len);
+ if (ret < 0) {
+ hid_err(hdev, "failed to retrieve uart settings\n");
+ return ret;
+ }
+ return 0;
+}
+
static void ft260_uart_wakeup_workaraund_enable(struct ft260_device *port,
bool enable)
{
@@ -1492,13 +1519,11 @@ static void ft260_uart_port_shutdown(struct tty_port *tport)
static int ft260_uart_port_activate(struct tty_port *tport, struct tty_struct *tty)
{
- struct ft260_device *port =
- container_of(tport, struct ft260_device, port);
+ int ret;
+ int baudrate;
+ struct ft260_get_uart_settings_report cfg;
+ struct ft260_device *port = container_of(tport, struct ft260_device, port);
- /*
- * Set the TTY IO error marker - we will only clear this
- * once we have successfully opened the port.
- */
set_bit(TTY_IO_ERROR, &tty->flags);
spin_lock(&port->xmit_fifo_lock);
@@ -1507,8 +1532,21 @@ static int ft260_uart_port_activate(struct tty_port *tport, struct tty_struct *t
clear_bit(TTY_IO_ERROR, &tty->flags);
- /* Wake up the chip as early as possible to not miss incoming data */
- ft260_uart_wakeup(port);
+ /*
+ * The port setting may remain intact after session termination.
+ * Then, when reopening the port without configuring the port
+ * setting, we need to retrieve the baud rate from the device to
+ * reactivate the wakeup workaround if needed.
+ */
+ ret = ft260_get_uart_settings(port->hdev, &cfg);
+ if (ret)
+ return ret;
+
+ baudrate = get_unaligned_le32(&cfg.baudrate);
+ if (baudrate > FT260_UART_EN_PW_SAVE_BAUD)
+ ft260_uart_wakeup_workaraund_enable(port, true);
+
+ ft260_dbg("configurd baudrate = %d", baudrate);
mod_timer(&port->wakeup_timer, jiffies +
msecs_to_jiffies(FT260_WAKEUP_NEEDED_AFTER_MS));
--
2.40.1
next prev parent reply other threads:[~2024-02-10 21:53 UTC|newest]
Thread overview: 23+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-02-10 21:51 [PATCH v1 00/19] hid-ft260: Fixes for serial driver patch v4 Michael Zaidman
2024-02-10 21:51 ` [PATCH v1 01/19] hid-ft260: fix incompatible-pointer-types error Michael Zaidman
2024-02-10 21:51 ` [PATCH v1 02/19] hid-ft260: fix Wformat warning Michael Zaidman
2024-02-10 21:51 ` [PATCH v1 03/19] hid-ft260: fix i2c driver regression in ft260_raw_event Michael Zaidman
2024-02-10 21:51 ` [PATCH v1 04/19] hid-ft260: remove dead code in ft260_uart_receive_chars Michael Zaidman
2024-02-10 21:51 ` [PATCH v1 05/19] hid-ft260: fix unprotected write_buf concurrent access Michael Zaidman
2024-02-10 21:51 ` [PATCH v1 06/19] hid-ft260: uart: enable wakeup workaround Michael Zaidman
2024-02-10 21:51 ` [PATCH v1 07/19] hid-ft260: depend wakeup workaround activation on uart baud rate Michael Zaidman
2024-02-10 21:51 ` [PATCH v1 08/19] hid-ft260: depend wakeup workaround activation on eeprom config Michael Zaidman
2024-02-10 21:51 ` [PATCH v1 09/19] hid-ft260: uart: wakeup device early to not lose rx data Michael Zaidman
2024-02-10 21:51 ` [PATCH v1 10/19] hid-ft260: uart: do not configure baud rate twice Michael Zaidman
2024-02-10 21:51 ` [PATCH v1 11/19] hid-ft260: uart: do not disable wakeup workaround twice Michael Zaidman
2024-02-10 21:51 ` [PATCH v1 12/19] hid-ft260: uart: use kfifo_avail for fifo write room check Michael Zaidman
2024-02-10 21:51 ` [PATCH v1 13/19] hid-ft260: improve usb interface type detection logic Michael Zaidman
2024-02-10 21:51 ` [PATCH v1 14/19] hid-ft260: uart: cleanup and refactoring Michael Zaidman
2024-02-10 21:51 ` [PATCH v1 15/19] hid-ft260: uart: remove FIXME for wake-up workaround Michael Zaidman
2024-02-10 21:51 ` [PATCH v1 16/19] hid-ft260: uart: suppress unhandled report 0xb1 dmesg Michael Zaidman
2024-02-10 21:51 ` [PATCH v1 17/19] hid-ft260: uart: arm wake-up timer unconditionally on tty session start Michael Zaidman
2024-02-10 21:51 ` Michael Zaidman [this message]
2024-02-10 21:51 ` [PATCH v1 19/19] hid-ft260: uart: improve write performance Michael Zaidman
2024-02-23 21:22 ` Michael Zaidman
2024-02-13 10:20 ` [PATCH v1 00/19] hid-ft260: Fixes for serial driver patch v4 Jiri Kosina
2024-02-23 13:07 ` Christina Quast
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20240210215147.77629-19-michael.zaidman@gmail.com \
--to=michael.zaidman@gmail.com \
--cc=chrysh@christina-quast.de \
--cc=daniel.beer@igorinstitute.com \
--cc=equinox@diac24.net \
--cc=gregkh@linuxfoundation.org \
--cc=ilpo.jarvinen@linux.intel.com \
--cc=jikos@kernel.org \
--cc=johan@kernel.org \
--cc=linux-input@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-serial@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).