aboutsummaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2012-05-22 16:12:24 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2012-05-22 16:12:24 -0700
commit94b5aff4c6f72fee6b0f49d49e4fa8b204e8ded9 (patch)
tree39197121b6ef8cddaa0f4057fe24b4ced58e8982 /drivers
parent5d4e2d08e7fdf7339f84a1c670d296a77e02f881 (diff)
parent59bd234b72fc29887839d792b7d6c7e8d2a577a6 (diff)
Merge tag 'tty-3.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty
Pull TTY updates from Greg Kroah-Hartman: "Here's the big TTY/serial driver pull request for the 3.5-rc1 merge window. Nothing major in here, just lots of incremental changes from Alan and Jiri reworking some tty core things to behave better and to get a more solid grasp on some of the nasty tty locking issues. There are a few tty and serial driver updates in here as well. All of this has been in the linux-next releases for a while with no problems. Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>" * tag 'tty-3.5-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty: (115 commits) serial: bfin_uart: Make MMR access compatible with 32 bits bf609 style controller. serial: bfin_uart: RTS and CTS MMRs can be either 16-bit width or 32-bit width. serial: bfin_uart: narrow the reboot condition in DMA tx interrupt serial: bfin_uart: Adapt bf5xx serial driver to bf60x serial4 controller. Revert "serial_core: Update buffer overrun statistics." tty: hvc_xen: NULL dereference on allocation failure tty: Fix LED error return tty: Allow uart_register/unregister/register tty: move global ldisc idle waitqueue to the individual ldisc serial8250-em: Add DT support serial8250-em: clk_get() IS_ERR() error handling fix serial_core: Update buffer overrun statistics. tty: drop the pty lock during hangup cris: fix missing tty arg in wait_event_interruptible_tty call tty/amiserial: Add missing argument for tty_unlock() tty_lock: Localise the lock pty: Lock the devpts bits privately tty_lock: undo the old tty_lock use on the ctty serial8250-em: Emma Mobile UART driver V2 Add missing call to uart_update_timeout() ...
Diffstat (limited to 'drivers')
-rw-r--r--drivers/isdn/i4l/isdn_common.c5
-rw-r--r--drivers/isdn/i4l/isdn_tty.c466
-rw-r--r--drivers/net/usb/hso.c105
-rw-r--r--drivers/s390/char/con3215.c142
-rw-r--r--drivers/s390/char/keyboard.c30
-rw-r--r--drivers/s390/char/keyboard.h14
-rw-r--r--drivers/s390/char/sclp_tty.c33
-rw-r--r--drivers/s390/char/sclp_vt220.c33
-rw-r--r--drivers/s390/char/tty3270.c121
-rw-r--r--drivers/staging/serial/68360serial.c4
-rw-r--r--drivers/tty/amiserial.c14
-rw-r--r--drivers/tty/bfin_jtag_comm.c44
-rw-r--r--drivers/tty/cyclades.c2
-rw-r--r--drivers/tty/hvc/hvc_console.c96
-rw-r--r--drivers/tty/hvc/hvc_console.h4
-rw-r--r--drivers/tty/hvc/hvc_xen.c4
-rw-r--r--drivers/tty/hvc/hvcs.c74
-rw-r--r--drivers/tty/hvc/hvsi.c128
-rw-r--r--drivers/tty/hvc/hvsi_lib.c2
-rw-r--r--drivers/tty/ipwireless/tty.c81
-rw-r--r--drivers/tty/mxser.c2
-rw-r--r--drivers/tty/n_r3964.c11
-rw-r--r--drivers/tty/n_tty.c9
-rw-r--r--drivers/tty/pty.c40
-rw-r--r--drivers/tty/serial/68328serial.c383
-rw-r--r--drivers/tty/serial/68328serial.h186
-rw-r--r--drivers/tty/serial/8250/8250.c312
-rw-r--r--drivers/tty/serial/8250/8250.h16
-rw-r--r--drivers/tty/serial/8250/8250_em.c186
-rw-r--r--drivers/tty/serial/8250/8250_pci.c63
-rw-r--r--drivers/tty/serial/8250/Kconfig8
-rw-r--r--drivers/tty/serial/8250/Makefile1
-rw-r--r--drivers/tty/serial/amba-pl011.c109
-rw-r--r--drivers/tty/serial/bfin_uart.c74
-rw-r--r--drivers/tty/serial/crisv10.c36
-rw-r--r--drivers/tty/serial/mxs-auart.c2
-rw-r--r--drivers/tty/serial/of_serial.c26
-rw-r--r--drivers/tty/serial/omap-serial.c74
-rw-r--r--drivers/tty/serial/pch_uart.c53
-rw-r--r--drivers/tty/serial/serial_core.c1
-rw-r--r--drivers/tty/synclink.c4
-rw-r--r--drivers/tty/synclink_gt.c4
-rw-r--r--drivers/tty/synclinkmp.c4
-rw-r--r--drivers/tty/tty_buffer.c85
-rw-r--r--drivers/tty/tty_io.c76
-rw-r--r--drivers/tty/tty_ldisc.c37
-rw-r--r--drivers/tty/tty_mutex.c60
-rw-r--r--drivers/tty/tty_port.c6
-rw-r--r--drivers/tty/vt/consolemap.c123
-rw-r--r--drivers/tty/vt/vt.c68
-rw-r--r--drivers/tty/vt/vt_ioctl.c25
-rw-r--r--drivers/usb/gadget/u_serial.c51
52 files changed, 1759 insertions, 1778 deletions
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c
index d9f5524593f..8c610fa6782 100644
--- a/drivers/isdn/i4l/isdn_common.c
+++ b/drivers/isdn/i4l/isdn_common.c
@@ -46,7 +46,6 @@ static DEFINE_MUTEX(isdn_mutex);
static char *isdn_revision = "$Revision: 1.1.2.3 $";
extern char *isdn_net_revision;
-extern char *isdn_tty_revision;
#ifdef CONFIG_ISDN_PPP
extern char *isdn_ppp_revision;
#else
@@ -2327,8 +2326,6 @@ static int __init isdn_init(void)
dev->chanmap[i] = -1;
dev->m_idx[i] = -1;
strcpy(dev->num[i], "???");
- init_waitqueue_head(&dev->mdm.info[i].open_wait);
- init_waitqueue_head(&dev->mdm.info[i].close_wait);
}
if (register_chrdev(ISDN_MAJOR, "isdn", &isdn_fops)) {
printk(KERN_WARNING "isdn: Could not register control devices\n");
@@ -2353,8 +2350,6 @@ static int __init isdn_init(void)
strcpy(tmprev, isdn_revision);
printk(KERN_NOTICE "ISDN subsystem Rev: %s/", isdn_getrev(tmprev));
- strcpy(tmprev, isdn_tty_revision);
- printk("%s/", isdn_getrev(tmprev));
strcpy(tmprev, isdn_net_revision);
printk("%s/", isdn_getrev(tmprev));
strcpy(tmprev, isdn_ppp_revision);
diff --git a/drivers/isdn/i4l/isdn_tty.c b/drivers/isdn/i4l/isdn_tty.c
index 3831abdbc66..7bc50670d7d 100644
--- a/drivers/isdn/i4l/isdn_tty.c
+++ b/drivers/isdn/i4l/isdn_tty.c
@@ -1,5 +1,4 @@
-/* $Id: isdn_tty.c,v 1.1.2.3 2004/02/10 01:07:13 keil Exp $
- *
+/*
* Linux ISDN subsystem, tty functions and AT-command emulator (linklevel).
*
* Copyright 1994-1999 by Fritz Elfert (fritz@isdn4linux.de)
@@ -12,6 +11,7 @@
#undef ISDN_TTY_STAT_DEBUG
#include <linux/isdn.h>
+#include <linux/serial.h> /* ASYNC_* flags */
#include <linux/slab.h>
#include <linux/delay.h>
#include <linux/mutex.h>
@@ -48,9 +48,6 @@ static int bit2si[8] =
static int si2bit[8] =
{4, 1, 4, 4, 4, 4, 4, 4};
-char *isdn_tty_revision = "$Revision: 1.1.2.3 $";
-
-
/* isdn_tty_try_read() is called from within isdn_tty_rcv_skb()
* to stuff incoming data directly into a tty's flip-buffer. This
* is done to speed up tty-receiving if the receive-queue is empty.
@@ -68,49 +65,54 @@ isdn_tty_try_read(modem_info *info, struct sk_buff *skb)
struct tty_struct *tty;
char last;
- if (info->online) {
- if ((tty = info->tty)) {
- if (info->mcr & UART_MCR_RTS) {
- len = skb->len
+ if (!info->online)
+ return 0;
+
+ tty = info->port.tty;
+ if (!tty)
+ return 0;
+
+ if (!(info->mcr & UART_MCR_RTS))
+ return 0;
+
+ len = skb->len
#ifdef CONFIG_ISDN_AUDIO
- + ISDN_AUDIO_SKB_DLECOUNT(skb)
+ + ISDN_AUDIO_SKB_DLECOUNT(skb)
#endif
- ;
+ ;
+
+ c = tty_buffer_request_room(tty, len);
+ if (c < len)
+ return 0;
- c = tty_buffer_request_room(tty, len);
- if (c >= len) {
-#ifdef CONFIG_ISDN_AUDIO
- if (ISDN_AUDIO_SKB_DLECOUNT(skb)) {
- int l = skb->len;
- unsigned char *dp = skb->data;
- while (--l) {
- if (*dp == DLE)
- tty_insert_flip_char(tty, DLE, 0);
- tty_insert_flip_char(tty, *dp++, 0);
- }
- if (*dp == DLE)
- tty_insert_flip_char(tty, DLE, 0);
- last = *dp;
- } else {
-#endif
- if (len > 1)
- tty_insert_flip_string(tty, skb->data, len - 1);
- last = skb->data[len - 1];
#ifdef CONFIG_ISDN_AUDIO
- }
+ if (ISDN_AUDIO_SKB_DLECOUNT(skb)) {
+ int l = skb->len;
+ unsigned char *dp = skb->data;
+ while (--l) {
+ if (*dp == DLE)
+ tty_insert_flip_char(tty, DLE, 0);
+ tty_insert_flip_char(tty, *dp++, 0);
+ }
+ if (*dp == DLE)
+ tty_insert_flip_char(tty, DLE, 0);
+ last = *dp;
+ } else {
#endif
- if (info->emu.mdmreg[REG_CPPP] & BIT_CPPP)
- tty_insert_flip_char(tty, last, 0xFF);
- else
- tty_insert_flip_char(tty, last, TTY_NORMAL);
- tty_flip_buffer_push(tty);
- kfree_skb(skb);
- return 1;
- }
- }
- }
+ if (len > 1)
+ tty_insert_flip_string(tty, skb->data, len - 1);
+ last = skb->data[len - 1];
+#ifdef CONFIG_ISDN_AUDIO
}
- return 0;
+#endif
+ if (info->emu.mdmreg[REG_CPPP] & BIT_CPPP)
+ tty_insert_flip_char(tty, last, 0xFF);
+ else
+ tty_insert_flip_char(tty, last, TTY_NORMAL);
+ tty_flip_buffer_push(tty);
+ kfree_skb(skb);
+
+ return 1;
}
/* isdn_tty_readmodem() is called periodically from within timer-interrupt.
@@ -128,35 +130,39 @@ isdn_tty_readmodem(void)
modem_info *info;
for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
- if ((midx = dev->m_idx[i]) >= 0) {
- info = &dev->mdm.info[midx];
- if (info->online) {
- r = 0;
+ midx = dev->m_idx[i];
+ if (midx < 0)
+ continue;
+
+ info = &dev->mdm.info[midx];
+ if (!info->online)
+ continue;
+
+ r = 0;
#ifdef CONFIG_ISDN_AUDIO
- isdn_audio_eval_dtmf(info);
- if ((info->vonline & 1) && (info->emu.vpar[1]))
- isdn_audio_eval_silence(info);
-#endif
- if ((tty = info->tty)) {
- if (info->mcr & UART_MCR_RTS) {
- /* CISCO AsyncPPP Hack */
- if (!(info->emu.mdmreg[REG_CPPP] & BIT_CPPP))
- r = isdn_readbchan_tty(info->isdn_driver, info->isdn_channel, tty, 0);
- else
- r = isdn_readbchan_tty(info->isdn_driver, info->isdn_channel, tty, 1);
- if (r)
- tty_flip_buffer_push(tty);
- } else
- r = 1;
- } else
- r = 1;
- if (r) {
- info->rcvsched = 0;
- resched = 1;
- } else
- info->rcvsched = 1;
- }
- }
+ isdn_audio_eval_dtmf(info);
+ if ((info->vonline & 1) && (info->emu.vpar[1]))
+ isdn_audio_eval_silence(info);
+#endif
+ tty = info->port.tty;
+ if (tty) {
+ if (info->mcr & UART_MCR_RTS) {
+ /* CISCO AsyncPPP Hack */
+ if (!(info->emu.mdmreg[REG_CPPP] & BIT_CPPP))
+ r = isdn_readbchan_tty(info->isdn_driver, info->isdn_channel, tty, 0);
+ else
+ r = isdn_readbchan_tty(info->isdn_driver, info->isdn_channel, tty, 1);
+ if (r)
+ tty_flip_buffer_push(tty);
+ } else
+ r = 1;
+ } else
+ r = 1;
+ if (r) {
+ info->rcvsched = 0;
+ resched = 1;
+ } else
+ info->rcvsched = 1;
}
if (!resched)
isdn_timer_ctrl(ISDN_TIMER_MODEMREAD, 0);
@@ -294,7 +300,7 @@ isdn_tty_tint(modem_info *info)
len = skb->len;
if ((slen = isdn_writebuf_skb_stub(info->isdn_driver,
info->isdn_channel, 1, skb)) == len) {
- struct tty_struct *tty = info->tty;
+ struct tty_struct *tty = info->port.tty;
info->send_outstanding++;
info->msr &= ~UART_MSR_CTS;
info->lsr &= ~UART_LSR_TEMT;
@@ -327,7 +333,7 @@ isdn_tty_countDLE(unsigned char *buf, int len)
static int
isdn_tty_handleDLEdown(modem_info *info, atemu *m, int len)
{
- unsigned char *p = &info->xmit_buf[info->xmit_count];
+ unsigned char *p = &info->port.xmit_buf[info->xmit_count];
int count = 0;
while (len > 0) {
@@ -471,7 +477,7 @@ isdn_tty_senddown(modem_info *info)
return;
}
skb_reserve(skb, skb_res);
- memcpy(skb_put(skb, buflen), info->xmit_buf, buflen);
+ memcpy(skb_put(skb, buflen), info->port.xmit_buf, buflen);
info->xmit_count = 0;
#ifdef CONFIG_ISDN_AUDIO
if (info->vonline & 2) {
@@ -699,7 +705,7 @@ isdn_tty_modem_hup(modem_info *info, int local)
printk(KERN_DEBUG "Mhup ttyI%d\n", info->line);
#endif
info->rcvsched = 0;
- isdn_tty_flush_buffer(info->tty);
+ isdn_tty_flush_buffer(info->port.tty);
if (info->online) {
info->last_lhup = local;
info->online = 0;
@@ -997,20 +1003,21 @@ isdn_tty_paranoia_check(modem_info *info, char *name, const char *routine)
static void
isdn_tty_change_speed(modem_info *info)
{
+ struct tty_port *port = &info->port;
uint cflag,
cval,
quot;
int i;
- if (!info->tty || !info->tty->termios)
+ if (!port->tty || !port->tty->termios)
return;
- cflag = info->tty->termios->c_cflag;
+ cflag = port->tty->termios->c_cflag;
quot = i = cflag & CBAUD;
if (i & CBAUDEX) {
i &= ~CBAUDEX;
if (i < 1 || i > 2)
- info->tty->termios->c_cflag &= ~CBAUDEX;
+ port->tty->termios->c_cflag &= ~CBAUDEX;
else
i += 15;
}
@@ -1040,20 +1047,20 @@ isdn_tty_change_speed(modem_info *info)
/* CTS flow control flag and modem status interrupts */
if (cflag & CRTSCTS) {
- info->flags |= ISDN_ASYNC_CTS_FLOW;
+ port->flags |= ASYNC_CTS_FLOW;
} else
- info->flags &= ~ISDN_ASYNC_CTS_FLOW;
+ port->flags &= ~ASYNC_CTS_FLOW;
if (cflag & CLOCAL)
- info->flags &= ~ISDN_ASYNC_CHECK_CD;
+ port->flags &= ~ASYNC_CHECK_CD;
else {
- info->flags |= ISDN_ASYNC_CHECK_CD;
+ port->flags |= ASYNC_CHECK_CD;
}
}
static int
isdn_tty_startup(modem_info *info)
{
- if (info->flags & ISDN_ASYNC_INITIALIZED)
+ if (info->port.flags & ASYNC_INITIALIZED)
return 0;
isdn_lock_drivers();
#ifdef ISDN_DEBUG_MODEM_OPEN
@@ -1063,14 +1070,14 @@ isdn_tty_startup(modem_info *info)
* Now, initialize the UART
*/
info->mcr = UART_MCR_DTR | UART_MCR_RTS | UART_MCR_OUT2;
- if (info->tty)
- clear_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ clear_bit(TTY_IO_ERROR, &info->port.tty->flags);
/*
* and set the speed of the serial port
*/
isdn_tty_change_speed(info);
- info->flags |= ISDN_ASYNC_INITIALIZED;
+ info->port.flags |= ASYNC_INITIALIZED;
info->msr |= (UART_MSR_DSR | UART_MSR_CTS);
info->send_outstanding = 0;
return 0;
@@ -1083,14 +1090,14 @@ isdn_tty_startup(modem_info *info)
static void
isdn_tty_shutdown(modem_info *info)
{
- if (!(info->flags & ISDN_ASYNC_INITIALIZED))
+ if (!(info->port.flags & ASYNC_INITIALIZED))
return;
#ifdef ISDN_DEBUG_MODEM_OPEN
printk(KERN_DEBUG "Shutting down isdnmodem port %d ....\n", info->line);
#endif
isdn_unlock_drivers();
info->msr &= ~UART_MSR_RI;
- if (!info->tty || (info->tty->termios->c_cflag & HUPCL)) {
+ if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL)) {
info->mcr &= ~(UART_MCR_DTR | UART_MCR_RTS);
if (info->emu.mdmreg[REG_DTRHUP] & BIT_DTRHUP) {
isdn_tty_modem_reset_regs(info, 0);
@@ -1100,10 +1107,10 @@ isdn_tty_shutdown(modem_info *info)
isdn_tty_modem_hup(info, 1);
}
}
- if (info->tty)
- set_bit(TTY_IO_ERROR, &info->tty->flags);
+ if (info->port.tty)
+ set_bit(TTY_IO_ERROR, &info->port.tty->flags);
- info->flags &= ~ISDN_ASYNC_INITIALIZED;
+ info->port.flags &= ~ASYNC_INITIALIZED;
}
/* isdn_tty_write() is the main send-routine. It is called from the upper
@@ -1146,7 +1153,7 @@ isdn_tty_write(struct tty_struct *tty, const u_char *buf, int count)
isdn_tty_check_esc(buf, m->mdmreg[REG_ESC], c,
&(m->pluscount),
&(m->lastplus));
- memcpy(&(info->xmit_buf[info->xmit_count]), buf, c);
+ memcpy(&info->port.xmit_buf[info->xmit_count], buf, c);
#ifdef CONFIG_ISDN_AUDIO
if (info->vonline) {
int cc = isdn_tty_handleDLEdown(info, m, c);
@@ -1478,107 +1485,6 @@ isdn_tty_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
* isdn_tty_open() and friends
* ------------------------------------------------------------
*/
-static int
-isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info *info)
-{
- DECLARE_WAITQUEUE(wait, NULL);
- int do_clocal = 0;
- int retval;
-
- /*
- * If the device is in the middle of being closed, then block
- * until it's done, and then try again.
- */
- if (tty_hung_up_p(filp) ||
- (info->flags & ISDN_ASYNC_CLOSING)) {
- if (info->flags & ISDN_ASYNC_CLOSING)
- interruptible_sleep_on(&info->close_wait);
-#ifdef MODEM_DO_RESTART
- if (info->flags & ISDN_ASYNC_HUP_NOTIFY)
- return -EAGAIN;
- else
- return -ERESTARTSYS;
-#else
- return -EAGAIN;
-#endif
- }
- /*
- * If non-blocking mode is set, then make the check up front
- * and then exit.
- */
- if ((filp->f_flags & O_NONBLOCK) ||
- (tty->flags & (1 << TTY_IO_ERROR))) {
- if (info->flags & ISDN_ASYNC_CALLOUT_ACTIVE)
- return -EBUSY;
- info->flags |= ISDN_ASYNC_NORMAL_ACTIVE;
- return 0;
- }
- if (info->flags & ISDN_ASYNC_CALLOUT_ACTIVE) {
- if (info->normal_termios.c_cflag & CLOCAL)
- do_clocal = 1;
- } else {
- if (tty->termios->c_cflag & CLOCAL)
- do_clocal = 1;
- }
- /*
- * Block waiting for the carrier detect and the line to become
- * free (i.e., not in use by the callout). While we are in
- * this loop, info->count is dropped by one, so that
- * isdn_tty_close() knows when to free things. We restore it upon
- * exit, either normal or abnormal.
- */
- retval = 0;
- add_wait_queue(&info->open_wait, &wait);
-#ifdef ISDN_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "isdn_tty_block_til_ready before block: ttyi%d, count = %d\n",
- info->line, info->count);
-#endif
- if (!(tty_hung_up_p(filp)))
- info->count--;
- info->blocked_open++;
- while (1) {
- set_current_state(TASK_INTERRUPTIBLE);
- if (tty_hung_up_p(filp) ||
- !(info->flags & ISDN_ASYNC_INITIALIZED)) {
-#ifdef MODEM_DO_RESTART
- if (info->flags & ISDN_ASYNC_HUP_NOTIFY)
- retval = -EAGAIN;
- else
- retval = -ERESTARTSYS;
-#else
- retval = -EAGAIN;
-#endif
- break;
- }
- if (!(info->flags & ISDN_ASYNC_CALLOUT_ACTIVE) &&
- !(info->flags & ISDN_ASYNC_CLOSING) &&
- (do_clocal || (info->msr & UART_MSR_DCD))) {
- break;
- }
- if (signal_pending(current)) {
- retval = -ERESTARTSYS;
- break;
- }
-#ifdef ISDN_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "isdn_tty_block_til_ready blocking: ttyi%d, count = %d\n",
- info->line, info->count);
-#endif
- schedule();
- }
- current->state = TASK_RUNNING;
- remove_wait_queue(&info->open_wait, &wait);
- if (!tty_hung_up_p(filp))
- info->count++;
- info->blocked_open--;
-#ifdef ISDN_DEBUG_MODEM_OPEN
- printk(KERN_DEBUG "isdn_tty_block_til_ready after blocking: ttyi%d, count = %d\n",
- info->line, info->count);
-#endif
- if (retval)
- return retval;
- info->flags |= ISDN_ASYNC_NORMAL_ACTIVE;
- return 0;
-}
/*
* This routine is called whenever a serial port is opened. It
@@ -1589,23 +1495,22 @@ isdn_tty_block_til_ready(struct tty_struct *tty, struct file *filp, modem_info *
static int
isdn_tty_open(struct tty_struct *tty, struct file *filp)
{
+ struct tty_port *port;
modem_info *info;
int retval;
info = &dev->mdm.info[tty->index];
if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_open"))
return -ENODEV;
- if (!try_module_get(info->owner)) {
- printk(KERN_WARNING "%s: cannot reserve module\n", __func__);
- return -ENODEV;
- }
+ port = &info->port;
#ifdef ISDN_DEBUG_MODEM_OPEN
printk(KERN_DEBUG "isdn_tty_open %s, count = %d\n", tty->name,
- info->count);
+ port->count);
#endif
- info->count++;
+ port->count++;
tty->driver_data = info;
- info->tty = tty;
+ port->tty = tty;
+ tty->port = port;
/*
* Start up serial port
*/
@@ -1614,15 +1519,13 @@ isdn_tty_open(struct tty_struct *tty, struct file *filp)
#ifdef ISDN_DEBUG_MODEM_OPEN
printk(KERN_DEBUG "isdn_tty_open return after startup\n");
#endif
- module_put(info->owner);
return retval;
}
- retval = isdn_tty_block_til_ready(tty, filp, info);
+ retval = tty_port_block_til_ready(port, tty, filp);
if (retval) {
#ifdef ISDN_DEBUG_MODEM_OPEN
printk(KERN_DEBUG "isdn_tty_open return after isdn_tty_block_til_ready \n");
#endif
- module_put(info->owner);
return retval;
}
#ifdef ISDN_DEBUG_MODEM_OPEN
@@ -1639,6 +1542,7 @@ static void
isdn_tty_close(struct tty_struct *tty, struct file *filp)
{
modem_info *info = (modem_info *) tty->driver_data;
+ struct tty_port *port = &info->port;
ulong timeout;
if (!info || isdn_tty_paranoia_check(info, tty->name, "isdn_tty_close"))
@@ -1649,7 +1553,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
#endif
return;
}
- if ((tty->count == 1) && (info->count != 1)) {
+ if ((tty->count == 1) && (port->count != 1)) {
/*
* Uh, oh. tty->count is 1, which means that the tty
* structure will be freed. Info->count should always
@@ -1658,30 +1562,21 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
* serial port won't be shutdown.
*/
printk(KERN_ERR "isdn_tty_close: bad port count; tty->count is 1, "
- "info->count is %d\n", info->count);
- info->count = 1;
+ "info->count is %d\n", port->count);
+ port->count = 1;
}
- if (--info->count < 0) {
+ if (--port->count < 0) {
printk(KERN_ERR "isdn_tty_close: bad port count for ttyi%d: %d\n",
- info->line, info->count);
- info->count = 0;
+ info->line, port->count);
+ port->count = 0;
}
- if (info->count) {
+ if (port->count) {
#ifdef ISDN_DEBUG_MODEM_OPEN
printk(KERN_DEBUG "isdn_tty_close after info->count != 0\n");
#endif
- module_put(info->owner);
return;
}
- info->flags |= ISDN_ASYNC_CLOSING;
- /*
- * Save the termios structure, since this port may have
- * separate termios for callout and dialin.
- */
- if (info->flags & ISDN_ASYNC_NORMAL_ACTIVE)
- info->normal_termios = *tty->termios;
- if (info->flags & ISDN_ASYNC_CALLOUT_ACTIVE)
- info->callout_termios = *tty->termios;
+ port->flags |= ASYNC_CLOSING;
tty->closing = 1;
/*
@@ -1690,7 +1585,7 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
* interrupt driver to stop checking the data ready bit in the
* line status register.
*/
- if (info->flags & ISDN_ASYNC_INITIALIZED) {
+ if (port->flags & ASYNC_INITIALIZED) {
tty_wait_until_sent_from_close(tty, 3000); /* 30 seconds timeout */
/*
* Before we drop DTR, make sure the UART transmitter
@@ -1708,16 +1603,10 @@ isdn_tty_close(struct tty_struct *tty, struct file *filp)
isdn_tty_shutdown(info);
isdn_tty_flush_buffer(tty);
tty_ldisc_flush(tty);
- info->tty = NULL;
+ port->tty = NULL;
info->ncarrier = 0;
- tty->closing = 0;
- module_put(info->owner);
- if (info->blocked_open) {
- msleep_interruptible(500);
- wake_up_interruptible(&info->open_wait);
- }
- info->flags &= ~(ISDN_ASYNC_NORMAL_ACTIVE | ISDN_ASYNC_CLOSING);
- wake_up_interruptible(&info->close_wait);
+
+ tty_port_close_end(port, tty);
#ifdef ISDN_DEBUG_MODEM_OPEN
printk(KERN_DEBUG "isdn_tty_close normal exit\n");
#endif
@@ -1730,14 +1619,15 @@ static void
isdn_tty_hangup(struct tty_struct *tty)
{
modem_info *info = (modem_info *) tty->driver_data;
+ struct tty_port *port = &info->port;
if (isdn_tty_paranoia_check(info, tty->name, "isdn_tty_hangup"))
return;
isdn_tty_shutdown(info);
- info->count = 0;
- info->flags &= ~(ISDN_ASYNC_NORMAL_ACTIVE | ISDN_ASYNC_CALLOUT_ACTIVE);
- info->tty = NULL;
- wake_up_interruptible(&info->open_wait);
+ port->count = 0;
+ port->flags &= ~ASYNC_NORMAL_ACTIVE;
+ port->tty = NULL;
+ wake_up_interruptible(&port->open_wait);
}
/* This routine initializes all emulator-data.
@@ -1864,6 +1754,16 @@ static const struct tty_operations modem_ops = {
.tiocmset = isdn_tty_tiocmset,
};
+static int isdn_tty_carrier_raised(struct tty_port *port)
+{
+ modem_info *info = container_of(port, modem_info, port);
+ return info->msr & UART_MSR_DCD;
+}
+
+static const struct tty_port_operations isdn_tty_port_ops = {
+ .carrier_raised = isdn_tty_carrier_raised,
+};
+
int
isdn_tty_modem_init(void)
{
@@ -1899,9 +1799,8 @@ isdn_tty_modem_init(void)
goto err_unregister;
}
#endif
-#ifdef MODULE
- info->owner = THIS_MODULE;
-#endif
+ tty_port_init(&info->port);
+ info->port.ops = &isdn_tty_port_ops;
spin_lock_init(&info->readlock);
sprintf(info->last_cause, "0000");
sprintf(info->last_num, "none");
@@ -1913,12 +1812,7 @@ isdn_tty_modem_init(void)
isdn_tty_modem_reset_regs(info, 1);
info->magic = ISDN_ASYNC_MAGIC;
info->line = i;
- info->tty = NULL;
info->x_char = 0;
- info->count = 0;
- info->blocked_open = 0;
- init_waitqueue_h