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 <greg@kroah.com>
This commit is contained in:
parent
d122382f88
commit
980c7c509e
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue