Commit 980c7c50 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman

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: default avatarGreg Kroah-Hartman <greg@kroah.com>
parent d122382f
...@@ -116,10 +116,7 @@ struct gb_tty { ...@@ -116,10 +116,7 @@ struct gb_tty {
u16 cport_id; u16 cport_id;
unsigned int minor; unsigned int minor;
unsigned char clocal; unsigned char clocal;
unsigned int throttled:1;
unsigned int throttle_req:1;
bool disconnected; bool disconnected;
int writesize; // FIXME - set this somehow.
spinlock_t read_lock; spinlock_t read_lock;
spinlock_t write_lock; spinlock_t write_lock;
struct async_icount iocount; struct async_icount iocount;
...@@ -567,25 +564,39 @@ static int gb_tty_tiocmset(struct tty_struct *tty, unsigned int set, ...@@ -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) static void gb_tty_throttle(struct tty_struct *tty)
{ {
struct gb_tty *gb_tty = tty->driver_data; 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) static void gb_tty_unthrottle(struct tty_struct *tty)
{ {
struct gb_tty *gb_tty = tty->driver_data; 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); if (I_IXOFF(tty)) {
was_throttled = gb_tty->throttled; start_char = START_CHAR(tty);
gb_tty->throttle_req = 0; retval = gb_tty_write(tty, &start_char, 1);
gb_tty->throttled = 0; if (retval <= 0)
spin_unlock_irq(&gb_tty->read_lock); return;
}
if (was_throttled) { if (tty->termios.c_cflag & CRTSCTS) {
// FIXME - send more data 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, ...@@ -598,9 +609,11 @@ static int get_serial_info(struct gb_tty *gb_tty,
return -EINVAL; return -EINVAL;
memset(&tmp, 0, sizeof(tmp)); memset(&tmp, 0, sizeof(tmp));
tmp.flags = ASYNC_LOW_LATENCY; tmp.flags = ASYNC_LOW_LATENCY | ASYNC_SKIP_TEST;
tmp.xmit_fifo_size = gb_tty->writesize; tmp.type = PORT_16550A;
tmp.baud_base = 0; // FIXME tmp.line = gb_tty->minor;
tmp.xmit_fifo_size = 16;
tmp.baud_base = 9600;
tmp.close_delay = gb_tty->port.close_delay / 10; tmp.close_delay = gb_tty->port.close_delay / 10;
tmp.closing_wait = gb_tty->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ? tmp.closing_wait = gb_tty->port.closing_wait == ASYNC_CLOSING_WAIT_NONE ?
ASYNC_CLOSING_WAIT_NONE : gb_tty->port.closing_wait / 10; ASYNC_CLOSING_WAIT_NONE : gb_tty->port.closing_wait / 10;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment