]> asedeno.scripts.mit.edu Git - linux.git/commitdiff
greybus: uart: Implement flush_buffer
authorAxel Haslam <ahaslam@baylibre.com>
Tue, 31 May 2016 12:36:12 +0000 (14:36 +0200)
committerGreg Kroah-Hartman <gregkh@google.com>
Wed, 1 Jun 2016 00:18:18 +0000 (17:18 -0700)
Data may be held pening in the hardware because of flow
control mechanisms. When the port is closed, we need to flush
all data that was not sent.

For this, use the greybus message GB_UART_TYPE_FLUSH_FIFOS
which will flush all data queued on the module but not
yet sent on the data line.

Suggested-by: Johan Hovold <johan@hovoldconsulting.com>
Signed-off-by: Axel Haslam <ahaslam@baylibre.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
drivers/staging/greybus/greybus_protocols.h
drivers/staging/greybus/uart.c

index 089751c24117efaa03056047bf9a0dea75cfb78b..ff371c44cdf4563659c980d24918a15c18a543d7 100644 (file)
@@ -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 */
index 14b3e9d06e9c15d328e10596272177cc77edbfbb..7dc9f9b873b198439a960ab5f9347b77c720e900 100644 (file)
@@ -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;
 }