summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/staging/greybus/greybus_protocols.h7
-rw-r--r--drivers/staging/greybus/uart.c15
2 files changed, 22 insertions, 0 deletions
diff --git a/drivers/staging/greybus/greybus_protocols.h b/drivers/staging/greybus/greybus_protocols.h
index 089751c24117..ff371c44cdf4 100644
--- a/drivers/staging/greybus/greybus_protocols.h
+++ b/drivers/staging/greybus/greybus_protocols.h
@@ -1270,6 +1270,7 @@ struct gb_raw_send_request {
#define GB_UART_TYPE_SEND_BREAK 0x06
#define GB_UART_TYPE_SERIAL_STATE 0x07 /* Unsolicited data */
#define GB_UART_TYPE_RECEIVE_CREDITS 0x08
+#define GB_UART_TYPE_FLUSH_FIFOS 0x09
/* Represents data from AP -> Module */
struct gb_uart_send_data_request {
@@ -1335,6 +1336,12 @@ struct gb_uart_serial_state_request {
__u8 control;
} __packed;
+struct gb_uart_serial_flush_request {
+ __u8 flags;
+#define GB_SERIAL_FLAG_FLUSH_TRANSMITTER 0x01
+#define GB_SERIAL_FLAG_FLUSH_RECEIVER 0x02
+} __packed;
+
/* Loopback */
/* Version of the Greybus loopback protocol we support */
diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c
index 14b3e9d06e9c..7dc9f9b873b1 100644
--- a/drivers/staging/greybus/uart.c
+++ b/drivers/staging/greybus/uart.c
@@ -317,6 +317,14 @@ static int send_break(struct gb_tty *gb_tty, u8 state)
&request, sizeof(request), NULL, 0);
}
+static int gb_uart_flush(struct gb_tty *gb_tty, u8 flags)
+{
+ struct gb_uart_serial_flush_request request;
+
+ request.flags = flags;
+ return gb_operation_sync(gb_tty->connection, GB_UART_TYPE_FLUSH_FIFOS,
+ &request, sizeof(request), NULL, 0);
+}
static struct gb_tty *get_gb_by_minor(unsigned minor)
{
@@ -745,6 +753,7 @@ static void gb_tty_port_shutdown(struct tty_port *port)
{
struct gb_tty *gb_tty;
unsigned long flags;
+ int ret;
gb_tty = container_of(port, struct gb_tty, port);
@@ -756,6 +765,12 @@ static void gb_tty_port_shutdown(struct tty_port *port)
kfifo_reset_out(&gb_tty->write_fifo);
spin_unlock_irqrestore(&gb_tty->write_lock, flags);
+ ret = gb_uart_flush(gb_tty, GB_SERIAL_FLAG_FLUSH_TRANSMITTER);
+ if (ret) {
+ dev_err(&gb_tty->gbphy_dev->dev,
+ "error flushing transmitter: %d\n", ret);
+ }
+
gb_tty->close_pending = false;
}