From: Greg Kroah-Hartman Date: Wed, 19 Nov 2014 22:23:00 +0000 (-0800) Subject: greybus: uart-gb: handle throttle/unthrottle properly X-Git-Url: https://git.stricted.de/?a=commitdiff_plain;h=980c7c509eb36c693576ad342a11455f530db0b9;p=GitHub%2Fmoto-9609%2Fandroid_kernel_motorola_exynos9610.git greybus: uart-gb: handle throttle/unthrottle properly This hooks up throttle/unthrottle to properly toggle the RTS line or do XON/XOFF if that is how the port is set up. Note, if the UART itself can handle XON/XOFF, we would need to send the correct character down to it, to have the firmware in the device set up the chip to use it automatically when needed. The odds of someone wanting to use this type of flow control is slim, so this isn't implemented at this point in time. Also fill in a few more fields in the get_serial_info ioctl, to make tools like stty(1) happier. Signed-off-by: Greg Kroah-Hartman --- diff --git a/drivers/staging/greybus/uart-gb.c b/drivers/staging/greybus/uart-gb.c index d01956acdedc..460947e94a38 100644 --- a/drivers/staging/greybus/uart-gb.c +++ b/drivers/staging/greybus/uart-gb.c @@ -116,10 +116,7 @@ struct gb_tty { u16 cport_id; unsigned int minor; unsigned char clocal; - unsigned int throttled:1; - unsigned int throttle_req:1; bool disconnected; - int writesize; // FIXME - set this somehow. spinlock_t read_lock; spinlock_t write_lock; struct async_icount iocount; @@ -567,25 +564,39 @@ static int gb_tty_tiocmset(struct tty_struct *tty, unsigned int set, static void gb_tty_throttle(struct tty_struct *tty) { struct gb_tty *gb_tty = tty->driver_data; + unsigned char stop_char; + int retval; + + if (I_IXOFF(tty)) { + stop_char = STOP_CHAR(tty); + retval = gb_tty_write(tty, &stop_char, 1); + if (retval <= 0) + return; + } + + if (tty->termios.c_cflag & CRTSCTS) { + gb_tty->ctrlout &= ~GB_UART_CTRL_RTS; + retval = send_control(gb_tty, gb_tty->ctrlout); + } - spin_lock_irq(&gb_tty->read_lock); - gb_tty->throttle_req = 1; - spin_unlock_irq(&gb_tty->read_lock); } static void gb_tty_unthrottle(struct tty_struct *tty) { struct gb_tty *gb_tty = tty->driver_data; - unsigned int was_throttled; + unsigned char start_char; + int retval; - spin_lock_irq(&gb_tty->read_lock); - was_throttled = gb_tty->throttled; - gb_tty->throttle_req = 0; - gb_tty->throttled = 0; - spin_unlock_irq(&gb_tty->read_lock); + if (I_IXOFF(tty)) { + start_char = START_CHAR(tty); + retval = gb_tty_write(tty, &start_char, 1); + if (retval <= 0) + return; + } - if (was_throttled) { - // FIXME - send more data + if (tty->termios.c_cflag & CRTSCTS) { + gb_tty->ctrlout |= GB_UART_CTRL_RTS; + retval = send_control(gb_tty, gb_tty->ctrlout); } } @@ -598,9 +609,11 @@ static int get_serial_info(struct gb_tty *gb_tty, return -EINVAL; memset(&tmp, 0, sizeof(tmp)); - tmp.flags = ASYNC_LOW_LATENCY; - tmp.xmit_fifo_size = gb_tty->writesize; - tmp.baud_base = 0; // FIXME + tmp.flags = ASYNC_LOW_LATENCY | ASYNC_SKIP_TEST; + tmp.type = PORT_16550A; + tmp.line = gb_tty->minor; + tmp.xmit_fifo_size = 16; + tmp.baud_base = 9600; tmp.close_delay = gb_tty->port.close_delay / 10; tmp.closing_wait = gb_tty->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ? ASYNC_CLOSING_WAIT_NONE : gb_tty->port.closing_wait / 10;