static int hsic_tty_open(struct tty_struct *tty, struct file *f) { int res = 0; unsigned int n = tty->index; struct hsic_tty_info *info = &hsic_tty; unsigned port_num; pr_debug("%s: #%d\n", __func__, n); if (n >= MAX_HSIC_TTYS) { pr_err("%s: NODEV\n", __func__); return -ENODEV; } if (info->serial_state & ACM_CTRL_DSR & ACM_CTRL_DCD) { pr_err("%s: NODEV: DSR(%d), DCD(%d)\n", __func__, info->serial_state & ACM_CTRL_DSR ? 1 : 0, info->serial_state & ACM_CTRL_DCD ? 1 : 0); return -ENODEV; } port_num = info->client_port_num; mutex_lock(&hsic_tty_lock); tty->driver_data = info; if (info->open_counts++ == 0) { wake_lock_init(&info->wake_lock, WAKE_LOCK_SUSPEND, "hsic_tty"); } if (info->open_count[n]++ == 0) { info->ttys[n] = tty; if (!info->tty || info->tty->index < n) { info->tty = tty; #ifdef CONFIG_MODEM_SUPPORT if (n == 1) { if (info->port_handshake_bits & TIOCM_DTR) hsic_tty_tiocmset(info->tty, 0, TIOCM_DTR); hsic_tty_tiocmset(info->tty, TIOCM_DTR, 0); } #endif } } mutex_unlock(&hsic_tty_lock); pr_debug("%s: #%d, done\n", __func__, n); return res; }
static void hsic_tty_close(struct tty_struct *tty, struct file *f) { struct hsic_tty_info *info = tty->driver_data; unsigned long flags; int n = tty->index; unsigned port_num; pr_debug("%s: #%d\n", __func__, n); if (info == 0) return; port_num = info->client_port_num; mutex_lock(&hsic_tty_lock); if (--info->open_count[n] == 0) { #ifdef CONFIG_MODEM_SUPPORT if (n == 1) hsic_tty_tiocmset(info->tty, 0, TIOCM_DTR); #endif if (n == 0) info->ttys[n] = NULL; if (n-- > 0) { info->tty = info->ttys[n]; } } if (--info->open_counts == 0) { spin_lock_irqsave(&info->reset_lock, flags); info->is_open = 0; spin_unlock_irqrestore(&info->reset_lock, flags); if (info->tty) { wake_lock_destroy(&info->wake_lock); info->tty = NULL; } tty->driver_data = 0; del_timer(&info->buf_req_timer); #ifdef CONFIG_MODEM_SUPPORT info->port_handshake_bits = 0; info->serial_state = 0; #endif } mutex_unlock(&hsic_tty_lock); }