diff options
author | Bryan O'Donoghue <bryan.odonoghue@linaro.org> | 2015-06-29 18:09:14 +0100 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@google.com> | 2015-06-30 19:34:47 -0700 |
commit | 4c025cf4168fe679b8a56eed210349458a142d07 (patch) | |
tree | 699efcb02b1d8fa45a84019647eb7ae59de7b38f /drivers/staging/greybus/uart.c | |
parent | 802362d4a621a03b394b3082b40e5471bf5268ad (diff) | |
download | op-kernel-dev-4c025cf4168fe679b8a56eed210349458a142d07.zip op-kernel-dev-4c025cf4168fe679b8a56eed210349458a142d07.tar.gz |
greybus: uart: Add support for UART error signals
After reviewing the UART specification for greybus break, parity, framing
and over-run errors were moved to the receive-data message. This patch
implements that specification change in the UART protocol driver. Matching
code in gbsim has been tested with this change.
Signed-off-by: Bryan O'Donoghue <bryan.odonoghue@linaro.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@google.com>
Diffstat (limited to 'drivers/staging/greybus/uart.c')
-rw-r--r-- | drivers/staging/greybus/uart.c | 59 |
1 files changed, 40 insertions, 19 deletions
diff --git a/drivers/staging/greybus/uart.c b/drivers/staging/greybus/uart.c index 3b06cd4..73e3c99 100644 --- a/drivers/staging/greybus/uart.c +++ b/drivers/staging/greybus/uart.c @@ -70,35 +70,56 @@ static atomic_t reference_count = ATOMIC_INIT(0); /* Define get_version() routine */ define_get_version(gb_tty, UART); +static int gb_uart_receive_data(struct gb_tty *gb_tty, + struct gb_connection *connection, + struct gb_uart_recv_data_request *receive_data) +{ + struct tty_port *port = &gb_tty->port; + u16 recv_data_size; + int count; + unsigned long tty_flags = TTY_NORMAL; + + count = gb_tty->buffer_payload_max - sizeof(*receive_data); + recv_data_size = le16_to_cpu(receive_data->size); + if (!recv_data_size || recv_data_size > count) + return -EINVAL; + + if (receive_data->flags) { + if (receive_data->flags & GB_UART_RECV_FLAG_BREAK) + tty_flags = TTY_BREAK; + else if (receive_data->flags & GB_UART_RECV_FLAG_PARITY) + tty_flags = TTY_PARITY; + else if (receive_data->flags & GB_UART_RECV_FLAG_FRAMING) + tty_flags = TTY_FRAME; + + /* overrun is special, not associated with a char */ + if (receive_data->flags & GB_UART_RECV_FLAG_OVERRUN) + tty_insert_flip_char(port, 0, TTY_OVERRUN); + } + count = tty_insert_flip_string_fixed_flag(port, receive_data->data, + tty_flags, recv_data_size); + if (count != recv_data_size) { + dev_err(&connection->dev, + "UART: RX 0x%08x bytes only wrote 0x%08x\n", + recv_data_size, count); + } + if (count) + tty_flip_buffer_push(port); + return 0; +} + 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; - u16 recv_data_size; - 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); - recv_data_size = le16_to_cpu(receive_data->size); - if (!recv_data_size || recv_data_size > count) - return -EINVAL; - - count = tty_insert_flip_string(port, receive_data->data, - recv_data_size); - if (count != recv_data_size) { - dev_err(&connection->dev, - "UART: RX 0x%08x bytes only wrote 0x%08x\n", - recv_data_size, count); - } - if (count) - tty_flip_buffer_push(port); + ret = gb_uart_receive_data(gb_tty, connection, + request->payload); break; case GB_UART_TYPE_SERIAL_STATE: serial_state = request->payload; |