/* Locking: Called functions take ldisc and termios_rwsem locks  */
static int set_termios(struct tty_struct *tty, void *arg, int opt)
/* Locking: Called functions take ldisc and termios_rwsem locks  */
static int set_termios(struct tty_struct *tty, void *arg, int opt)
{
    struct termios old_termios;
    struct tty_ldisc *ld = RT_NULL;
    struct termios *new_termios = (struct termios *)arg;
    rt_base_t level = 0;
    int retval = tty_check_change(tty);
    if (retval)
    {
        return retval;
    }
    memcpy(&old_termios, &(tty->init_termios), sizeof(struct termios));
    level = rt_spin_lock_irqsave(&tty->spinlock);
    tty->init_termios = *new_termios;
    rt_spin_unlock_irqrestore(&tty->spinlock, level);
    ld = tty->ldisc;
    if (ld != NULL)
    {
        if (ld->ops->set_termios)
        {
            ld->ops->set_termios(tty, &old_termios);
        }
    }
    return 0;
}