OSDN Git Service

greybus: uart: Add gb_uart_request_recv for receiving async UART data
authorBryan O'Donoghue <bryan.odonoghue@linaro.org>
Tue, 2 Jun 2015 12:40:50 +0000 (13:40 +0100)
committerGreg Kroah-Hartman <gregkh@google.com>
Thu, 4 Jun 2015 05:11:05 +0000 (14:11 +0900)
gb_uart_request_recv job in life is to process unsolicited greybus
mesages from the UART.
Hook the incoming UART data and pass to the TTY layer.
Line-state changes still TBD.

Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
drivers/staging/greybus/uart.c

index ed03ba4..2d19d39 100644 (file)
@@ -70,6 +70,47 @@ static atomic_t reference_count = ATOMIC_INIT(0);
 /* Define get_version() routine */
 define_get_version(gb_tty, UART);
 
+static int gb_uart_request_recv(u8 type, struct gb_operation *op)
+{
+       struct gb_connection *connection = op->connection;
+       struct gb_tty *gb_tty = connection->private;
+       struct gb_message *request = op->request;
+       struct gb_uart_recv_data_request *receive_data;
+       struct gb_uart_serial_state_request *serial_state;
+       struct tty_port *port = &gb_tty->port;
+       int count;
+       int ret = 0;
+
+       switch (type) {
+       case GB_UART_TYPE_RECEIVE_DATA:
+               receive_data = request->payload;
+               count = gb_tty->buffer_payload_max - sizeof(*receive_data);
+               if (!receive_data->size || receive_data->size > count)
+                       return -EINVAL;
+
+               count = tty_insert_flip_string(port, receive_data->data,
+                                              receive_data->size);
+               if (count != receive_data->size) {
+                       dev_err(&connection->dev,
+                               "UART: RX 0x%08x bytes only wrote 0x%08x\n",
+                               receive_data->size, count);
+               }
+               if (count)
+                       tty_flip_buffer_push(port);
+               break;
+       case GB_UART_TYPE_SERIAL_STATE:
+               serial_state = request->payload;
+               /* TODO: Parse state change and translate to tty API. */
+               break;
+       default:
+               dev_err(&connection->dev,
+                       "unsupported unsolicited request: %02x\n", type);
+               ret = -EINVAL;
+       }
+
+       return ret;
+}
+
 static int send_data(struct gb_tty *tty, u16 size, const u8 *data)
 {
        struct gb_uart_send_data_request *request;
@@ -703,7 +744,7 @@ static struct gb_protocol uart_protocol = {
        .minor                  = 1,
        .connection_init        = gb_uart_connection_init,
        .connection_exit        = gb_uart_connection_exit,
-       .request_recv           = NULL, /* FIXME we have 2 types of requests!!! */
+       .request_recv           = gb_uart_request_recv,
 };
 
 gb_gpbridge_protocol_driver(uart_protocol);