Merge tty-next into 3.6-rc1
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 6 Aug 2012 16:48:31 +0000 (09:48 -0700)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Mon, 6 Aug 2012 16:48:31 +0000 (09:48 -0700)
This handles the merge issue in:
arch/um/drivers/line.c
arch/um/drivers/line.h
And resolves the duplicate patches that were in both trees do to the
tty-next branch not getting merged into 3.6-rc1.

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
104 files changed:
Documentation/devicetree/bindings/tty/serial/nxp-lpc32xx-hsuart.txt [new file with mode: 0644]
Documentation/devicetree/bindings/tty/serial/of-serial.txt
arch/ia64/hp/sim/simserial.c
drivers/bluetooth/hci_ath.c
drivers/char/mwave/mwavedd.c
drivers/char/pcmcia/synclink_cs.c
drivers/isdn/gigaset/interface.c
drivers/isdn/i4l/isdn_tty.c
drivers/misc/ibmasm/uart.c
drivers/mmc/card/sdio_uart.c
drivers/net/ethernet/sgi/ioc3-eth.c
drivers/net/irda/irtty-sir.c
drivers/net/usb/hso.c
drivers/tty/amiserial.c
drivers/tty/cyclades.c
drivers/tty/hvc/hvsi_lib.c
drivers/tty/isicom.c
drivers/tty/moxa.c
drivers/tty/mxser.c
drivers/tty/n_gsm.c
drivers/tty/n_tty.c
drivers/tty/pty.c
drivers/tty/rocket.c
drivers/tty/serial/8250/8250.c
drivers/tty/serial/8250/8250.h
drivers/tty/serial/8250/8250_acorn.c
drivers/tty/serial/8250/8250_dw.c
drivers/tty/serial/8250/8250_gsc.c
drivers/tty/serial/8250/8250_hp300.c
drivers/tty/serial/8250/8250_pci.c
drivers/tty/serial/8250/8250_pnp.c
drivers/tty/serial/8250/serial_cs.c
drivers/tty/serial/Kconfig
drivers/tty/serial/Makefile
drivers/tty/serial/amba-pl011.c
drivers/tty/serial/bfin_uart.c
drivers/tty/serial/crisv10.c
drivers/tty/serial/imx.c
drivers/tty/serial/ioc4_serial.c
drivers/tty/serial/jsm/jsm_tty.c
drivers/tty/serial/lpc32xx_hs.c [new file with mode: 0644]
drivers/tty/serial/of_serial.c
drivers/tty/serial/pxa.c
drivers/tty/serial/samsung.c
drivers/tty/serial/serial_core.c
drivers/tty/synclink.c
drivers/tty/synclink_gt.c
drivers/tty/synclinkmp.c
drivers/tty/tty_io.c
drivers/tty/tty_ioctl.c
drivers/tty/tty_ldisc.c
drivers/tty/tty_port.c
drivers/tty/vt/keyboard.c
drivers/tty/vt/vt.c
drivers/usb/class/cdc-acm.c
drivers/usb/serial/ark3116.c
drivers/usb/serial/belkin_sa.c
drivers/usb/serial/cp210x.c
drivers/usb/serial/cypress_m8.c
drivers/usb/serial/digi_acceleport.c
drivers/usb/serial/empeg.c
drivers/usb/serial/f81232.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/io_edgeport.c
drivers/usb/serial/io_ti.c
drivers/usb/serial/ir-usb.c
drivers/usb/serial/iuu_phoenix.c
drivers/usb/serial/keyspan.c
drivers/usb/serial/keyspan_pda.c
drivers/usb/serial/kl5kusb105.c
drivers/usb/serial/kobil_sct.c
drivers/usb/serial/mct_u232.c
drivers/usb/serial/metro-usb.c
drivers/usb/serial/mos7720.c
drivers/usb/serial/mos7840.c
drivers/usb/serial/oti6858.c
drivers/usb/serial/pl2303.c
drivers/usb/serial/quatech2.c
drivers/usb/serial/sierra.c
drivers/usb/serial/spcp8x5.c
drivers/usb/serial/ssu100.c
drivers/usb/serial/ti_usb_3410_5052.c
drivers/usb/serial/usb-serial.c
drivers/usb/serial/usb_wwan.c
drivers/usb/serial/whiteheat.c
include/linux/Kbuild
include/linux/cd1400.h [deleted file]
include/linux/cdk.h [deleted file]
include/linux/comstats.h [deleted file]
include/linux/generic_serial.h [deleted file]
include/linux/istallion.h [deleted file]
include/linux/kbd_kern.h
include/linux/sc26198.h [deleted file]
include/linux/serial167.h [deleted file]
include/linux/serial_8250.h
include/linux/stallion.h [deleted file]
include/linux/tty.h
include/linux/tty_driver.h
include/net/irda/ircomm_tty.h
net/bluetooth/rfcomm/tty.c
net/irda/ircomm/ircomm_param.c
net/irda/ircomm/ircomm_tty.c
net/irda/ircomm/ircomm_tty_attach.c
net/irda/ircomm/ircomm_tty_ioctl.c

diff --git a/Documentation/devicetree/bindings/tty/serial/nxp-lpc32xx-hsuart.txt b/Documentation/devicetree/bindings/tty/serial/nxp-lpc32xx-hsuart.txt
new file mode 100644 (file)
index 0000000..0d439df
--- /dev/null
@@ -0,0 +1,14 @@
+* NXP LPC32xx SoC High Speed UART
+
+Required properties:
+- compatible: Should be "nxp,lpc3220-hsuart"
+- reg: Should contain registers location and length
+- interrupts: Should contain interrupt
+
+Example:
+
+       uart1: serial@40014000 {
+               compatible = "nxp,lpc3220-hsuart";
+               reg = <0x40014000 0x1000>;
+               interrupts = <26 0>;
+       };
index 0847fdeee11a5b2961731b97c017df5bf4f4f9ca..ba385f2e0ddc5777daf3f7e9d667e6727ec4c26d 100644 (file)
@@ -25,6 +25,8 @@ Optional properties:
   accesses to the UART (e.g. TI davinci).
 - used-by-rtas : set to indicate that the port is in use by the OpenFirmware
   RTAS and should not be registered.
+- no-loopback-test: set to indicate that the port does not implements loopback
+  test mode
 
 Example:
 
index c34785dca92b8c7ce590c2460f6c9ddab4b65f30..1ce97f497d23952d1b8357f18cf2432c96ddf00e 100644 (file)
@@ -338,7 +338,7 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 {
        /* Handle turning off CRTSCTS */
        if ((old_termios->c_cflag & CRTSCTS) &&
-           !(tty->termios->c_cflag & CRTSCTS)) {
+           !(tty->termios.c_cflag & CRTSCTS)) {
                tty->hw_stopped = 0;
        }
 }
index 12172a6a95c440467666d1599f13bab4fe45253f..0bc8a6a6a14850744d27788b9850ddf9bacac99f 100644 (file)
@@ -58,7 +58,7 @@ static int ath_wakeup_ar3k(struct tty_struct *tty)
                return status;
 
        /* Disable Automatic RTSCTS */
-       memcpy(&ktermios, tty->termios, sizeof(ktermios));
+       ktermios = tty->termios;
        ktermios.c_cflag &= ~CRTSCTS;
        tty_set_termios(tty, &ktermios);
 
index 1d82d5838f0c38c416947d7f95b17d204d0a93b1..164544afd6809b1c1287c5d3fb02c99a29de7ab6 100644 (file)
@@ -430,7 +430,7 @@ static ssize_t mwave_write(struct file *file, const char __user *buf,
 
 static int register_serial_portandirq(unsigned int port, int irq)
 {
-       struct uart_port uart;
+       struct uart_8250_port uart;
        
        switch ( port ) {
                case 0x3f8:
@@ -462,14 +462,14 @@ static int register_serial_portandirq(unsigned int port, int irq)
        } /* switch */
        /* irq is okay */
 
-       memset(&uart, 0, sizeof(struct uart_port));
+       memset(&uart, 0, sizeof(uart));
        
-       uart.uartclk =  1843200;
-       uart.iobase = port;
-       uart.irq = irq;
-       uart.iotype = UPIO_PORT;
-       uart.flags =  UPF_SHARE_IRQ;
-       return serial8250_register_port(&uart);
+       uart.port.uartclk =  1843200;
+       uart.port.iobase = port;
+       uart.port.irq = irq;
+       uart.port.iotype = UPIO_PORT;
+       uart.port.flags =  UPF_SHARE_IRQ;
+       return serial8250_register_8250_port(&uart);
 }
 
 
index 0a484b4a1b02bdabfd231a2ed21b5446ccd95642..d0cbd29ecfd751e14d71425f649ccbd71a286def 100644 (file)
@@ -1344,7 +1344,7 @@ static void shutdown(MGSLPC_INFO * info, struct tty_struct *tty)
        /* TODO:disable interrupts instead of reset to preserve signal states */
        reset_device(info);
 
-       if (!tty || tty->termios->c_cflag & HUPCL) {
+       if (!tty || tty->termios.c_cflag & HUPCL) {
                info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS);
                set_signals(info);
        }
@@ -1385,7 +1385,7 @@ static void mgslpc_program_hw(MGSLPC_INFO *info, struct tty_struct *tty)
        port_irq_enable(info, (unsigned char) PVR_DSR | PVR_RI);
        get_signals(info);
 
-       if (info->netcount || (tty && (tty->termios->c_cflag & CREAD)))
+       if (info->netcount || (tty && (tty->termios.c_cflag & CREAD)))
                rx_start(info);
 
        spin_unlock_irqrestore(&info->lock,flags);
@@ -1398,14 +1398,14 @@ static void mgslpc_change_params(MGSLPC_INFO *info, struct tty_struct *tty)
        unsigned cflag;
        int bits_per_char;
 
-       if (!tty || !tty->termios)
+       if (!tty)
                return;
 
        if (debug_level >= DEBUG_LEVEL_INFO)
                printk("%s(%d):mgslpc_change_params(%s)\n",
                         __FILE__,__LINE__, info->device_name );
 
-       cflag = tty->termios->c_cflag;
+       cflag = tty->termios.c_cflag;
 
        /* if B0 rate (hangup) specified then negate DTR and RTS */
        /* otherwise assert DTR and RTS */
@@ -1728,7 +1728,7 @@ static void mgslpc_throttle(struct tty_struct * tty)
        if (I_IXOFF(tty))
                mgslpc_send_xchar(tty, STOP_CHAR(tty));
 
-       if (tty->termios->c_cflag & CRTSCTS) {
+       if (tty->termios.c_cflag & CRTSCTS) {
                spin_lock_irqsave(&info->lock,flags);
                info->serial_signals &= ~SerialSignal_RTS;
                set_signals(info);
@@ -1757,7 +1757,7 @@ static void mgslpc_unthrottle(struct tty_struct * tty)
                        mgslpc_send_xchar(tty, START_CHAR(tty));
        }
 
-       if (tty->termios->c_cflag & CRTSCTS) {
+       if (tty->termios.c_cflag & CRTSCTS) {
                spin_lock_irqsave(&info->lock,flags);
                info->serial_signals |= SerialSignal_RTS;
                set_signals(info);
@@ -2293,8 +2293,8 @@ static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_term
                        tty->driver->name );
 
        /* just return if nothing has changed */
-       if ((tty->termios->c_cflag == old_termios->c_cflag)
-           && (RELEVANT_IFLAG(tty->termios->c_iflag)
+       if ((tty->termios.c_cflag == old_termios->c_cflag)
+           && (RELEVANT_IFLAG(tty->termios.c_iflag)
                == RELEVANT_IFLAG(old_termios->c_iflag)))
          return;
 
@@ -2302,7 +2302,7 @@ static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_term
 
        /* Handle transition to B0 status */
        if (old_termios->c_cflag & CBAUD &&
-           !(tty->termios->c_cflag & CBAUD)) {
+           !(tty->termios.c_cflag & CBAUD)) {
                info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR);
                spin_lock_irqsave(&info->lock,flags);
                set_signals(info);
@@ -2311,9 +2311,9 @@ static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_term
 
        /* Handle transition away from B0 status */
        if (!(old_termios->c_cflag & CBAUD) &&
-           tty->termios->c_cflag & CBAUD) {
+           tty->termios.c_cflag & CBAUD) {
                info->serial_signals |= SerialSignal_DTR;
-               if (!(tty->termios->c_cflag & CRTSCTS) ||
+               if (!(tty->termios.c_cflag & CRTSCTS) ||
                    !test_bit(TTY_THROTTLED, &tty->flags)) {
                        info->serial_signals |= SerialSignal_RTS;
                }
@@ -2324,7 +2324,7 @@ static void mgslpc_set_termios(struct tty_struct *tty, struct ktermios *old_term
 
        /* Handle turning off CRTSCTS */
        if (old_termios->c_cflag & CRTSCTS &&
-           !(tty->termios->c_cflag & CRTSCTS)) {
+           !(tty->termios.c_cflag & CRTSCTS)) {
                tty->hw_stopped = 0;
                tx_release(tty);
        }
index a6d9fd2858f74d2b6690cfcf9c6edc832f641bb2..f9aab7490868e76e5ec126d3ff1121bfe857b764 100644 (file)
@@ -446,8 +446,8 @@ static void if_set_termios(struct tty_struct *tty, struct ktermios *old)
                goto out;
        }
 
-       iflag = tty->termios->c_iflag;
-       cflag = tty->termios->c_cflag;
+       iflag = tty->termios.c_iflag;
+       cflag = tty->termios.c_cflag;
        old_cflag = old ? old->c_cflag : cflag;
        gig_dbg(DEBUG_IF, "%u: iflag %x cflag %x old %x",
                cs->minor_index, iflag, cflag, old_cflag);
index 7bc50670d7d9fd3cb5c3d4decbf0e32ca86296ea..7a61ef6cffaaf0756159eaf20e0b78c6950f3830 100644 (file)
@@ -1009,15 +1009,15 @@ isdn_tty_change_speed(modem_info *info)
                quot;
        int i;
 
-       if (!port->tty || !port->tty->termios)
+       if (!port->tty)
                return;
-       cflag = port->tty->termios->c_cflag;
+       cflag = port->tty->termios.c_cflag;
 
        quot = i = cflag & CBAUD;
        if (i & CBAUDEX) {
                i &= ~CBAUDEX;
                if (i < 1 || i > 2)
-                       port->tty->termios->c_cflag &= ~CBAUDEX;
+                       port->tty->termios.c_cflag &= ~CBAUDEX;
                else
                        i += 15;
        }
@@ -1097,7 +1097,7 @@ isdn_tty_shutdown(modem_info *info)
 #endif
        isdn_unlock_drivers();
        info->msr &= ~UART_MSR_RI;
-       if (!info->port.tty || (info->port.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);
@@ -1469,13 +1469,13 @@ isdn_tty_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
        if (!old_termios)
                isdn_tty_change_speed(info);
        else {
-               if (tty->termios->c_cflag == old_termios->c_cflag &&
-                   tty->termios->c_ispeed == old_termios->c_ispeed &&
-                   tty->termios->c_ospeed == old_termios->c_ospeed)
+               if (tty->termios.c_cflag == old_termios->c_cflag &&
+                   tty->termios.c_ispeed == old_termios->c_ispeed &&
+                   tty->termios.c_ospeed == old_termios->c_ospeed)
                        return;
                isdn_tty_change_speed(info);
                if ((old_termios->c_cflag & CRTSCTS) &&
-                   !(tty->termios->c_cflag & CRTSCTS))
+                   !(tty->termios.c_cflag & CRTSCTS))
                        tty->hw_stopped = 0;
        }
 }
index 1dcb9ae1905a0853d45795082561f61a0fb56a15..01e2b0d7e59043cfcf652090b5c328a789dd9383 100644 (file)
@@ -33,7 +33,7 @@
 
 void ibmasm_register_uart(struct service_processor *sp)
 {
-       struct uart_port uport;
+       struct uart_8250_port uart;
        void __iomem *iomem_base;
 
        iomem_base = sp->base_address + SCOUT_COM_B_BASE;
@@ -47,14 +47,14 @@ void ibmasm_register_uart(struct service_processor *sp)
                return;
        }
 
-       memset(&uport, 0, sizeof(struct uart_port));
-       uport.irq       = sp->irq;
-       uport.uartclk   = 3686400;
-       uport.flags     = UPF_SHARE_IRQ;
-       uport.iotype    = UPIO_MEM;
-       uport.membase   = iomem_base;
+       memset(&uart, 0, sizeof(uart));
+       uart.port.irq           = sp->irq;
+       uart.port.uartclk       = 3686400;
+       uart.port.flags         = UPF_SHARE_IRQ;
+       uart.port.iotype        = UPIO_MEM;
+       uart.port.membase       = iomem_base;
 
-       sp->serial_line = serial8250_register_port(&uport);
+       sp->serial_line = serial8250_register_8250_port(&uart);
        if (sp->serial_line < 0) {
                dev_err(sp->dev, "Failed to register serial port\n");
                return;
index 5a2cbfac66d23b3197ea548df65b59c8b5f2bbcf..372c0325c1494f09ea564fe88d719eecbdec9a3b 100644 (file)
@@ -518,7 +518,7 @@ static void sdio_uart_check_modem_status(struct sdio_uart_port *port)
        if (status & UART_MSR_DCTS) {
                port->icount.cts++;
                tty = tty_port_tty_get(&port->port);
-               if (tty && (tty->termios->c_cflag & CRTSCTS)) {
+               if (tty && (tty->termios.c_cflag & CRTSCTS)) {
                        int cts = (status & UART_MSR_CTS);
                        if (tty->hw_stopped) {
                                if (cts) {
@@ -671,12 +671,12 @@ static int sdio_uart_activate(struct tty_port *tport, struct tty_struct *tty)
        port->ier = UART_IER_RLSI|UART_IER_RDI|UART_IER_RTOIE|UART_IER_UUE;
        port->mctrl = TIOCM_OUT2;
 
-       sdio_uart_change_speed(port, tty->termios, NULL);
+       sdio_uart_change_speed(port, &tty->termios, NULL);
 
-       if (tty->termios->c_cflag & CBAUD)
+       if (tty->termios.c_cflag & CBAUD)
                sdio_uart_set_mctrl(port, TIOCM_RTS | TIOCM_DTR);
 
-       if (tty->termios->c_cflag & CRTSCTS)
+       if (tty->termios.c_cflag & CRTSCTS)
                if (!(sdio_uart_get_mctrl(port) & TIOCM_CTS))
                        tty->hw_stopped = 1;
 
@@ -850,7 +850,7 @@ static void sdio_uart_throttle(struct tty_struct *tty)
 {
        struct sdio_uart_port *port = tty->driver_data;
 
-       if (!I_IXOFF(tty) && !(tty->termios->c_cflag & CRTSCTS))
+       if (!I_IXOFF(tty) && !(tty->termios.c_cflag & CRTSCTS))
                return;
 
        if (sdio_uart_claim_func(port) != 0)
@@ -861,7 +861,7 @@ static void sdio_uart_throttle(struct tty_struct *tty)
                sdio_uart_start_tx(port);
        }
 
-       if (tty->termios->c_cflag & CRTSCTS)
+       if (tty->termios.c_cflag & CRTSCTS)
                sdio_uart_clear_mctrl(port, TIOCM_RTS);
 
        sdio_uart_irq(port->func);
@@ -872,7 +872,7 @@ static void sdio_uart_unthrottle(struct tty_struct *tty)
 {
        struct sdio_uart_port *port = tty->driver_data;
 
-       if (!I_IXOFF(tty) && !(tty->termios->c_cflag & CRTSCTS))
+       if (!I_IXOFF(tty) && !(tty->termios.c_cflag & CRTSCTS))
                return;
 
        if (sdio_uart_claim_func(port) != 0)
@@ -887,7 +887,7 @@ static void sdio_uart_unthrottle(struct tty_struct *tty)
                }
        }
 
-       if (tty->termios->c_cflag & CRTSCTS)
+       if (tty->termios.c_cflag & CRTSCTS)
                sdio_uart_set_mctrl(port, TIOCM_RTS);
 
        sdio_uart_irq(port->func);
@@ -898,12 +898,12 @@ static void sdio_uart_set_termios(struct tty_struct *tty,
                                                struct ktermios *old_termios)
 {
        struct sdio_uart_port *port = tty->driver_data;
-       unsigned int cflag = tty->termios->c_cflag;
+       unsigned int cflag = tty->termios.c_cflag;
 
        if (sdio_uart_claim_func(port) != 0)
                return;
 
-       sdio_uart_change_speed(port, tty->termios, old_termios);
+       sdio_uart_change_speed(port, &tty->termios, old_termios);
 
        /* Handle transition to B0 status */
        if ((old_termios->c_cflag & CBAUD) && !(cflag & CBAUD))
index b5ba3084c7fc056db06cc07f1e19b1aae1f71c7a..3e5519a0acc7ebcccb897ed3719b8506a3b585ba 100644 (file)
@@ -1147,15 +1147,17 @@ static void __devinit ioc3_8250_register(struct ioc3_uartregs __iomem *uart)
 {
 #define COSMISC_CONSTANT 6
 
-       struct uart_port port = {
-               .irq            = 0,
-               .flags          = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
-               .iotype         = UPIO_MEM,
-               .regshift       = 0,
-               .uartclk        = (22000000 << 1) / COSMISC_CONSTANT,
-
-               .membase        = (unsigned char __iomem *) uart,
-               .mapbase        = (unsigned long) uart,
+       struct uart_8250_port port = {
+               .port = {
+                       .irq            = 0,
+                       .flags          = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF,
+                       .iotype         = UPIO_MEM,
+                       .regshift       = 0,
+                       .uartclk        = (22000000 << 1) / COSMISC_CONSTANT,
+
+                       .membase        = (unsigned char __iomem *) uart,
+                       .mapbase        = (unsigned long) uart,
+                }
        };
        unsigned char lcr;
 
@@ -1164,7 +1166,7 @@ static void __devinit ioc3_8250_register(struct ioc3_uartregs __iomem *uart)
        uart->iu_scr = COSMISC_CONSTANT,
        uart->iu_lcr = lcr;
        uart->iu_lcr;
-       serial8250_register_port(&port);
+       serial8250_register_8250_port(&port);
 }
 
 static void __devinit ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3)
index 3352b2443e58eb1ca0a45856c628850c08092be6..30087ca23a0fc7e6c33c75fcb80f020aae42186c 100644 (file)
@@ -124,8 +124,8 @@ static int irtty_change_speed(struct sir_dev *dev, unsigned speed)
        tty = priv->tty;
 
        mutex_lock(&tty->termios_mutex);
-       old_termios = *(tty->termios);
-       cflag = tty->termios->c_cflag;
+       old_termios = tty->termios;
+       cflag = tty->termios.c_cflag;
        tty_encode_baud_rate(tty, speed, speed);
        if (tty->ops->set_termios)
                tty->ops->set_termios(tty, &old_termios);
@@ -281,15 +281,15 @@ static inline void irtty_stop_receiver(struct tty_struct *tty, int stop)
        int cflag;
 
        mutex_lock(&tty->termios_mutex);
-       old_termios = *(tty->termios);
-       cflag = tty->termios->c_cflag;
+       old_termios = tty->termios;
+       cflag = tty->termios.c_cflag;
        
        if (stop)
                cflag &= ~CREAD;
        else
                cflag |= CREAD;
 
-       tty->termios->c_cflag = cflag;
+       tty->termios.c_cflag = cflag;
        if (tty->ops->set_termios)
                tty->ops->set_termios(tty, &old_termios);
        mutex_unlock(&tty->termios_mutex);
index 62f30b46fa42d26544f20e3158e964eccaa05da4..7736af75e12bd0b4670c97f71856ffdf000a5d52 100644 (file)
@@ -1107,7 +1107,6 @@ static void _hso_serial_set_termios(struct tty_struct *tty,
                                    struct ktermios *old)
 {
        struct hso_serial *serial = tty->driver_data;
-       struct ktermios *termios;
 
        if (!serial) {
                printk(KERN_ERR "%s: no tty structures", __func__);
@@ -1119,16 +1118,15 @@ static void _hso_serial_set_termios(struct tty_struct *tty,
        /*
         *      Fix up unsupported bits
         */
-       termios = tty->termios;
-       termios->c_iflag &= ~IXON; /* disable enable XON/XOFF flow control */
+       tty->termios.c_iflag &= ~IXON; /* disable enable XON/XOFF flow control */
 
-       termios->c_cflag &=
+       tty->termios.c_cflag &=
                ~(CSIZE         /* no size */
                | PARENB        /* disable parity bit */
                | CBAUD         /* clear current baud rate */
                | CBAUDEX);     /* clear current buad rate */
 
-       termios->c_cflag |= CS8;        /* character size 8 bits */
+       tty->termios.c_cflag |= CS8;    /* character size 8 bits */
 
        /* baud rate 115200 */
        tty_encode_baud_rate(tty, 115200, 115200);
@@ -1425,14 +1423,14 @@ static void hso_serial_set_termios(struct tty_struct *tty, struct ktermios *old)
 
        if (old)
                D5("Termios called with: cflags new[%d] - old[%d]",
-                  tty->termios->c_cflag, old->c_cflag);
+                  tty->termios.c_cflag, old->c_cflag);
 
        /* the actual setup */
        spin_lock_irqsave(&serial->serial_lock, flags);
        if (serial->port.count)
                _hso_serial_set_termios(tty, old);
        else
-               tty->termios = old;
+               tty->termios = *old;
        spin_unlock_irqrestore(&serial->serial_lock, flags);
 
        /* done */
index 6cc4358f68c12ad2c779c7837207ce875968cf40..0e8441e73ee01e95b45c72ac60be858e6ff71708 100644 (file)
@@ -646,7 +646,7 @@ static void shutdown(struct tty_struct *tty, struct serial_state *info)
        custom.adkcon = AC_UARTBRK;
        mb();
 
-       if (tty->termios->c_cflag & HUPCL)
+       if (tty->termios.c_cflag & HUPCL)
                info->MCR &= ~(SER_DTR|SER_RTS);
        rtsdtr_ctrl(info->MCR);
 
@@ -670,7 +670,7 @@ static void change_speed(struct tty_struct *tty, struct serial_state *info,
        int     bits;
        unsigned long   flags;
 
-       cflag = tty->termios->c_cflag;
+       cflag = tty->termios.c_cflag;
 
        /* Byte size is always 8 bits plus parity bit if requested */
 
@@ -707,8 +707,8 @@ static void change_speed(struct tty_struct *tty, struct serial_state *info,
        /* If the quotient is zero refuse the change */
        if (!quot && old_termios) {
                /* FIXME: Will need updating for new tty in the end */
-               tty->termios->c_cflag &= ~CBAUD;
-               tty->termios->c_cflag |= (old_termios->c_cflag & CBAUD);
+               tty->termios.c_cflag &= ~CBAUD;
+               tty->termios.c_cflag |= (old_termios->c_cflag & CBAUD);
                baud = tty_get_baud_rate(tty);
                if (!baud)
                        baud = 9600;
@@ -984,7 +984,7 @@ static void rs_throttle(struct tty_struct * tty)
        if (I_IXOFF(tty))
                rs_send_xchar(tty, STOP_CHAR(tty));
 
-       if (tty->termios->c_cflag & CRTSCTS)
+       if (tty->termios.c_cflag & CRTSCTS)
                info->MCR &= ~SER_RTS;
 
        local_irq_save(flags);
@@ -1012,7 +1012,7 @@ static void rs_unthrottle(struct tty_struct * tty)
                else
                        rs_send_xchar(tty, START_CHAR(tty));
        }
-       if (tty->termios->c_cflag & CRTSCTS)
+       if (tty->termios.c_cflag & CRTSCTS)
                info->MCR |= SER_RTS;
        local_irq_save(flags);
        rtsdtr_ctrl(info->MCR);
@@ -1330,7 +1330,7 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 {
        struct serial_state *info = tty->driver_data;
        unsigned long flags;
-       unsigned int cflag = tty->termios->c_cflag;
+       unsigned int cflag = tty->termios.c_cflag;
 
        change_speed(tty, info, old_termios);
 
@@ -1347,7 +1347,7 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
        if (!(old_termios->c_cflag & CBAUD) &&
            (cflag & CBAUD)) {
                info->MCR |= SER_DTR;
-               if (!(tty->termios->c_cflag & CRTSCTS) || 
+               if (!(tty->termios.c_cflag & CRTSCTS) || 
                    !test_bit(TTY_THROTTLED, &tty->flags)) {
                        info->MCR |= SER_RTS;
                }
@@ -1358,7 +1358,7 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 
        /* Handle turning off CRTSCTS */
        if ((old_termios->c_cflag & CRTSCTS) &&
-           !(tty->termios->c_cflag & CRTSCTS)) {
+           !(tty->termios.c_cflag & CRTSCTS)) {
                tty->hw_stopped = 0;
                rs_start(tty);
        }
@@ -1371,7 +1371,7 @@ static void rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
         * or not.  Hence, this may change.....
         */
        if (!(old_termios->c_cflag & CLOCAL) &&
-           (tty->termios->c_cflag & CLOCAL))
+           (tty->termios.c_cflag & CLOCAL))
                wake_up_interruptible(&info->open_wait);
 #endif
 }
index e61cabdd69df36d56ea0c0cd27fcaeadc488f8de..e77db714ab26d4a3e2d6e1d15434495d473e7e14 100644 (file)
@@ -1459,7 +1459,7 @@ static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty)
                        info->port.xmit_buf = NULL;
                        free_page((unsigned long)temp);
                }
-               if (tty->termios->c_cflag & HUPCL)
+               if (tty->termios.c_cflag & HUPCL)
                        cyy_change_rts_dtr(info, 0, TIOCM_RTS | TIOCM_DTR);
 
                cyy_issue_cmd(info, CyCHAN_CTL | CyDIS_RCVR);
@@ -1488,7 +1488,7 @@ static void cy_shutdown(struct cyclades_port *info, struct tty_struct *tty)
                        free_page((unsigned long)temp);
                }
 
-               if (tty->termios->c_cflag & HUPCL)
+               if (tty->termios.c_cflag & HUPCL)
                        tty_port_lower_dtr_rts(&info->port);
 
                set_bit(TTY_IO_ERROR, &tty->flags);
@@ -1999,14 +1999,11 @@ static void cy_set_line_char(struct cyclades_port *info, struct tty_struct *tty)
        int baud, baud_rate = 0;
        int i;
 
-       if (!tty->termios) /* XXX can this happen at all? */
-               return;
-
        if (info->line == -1)
                return;
 
-       cflag = tty->termios->c_cflag;
-       iflag = tty->termios->c_iflag;
+       cflag = tty->termios.c_cflag;
+       iflag = tty->termios.c_iflag;
 
        /*
         * Set up the tty->alt_speed kludge
@@ -2825,7 +2822,7 @@ static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
        cy_set_line_char(info, tty);
 
        if ((old_termios->c_cflag & CRTSCTS) &&
-                       !(tty->termios->c_cflag & CRTSCTS)) {
+                       !(tty->termios.c_cflag & CRTSCTS)) {
                tty->hw_stopped = 0;
                cy_start(tty);
        }
@@ -2837,7 +2834,7 @@ static void cy_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
         * or not.  Hence, this may change.....
         */
        if (!(old_termios->c_cflag & CLOCAL) &&
-           (tty->termios->c_cflag & CLOCAL))
+           (tty->termios.c_cflag & CLOCAL))
                wake_up_interruptible(&info->port.open_wait);
 #endif
 }                              /* cy_set_termios */
@@ -2899,7 +2896,7 @@ static void cy_throttle(struct tty_struct *tty)
                        info->throttle = 1;
        }
 
-       if (tty->termios->c_cflag & CRTSCTS) {
+       if (tty->termios.c_cflag & CRTSCTS) {
                if (!cy_is_Z(card)) {
                        spin_lock_irqsave(&card->card_lock, flags);
                        cyy_change_rts_dtr(info, 0, TIOCM_RTS);
@@ -2938,7 +2935,7 @@ static void cy_unthrottle(struct tty_struct *tty)
                        cy_send_xchar(tty, START_CHAR(tty));
        }
 
-       if (tty->termios->c_cflag & CRTSCTS) {
+       if (tty->termios.c_cflag & CRTSCTS) {
                card = info->card;
                if (!cy_is_Z(card)) {
                        spin_lock_irqsave(&card->card_lock, flags);
@@ -3289,6 +3286,7 @@ static unsigned short __devinit cyy_init_card(void __iomem *true_base_addr,
 static int __init cy_detect_isa(void)
 {
 #ifdef CONFIG_ISA
+       struct cyclades_card *card;
        unsigned short cy_isa_irq, nboard;
        void __iomem *cy_isa_address;
        unsigned short i, j, cy_isa_nchan;
@@ -3349,7 +3347,8 @@ static int __init cy_detect_isa(void)
                }
                /* fill the next cy_card structure available */
                for (j = 0; j < NR_CARDS; j++) {
-                       if (cy_card[j].base_addr == NULL)
+                       card = &cy_card[j];
+                       if (card->base_addr == NULL)
                                break;
                }
                if (j == NR_CARDS) {    /* no more cy_cards available */
@@ -3363,7 +3362,7 @@ static int __init cy_detect_isa(void)
 
                /* allocate IRQ */
                if (request_irq(cy_isa_irq, cyy_interrupt,
-                               0, "Cyclom-Y", &cy_card[j])) {
+                               0, "Cyclom-Y", card)) {
                        printk(KERN_ERR "Cyclom-Y/ISA found at 0x%lx, but "
                                "could not allocate IRQ#%d.\n",
                                (unsigned long)cy_isa_address, cy_isa_irq);
@@ -3372,16 +3371,16 @@ static int __init cy_detect_isa(void)
                }
 
                /* set cy_card */
-               cy_card[j].base_addr = cy_isa_address;
-               cy_card[j].ctl_addr.p9050 = NULL;
-               cy_card[j].irq = (int)cy_isa_irq;
-               cy_card[j].bus_index = 0;
-               cy_card[j].first_line = cy_next_channel;
-               cy_card[j].num_chips = cy_isa_nchan / CyPORTS_PER_CHIP;
-               cy_card[j].nports = cy_isa_nchan;
-               if (cy_init_card(&cy_card[j])) {
-                       cy_card[j].base_addr = NULL;
-                       free_irq(cy_isa_irq, &cy_card[j]);
+               card->base_addr = cy_isa_address;
+               card->ctl_addr.p9050 = NULL;
+               card->irq = (int)cy_isa_irq;
+               card->bus_index = 0;
+               card->first_line = cy_next_channel;
+               card->num_chips = cy_isa_nchan / CyPORTS_PER_CHIP;
+               card->nports = cy_isa_nchan;
+               if (cy_init_card(card)) {
+                       card->base_addr = NULL;
+                       free_irq(cy_isa_irq, card);
                        iounmap(cy_isa_address);
                        continue;
                }
@@ -3695,6 +3694,7 @@ err:
 static int __devinit cy_pci_probe(struct pci_dev *pdev,
                const struct pci_device_id *ent)
 {
+       struct cyclades_card *card;
        void __iomem *addr0 = NULL, *addr2 = NULL;
        char *card_name = NULL;
        u32 uninitialized_var(mailbox);
@@ -3829,7 +3829,8 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev,
        }
        /* fill the next cy_card structure available */
        for (card_no = 0; card_no < NR_CARDS; card_no++) {
-               if (cy_card[card_no].base_addr == NULL)
+               card = &cy_card[card_no];
+               if (card->base_addr == NULL)
                        break;
        }
        if (card_no == NR_CARDS) {      /* no more cy_cards available */
@@ -3843,27 +3844,26 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev,
                        device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) {
                /* allocate IRQ */
                retval = request_irq(irq, cyy_interrupt,
-                               IRQF_SHARED, "Cyclom-Y", &cy_card[card_no]);
+                               IRQF_SHARED, "Cyclom-Y", card);
                if (retval) {
                        dev_err(&pdev->dev, "could not allocate IRQ\n");
                        goto err_unmap;
                }
-               cy_card[card_no].num_chips = nchan / CyPORTS_PER_CHIP;
+               card->num_chips = nchan / CyPORTS_PER_CHIP;
        } else {
                struct FIRM_ID __iomem *firm_id = addr2 + ID_ADDRESS;
                struct ZFW_CTRL __iomem *zfw_ctrl;
 
                zfw_ctrl = addr2 + (readl(&firm_id->zfwctrl_addr) & 0xfffff);
 
-               cy_card[card_no].hw_ver = mailbox;
-               cy_card[card_no].num_chips = (unsigned int)-1;
-               cy_card[card_no].board_ctrl = &zfw_ctrl->board_ctrl;
+               card->hw_ver = mailbox;
+               card->num_chips = (unsigned int)-1;
+               card->board_ctrl = &zfw_ctrl->board_ctrl;
 #ifdef CONFIG_CYZ_INTR
                /* allocate IRQ only if board has an IRQ */
                if (irq != 0 && irq != 255) {
                        retval = request_irq(irq, cyz_interrupt,
-                                       IRQF_SHARED, "Cyclades-Z",
-                                       &cy_card[card_no]);
+                                       IRQF_SHARED, "Cyclades-Z", card);
                        if (retval) {
                                dev_err(&pdev->dev, "could not allocate IRQ\n");
                                goto err_unmap;
@@ -3873,17 +3873,17 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev,
        }
 
        /* set cy_card */
-       cy_card[card_no].base_addr = addr2;
-       cy_card[card_no].ctl_addr.p9050 = addr0;
-       cy_card[card_no].irq = irq;
-       cy_card[card_no].bus_index = 1;
-       cy_card[card_no].first_line = cy_next_channel;
-       cy_card[card_no].nports = nchan;
-       retval = cy_init_card(&cy_card[card_no]);
+       card->base_addr = addr2;
+       card->ctl_addr.p9050 = addr0;
+       card->irq = irq;
+       card->bus_index = 1;
+       card->first_line = cy_next_channel;
+       card->nports = nchan;
+       retval = cy_init_card(card);
        if (retval)
                goto err_null;
 
-       pci_set_drvdata(pdev, &cy_card[card_no]);
+       pci_set_drvdata(pdev, card);
 
        if (device_id == PCI_DEVICE_ID_CYCLOM_Y_Lo ||
                        device_id == PCI_DEVICE_ID_CYCLOM_Y_Hi) {
@@ -3915,8 +3915,8 @@ static int __devinit cy_pci_probe(struct pci_dev *pdev,
 
        return 0;
 err_null:
-       cy_card[card_no].base_addr = NULL;
-       free_irq(irq, &cy_card[card_no]);
+       card->base_addr = NULL;
+       free_irq(irq, card);
 err_unmap:
        iounmap(addr0);
        if (addr2)
index 59c135dd5d2069ecee49e21480e47e52359fec46..3396eb9d57a374770f22dd956d06fa3382196f66 100644 (file)
@@ -400,7 +400,7 @@ void hvsilib_close(struct hvsi_priv *pv, struct hvc_struct *hp)
                spin_unlock_irqrestore(&hp->lock, flags);
 
                /* Clear our own DTR */
-               if (!pv->tty || (pv->tty->termios->c_cflag & HUPCL))
+               if (!pv->tty || (pv->tty->termios.c_cflag & HUPCL))
                        hvsilib_write_mctrl(pv, 0);
 
                /* Tear down the connection */
index e1235accab740b4bca4eb01c28b0ed76e170ea93..d593a7d18ad5f462ee7c00ad022ee3b4b2b399da 100644 (file)
@@ -702,7 +702,7 @@ static void isicom_config_port(struct tty_struct *tty)
 
                /* 1,2,3,4 => 57.6, 115.2, 230, 460 kbps resp. */
                if (baud < 1 || baud > 4)
-                       tty->termios->c_cflag &= ~CBAUDEX;
+                       tty->termios.c_cflag &= ~CBAUDEX;
                else
                        baud += 15;
        }
@@ -1196,8 +1196,8 @@ static void isicom_set_termios(struct tty_struct *tty,
        if (isicom_paranoia_check(port, tty->name, "isicom_set_termios"))
                return;
 
-       if (tty->termios->c_cflag == old_termios->c_cflag &&
-                       tty->termios->c_iflag == old_termios->c_iflag)
+       if (tty->termios.c_cflag == old_termios->c_cflag &&
+                       tty->termios.c_iflag == old_termios->c_iflag)
                return;
 
        spin_lock_irqsave(&port->card->card_lock, flags);
@@ -1205,7 +1205,7 @@ static void isicom_set_termios(struct tty_struct *tty,
        spin_unlock_irqrestore(&port->card->card_lock, flags);
 
        if ((old_termios->c_cflag & CRTSCTS) &&
-                       !(tty->termios->c_cflag & CRTSCTS)) {
+                       !(tty->termios.c_cflag & CRTSCTS)) {
                tty->hw_stopped = 0;
                isicom_start(tty);
        }
index 324467d28a5497bcca18b2f52d31943d2747f795..89cc9344325b8ac6a117f61f50243324e1d4c4a6 100644 (file)
@@ -367,10 +367,10 @@ static int moxa_ioctl(struct tty_struct *tty,
                                        tmp.dcd = 1;
 
                                ttyp = tty_port_tty_get(&p->port);
-                               if (!ttyp || !ttyp->termios)
+                               if (!ttyp)
                                        tmp.cflag = p->cflag;
                                else
-                                       tmp.cflag = ttyp->termios->c_cflag;
+                                       tmp.cflag = ttyp->termios.c_cflag;
                                tty_kref_put(ttyp);
 copy:
                                if (copy_to_user(argm, &tmp, sizeof(tmp)))
@@ -1178,7 +1178,7 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
        mutex_lock(&ch->port.mutex);
        if (!(ch->port.flags & ASYNC_INITIALIZED)) {
                ch->statusflags = 0;
-               moxa_set_tty_param(tty, tty->termios);
+               moxa_set_tty_param(tty, &tty->termios);
                MoxaPortLineCtrl(ch, 1, 1);
                MoxaPortEnable(ch);
                MoxaSetFifo(ch, ch->type == PORT_16550A);
@@ -1193,7 +1193,7 @@ static int moxa_open(struct tty_struct *tty, struct file *filp)
 static void moxa_close(struct tty_struct *tty, struct file *filp)
 {
        struct moxa_port *ch = tty->driver_data;
-       ch->cflag = tty->termios->c_cflag;
+       ch->cflag = tty->termios.c_cflag;
        tty_port_close(&ch->port, tty, filp);
 }
 
@@ -1464,7 +1464,7 @@ static void moxa_poll(unsigned long ignored)
 
 static void moxa_set_tty_param(struct tty_struct *tty, struct ktermios *old_termios)
 {
-       register struct ktermios *ts = tty->termios;
+       register struct ktermios *ts = &tty->termios;
        struct moxa_port *ch = tty->driver_data;
        int rts, cts, txflow, rxflow, xany, baud;
 
index 90cc680c4f0e7e330f9daa201cb0b30fd2be8aab..c162ee93116750dbcaabd01f633fe010b5bb6c96 100644 (file)
@@ -643,7 +643,7 @@ static int mxser_change_speed(struct tty_struct *tty,
        int ret = 0;
        unsigned char status;
 
-       cflag = tty->termios->c_cflag;
+       cflag = tty->termios.c_cflag;
        if (!info->ioaddr)
                return ret;
 
@@ -1520,10 +1520,10 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp)
                                
                                tty = tty_port_tty_get(port);
 
-                               if (!tty || !tty->termios)
+                               if (!tty)
                                        ms.cflag = ip->normal_termios.c_cflag;
                                else
-                                       ms.cflag = tty->termios->c_cflag;
+                                       ms.cflag = tty->termios.c_cflag;
                                tty_kref_put(tty);
                                spin_lock_irq(&ip->slock);
                                status = inb(ip->ioaddr + UART_MSR);
@@ -1589,13 +1589,13 @@ static int mxser_ioctl_special(unsigned int cmd, void __user *argp)
 
                                tty = tty_port_tty_get(&ip->port);
 
-                               if (!tty || !tty->termios) {
+                               if (!tty) {
                                        cflag = ip->normal_termios.c_cflag;
                                        iflag = ip->normal_termios.c_iflag;
                                        me->baudrate[p] = tty_termios_baud_rate(&ip->normal_termios);
                                } else {
-                                       cflag = tty->termios->c_cflag;
-                                       iflag = tty->termios->c_iflag;
+                                       cflag = tty->termios.c_cflag;
+                                       iflag = tty->termios.c_iflag;
                                        me->baudrate[p] = tty_get_baud_rate(tty);
                                }
                                tty_kref_put(tty);
@@ -1853,7 +1853,7 @@ static void mxser_stoprx(struct tty_struct *tty)
                }
        }
 
-       if (tty->termios->c_cflag & CRTSCTS) {
+       if (tty->termios.c_cflag & CRTSCTS) {
                info->MCR &= ~UART_MCR_RTS;
                outb(info->MCR, info->ioaddr + UART_MCR);
        }
@@ -1890,7 +1890,7 @@ static void mxser_unthrottle(struct tty_struct *tty)
                }
        }
 
-       if (tty->termios->c_cflag & CRTSCTS) {
+       if (tty->termios.c_cflag & CRTSCTS) {
                info->MCR |= UART_MCR_RTS;
                outb(info->MCR, info->ioaddr + UART_MCR);
        }
@@ -1939,14 +1939,14 @@ static void mxser_set_termios(struct tty_struct *tty, struct ktermios *old_termi
        spin_unlock_irqrestore(&info->slock, flags);
 
        if ((old_termios->c_cflag & CRTSCTS) &&
-                       !(tty->termios->c_cflag & CRTSCTS)) {
+                       !(tty->termios.c_cflag & CRTSCTS)) {
                tty->hw_stopped = 0;
                mxser_start(tty);
        }
 
        /* Handle sw stopped */
        if ((old_termios->c_iflag & IXON) &&
-                       !(tty->termios->c_iflag & IXON)) {
+                       !(tty->termios.c_iflag & IXON)) {
                tty->stopped = 0;
 
                if (info->board->chip_flag) {
index c43b683b6eb811babdb7cbc1a1c6bc75eb7ae413..7a4bf3053a153e175b7336b981c88e71a1a8ac7e 100644 (file)
@@ -1061,7 +1061,7 @@ static void gsm_process_modem(struct tty_struct *tty, struct gsm_dlci *dlci,
        /* Carrier drop -> hangup */
        if (tty) {
                if ((mlines & TIOCM_CD) == 0 && (dlci->modem_rx & TIOCM_CD))
-                       if (!(tty->termios->c_cflag & CLOCAL))
+                       if (!(tty->termios.c_cflag & CLOCAL))
                                tty_hangup(tty);
                if (brk & 0x01)
                        tty_insert_flip_char(tty, 0, TTY_BREAK);
@@ -3043,13 +3043,13 @@ static void gsmtty_set_termios(struct tty_struct *tty, struct ktermios *old)
           the RPN control message. This however rapidly gets nasty as we
           then have to remap modem signals each way according to whether
           our virtual cable is null modem etc .. */
-       tty_termios_copy_hw(tty->termios, old);
+       tty_termios_copy_hw(&tty->termios, old);
 }
 
 static void gsmtty_throttle(struct tty_struct *tty)
 {
        struct gsm_dlci *dlci = tty->driver_data;
-       if (tty->termios->c_cflag & CRTSCTS)
+       if (tty->termios.c_cflag & CRTSCTS)
                dlci->modem_tx &= ~TIOCM_DTR;
        dlci->throttled = 1;
        /* Send an MSC with DTR cleared */
@@ -3059,7 +3059,7 @@ static void gsmtty_throttle(struct tty_struct *tty)
 static void gsmtty_unthrottle(struct tty_struct *tty)
 {
        struct gsm_dlci *dlci = tty->driver_data;
-       if (tty->termios->c_cflag & CRTSCTS)
+       if (tty->termios.c_cflag & CRTSCTS)
                dlci->modem_tx |= TIOCM_DTR;
        dlci->throttled = 0;
        /* Send an MSC with DTR set */
index ee1c268f5f9d6582da5b0eeb5121ada945fcd800..101790cea4ae45622c0628bf1833012087f9c7c5 100644 (file)
@@ -1432,6 +1432,12 @@ static void n_tty_receive_buf(struct tty_struct *tty, const unsigned char *cp,
         */
        if (tty->receive_room < TTY_THRESHOLD_THROTTLE)
                tty_throttle(tty);
+
+        /* FIXME: there is a tiny race here if the receive room check runs
+           before the other work executes and empties the buffer (upping
+           the receiving room and unthrottling. We then throttle and get
+           stuck. This has been observed and traced down by Vincent Pillet/
+           We need to address this when we sort out out the rx path locking */
 }
 
 int is_ignored(int sig)
@@ -1460,7 +1466,7 @@ static void n_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
        BUG_ON(!tty);
 
        if (old)
-               canon_change = (old->c_lflag ^ tty->termios->c_lflag) & ICANON;
+               canon_change = (old->c_lflag ^ tty->termios.c_lflag) & ICANON;
        if (canon_change) {
                memset(&tty->read_flags, 0, sizeof tty->read_flags);
                tty->canon_head = tty->read_tail;
index 5505ffc91da4b5780b33af2cac624ea8f696f5e4..d6579a9064c480db17c29559d2318b2d137337fb 100644 (file)
@@ -231,8 +231,8 @@ out:
 static void pty_set_termios(struct tty_struct *tty,
                                        struct ktermios *old_termios)
 {
-       tty->termios->c_cflag &= ~(CSIZE | PARENB);
-       tty->termios->c_cflag |= (CS8 | CREAD);
+       tty->termios.c_cflag &= ~(CSIZE | PARENB);
+       tty->termios.c_cflag |= (CS8 | CREAD);
 }
 
 /**
@@ -282,60 +282,107 @@ done:
        return 0;
 }
 
-/* Traditional BSD devices */
-#ifdef CONFIG_LEGACY_PTYS
-
-static int pty_install(struct tty_driver *driver, struct tty_struct *tty)
+/**
+ *     pty_common_install              -       set up the pty pair
+ *     @driver: the pty driver
+ *     @tty: the tty being instantiated
+ *     @bool: legacy, true if this is BSD style
+ *
+ *     Perform the initial set up for the tty/pty pair. Called from the
+ *     tty layer when the port is first opened.
+ *
+ *     Locking: the caller must hold the tty_mutex
+ */
+static int pty_common_install(struct tty_driver *driver, struct tty_struct *tty,
+               bool legacy)
 {
        struct tty_struct *o_tty;
+       struct tty_port *ports[2];
        int idx = tty->index;
-       int retval;
+       int retval = -ENOMEM;
 
        o_tty = alloc_tty_struct();
-       if (!o_tty)
-               return -ENOMEM;
+       ports[0] = kmalloc(sizeof **ports, GFP_KERNEL);
+       ports[1] = kmalloc(sizeof **ports, GFP_KERNEL);
+       if (!o_tty || !ports[0] || !ports[1])
+               goto err_free_tty;
        if (!try_module_get(driver->other->owner)) {
                /* This cannot in fact currently happen */
-               retval = -ENOMEM;
                goto err_free_tty;
        }
        initialize_tty_struct(o_tty, driver->other, idx);
 
-       /* We always use new tty termios data so we can do this
-          the easy way .. */
-       retval = tty_init_termios(tty);
-       if (retval)
-               goto err_deinit_tty;
-
-       retval = tty_init_termios(o_tty);
-       if (retval)
-               goto err_free_termios;
+       if (legacy) {
+               /* We always use new tty termios data so we can do this
+                  the easy way .. */
+               retval = tty_init_termios(tty);
+               if (retval)
+                       goto err_deinit_tty;
+
+               retval = tty_init_termios(o_tty);
+               if (retval)
+                       goto err_free_termios;
+
+               driver->other->ttys[idx] = o_tty;
+               driver->ttys[idx] = tty;
+       } else {
+               memset(&tty->termios_locked, 0, sizeof(tty->termios_locked));
+               tty->termios = driver->init_termios;
+               memset(&o_tty->termios_locked, 0, sizeof(tty->termios_locked));
+               o_tty->termios = driver->other->init_termios;
+       }
 
        /*
         * Everything allocated ... set up the o_tty structure.
         */
-       driver->other->ttys[idx] = o_tty;
        tty_driver_kref_get(driver->other);
        if (driver->subtype == PTY_TYPE_MASTER)
                o_tty->count++;
        /* Establish the links in both directions */
        tty->link   = o_tty;
        o_tty->link = tty;
+       tty_port_init(ports[0]);
+       tty_port_init(ports[1]);
+       o_tty->port = ports[0];
+       tty->port = ports[1];
 
        tty_driver_kref_get(driver);
        tty->count++;
-       driver->ttys[idx] = tty;
        return 0;
 err_free_termios:
-       tty_free_termios(tty);
+       if (legacy)
+               tty_free_termios(tty);
 err_deinit_tty:
        deinitialize_tty_struct(o_tty);
        module_put(o_tty->driver->owner);
 err_free_tty:
+       kfree(ports[0]);
+       kfree(ports[1]);
        free_tty_struct(o_tty);
        return retval;
 }
 
+static void pty_cleanup(struct tty_struct *tty)
+{
+       kfree(tty->port);
+}
+
+/* Traditional BSD devices */
+#ifdef CONFIG_LEGACY_PTYS
+
+static int pty_install(struct tty_driver *driver, struct tty_struct *tty)
+{
+       return pty_common_install(driver, tty, true);
+}
+
+static void pty_remove(struct tty_driver *driver, struct tty_struct *tty)
+{
+       struct tty_struct *pair = tty->link;
+       driver->ttys[tty->index] = NULL;
+       if (pair)
+               pair->driver->ttys[pair->index] = NULL;
+}
+
 static int pty_bsd_ioctl(struct tty_struct *tty,
                         unsigned int cmd, unsigned long arg)
 {
@@ -366,7 +413,9 @@ static const struct tty_operations master_pty_ops_bsd = {
        .unthrottle = pty_unthrottle,
        .set_termios = pty_set_termios,
        .ioctl = pty_bsd_ioctl,
-       .resize = pty_resize
+       .cleanup = pty_cleanup,
+       .resize = pty_resize,
+       .remove = pty_remove
 };
 
 static const struct tty_operations slave_pty_ops_bsd = {
@@ -379,7 +428,9 @@ static const struct tty_operations slave_pty_ops_bsd = {
        .chars_in_buffer = pty_chars_in_buffer,
        .unthrottle = pty_unthrottle,
        .set_termios = pty_set_termios,
-       .resize = pty_resize
+       .cleanup = pty_cleanup,
+       .resize = pty_resize,
+       .remove = pty_remove
 };
 
 static void __init legacy_pty_init(void)
@@ -497,78 +548,22 @@ static struct tty_struct *pts_unix98_lookup(struct tty_driver *driver,
        return tty;
 }
 
-static void pty_unix98_shutdown(struct tty_struct *tty)
-{
-       tty_driver_remove_tty(tty->driver, tty);
-       /* We have our own method as we don't use the tty index */
-       kfree(tty->termios);
-}
-
 /* We have no need to install and remove our tty objects as devpts does all
    the work for us */
 
 static int pty_unix98_install(struct tty_driver *driver, struct tty_struct *tty)
 {
-       struct tty_struct *o_tty;
-       int idx = tty->index;
-
-       o_tty = alloc_tty_struct();
-       if (!o_tty)
-               return -ENOMEM;
-       if (!try_module_get(driver->other->owner)) {
-               /* This cannot in fact currently happen */
-               goto err_free_tty;
-       }
-       initialize_tty_struct(o_tty, driver->other, idx);
-
-       tty->termios = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL);
-       if (tty->termios == NULL)
-               goto err_free_mem;
-       *tty->termios = driver->init_termios;
-       tty->termios_locked = tty->termios + 1;
-
-       o_tty->termios = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL);
-       if (o_tty->termios == NULL)
-               goto err_free_mem;
-       *o_tty->termios = driver->other->init_termios;
-       o_tty->termios_locked = o_tty->termios + 1;
-
-       tty_driver_kref_get(driver->other);
-       if (driver->subtype == PTY_TYPE_MASTER)
-               o_tty->count++;
-       /* Establish the links in both directions */
-       tty->link   = o_tty;
-       o_tty->link = tty;
-       /*
-        * All structures have been allocated, so now we install them.
-        * Failures after this point use release_tty to clean up, so
-        * there's no need to null out the local pointers.
-        */
-       tty_driver_kref_get(driver);
-       tty->count++;
-       return 0;
-err_free_mem:
-       deinitialize_tty_struct(o_tty);
-       kfree(o_tty->termios);
-       kfree(tty->termios);
-       module_put(o_tty->driver->owner);
-err_free_tty:
-       free_tty_struct(o_tty);
-       return -ENOMEM;
-}
-
-static void ptm_unix98_remove(struct tty_driver *driver, struct tty_struct *tty)
-{
+       return pty_common_install(driver, tty, false);
 }
 
-static void pts_unix98_remove(struct tty_driver *driver, struct tty_struct *tty)
+static void pty_unix98_remove(struct tty_driver *driver, struct tty_struct *tty)
 {
 }
 
 static const struct tty_operations ptm_unix98_ops = {
        .lookup = ptm_unix98_lookup,
        .install = pty_unix98_install,
-       .remove = ptm_unix98_remove,
+       .remove = pty_unix98_remove,
        .open = pty_open,
        .close = pty_close,
        .write = pty_write,
@@ -578,14 +573,14 @@ static const struct tty_operations ptm_unix98_ops = {
        .unthrottle = pty_unthrottle,
        .set_termios = pty_set_termios,
        .ioctl = pty_unix98_ioctl,
-       .shutdown = pty_unix98_shutdown,
-       .resize = pty_resize
+       .resize = pty_resize,
+       .cleanup = pty_cleanup
 };
 
 static const struct tty_operations pty_unix98_ops = {
        .lookup = pts_unix98_lookup,
        .install = pty_unix98_install,
-       .remove = pts_unix98_remove,
+       .remove = pty_unix98_remove,
        .open = pty_open,
        .close = pty_close,
        .write = pty_write,
@@ -594,7 +589,7 @@ static const struct tty_operations pty_unix98_ops = {
        .chars_in_buffer = pty_chars_in_buffer,
        .unthrottle = pty_unthrottle,
        .set_termios = pty_set_termios,
-       .shutdown = pty_unix98_shutdown
+       .cleanup = pty_cleanup,
 };
 
 /**
index 777d5f9cf6cc13e4d91c3ec175621aa4c16d2456..016984a460e0c968a5f3e305341d69e36b28715b 100644 (file)
@@ -720,7 +720,7 @@ static void configure_r_port(struct tty_struct *tty, struct r_port *info,
        unsigned rocketMode;
        int bits, baud, divisor;
        CHANNEL_t *cp;
-       struct ktermios *t = tty->termios;
+       struct ktermios *t = &tty->termios;
 
        cp = &info->channel;
        cflag = t->c_cflag;
@@ -978,7 +978,7 @@ static int rp_open(struct tty_struct *tty, struct file *filp)
                        tty->alt_speed = 460800;
 
                configure_r_port(tty, info, NULL);
-               if (tty->termios->c_cflag & CBAUD) {
+               if (tty->termios.c_cflag & CBAUD) {
                        sSetDTR(cp);
                        sSetRTS(cp);
                }
@@ -1089,35 +1089,35 @@ static void rp_set_termios(struct tty_struct *tty,
        if (rocket_paranoia_check(info, "rp_set_termios"))
                return;
 
-       cflag = tty->termios->c_cflag;
+       cflag = tty->termios.c_cflag;
 
        /*
         * This driver doesn't support CS5 or CS6
         */
        if (((cflag & CSIZE) == CS5) || ((cflag & CSIZE) == CS6))
-               tty->termios->c_cflag =
+               tty->termios.c_cflag =
                    ((cflag & ~CSIZE) | (old_termios->c_cflag & CSIZE));
        /* Or CMSPAR */
-       tty->termios->c_cflag &= ~CMSPAR;
+       tty->termios.c_cflag &= ~CMSPAR;
 
        configure_r_port(tty, info, old_termios);
 
        cp = &info->channel;
 
        /* Handle transition to B0 status */
-       if ((old_termios->c_cflag & CBAUD) && !(tty->termios->c_cflag & CBAUD)) {
+       if ((old_termios->c_cflag & CBAUD) && !(tty->termios.c_cflag & CBAUD)) {
                sClrDTR(cp);
                sClrRTS(cp);
        }
 
        /* Handle transition away from B0 status */
-       if (!(old_termios->c_cflag & CBAUD) && (tty->termios->c_cflag & CBAUD)) {
-               if (!tty->hw_stopped || !(tty->termios->c_cflag & CRTSCTS))
+       if (!(old_termios->c_cflag & CBAUD) && (tty->termios.c_cflag & CBAUD)) {
+               if (!tty->hw_stopped || !(tty->termios.c_cflag & CRTSCTS))
                        sSetRTS(cp);
                sSetDTR(cp);
        }
 
-       if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios->c_cflag & CRTSCTS)) {
+       if ((old_termios->c_cflag & CRTSCTS) && !(tty->termios.c_cflag & CRTSCTS)) {
                tty->hw_stopped = 0;
                rp_start(tty);
        }
index 8123f784bcdacf3bf653fc7c2c1c57ba0540609f..44f52c6f15b9870ad499f1fac41478057ecec268 100644 (file)
@@ -2202,6 +2202,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
        unsigned char cval, fcr = 0;
        unsigned long flags;
        unsigned int baud, quot;
+       int fifo_bug = 0;
 
        switch (termios->c_cflag & CSIZE) {
        case CS5:
@@ -2221,8 +2222,11 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
 
        if (termios->c_cflag & CSTOPB)
                cval |= UART_LCR_STOP;
-       if (termios->c_cflag & PARENB)
+       if (termios->c_cflag & PARENB) {
                cval |= UART_LCR_PARITY;
+               if (up->bugs & UART_BUG_PARITY)
+                       fifo_bug = 1;
+       }
        if (!(termios->c_cflag & PARODD))
                cval |= UART_LCR_EPAR;
 #ifdef CMSPAR
@@ -2246,7 +2250,7 @@ serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
 
        if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) {
                fcr = uart_config[port->type].fcr;
-               if (baud < 2400) {
+               if (baud < 2400 || fifo_bug) {
                        fcr &= ~UART_FCR_TRIGGER_MASK;
                        fcr |= UART_FCR_TRIGGER_1;
                }
@@ -2979,36 +2983,36 @@ void serial8250_resume_port(int line)
 static int __devinit serial8250_probe(struct platform_device *dev)
 {
        struct plat_serial8250_port *p = dev->dev.platform_data;
-       struct uart_port port;
+       struct uart_8250_port uart;
        int ret, i, irqflag = 0;
 
-       memset(&port, 0, sizeof(struct uart_port));
+       memset(&uart, 0, sizeof(uart));
 
        if (share_irqs)
                irqflag = IRQF_SHARED;
 
        for (i = 0; p && p->flags != 0; p++, i++) {
-               port.iobase             = p->iobase;
-               port.membase            = p->membase;
-               port.irq                = p->irq;
-               port.irqflags           = p->irqflags;
-               port.uartclk            = p->uartclk;
-               port.regshift           = p->regshift;
-               port.iotype             = p->iotype;
-               port.flags              = p->flags;
-               port.mapbase            = p->mapbase;
-               port.hub6               = p->hub6;
-               port.private_data       = p->private_data;
-               port.type               = p->type;
-               port.serial_in          = p->serial_in;
-               port.serial_out         = p->serial_out;
-               port.handle_irq         = p->handle_irq;
-               port.handle_break       = p->handle_break;
-               port.set_termios        = p->set_termios;
-               port.pm                 = p->pm;
-               port.dev                = &dev->dev;
-               port.irqflags           |= irqflag;
-               ret = serial8250_register_port(&port);
+               uart.port.iobase        = p->iobase;
+               uart.port.membase       = p->membase;
+               uart.port.irq           = p->irq;
+               uart.port.irqflags      = p->irqflags;
+               uart.port.uartclk       = p->uartclk;
+               uart.port.regshift      = p->regshift;
+               uart.port.iotype        = p->iotype;
+               uart.port.flags         = p->flags;
+               uart.port.mapbase       = p->mapbase;
+               uart.port.hub6          = p->hub6;
+               uart.port.private_data  = p->private_data;
+               uart.port.type          = p->type;
+               uart.port.serial_in     = p->serial_in;
+               uart.port.serial_out    = p->serial_out;
+               uart.port.handle_irq    = p->handle_irq;
+               uart.port.handle_break  = p->handle_break;
+               uart.port.set_termios   = p->set_termios;
+               uart.port.pm            = p->pm;
+               uart.port.dev           = &dev->dev;
+               uart.port.irqflags      |= irqflag;
+               ret = serial8250_register_8250_port(&uart);
                if (ret < 0) {
                        dev_err(&dev->dev, "unable to register port at index %d "
                                "(IO%lx MEM%llx IRQ%d): %d\n", i,
@@ -3081,7 +3085,7 @@ static struct platform_driver serial8250_isa_driver = {
 static struct platform_device *serial8250_isa_devs;
 
 /*
- * serial8250_register_port and serial8250_unregister_port allows for
+ * serial8250_register_8250_port and serial8250_unregister_port allows for
  * 16x50 serial ports to be configured at run-time, to support PCMCIA
  * modems and PCI multiport cards.
  */
@@ -3155,6 +3159,7 @@ int serial8250_register_8250_port(struct uart_8250_port *up)
                uart->port.regshift     = up->port.regshift;
                uart->port.iotype       = up->port.iotype;
                uart->port.flags        = up->port.flags | UPF_BOOT_AUTOCONF;
+               uart->bugs              = up->bugs;
                uart->port.mapbase      = up->port.mapbase;
                uart->port.private_data = up->port.private_data;
                if (up->port.dev)
@@ -3197,29 +3202,6 @@ int serial8250_register_8250_port(struct uart_8250_port *up)
 }
 EXPORT_SYMBOL(serial8250_register_8250_port);
 
-/**
- *     serial8250_register_port - register a serial port
- *     @port: serial port template
- *
- *     Configure the serial port specified by the request. If the
- *     port exists and is in use, it is hung up and unregistered
- *     first.
- *
- *     The port is then probed and if necessary the IRQ is autodetected
- *     If this fails an error is returned.
- *
- *     On success the port is ready to use and the line number is returned.
- */
-int serial8250_register_port(struct uart_port *port)
-{
-       struct uart_8250_port up;
-
-       memset(&up, 0, sizeof(up));
-       memcpy(&up.port, port, sizeof(*port));
-       return serial8250_register_8250_port(&up);
-}
-EXPORT_SYMBOL(serial8250_register_port);
-
 /**
  *     serial8250_unregister_port - remove a 16x50 serial port at runtime
  *     @line: serial line number
index f9719d167c8d74f3159d995b09899bc52eab8294..972b5212b58cbc3f28fef7a112fbbda17301606c 100644 (file)
 
 #include <linux/serial_8250.h>
 
-struct uart_8250_port {
-       struct uart_port        port;
-       struct timer_list       timer;          /* "no irq" timer */
-       struct list_head        list;           /* ports on this IRQ */
-       unsigned short          capabilities;   /* port capabilities */
-       unsigned short          bugs;           /* port bugs */
-       unsigned int            tx_loadsz;      /* transmit fifo load size */
-       unsigned char           acr;
-       unsigned char           ier;
-       unsigned char           lcr;
-       unsigned char           mcr;
-       unsigned char           mcr_mask;       /* mask of user bits */
-       unsigned char           mcr_force;      /* mask of forced bits */
-       unsigned char           cur_iotype;     /* Running I/O type */
-
-       /*
-        * Some bits in registers are cleared on a read, so they must
-        * be saved whenever the register is read but the bits will not
-        * be immediately processed.
-        */
-#define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS
-       unsigned char           lsr_saved_flags;
-#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
-       unsigned char           msr_saved_flags;
-
-       /* 8250 specific callbacks */
-       int                     (*dl_read)(struct uart_8250_port *);
-       void                    (*dl_write)(struct uart_8250_port *, int);
-};
-
 struct old_serial_port {
        unsigned int uart;
        unsigned int baud_base;
@@ -78,6 +48,7 @@ struct serial8250_config {
 #define UART_BUG_TXEN  (1 << 1)        /* UART has buggy TX IIR status */
 #define UART_BUG_NOMSR (1 << 2)        /* UART has buggy MSR status bits (Au1x00) */
 #define UART_BUG_THRE  (1 << 3)        /* UART has buggy THRE reassertion */
+#define UART_BUG_PARITY        (1 << 4)        /* UART mishandles parity if FIFO enabled */
 
 #define PROBE_RSA      (1 << 0)
 #define PROBE_ANY      (~0)
index b0ce8c56f1a4dcdb8ac077888ed3973756b8f2e6..857498312a9a84146b6c4c3493c224491fc1213d 100644 (file)
@@ -43,7 +43,7 @@ serial_card_probe(struct expansion_card *ec, const struct ecard_id *id)
 {
        struct serial_card_info *info;
        struct serial_card_type *type = id->data;
-       struct uart_port port;
+       struct uart_8250_port uart;
        unsigned long bus_addr;
        unsigned int i;
 
@@ -62,19 +62,19 @@ serial_card_probe(struct expansion_card *ec, const struct ecard_id *id)
 
        ecard_set_drvdata(ec, info);
 
-       memset(&port, 0, sizeof(struct uart_port));
-       port.irq        = ec->irq;
-       port.flags      = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
-       port.uartclk    = type->uartclk;
-       port.iotype     = UPIO_MEM;
-       port.regshift   = 2;
-       port.dev        = &ec->dev;
+       memset(&uart, 0, sizeof(struct uart_8250_port));
+       uart.port.irq   = ec->irq;
+       uart.port.flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
+       uart.port.uartclk       = type->uartclk;
+       uart.port.iotype        = UPIO_MEM;
+       uart.port.regshift      = 2;
+       uart.port.dev   = &ec->dev;
 
        for (i = 0; i < info->num_ports; i ++) {
-               port.membase = info->vaddr + type->offset[i];
-               port.mapbase = bus_addr + type->offset[i];
+               uart.port.membase = info->vaddr + type->offset[i];
+               uart.port.mapbase = bus_addr + type->offset[i];
 
-               info->ports[i] = serial8250_register_port(&port);
+               info->ports[i] = serial8250_register_8250_port(&uart);
        }
 
        return 0;
index f574eef3075f987b41784c635400f970947e9480..c3b2ec0c8c0b7f3a6749f41feedb38fe0af58ac2 100644 (file)
@@ -89,7 +89,7 @@ static int dw8250_handle_irq(struct uart_port *p)
 
 static int __devinit dw8250_probe(struct platform_device *pdev)
 {
-       struct uart_port port = {};
+       struct uart_8250_port uart = {};
        struct resource *regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        struct resource *irq = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
        struct device_node *np = pdev->dev.of_node;
@@ -104,28 +104,28 @@ static int __devinit dw8250_probe(struct platform_device *pdev)
        data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
        if (!data)
                return -ENOMEM;
-       port.private_data = data;
-
-       spin_lock_init(&port.lock);
-       port.mapbase = regs->start;
-       port.irq = irq->start;
-       port.handle_irq = dw8250_handle_irq;
-       port.type = PORT_8250;
-       port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP |
+       uart.port.private_data = data;
+
+       spin_lock_init(&uart.port.lock);
+       uart.port.mapbase = regs->start;
+       uart.port.irq = irq->start;
+       uart.port.handle_irq = dw8250_handle_irq;
+       uart.port.type = PORT_8250;
+       uart.port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP |
                UPF_FIXED_PORT | UPF_FIXED_TYPE;
-       port.dev = &pdev->dev;
+       uart.port.dev = &pdev->dev;
 
-       port.iotype = UPIO_MEM;
-       port.serial_in = dw8250_serial_in;
-       port.serial_out = dw8250_serial_out;
+       uart.port.iotype = UPIO_MEM;
+       uart.port.serial_in = dw8250_serial_in;
+       uart.port.serial_out = dw8250_serial_out;
        if (!of_property_read_u32(np, "reg-io-width", &val)) {
                switch (val) {
                case 1:
                        break;
                case 4:
-                       port.iotype = UPIO_MEM32;
-                       port.serial_in = dw8250_serial_in32;
-                       port.serial_out = dw8250_serial_out32;
+                       uart.port.iotype = UPIO_MEM32;
+                       uart.port.serial_in = dw8250_serial_in32;
+                       uart.port.serial_out = dw8250_serial_out32;
                        break;
                default:
                        dev_err(&pdev->dev, "unsupported reg-io-width (%u)\n",
@@ -135,15 +135,15 @@ static int __devinit dw8250_probe(struct platform_device *pdev)
        }
 
        if (!of_property_read_u32(np, "reg-shift", &val))
-               port.regshift = val;
+               uart.port.regshift = val;
 
        if (of_property_read_u32(np, "clock-frequency", &val)) {
                dev_err(&pdev->dev, "no clock-frequency property set\n");
                return -EINVAL;
        }
-       port.uartclk = val;
+       uart.port.uartclk = val;
 
-       data->line = serial8250_register_port(&port);
+       data->line = serial8250_register_8250_port(&uart);
        if (data->line < 0)
                return data->line;
 
index d8c0ffbfa6e39b53bafaef22f2d090e2739613e9..097dff9c08ad9e4ebec835f20800e6d118931bd0 100644 (file)
@@ -26,7 +26,7 @@
 
 static int __init serial_init_chip(struct parisc_device *dev)
 {
-       struct uart_port port;
+       struct uart_8250_port uart;
        unsigned long address;
        int err;
 
@@ -48,21 +48,21 @@ static int __init serial_init_chip(struct parisc_device *dev)
        if (dev->id.sversion != 0x8d)
                address += 0x800;
 
-       memset(&port, 0, sizeof(port));
-       port.iotype     = UPIO_MEM;
+       memset(&uart, 0, sizeof(uart));
+       uart.port.iotype        = UPIO_MEM;
        /* 7.272727MHz on Lasi.  Assumed the same for Dino, Wax and Timi. */
-       port.uartclk    = 7272727;
-       port.mapbase    = address;
-       port.membase    = ioremap_nocache(address, 16);
-       port.irq        = dev->irq;
-       port.flags      = UPF_BOOT_AUTOCONF;
-       port.dev        = &dev->dev;
-
-       err = serial8250_register_port(&port);
+       uart.port.uartclk       = 7272727;
+       uart.port.mapbase       = address;
+       uart.port.membase       = ioremap_nocache(address, 16);
+       uart.port.irq   = dev->irq;
+       uart.port.flags = UPF_BOOT_AUTOCONF;
+       uart.port.dev   = &dev->dev;
+
+       err = serial8250_register_8250_port(&uart);
        if (err < 0) {
                printk(KERN_WARNING
-                       "serial8250_register_port returned error %d\n", err);
-               iounmap(port.membase);
+                       "serial8250_register_8250_port returned error %d\n", err);
+               iounmap(uart.port.membase);
                return err;
        }
 
index c13438c930129a0b4e736fd67630a1ef9338345b..8f1dd2cc00a8de79ac9538248271d2be376336aa 100644 (file)
@@ -171,7 +171,7 @@ static int __devinit hpdca_init_one(struct dio_dev *d,
                return 0;
        }
 #endif
-       memset(&port, 0, sizeof(struct uart_port));
+       memset(&uart, 0, sizeof(uart));
 
        /* Memory mapped I/O */
        port.iotype = UPIO_MEM;
@@ -182,7 +182,7 @@ static int __devinit hpdca_init_one(struct dio_dev *d,
        port.membase = (char *)(port.mapbase + DIO_VIRADDRBASE);
        port.regshift = 1;
        port.dev = &d->dev;
-       line = serial8250_register_port(&port);
+       line = serial8250_register_8250_port(&uart);
 
        if (line < 0) {
                printk(KERN_NOTICE "8250_hp300: register_serial() DCA scode %d"
@@ -210,7 +210,7 @@ static int __init hp300_8250_init(void)
 #ifdef CONFIG_HPAPCI
        int line;
        unsigned long base;
-       struct uart_port uport;
+       struct uart_8250_port uart;
        struct hp300_port *port;
        int i;
 #endif
@@ -248,26 +248,26 @@ static int __init hp300_8250_init(void)
                if (!port)
                        return -ENOMEM;
 
-               memset(&uport, 0, sizeof(struct uart_port));
+               memset(&uart, 0, sizeof(uart));
 
                base = (FRODO_BASE + FRODO_APCI_OFFSET(i));
 
                /* Memory mapped I/O */
-               uport.iotype = UPIO_MEM;
-               uport.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ \
+               uart.port.iotype = UPIO_MEM;
+               uart.port.flags = UPF_SKIP_TEST | UPF_SHARE_IRQ \
                              | UPF_BOOT_AUTOCONF;
                /* XXX - no interrupt support yet */
-               uport.irq = 0;
-               uport.uartclk = HPAPCI_BAUD_BASE * 16;
-               uport.mapbase = base;
-               uport.membase = (char *)(base + DIO_VIRADDRBASE);
-               uport.regshift = 2;
+               uart.port.irq = 0;
+               uart.port.uartclk = HPAPCI_BAUD_BASE * 16;
+               uart.port.mapbase = base;
+               uart.port.membase = (char *)(base + DIO_VIRADDRBASE);
+               uart.port.regshift = 2;
 
-               line = serial8250_register_port(&uport);
+               line = serial8250_register_8250_port(&uart);
 
                if (line < 0) {
                        printk(KERN_NOTICE "8250_hp300: register_serial() APCI"
-                              " %d irq %d failed\n", i, uport.irq);
+                              " %d irq %d failed\n", i, uart.port.irq);
                        kfree(port);
                        continue;
                }
index 28e7c7cce8935acc8257fafaff86121fa55bf6dd..62e10fe747a8756e3826400c375dba876f3c43ea 100644 (file)
@@ -44,7 +44,7 @@ struct pci_serial_quirk {
        int     (*init)(struct pci_dev *dev);
        int     (*setup)(struct serial_private *,
                         const struct pciserial_board *,
-                        struct uart_port *, int);
+                        struct uart_8250_port *, int);
        void    (*exit)(struct pci_dev *dev);
 };
 
@@ -59,7 +59,7 @@ struct serial_private {
 };
 
 static int pci_default_setup(struct serial_private*,
-         const struct pciserial_board*, struct uart_port*, int);
+         const struct pciserial_board*, struct uart_8250_port *, int);
 
 static void moan_device(const char *str, struct pci_dev *dev)
 {
@@ -74,7 +74,7 @@ static void moan_device(const char *str, struct pci_dev *dev)
 }
 
 static int
-setup_port(struct serial_private *priv, struct uart_port *port,
+setup_port(struct serial_private *priv, struct uart_8250_port *port,
           int bar, int offset, int regshift)
 {
        struct pci_dev *dev = priv->dev;
@@ -93,17 +93,17 @@ setup_port(struct serial_private *priv, struct uart_port *port,
                if (!priv->remapped_bar[bar])
                        return -ENOMEM;
 
-               port->iotype = UPIO_MEM;
-               port->iobase = 0;
-               port->mapbase = base + offset;
-               port->membase = priv->remapped_bar[bar] + offset;
-               port->regshift = regshift;
+               port->port.iotype = UPIO_MEM;
+               port->port.iobase = 0;
+               port->port.mapbase = base + offset;
+               port->port.membase = priv->remapped_bar[bar] + offset;
+               port->port.regshift = regshift;
        } else {
-               port->iotype = UPIO_PORT;
-               port->iobase = base + offset;
-               port->mapbase = 0;
-               port->membase = NULL;
-               port->regshift = 0;
+               port->port.iotype = UPIO_PORT;
+               port->port.iobase = base + offset;
+               port->port.mapbase = 0;
+               port->port.membase = NULL;
+               port->port.regshift = 0;
        }
        return 0;
 }
@@ -113,7 +113,7 @@ setup_port(struct serial_private *priv, struct uart_port *port,
  */
 static int addidata_apci7800_setup(struct serial_private *priv,
                                const struct pciserial_board *board,
-                               struct uart_port *port, int idx)
+                               struct uart_8250_port *port, int idx)
 {
        unsigned int bar = 0, offset = board->first_offset;
        bar = FL_GET_BASE(board->flags);
@@ -140,7 +140,7 @@ static int addidata_apci7800_setup(struct serial_private *priv,
  */
 static int
 afavlab_setup(struct serial_private *priv, const struct pciserial_board *board,
-             struct uart_port *port, int idx)
+             struct uart_8250_port *port, int idx)
 {
        unsigned int bar, offset = board->first_offset;
 
@@ -195,7 +195,7 @@ static int pci_hp_diva_init(struct pci_dev *dev)
 static int
 pci_hp_diva_setup(struct serial_private *priv,
                const struct pciserial_board *board,
-               struct uart_port *port, int idx)
+               struct uart_8250_port *port, int idx)
 {
        unsigned int offset = board->first_offset;
        unsigned int bar = FL_GET_BASE(board->flags);
@@ -370,7 +370,7 @@ static void __devexit pci_ni8430_exit(struct pci_dev *dev)
 /* SBS Technologies Inc. PMC-OCTPRO and P-OCTAL cards */
 static int
 sbs_setup(struct serial_private *priv, const struct pciserial_board *board,
-               struct uart_port *port, int idx)
+               struct uart_8250_port *port, int idx)
 {
        unsigned int bar, offset = board->first_offset;
 
@@ -525,7 +525,7 @@ static int pci_siig_init(struct pci_dev *dev)
 
 static int pci_siig_setup(struct serial_private *priv,
                          const struct pciserial_board *board,
-                         struct uart_port *port, int idx)
+                         struct uart_8250_port *port, int idx)
 {
        unsigned int bar = FL_GET_BASE(board->flags) + idx, offset = 0;
 
@@ -619,7 +619,7 @@ static int pci_timedia_init(struct pci_dev *dev)
 static int
 pci_timedia_setup(struct serial_private *priv,
                  const struct pciserial_board *board,
-                 struct uart_port *port, int idx)
+                 struct uart_8250_port *port, int idx)
 {
        unsigned int bar = 0, offset = board->first_offset;
 
@@ -653,7 +653,7 @@ pci_timedia_setup(struct serial_private *priv,
 static int
 titan_400l_800l_setup(struct serial_private *priv,
                      const struct pciserial_board *board,
-                     struct uart_port *port, int idx)
+                     struct uart_8250_port *port, int idx)
 {
        unsigned int bar, offset = board->first_offset;
 
@@ -754,7 +754,7 @@ static int pci_ni8430_init(struct pci_dev *dev)
 static int
 pci_ni8430_setup(struct serial_private *priv,
                 const struct pciserial_board *board,
-                struct uart_port *port, int idx)
+                struct uart_8250_port *port, int idx)
 {
        void __iomem *p;
        unsigned long base, len;
@@ -781,7 +781,7 @@ pci_ni8430_setup(struct serial_private *priv,
 
 static int pci_netmos_9900_setup(struct serial_private *priv,
                                const struct pciserial_board *board,
-                               struct uart_port *port, int idx)
+                               struct uart_8250_port *port, int idx)
 {
        unsigned int bar;
 
@@ -1032,10 +1032,17 @@ static int pci_oxsemi_tornado_init(struct pci_dev *dev)
        return number_uarts;
 }
 
-static int
-pci_default_setup(struct serial_private *priv,
+static int pci_asix_setup(struct serial_private *priv,
+                 const struct pciserial_board *board,
+                 struct uart_8250_port *port, int idx)
+{
+       port->bugs |= UART_BUG_PARITY;
+       return pci_default_setup(priv, board, port, idx);
+}
+
+static int pci_default_setup(struct serial_private *priv,
                  const struct pciserial_board *board,
-                 struct uart_port *port, int idx)
+                 struct uart_8250_port *port, int idx)
 {
        unsigned int bar, offset = board->first_offset, maxnr;
 
@@ -1057,15 +1064,15 @@ pci_default_setup(struct serial_private *priv,
 static int
 ce4100_serial_setup(struct serial_private *priv,
                  const struct pciserial_board *board,
-                 struct uart_port *port, int idx)
+                 struct uart_8250_port *port, int idx)
 {
        int ret;
 
        ret = setup_port(priv, port, 0, 0, board->reg_shift);
-       port->iotype = UPIO_MEM32;
-       port->type = PORT_XSCALE;
-       port->flags = (port->flags | UPF_FIXED_PORT | UPF_FIXED_TYPE);
-       port->regshift = 2;
+       port->port.iotype = UPIO_MEM32;
+       port->port.type = PORT_XSCALE;
+       port->port.flags = (port->port.flags | UPF_FIXED_PORT | UPF_FIXED_TYPE);
+       port->port.regshift = 2;
 
        return ret;
 }
@@ -1073,16 +1080,16 @@ ce4100_serial_setup(struct serial_private *priv,
 static int
 pci_omegapci_setup(struct serial_private *priv,
                      const struct pciserial_board *board,
-                     struct uart_port *port, int idx)
+                     struct uart_8250_port *port, int idx)
 {
        return setup_port(priv, port, 2, idx * 8, 0);
 }
 
 static int skip_tx_en_setup(struct serial_private *priv,
                        const struct pciserial_board *board,
-                       struct uart_port *port, int idx)
+                       struct uart_8250_port *port, int idx)
 {
-       port->flags |= UPF_NO_TXEN_TEST;
+       port->port.flags |= UPF_NO_TXEN_TEST;
        printk(KERN_DEBUG "serial8250: skipping TxEn test for device "
                          "[%04x:%04x] subsystem [%04x:%04x]\n",
                          priv->dev->vendor,
@@ -1131,11 +1138,11 @@ static unsigned int kt_serial_in(struct uart_port *p, int offset)
 
 static int kt_serial_setup(struct serial_private *priv,
                           const struct pciserial_board *board,
-                          struct uart_port *port, int idx)
+                          struct uart_8250_port *port, int idx)
 {
-       port->flags |= UPF_BUG_THRE;
-       port->serial_in = kt_serial_in;
-       port->handle_break = kt_handle_break;
+       port->port.flags |= UPF_BUG_THRE;
+       port->port.serial_in = kt_serial_in;
+       port->port.handle_break = kt_handle_break;
        return skip_tx_en_setup(priv, board, port, idx);
 }
 
@@ -1151,9 +1158,9 @@ static int pci_eg20t_init(struct pci_dev *dev)
 static int
 pci_xr17c154_setup(struct serial_private *priv,
                  const struct pciserial_board *board,
-                 struct uart_port *port, int idx)
+                 struct uart_8250_port *port, int idx)
 {
-       port->flags |= UPF_EXAR_EFR;
+       port->port.flags |= UPF_EXAR_EFR;
        return pci_default_setup(priv, board, port, idx);
 }
 
@@ -1187,6 +1194,7 @@ pci_xr17c154_setup(struct serial_private *priv,
 #define PCIE_DEVICE_ID_NEO_2_OX_IBM    0x00F6
 #define PCI_DEVICE_ID_PLX_CRONYX_OMEGA 0xc001
 #define PCI_DEVICE_ID_INTEL_PATSBURG_KT 0x1d3d
+#define PCI_VENDOR_ID_ASIX             0x9710
 
 /* Unknown vendors/cards - this should not be in linux/pci_ids.h */
 #define PCI_SUBDEVICE_ID_UNKNOWN_0x1584        0x1584
@@ -1726,7 +1734,17 @@ static struct pci_serial_quirk pci_serial_quirks[] __refdata = {
                .subvendor      = PCI_ANY_ID,
                .subdevice      = PCI_ANY_ID,
                .setup          = pci_omegapci_setup,
-        },
+       },
+       /*
+        * ASIX devices with FIFO bug
+        */
+       {
+               .vendor         = PCI_VENDOR_ID_ASIX,
+               .device         = PCI_ANY_ID,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = pci_asix_setup,
+       },
        /*
         * Default "match everything" terminator entry
         */
@@ -1887,7 +1905,6 @@ enum pci_board_num_t {
        pbn_panacom,
        pbn_panacom2,
        pbn_panacom4,
-       pbn_exsys_4055,
        pbn_plx_romulus,
        pbn_oxsemi,
        pbn_oxsemi_1_4000000,
@@ -2393,13 +2410,6 @@ static struct pciserial_board pci_boards[] __devinitdata = {
                .reg_shift      = 7,
        },
 
-       [pbn_exsys_4055] = {
-               .flags          = FL_BASE2,
-               .num_ports      = 4,
-               .base_baud      = 115200,
-               .uart_offset    = 8,
-       },
-
        /* I think this entry is broken - the first_offset looks wrong --rmk */
        [pbn_plx_romulus] = {
                .flags          = FL_BASE2,
@@ -2728,7 +2738,7 @@ serial_pci_matches(const struct pciserial_board *board,
 struct serial_private *
 pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board)
 {
-       struct uart_port serial_port;
+       struct uart_8250_port uart;
        struct serial_private *priv;
        struct pci_serial_quirk *quirk;
        int rc, nr_ports, i;
@@ -2768,22 +2778,22 @@ pciserial_init_ports(struct pci_dev *dev, const struct pciserial_board *board)
        priv->dev = dev;
        priv->quirk = quirk;
 
-       memset(&serial_port, 0, sizeof(struct uart_port));
-       serial_port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
-       serial_port.uartclk = board->base_baud * 16;
-       serial_port.irq = get_pci_irq(dev, board);
-       serial_port.dev = &dev->dev;
+       memset(&uart, 0, sizeof(uart));
+       uart.port.flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ;
+       uart.port.uartclk = board->base_baud * 16;
+       uart.port.irq = get_pci_irq(dev, board);
+       uart.port.dev = &dev->dev;
 
        for (i = 0; i < nr_ports; i++) {
-               if (quirk->setup(priv, board, &serial_port, i))
+               if (quirk->setup(priv, board, &uart, i))
                        break;
 
 #ifdef SERIAL_DEBUG_PCI
                printk(KERN_DEBUG "Setup PCI port: port %lx, irq %d, type %d\n",
-                      serial_port.iobase, serial_port.irq, serial_port.iotype);
+                      uart.port.iobase, uart.port.irq, uart.port.iotype);
 #endif
 
-               priv->line[i] = serial8250_register_port(&serial_port);
+               priv->line[i] = serial8250_register_8250_port(&uart);
                if (priv->line[i] < 0) {
                        printk(KERN_WARNING "Couldn't register serial port %s: %d\n", pci_name(dev), priv->line[i]);
                        break;
@@ -3193,7 +3203,7 @@ static struct pci_device_id serial_pci_tbl[] = {
        {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9050,
                PCI_SUBVENDOR_ID_EXSYS,
                PCI_SUBDEVICE_ID_EXSYS_4055, 0, 0,
-               pbn_exsys_4055 },
+               pbn_b2_4_115200 },
        /*
         * Megawolf Romulus PCI Serial Card, from Mike Hudson
         * (Exoray@isys.ca)
index a2f236510ff1cd3f7fc92524f6096dc8678946f0..fde5aa60d51e92391dfdb996a7065d25d4f12c00 100644 (file)
@@ -424,7 +424,7 @@ static int __devinit serial_pnp_guess_board(struct pnp_dev *dev, int *flags)
 static int __devinit
 serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
 {
-       struct uart_port port;
+       struct uart_8250_port uart;
        int ret, line, flags = dev_id->driver_data;
 
        if (flags & UNKNOWN_DEV) {
@@ -433,32 +433,32 @@ serial_pnp_probe(struct pnp_dev *dev, const struct pnp_device_id *dev_id)
                        return ret;
        }
 
-       memset(&port, 0, sizeof(struct uart_port));
+       memset(&uart, 0, sizeof(uart));
        if (pnp_irq_valid(dev, 0))
-               port.irq = pnp_irq(dev, 0);
+               uart.port.irq = pnp_irq(dev, 0);
        if (pnp_port_valid(dev, 0)) {
-               port.iobase = pnp_port_start(dev, 0);
-               port.iotype = UPIO_PORT;
+               uart.port.iobase = pnp_port_start(dev, 0);
+               uart.port.iotype = UPIO_PORT;
        } else if (pnp_mem_valid(dev, 0)) {
-               port.mapbase = pnp_mem_start(dev, 0);
-               port.iotype = UPIO_MEM;
-               port.flags = UPF_IOREMAP;
+               uart.port.mapbase = pnp_mem_start(dev, 0);
+               uart.port.iotype = UPIO_MEM;
+               uart.port.flags = UPF_IOREMAP;
        } else
                return -ENODEV;
 
 #ifdef SERIAL_DEBUG_PNP
        printk(KERN_DEBUG
                "Setup PNP port: port %x, mem 0x%lx, irq %d, type %d\n",
-                      port.iobase, port.mapbase, port.irq, port.iotype);
+                      uart.port.iobase, uart.port.mapbase, uart.port.irq, uart.port.iotype);
 #endif
 
-       port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
+       uart.port.flags |= UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
        if (pnp_irq_flags(dev, 0) & IORESOURCE_IRQ_SHAREABLE)
-               port.flags |= UPF_SHARE_IRQ;
-       port.uartclk = 1843200;
-       port.dev = &dev->dev;
+               uart.port.flags |= UPF_SHARE_IRQ;
+       uart.port.uartclk = 1843200;
+       uart.port.dev = &dev->dev;
 
-       line = serial8250_register_port(&port);
+       line = serial8250_register_8250_port(&uart);
        if (line < 0)
                return -ENODEV;
 
index 29b695d041ecd45cdfe18914b8c02d10ff7f79a5..b7d48b346393f08e2a44c88fa0e2c99e3a9c652b 100644 (file)
@@ -73,7 +73,7 @@ struct serial_quirk {
        unsigned int prodid;
        int multi;              /* 1 = multifunction, > 1 = # ports */
        void (*config)(struct pcmcia_device *);
-       void (*setup)(struct pcmcia_device *, struct uart_port *);
+       void (*setup)(struct pcmcia_device *, struct uart_8250_port *);
        void (*wakeup)(struct pcmcia_device *);
        int (*post)(struct pcmcia_device *);
 };
@@ -105,9 +105,9 @@ struct serial_cfg_mem {
  * Elan VPU16551 UART with 14.7456MHz oscillator
  * manfid 0x015D, 0x4C45
  */
-static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_port *port)
+static void quirk_setup_brainboxes_0104(struct pcmcia_device *link, struct uart_8250_port *uart)
 {
-       port->uartclk = 14745600;
+       uart->port.uartclk = 14745600;
 }
 
 static int quirk_post_ibm(struct pcmcia_device *link)
@@ -343,25 +343,25 @@ static void serial_detach(struct pcmcia_device *link)
 static int setup_serial(struct pcmcia_device *handle, struct serial_info * info,
                        unsigned int iobase, int irq)
 {
-       struct uart_port port;
+       struct uart_8250_port uart;
        int line;
 
-       memset(&port, 0, sizeof (struct uart_port));
-       port.iobase = iobase;
-       port.irq = irq;
-       port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
-       port.uartclk = 1843200;
-       port.dev = &handle->dev;
+       memset(&uart, 0, sizeof(uart));
+       uart.port.iobase = iobase;
+       uart.port.irq = irq;
+       uart.port.flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST | UPF_SHARE_IRQ;
+       uart.port.uartclk = 1843200;
+       uart.port.dev = &handle->dev;
        if (buggy_uart)
-               port.flags |= UPF_BUGGY_UART;
+               uart.port.flags |= UPF_BUGGY_UART;
 
        if (info->quirk && info->quirk->setup)
-               info->quirk->setup(handle, &port);
+               info->quirk->setup(handle, &uart);
 
-       line = serial8250_register_port(&port);
+       line = serial8250_register_8250_port(&uart);
        if (line < 0) {
-               printk(KERN_NOTICE "serial_cs: serial8250_register_port() at "
-                      "0x%04lx, irq %d failed\n", (u_long)iobase, irq);
+               pr_err("serial_cs: serial8250_register_8250_port() at 0x%04lx, irq %d failed\n",
+                                                       (unsigned long)iobase, irq);
                return -EINVAL;
        }
 
index 070b442c1f81abb08ffee6cd69e3ffe0ab87b209..00207865ec55c5e0557d1f351e05ee3f4850c2b6 100644 (file)
@@ -704,6 +704,25 @@ config SERIAL_PNX8XXX_CONSOLE
          If you have a MIPS-based Philips SoC such as PNX8550 or PNX8330
          and you want to use serial console, say Y. Otherwise, say N.
 
+config SERIAL_HS_LPC32XX
+       tristate "LPC32XX high speed serial port support"
+       depends on ARCH_LPC32XX && OF
+       select SERIAL_CORE
+       help
+         Support for the LPC32XX high speed serial ports (up to 900kbps).
+         Those are UARTs completely different from the Standard UARTs on the
+         LPC32XX SoC.
+         Choose M or Y here to build this driver.
+
+config SERIAL_HS_LPC32XX_CONSOLE
+       bool "Enable LPC32XX high speed UART serial console"
+       depends on SERIAL_HS_LPC32XX
+       select SERIAL_CORE_CONSOLE
+       help
+         If you would like to be able to use one of the high speed serial
+         ports on the LPC32XX as the console, you can do so by answering
+         Y to this option.
+
 config SERIAL_CORE
        tristate
 
index 7257c5d898ae2d36da427c3f6a9e225f1a0741ae..8a5df3804e5f1b8e4fbcb949efbc78205bf9e1d8 100644 (file)
@@ -34,6 +34,7 @@ obj-$(CONFIG_SERIAL_MUX) += mux.o
 obj-$(CONFIG_SERIAL_68328) += 68328serial.o
 obj-$(CONFIG_SERIAL_MCF) += mcf.o
 obj-$(CONFIG_SERIAL_PMACZILOG) += pmac_zilog.o
+obj-$(CONFIG_SERIAL_HS_LPC32XX) += lpc32xx_hs.o
 obj-$(CONFIG_SERIAL_DZ) += dz.o
 obj-$(CONFIG_SERIAL_ZS) += zs.o
 obj-$(CONFIG_SERIAL_SH_SCI) += sh-sci.o
index d3553b5d3fcabd851d6cce4b6eab6eb6bca80cbc..92b1ac8db63d8e566573cfc87dc96248dae5bc52 100644 (file)
@@ -1215,14 +1215,14 @@ static irqreturn_t pl011_int(int irq, void *dev_id)
        return IRQ_RETVAL(handled);
 }
 
-static unsigned int pl01x_tx_empty(struct uart_port *port)
+static unsigned int pl011_tx_empty(struct uart_port *port)
 {
        struct uart_amba_port *uap = (struct uart_amba_port *)port;
        unsigned int status = readw(uap->port.membase + UART01x_FR);
        return status & (UART01x_FR_BUSY|UART01x_FR_TXFF) ? 0 : TIOCSER_TEMT;
 }
 
-static unsigned int pl01x_get_mctrl(struct uart_port *port)
+static unsigned int pl011_get_mctrl(struct uart_port *port)
 {
        struct uart_amba_port *uap = (struct uart_amba_port *)port;
        unsigned int result = 0;
@@ -1285,7 +1285,7 @@ static void pl011_break_ctl(struct uart_port *port, int break_state)
 }
 
 #ifdef CONFIG_CONSOLE_POLL
-static int pl010_get_poll_char(struct uart_port *port)
+static int pl011_get_poll_char(struct uart_port *port)
 {
        struct uart_amba_port *uap = (struct uart_amba_port *)port;
        unsigned int status;
@@ -1297,7 +1297,7 @@ static int pl010_get_poll_char(struct uart_port *port)
        return readw(uap->port.membase + UART01x_DR);
 }
 
-static void pl010_put_poll_char(struct uart_port *port,
+static void pl011_put_poll_char(struct uart_port *port,
                         unsigned char ch)
 {
        struct uart_amba_port *uap = (struct uart_amba_port *)port;
@@ -1637,7 +1637,7 @@ static const char *pl011_type(struct uart_port *port)
 /*
  * Release the memory region(s) being used by 'port'
  */
-static void pl010_release_port(struct uart_port *port)
+static void pl011_release_port(struct uart_port *port)
 {
        release_mem_region(port->mapbase, SZ_4K);
 }
@@ -1645,7 +1645,7 @@ static void pl010_release_port(struct uart_port *port)
 /*
  * Request the memory region(s) being used by 'port'
  */
-static int pl010_request_port(struct uart_port *port)
+static int pl011_request_port(struct uart_port *port)
 {
        return request_mem_region(port->mapbase, SZ_4K, "uart-pl011")
                        != NULL ? 0 : -EBUSY;
@@ -1654,18 +1654,18 @@ static int pl010_request_port(struct uart_port *port)
 /*
  * Configure/autoconfigure the port.
  */
-static void pl010_config_port(struct uart_port *port, int flags)
+static void pl011_config_port(struct uart_port *port, int flags)
 {
        if (flags & UART_CONFIG_TYPE) {
                port->type = PORT_AMBA;
-               pl010_request_port(port);
+               pl011_request_port(port);
        }
 }
 
 /*
  * verify the new serial_struct (for TIOCSSERIAL).
  */
-static int pl010_verify_port(struct uart_port *port, struct serial_struct *ser)
+static int pl011_verify_port(struct uart_port *port, struct serial_struct *ser)
 {
        int ret = 0;
        if (ser->type != PORT_UNKNOWN && ser->type != PORT_AMBA)
@@ -1678,9 +1678,9 @@ static int pl010_verify_port(struct uart_port *port, struct serial_struct *ser)
 }
 
 static struct uart_ops amba_pl011_pops = {
-       .tx_empty       = pl01x_tx_empty,
+       .tx_empty       = pl011_tx_empty,
        .set_mctrl      = pl011_set_mctrl,
-       .get_mctrl      = pl01x_get_mctrl,
+       .get_mctrl      = pl011_get_mctrl,
        .stop_tx        = pl011_stop_tx,
        .start_tx       = pl011_start_tx,
        .stop_rx        = pl011_stop_rx,
@@ -1691,13 +1691,13 @@ static struct uart_ops amba_pl011_pops = {
        .flush_buffer   = pl011_dma_flush_buffer,
        .set_termios    = pl011_set_termios,
        .type           = pl011_type,
-       .release_port   = pl010_release_port,
-       .request_port   = pl010_request_port,
-       .config_port    = pl010_config_port,
-       .verify_port    = pl010_verify_port,
+       .release_port   = pl011_release_port,
+       .request_port   = pl011_request_port,
+       .config_port    = pl011_config_port,
+       .verify_port    = pl011_verify_port,
 #ifdef CONFIG_CONSOLE_POLL
-       .poll_get_char = pl010_get_poll_char,
-       .poll_put_char = pl010_put_poll_char,
+       .poll_get_char = pl011_get_poll_char,
+       .poll_put_char = pl011_put_poll_char,
 #endif
 };
 
index bd97db23985bbc4ae6db1b666ff1900f09afb97d..9242d56ba2670d4aebc21749d9003c4d42986a35 100644 (file)
@@ -182,7 +182,7 @@ static void bfin_serial_start_tx(struct uart_port *port)
         * To avoid losting RX interrupt, we reset IR function
         * before sending data.
         */
-       if (tty->termios->c_line == N_IRDA)
+       if (tty->termios.c_line == N_IRDA)
                bfin_serial_reset_irda(port);
 
 #ifdef CONFIG_SERIAL_BFIN_DMA
index 80b6b1b1f7257d3b1da80f1b58523e7465bdb36b..6b705b2435227a0d03ab96307ff21aaab0a56db1 100644 (file)
@@ -955,7 +955,7 @@ static const struct control_pins e100_modem_pins[NR_PORTS] =
 /* Calculate the chartime depending on baudrate, numbor of bits etc. */
 static void update_char_time(struct e100_serial * info)
 {
-       tcflag_t cflags = info->port.tty->termios->c_cflag;
+       tcflag_t cflags = info->port.tty->termios.c_cflag;
        int bits;
 
        /* calc. number of bits / data byte */
@@ -1473,7 +1473,7 @@ rs_stop(struct tty_struct *tty)
                xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char,
                                STOP_CHAR(info->port.tty));
                xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, stop);
-               if (tty->termios->c_iflag & IXON ) {
+               if (tty->termios.c_iflag & IXON ) {
                        xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable);
                }
 
@@ -1496,7 +1496,7 @@ rs_start(struct tty_struct *tty)
                                         info->xmit.tail,SERIAL_XMIT_SIZE)));
                xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(tty));
                xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, enable);
-               if (tty->termios->c_iflag & IXON ) {
+               if (tty->termios.c_iflag & IXON ) {
                        xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable);
                }
 
@@ -2929,7 +2929,7 @@ shutdown(struct e100_serial * info)
                        descr[i].buf = 0;
                }
 
-       if (!info->port.tty || (info->port.tty->termios->c_cflag & HUPCL)) {
+       if (!info->port.tty || (info->port.tty->termios.c_cflag & HUPCL)) {
                /* hang up DTR and RTS if HUPCL is enabled */
                e100_dtr(info, 0);
                e100_rts(info, 0); /* could check CRTSCTS before doing this */
@@ -2953,12 +2953,12 @@ change_speed(struct e100_serial *info)
        unsigned long flags;
        /* first some safety checks */
 
-       if (!info->port.tty || !info->port.tty->termios)
+       if (!info->port.tty)
                return;
        if (!info->ioport)
                return;
 
-       cflag = info->port.tty->termios->c_cflag;
+       cflag = info->port.tty->termios.c_cflag;
 
        /* possibly, the tx/rx should be disabled first to do this safely */
 
@@ -3088,7 +3088,7 @@ change_speed(struct e100_serial *info)
        info->ioport[REG_REC_CTRL] = info->rx_ctrl;
        xoff = IO_FIELD(R_SERIAL0_XOFF, xoff_char, STOP_CHAR(info->port.tty));
        xoff |= IO_STATE(R_SERIAL0_XOFF, tx_stop, enable);
-       if (info->port.tty->termios->c_iflag & IXON ) {
+       if (info->port.tty->termios.c_iflag & IXON ) {
                DFLOW(DEBUG_LOG(info->line, "FLOW XOFF enabled 0x%02X\n",
                                STOP_CHAR(info->port.tty)));
                xoff |= IO_STATE(R_SERIAL0_XOFF, auto_xoff, enable);
@@ -3355,7 +3355,7 @@ rs_throttle(struct tty_struct * tty)
        DFLOW(DEBUG_LOG(info->line,"rs_throttle %lu\n", tty->ldisc.chars_in_buffer(tty)));
 
        /* Do RTS before XOFF since XOFF might take some time */
-       if (tty->termios->c_cflag & CRTSCTS) {
+       if (tty->termios.c_cflag & CRTSCTS) {
                /* Turn off RTS line */
                e100_rts(info, 0);
        }
@@ -3377,7 +3377,7 @@ rs_unthrottle(struct tty_struct * tty)
        DFLOW(DEBUG_LOG(info->line,"rs_unthrottle ldisc %d\n", tty->ldisc.chars_in_buffer(tty)));
        DFLOW(DEBUG_LOG(info->line,"rs_unthrottle flip.count: %i\n", tty->flip.count));
        /* Do RTS before XOFF since XOFF might take some time */
-       if (tty->termios->c_cflag & CRTSCTS) {
+       if (tty->termios.c_cflag & CRTSCTS) {
                /* Assert RTS line  */
                e100_rts(info, 1);
        }
@@ -3748,7 +3748,7 @@ rs_set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 
        /* Handle turning off CRTSCTS */
        if ((old_termios->c_cflag & CRTSCTS) &&
-           !(tty->termios->c_cflag & CRTSCTS)) {
+           !(tty->termios.c_cflag & CRTSCTS)) {
                tty->hw_stopped = 0;
                rs_start(tty);
        }
@@ -3815,7 +3815,7 @@ rs_close(struct tty_struct *tty, struct file * filp)
         * separate termios for callout and dialin.
         */
        if (info->flags & ASYNC_NORMAL_ACTIVE)
-               info->normal_termios = *tty->termios;
+               info->normal_termios = tty->termios;
        /*
         * Now we wait for the transmit buffer to clear; and we notify
         * the line discipline to only process XON/XOFF characters.
@@ -3998,7 +3998,7 @@ block_til_ready(struct tty_struct *tty, struct file * filp,
                return 0;
        }
 
-       if (tty->termios->c_cflag & CLOCAL) {
+       if (tty->termios.c_cflag & CLOCAL) {
                        do_clocal = 1;
        }
 
@@ -4219,7 +4219,7 @@ rs_open(struct tty_struct *tty, struct file * filp)
        }
 
        if ((info->count == 1) && (info->flags & ASYNC_SPLIT_TERMIOS)) {
-               *tty->termios = info->normal_termios;
+               tty->termios = info->normal_termios;
                change_speed(info);
        }
 
index d5c689d6217e3a2eb46223fa1ffd01b77e15e0df..20e911724027a1db5da67423235f1961f76c0077 100644 (file)
@@ -206,7 +206,7 @@ struct imx_port {
        unsigned short          trcv_delay; /* transceiver delay */
        struct clk              *clk_ipg;
        struct clk              *clk_per;
-       struct imx_uart_data    *devdata;
+       const struct imx_uart_data *devdata;
 };
 
 struct imx_port_ucrs {
index e16894fb2ca3532067bbfe90cffa321ca64d869b..cc5aca78ad9b6344001ec97155a829ddba7a855d 100644 (file)
@@ -1803,7 +1803,7 @@ static inline int ic4_startup_local(struct uart_port *the_port)
        ioc4_set_proto(port, the_port->mapbase);
 
        /* set the speed of the serial port */
-       ioc4_change_speed(the_port, state->port.tty->termios,
+       ioc4_change_speed(the_port, &state->port.tty->termios,
                          (struct ktermios *)0);
 
        return 0;
index 434bd881fcae84dd26386502c4817eaf87dd2c21..71397961773c232413600dd68a69ea7e43d72ec6 100644 (file)
@@ -161,7 +161,7 @@ static void jsm_tty_send_xchar(struct uart_port *port, char ch)
        struct ktermios *termios;
 
        spin_lock_irqsave(&port->lock, lock_flags);
-       termios = port->state->port.tty->termios;
+       termios = &port->state->port.tty->termios;
        if (ch == termios->c_cc[VSTART])
                channel->ch_bd->bd_ops->send_start_character(channel);
 
@@ -250,7 +250,7 @@ static int jsm_tty_open(struct uart_port *port)
        channel->ch_cached_lsr = 0;
        channel->ch_stops_sent = 0;
 
-       termios = port->state->port.tty->termios;
+       termios = &port->state->port.tty->termios;
        channel->ch_c_cflag     = termios->c_cflag;
        channel->ch_c_iflag     = termios->c_iflag;
        channel->ch_c_oflag     = termios->c_oflag;
@@ -283,7 +283,7 @@ static void jsm_tty_close(struct uart_port *port)
        jsm_printk(CLOSE, INFO, &channel->ch_bd->pci_dev, "start\n");
 
        bd = channel->ch_bd;
-       ts = port->state->port.tty->termios;
+       ts = &port->state->port.tty->termios;
 
        channel->ch_flags &= ~(CH_STOPI);
 
@@ -567,7 +567,7 @@ void jsm_input(struct jsm_channel *ch)
         *input data and return immediately.
         */
        if (!tp ||
-               !(tp->termios->c_cflag & CREAD) ) {
+               !(tp->termios.c_cflag & CREAD) ) {
 
                jsm_printk(READ, INFO, &ch->ch_bd->pci_dev,
                        "input. dropping %d bytes on port %d...\n", data_len, ch->ch_portnum);
diff --git a/drivers/tty/serial/lpc32xx_hs.c b/drivers/tty/serial/lpc32xx_hs.c
new file mode 100644 (file)
index 0000000..ba3af3b
--- /dev/null
@@ -0,0 +1,823 @@
+/*
+ * High Speed Serial Ports on NXP LPC32xx SoC
+ *
+ * Authors: Kevin Wells <kevin.wells@nxp.com>
+ *          Roland Stigge <stigge@antcom.de>
+ *
+ * Copyright (C) 2010 NXP Semiconductors
+ * Copyright (C) 2012 Roland Stigge
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/console.h>
+#include <linux/sysrq.h>
+#include <linux/tty.h>
+#include <linux/tty_flip.h>
+#include <linux/serial_core.h>
+#include <linux/serial.h>
+#include <linux/platform_device.h>
+#include <linux/delay.h>
+#include <linux/nmi.h>
+#include <linux/io.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/of.h>
+#include <mach/platform.h>
+#include <mach/hardware.h>
+
+/*
+ * High Speed UART register offsets
+ */
+#define LPC32XX_HSUART_FIFO(x)                 ((x) + 0x00)
+#define LPC32XX_HSUART_LEVEL(x)                        ((x) + 0x04)
+#define LPC32XX_HSUART_IIR(x)                  ((x) + 0x08)
+#define LPC32XX_HSUART_CTRL(x)                 ((x) + 0x0C)
+#define LPC32XX_HSUART_RATE(x)                 ((x) + 0x10)
+
+#define LPC32XX_HSU_BREAK_DATA                 (1 << 10)
+#define LPC32XX_HSU_ERROR_DATA                 (1 << 9)
+#define LPC32XX_HSU_RX_EMPTY                   (1 << 8)
+
+#define LPC32XX_HSU_TX_LEV(n)                  (((n) >> 8) & 0xFF)
+#define LPC32XX_HSU_RX_LEV(n)                  ((n) & 0xFF)
+
+#define LPC32XX_HSU_TX_INT_SET                 (1 << 6)
+#define LPC32XX_HSU_RX_OE_INT                  (1 << 5)
+#define LPC32XX_HSU_BRK_INT                    (1 << 4)
+#define LPC32XX_HSU_FE_INT                     (1 << 3)
+#define LPC32XX_HSU_RX_TIMEOUT_INT             (1 << 2)
+#define LPC32XX_HSU_RX_TRIG_INT                        (1 << 1)
+#define LPC32XX_HSU_TX_INT                     (1 << 0)
+
+#define LPC32XX_HSU_HRTS_INV                   (1 << 21)
+#define LPC32XX_HSU_HRTS_TRIG_8B               (0x0 << 19)
+#define LPC32XX_HSU_HRTS_TRIG_16B              (0x1 << 19)
+#define LPC32XX_HSU_HRTS_TRIG_32B              (0x2 << 19)
+#define LPC32XX_HSU_HRTS_TRIG_48B              (0x3 << 19)
+#define LPC32XX_HSU_HRTS_EN                    (1 << 18)
+#define LPC32XX_HSU_TMO_DISABLED               (0x0 << 16)
+#define LPC32XX_HSU_TMO_INACT_4B               (0x1 << 16)
+#define LPC32XX_HSU_TMO_INACT_8B               (0x2 << 16)
+#define LPC32XX_HSU_TMO_INACT_16B              (0x3 << 16)
+#define LPC32XX_HSU_HCTS_INV                   (1 << 15)
+#define LPC32XX_HSU_HCTS_EN                    (1 << 14)
+#define LPC32XX_HSU_OFFSET(n)                  ((n) << 9)
+#define LPC32XX_HSU_BREAK                      (1 << 8)
+#define LPC32XX_HSU_ERR_INT_EN                 (1 << 7)
+#define LPC32XX_HSU_RX_INT_EN                  (1 << 6)
+#define LPC32XX_HSU_TX_INT_EN                  (1 << 5)
+#define LPC32XX_HSU_RX_TL1B                    (0x0 << 2)
+#define LPC32XX_HSU_RX_TL4B                    (0x1 << 2)
+#define LPC32XX_HSU_RX_TL8B                    (0x2 << 2)
+#define LPC32XX_HSU_RX_TL16B                   (0x3 << 2)
+#define LPC32XX_HSU_RX_TL32B                   (0x4 << 2)
+#define LPC32XX_HSU_RX_TL48B                   (0x5 << 2)
+#define LPC32XX_HSU_TX_TLEMPTY                 (0x0 << 0)
+#define LPC32XX_HSU_TX_TL0B                    (0x0 << 0)
+#define LPC32XX_HSU_TX_TL4B                    (0x1 << 0)
+#define LPC32XX_HSU_TX_TL8B                    (0x2 << 0)
+#define LPC32XX_HSU_TX_TL16B                   (0x3 << 0)
+
+#define MODNAME "lpc32xx_hsuart"
+
+struct lpc32xx_hsuart_port {
+       struct uart_port port;
+};
+
+#define FIFO_READ_LIMIT 128
+#define MAX_PORTS 3
+#define LPC32XX_TTY_NAME "ttyTX"
+static struct lpc32xx_hsuart_port lpc32xx_hs_ports[MAX_PORTS];
+
+#ifdef CONFIG_SERIAL_HS_LPC32XX_CONSOLE
+static void wait_for_xmit_empty(struct uart_port *port)
+{
+       unsigned int timeout = 10000;
+
+       do {
+               if (LPC32XX_HSU_TX_LEV(readl(LPC32XX_HSUART_LEVEL(
+                                                       port->membase))) == 0)
+                       break;
+               if (--timeout == 0)
+                       break;
+               udelay(1);
+       } while (1);
+}
+
+static void wait_for_xmit_ready(struct uart_port *port)
+{
+       unsigned int timeout = 10000;
+
+       while (1) {
+               if (LPC32XX_HSU_TX_LEV(readl(LPC32XX_HSUART_LEVEL(
+                                                       port->membase))) < 32)
+                       break;
+               if (--timeout == 0)
+                       break;
+               udelay(1);
+       }
+}
+
+static void lpc32xx_hsuart_console_putchar(struct uart_port *port, int ch)
+{
+       wait_for_xmit_ready(port);
+       writel((u32)ch, LPC32XX_HSUART_FIFO(port->membase));
+}
+
+static void lpc32xx_hsuart_console_write(struct console *co, const char *s,
+                                        unsigned int count)
+{
+       struct lpc32xx_hsuart_port *up = &lpc32xx_hs_ports[co->index];
+       unsigned long flags;
+       int locked = 1;
+
+       touch_nmi_watchdog();
+       local_irq_save(flags);
+       if (up->port.sysrq)
+               locked = 0;
+       else if (oops_in_progress)
+               locked = spin_trylock(&up->port.lock);
+       else
+               spin_lock(&up->port.lock);
+
+       uart_console_write(&up->port, s, count, lpc32xx_hsuart_console_putchar);
+       wait_for_xmit_empty(&up->port);
+
+       if (locked)
+               spin_unlock(&up->port.lock);
+       local_irq_restore(flags);
+}
+
+static int __init lpc32xx_hsuart_console_setup(struct console *co,
+                                              char *options)
+{
+       struct uart_port *port;
+       int baud = 115200;
+       int bits = 8;
+       int parity = 'n';
+       int flow = 'n';
+
+       if (co->index >= MAX_PORTS)
+               co->index = 0;
+
+       port = &lpc32xx_hs_ports[co->index].port;
+       if (!port->membase)
+               return -ENODEV;
+
+       if (options)
+               uart_parse_options(options, &baud, &parity, &bits, &flow);
+
+       return uart_set_options(port, co, baud, parity, bits, flow);
+}
+
+static struct uart_driver lpc32xx_hsuart_reg;
+static struct console lpc32xx_hsuart_console = {
+       .name           = LPC32XX_TTY_NAME,
+       .write          = lpc32xx_hsuart_console_write,
+       .device         = uart_console_device,
+       .setup          = lpc32xx_hsuart_console_setup,
+       .flags          = CON_PRINTBUFFER,
+       .index          = -1,
+       .data           = &lpc32xx_hsuart_reg,
+};
+
+static int __init lpc32xx_hsuart_console_init(void)
+{
+       register_console(&lpc32xx_hsuart_console);
+       return 0;
+}
+console_initcall(lpc32xx_hsuart_console_init);
+
+#define LPC32XX_HSUART_CONSOLE (&lpc32xx_hsuart_console)
+#else
+#define LPC32XX_HSUART_CONSOLE NULL
+#endif
+
+static struct uart_driver lpc32xx_hs_reg = {
+       .owner          = THIS_MODULE,
+       .driver_name    = MODNAME,
+       .dev_name       = LPC32XX_TTY_NAME,
+       .nr             = MAX_PORTS,
+       .cons           = LPC32XX_HSUART_CONSOLE,
+};
+static int uarts_registered;
+
+static unsigned int __serial_get_clock_div(unsigned long uartclk,
+                                          unsigned long rate)
+{
+       u32 div, goodrate, hsu_rate, l_hsu_rate, comprate;
+       u32 rate_diff;
+
+       /* Find the closest divider to get the desired clock rate */
+       div = uartclk / rate;
+       goodrate = hsu_rate = (div / 14) - 1;
+       if (hsu_rate != 0)
+               hsu_rate--;
+
+       /* Tweak divider */
+       l_hsu_rate = hsu_rate + 3;
+       rate_diff = 0xFFFFFFFF;
+
+       while (hsu_rate < l_hsu_rate) {
+               comprate = uartclk / ((hsu_rate + 1) * 14);
+               if (abs(comprate - rate) < rate_diff) {
+                       goodrate = hsu_rate;
+                       rate_diff = abs(comprate - rate);
+               }
+
+               hsu_rate++;
+       }
+       if (hsu_rate > 0xFF)
+               hsu_rate = 0xFF;
+
+       return goodrate;
+}
+
+static void __serial_uart_flush(struct uart_port *port)
+{
+       u32 tmp;
+       int cnt = 0;
+
+       while ((readl(LPC32XX_HSUART_LEVEL(port->membase)) > 0) &&
+              (cnt++ < FIFO_READ_LIMIT))
+               tmp = readl(LPC32XX_HSUART_FIFO(port->membase));
+}
+
+static void __serial_lpc32xx_rx(struct uart_port *port)
+{
+       unsigned int tmp, flag;
+       struct tty_struct *tty = tty_port_tty_get(&port->state->port);
+
+       if (!tty) {
+               /* Discard data: no tty available */
+               while (!(readl(LPC32XX_HSUART_FIFO(port->membase)) &
+                        LPC32XX_HSU_RX_EMPTY))
+                       ;
+
+               return;
+       }
+
+       /* Read data from FIFO and push into terminal */
+       tmp = readl(LPC32XX_HSUART_FIFO(port->membase));
+       while (!(tmp & LPC32XX_HSU_RX_EMPTY)) {
+               flag = TTY_NORMAL;
+               port->icount.rx++;
+
+               if (tmp & LPC32XX_HSU_ERROR_DATA) {
+                       /* Framing error */
+                       writel(LPC32XX_HSU_FE_INT,
+                              LPC32XX_HSUART_IIR(port->membase));
+                       port->icount.frame++;
+                       flag = TTY_FRAME;
+                       tty_insert_flip_char(tty, 0, TTY_FRAME);
+               }
+
+               tty_insert_flip_char(tty, (tmp & 0xFF), flag);
+
+               tmp = readl(LPC32XX_HSUART_FIFO(port->membase));
+       }
+       tty_flip_buffer_push(tty);
+       tty_kref_put(tty);
+}
+
+static void __serial_lpc32xx_tx(struct uart_port *port)
+{
+       struct circ_buf *xmit = &port->state->xmit;
+       unsigned int tmp;
+
+       if (port->x_char) {
+               writel((u32)port->x_char, LPC32XX_HSUART_FIFO(port->membase));
+               port->icount.tx++;
+               port->x_char = 0;
+               return;
+       }
+
+       if (uart_circ_empty(xmit) || uart_tx_stopped(port))
+               goto exit_tx;
+
+       /* Transfer data */
+       while (LPC32XX_HSU_TX_LEV(readl(
+               LPC32XX_HSUART_LEVEL(port->membase))) < 64) {
+               writel((u32) xmit->buf[xmit->tail],
+                      LPC32XX_HSUART_FIFO(port->membase));
+               xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
+               port->icount.tx++;
+               if (uart_circ_empty(xmit))
+                       break;
+       }
+
+       if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
+               uart_write_wakeup(port);
+
+exit_tx:
+       if (uart_circ_empty(xmit)) {
+               tmp = readl(LPC32XX_HSUART_CTRL(port->membase));
+               tmp &= ~LPC32XX_HSU_TX_INT_EN;
+               writel(tmp, LPC32XX_HSUART_CTRL(port->membase));
+       }
+}
+
+static irqreturn_t serial_lpc32xx_interrupt(int irq, void *dev_id)
+{
+       struct uart_port *port = dev_id;
+       struct tty_struct *tty = tty_port_tty_get(&port->state->port);
+       u32 status;
+
+       spin_lock(&port->lock);
+
+       /* Read UART status and clear latched interrupts */
+       status = readl(LPC32XX_HSUART_IIR(port->membase));
+
+       if (status & LPC32XX_HSU_BRK_INT) {
+               /* Break received */
+               writel(LPC32XX_HSU_BRK_INT, LPC32XX_HSUART_IIR(port->membase));
+               port->icount.brk++;
+               uart_handle_break(port);
+       }
+
+       /* Framing error */
+       if (status & LPC32XX_HSU_FE_INT)
+               writel(LPC32XX_HSU_FE_INT, LPC32XX_HSUART_IIR(port->membase));
+
+       if (status & LPC32XX_HSU_RX_OE_INT) {
+               /* Receive FIFO overrun */
+               writel(LPC32XX_HSU_RX_OE_INT,
+                      LPC32XX_HSUART_IIR(port->membase));
+               port->icount.overrun++;
+               if (tty) {
+                       tty_insert_flip_char(tty, 0, TTY_OVERRUN);
+                       tty_schedule_flip(tty);
+               }
+       }
+
+       /* Data received? */
+       if (status & (LPC32XX_HSU_RX_TIMEOUT_INT | LPC32XX_HSU_RX_TRIG_INT)) {
+               __serial_lpc32xx_rx(port);
+               if (tty)
+                       tty_flip_buffer_push(tty);
+       }
+
+       /* Transmit data request? */
+       if ((status & LPC32XX_HSU_TX_INT) && (!uart_tx_stopped(port))) {
+               writel(LPC32XX_HSU_TX_INT, LPC32XX_HSUART_IIR(port->membase));
+               __serial_lpc32xx_tx(port);
+       }
+
+       spin_unlock(&port->lock);
+       tty_kref_put(tty);
+
+       return IRQ_HANDLED;
+}
+
+/* port->lock is not held.  */
+static unsigned int serial_lpc32xx_tx_empty(struct uart_port *port)
+{
+       unsigned int ret = 0;
+
+       if (LPC32XX_HSU_TX_LEV(readl(LPC32XX_HSUART_LEVEL(port->membase))) == 0)
+               ret = TIOCSER_TEMT;
+
+       return ret;
+}
+
+/* port->lock held by caller.  */
+static void serial_lpc32xx_set_mctrl(struct uart_port *port,
+                                    unsigned int mctrl)
+{
+       /* No signals are supported on HS UARTs */
+}
+
+/* port->lock is held by caller and interrupts are disabled.  */
+static unsigned int serial_lpc32xx_get_mctrl(struct uart_port *port)
+{
+       /* No signals are supported on HS UARTs */
+       return TIOCM_CAR | TIOCM_DSR | TIOCM_CTS;
+}
+
+/* port->lock held by caller.  */
+static void serial_lpc32xx_stop_tx(struct uart_port *port)
+{
+       u32 tmp;
+
+       tmp = readl(LPC32XX_HSUART_CTRL(port->membase));
+       tmp &= ~LPC32XX_HSU_TX_INT_EN;
+       writel(tmp, LPC32XX_HSUART_CTRL(port->membase));
+}
+
+/* port->lock held by caller.  */
+static void serial_lpc32xx_start_tx(struct uart_port *port)
+{
+       u32 tmp;
+
+       __serial_lpc32xx_tx(port);
+       tmp = readl(LPC32XX_HSUART_CTRL(port->membase));
+       tmp |= LPC32XX_HSU_TX_INT_EN;
+       writel(tmp, LPC32XX_HSUART_CTRL(port->membase));
+}
+
+/* port->lock held by caller.  */
+static void serial_lpc32xx_stop_rx(struct uart_port *port)
+{
+       u32 tmp;
+
+       tmp = readl(LPC32XX_HSUART_CTRL(port->membase));
+       tmp &= ~(LPC32XX_HSU_RX_INT_EN | LPC32XX_HSU_ERR_INT_EN);
+       writel(tmp, LPC32XX_HSUART_CTRL(port->membase));
+
+       writel((LPC32XX_HSU_BRK_INT | LPC32XX_HSU_RX_OE_INT |
+               LPC32XX_HSU_FE_INT), LPC32XX_HSUART_IIR(port->membase));
+}
+
+/* port->lock held by caller.  */
+static void serial_lpc32xx_enable_ms(struct uart_port *port)
+{
+       /* Modem status is not supported */
+}
+
+/* port->lock is not held.  */
+static void serial_lpc32xx_break_ctl(struct uart_port *port,
+                                    int break_state)
+{
+       unsigned long flags;
+       u32 tmp;
+
+       spin_lock_irqsave(&port->lock, flags);
+       tmp = readl(LPC32XX_HSUART_CTRL(port->membase));
+       if (break_state != 0)
+               tmp |= LPC32XX_HSU_BREAK;
+       else
+               tmp &= ~LPC32XX_HSU_BREAK;
+       writel(tmp, LPC32XX_HSUART_CTRL(port->membase));
+       spin_unlock_irqrestore(&port->lock, flags);
+}
+
+/* LPC3250 Errata HSUART.1: Hang workaround via loopback mode on inactivity */
+static void lpc32xx_loopback_set(resource_size_t mapbase, int state)
+{
+       int bit;
+       u32 tmp;
+
+       switch (mapbase) {
+       case LPC32XX_HS_UART1_BASE:
+               bit = 0;
+               break;
+       case LPC32XX_HS_UART2_BASE:
+               bit = 1;
+               break;
+       case LPC32XX_HS_UART7_BASE:
+               bit = 6;
+               break;
+       default:
+               WARN(1, "lpc32xx_hs: Warning: Unknown port at %08x\n", mapbase);
+               return;
+       }
+
+       tmp = readl(LPC32XX_UARTCTL_CLOOP);
+       if (state)
+               tmp |= (1 << bit);
+       else
+               tmp &= ~(1 << bit);
+       writel(tmp, LPC32XX_UARTCTL_CLOOP);
+}
+
+/* port->lock is not held.  */
+static int serial_lpc32xx_startup(struct uart_port *port)
+{
+       int retval;
+       unsigned long flags;
+       u32 tmp;
+
+       spin_lock_irqsave(&port->lock, flags);
+
+       __serial_uart_flush(port);
+
+       writel((LPC32XX_HSU_TX_INT | LPC32XX_HSU_FE_INT |
+               LPC32XX_HSU_BRK_INT | LPC32XX_HSU_RX_OE_INT),
+              LPC32XX_HSUART_IIR(port->membase));
+
+       writel(0xFF, LPC32XX_HSUART_RATE(port->membase));
+
+       /*
+        * Set receiver timeout, HSU offset of 20, no break, no interrupts,
+        * and default FIFO trigger levels
+        */
+       tmp = LPC32XX_HSU_TX_TL8B | LPC32XX_HSU_RX_TL32B |
+               LPC32XX_HSU_OFFSET(20) | LPC32XX_HSU_TMO_INACT_4B;
+       writel(tmp, LPC32XX_HSUART_CTRL(port->membase));
+
+       lpc32xx_loopback_set(port->mapbase, 0); /* get out of loopback mode */
+
+       spin_unlock_irqrestore(&port->lock, flags);
+
+       retval = request_irq(port->irq, serial_lpc32xx_interrupt,
+                            0, MODNAME, port);
+       if (!retval)
+               writel((tmp | LPC32XX_HSU_RX_INT_EN | LPC32XX_HSU_ERR_INT_EN),
+                      LPC32XX_HSUART_CTRL(port->membase));
+
+       return retval;
+}
+
+/* port->lock is not held.  */
+static void serial_lpc32xx_shutdown(struct uart_port *port)
+{
+       u32 tmp;
+       unsigned long flags;
+
+       spin_lock_irqsave(&port->lock, flags);
+
+       tmp = LPC32XX_HSU_TX_TL8B | LPC32XX_HSU_RX_TL32B |
+               LPC32XX_HSU_OFFSET(20) | LPC32XX_HSU_TMO_INACT_4B;
+       writel(tmp, LPC32XX_HSUART_CTRL(port->membase));
+
+       lpc32xx_loopback_set(port->mapbase, 1); /* go to loopback mode */
+
+       spin_unlock_irqrestore(&port->lock, flags);
+
+       free_irq(port->irq, port);
+}
+
+/* port->lock is not held.  */
+static void serial_lpc32xx_set_termios(struct uart_port *port,
+                                      struct ktermios *termios,
+                                      struct ktermios *old)
+{
+       unsigned long flags;
+       unsigned int baud, quot;
+       u32 tmp;
+
+       /* Always 8-bit, no parity, 1 stop bit */
+       termios->c_cflag &= ~(CSIZE | CSTOPB | PARENB | PARODD);
+       termios->c_cflag |= CS8;
+
+       termios->c_cflag &= ~(HUPCL | CMSPAR | CLOCAL | CRTSCTS);
+
+       baud = uart_get_baud_rate(port, termios, old, 0,
+                                 port->uartclk / 14);
+
+       quot = __serial_get_clock_div(port->uartclk, baud);
+
+       spin_lock_irqsave(&port->lock, flags);
+
+       /* Ignore characters? */
+       tmp = readl(LPC32XX_HSUART_CTRL(port->membase));
+       if ((termios->c_cflag & CREAD) == 0)
+               tmp &= ~(LPC32XX_HSU_RX_INT_EN | LPC32XX_HSU_ERR_INT_EN);
+       else
+               tmp |= LPC32XX_HSU_RX_INT_EN | LPC32XX_HSU_ERR_INT_EN;
+       writel(tmp, LPC32XX_HSUART_CTRL(port->membase));
+
+       writel(quot, LPC32XX_HSUART_RATE(port->membase));
+
+       uart_update_timeout(port, termios->c_cflag, baud);
+
+       spin_unlock_irqrestore(&port->lock, flags);
+
+       /* Don't rewrite B0 */
+       if (tty_termios_baud_rate(termios))
+               tty_termios_encode_baud_rate(termios, baud, baud);
+}
+
+static const char *serial_lpc32xx_type(struct uart_port *port)
+{
+       return MODNAME;
+}
+
+static void serial_lpc32xx_release_port(struct uart_port *port)
+{
+       if ((port->iotype == UPIO_MEM32) && (port->mapbase)) {
+               if (port->flags & UPF_IOREMAP) {
+                       iounmap(port->membase);
+                       port->membase = NULL;
+               }
+
+               release_mem_region(port->mapbase, SZ_4K);
+       }
+}
+
+static int serial_lpc32xx_request_port(struct uart_port *port)
+{
+       int ret = -ENODEV;
+
+       if ((port->iotype == UPIO_MEM32) && (port->mapbase)) {
+               ret = 0;
+
+               if (!request_mem_region(port->mapbase, SZ_4K, MODNAME))
+                       ret = -EBUSY;
+               else if (port->flags & UPF_IOREMAP) {
+                       port->membase = ioremap(port->mapbase, SZ_4K);
+                       if (!port->membase) {
+                               release_mem_region(port->mapbase, SZ_4K);
+                               ret = -ENOMEM;
+                       }
+               }
+       }
+
+       return ret;
+}
+
+static void serial_lpc32xx_config_port(struct uart_port *port, int uflags)
+{
+       int ret;
+
+       ret = serial_lpc32xx_request_port(port);
+       if (ret < 0)
+               return;
+       port->type = PORT_UART00;
+       port->fifosize = 64;
+
+       __serial_uart_flush(port);
+
+       writel((LPC32XX_HSU_TX_INT | LPC32XX_HSU_FE_INT |
+               LPC32XX_HSU_BRK_INT | LPC32XX_HSU_RX_OE_INT),
+              LPC32XX_HSUART_IIR(port->membase));
+
+       writel(0xFF, LPC32XX_HSUART_RATE(port->membase));
+
+       /* Set receiver timeout, HSU offset of 20, no break, no interrupts,
+          and default FIFO trigger levels */
+       writel(LPC32XX_HSU_TX_TL8B | LPC32XX_HSU_RX_TL32B |
+              LPC32XX_HSU_OFFSET(20) | LPC32XX_HSU_TMO_INACT_4B,
+              LPC32XX_HSUART_CTRL(port->membase));
+}
+
+static int serial_lpc32xx_verify_port(struct uart_port *port,
+                                     struct serial_struct *ser)
+{
+       int ret = 0;
+
+       if (ser->type != PORT_UART00)
+               ret = -EINVAL;
+
+       return ret;
+}
+
+static struct uart_ops serial_lpc32xx_pops = {
+       .tx_empty       = serial_lpc32xx_tx_empty,
+       .set_mctrl      = serial_lpc32xx_set_mctrl,
+       .get_mctrl      = serial_lpc32xx_get_mctrl,
+       .stop_tx        = serial_lpc32xx_stop_tx,
+       .start_tx       = serial_lpc32xx_start_tx,
+       .stop_rx        = serial_lpc32xx_stop_rx,
+       .enable_ms      = serial_lpc32xx_enable_ms,
+       .break_ctl      = serial_lpc32xx_break_ctl,
+       .startup        = serial_lpc32xx_startup,
+       .shutdown       = serial_lpc32xx_shutdown,
+       .set_termios    = serial_lpc32xx_set_termios,
+       .type           = serial_lpc32xx_type,
+       .release_port   = serial_lpc32xx_release_port,
+       .request_port   = serial_lpc32xx_request_port,
+       .config_port    = serial_lpc32xx_config_port,
+       .verify_port    = serial_lpc32xx_verify_port,
+};
+
+/*
+ * Register a set of serial devices attached to a platform device
+ */
+static int __devinit serial_hs_lpc32xx_probe(struct platform_device *pdev)
+{
+       struct lpc32xx_hsuart_port *p = &lpc32xx_hs_ports[uarts_registered];
+       int ret = 0;
+       struct resource *res;
+
+       if (uarts_registered >= MAX_PORTS) {
+               dev_err(&pdev->dev,
+                       "Error: Number of possible ports exceeded (%d)!\n",
+                       uarts_registered + 1);
+               return -ENXIO;
+       }
+
+       memset(p, 0, sizeof(*p));
+
+       res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+       if (!res) {
+               dev_err(&pdev->dev,
+                       "Error getting mem resource for HS UART port %d\n",
+                       uarts_registered);
+               return -ENXIO;
+       }
+       p->port.mapbase = res->start;
+       p->port.membase = NULL;
+
+       p->port.irq = platform_get_irq(pdev, 0);
+       if (p->port.irq < 0) {
+               dev_err(&pdev->dev, "Error getting irq for HS UART port %d\n",
+                       uarts_registered);
+               return p->port.irq;
+       }
+
+       p->port.iotype = UPIO_MEM32;
+       p->port.uartclk = LPC32XX_MAIN_OSC_FREQ;
+       p->port.regshift = 2;
+       p->port.flags = UPF_BOOT_AUTOCONF | UPF_FIXED_PORT | UPF_IOREMAP;
+       p->port.dev = &pdev->dev;
+       p->port.ops = &serial_lpc32xx_pops;
+       p->port.line = uarts_registered++;
+       spin_lock_init(&p->port.lock);
+
+       /* send port to loopback mode by default */
+       lpc32xx_loopback_set(p->port.mapbase, 1);
+
+       ret = uart_add_one_port(&lpc32xx_hs_reg, &p->port);
+
+       platform_set_drvdata(pdev, p);
+
+       return ret;
+}
+
+/*
+ * Remove serial ports registered against a platform device.
+ */
+static int __devexit serial_hs_lpc32xx_remove(struct platform_device *pdev)
+{
+       struct lpc32xx_hsuart_port *p = platform_get_drvdata(pdev);
+
+       uart_remove_one_port(&lpc32xx_hs_reg, &p->port);
+
+       return 0;
+}
+
+
+#ifdef CONFIG_PM
+static int serial_hs_lpc32xx_suspend(struct platform_device *pdev,
+                                    pm_message_t state)
+{
+       struct lpc32xx_hsuart_port *p = platform_get_drvdata(pdev);
+
+       uart_suspend_port(&lpc32xx_hs_reg, &p->port);
+
+       return 0;
+}
+
+static int serial_hs_lpc32xx_resume(struct platform_device *pdev)
+{
+       struct lpc32xx_hsuart_port *p = platform_get_drvdata(pdev);
+
+       uart_resume_port(&lpc32xx_hs_reg, &p->port);
+
+       return 0;
+}
+#else
+#define serial_hs_lpc32xx_suspend      NULL
+#define serial_hs_lpc32xx_resume       NULL
+#endif
+
+static const struct of_device_id serial_hs_lpc32xx_dt_ids[] = {
+       { .compatible = "nxp,lpc3220-hsuart" },
+       { /* sentinel */ }
+};
+
+MODULE_DEVICE_TABLE(of, serial_hs_lpc32xx_dt_ids);
+
+static struct platform_driver serial_hs_lpc32xx_driver = {
+       .probe          = serial_hs_lpc32xx_probe,
+       .remove         = __devexit_p(serial_hs_lpc32xx_remove),
+       .suspend        = serial_hs_lpc32xx_suspend,
+       .resume         = serial_hs_lpc32xx_resume,
+       .driver         = {
+               .name   = MODNAME,
+               .owner  = THIS_MODULE,
+               .of_match_table = serial_hs_lpc32xx_dt_ids,
+       },
+};
+
+static int __init lpc32xx_hsuart_init(void)
+{
+       int ret;
+
+       ret = uart_register_driver(&lpc32xx_hs_reg);
+       if (ret)
+               return ret;
+
+       ret = platform_driver_register(&serial_hs_lpc32xx_driver);
+       if (ret)
+               uart_unregister_driver(&lpc32xx_hs_reg);
+
+       return ret;
+}
+
+static void __exit lpc32xx_hsuart_exit(void)
+{
+       platform_driver_unregister(&serial_hs_lpc32xx_driver);
+       uart_unregister_driver(&lpc32xx_hs_reg);
+}
+
+module_init(lpc32xx_hsuart_init);
+module_exit(lpc32xx_hsuart_exit);
+
+MODULE_AUTHOR("Kevin Wells <kevin.wells@nxp.com>");
+MODULE_AUTHOR("Roland Stigge <stigge@antcom.de>");
+MODULE_DESCRIPTION("NXP LPC32XX High Speed UART driver");
+MODULE_LICENSE("GPL");
index 34e71874a89266db9ebd47cb9a156e89192af7a1..df443b908ca305694c43d9665859c9cca11f3dde 100644 (file)
@@ -105,6 +105,10 @@ static int __devinit of_platform_serial_setup(struct platform_device *ofdev,
        port->uartclk = clk;
        port->flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_IOREMAP
                | UPF_FIXED_PORT | UPF_FIXED_TYPE;
+
+       if (of_find_property(np, "no-loopback-test", NULL))
+               port->flags |= UPF_SKIP_TEST;
+
        port->dev = &ofdev->dev;
 
        if (type == PORT_TEGRA)
@@ -144,8 +148,15 @@ static int __devinit of_platform_serial_probe(struct platform_device *ofdev)
        switch (port_type) {
 #ifdef CONFIG_SERIAL_8250
        case PORT_8250 ... PORT_MAX_8250:
-               ret = serial8250_register_port(&port);
+       {
+               /* For now the of bindings don't support the extra
+                  8250 specific bits */
+               struct uart_8250_port port8250;
+               memset(&port8250, 0, sizeof(port8250));
+               port8250.port = port;
+               ret = serial8250_register_8250_port(&port8250);
                break;
+       }
 #endif
 #ifdef CONFIG_SERIAL_OF_PLATFORM_NWPSERIAL
        case PORT_NWPSERIAL:
index 5847a4b855f74804d327cca6490cade872f673d2..9033fc6e0e4eb31a4fea337eca73634c8eec5109 100644 (file)
@@ -670,9 +670,19 @@ serial_pxa_console_write(struct console *co, const char *s, unsigned int count)
 {
        struct uart_pxa_port *up = serial_pxa_ports[co->index];
        unsigned int ier;
+       unsigned long flags;
+       int locked = 1;
 
        clk_prepare_enable(up->clk);
 
+       local_irq_save(flags);
+       if (up->port.sysrq)
+               locked = 0;
+       else if (oops_in_progress)
+               locked = spin_trylock(&up->port.lock);
+       else
+               spin_lock(&up->port.lock);
+
        /*
         *      First save the IER then disable the interrupts
         */
@@ -688,6 +698,10 @@ serial_pxa_console_write(struct console *co, const char *s, unsigned int count)
        wait_for_xmitr(up);
        serial_out(up, UART_IER, ier);
 
+       if (locked)
+               spin_unlock(&up->port.lock);
+       local_irq_restore(flags);
+
        clk_disable_unprepare(up->clk);
 }
 
index 02d07bfcfa8add3f46f0eb9b36a6b821305e8493..5c5e7e09f23e67eda88a4dd7b188eabb5ee46e9a 100644 (file)
@@ -529,7 +529,7 @@ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
 
        switch (level) {
        case 3:
-               if (!IS_ERR(ourport->baudclk) && ourport->baudclk != NULL)
+               if (!IS_ERR(ourport->baudclk))
                        clk_disable(ourport->baudclk);
 
                clk_disable(ourport->clk);
@@ -538,7 +538,7 @@ static void s3c24xx_serial_pm(struct uart_port *port, unsigned int level,
        case 0:
                clk_enable(ourport->clk);
 
-               if (!IS_ERR(ourport->baudclk) && ourport->baudclk != NULL)
+               if (!IS_ERR(ourport->baudclk))
                        clk_enable(ourport->baudclk);
 
                break;
@@ -604,7 +604,6 @@ static unsigned int s3c24xx_serial_getclk(struct s3c24xx_uart_port *ourport,
        char clkname[MAX_CLK_NAME_LENGTH];
        int calc_deviation, deviation = (1 << 30) - 1;
 
-       *best_clk = NULL;
        clk_sel = (ourport->cfg->clk_sel) ? ourport->cfg->clk_sel :
                        ourport->info->def_clk_sel;
        for (cnt = 0; cnt < info->num_clks; cnt++) {
@@ -613,7 +612,7 @@ static unsigned int s3c24xx_serial_getclk(struct s3c24xx_uart_port *ourport,
 
                sprintf(clkname, "clk_uart_baud%d", cnt);
                clk = clk_get(ourport->port.dev, clkname);
-               if (IS_ERR_OR_NULL(clk))
+               if (IS_ERR(clk))
                        continue;
 
                rate = clk_get_rate(clk);
@@ -684,7 +683,7 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
 {
        struct s3c2410_uartcfg *cfg = s3c24xx_port_to_cfg(port);
        struct s3c24xx_uart_port *ourport = to_ourport(port);
-       struct clk *clk = NULL;
+       struct clk *clk = ERR_PTR(-EINVAL);
        unsigned long flags;
        unsigned int baud, quot, clk_sel = 0;
        unsigned int ulcon;
@@ -705,7 +704,7 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
        quot = s3c24xx_serial_getclk(ourport, baud, &clk, &clk_sel);
        if (baud == 38400 && (port->flags & UPF_SPD_MASK) == UPF_SPD_CUST)
                quot = port->custom_divisor;
-       if (!clk)
+       if (IS_ERR(clk))
                return;
 
        /* check to see if we need  to change clock source */
@@ -713,9 +712,9 @@ static void s3c24xx_serial_set_termios(struct uart_port *port,
        if (ourport->baudclk != clk) {
                s3c24xx_serial_setsource(port, clk_sel);
 
-               if (ourport->baudclk != NULL && !IS_ERR(ourport->baudclk)) {
+               if (!IS_ERR(ourport->baudclk)) {
                        clk_disable(ourport->baudclk);
-                       ourport->baudclk  = NULL;
+                       ourport->baudclk = ERR_PTR(-EINVAL);
                }
 
                clk_enable(clk);
@@ -1036,7 +1035,7 @@ static int s3c24xx_serial_cpufreq_transition(struct notifier_block *nb,
                if (tty == NULL)
                        goto exit;
 
-               termios = tty->termios;
+               termios = &tty->termios;
 
                if (termios == NULL) {
                        printk(KERN_WARNING "%s: no termios?\n", __func__);
@@ -1160,7 +1159,11 @@ static ssize_t s3c24xx_serial_show_clksrc(struct device *dev,
        struct uart_port *port = s3c24xx_dev_to_port(dev);
        struct s3c24xx_uart_port *ourport = to_ourport(port);
 
-       return snprintf(buf, PAGE_SIZE, "* %s\n", ourport->baudclk->name);
+       if (IS_ERR(ourport->baudclk))
+               return -EINVAL;
+
+       return snprintf(buf, PAGE_SIZE, "* %s\n",
+                       ourport->baudclk->name ?: "(null)");
 }
 
 static DEVICE_ATTR(clock_source, S_IRUGO, s3c24xx_serial_show_clksrc, NULL);
@@ -1200,6 +1203,7 @@ static int s3c24xx_serial_probe(struct platform_device *pdev)
                return -ENODEV;
        }
 
+       ourport->baudclk = ERR_PTR(-EINVAL);
        ourport->info = ourport->drv_data->info;
        ourport->cfg = (pdev->dev.platform_data) ?
                        (struct s3c2410_uartcfg *)pdev->dev.platform_data :
@@ -1387,7 +1391,7 @@ s3c24xx_serial_get_options(struct uart_port *port, int *baud,
                sprintf(clk_name, "clk_uart_baud%d", clk_sel);
 
                clk = clk_get(port->dev, clk_name);
-               if (!IS_ERR(clk) && clk != NULL)
+               if (!IS_ERR(clk))
                        rate = clk_get_rate(clk);
                else
                        rate = 1;
index a21dc8e3b7c0cf56ed808e006499abf4b661a217..d98b1bd407f6f1e84420cf8b99813858d0e2db12 100644 (file)
@@ -159,7 +159,7 @@ static int uart_port_startup(struct tty_struct *tty, struct uart_state *state,
        retval = uport->ops->startup(uport);
        if (retval == 0) {
                if (uart_console(uport) && uport->cons->cflag) {
-                       tty->termios->c_cflag = uport->cons->cflag;
+                       tty->termios.c_cflag = uport->cons->cflag;
                        uport->cons->cflag = 0;
                }
                /*
@@ -172,7 +172,7 @@ static int uart_port_startup(struct tty_struct *tty, struct uart_state *state,
                         * Setup the RTS and DTR signals once the
                         * port is open and ready to respond.
                         */
-                       if (tty->termios->c_cflag & CBAUD)
+                       if (tty->termios.c_cflag & CBAUD)
                                uart_set_mctrl(uport, TIOCM_RTS | TIOCM_DTR);
                }
 
@@ -240,7 +240,7 @@ static void uart_shutdown(struct tty_struct *tty, struct uart_state *state)
                /*
                 * Turn off DTR and RTS early.
                 */
-               if (!tty || (tty->termios->c_cflag & HUPCL))
+               if (!tty || (tty->termios.c_cflag & HUPCL))
                        uart_clear_mctrl(uport, TIOCM_DTR | TIOCM_RTS);
 
                uart_port_shutdown(port);
@@ -440,10 +440,10 @@ static void uart_change_speed(struct tty_struct *tty, struct uart_state *state,
         * If we have no tty, termios, or the port does not exist,
         * then we can't set the parameters for this port.
         */
-       if (!tty || !tty->termios || uport->type == PORT_UNKNOWN)
+       if (!tty || uport->type == PORT_UNKNOWN)
                return;
 
-       termios = tty->termios;
+       termios = &tty->termios;
 
        /*
         * Set flags based on termios cflag
@@ -614,7 +614,7 @@ static void uart_throttle(struct tty_struct *tty)
        if (I_IXOFF(tty))
                uart_send_xchar(tty, STOP_CHAR(tty));
 
-       if (tty->termios->c_cflag & CRTSCTS)
+       if (tty->termios.c_cflag & CRTSCTS)
                uart_clear_mctrl(state->uart_port, TIOCM_RTS);
 }
 
@@ -630,7 +630,7 @@ static void uart_unthrottle(struct tty_struct *tty)
                        uart_send_xchar(tty, START_CHAR(tty));
        }
 
-       if (tty->termios->c_cflag & CRTSCTS)
+       if (tty->termios.c_cflag & CRTSCTS)
                uart_set_mctrl(port, TIOCM_RTS);
 }
 
@@ -1187,7 +1187,7 @@ static void uart_set_ldisc(struct tty_struct *tty)
        struct uart_port *uport = state->uart_port;
 
        if (uport->ops->set_ldisc)
-               uport->ops->set_ldisc(uport, tty->termios->c_line);
+               uport->ops->set_ldisc(uport, tty->termios.c_line);
 }
 
 static void uart_set_termios(struct tty_struct *tty,
@@ -1195,7 +1195,7 @@ static void uart_set_termios(struct tty_struct *tty,
 {
        struct uart_state *state = tty->driver_data;
        unsigned long flags;
-       unsigned int cflag = tty->termios->c_cflag;
+       unsigned int cflag = tty->termios.c_cflag;
 
 
        /*
@@ -1206,9 +1206,9 @@ static void uart_set_termios(struct tty_struct *tty,
         */
 #define RELEVANT_IFLAG(iflag)  ((iflag) & (IGNBRK|BRKINT|IGNPAR|PARMRK|INPCK))
        if ((cflag ^ old_termios->c_cflag) == 0 &&
-           tty->termios->c_ospeed == old_termios->c_ospeed &&
-           tty->termios->c_ispeed == old_termios->c_ispeed &&
-           RELEVANT_IFLAG(tty->termios->c_iflag ^ old_termios->c_iflag) == 0) {
+           tty->termios.c_ospeed == old_termios->c_ospeed &&
+           tty->termios.c_ispeed == old_termios->c_ispeed &&
+           RELEVANT_IFLAG(tty->termios.c_iflag ^ old_termios->c_iflag) == 0) {
                return;
        }
 
@@ -1960,8 +1960,8 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *uport)
                /*
                 * If that's unset, use the tty termios setting.
                 */
-               if (port->tty && port->tty->termios && termios.c_cflag == 0)
-                       termios = *(port->tty->termios);
+               if (port->tty && termios.c_cflag == 0)
+                       termios = port->tty->termios;
 
                if (console_suspend_enabled)
                        uart_change_pm(state, 0);
index 593d40ad0a6be9b0de161803aa69c9011e2fdab8..bdeeb3133f621c37edd55ba756a5513ead68d3c5 100644 (file)
@@ -1840,22 +1840,22 @@ static void shutdown(struct mgsl_struct * info)
        usc_DisableInterrupts(info,RECEIVE_DATA + RECEIVE_STATUS +
                TRANSMIT_DATA + TRANSMIT_STATUS + IO_PIN + MISC );
        usc_DisableDmaInterrupts(info,DICR_MASTER + DICR_TRANSMIT + DICR_RECEIVE);
-       
+
        /* Disable DMAEN (Port 7, Bit 14) */
        /* This disconnects the DMA request signal from the ISA bus */
        /* on the ISA adapter. This has no effect for the PCI adapter */
        usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT15) | BIT14));
-       
+
        /* Disable INTEN (Port 6, Bit12) */
        /* This disconnects the IRQ request signal to the ISA bus */
        /* on the ISA adapter. This has no effect for the PCI adapter */
        usc_OutReg(info, PCR, (u16)((usc_InReg(info, PCR) | BIT13) | BIT12));
-       
-       if (!info->port.tty || info->port.tty->termios->c_cflag & HUPCL) {
+
+       if (!info->port.tty || info->port.tty->termios.c_cflag & HUPCL) {
                info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS);
                usc_set_serial_signals(info);
        }
-       
+
        spin_unlock_irqrestore(&info->irq_spinlock,flags);
 
        mgsl_release_resources(info);   
@@ -1895,7 +1895,7 @@ static void mgsl_program_hw(struct mgsl_struct *info)
        usc_EnableInterrupts(info, IO_PIN);
        usc_get_serial_signals(info);
                
-       if (info->netcount || info->port.tty->termios->c_cflag & CREAD)
+       if (info->netcount || info->port.tty->termios.c_cflag & CREAD)
                usc_start_receiver(info);
                
        spin_unlock_irqrestore(&info->irq_spinlock,flags);
@@ -1908,14 +1908,14 @@ static void mgsl_change_params(struct mgsl_struct *info)
        unsigned cflag;
        int bits_per_char;
 
-       if (!info->port.tty || !info->port.tty->termios)
+       if (!info->port.tty)
                return;
                
        if (debug_level >= DEBUG_LEVEL_INFO)
                printk("%s(%d):mgsl_change_params(%s)\n",
                         __FILE__,__LINE__, info->device_name );
                         
-       cflag = info->port.tty->termios->c_cflag;
+       cflag = info->port.tty->termios.c_cflag;
 
        /* if B0 rate (hangup) specified then negate DTR and RTS */
        /* otherwise assert DTR and RTS */
@@ -2367,8 +2367,8 @@ static void mgsl_throttle(struct tty_struct * tty)
        
        if (I_IXOFF(tty))
                mgsl_send_xchar(tty, STOP_CHAR(tty));
-       if (tty->termios->c_cflag & CRTSCTS) {
+
+       if (tty->termios.c_cflag & CRTSCTS) {
                spin_lock_irqsave(&info->irq_spinlock,flags);
                info->serial_signals &= ~SerialSignal_RTS;
                usc_set_serial_signals(info);
@@ -2401,8 +2401,8 @@ static void mgsl_unthrottle(struct tty_struct * tty)
                else
                        mgsl_send_xchar(tty, START_CHAR(tty));
        }
-       
-       if (tty->termios->c_cflag & CRTSCTS) {
+
+       if (tty->termios.c_cflag & CRTSCTS) {
                spin_lock_irqsave(&info->irq_spinlock,flags);
                info->serial_signals |= SerialSignal_RTS;
                usc_set_serial_signals(info);
@@ -3045,7 +3045,7 @@ static void mgsl_set_termios(struct tty_struct *tty, struct ktermios *old_termio
 
        /* Handle transition to B0 status */
        if (old_termios->c_cflag & CBAUD &&
-           !(tty->termios->c_cflag & CBAUD)) {
+           !(tty->termios.c_cflag & CBAUD)) {
                info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR);
                spin_lock_irqsave(&info->irq_spinlock,flags);
                usc_set_serial_signals(info);
@@ -3054,9 +3054,9 @@ static void mgsl_set_termios(struct tty_struct *tty, struct ktermios *old_termio
        
        /* Handle transition away from B0 status */
        if (!(old_termios->c_cflag & CBAUD) &&
-           tty->termios->c_cflag & CBAUD) {
+           tty->termios.c_cflag & CBAUD) {
                info->serial_signals |= SerialSignal_DTR;
-               if (!(tty->termios->c_cflag & CRTSCTS) || 
+               if (!(tty->termios.c_cflag & CRTSCTS) || 
                    !test_bit(TTY_THROTTLED, &tty->flags)) {
                        info->serial_signals |= SerialSignal_RTS;
                }
@@ -3067,7 +3067,7 @@ static void mgsl_set_termios(struct tty_struct *tty, struct ktermios *old_termio
        
        /* Handle turning off CRTSCTS */
        if (old_termios->c_cflag & CRTSCTS &&
-           !(tty->termios->c_cflag & CRTSCTS)) {
+           !(tty->termios.c_cflag & CRTSCTS)) {
                tty->hw_stopped = 0;
                mgsl_start(tty);
        }
@@ -3287,7 +3287,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
                return 0;
        }
 
-       if (tty->termios->c_cflag & CLOCAL)
+       if (tty->termios.c_cflag & CLOCAL)
                do_clocal = true;
 
        /* Wait for carrier detect and the line to become
@@ -3313,7 +3313,7 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp,
        port->blocked_open++;
        
        while (1) {
-               if (tty->termios->c_cflag & CBAUD)
+               if (tty->termios.c_cflag & CBAUD)
                        tty_port_raise_dtr_rts(port);
                
                set_current_state(TASK_INTERRUPTIBLE);
index aa1debf97cc741e3f5914cb5396c8397bd37f362..f02d18a391e5b510af4a2a66bc49f7f6ceb67809 100644 (file)
@@ -785,7 +785,7 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 
        /* Handle transition to B0 status */
        if (old_termios->c_cflag & CBAUD &&
-           !(tty->termios->c_cflag & CBAUD)) {
+           !(tty->termios.c_cflag & CBAUD)) {
                info->signals &= ~(SerialSignal_RTS + SerialSignal_DTR);
                spin_lock_irqsave(&info->lock,flags);
                set_signals(info);
@@ -794,9 +794,9 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 
        /* Handle transition away from B0 status */
        if (!(old_termios->c_cflag & CBAUD) &&
-           tty->termios->c_cflag & CBAUD) {
+           tty->termios.c_cflag & CBAUD) {
                info->signals |= SerialSignal_DTR;
-               if (!(tty->termios->c_cflag & CRTSCTS) ||
+               if (!(tty->termios.c_cflag & CRTSCTS) ||
                    !test_bit(TTY_THROTTLED, &tty->flags)) {
                        info->signals |= SerialSignal_RTS;
                }
@@ -807,7 +807,7 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 
        /* Handle turning off CRTSCTS */
        if (old_termios->c_cflag & CRTSCTS &&
-           !(tty->termios->c_cflag & CRTSCTS)) {
+           !(tty->termios.c_cflag & CRTSCTS)) {
                tty->hw_stopped = 0;
                tx_release(tty);
        }
@@ -1372,7 +1372,7 @@ static void throttle(struct tty_struct * tty)
        DBGINFO(("%s throttle\n", info->device_name));
        if (I_IXOFF(tty))
                send_xchar(tty, STOP_CHAR(tty));
-       if (tty->termios->c_cflag & CRTSCTS) {
+       if (tty->termios.c_cflag & CRTSCTS) {
                spin_lock_irqsave(&info->lock,flags);
                info->signals &= ~SerialSignal_RTS;
                set_signals(info);
@@ -1397,7 +1397,7 @@ static void unthrottle(struct tty_struct * tty)
                else
                        send_xchar(tty, START_CHAR(tty));
        }
-       if (tty->termios->c_cflag & CRTSCTS) {
+       if (tty->termios.c_cflag & CRTSCTS) {
                spin_lock_irqsave(&info->lock,flags);
                info->signals |= SerialSignal_RTS;
                set_signals(info);
@@ -2493,7 +2493,7 @@ static void shutdown(struct slgt_info *info)
 
        slgt_irq_off(info, IRQ_ALL | IRQ_MASTER);
 
-       if (!info->port.tty || info->port.tty->termios->c_cflag & HUPCL) {
+       if (!info->port.tty || info->port.tty->termios.c_cflag & HUPCL) {
                info->signals &= ~(SerialSignal_DTR + SerialSignal_RTS);
                set_signals(info);
        }
@@ -2534,7 +2534,7 @@ static void program_hw(struct slgt_info *info)
        get_signals(info);
 
        if (info->netcount ||
-           (info->port.tty && info->port.tty->termios->c_cflag & CREAD))
+           (info->port.tty && info->port.tty->termios.c_cflag & CREAD))
                rx_start(info);
 
        spin_unlock_irqrestore(&info->lock,flags);
@@ -2548,11 +2548,11 @@ static void change_params(struct slgt_info *info)
        unsigned cflag;
        int bits_per_char;
 
-       if (!info->port.tty || !info->port.tty->termios)
+       if (!info->port.tty)
                return;
        DBGINFO(("%s change_params\n", info->device_name));
 
-       cflag = info->port.tty->termios->c_cflag;
+       cflag = info->port.tty->termios.c_cflag;
 
        /* if B0 rate (hangup) specified then negate DTR and RTS */
        /* otherwise assert DTR and RTS */
@@ -3292,7 +3292,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
                return 0;
        }
 
-       if (tty->termios->c_cflag & CLOCAL)
+       if (tty->termios.c_cflag & CLOCAL)
                do_clocal = true;
 
        /* Wait for carrier detect and the line to become
@@ -3314,7 +3314,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
        port->blocked_open++;
 
        while (1) {
-               if ((tty->termios->c_cflag & CBAUD))
+               if ((tty->termios.c_cflag & CBAUD))
                        tty_port_raise_dtr_rts(port);
 
                set_current_state(TASK_INTERRUPTIBLE);
index a3dddc12d2fedc3ec261c2c8f2b3da215f564a20..ae75a3c21fd3a340d5ebd5096ca1971cbe1871c2 100644 (file)
@@ -873,7 +873,7 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 
        /* Handle transition to B0 status */
        if (old_termios->c_cflag & CBAUD &&
-           !(tty->termios->c_cflag & CBAUD)) {
+           !(tty->termios.c_cflag & CBAUD)) {
                info->serial_signals &= ~(SerialSignal_RTS + SerialSignal_DTR);
                spin_lock_irqsave(&info->lock,flags);
                set_signals(info);
@@ -882,9 +882,9 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 
        /* Handle transition away from B0 status */
        if (!(old_termios->c_cflag & CBAUD) &&
-           tty->termios->c_cflag & CBAUD) {
+           tty->termios.c_cflag & CBAUD) {
                info->serial_signals |= SerialSignal_DTR;
-               if (!(tty->termios->c_cflag & CRTSCTS) ||
+               if (!(tty->termios.c_cflag & CRTSCTS) ||
                    !test_bit(TTY_THROTTLED, &tty->flags)) {
                        info->serial_signals |= SerialSignal_RTS;
                }
@@ -895,7 +895,7 @@ static void set_termios(struct tty_struct *tty, struct ktermios *old_termios)
 
        /* Handle turning off CRTSCTS */
        if (old_termios->c_cflag & CRTSCTS &&
-           !(tty->termios->c_cflag & CRTSCTS)) {
+           !(tty->termios.c_cflag & CRTSCTS)) {
                tty->hw_stopped = 0;
                tx_release(tty);
        }
@@ -1473,7 +1473,7 @@ static void throttle(struct tty_struct * tty)
        if (I_IXOFF(tty))
                send_xchar(tty, STOP_CHAR(tty));
 
-       if (tty->termios->c_cflag & CRTSCTS) {
+       if (tty->termios.c_cflag & CRTSCTS) {
                spin_lock_irqsave(&info->lock,flags);
                info->serial_signals &= ~SerialSignal_RTS;
                set_signals(info);
@@ -1502,7 +1502,7 @@ static void unthrottle(struct tty_struct * tty)
                        send_xchar(tty, START_CHAR(tty));
        }
 
-       if (tty->termios->c_cflag & CRTSCTS) {
+       if (tty->termios.c_cflag & CRTSCTS) {
                spin_lock_irqsave(&info->lock,flags);
                info->serial_signals |= SerialSignal_RTS;
                set_signals(info);
@@ -2708,7 +2708,7 @@ static void shutdown(SLMP_INFO * info)
 
        reset_port(info);
 
-       if (!info->port.tty || info->port.tty->termios->c_cflag & HUPCL) {
+       if (!info->port.tty || info->port.tty->termios.c_cflag & HUPCL) {
                info->serial_signals &= ~(SerialSignal_DTR + SerialSignal_RTS);
                set_signals(info);
        }
@@ -2749,7 +2749,7 @@ static void program_hw(SLMP_INFO *info)
 
        get_signals(info);
 
-       if (info->netcount || (info->port.tty && info->port.tty->termios->c_cflag & CREAD) )
+       if (info->netcount || (info->port.tty && info->port.tty->termios.c_cflag & CREAD) )
                rx_start(info);
 
        spin_unlock_irqrestore(&info->lock,flags);
@@ -2762,14 +2762,14 @@ static void change_params(SLMP_INFO *info)
        unsigned cflag;
        int bits_per_char;
 
-       if (!info->port.tty || !info->port.tty->termios)
+       if (!info->port.tty)
                return;
 
        if (debug_level >= DEBUG_LEVEL_INFO)
                printk("%s(%d):%s change_params()\n",
                         __FILE__,__LINE__, info->device_name );
 
-       cflag = info->port.tty->termios->c_cflag;
+       cflag = info->port.tty->termios.c_cflag;
 
        /* if B0 rate (hangup) specified then negate DTR and RTS */
        /* otherwise assert DTR and RTS */
@@ -3306,7 +3306,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
                return 0;
        }
 
-       if (tty->termios->c_cflag & CLOCAL)
+       if (tty->termios.c_cflag & CLOCAL)
                do_clocal = true;
 
        /* Wait for carrier detect and the line to become
@@ -3332,7 +3332,7 @@ static int block_til_ready(struct tty_struct *tty, struct file *filp,
        port->blocked_open++;
 
        while (1) {
-               if (tty->termios->c_cflag & CBAUD)
+               if (tty->termios.c_cflag & CBAUD)
                        tty_port_raise_dtr_rts(port);
 
                set_current_state(TASK_INTERRUPTIBLE);
index b425c79675ad96adc187c601e36d65c2bebc3581..c6f4d711771b8d4f59b1830f6fe98b68dd69cb9d 100644 (file)
@@ -1249,21 +1249,19 @@ int tty_init_termios(struct tty_struct *tty)
        struct ktermios *tp;
        int idx = tty->index;
 
-       tp = tty->driver->termios[idx];
-       if (tp == NULL) {
-               tp = kzalloc(sizeof(struct ktermios[2]), GFP_KERNEL);
-               if (tp == NULL)
-                       return -ENOMEM;
-               memcpy(tp, &tty->driver->init_termios,
-                                               sizeof(struct ktermios));
-               tty->driver->termios[idx] = tp;
+       if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS)
+               tty->termios = tty->driver->init_termios;
+       else {
+               /* Check for lazy saved data */
+               tp = tty->driver->termios[idx];
+               if (tp != NULL)
+                       tty->termios = *tp;
+               else
+                       tty->termios = tty->driver->init_termios;
        }
-       tty->termios = tp;
-       tty->termios_locked = tp + 1;
-
        /* Compatibility until drivers always set this */
-       tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios);
-       tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios);
+       tty->termios.c_ispeed = tty_termios_input_baud_rate(&tty->termios);
+       tty->termios.c_ospeed = tty_termios_baud_rate(&tty->termios);
        return 0;
 }
 EXPORT_SYMBOL_GPL(tty_init_termios);
@@ -1407,6 +1405,9 @@ struct tty_struct *tty_init_dev(struct tty_driver *driver, int idx)
        if (retval < 0)
                goto err_deinit_tty;
 
+       if (!tty->port)
+               tty->port = driver->ports[idx];
+
        /*
         * Structures all installed ... call the ldisc open routines.
         * If we fail here just call release_tty to clean up.  No need
@@ -1436,22 +1437,24 @@ void tty_free_termios(struct tty_struct *tty)
 {
        struct ktermios *tp;
        int idx = tty->index;
-       /* Kill this flag and push into drivers for locking etc */
-       if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS) {
-               /* FIXME: Locking on ->termios array */
-               tp = tty->termios;
-               tty->driver->termios[idx] = NULL;
-               kfree(tp);
+
+       /* If the port is going to reset then it has no termios to save */
+       if (tty->driver->flags & TTY_DRIVER_RESET_TERMIOS)
+               return;
+
+       /* Stash the termios data */
+       tp = tty->driver->termios[idx];
+       if (tp == NULL) {
+               tp = kmalloc(sizeof(struct ktermios), GFP_KERNEL);
+               if (tp == NULL) {
+                       pr_warn("tty: no memory to save termios state.\n");
+                       return;
+               }
        }
+       *tp = tty->termios;
 }
 EXPORT_SYMBOL(tty_free_termios);
 
-void tty_shutdown(struct tty_struct *tty)
-{
-       tty_driver_remove_tty(tty->driver, tty);
-       tty_free_termios(tty);
-}
-EXPORT_SYMBOL(tty_shutdown);
 
 /**
  *     release_one_tty         -       release tty structure memory
@@ -1462,7 +1465,6 @@ EXPORT_SYMBOL(tty_shutdown);
  *     in use. It also gets called when setup of a device fails.
  *
  *     Locking:
- *             tty_mutex - sometimes only
  *             takes the file list lock internally when working on the list
  *     of ttys that the driver keeps.
  *
@@ -1495,11 +1497,6 @@ static void queue_release_one_tty(struct kref *kref)
 {
        struct tty_struct *tty = container_of(kref, struct tty_struct, kref);
 
-       if (tty->ops->shutdown)
-               tty->ops->shutdown(tty);
-       else
-               tty_shutdown(tty);
-
        /* The hangup queue is now free so we can reuse it rather than
           waste a chunk of memory for each port */
        INIT_WORK(&tty->hangup_work, release_one_tty);
@@ -1528,16 +1525,20 @@ EXPORT_SYMBOL(tty_kref_put);
  *     and decrement the refcount of the backing module.
  *
  *     Locking:
- *             tty_mutex - sometimes only
+ *             tty_mutex
  *             takes the file list lock internally when working on the list
  *     of ttys that the driver keeps.
- *             FIXME: should we require tty_mutex is held here ??
  *
  */
 static void release_tty(struct tty_struct *tty, int idx)
 {
        /* This should always be true but check for the moment */
        WARN_ON(tty->index != idx);
+       WARN_ON(!mutex_is_locked(&tty_mutex));
+       if (tty->ops->shutdown)
+               tty->ops->shutdown(tty);
+       tty_free_termios(tty);
+       tty_driver_remove_tty(tty->driver, tty);
 
        if (tty->link)
                tty_kref_put(tty->link);
@@ -1572,22 +1573,12 @@ static int tty_release_checks(struct tty_struct *tty, struct tty_struct *o_tty,
                                __func__, idx, tty->name);
                return -1;
        }
-       if (tty->termios != tty->driver->termios[idx]) {
-               printk(KERN_DEBUG "%s: driver.termios[%d] not termios for (%s)\n",
-                               __func__, idx, tty->name);
-               return -1;
-       }
        if (tty->driver->other) {
                if (o_tty != tty->driver->other->ttys[idx]) {
                        printk(KERN_DEBUG "%s: other->table[%d] not o_tty for (%s)\n",
                                        __func__, idx, tty->name);
                        return -1;
                }
-               if (o_tty->termios != tty->driver->other->termios[idx]) {
-                       printk(KERN_DEBUG "%s: other->termios[%d] not o_termios for (%s)\n",
-                                       __func__, idx, tty->name);
-                       return -1;
-               }
                if (o_tty->link != tty) {
                        printk(KERN_DEBUG "%s: bad pty pointers\n", __func__);
                        return -1;
@@ -1715,6 +1706,9 @@ int tty_release(struct inode *inode, struct file *filp)
         * The closing flags are now consistent with the open counts on
         * both sides, and we've completed the last operation that could
         * block, so it's safe to proceed with closing.
+        *
+        * We must *not* drop the tty_mutex until we ensure that a further
+        * entry into tty_open can not pick up this tty.
         */
        if (pty_master) {
                if (--o_tty->count < 0) {
@@ -1766,12 +1760,13 @@ int tty_release(struct inode *inode, struct file *filp)
        }
 
        mutex_unlock(&tty_mutex);
+       tty_unlock();
+       /* At this point the TTY_CLOSING flag should ensure a dead tty
+          cannot be re-opened by a racing opener */
 
        /* check whether both sides are closing ... */
-       if (!tty_closing || (o_tty && !o_tty_closing)) {
-               tty_unlock();
+       if (!tty_closing || (o_tty && !o_tty_closing))
                return 0;
-       }
 
 #ifdef TTY_DEBUG_HANGUP
        printk(KERN_DEBUG "%s: freeing tty structure...\n", __func__);
@@ -1784,12 +1779,14 @@ int tty_release(struct inode *inode, struct file *filp)
         * The release_tty function takes care of the details of clearing
         * the slots and preserving the termios structure.
         */
+       mutex_lock(&tty_mutex);
        release_tty(tty, idx);
+       mutex_unlock(&tty_mutex);
 
        /* Make this pty number available for reallocation */
        if (devpts)
                devpts_kill_index(inode, idx);
-       tty_unlock();
+
        return 0;
 }
 
@@ -3094,6 +3091,7 @@ static void destruct_tty_driver(struct kref *kref)
                kfree(p);
                cdev_del(&driver->cdev);
        }
+       kfree(driver->ports);
        kfree(driver);
 }
 
@@ -3132,6 +3130,18 @@ int tty_register_driver(struct tty_driver *driver)
                if (!p)
                        return -ENOMEM;
        }
+       /*
+        * There is too many lines in PTY and we won't need the array there
+        * since it has an ->install hook where it assigns ports properly.
+        */
+       if (driver->type != TTY_DRIVER_TYPE_PTY) {
+               driver->ports = kcalloc(driver->num, sizeof(struct tty_port *),
+                               GFP_KERNEL);
+               if (!driver->ports) {
+                       error = -ENOMEM;
+                       goto err_free_p;
+               }
+       }
 
        if (!driver->major) {
                error = alloc_chrdev_region(&dev, driver->minor_start,
@@ -3144,10 +3154,8 @@ int tty_register_driver(struct tty_driver *driver)
                dev = MKDEV(driver->major, driver->minor_start);
                error = register_chrdev_region(dev, driver->num, driver->name);
        }
-       if (error < 0) {
-               kfree(p);
-               return error;
-       }
+       if (error < 0)
+               goto err_free_p;
 
        if (p) {
                driver->ttys = (struct tty_struct **)p;
@@ -3160,13 +3168,8 @@ int tty_register_driver(struct tty_driver *driver)
        cdev_init(&driver->cdev, &tty_fops);
        driver->cdev.owner = driver->owner;
        error = cdev_add(&driver->cdev, dev, driver->num);
-       if (error) {
-               unregister_chrdev_region(dev, driver->num);
-               driver->ttys = NULL;
-               driver->termios = NULL;
-               kfree(p);
-               return error;
-       }
+       if (error)
+               goto err_unreg_char;
 
        mutex_lock(&tty_mutex);
        list_add(&driver->tty_drivers, &tty_drivers);
@@ -3193,13 +3196,14 @@ err:
        list_del(&driver->tty_drivers);
        mutex_unlock(&tty_mutex);
 
+err_unreg_char:
        unregister_chrdev_region(dev, driver->num);
        driver->ttys = NULL;
        driver->termios = NULL;
+err_free_p: /* destruct_tty_driver will free driver->ports */
        kfree(p);
        return error;
 }
-
 EXPORT_SYMBOL(tty_register_driver);
 
 /*
index a1b9a2f68567e2755871280c555f8a4f52168eb6..12b1fa0f4f867ed014d7a96eac79ccae76053c6d 100644 (file)
@@ -410,7 +410,7 @@ EXPORT_SYMBOL_GPL(tty_termios_encode_baud_rate);
 
 void tty_encode_baud_rate(struct tty_struct *tty, speed_t ibaud, speed_t obaud)
 {
-       tty_termios_encode_baud_rate(tty->termios, ibaud, obaud);
+       tty_termios_encode_baud_rate(&tty->termios, ibaud, obaud);
 }
 EXPORT_SYMBOL_GPL(tty_encode_baud_rate);
 
@@ -427,7 +427,7 @@ EXPORT_SYMBOL_GPL(tty_encode_baud_rate);
 
 speed_t tty_get_baud_rate(struct tty_struct *tty)
 {
-       speed_t baud = tty_termios_baud_rate(tty->termios);
+       speed_t baud = tty_termios_baud_rate(&tty->termios);
 
        if (baud == 38400 && tty->alt_speed) {
                if (!tty->warned) {
@@ -509,14 +509,14 @@ int tty_set_termios(struct tty_struct *tty, struct ktermios *new_termios)
        /* FIXME: we need to decide on some locking/ordering semantics
           for the set_termios notification eventually */
        mutex_lock(&tty->termios_mutex);
-       old_termios = *tty->termios;
-       *tty->termios = *new_termios;
-       unset_locked_termios(tty->termios, &old_termios, tty->termios_locked);
+       old_termios = tty->termios;
+       tty->termios = *new_termios;
+       unset_locked_termios(&tty->termios, &old_termios, &tty->termios_locked);
 
        /* See if packet mode change of state. */
        if (tty->link && tty->link->packet) {
                int extproc = (old_termios.c_lflag & EXTPROC) |
-                               (tty->termios->c_lflag & EXTPROC);
+                               (tty->termios.c_lflag & EXTPROC);
                int old_flow = ((old_termios.c_iflag & IXON) &&
                                (old_termios.c_cc[VSTOP] == '\023') &&
                                (old_termios.c_cc[VSTART] == '\021'));
@@ -542,7 +542,7 @@ int tty_set_termios(struct tty_struct *tty, struct ktermios *new_termios)
        if (tty->ops->set_termios)
                (*tty->ops->set_termios)(tty, &old_termios);
        else
-               tty_termios_copy_hw(tty->termios, &old_termios);
+               tty_termios_copy_hw(&tty->termios, &old_termios);
 
        ld = tty_ldisc_ref(tty);
        if (ld != NULL) {
@@ -578,7 +578,7 @@ static int set_termios(struct tty_struct *tty, void __user *arg, int opt)
                return retval;
 
        mutex_lock(&tty->termios_mutex);
-       memcpy(&tmp_termios, tty->termios, sizeof(struct ktermios));
+       tmp_termios = tty->termios;
        mutex_unlock(&tty->termios_mutex);
 
        if (opt & TERMIOS_TERMIO) {
@@ -632,14 +632,14 @@ static int set_termios(struct tty_struct *tty, void __user *arg, int opt)
 static void copy_termios(struct tty_struct *tty, struct ktermios *kterm)
 {
        mutex_lock(&tty->termios_mutex);
-       memcpy(kterm, tty->termios, sizeof(struct ktermios));
+       *kterm = tty->termios;
        mutex_unlock(&tty->termios_mutex);
 }
 
 static void copy_termios_locked(struct tty_struct *tty, struct ktermios *kterm)
 {
        mutex_lock(&tty->termios_mutex);
-       memcpy(kterm, tty->termios_locked, sizeof(struct ktermios));
+       *kterm = tty->termios_locked;
        mutex_unlock(&tty->termios_mutex);
 }
 
@@ -707,16 +707,16 @@ static int get_sgflags(struct tty_struct *tty)
 {
        int flags = 0;
 
-       if (!(tty->termios->c_lflag & ICANON)) {
-               if (tty->termios->c_lflag & ISIG)
+       if (!(tty->termios.c_lflag & ICANON)) {
+               if (tty->termios.c_lflag & ISIG)
                        flags |= 0x02;          /* cbreak */
                else
                        flags |= 0x20;          /* raw */
        }
-       if (tty->termios->c_lflag & ECHO)
+       if (tty->termios.c_lflag & ECHO)
                flags |= 0x08;                  /* echo */
-       if (tty->termios->c_oflag & OPOST)
-               if (tty->termios->c_oflag & ONLCR)
+       if (tty->termios.c_oflag & OPOST)
+               if (tty->termios.c_oflag & ONLCR)
                        flags |= 0x10;          /* crmod */
        return flags;
 }
@@ -726,10 +726,10 @@ static int get_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
        struct sgttyb tmp;
 
        mutex_lock(&tty->termios_mutex);
-       tmp.sg_ispeed = tty->termios->c_ispeed;
-       tmp.sg_ospeed = tty->termios->c_ospeed;
-       tmp.sg_erase = tty->termios->c_cc[VERASE];
-       tmp.sg_kill = tty->termios->c_cc[VKILL];
+       tmp.sg_ispeed = tty->termios.c_ispeed;
+       tmp.sg_ospeed = tty->termios.c_ospeed;
+       tmp.sg_erase = tty->termios.c_cc[VERASE];
+       tmp.sg_kill = tty->termios.c_cc[VKILL];
        tmp.sg_flags = get_sgflags(tty);
        mutex_unlock(&tty->termios_mutex);
 
@@ -787,7 +787,7 @@ static int set_sgttyb(struct tty_struct *tty, struct sgttyb __user *sgttyb)
                return -EFAULT;
 
        mutex_lock(&tty->termios_mutex);
-       termios = *tty->termios;
+       termios = tty->termios;
        termios.c_cc[VERASE] = tmp.sg_erase;
        termios.c_cc[VKILL] = tmp.sg_kill;
        set_sgflags(&termios, tmp.sg_flags);
@@ -808,12 +808,12 @@ static int get_tchars(struct tty_struct *tty, struct tchars __user *tchars)
        struct tchars tmp;
 
        mutex_lock(&tty->termios_mutex);
-       tmp.t_intrc = tty->termios->c_cc[VINTR];
-       tmp.t_quitc = tty->termios->c_cc[VQUIT];
-       tmp.t_startc = tty->termios->c_cc[VSTART];
-       tmp.t_stopc = tty->termios->c_cc[VSTOP];
-       tmp.t_eofc = tty->termios->c_cc[VEOF];
-       tmp.t_brkc = tty->termios->c_cc[VEOL2]; /* what is brkc anyway? */
+       tmp.t_intrc = tty->termios.c_cc[VINTR];
+       tmp.t_quitc = tty->termios.c_cc[VQUIT];
+       tmp.t_startc = tty->termios.c_cc[VSTART];
+       tmp.t_stopc = tty->termios.c_cc[VSTOP];
+       tmp.t_eofc = tty->termios.c_cc[VEOF];
+       tmp.t_brkc = tty->termios.c_cc[VEOL2];  /* what is brkc anyway? */
        mutex_unlock(&tty->termios_mutex);
        return copy_to_user(tchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
 }
@@ -825,12 +825,12 @@ static int set_tchars(struct tty_struct *tty, struct tchars __user *tchars)
        if (copy_from_user(&tmp, tchars, sizeof(tmp)))
                return -EFAULT;
        mutex_lock(&tty->termios_mutex);
-       tty->termios->c_cc[VINTR] = tmp.t_intrc;
-       tty->termios->c_cc[VQUIT] = tmp.t_quitc;
-       tty->termios->c_cc[VSTART] = tmp.t_startc;
-       tty->termios->c_cc[VSTOP] = tmp.t_stopc;
-       tty->termios->c_cc[VEOF] = tmp.t_eofc;
-       tty->termios->c_cc[VEOL2] = tmp.t_brkc; /* what is brkc anyway? */
+       tty->termios.c_cc[VINTR] = tmp.t_intrc;
+       tty->termios.c_cc[VQUIT] = tmp.t_quitc;
+       tty->termios.c_cc[VSTART] = tmp.t_startc;
+       tty->termios.c_cc[VSTOP] = tmp.t_stopc;
+       tty->termios.c_cc[VEOF] = tmp.t_eofc;
+       tty->termios.c_cc[VEOL2] = tmp.t_brkc;  /* what is brkc anyway? */
        mutex_unlock(&tty->termios_mutex);
        return 0;
 }
@@ -842,14 +842,14 @@ static int get_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
        struct ltchars tmp;
 
        mutex_lock(&tty->termios_mutex);
-       tmp.t_suspc = tty->termios->c_cc[VSUSP];
+       tmp.t_suspc = tty->termios.c_cc[VSUSP];
        /* what is dsuspc anyway? */
-       tmp.t_dsuspc = tty->termios->c_cc[VSUSP];
-       tmp.t_rprntc = tty->termios->c_cc[VREPRINT];
+       tmp.t_dsuspc = tty->termios.c_cc[VSUSP];
+       tmp.t_rprntc = tty->termios.c_cc[VREPRINT];
        /* what is flushc anyway? */
-       tmp.t_flushc = tty->termios->c_cc[VEOL2];
-       tmp.t_werasc = tty->termios->c_cc[VWERASE];
-       tmp.t_lnextc = tty->termios->c_cc[VLNEXT];
+       tmp.t_flushc = tty->termios.c_cc[VEOL2];
+       tmp.t_werasc = tty->termios.c_cc[VWERASE];
+       tmp.t_lnextc = tty->termios.c_cc[VLNEXT];
        mutex_unlock(&tty->termios_mutex);
        return copy_to_user(ltchars, &tmp, sizeof(tmp)) ? -EFAULT : 0;
 }
@@ -862,14 +862,14 @@ static int set_ltchars(struct tty_struct *tty, struct ltchars __user *ltchars)
                return -EFAULT;
 
        mutex_lock(&tty->termios_mutex);
-       tty->termios->c_cc[VSUSP] = tmp.t_suspc;
+       tty->termios.c_cc[VSUSP] = tmp.t_suspc;
        /* what is dsuspc anyway? */
-       tty->termios->c_cc[VEOL2] = tmp.t_dsuspc;
-       tty->termios->c_cc[VREPRINT] = tmp.t_rprntc;
+       tty->termios.c_cc[VEOL2] = tmp.t_dsuspc;
+       tty->termios.c_cc[VREPRINT] = tmp.t_rprntc;
        /* what is flushc anyway? */
-       tty->termios->c_cc[VEOL2] = tmp.t_flushc;
-       tty->termios->c_cc[VWERASE] = tmp.t_werasc;
-       tty->termios->c_cc[VLNEXT] = tmp.t_lnextc;
+       tty->termios.c_cc[VEOL2] = tmp.t_flushc;
+       tty->termios.c_cc[VWERASE] = tmp.t_werasc;
+       tty->termios.c_cc[VLNEXT] = tmp.t_lnextc;
        mutex_unlock(&tty->termios_mutex);
        return 0;
 }
@@ -920,12 +920,12 @@ static int tty_change_softcar(struct tty_struct *tty, int arg)
        struct ktermios old;
 
        mutex_lock(&tty->termios_mutex);
-       old = *tty->termios;
-       tty->termios->c_cflag &= ~CLOCAL;
-       tty->termios->c_cflag |= bit;
+       old = tty->termios;
+       tty->termios.c_cflag &= ~CLOCAL;
+       tty->termios.c_cflag |= bit;
        if (tty->ops->set_termios)
                tty->ops->set_termios(tty, &old);
-       if ((tty->termios->c_cflag & CLOCAL) != bit)
+       if ((tty->termios.c_cflag & CLOCAL) != bit)
                ret = -EINVAL;
        mutex_unlock(&tty->termios_mutex);
        return ret;
@@ -1031,7 +1031,7 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
                                               (struct termios __user *) arg))
                        return -EFAULT;
                mutex_lock(&real_tty->termios_mutex);
-               memcpy(real_tty->termios_locked, &kterm, sizeof(struct ktermios));
+               real_tty->termios_locked = kterm;
                mutex_unlock(&real_tty->termios_mutex);
                return 0;
 #else
@@ -1048,7 +1048,7 @@ int tty_mode_ioctl(struct tty_struct *tty, struct file *file,
                                               (struct termios __user *) arg))
                        return -EFAULT;
                mutex_lock(&real_tty->termios_mutex);
-               memcpy(real_tty->termios_locked, &kterm, sizeof(struct ktermios));
+               real_tty->termios_locked = kterm;
                mutex_unlock(&real_tty->termios_mutex);
                return ret;
 #endif
index 6f99c9959f0c8f5db9c950810a8196e0907415b2..3d0687197d09174677216d3b4f70cf6832e947c8 100644 (file)
@@ -413,7 +413,7 @@ EXPORT_SYMBOL_GPL(tty_ldisc_flush);
 static void tty_set_termios_ldisc(struct tty_struct *tty, int num)
 {
        mutex_lock(&tty->termios_mutex);
-       tty->termios->c_line = num;
+       tty->termios.c_line = num;
        mutex_unlock(&tty->termios_mutex);
 }
 
@@ -722,9 +722,9 @@ enable:
 static void tty_reset_termios(struct tty_struct *tty)
 {
        mutex_lock(&tty->termios_mutex);
-       *tty->termios = tty->driver->init_termios;
-       tty->termios->c_ispeed = tty_termios_input_baud_rate(tty->termios);
-       tty->termios->c_ospeed = tty_termios_baud_rate(tty->termios);
+       tty->termios = tty->driver->init_termios;
+       tty->termios.c_ispeed = tty_termios_input_baud_rate(&tty->termios);
+       tty->termios.c_ospeed = tty_termios_baud_rate(&tty->termios);
        mutex_unlock(&tty->termios_mutex);
 }
 
@@ -846,7 +846,7 @@ retry:
 
                if (reset == 0) {
 
-                       if (!tty_ldisc_reinit(tty, tty->termios->c_line))
+                       if (!tty_ldisc_reinit(tty, tty->termios.c_line))
                                err = tty_ldisc_open(tty, tty->ldisc);
                        else
                                err = 1;
@@ -912,7 +912,6 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty)
         * race with the set_ldisc code path.
         */
 
-       tty_unlock();
        tty_ldisc_halt(tty);
        tty_ldisc_flush_works(tty);
        tty_lock();
@@ -930,6 +929,8 @@ void tty_ldisc_release(struct tty_struct *tty, struct tty_struct *o_tty)
        tty_set_termios_ldisc(tty, N_TTY);
        mutex_unlock(&tty->ldisc_mutex);
 
+       tty_unlock();
+
        /* This will need doing differently if we need to lock */
        if (o_tty)
                tty_ldisc_release(o_tty, NULL);
index bf6e238146ae40acd4ac8ea2f517574870366590..edcb827c1286d6f0db94abc36bfc628324dc0453 100644 (file)
@@ -33,6 +33,15 @@ void tty_port_init(struct tty_port *port)
 }
 EXPORT_SYMBOL(tty_port_init);
 
+struct device *tty_port_register_device(struct tty_port *port,
+               struct tty_driver *driver, unsigned index,
+               struct device *device)
+{
+       driver->ports[index] = port;
+       return tty_register_device(driver, index, device);
+}
+EXPORT_SYMBOL_GPL(tty_port_register_device);
+
 int tty_port_alloc_xmit_buf(struct tty_port *port)
 {
        /* We may sleep in get_zeroed_page() */
@@ -246,7 +255,7 @@ int tty_port_block_til_ready(struct tty_port *port,
        }
        if (filp->f_flags & O_NONBLOCK) {
                /* Indicate we are open */
-               if (tty->termios->c_cflag & CBAUD)
+               if (tty->termios.c_cflag & CBAUD)
                        tty_port_raise_dtr_rts(port);
                port->flags |= ASYNC_NORMAL_ACTIVE;
                return 0;
@@ -270,7 +279,7 @@ int tty_port_block_til_ready(struct tty_port *port,
 
        while (1) {
                /* Indicate we are open */
-               if (tty->termios->c_cflag & CBAUD)
+               if (tty->termios.c_cflag & CBAUD)
                        tty_port_raise_dtr_rts(port);
 
                prepare_to_wait(&port->open_wait, &wait, TASK_INTERRUPTIBLE);
@@ -369,7 +378,7 @@ int tty_port_close_start(struct tty_port *port,
 
        /* Drop DTR/RTS if HUPCL is set. This causes any attached modem to
           hang up the line */
-       if (tty->termios->c_cflag & HUPCL)
+       if (tty->termios.c_cflag & HUPCL)
                tty_port_lower_dtr_rts(port);
 
        /* Don't call port->drop for the last reference. Callers will want
@@ -413,6 +422,14 @@ void tty_port_close(struct tty_port *port, struct tty_struct *tty,
 }
 EXPORT_SYMBOL(tty_port_close);
 
+int tty_port_install(struct tty_port *port, struct tty_driver *driver,
+               struct tty_struct *tty)
+{
+       tty->port = port;
+       return tty_standard_install(driver, tty);
+}
+EXPORT_SYMBOL_GPL(tty_port_install);
+
 int tty_port_open(struct tty_port *port, struct tty_struct *tty,
                                                        struct file *filp)
 {
index 48cc6f25cfd39c319cea40e5d70232ca39c3c964..681765baef69345f568ce29bce068601b812db56 100644 (file)
@@ -119,6 +119,7 @@ static const int NR_TYPES = ARRAY_SIZE(max_vals);
 
 static struct input_handler kbd_handler;
 static DEFINE_SPINLOCK(kbd_event_lock);
+static DEFINE_SPINLOCK(led_lock);
 static unsigned long key_down[BITS_TO_LONGS(KEY_CNT)]; /* keyboard key bitmap */
 static unsigned char shift_down[NR_SHIFT];             /* shift state counters.. */
 static bool dead_key_next;
@@ -310,7 +311,7 @@ static void put_queue(struct vc_data *vc, int ch)
 
        if (tty) {
                tty_insert_flip_char(tty, ch, 0);
-               con_schedule_flip(tty);
+               tty_schedule_flip(tty);
        }
 }
 
@@ -325,7 +326,7 @@ static void puts_queue(struct vc_data *vc, char *cp)
                tty_insert_flip_char(tty, *cp, 0);
                cp++;
        }
-       con_schedule_flip(tty);
+       tty_schedule_flip(tty);
 }
 
 static void applkey(struct vc_data *vc, int key, char mode)
@@ -586,7 +587,7 @@ static void fn_send_intr(struct vc_data *vc)
        if (!tty)
                return;
        tty_insert_flip_char(tty, 0, TTY_BREAK);
-       con_schedule_flip(tty);
+       tty_schedule_flip(tty);
 }
 
 static void fn_scroll_forw(struct vc_data *vc)
@@ -984,7 +985,7 @@ static void k_brl(struct vc_data *vc, unsigned char value, char up_flag)
  * or (ii) whatever pattern of lights people want to show using KDSETLED,
  * or (iii) specified bits of specified words in kernel memory.
  */
-unsigned char getledstate(void)
+static unsigned char getledstate(void)
 {
        return ledstate;
 }
@@ -992,7 +993,7 @@ unsigned char getledstate(void)
 void setledstate(struct kbd_struct *kbd, unsigned int led)
 {
         unsigned long flags;
-        spin_lock_irqsave(&kbd_event_lock, flags);
+        spin_lock_irqsave(&led_lock, flags);
        if (!(led & ~7)) {
                ledioctl = led;
                kbd->ledmode = LED_SHOW_IOCTL;
@@ -1000,7 +1001,7 @@ void setledstate(struct kbd_struct *kbd, unsigned int led)
                kbd->ledmode = LED_SHOW_FLAGS;
 
        set_leds();
-       spin_unlock_irqrestore(&kbd_event_lock, flags);
+       spin_unlock_irqrestore(&led_lock, flags);
 }
 
 static inline unsigned char getleds(void)
@@ -1049,13 +1050,13 @@ static int kbd_update_leds_helper(struct input_handle *handle, void *data)
  */
 int vt_get_leds(int console, int flag)
 {
-       unsigned long flags;
        struct kbd_struct * kbd = kbd_table + console;
        int ret;
+       unsigned long flags;
 
-       spin_lock_irqsave(&kbd_event_lock, flags);
+       spin_lock_irqsave(&led_lock, flags);
        ret = vc_kbd_led(kbd, flag);
-       spin_unlock_irqrestore(&kbd_event_lock, flags);
+       spin_unlock_irqrestore(&led_lock, flags);
 
        return ret;
 }
@@ -1091,11 +1092,11 @@ void vt_set_led_state(int console, int leds)
 void vt_kbd_con_start(int console)
 {
        struct kbd_struct * kbd = kbd_table + console;
-/*     unsigned long flags; */
-/*     spin_lock_irqsave(&kbd_event_lock, flags); */
+       unsigned long flags;
+       spin_lock_irqsave(&led_lock, flags);
        clr_vc_kbd_led(kbd, VC_SCROLLOCK);
        set_leds();
-/*     spin_unlock_irqrestore(&kbd_event_lock, flags); */
+       spin_unlock_irqrestore(&led_lock, flags);
 }
 
 /**
@@ -1104,21 +1105,15 @@ void vt_kbd_con_start(int console)
  *
  *     Handle console stop. This is a wrapper for the VT layer
  *     so that we can keep kbd knowledge internal
- *
- *     FIXME: We eventually need to hold the kbd lock here to protect
- *     the LED updating. We can't do it yet because fn_hold calls stop_tty
- *     and start_tty under the kbd_event_lock, while normal tty paths
- *     don't hold the lock. We probably need to split out an LED lock
- *     but not during an -rc release!
  */
 void vt_kbd_con_stop(int console)
 {
        struct kbd_struct * kbd = kbd_table + console;
-/*     unsigned long flags; */
-/*     spin_lock_irqsave(&kbd_event_lock, flags); */
+       unsigned long flags;
+       spin_lock_irqsave(&led_lock, flags);
        set_vc_kbd_led(kbd, VC_SCROLLOCK);
        set_leds();
-/*     spin_unlock_irqrestore(&kbd_event_lock, flags); */
+       spin_unlock_irqrestore(&led_lock, flags);
 }
 
 /*
@@ -1130,7 +1125,12 @@ void vt_kbd_con_stop(int console)
  */
 static void kbd_bh(unsigned long dummy)
 {
-       unsigned char leds = getleds();
+       unsigned char leds;
+       unsigned long flags;
+       
+       spin_lock_irqsave(&led_lock, flags);
+       leds = getleds();
+       spin_unlock_irqrestore(&led_lock, flags);
 
        if (leds != ledstate) {
                input_handler_for_each_handle(&kbd_handler, &leds,
@@ -2035,11 +2035,11 @@ int vt_do_kdskled(int console, int cmd, unsigned long arg, int perm)
                        return -EPERM;
                if (arg & ~0x77)
                        return -EINVAL;
-                spin_lock_irqsave(&kbd_event_lock, flags);
+                spin_lock_irqsave(&led_lock, flags);
                kbd->ledflagstate = (arg & 7);
                kbd->default_ledflagstate = ((arg >> 4) & 7);
                set_leds();
-                spin_unlock_irqrestore(&kbd_event_lock, flags);
+                spin_unlock_irqrestore(&led_lock, flags);
                return 0;
 
        /* the ioctls below only set the lights, not the functions */
@@ -2134,8 +2134,10 @@ void vt_reset_keyboard(int console)
        clr_vc_kbd_mode(kbd, VC_CRLF);
        kbd->lockstate = 0;
        kbd->slockstate = 0;
+       spin_lock(&led_lock);
        kbd->ledmode = LED_SHOW_FLAGS;
        kbd->ledflagstate = kbd->default_ledflagstate;
+       spin_unlock(&led_lock);
        /* do not do set_leds here because this causes an endless tasklet loop
           when the keyboard hasn't been initialized yet */
        spin_unlock_irqrestore(&kbd_event_lock, flags);
index 84cbf298c0947c192b98ead8d71c4362458da459..e07ded30fc7f00b5d5b74d8d8fdb8a3fc64bab0f 100644 (file)
@@ -1380,7 +1380,7 @@ static void respond_string(const char *p, struct tty_struct *tty)
                tty_insert_flip_char(tty, *p, 0);
                p++;
        }
-       con_schedule_flip(tty);
+       tty_schedule_flip(tty);
 }
 
 static void cursor_report(struct vc_data *vc, struct tty_struct *tty)
@@ -2792,41 +2792,52 @@ static void con_flush_chars(struct tty_struct *tty)
 /*
  * Allocate the console screen memory.
  */
-static int con_open(struct tty_struct *tty, struct file *filp)
+static int con_install(struct tty_driver *driver, struct tty_struct *tty)
 {
        unsigned int currcons = tty->index;
-       int ret = 0;
+       struct vc_data *vc;
+       int ret;
 
        console_lock();
-       if (tty->driver_data == NULL) {
-               ret = vc_allocate(currcons);
-               if (ret == 0) {
-                       struct vc_data *vc = vc_cons[currcons].d;
+       ret = vc_allocate(currcons);
+       if (ret)
+               goto unlock;
 
-                       /* Still being freed */
-                       if (vc->port.tty) {
-                               console_unlock();
-                               return -ERESTARTSYS;
-                       }
-                       tty->driver_data = vc;
-                       vc->port.tty = tty;
+       vc = vc_cons[currcons].d;
 
-                       if (!tty->winsize.ws_row && !tty->winsize.ws_col) {
-                               tty->winsize.ws_row = vc_cons[currcons].d->vc_rows;
-                               tty->winsize.ws_col = vc_cons[currcons].d->vc_cols;
-                       }
-                       if (vc->vc_utf)
-                               tty->termios->c_iflag |= IUTF8;
-                       else
-                               tty->termios->c_iflag &= ~IUTF8;
-                       console_unlock();
-                       return ret;
-               }
+       /* Still being freed */
+       if (vc->port.tty) {
+               ret = -ERESTARTSYS;
+               goto unlock;
        }
+
+       ret = tty_port_install(&vc->port, driver, tty);
+       if (ret)
+               goto unlock;
+
+       tty->driver_data = vc;
+       vc->port.tty = tty;
+
+       if (!tty->winsize.ws_row && !tty->winsize.ws_col) {
+               tty->winsize.ws_row = vc_cons[currcons].d->vc_rows;
+               tty->winsize.ws_col = vc_cons[currcons].d->vc_cols;
+       }
+       if (vc->vc_utf)
+               tty->termios.c_iflag |= IUTF8;
+       else
+               tty->termios.c_iflag &= ~IUTF8;
+unlock:
        console_unlock();
        return ret;
 }
 
+static int con_open(struct tty_struct *tty, struct file *filp)
+{
+       /* everything done in install */
+       return 0;
+}
+
+
 static void con_close(struct tty_struct *tty, struct file *filp)
 {
        /* Nothing to do - we defer to shutdown */
@@ -2839,7 +2850,6 @@ static void con_shutdown(struct tty_struct *tty)
        console_lock();
        vc->port.tty = NULL;
        console_unlock();
-       tty_shutdown(tty);
 }
 
 static int default_italic_color    = 2; // green (ASCII)
@@ -2947,6 +2957,7 @@ static int __init con_init(void)
 console_initcall(con_init);
 
 static const struct tty_operations con_ops = {
+       .install = con_install,
        .open = con_open,
        .close = con_close,
        .write = con_write,
index 56d6bf66848894b76564ba452e00d6cf37f13416..18f4e62aaa75863b817d94842caf99f00fa2b069 100644 (file)
@@ -826,7 +826,7 @@ static void acm_tty_set_termios(struct tty_struct *tty,
                                                struct ktermios *termios_old)
 {
        struct acm *acm = tty->driver_data;
-       struct ktermios *termios = tty->termios;
+       struct ktermios *termios = &tty->termios;
        struct usb_cdc_line_coding newline;
        int newctrl = acm->ctrlout;
 
index f8ce97d8b0ad3c5beb79868a35b0dbfe8495368c..3b98fb733362d21ad994f6f5a7950312d78e2f1b 100644 (file)
@@ -215,7 +215,7 @@ static void ark3116_release(struct usb_serial *serial)
 
 static void ark3116_init_termios(struct tty_struct *tty)
 {
-       struct ktermios *termios = tty->termios;
+       struct ktermios *termios = &tty->termios;
        *termios = tty_std_termios;
        termios->c_cflag = B9600 | CS8
                                      | CREAD | HUPCL | CLOCAL;
@@ -229,7 +229,7 @@ static void ark3116_set_termios(struct tty_struct *tty,
 {
        struct usb_serial *serial = port->serial;
        struct ark3116_private *priv = usb_get_serial_port_data(port);
-       struct ktermios *termios = tty->termios;
+       struct ktermios *termios = &tty->termios;
        unsigned int cflag = termios->c_cflag;
        int bps = tty_get_baud_rate(tty);
        int quot;
index 6b7365632951c6c8735c25fcec0c69aa9a8026c8..a46df73ee96e34310f9a1640d6c88cd89c3be09c 100644 (file)
@@ -307,7 +307,7 @@ static void belkin_sa_set_termios(struct tty_struct *tty,
        unsigned long control_state;
        int bad_flow_control;
        speed_t baud;
-       struct ktermios *termios = tty->termios;
+       struct ktermios *termios = &tty->termios;
 
        iflag = termios->c_iflag;
        cflag = termios->c_cflag;
index 1e71079ce33b7128c116f602d865428297804da7..ba5e07e188a0aa585aee873a7377e73e5b15385e 100644 (file)
@@ -469,7 +469,7 @@ static void cp210x_get_termios(struct tty_struct *tty,
 
        if (tty) {
                cp210x_get_termios_port(tty->driver_data,
-                       &tty->termios->c_cflag, &baud);
+                       &tty->termios.c_cflag, &baud);
                tty_encode_baud_rate(tty, baud, baud);
        }
 
@@ -631,7 +631,7 @@ static void cp210x_change_speed(struct tty_struct *tty,
 {
        u32 baud;
 
-       baud = tty->termios->c_ospeed;
+       baud = tty->termios.c_ospeed;
 
        /* This maps the requested rate to a rate valid on cp2102 or cp2103,
         * or to an arbitrary rate in [1M,2M].
@@ -665,10 +665,10 @@ static void cp210x_set_termios(struct tty_struct *tty,
        if (!tty)
                return;
 
-       cflag = tty->termios->c_cflag;
+       cflag = tty->termios.c_cflag;
        old_cflag = old_termios->c_cflag;
 
-       if (tty->termios->c_ospeed != old_termios->c_ospeed)
+       if (tty->termios.c_ospeed != old_termios->c_ospeed)
                cp210x_change_speed(tty, port, old_termios);
 
        /* If the number of data bits is to be updated */
index b78c34eb5d3f6f976aac101eb15094e8f99370e4..be34f153e56616462aa686611e284e492d1bc60b 100644 (file)
@@ -922,38 +922,38 @@ static void cypress_set_termios(struct tty_struct *tty,
           early enough */
        if (!priv->termios_initialized) {
                if (priv->chiptype == CT_EARTHMATE) {
-                       *(tty->termios) = tty_std_termios;
-                       tty->termios->c_cflag = B4800 | CS8 | CREAD | HUPCL |
+                       tty->termios = tty_std_termios;
+                       tty->termios.c_cflag = B4800 | CS8 | CREAD | HUPCL |
                                CLOCAL;
-                       tty->termios->c_ispeed = 4800;
-                       tty->termios->c_ospeed = 4800;
+                       tty->termios.c_ispeed = 4800;
+                       tty->termios.c_ospeed = 4800;
                } else if (priv->chiptype == CT_CYPHIDCOM) {
-                       *(tty->termios) = tty_std_termios;
-                       tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL |
+                       tty->termios = tty_std_termios;
+                       tty->termios.c_cflag = B9600 | CS8 | CREAD | HUPCL |
                                CLOCAL;
-                       tty->termios->c_ispeed = 9600;
-                       tty->termios->c_ospeed = 9600;
+                       tty->termios.c_ispeed = 9600;
+                       tty->termios.c_ospeed = 9600;
                } else if (priv->chiptype == CT_CA42V2) {
-                       *(tty->termios) = tty_std_termios;
-                       tty->termios->c_cflag = B9600 | CS8 | CREAD | HUPCL |
+                       tty->termios = tty_std_termios;
+                       tty->termios.c_cflag = B9600 | CS8 | CREAD | HUPCL |
                                CLOCAL;
-                       tty->termios->c_ispeed = 9600;
-                       tty->termios->c_ospeed = 9600;
+                       tty->termios.c_ispeed = 9600;
+                       tty->termios.c_ospeed = 9600;
                }
                priv->termios_initialized = 1;
        }
        spin_unlock_irqrestore(&priv->lock, flags);
 
        /* Unsupported features need clearing */
-       tty->termios->c_cflag &= ~(CMSPAR|CRTSCTS);
+       tty->termios.c_cflag &= ~(CMSPAR|CRTSCTS);
 
-       cflag = tty->termios->c_cflag;
-       iflag = tty->termios->c_iflag;
+       cflag = tty->termios.c_cflag;
+       iflag = tty->termios.c_iflag;
 
        /* check if there are new settings */
        if (old_termios) {
                spin_lock_irqsave(&priv->lock, flags);
-               priv->tmp_termios = *(tty->termios);
+               priv->tmp_termios = tty->termios;
                spin_unlock_irqrestore(&priv->lock, flags);
        }
 
@@ -1021,7 +1021,7 @@ static void cypress_set_termios(struct tty_struct *tty,
                                "4800bps.");
                /* define custom termios settings for NMEA protocol */
 
-               tty->termios->c_iflag /* input modes - */
+               tty->termios.c_iflag /* input modes - */
                        &= ~(IGNBRK  /* disable ignore break */
                        | BRKINT     /* disable break causes interrupt */
                        | PARMRK     /* disable mark parity errors */
@@ -1031,10 +1031,10 @@ static void cypress_set_termios(struct tty_struct *tty,
                        | ICRNL      /* disable translate CR to NL */
                        | IXON);     /* disable enable XON/XOFF flow control */
 
-               tty->termios->c_oflag /* output modes */
+               tty->termios.c_oflag /* output modes */
                        &= ~OPOST;    /* disable postprocess output char */
 
-               tty->termios->c_lflag /* line discipline modes */
+               tty->termios.c_lflag /* line discipline modes */
                        &= ~(ECHO     /* disable echo input characters */
                        | ECHONL      /* disable echo new line */
                        | ICANON      /* disable erase, kill, werase, and rprnt
@@ -1200,7 +1200,7 @@ static void cypress_read_int_callback(struct urb *urb)
 
        /* hangup, as defined in acm.c... this might be a bad place for it
         * though */
-       if (tty && !(tty->termios->c_cflag & CLOCAL) &&
+       if (tty && !(tty->termios.c_cflag & CLOCAL) &&
                        !(priv->current_status & UART_CD)) {
                dbg("%s - calling hangup", __func__);
                tty_hangup(tty);
index b5cd838093ef58be7129ff9f78bcb814fc697da0..afd9d2ec577ba02f32afbe4e396252643e29ec0d 100644 (file)
@@ -687,8 +687,8 @@ static void digi_set_termios(struct tty_struct *tty,
                struct usb_serial_port *port, struct ktermios *old_termios)
 {
        struct digi_port *priv = usb_get_serial_port_data(port);
-       unsigned int iflag = tty->termios->c_iflag;
-       unsigned int cflag = tty->termios->c_cflag;
+       unsigned int iflag = tty->termios.c_iflag;
+       unsigned int cflag = tty->termios.c_cflag;
        unsigned int old_iflag = old_termios->c_iflag;
        unsigned int old_cflag = old_termios->c_cflag;
        unsigned char buf[32];
@@ -709,7 +709,7 @@ static void digi_set_termios(struct tty_struct *tty,
                        /* don't set RTS if using hardware flow control */
                        /* and throttling input */
                        modem_signals = TIOCM_DTR;
-                       if (!(tty->termios->c_cflag & CRTSCTS) ||
+                       if (!(tty->termios.c_cflag & CRTSCTS) ||
                            !test_bit(TTY_THROTTLED, &tty->flags))
                                modem_signals |= TIOCM_RTS;
                        digi_set_modem_signals(port, modem_signals, 1);
@@ -748,7 +748,7 @@ static void digi_set_termios(struct tty_struct *tty,
                }
        }
        /* set parity */
-       tty->termios->c_cflag &= ~CMSPAR;
+       tty->termios.c_cflag &= ~CMSPAR;
 
        if ((cflag&(PARENB|PARODD)) != (old_cflag&(PARENB|PARODD))) {
                if (cflag&PARENB) {
@@ -1124,8 +1124,8 @@ static int digi_open(struct tty_struct *tty, struct usb_serial_port *port)
 
        /* set termios settings */
        if (tty) {
-               not_termios.c_cflag = ~tty->termios->c_cflag;
-               not_termios.c_iflag = ~tty->termios->c_iflag;
+               not_termios.c_cflag = ~tty->termios.c_cflag;
+               not_termios.c_iflag = ~tty->termios.c_iflag;
                digi_set_termios(tty, port, &not_termios);
        }
        return 0;
@@ -1500,7 +1500,7 @@ static int digi_read_oob_callback(struct urb *urb)
 
                rts = 0;
                if (tty)
-                       rts = tty->termios->c_cflag & CRTSCTS;
+                       rts = tty->termios.c_cflag & CRTSCTS;
                
                if (tty && opcode == DIGI_CMD_READ_INPUT_SIGNALS) {
                        spin_lock(&priv->dp_port_lock);
index cdf61dd0731837fb0acf62fc6cd44f0a199ef38f..34e86383090a846e2f843a716ff047bde9c59390 100644 (file)
@@ -87,7 +87,7 @@ static int empeg_startup(struct usb_serial *serial)
 
 static void empeg_init_termios(struct tty_struct *tty)
 {
-       struct ktermios *termios = tty->termios;
+       struct ktermios *termios = &tty->termios;
 
        /*
         * The empeg-car player wants these particular tty settings.
index 499b15fd82f162e788afefba9ec50271f9cf94d0..79451ee12ca08c451e4c2ad75f25823126ffce69 100644 (file)
@@ -173,10 +173,11 @@ static void f81232_set_termios(struct tty_struct *tty,
        /* FIXME - Stubbed out for now */
 
        /* Don't change anything if nothing has changed */
-       if (!tty_termios_hw_change(tty->termios, old_termios))
+       if (!tty_termios_hw_change(&tty->termios, old_termios))
                return;
 
        /* Do the real work here... */
+       tty_termios_copy_hw(&tty->termios, old_termios);
 }
 
 static int f81232_tiocmget(struct tty_struct *tty)
index bc912e5a3bebddf3073fe17e015b6195be3708be..4b8b41a3351f7004c294d7a31c75d062fc7c6dda 100644 (file)
@@ -2081,7 +2081,7 @@ static void ftdi_set_termios(struct tty_struct *tty,
 {
        struct usb_device *dev = port->serial->dev;
        struct ftdi_private *priv = usb_get_serial_port_data(port);
-       struct ktermios *termios = tty->termios;
+       struct ktermios *termios = &tty->termios;
        unsigned int cflag = termios->c_cflag;
        __u16 urb_value; /* will hold the new flags */
 
index e1f5ccd1e8f8c64a49e12d9ff3463d60e4f9fb01..f435575c4e6e256382d29e6eff05c5c0c00293d6 100644 (file)
@@ -1458,7 +1458,7 @@ static void edge_throttle(struct tty_struct *tty)
        }
 
        /* if we are implementing RTS/CTS, toggle that line */
-       if (tty->termios->c_cflag & CRTSCTS) {
+       if (tty->termios.c_cflag & CRTSCTS) {
                edge_port->shadowMCR &= ~MCR_RTS;
                status = send_cmd_write_uart_register(edge_port, MCR,
                                                        edge_port->shadowMCR);
@@ -1497,7 +1497,7 @@ static void edge_unthrottle(struct tty_struct *tty)
                        return;
        }
        /* if we are implementing RTS/CTS, toggle that line */
-       if (tty->termios->c_cflag & CRTSCTS) {
+       if (tty->termios.c_cflag & CRTSCTS) {
                edge_port->shadowMCR |= MCR_RTS;
                send_cmd_write_uart_register(edge_port, MCR,
                                                edge_port->shadowMCR);
@@ -1516,9 +1516,9 @@ static void edge_set_termios(struct tty_struct *tty,
        struct edgeport_port *edge_port = usb_get_serial_port_data(port);
        unsigned int cflag;
 
-       cflag = tty->termios->c_cflag;
+       cflag = tty->termios.c_cflag;
        dbg("%s - clfag %08x iflag %08x", __func__,
-           tty->termios->c_cflag, tty->termios->c_iflag);
+           tty->termios.c_cflag, tty->termios.c_iflag);
        dbg("%s - old clfag %08x old iflag %08x", __func__,
            old_termios->c_cflag, old_termios->c_iflag);
 
@@ -1987,7 +1987,7 @@ static void process_rcvd_status(struct edgeport_serial *edge_serial,
                tty = tty_port_tty_get(&edge_port->port->port);
                if (tty) {
                        change_port_settings(tty,
-                               edge_port, tty->termios);
+                               edge_port, &tty->termios);
                        tty_kref_put(tty);
                }
 
@@ -2570,7 +2570,7 @@ static void change_port_settings(struct tty_struct *tty,
                return;
        }
 
-       cflag = tty->termios->c_cflag;
+       cflag = tty->termios.c_cflag;
 
        switch (cflag & CSIZE) {
        case CS5:
index 3936904c641969cd4566ba88ee5dc39d8912e6b9..765978ae752ec6b7991154b6fe193029278f8bd9 100644 (file)
@@ -1870,7 +1870,7 @@ static int edge_open(struct tty_struct *tty, struct usb_serial_port *port)
 
        /* set up the port settings */
        if (tty)
-               edge_set_termios(tty, port, tty->termios);
+               edge_set_termios(tty, port, &tty->termios);
 
        /* open up the port */
 
@@ -2272,13 +2272,13 @@ static void change_port_settings(struct tty_struct *tty,
 
        config = kmalloc (sizeof (*config), GFP_KERNEL);
        if (!config) {
-               *tty->termios = *old_termios;
+               tty->termios = *old_termios;
                dev_err(&edge_port->port->dev, "%s - out of memory\n",
                                                                __func__);
                return;
        }
 
-       cflag = tty->termios->c_cflag;
+       cflag = tty->termios.c_cflag;
 
        config->wFlags = 0;
 
@@ -2362,7 +2362,7 @@ static void change_port_settings(struct tty_struct *tty,
        } else
                dbg("%s - OUTBOUND XON/XOFF is disabled", __func__);
 
-       tty->termios->c_cflag &= ~CMSPAR;
+       tty->termios.c_cflag &= ~CMSPAR;
 
        /* Round the baud rate */
        baud = tty_get_baud_rate(tty);
@@ -2408,10 +2408,10 @@ static void edge_set_termios(struct tty_struct *tty,
        struct edgeport_port *edge_port = usb_get_serial_port_data(port);
        unsigned int cflag;
 
-       cflag = tty->termios->c_cflag;
+       cflag = tty->termios.c_cflag;
 
        dbg("%s - clfag %08x iflag %08x", __func__,
-           tty->termios->c_cflag, tty->termios->c_iflag);
+           tty->termios.c_cflag, tty->termios.c_iflag);
        dbg("%s - old clfag %08x old iflag %08x", __func__,
            old_termios->c_cflag, old_termios->c_iflag);
        dbg("%s - port %d", __func__, port->number);
index fc09414c960f045767446ee4a36f4001235700fd..5a96692b12a21235915dd7ba91a8071ff0711f04 100644 (file)
@@ -381,7 +381,7 @@ static void ir_set_termios(struct tty_struct *tty,
                ir_xbof = ir_xbof_change(xbof) ;
 
        /* Only speed changes are supported */
-       tty_termios_copy_hw(tty->termios, old_termios);
+       tty_termios_copy_hw(&tty->termios, old_termios);
        tty_encode_baud_rate(tty, baud, baud);
 
        /*
index 22b1eb5040b7648815be691e215bcfe306cb2d78..bf3864045c1842291d38dc42bd7f536c4413f214 100644 (file)
@@ -921,7 +921,7 @@ static void iuu_set_termios(struct tty_struct *tty,
 {
        const u32 supported_mask = CMSPAR|PARENB|PARODD;
        struct iuu_private *priv = usb_get_serial_port_data(port);
-       unsigned int cflag = tty->termios->c_cflag;
+       unsigned int cflag = tty->termios.c_cflag;
        int status;
        u32 actual;
        u32 parity;
@@ -930,7 +930,7 @@ static void iuu_set_termios(struct tty_struct *tty,
        u32 newval = cflag & supported_mask;
 
        /* Just use the ospeed. ispeed should be the same. */
-       baud = tty->termios->c_ospeed;
+       baud = tty->termios.c_ospeed;
 
        dbg("%s - enter c_ospeed or baud=%d", __func__, baud);
 
@@ -961,13 +961,13 @@ static void iuu_set_termios(struct tty_struct *tty,
         * settings back over and then adjust them
         */
        if (old_termios)
-               tty_termios_copy_hw(tty->termios, old_termios);
+               tty_termios_copy_hw(&tty->termios, old_termios);
        if (status != 0)        /* Set failed - return old bits */
                return;
        /* Re-encode speed, parity and csize */
        tty_encode_baud_rate(tty, baud, baud);
-       tty->termios->c_cflag &= ~(supported_mask|CSIZE);
-       tty->termios->c_cflag |= newval | csize;
+       tty->termios.c_cflag &= ~(supported_mask|CSIZE);
+       tty->termios.c_cflag |= newval | csize;
 }
 
 static void iuu_close(struct usb_serial_port *port)
@@ -993,14 +993,14 @@ static void iuu_close(struct usb_serial_port *port)
 
 static void iuu_init_termios(struct tty_struct *tty)
 {
-       *(tty->termios) = tty_std_termios;
-       tty->termios->c_cflag = CLOCAL | CREAD | CS8 | B9600
+       tty->termios = tty_std_termios;
+       tty->termios.c_cflag = CLOCAL | CREAD | CS8 | B9600
                                | TIOCM_CTS | CSTOPB | PARENB;
-       tty->termios->c_ispeed = 9600;
-       tty->termios->c_ospeed = 9600;
-       tty->termios->c_lflag = 0;
-       tty->termios->c_oflag = 0;
-       tty->termios->c_iflag = 0;
+       tty->termios.c_ispeed = 9600;
+       tty->termios.c_ospeed = 9600;
+       tty->termios.c_lflag = 0;
+       tty->termios.c_oflag = 0;
+       tty->termios.c_iflag = 0;
 }
 
 static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port)
@@ -1012,8 +1012,8 @@ static int iuu_open(struct tty_struct *tty, struct usb_serial_port *port)
        u32 actual;
        struct iuu_private *priv = usb_get_serial_port_data(port);
 
-       baud = tty->termios->c_ospeed;
-       tty->termios->c_ispeed = baud;
+       baud = tty->termios.c_ospeed;
+       tty->termios.c_ispeed = baud;
        /* Re-encode speed */
        tty_encode_baud_rate(tty, baud, baud);
 
index af0b70eaf032f6617c36b596ce70776842a20d9f..7bcbb47e1449a83b210f9d280d5f60c965607641 100644 (file)
@@ -158,7 +158,7 @@ static void keyspan_set_termios(struct tty_struct *tty,
 
        p_priv = usb_get_serial_port_data(port);
        d_details = p_priv->device_details;
-       cflag = tty->termios->c_cflag;
+       cflag = tty->termios.c_cflag;
        device_port = port->number - port->serial->minor;
 
        /* Baud rate calculation takes baud rate as an integer
@@ -179,7 +179,7 @@ static void keyspan_set_termios(struct tty_struct *tty,
        p_priv->flow_control = (cflag & CRTSCTS) ? flow_cts : flow_none;
 
        /* Mark/Space not supported */
-       tty->termios->c_cflag &= ~CMSPAR;
+       tty->termios.c_cflag &= ~CMSPAR;
 
        keyspan_send_setup(port, 0);
 }
@@ -1086,7 +1086,7 @@ static int keyspan_open(struct tty_struct *tty, struct usb_serial_port *port)
 
        device_port = port->number - port->serial->minor;
        if (tty) {
-               cflag = tty->termios->c_cflag;
+               cflag = tty->termios.c_cflag;
                /* Baud rate calculation takes baud rate as an integer
                   so other rates can be generated if desired. */
                baud_rate = tty_get_baud_rate(tty);
index a4ac3cfeffc4b84d6fa8ac41236bad5f2bf6e724..dcada8615fcf851eab023134ee7d5215d17f4c0b 100644 (file)
@@ -338,7 +338,7 @@ static void keyspan_pda_set_termios(struct tty_struct *tty,
           7[EOMS]1: 10 bit, b0/b7 is parity
           7[EOMS]2: 11 bit, b0/b7 is parity, extra bit always (mark?)
 
-          HW flow control is dictated by the tty->termios->c_cflags & CRTSCTS
+          HW flow control is dictated by the tty->termios.c_cflags & CRTSCTS
           bit.
 
           For now, just do baud. */
@@ -353,7 +353,7 @@ static void keyspan_pda_set_termios(struct tty_struct *tty,
        }
        /* Only speed can change so copy the old h/w parameters
           then encode the new speed */
-       tty_termios_copy_hw(tty->termios, old_termios);
+       tty_termios_copy_hw(&tty->termios, old_termios);
        tty_encode_baud_rate(tty, speed, speed);
 }
 
index 5bed59cd5776d097e210944ed51339c53564faeb..def9ad2587157ebc7c0cb856da5a23f96d314f9f 100644 (file)
@@ -311,12 +311,12 @@ static int  klsi_105_open(struct tty_struct *tty, struct usb_serial_port *port)
 
        /* set up termios structure */
        spin_lock_irqsave(&priv->lock, flags);
-       priv->termios.c_iflag = tty->termios->c_iflag;
-       priv->termios.c_oflag = tty->termios->c_oflag;
-       priv->termios.c_cflag = tty->termios->c_cflag;
-       priv->termios.c_lflag = tty->termios->c_lflag;
+       priv->termios.c_iflag = tty->termios.c_iflag;
+       priv->termios.c_oflag = tty->termios.c_oflag;
+       priv->termios.c_cflag = tty->termios.c_cflag;
+       priv->termios.c_lflag = tty->termios.c_lflag;
        for (i = 0; i < NCCS; i++)
-               priv->termios.c_cc[i] = tty->termios->c_cc[i];
+               priv->termios.c_cc[i] = tty->termios.c_cc[i];
        priv->cfg.pktlen   = cfg->pktlen;
        priv->cfg.baudrate = cfg->baudrate;
        priv->cfg.databits = cfg->databits;
@@ -445,9 +445,9 @@ static void klsi_105_set_termios(struct tty_struct *tty,
                                 struct ktermios *old_termios)
 {
        struct klsi_105_private *priv = usb_get_serial_port_data(port);
-       unsigned int iflag = tty->termios->c_iflag;
+       unsigned int iflag = tty->termios.c_iflag;
        unsigned int old_iflag = old_termios->c_iflag;
-       unsigned int cflag = tty->termios->c_cflag;
+       unsigned int cflag = tty->termios.c_cflag;
        unsigned int old_cflag = old_termios->c_cflag;
        struct klsi_105_port_settings *cfg;
        unsigned long flags;
@@ -560,7 +560,7 @@ static void klsi_105_set_termios(struct tty_struct *tty,
        if ((cflag & (PARENB|PARODD)) != (old_cflag & (PARENB|PARODD))
            || (cflag & CSTOPB) != (old_cflag & CSTOPB)) {
                /* Not currently supported */
-               tty->termios->c_cflag &= ~(PARENB|PARODD|CSTOPB);
+               tty->termios.c_cflag &= ~(PARENB|PARODD|CSTOPB);
 #if 0
                priv->last_lcr = 0;
 
@@ -587,7 +587,7 @@ static void klsi_105_set_termios(struct tty_struct *tty,
            || (iflag & IXON) != (old_iflag & IXON)
            ||  (cflag & CRTSCTS) != (old_cflag & CRTSCTS)) {
                /* Not currently supported */
-               tty->termios->c_cflag &= ~CRTSCTS;
+               tty->termios.c_cflag &= ~CRTSCTS;
                /* Drop DTR/RTS if no flow control otherwise assert */
 #if 0
                if ((iflag & IXOFF) || (iflag & IXON) || (cflag & CRTSCTS))
index fafeabb64c553152946618f6f65d37d46131f2fd..bf5c74965d3467603066511d8259600559a6a043 100644 (file)
@@ -191,11 +191,11 @@ static void kobil_release(struct usb_serial *serial)
 static void kobil_init_termios(struct tty_struct *tty)
 {
        /* Default to echo off and other sane device settings */
-       tty->termios->c_lflag = 0;
-       tty->termios->c_lflag &= ~(ISIG | ICANON | ECHO | IEXTEN | XCASE);
-       tty->termios->c_iflag = IGNBRK | IGNPAR | IXOFF;
+       tty->termios.c_lflag = 0;
+       tty->termios.c_iflag &= ~(ISIG | ICANON | ECHO | IEXTEN | XCASE);
+       tty->termios.c_iflag |= IGNBRK | IGNPAR | IXOFF;
        /* do NOT translate CR to CR-NL (0x0A -> 0x0A 0x0D) */
-       tty->termios->c_oflag &= ~ONLCR;
+       tty->termios.c_oflag &= ~ONLCR;
 }
 
 static int kobil_open(struct tty_struct *tty, struct usb_serial_port *port)
@@ -581,14 +581,14 @@ static void kobil_set_termios(struct tty_struct *tty,
        struct kobil_private *priv;
        int result;
        unsigned short urb_val = 0;
-       int c_cflag = tty->termios->c_cflag;
+       int c_cflag = tty->termios.c_cflag;
        speed_t speed;
 
        priv = usb_get_serial_port_data(port);
        if (priv->device_type == KOBIL_USBTWIN_PRODUCT_ID ||
                        priv->device_type == KOBIL_KAAN_SIM_PRODUCT_ID) {
                /* This device doesn't support ioctl calls */
-               *tty->termios = *old;
+               tty_termios_copy_hw(&tty->termios, old);
                return;
        }
 
@@ -612,7 +612,7 @@ static void kobil_set_termios(struct tty_struct *tty,
                        urb_val |= SUSBCR_SPASB_EvenParity;
        } else
                urb_val |= SUSBCR_SPASB_NoParity;
-       tty->termios->c_cflag &= ~CMSPAR;
+       tty->termios.c_cflag &= ~CMSPAR;
        tty_encode_baud_rate(tty, speed, speed);
 
        result = usb_control_msg(port->serial->dev,
index a71fa0aa04066dd38758fe35c87cf007a3b55f4a..df98cffdba65532927997ab8536a2618d1befbc3 100644 (file)
@@ -454,7 +454,7 @@ static int  mct_u232_open(struct tty_struct *tty, struct usb_serial_port *port)
         * either.
         */
        spin_lock_irqsave(&priv->lock, flags);
-       if (tty && (tty->termios->c_cflag & CBAUD))
+       if (tty && (tty->termios.c_cflag & CBAUD))
                priv->control_state = TIOCM_DTR | TIOCM_RTS;
        else
                priv->control_state = 0;
@@ -634,7 +634,7 @@ static void mct_u232_set_termios(struct tty_struct *tty,
 {
        struct usb_serial *serial = port->serial;
        struct mct_u232_private *priv = usb_get_serial_port_data(port);
-       struct ktermios *termios = tty->termios;
+       struct ktermios *termios = &tty->termios;
        unsigned int cflag = termios->c_cflag;
        unsigned int old_cflag = old_termios->c_cflag;
        unsigned long flags;
index d47eb06fe463b51463cb899659a5f2428d5bd24b..7ae9af6b2a54981799ea65ec94d3c433fa877358 100644 (file)
@@ -130,20 +130,14 @@ static void metrousb_read_int_callback(struct urb *urb)
 
        /* Set the data read from the usb port into the serial port buffer. */
        tty = tty_port_tty_get(&port->port);
-       if (!tty) {
-               dev_err(&port->dev, "%s - bad tty pointer - exiting\n",
-                       __func__);
-               return;
-       }
-
        if (tty && urb->actual_length) {
                /* Loop through the data copying each byte to the tty layer. */
                tty_insert_flip_string(tty, data, urb->actual_length);
 
                /* Force the data to the tty layer. */
                tty_flip_buffer_push(tty);
+               tty_kref_put(tty);
        }
-       tty_kref_put(tty);
 
        /* Set any port variables. */
        spin_lock_irqsave(&metro_priv->lock, flags);
index a07dd3c8cfef3e408fbaa4bba593267621ccec71..012f67b2e4cc2eb50145c3b7b2f9ff1f4fcf5e82 100644 (file)
@@ -1349,7 +1349,7 @@ static void mos7720_throttle(struct tty_struct *tty)
        }
 
        /* if we are implementing RTS/CTS, toggle that line */
-       if (tty->termios->c_cflag & CRTSCTS) {
+       if (tty->termios.c_cflag & CRTSCTS) {
                mos7720_port->shadowMCR &= ~UART_MCR_RTS;
                write_mos_reg(port->serial, port->number - port->serial->minor,
                              MCR, mos7720_port->shadowMCR);
@@ -1383,7 +1383,7 @@ static void mos7720_unthrottle(struct tty_struct *tty)
        }
 
        /* if we are implementing RTS/CTS, toggle that line */
-       if (tty->termios->c_cflag & CRTSCTS) {
+       if (tty->termios.c_cflag & CRTSCTS) {
                mos7720_port->shadowMCR |= UART_MCR_RTS;
                write_mos_reg(port->serial, port->number - port->serial->minor,
                              MCR, mos7720_port->shadowMCR);
@@ -1604,8 +1604,8 @@ static void change_port_settings(struct tty_struct *tty,
        lStop = 0x00;   /* 1 stop bit */
        lParity = 0x00; /* No parity */
 
-       cflag = tty->termios->c_cflag;
-       iflag = tty->termios->c_iflag;
+       cflag = tty->termios.c_cflag;
+       iflag = tty->termios.c_iflag;
 
        /* Change the number of bits */
        switch (cflag & CSIZE) {
@@ -1753,11 +1753,11 @@ static void mos7720_set_termios(struct tty_struct *tty,
 
        dbg("%s\n", "setting termios - ASPIRE");
 
-       cflag = tty->termios->c_cflag;
+       cflag = tty->termios.c_cflag;
 
        dbg("%s - cflag %08x iflag %08x", __func__,
-           tty->termios->c_cflag,
-           RELEVANT_IFLAG(tty->termios->c_iflag));
+           tty->termios.c_cflag,
+           RELEVANT_IFLAG(tty->termios.c_iflag));
 
        dbg("%s - old cflag %08x old iflag %08x", __func__,
            old_termios->c_cflag,
index 57eca244842431fa100f742424c9dbc6310c4156..d2f2b5d657321113b4255ce16f619f889d44e03d 100644 (file)
@@ -1649,7 +1649,7 @@ static void mos7840_throttle(struct tty_struct *tty)
                        return;
        }
        /* if we are implementing RTS/CTS, toggle that line */
-       if (tty->termios->c_cflag & CRTSCTS) {
+       if (tty->termios.c_cflag & CRTSCTS) {
                mos7840_port->shadowMCR &= ~MCR_RTS;
                status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER,
                                         mos7840_port->shadowMCR);
@@ -1692,7 +1692,7 @@ static void mos7840_unthrottle(struct tty_struct *tty)
        }
 
        /* if we are implementing RTS/CTS, toggle that line */
-       if (tty->termios->c_cflag & CRTSCTS) {
+       if (tty->termios.c_cflag & CRTSCTS) {
                mos7840_port->shadowMCR |= MCR_RTS;
                status = mos7840_set_uart_reg(port, MODEM_CONTROL_REGISTER,
                                         mos7840_port->shadowMCR);
@@ -1998,8 +1998,8 @@ static void mos7840_change_port_settings(struct tty_struct *tty,
        lStop = LCR_STOP_1;
        lParity = LCR_PAR_NONE;
 
-       cflag = tty->termios->c_cflag;
-       iflag = tty->termios->c_iflag;
+       cflag = tty->termios.c_cflag;
+       iflag = tty->termios.c_iflag;
 
        /* Change the number of bits */
        if (cflag & CSIZE) {
@@ -2159,10 +2159,10 @@ static void mos7840_set_termios(struct tty_struct *tty,
 
        dbg("%s", "setting termios - ");
 
-       cflag = tty->termios->c_cflag;
+       cflag = tty->termios.c_cflag;
 
        dbg("%s - clfag %08x iflag %08x", __func__,
-           tty->termios->c_cflag, RELEVANT_IFLAG(tty->termios->c_iflag));
+           tty->termios.c_cflag, RELEVANT_IFLAG(tty->termios.c_iflag));
        dbg("%s - old clfag %08x old iflag %08x", __func__,
            old_termios->c_cflag, RELEVANT_IFLAG(old_termios->c_iflag));
        dbg("%s - port %d", __func__, port->number);
index 5976b65ab6ee6851cfb10ca2f5dd956c71c8a284..9f555560bfbf0355e6fb8e981168b30daedb4f2b 100644 (file)
@@ -404,10 +404,10 @@ static int oti6858_chars_in_buffer(struct tty_struct *tty)
 
 static void oti6858_init_termios(struct tty_struct *tty)
 {
-       *(tty->termios) = tty_std_termios;
-       tty->termios->c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL;
-       tty->termios->c_ispeed = 38400;
-       tty->termios->c_ospeed = 38400;
+       tty->termios = tty_std_termios;
+       tty->termios.c_cflag = B38400 | CS8 | CREAD | HUPCL | CLOCAL;
+       tty->termios.c_ispeed = 38400;
+       tty->termios.c_ospeed = 38400;
 }
 
 static void oti6858_set_termios(struct tty_struct *tty,
@@ -425,7 +425,7 @@ static void oti6858_set_termios(struct tty_struct *tty,
                return;
        }
 
-       cflag = tty->termios->c_cflag;
+       cflag = tty->termios.c_cflag;
 
        spin_lock_irqsave(&priv->lock, flags);
        divisor = priv->pending_setup.divisor;
index 13b8dd6481f565bd421a0a504b15d449ecbc3d72..2b9108a8ea6470bb32eb9adceaabe150a959cffc 100644 (file)
@@ -260,16 +260,16 @@ static void pl2303_set_termios(struct tty_struct *tty,
           serial settings even to the same values as before. Thus
           we actually need to filter in this specific case */
 
-       if (!tty_termios_hw_change(tty->termios, old_termios))
+       if (!tty_termios_hw_change(&tty->termios, old_termios))
                return;
 
-       cflag = tty->termios->c_cflag;
+       cflag = tty->termios.c_cflag;
 
        buf = kzalloc(7, GFP_KERNEL);
        if (!buf) {
                dev_err(&port->dev, "%s - out of memory.\n", __func__);
                /* Report back no change occurred */
-               *tty->termios = *old_termios;
+               tty->termios = *old_termios;
                return;
        }
 
index 151670b6b72a9871bcf88fd5e611b3247bae9904..7df9cdb053ed757dc119c5b3a0b22dc69b0c4dec 100644 (file)
@@ -275,7 +275,7 @@ static void qt2_set_termios(struct tty_struct *tty,
 {
        struct usb_device *dev = port->serial->dev;
        struct qt2_port_private *port_priv;
-       struct ktermios *termios = tty->termios;
+       struct ktermios *termios = &tty->termios;
        u16 baud;
        unsigned int cflag = termios->c_cflag;
        u16 new_lcr = 0;
@@ -406,7 +406,7 @@ static int qt2_open(struct tty_struct *tty, struct usb_serial_port *port)
        port_priv->device_port = (u8) device_port;
 
        if (tty)
-               qt2_set_termios(tty, port, tty->termios);
+               qt2_set_termios(tty, port, &tty->termios);
 
        return 0;
 
index 0274710cced5ce432504ca02c98de0cab2add0ee..b14ebbd735676d564fc992511d0efa5d5e1d6a61 100644 (file)
@@ -382,7 +382,7 @@ static int sierra_send_setup(struct usb_serial_port *port)
 static void sierra_set_termios(struct tty_struct *tty,
                struct usb_serial_port *port, struct ktermios *old_termios)
 {
-       tty_termios_copy_hw(tty->termios, old_termios);
+       tty_termios_copy_hw(&tty->termios, old_termios);
        sierra_send_setup(port);
 }
 
index cad608984710321903ccef7ef0ce8d53a4e88ebf..ab68a4d74d61b5a5a2e8bc67479e4f7750098946 100644 (file)
@@ -316,10 +316,10 @@ static void spcp8x5_dtr_rts(struct usb_serial_port *port, int on)
 static void spcp8x5_init_termios(struct tty_struct *tty)
 {
        /* for the 1st time call this function */
-       *(tty->termios) = tty_std_termios;
-       tty->termios->c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL;
-       tty->termios->c_ispeed = 115200;
-       tty->termios->c_ospeed = 115200;
+       tty->termios = tty_std_termios;
+       tty->termios.c_cflag = B115200 | CS8 | CREAD | HUPCL | CLOCAL;
+       tty->termios.c_ispeed = 115200;
+       tty->termios.c_ospeed = 115200;
 }
 
 /* set the serial param for transfer. we should check if we really need to
@@ -330,7 +330,7 @@ static void spcp8x5_set_termios(struct tty_struct *tty,
        struct usb_serial *serial = port->serial;
        struct spcp8x5_private *priv = usb_get_serial_port_data(port);
        unsigned long flags;
-       unsigned int cflag = tty->termios->c_cflag;
+       unsigned int cflag = tty->termios.c_cflag;
        unsigned int old_cflag = old_termios->c_cflag;
        unsigned short uartdata;
        unsigned char buf[2] = {0, 0};
@@ -340,7 +340,7 @@ static void spcp8x5_set_termios(struct tty_struct *tty,
 
 
        /* check that they really want us to change something */
-       if (!tty_termios_hw_change(tty->termios, old_termios))
+       if (!tty_termios_hw_change(&tty->termios, old_termios))
                return;
 
        /* set DTR/RTS active */
index 3fee23bf0c141718228d6b3a5ae04bc42a58a96d..cf2d30cf7588c09ca1e502471990d4c2a92cc456 100644 (file)
@@ -216,7 +216,7 @@ static void ssu100_set_termios(struct tty_struct *tty,
                               struct ktermios *old_termios)
 {
        struct usb_device *dev = port->serial->dev;
-       struct ktermios *termios = tty->termios;
+       struct ktermios *termios = &tty->termios;
        u16 baud, divisor, remainder;
        unsigned int cflag = termios->c_cflag;
        u16 urb_value = 0; /* will hold the new flags */
@@ -322,7 +322,7 @@ static int ssu100_open(struct tty_struct *tty, struct usb_serial_port *port)
                dbg("%s - set uart failed", __func__);
 
        if (tty)
-               ssu100_set_termios(tty, port, tty->termios);
+               ssu100_set_termios(tty, port, &tty->termios);
 
        return usb_serial_generic_open(tty, port);
 }
index a4404f5ad68ec5e782c68f9b261e52b4224ac497..f502a16aac215db11f5ce53a4492422495768340 100644 (file)
@@ -520,7 +520,7 @@ static int ti_open(struct tty_struct *tty, struct usb_serial_port *port)
        }
 
        if (tty)
-               ti_set_termios(tty, port, tty->termios);
+               ti_set_termios(tty, port, &tty->termios);
 
        dbg("%s - sending TI_OPEN_PORT", __func__);
        status = ti_command_out_sync(tdev, TI_OPEN_PORT,
@@ -562,7 +562,7 @@ static int ti_open(struct tty_struct *tty, struct usb_serial_port *port)
        usb_clear_halt(dev, port->read_urb->pipe);
 
        if (tty)
-               ti_set_termios(tty, port, tty->termios);
+               ti_set_termios(tty, port, &tty->termios);
 
        dbg("%s - sending TI_OPEN_PORT (2)", __func__);
        status = ti_command_out_sync(tdev, TI_OPEN_PORT,
@@ -831,8 +831,8 @@ static void ti_set_termios(struct tty_struct *tty,
        int port_number = port->number - port->serial->minor;
        unsigned int mcr;
 
-       cflag = tty->termios->c_cflag;
-       iflag = tty->termios->c_iflag;
+       cflag = tty->termios.c_cflag;
+       iflag = tty->termios.c_iflag;
 
        dbg("%s - cflag %08x, iflag %08x", __func__, cflag, iflag);
        dbg("%s - old clfag %08x, old iflag %08x", __func__,
@@ -871,7 +871,7 @@ static void ti_set_termios(struct tty_struct *tty,
        }
 
        /* CMSPAR isn't supported by this driver */
-       tty->termios->c_cflag &= ~CMSPAR;
+       tty->termios.c_cflag &= ~CMSPAR;
 
        if (cflag & PARENB) {
                if (cflag & PARODD) {
index 27483f91a4a38a41bfdd3f2a5c9583be33ac8027..aa4b0d7759924af8d7a728396c9acb26926ae617 100644 (file)
@@ -207,7 +207,7 @@ static int serial_install(struct tty_driver *driver, struct tty_struct *tty)
        if (retval)
                goto error_get_interface;
 
-       retval = tty_standard_install(driver, tty);
+       retval = tty_port_install(&port->port, driver, tty);
        if (retval)
                goto error_init_termios;
 
@@ -305,8 +305,7 @@ static void serial_close(struct tty_struct *tty, struct file *filp)
  * Do the resource freeing and refcount dropping for the port.
  * Avoid freeing the console.
  *
- * Called asynchronously after the last tty kref is dropped,
- * and the tty layer has already done the tty_shutdown(tty);
+ * Called asynchronously after the last tty kref is dropped.
  */
 static void serial_cleanup(struct tty_struct *tty)
 {
@@ -423,7 +422,7 @@ static void serial_set_termios(struct tty_struct *tty, struct ktermios *old)
        if (port->serial->type->set_termios)
                port->serial->type->set_termios(tty, port, old);
        else
-               tty_termios_copy_hw(tty->termios, old);
+               tty_termios_copy_hw(&tty->termios, old);
 }
 
 static int serial_break(struct tty_struct *tty, int break_state)
index f35971dff4a5782d6c0cca563f53558043359674..7c3db9e6f3246504dea8a7430c2d61517f2e3f7d 100644 (file)
@@ -67,7 +67,7 @@ void usb_wwan_set_termios(struct tty_struct *tty,
        struct usb_wwan_intf_private *intfdata = port->serial->private;
 
        /* Doesn't support option setting */
-       tty_termios_copy_hw(tty->termios, old_termios);
+       tty_termios_copy_hw(&tty->termios, old_termios);
 
        if (intfdata->send_setup)
                intfdata->send_setup(port);
index 473635e7f5dbdf8bb4c28c20102f12b438b31d77..b36077de72b96e17fe9eb1c830ec73c0d6e3f0eb 100644 (file)
@@ -724,7 +724,7 @@ static void firm_setup_port(struct tty_struct *tty)
 {
        struct usb_serial_port *port = tty->driver_data;
        struct whiteheat_port_settings port_settings;
-       unsigned int cflag = tty->termios->c_cflag;
+       unsigned int cflag = tty->termios.c_cflag;
 
        port_settings.port = port->number + 1;
 
index d9a7544748785d020ba77f74392fb1275fbe02fd..28ea2b4d1b4548036f3ba0d8e90fe66a93f59d98 100644 (file)
@@ -84,7 +84,6 @@ header-y += capability.h
 header-y += capi.h
 header-y += cciss_defs.h
 header-y += cciss_ioctl.h
-header-y += cdk.h
 header-y += cdrom.h
 header-y += cgroupstats.h
 header-y += chio.h
@@ -93,7 +92,6 @@ header-y += cn_proc.h
 header-y += coda.h
 header-y += coda_psdev.h
 header-y += coff.h
-header-y += comstats.h
 header-y += connector.h
 header-y += const.h
 header-y += cramfs_fs.h
@@ -140,7 +138,6 @@ header-y += fuse.h
 header-y += futex.h
 header-y += gameport.h
 header-y += gen_stats.h
-header-y += generic_serial.h
 header-y += genetlink.h
 header-y += gfs2_ondisk.h
 header-y += gigaset_dev.h
diff --git a/include/linux/cd1400.h b/include/linux/cd1400.h
deleted file mode 100644 (file)
index 1dc3ab0..0000000
+++ /dev/null
@@ -1,292 +0,0 @@
-/*****************************************************************************/
-
-/*
- *     cd1400.h  -- cd1400 UART hardware info.
- *
- *     Copyright (C) 1996-1998  Stallion Technologies
- *     Copyright (C) 1994-1996  Greg Ungerer.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     This program is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *     You should have received a copy of the GNU General Public License
- *     along with this program; if not, write to the Free Software
- *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*****************************************************************************/
-#ifndef        _CD1400_H
-#define        _CD1400_H
-/*****************************************************************************/
-
-/*
- *     Define the number of async ports per cd1400 uart chip.
- */
-#define        CD1400_PORTS            4
-
-/*
- *     Define the cd1400 uarts internal FIFO sizes.
- */
-#define        CD1400_TXFIFOSIZE       12
-#define        CD1400_RXFIFOSIZE       12
-
-/*
- *     Local RX FIFO thresh hold level. Also define the RTS thresh hold
- *     based on the RX thresh hold.
- */
-#define        FIFO_RXTHRESHOLD        6
-#define        FIFO_RTSTHRESHOLD       7
-
-/*****************************************************************************/
-
-/*
- *     Define the cd1400 register addresses. These are all the valid
- *     registers with the cd1400. Some are global, some virtual, some
- *     per port.
- */
-#define        GFRCR           0x40
-#define        CAR             0x68
-#define        GCR             0x4b
-#define        SVRR            0x67
-#define        RICR            0x44
-#define        TICR            0x45
-#define        MICR            0x46
-#define        RIR             0x6b
-#define        TIR             0x6a
-#define        MIR             0x69
-#define        PPR             0x7e
-
-#define        RIVR            0x43
-#define        TIVR            0x42
-#define        MIVR            0x41
-#define        TDR             0x63
-#define        RDSR            0x62
-#define        MISR            0x4c
-#define        EOSRR           0x60
-
-#define        LIVR            0x18
-#define        CCR             0x05
-#define        SRER            0x06
-#define        COR1            0x08
-#define        COR2            0x09
-#define        COR3            0x0a
-#define        COR4            0x1e
-#define        COR5            0x1f
-#define        CCSR            0x0b
-#define        RDCR            0x0e
-#define        SCHR1           0x1a
-#define        SCHR2           0x1b
-#define        SCHR3           0x1c
-#define        SCHR4           0x1d
-#define        SCRL            0x22
-#define        SCRH            0x23
-#define        LNC             0x24
-#define        MCOR1           0x15
-#define        MCOR2           0x16
-#define        RTPR            0x21
-#define        MSVR1           0x6c
-#define        MSVR2           0x6d
-#define        PSVR            0x6f
-#define        RBPR            0x78
-#define        RCOR            0x7c
-#define        TBPR            0x72
-#define        TCOR            0x76
-
-/*****************************************************************************/
-
-/*
- *     Define the set of baud rate clock divisors.
- */
-#define        CD1400_CLK0     8
-#define        CD1400_CLK1     32
-#define        CD1400_CLK2     128
-#define        CD1400_CLK3     512
-#define        CD1400_CLK4     2048
-
-#define        CD1400_NUMCLKS  5
-
-/*****************************************************************************/
-
-/*
- *     Define the clock pre-scalar value to be a 5 ms clock. This should be
- *     OK for now. It would probably be better to make it 10 ms, but we
- *     can't fit that divisor into 8 bits!
- */
-#define        PPR_SCALAR      244
-
-/*****************************************************************************/
-
-/*
- *     Define values used to set character size options.
- */
-#define        COR1_CHL5       0x00
-#define        COR1_CHL6       0x01
-#define        COR1_CHL7       0x02
-#define        COR1_CHL8       0x03
-
-/*
- *     Define values used to set the number of stop bits.
- */
-#define        COR1_STOP1      0x00
-#define        COR1_STOP15     0x04
-#define        COR1_STOP2      0x08
-
-/*
- *     Define values used to set the parity scheme in use.
- */
-#define        COR1_PARNONE    0x00
-#define        COR1_PARFORCE   0x20
-#define        COR1_PARENB     0x40
-#define        COR1_PARIGNORE  0x10
-
-#define        COR1_PARODD     0x80
-#define        COR1_PAREVEN    0x00
-
-#define        COR2_IXM        0x80
-#define        COR2_TXIBE      0x40
-#define        COR2_ETC        0x20
-#define        COR2_LLM        0x10
-#define        COR2_RLM        0x08
-#define        COR2_RTSAO      0x04
-#define        COR2_CTSAE      0x02
-
-#define        COR3_SCDRNG     0x80
-#define        COR3_SCD34      0x40
-#define        COR3_FCT        0x20
-#define        COR3_SCD12      0x10
-
-/*
- *     Define values used by COR4.
- */
-#define        COR4_BRKINT     0x08
-#define        COR4_IGNBRK     0x18
-
-/*****************************************************************************/
-
-/*
- *     Define the modem control register values.
- *     Note that the actual hardware is a little different to the conventional
- *     pin names on the cd1400.
- */
-#define        MSVR1_DTR       0x01
-#define        MSVR1_DSR       0x10
-#define        MSVR1_RI        0x20
-#define        MSVR1_CTS       0x40
-#define        MSVR1_DCD       0x80
-
-#define        MSVR2_RTS       0x02
-#define        MSVR2_DSR       0x10
-#define        MSVR2_RI        0x20
-#define        MSVR2_CTS       0x40
-#define        MSVR2_DCD       0x80
-
-#define        MCOR1_DCD       0x80
-#define        MCOR1_CTS       0x40
-#define        MCOR1_RI        0x20
-#define        MCOR1_DSR       0x10
-
-#define        MCOR2_DCD       0x80
-#define        MCOR2_CTS       0x40
-#define        MCOR2_RI        0x20
-#define        MCOR2_DSR       0x10
-
-/*****************************************************************************/
-
-/*
- *     Define the bits used with the service (interrupt) enable register.
- */
-#define        SRER_NNDT       0x01
-#define        SRER_TXEMPTY    0x02
-#define        SRER_TXDATA     0x04
-#define        SRER_RXDATA     0x10
-#define        SRER_MODEM      0x80
-
-/*****************************************************************************/
-
-/*
- *     Define operational commands for the command register.
- */
-#define        CCR_RESET       0x80
-#define        CCR_CORCHANGE   0x4e
-#define        CCR_SENDCH      0x20
-#define        CCR_CHANCTRL    0x10
-
-#define        CCR_TXENABLE    (CCR_CHANCTRL | 0x08)
-#define        CCR_TXDISABLE   (CCR_CHANCTRL | 0x04)
-#define        CCR_RXENABLE    (CCR_CHANCTRL | 0x02)
-#define        CCR_RXDISABLE   (CCR_CHANCTRL | 0x01)
-
-#define        CCR_SENDSCHR1   (CCR_SENDCH | 0x01)
-#define        CCR_SENDSCHR2   (CCR_SENDCH | 0x02)
-#define        CCR_SENDSCHR3   (CCR_SENDCH | 0x03)
-#define        CCR_SENDSCHR4   (CCR_SENDCH | 0x04)
-
-#define        CCR_RESETCHAN   (CCR_RESET | 0x00)
-#define        CCR_RESETFULL   (CCR_RESET | 0x01)
-#define        CCR_TXFLUSHFIFO (CCR_RESET | 0x02)
-
-#define        CCR_MAXWAIT     10000
-
-/*****************************************************************************/
-
-/*
- *     Define the valid acknowledgement types (for hw ack cycle).
- */
-#define        ACK_TYPMASK     0x07
-#define        ACK_TYPTX       0x02
-#define        ACK_TYPMDM      0x01
-#define        ACK_TYPRXGOOD   0x03
-#define        ACK_TYPRXBAD    0x07
-
-#define        SVRR_RX         0x01
-#define        SVRR_TX         0x02
-#define        SVRR_MDM        0x04
-
-#define        ST_OVERRUN      0x01
-#define        ST_FRAMING      0x02
-#define        ST_PARITY       0x04
-#define        ST_BREAK        0x08
-#define        ST_SCHAR1       0x10
-#define        ST_SCHAR2       0x20
-#define        ST_SCHAR3       0x30
-#define        ST_SCHAR4       0x40
-#define        ST_RANGE        0x70
-#define        ST_SCHARMASK    0x70
-#define        ST_TIMEOUT      0x80
-
-#define        MISR_DCD        0x80
-#define        MISR_CTS        0x40
-#define        MISR_RI         0x20
-#define        MISR_DSR        0x10
-
-/*****************************************************************************/
-
-/*
- *     Defines for the CCSR status register.
- */
-#define        CCSR_RXENABLED  0x80
-#define        CCSR_RXFLOWON   0x40
-#define        CCSR_RXFLOWOFF  0x20
-#define        CCSR_TXENABLED  0x08
-#define        CCSR_TXFLOWON   0x04
-#define        CCSR_TXFLOWOFF  0x02
-
-/*****************************************************************************/
-
-/*
- *     Define the embedded commands.
- */
-#define        ETC_CMD         0x00
-#define        ETC_STARTBREAK  0x81
-#define        ETC_DELAY       0x82
-#define        ETC_STOPBREAK   0x83
-
-/*****************************************************************************/
-#endif
diff --git a/include/linux/cdk.h b/include/linux/cdk.h
deleted file mode 100644 (file)
index 80093a8..0000000
+++ /dev/null
@@ -1,486 +0,0 @@
-/*****************************************************************************/
-
-/*
- *     cdk.h  -- CDK interface definitions.
- *
- *     Copyright (C) 1996-1998  Stallion Technologies
- *     Copyright (C) 1994-1996  Greg Ungerer.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     This program is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *     You should have received a copy of the GNU General Public License
- *     along with this program; if not, write to the Free Software
- *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*****************************************************************************/
-#ifndef        _CDK_H
-#define        _CDK_H
-/*****************************************************************************/
-
-#pragma        pack(2)
-
-/*
- *     The following set of definitions is used to communicate with the
- *     shared memory interface of the Stallion intelligent multiport serial
- *     boards. The definitions in this file are taken directly from the
- *     document titled "Generic Stackable Interface, Downloader and
- *     Communications Development Kit".
- */
-
-/*
- *     Define the set of important shared memory addresses. These are
- *     required to initialize the board and get things started. All of these
- *     addresses are relative to the start of the shared memory.
- */
-#define        CDK_SIGADDR     0x200
-#define        CDK_FEATADDR    0x280
-#define        CDK_CDKADDR     0x300
-#define        CDK_RDYADDR     0x262
-
-#define        CDK_ALIVEMARKER 13
-
-/*
- *     On hardware power up the ROMs located on the EasyConnection 8/64 will
- *     fill out the following signature information into shared memory. This
- *     way the host system can quickly determine that the board is present
- *     and is operational.
- */
-typedef struct cdkecpsig {
-       unsigned long   magic;
-       unsigned short  romver;
-       unsigned short  cputype;
-       unsigned char   panelid[8];
-} cdkecpsig_t;
-
-#define        ECP_MAGIC       0x21504345
-
-/*
- *     On hardware power up the ROMs located on the ONboard, Stallion and
- *     Brumbys will fill out the following signature information into shared
- *     memory. This way the host system can quickly determine that the board
- *     is present and is operational.
- */
-typedef struct cdkonbsig {
-       unsigned short  magic0;
-       unsigned short  magic1;
-       unsigned short  magic2;
-       unsigned short  magic3;
-       unsigned short  romver;
-       unsigned short  memoff;
-       unsigned short  memseg;
-       unsigned short  amask0;
-       unsigned short  pic;
-       unsigned short  status;
-       unsigned short  btype;
-       unsigned short  clkticks;
-       unsigned short  clkspeed;
-       unsigned short  amask1;
-       unsigned short  amask2;
-} cdkonbsig_t;
-
-#define        ONB_MAGIC0      0xf2a7
-#define        ONB_MAGIC1      0xa149
-#define        ONB_MAGIC2      0x6352
-#define        ONB_MAGIC3      0xf121
-
-/*
- *     Define the feature area structure. The feature area is the set of
- *     startup parameters used by the slave image when it starts executing.
- *     They allow for the specification of buffer sizes, debug trace, etc.
- */
-typedef struct cdkfeature {
-       unsigned long   debug;
-       unsigned long   banner;
-       unsigned long   etype;
-       unsigned long   nrdevs;
-       unsigned long   brdspec;
-       unsigned long   txrqsize;
-       unsigned long   rxrqsize;
-       unsigned long   flags;
-} cdkfeature_t;
-
-#define        ETYP_DDK        0
-#define        ETYP_CDK        1
-
-/*
- *     Define the CDK header structure. This is the info that the slave
- *     environment sets up after it has been downloaded and started. It
- *     essentially provides a memory map for the shared memory interface.
- */
-typedef struct cdkhdr {
-       unsigned short  command;
-       unsigned short  status;
-       unsigned short  port;
-       unsigned short  mode;
-       unsigned long   cmd_buf[14];
-       unsigned short  alive_cnt;
-       unsigned short  intrpt_mode;
-       unsigned char   intrpt_id[8];
-       unsigned char   ver_release;
-       unsigned char   ver_modification;
-       unsigned char   ver_fix;
-       unsigned char   deadman_restart;
-       unsigned short  deadman;
-       unsigned short  nrdevs;
-       unsigned long   memp;
-       unsigned long   hostp;
-       unsigned long   slavep;
-       unsigned char   hostreq;
-       unsigned char   slavereq;
-       unsigned char   cmd_reserved[30];
-} cdkhdr_t;
-
-#define        MODE_DDK        0
-#define        MODE_CDK        1
-
-#define        IMD_INTR        0x0
-#define        IMD_PPINTR      0x1
-#define        IMD_POLL        0xff
-
-/*
- *     Define the memory mapping structure. This structure is pointed to by
- *     the memp field in the stlcdkhdr struct. As many as these structures
- *     as required are laid out in shared memory to define how the rest of
- *     shared memory is divided up. There will be one for each port.
- */
-typedef struct cdkmem {
-       unsigned short  dtype;
-       unsigned long   offset;
-} cdkmem_t;
-
-#define        TYP_UNDEFINED   0x0
-#define        TYP_ASYNCTRL    0x1
-#define        TYP_ASYNC       0x20
-#define        TYP_PARALLEL    0x40
-#define        TYP_SYNCX21     0x60
-
-/*****************************************************************************/
-
-/*
- *     Following is a set of defines and structures used to actually deal
- *     with the serial ports on the board. Firstly is the set of commands
- *     that can be applied to ports.
- */
-#define        ASYCMD          (((unsigned long) 'a') << 8)
-
-#define        A_NULL          (ASYCMD | 0)
-#define        A_FLUSH         (ASYCMD | 1)
-#define        A_BREAK         (ASYCMD | 2)
-#define        A_GETPORT       (ASYCMD | 3)
-#define        A_SETPORT       (ASYCMD | 4)
-#define        A_SETPORTF      (ASYCMD | 5)
-#define        A_SETPORTFTX    (ASYCMD | 6)
-#define        A_SETPORTFRX    (ASYCMD | 7)
-#define        A_GETSIGNALS    (ASYCMD | 8)
-#define        A_SETSIGNALS    (ASYCMD | 9)
-#define        A_SETSIGNALSF   (ASYCMD | 10)
-#define        A_SETSIGNALSFTX (ASYCMD | 11)
-#define        A_SETSIGNALSFRX (ASYCMD | 12)
-#define        A_GETNOTIFY     (ASYCMD | 13)
-#define        A_SETNOTIFY     (ASYCMD | 14)
-#define        A_NOTIFY        (ASYCMD | 15)
-#define        A_PORTCTRL      (ASYCMD | 16)
-#define        A_GETSTATS      (ASYCMD | 17)
-#define        A_RQSTATE       (ASYCMD | 18)
-#define        A_FLOWSTATE     (ASYCMD | 19)
-#define        A_CLEARSTATS    (ASYCMD | 20)
-
-/*
- *     Define those arguments used for simple commands.
- */
-#define        FLUSHRX         0x1
-#define        FLUSHTX         0x2
-
-#define        BREAKON         -1
-#define        BREAKOFF        -2
-
-/*
- *     Define the port setting structure, and all those defines that go along
- *     with it. Basically this structure defines the characteristics of this
- *     port: baud rate, chars, parity, input/output char cooking etc.
- */
-typedef struct asyport {
-       unsigned long   baudout;
-       unsigned long   baudin;
-       unsigned long   iflag;
-       unsigned long   oflag;
-       unsigned long   lflag;
-       unsigned long   pflag;
-       unsigned long   flow;
-       unsigned long   spare1;
-       unsigned short  vtime;
-       unsigned short  vmin;
-       unsigned short  txlo;
-       unsigned short  txhi;
-       unsigned short  rxlo;
-       unsigned short  rxhi;
-       unsigned short  rxhog;
-       unsigned short  spare2;
-       unsigned char   csize;
-       unsigned char   stopbs;
-       unsigned char   parity;
-       unsigned char   stopin;
-       unsigned char   startin;
-       unsigned char   stopout;
-       unsigned char   startout;
-       unsigned char   parmark;
-       unsigned char   brkmark;
-       unsigned char   cc[11];
-} asyport_t;
-
-#define        PT_STOP1        0x0
-#define        PT_STOP15       0x1
-#define        PT_STOP2        0x2
-
-#define        PT_NOPARITY     0x0
-#define        PT_ODDPARITY    0x1
-#define        PT_EVENPARITY   0x2
-#define        PT_MARKPARITY   0x3
-#define        PT_SPACEPARITY  0x4
-
-#define        F_NONE          0x0
-#define        F_IXON          0x1
-#define        F_IXOFF         0x2
-#define        F_IXANY         0x4
-#define        F_IOXANY        0x8
-#define        F_RTSFLOW       0x10
-#define        F_CTSFLOW       0x20
-#define        F_DTRFLOW       0x40
-#define        F_DCDFLOW       0x80
-#define        F_DSROFLOW      0x100
-#define        F_DSRIFLOW      0x200
-
-#define        FI_NORX         0x1
-#define        FI_RAW          0x2
-#define        FI_ISTRIP       0x4
-#define        FI_UCLC         0x8
-#define        FI_INLCR        0x10
-#define        FI_ICRNL        0x20
-#define        FI_IGNCR        0x40
-#define        FI_IGNBREAK     0x80
-#define        FI_DSCRDBREAK   0x100
-#define        FI_1MARKBREAK   0x200
-#define        FI_2MARKBREAK   0x400
-#define        FI_XCHNGBREAK   0x800
-#define        FI_IGNRXERRS    0x1000
-#define        FI_DSCDRXERRS   0x2000
-#define        FI_1MARKRXERRS  0x4000
-#define        FI_2MARKRXERRS  0x8000
-#define        FI_XCHNGRXERRS  0x10000
-#define        FI_DSCRDNULL    0x20000
-
-#define        FO_OLCUC        0x1
-#define        FO_ONLCR        0x2
-#define        FO_OOCRNL       0x4
-#define        FO_ONOCR        0x8
-#define        FO_ONLRET       0x10
-#define        FO_ONL          0x20
-#define        FO_OBS          0x40
-#define        FO_OVT          0x80
-#define        FO_OFF          0x100
-#define        FO_OTAB1        0x200
-#define        FO_OTAB2        0x400
-#define        FO_OTAB3        0x800
-#define        FO_OCR1         0x1000
-#define        FO_OCR2         0x2000
-#define        FO_OCR3         0x4000
-#define        FO_OFILL        0x8000
-#define        FO_ODELL        0x10000
-
-#define        P_RTSLOCK       0x1
-#define        P_CTSLOCK       0x2
-#define        P_MAPRTS        0x4
-#define        P_MAPCTS        0x8
-#define        P_LOOPBACK      0x10
-#define        P_DTRFOLLOW     0x20
-#define        P_FAKEDCD       0x40
-
-#define        P_RXIMIN        0x10000
-#define        P_RXITIME       0x20000
-#define        P_RXTHOLD       0x40000
-
-/*
- *     Define a structure to communicate serial port signal and data state
- *     information.
- */
-typedef struct asysigs {
-       unsigned long   data;
-       unsigned long   signal;
-       unsigned long   sigvalue;
-} asysigs_t;
-
-#define        DT_TXBUSY       0x1
-#define        DT_TXEMPTY      0x2
-#define        DT_TXLOW        0x4
-#define        DT_TXHIGH       0x8
-#define        DT_TXFULL       0x10
-#define        DT_TXHOG        0x20
-#define        DT_TXFLOWED     0x40
-#define        DT_TXBREAK      0x80
-
-#define        DT_RXBUSY       0x100
-#define        DT_RXEMPTY      0x200
-#define        DT_RXLOW        0x400
-#define        DT_RXHIGH       0x800
-#define        DT_RXFULL       0x1000
-#define        DT_RXHOG        0x2000
-#define        DT_RXFLOWED     0x4000
-#define        DT_RXBREAK      0x8000
-
-#define        SG_DTR          0x1
-#define        SG_DCD          0x2
-#define        SG_RTS          0x4
-#define        SG_CTS          0x8
-#define        SG_DSR          0x10
-#define        SG_RI           0x20
-
-/*
- *     Define the notification setting structure. This is used to tell the
- *     port what events we want to be informed about. Fields here use the
- *     same defines as for the asysigs structure above.
- */
-typedef struct asynotify {
-       unsigned long   ctrl;
-       unsigned long   data;
-       unsigned long   signal;
-       unsigned long   sigvalue;
-} asynotify_t;
-
-/*
- *     Define the port control structure. It is used to do fine grain
- *     control operations on the port.
- */
-typedef struct {
-       unsigned long   rxctrl;
-       unsigned long   txctrl;
-       char            rximdch;
-       char            tximdch;
-       char            spare1;
-       char            spare2;
-} asyctrl_t;
-
-#define        CT_ENABLE       0x1
-#define        CT_DISABLE      0x2
-#define        CT_STOP         0x4
-#define        CT_START        0x8
-#define        CT_STARTFLOW    0x10
-#define        CT_STOPFLOW     0x20
-#define        CT_SENDCHR      0x40
-
-/*
- *     Define the stats structure kept for each port. This is a useful set
- *     of data collected for each port on the slave. The A_GETSTATS command
- *     is used to retrieve this data from the slave.
- */
-typedef struct asystats {
-       unsigned long   opens;
-       unsigned long   txchars;
-       unsigned long   rxchars;
-       unsigned long   txringq;
-       unsigned long   rxringq;
-       unsigned long   txmsgs;
-       unsigned long   rxmsgs;
-       unsigned long   txflushes;
-       unsigned long   rxflushes;
-       unsigned long   overruns;
-       unsigned long   framing;
-       unsigned long   parity;
-       unsigned long   ringover;
-       unsigned long   lost;
-       unsigned long   rxstart;
-       unsigned long   rxstop;
-       unsigned long   txstart;
-       unsigned long   txstop;
-       unsigned long   dcdcnt;
-       unsigned long   dtrcnt;
-       unsigned long   ctscnt;
-       unsigned long   rtscnt;
-       unsigned long   dsrcnt;
-       unsigned long   ricnt;
-       unsigned long   txbreaks;
-       unsigned long   rxbreaks;
-       unsigned long   signals;
-       unsigned long   state;
-       unsigned long   hwid;
-} asystats_t;
-
-/*****************************************************************************/
-
-/*
- *     All command and control communication with a device on the slave is
- *     via a control block in shared memory. Each device has its own control
- *     block, defined by the following structure. The control block allows
- *     the host to open, close and control the device on the slave.
- */
-typedef struct cdkctrl {
-       unsigned char   open;
-       unsigned char   close;
-       unsigned long   openarg;
-       unsigned long   closearg;
-       unsigned long   cmd;
-       unsigned long   status;
-       unsigned long   args[32];
-} cdkctrl_t;
-
-/*
- *     Each device on the slave passes data to and from the host via a ring
- *     queue in shared memory. Define a ring queue structure to hold the
- *     vital information about each ring queue. Two ring queues will be
- *     allocated for each port, one for receive data and one for transmit
- *     data.
- */
-typedef struct cdkasyrq {
-       unsigned long   offset;
-       unsigned short  size;
-       unsigned short  head;
-       unsigned short  tail;
-} cdkasyrq_t;
-
-/*
- *     Each asynchronous port is defined in shared memory by the following
- *     structure. It contains a control block to command a device, and also
- *     the necessary data channel information as well.
- */
-typedef struct cdkasy {
-       cdkctrl_t       ctrl;
-       unsigned short  notify;
-       asynotify_t     changed;
-       unsigned short  receive;
-       cdkasyrq_t      rxq;
-       unsigned short  transmit;
-       cdkasyrq_t      txq;
-} cdkasy_t;
-
-#pragma        pack()
-
-/*****************************************************************************/
-
-/*
- *     Define the set of ioctls used by the driver to do special things
- *     to the board. These include interrupting it, and initializing
- *     the driver after board startup and shutdown.
- */
-#include <linux/ioctl.h>
-
-#define        STL_BINTR       _IO('s',20)
-#define        STL_BSTART      _IO('s',21)
-#define        STL_BSTOP       _IO('s',22)
-#define        STL_BRESET      _IO('s',23)
-
-/*
- *     Define a set of ioctl extensions, used to get at special stuff.
- */
-#define        STL_GETPFLAG    _IO('s',80)
-#define        STL_SETPFLAG    _IO('s',81)
-
-/*****************************************************************************/
-#endif
diff --git a/include/linux/comstats.h b/include/linux/comstats.h
deleted file mode 100644 (file)
index 3f5ea8e..0000000
+++ /dev/null
@@ -1,119 +0,0 @@
-/*****************************************************************************/
-
-/*
- *     comstats.h  -- Serial Port Stats.
- *
- *     Copyright (C) 1996-1998  Stallion Technologies
- *     Copyright (C) 1994-1996  Greg Ungerer.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     This program is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *     You should have received a copy of the GNU General Public License
- *     along with this program; if not, write to the Free Software
- *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*****************************************************************************/
-#ifndef        _COMSTATS_H
-#define        _COMSTATS_H
-/*****************************************************************************/
-
-/*
- *     Serial port stats structure. The structure itself is UART
- *     independent, but some fields may be UART/driver specific (for
- *     example state).
- */
-
-typedef struct {
-       unsigned long   brd;
-       unsigned long   panel;
-       unsigned long   port;
-       unsigned long   hwid;
-       unsigned long   type;
-       unsigned long   txtotal;
-       unsigned long   rxtotal;
-       unsigned long   txbuffered;
-       unsigned long   rxbuffered;
-       unsigned long   rxoverrun;
-       unsigned long   rxparity;
-       unsigned long   rxframing;
-       unsigned long   rxlost;
-       unsigned long   txbreaks;
-       unsigned long   rxbreaks;
-       unsigned long   txxon;
-       unsigned long   txxoff;
-       unsigned long   rxxon;
-       unsigned long   rxxoff;
-       unsigned long   txctson;
-       unsigned long   txctsoff;
-       unsigned long   rxrtson;
-       unsigned long   rxrtsoff;
-       unsigned long   modem;
-       unsigned long   state;
-       unsigned long   flags;
-       unsigned long   ttystate;
-       unsigned long   cflags;
-       unsigned long   iflags;
-       unsigned long   oflags;
-       unsigned long   lflags;
-       unsigned long   signals;
-} comstats_t;
-
-
-/*
- *     Board stats structure. Returns useful info about the board.
- */
-
-#define        COM_MAXPANELS   8
-
-typedef struct {
-       unsigned long   panel;
-       unsigned long   type;
-       unsigned long   hwid;
-       unsigned long   nrports;
-} companel_t;
-
-typedef struct {
-       unsigned long   brd;
-       unsigned long   type;
-       unsigned long   hwid;
-       unsigned long   state;
-       unsigned long   ioaddr;
-       unsigned long   ioaddr2;
-       unsigned long   memaddr;
-       unsigned long   irq;
-       unsigned long   nrpanels;
-       unsigned long   nrports;
-       companel_t      panels[COM_MAXPANELS];
-} combrd_t;
-
-
-/*
- *     Define the ioctl operations for stats stuff.
- */
-#include <linux/ioctl.h>
-
-#define        COM_GETPORTSTATS        _IO('c',30)
-#define        COM_CLRPORTSTATS        _IO('c',31)
-#define        COM_GETBRDSTATS         _IO('c',32)
-
-
-/*
- *     Define the set of ioctls that give user level access to the
- *     private port, panel and board structures. The argument required
- *     will be driver dependent!  
- */
-#define        COM_READPORT            _IO('c',40)
-#define        COM_READBOARD           _IO('c',41)
-#define        COM_READPANEL           _IO('c',42)
-
-/*****************************************************************************/
-#endif
diff --git a/include/linux/generic_serial.h b/include/linux/generic_serial.h
deleted file mode 100644 (file)
index 79b3eb3..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- *  generic_serial.h
- *
- *  Copyright (C) 1998 R.E.Wolff@BitWizard.nl
- *
- *  written for the SX serial driver.
- *
- *  Version 0.1 -- December, 1998.
- */
-
-#ifndef GENERIC_SERIAL_H
-#define GENERIC_SERIAL_H
-
-#warning Use of this header is deprecated.
-#warning Since nobody sets the constants defined here for you, you should not, in any case, use them. Including the header is thus pointless.
-
-/* Flags */
-/* Warning: serial.h defines some ASYNC_ flags, they say they are "only"
-   used in serial.c, but they are also used in all other serial drivers. 
-   Make sure they don't clash with these here... */
-#define GS_TX_INTEN      0x00800000
-#define GS_RX_INTEN      0x00400000
-#define GS_ACTIVE        0x00200000
-
-#define GS_TYPE_NORMAL   1
-
-#define GS_DEBUG_FLUSH   0x00000001
-#define GS_DEBUG_BTR     0x00000002
-#define GS_DEBUG_TERMIOS 0x00000004
-#define GS_DEBUG_STUFF   0x00000008
-#define GS_DEBUG_CLOSE   0x00000010
-#define GS_DEBUG_FLOW    0x00000020
-#define GS_DEBUG_WRITE   0x00000040
-
-#endif
diff --git a/include/linux/istallion.h b/include/linux/istallion.h
deleted file mode 100644 (file)
index ad700a6..0000000
+++ /dev/null
@@ -1,123 +0,0 @@
-/*****************************************************************************/
-
-/*
- *     istallion.h  -- stallion intelligent multiport serial driver.
- *
- *     Copyright (C) 1996-1998  Stallion Technologies
- *     Copyright (C) 1994-1996  Greg Ungerer.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     This program is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *     You should have received a copy of the GNU General Public License
- *     along with this program; if not, write to the Free Software
- *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*****************************************************************************/
-#ifndef        _ISTALLION_H
-#define        _ISTALLION_H
-/*****************************************************************************/
-
-/*
- *     Define important driver constants here.
- */
-#define        STL_MAXBRDS             4
-#define        STL_MAXPANELS           4
-#define        STL_MAXPORTS            64
-#define        STL_MAXCHANS            (STL_MAXPORTS + 1)
-#define        STL_MAXDEVS             (STL_MAXBRDS * STL_MAXPORTS)
-
-
-/*
- *     Define a set of structures to hold all the board/panel/port info
- *     for our ports. These will be dynamically allocated as required at
- *     driver initialization time.
- */
-
-/*
- *     Port and board structures to hold status info about each object.
- *     The board structure contains pointers to structures for each port
- *     connected to it. Panels are not distinguished here, since
- *     communication with the slave board will always be on a per port
- *     basis.
- */
-struct stliport {
-       unsigned long           magic;
-       struct tty_port         port;
-       unsigned int            portnr;
-       unsigned int            panelnr;
-       unsigned int            brdnr;
-       unsigned long           state;
-       unsigned int            devnr;
-       int                     baud_base;
-       int                     custom_divisor;
-       int                     closing_wait;
-       int                     rc;
-       int                     argsize;
-       void                    *argp;
-       unsigned int            rxmarkmsk;
-       wait_queue_head_t       raw_wait;
-       struct asysigs          asig;
-       unsigned long           addr;
-       unsigned long           rxoffset;
-       unsigned long           txoffset;
-       unsigned long           sigs;
-       unsigned long           pflag;
-       unsigned int            rxsize;
-       unsigned int            txsize;
-       unsigned char           reqbit;
-       unsigned char           portidx;
-       unsigned char           portbit;
-};
-
-/*
- *     Use a structure of function pointers to do board level operations.
- *     These include, enable/disable, paging shared memory, interrupting, etc.
- */
-struct stlibrd {
-       unsigned long   magic;
-       unsigned int    brdnr;
-       unsigned int    brdtype;
-       unsigned long   state;
-       unsigned int    nrpanels;
-       unsigned int    nrports;
-       unsigned int    nrdevs;
-       unsigned int    iobase;
-       int             iosize;
-       unsigned long   memaddr;
-       void            __iomem *membase;
-       unsigned long   memsize;
-       int             pagesize;
-       int             hostoffset;
-       int             slaveoffset;
-       int             bitsize;
-       int             enabval;
-       unsigned int    panels[STL_MAXPANELS];
-       int             panelids[STL_MAXPANELS];
-       void            (*init)(struct stlibrd *brdp);
-       void            (*enable)(struct stlibrd *brdp);
-       void            (*reenable)(struct stlibrd *brdp);
-       void            (*disable)(struct stlibrd *brdp);
-       void            __iomem *(*getmemptr)(struct stlibrd *brdp, unsigned long offset, int line);
-       void            (*intr)(struct stlibrd *brdp);
-       void            (*reset)(struct stlibrd *brdp);
-       struct stliport *ports[STL_MAXPORTS];
-};
-
-
-/*
- *     Define MAGIC numbers used for above structures.
- */
-#define        STLI_PORTMAGIC  0xe671c7a1
-#define        STLI_BOARDMAGIC 0x4bc6c825
-
-/*****************************************************************************/
-#endif
index daf4a3a40ee0e4ed7d5e29be6b6a342f11ed487b..b7c8cdc1d4223b4565d7c1ede7e10229621cca97 100644 (file)
@@ -65,7 +65,6 @@ struct kbd_struct {
 
 extern int kbd_init(void);
 
-extern unsigned char getledstate(void);
 extern void setledstate(struct kbd_struct *kbd, unsigned int led);
 
 extern int do_poke_blanked_console;
@@ -145,16 +144,4 @@ void compute_shiftstate(void);
 
 extern unsigned int keymap_count;
 
-/* console.c */
-
-static inline void con_schedule_flip(struct tty_struct *t)
-{
-       unsigned long flags;
-       spin_lock_irqsave(&t->buf.lock, flags);
-       if (t->buf.tail != NULL)
-               t->buf.tail->commit = t->buf.tail->used;
-       spin_unlock_irqrestore(&t->buf.lock, flags);
-       schedule_work(&t->buf.work);
-}
-
 #endif
diff --git a/include/linux/sc26198.h b/include/linux/sc26198.h
deleted file mode 100644 (file)
index 7ca35ab..0000000
+++ /dev/null
@@ -1,533 +0,0 @@
-/*****************************************************************************/
-
-/*
- *     sc26198.h  -- SC26198 UART hardware info.
- *
- *     Copyright (C) 1995-1998  Stallion Technologies
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     This program is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *     You should have received a copy of the GNU General Public License
- *     along with this program; if not, write to the Free Software
- *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*****************************************************************************/
-#ifndef        _SC26198_H
-#define        _SC26198_H
-/*****************************************************************************/
-
-/*
- *     Define the number of async ports per sc26198 uart device.
- */
-#define        SC26198_PORTS           8
-
-/*
- *     Baud rate timing clocks. All derived from a master 14.7456 MHz clock.
- */
-#define        SC26198_MASTERCLOCK     14745600L
-#define        SC26198_DCLK            (SC26198_MASTERCLOCK)
-#define        SC26198_CCLK            (SC26198_MASTERCLOCK / 2)
-#define        SC26198_BCLK            (SC26198_MASTERCLOCK / 4)
-
-/*
- *     Define internal FIFO sizes for the 26198 ports.
- */
-#define        SC26198_TXFIFOSIZE      16
-#define        SC26198_RXFIFOSIZE      16
-
-/*****************************************************************************/
-
-/*
- *     Global register definitions. These registers are global to each 26198
- *     device, not specific ports on it.
- */
-#define        TSTR            0x0d
-#define        GCCR            0x0f
-#define        ICR             0x1b
-#define        WDTRCR          0x1d
-#define        IVR             0x1f
-#define        BRGTRUA         0x84
-#define        GPOSR           0x87
-#define        GPOC            0x8b
-#define        UCIR            0x8c
-#define        CIR             0x8c
-#define        BRGTRUB         0x8d
-#define        GRXFIFO         0x8e
-#define        GTXFIFO         0x8e
-#define        GCCR2           0x8f
-#define        BRGTRLA         0x94
-#define        GPOR            0x97
-#define        GPOD            0x9b
-#define        BRGTCR          0x9c
-#define        GICR            0x9c
-#define        BRGTRLB         0x9d
-#define        GIBCR           0x9d
-#define        GITR            0x9f
-
-/*
- *     Per port channel registers. These are the register offsets within
- *     the port address space, so need to have the port address (0 to 7)
- *     inserted in bit positions 4:6.
- */
-#define        MR0             0x00
-#define        MR1             0x01
-#define        IOPCR           0x02
-#define        BCRBRK          0x03
-#define        BCRCOS          0x04
-#define        BCRX            0x06
-#define        BCRA            0x07
-#define        XONCR           0x08
-#define        XOFFCR          0x09
-#define        ARCR            0x0a
-#define        RXCSR           0x0c
-#define        TXCSR           0x0e
-#define        MR2             0x80
-#define        SR              0x81
-#define SCCR           0x81
-#define        ISR             0x82
-#define        IMR             0x82
-#define        TXFIFO          0x83
-#define        RXFIFO          0x83
-#define        IPR             0x84
-#define        IOPIOR          0x85
-#define        XISR            0x86
-
-/*
- *     For any given port calculate the address to use to access a specified
- *     register. This is only used for unusual access, mostly this is done
- *     through the assembler access routines.
- */
-#define        SC26198_PORTREG(port,reg)       ((((port) & 0x07) << 4) | (reg))
-
-/*****************************************************************************/
-
-/*
- *     Global configuration control register bit definitions.
- */
-#define        GCCR_NOACK              0x00
-#define        GCCR_IVRACK             0x02
-#define        GCCR_IVRCHANACK         0x04
-#define        GCCR_IVRTYPCHANACK      0x06
-#define        GCCR_ASYNCCYCLE         0x00
-#define        GCCR_SYNCCYCLE          0x40
-
-/*****************************************************************************/
-
-/*
- *     Mode register 0 bit definitions.
- */
-#define        MR0_ADDRNONE            0x00
-#define        MR0_AUTOWAKE            0x01
-#define        MR0_AUTODOZE            0x02
-#define        MR0_AUTOWAKEDOZE        0x03
-#define        MR0_SWFNONE             0x00
-#define        MR0_SWFTX               0x04
-#define        MR0_SWFRX               0x08
-#define        MR0_SWFRXTX             0x0c
-#define        MR0_TXMASK              0x30
-#define        MR0_TXEMPTY             0x00
-#define        MR0_TXHIGH              0x10
-#define        MR0_TXHALF              0x20
-#define        MR0_TXRDY               0x00
-#define        MR0_ADDRNT              0x00
-#define        MR0_ADDRT               0x40
-#define        MR0_SWFNT               0x00
-#define        MR0_SWFT                0x80
-
-/*
- *     Mode register 1 bit definitions.
- */
-#define        MR1_CS5                 0x00
-#define        MR1_CS6                 0x01
-#define        MR1_CS7                 0x02
-#define        MR1_CS8                 0x03
-#define        MR1_PAREVEN             0x00
-#define        MR1_PARODD              0x04
-#define        MR1_PARENB              0x00
-#define        MR1_PARFORCE            0x08
-#define        MR1_PARNONE             0x10
-#define        MR1_PARSPECIAL          0x18
-#define        MR1_ERRCHAR             0x00
-#define        MR1_ERRBLOCK            0x20
-#define        MR1_ISRUNMASKED         0x00
-#define        MR1_ISRMASKED           0x40
-#define        MR1_AUTORTS             0x80
-
-/*
- *     Mode register 2 bit definitions.
- */
-#define        MR2_STOP1               0x00
-#define        MR2_STOP15              0x01
-#define        MR2_STOP2               0x02
-#define        MR2_STOP916             0x03
-#define        MR2_RXFIFORDY           0x00
-#define        MR2_RXFIFOHALF          0x04
-#define        MR2_RXFIFOHIGH          0x08
-#define        MR2_RXFIFOFULL          0x0c
-#define        MR2_AUTOCTS             0x10
-#define        MR2_TXRTS               0x20
-#define        MR2_MODENORM            0x00
-#define        MR2_MODEAUTOECHO        0x40
-#define        MR2_MODELOOP            0x80
-#define        MR2_MODEREMECHO         0xc0
-
-/*****************************************************************************/
-
-/*
- *     Baud Rate Generator (BRG) selector values.
- */
-#define        BRG_50                  0x00
-#define        BRG_75                  0x01
-#define        BRG_150                 0x02
-#define        BRG_200                 0x03
-#define        BRG_300                 0x04
-#define        BRG_450                 0x05
-#define        BRG_600                 0x06
-#define        BRG_900                 0x07
-#define        BRG_1200                0x08
-#define        BRG_1800                0x09
-#define        BRG_2400                0x0a
-#define        BRG_3600                0x0b
-#define        BRG_4800                0x0c
-#define        BRG_7200                0x0d
-#define        BRG_9600                0x0e
-#define        BRG_14400               0x0f
-#define        BRG_19200               0x10
-#define        BRG_28200               0x11
-#define        BRG_38400               0x12
-#define        BRG_57600               0x13
-#define        BRG_115200              0x14
-#define        BRG_230400              0x15
-#define        BRG_GIN0                0x16
-#define        BRG_GIN1                0x17
-#define        BRG_CT0                 0x18
-#define        BRG_CT1                 0x19
-#define        BRG_RX2TX316            0x1b
-#define        BRG_RX2TX31             0x1c
-
-#define        SC26198_MAXBAUD         921600
-
-/*****************************************************************************/
-
-/*
- *     Command register command definitions.
- */
-#define        CR_NULL                 0x04
-#define        CR_ADDRNORMAL           0x0c
-#define        CR_RXRESET              0x14
-#define        CR_TXRESET              0x1c
-#define        CR_CLEARRXERR           0x24
-#define        CR_BREAKRESET           0x2c
-#define        CR_TXSTARTBREAK         0x34
-#define        CR_TXSTOPBREAK          0x3c
-#define        CR_RTSON                0x44
-#define        CR_RTSOFF               0x4c
-#define        CR_ADDRINIT             0x5c
-#define        CR_RXERRBLOCK           0x6c
-#define        CR_TXSENDXON            0x84
-#define        CR_TXSENDXOFF           0x8c
-#define        CR_GANGXONSET           0x94
-#define        CR_GANGXOFFSET          0x9c
-#define        CR_GANGXONINIT          0xa4
-#define        CR_GANGXOFFINIT         0xac
-#define        CR_HOSTXON              0xb4
-#define        CR_HOSTXOFF             0xbc
-#define        CR_CANCELXOFF           0xc4
-#define        CR_ADDRRESET            0xdc
-#define        CR_RESETALLPORTS        0xf4
-#define        CR_RESETALL             0xfc
-
-#define        CR_RXENABLE             0x01
-#define        CR_TXENABLE             0x02
-
-/*****************************************************************************/
-
-/*
- *     Channel status register.
- */
-#define        SR_RXRDY                0x01
-#define        SR_RXFULL               0x02
-#define        SR_TXRDY                0x04
-#define        SR_TXEMPTY              0x08
-#define        SR_RXOVERRUN            0x10
-#define        SR_RXPARITY             0x20
-#define        SR_RXFRAMING            0x40
-#define        SR_RXBREAK              0x80
-
-#define        SR_RXERRS               (SR_RXPARITY | SR_RXFRAMING | SR_RXOVERRUN)
-
-/*****************************************************************************/
-
-/*
- *     Interrupt status register and interrupt mask register bit definitions.
- */
-#define        IR_TXRDY                0x01
-#define        IR_RXRDY                0x02
-#define        IR_RXBREAK              0x04
-#define        IR_XONXOFF              0x10
-#define        IR_ADDRRECOG            0x20
-#define        IR_RXWATCHDOG           0x40
-#define        IR_IOPORT               0x80
-
-/*****************************************************************************/
-
-/*
- *     Interrupt vector register field definitions.
- */
-#define        IVR_CHANMASK            0x07
-#define        IVR_TYPEMASK            0x18
-#define        IVR_CONSTMASK           0xc0
-
-#define        IVR_RXDATA              0x10
-#define        IVR_RXBADDATA           0x18
-#define        IVR_TXDATA              0x08
-#define        IVR_OTHER               0x00
-
-/*****************************************************************************/
-
-/*
- *     BRG timer control register bit definitions.
- */
-#define        BRGCTCR_DISABCLK0       0x00
-#define        BRGCTCR_ENABCLK0        0x08
-#define        BRGCTCR_DISABCLK1       0x00
-#define        BRGCTCR_ENABCLK1        0x80
-
-#define        BRGCTCR_0SCLK16         0x00
-#define        BRGCTCR_0SCLK32         0x01
-#define        BRGCTCR_0SCLK64         0x02
-#define        BRGCTCR_0SCLK128        0x03
-#define        BRGCTCR_0X1             0x04
-#define        BRGCTCR_0X12            0x05
-#define        BRGCTCR_0IO1A           0x06
-#define        BRGCTCR_0GIN0           0x07
-
-#define        BRGCTCR_1SCLK16         0x00
-#define        BRGCTCR_1SCLK32         0x10
-#define        BRGCTCR_1SCLK64         0x20
-#define        BRGCTCR_1SCLK128        0x30
-#define        BRGCTCR_1X1             0x40
-#define        BRGCTCR_1X12            0x50
-#define        BRGCTCR_1IO1B           0x60
-#define        BRGCTCR_1GIN1           0x70
-
-/*****************************************************************************/
-
-/*
- *     Watch dog timer enable register.
- */
-#define        WDTRCR_ENABALL          0xff
-
-/*****************************************************************************/
-
-/*
- *     XON/XOFF interrupt status register.
- */
-#define        XISR_TXCHARMASK         0x03
-#define        XISR_TXCHARNORMAL       0x00
-#define        XISR_TXWAIT             0x01
-#define        XISR_TXXOFFPEND         0x02
-#define        XISR_TXXONPEND          0x03
-
-#define        XISR_TXFLOWMASK         0x0c
-#define        XISR_TXNORMAL           0x00
-#define        XISR_TXSTOPPEND         0x04
-#define        XISR_TXSTARTED          0x08
-#define        XISR_TXSTOPPED          0x0c
-
-#define        XISR_RXFLOWMASK         0x30
-#define        XISR_RXFLOWNONE         0x00
-#define        XISR_RXXONSENT          0x10
-#define        XISR_RXXOFFSENT         0x20
-
-#define        XISR_RXXONGOT           0x40
-#define        XISR_RXXOFFGOT          0x80
-
-/*****************************************************************************/
-
-/*
- *     Current interrupt register.
- */
-#define        CIR_TYPEMASK            0xc0
-#define        CIR_TYPEOTHER           0x00
-#define        CIR_TYPETX              0x40
-#define        CIR_TYPERXGOOD          0x80
-#define        CIR_TYPERXBAD           0xc0
-
-#define        CIR_RXDATA              0x80
-#define        CIR_RXBADDATA           0x40
-#define        CIR_TXDATA              0x40
-
-#define        CIR_CHANMASK            0x07
-#define        CIR_CNTMASK             0x38
-
-#define        CIR_SUBTYPEMASK         0x38
-#define        CIR_SUBNONE             0x00
-#define        CIR_SUBCOS              0x08
-#define        CIR_SUBADDR             0x10
-#define        CIR_SUBXONXOFF          0x18
-#define        CIR_SUBBREAK            0x28
-
-/*****************************************************************************/
-
-/*
- *     Global interrupting channel register.
- */
-#define        GICR_CHANMASK           0x07
-
-/*****************************************************************************/
-
-/*
- *     Global interrupting byte count register.
- */
-#define        GICR_COUNTMASK          0x0f
-
-/*****************************************************************************/
-
-/*
- *     Global interrupting type register.
- */
-#define        GITR_RXMASK             0xc0
-#define        GITR_RXNONE             0x00
-#define        GITR_RXBADDATA          0x80
-#define        GITR_RXGOODDATA         0xc0
-#define        GITR_TXDATA             0x20
-
-#define        GITR_SUBTYPEMASK        0x07
-#define        GITR_SUBNONE            0x00
-#define        GITR_SUBCOS             0x01
-#define        GITR_SUBADDR            0x02
-#define        GITR_SUBXONXOFF         0x03
-#define        GITR_SUBBREAK           0x05
-
-/*****************************************************************************/
-
-/*
- *     Input port change register.
- */
-#define        IPR_CTS                 0x01
-#define        IPR_DTR                 0x02
-#define        IPR_RTS                 0x04
-#define        IPR_DCD                 0x08
-#define        IPR_CTSCHANGE           0x10
-#define        IPR_DTRCHANGE           0x20
-#define        IPR_RTSCHANGE           0x40
-#define        IPR_DCDCHANGE           0x80
-
-#define        IPR_CHANGEMASK          0xf0
-
-/*****************************************************************************/
-
-/*
- *     IO port interrupt and output register.
- */
-#define        IOPR_CTS                0x01
-#define        IOPR_DTR                0x02
-#define        IOPR_RTS                0x04
-#define        IOPR_DCD                0x08
-#define        IOPR_CTSCOS             0x10
-#define        IOPR_DTRCOS             0x20
-#define        IOPR_RTSCOS             0x40
-#define        IOPR_DCDCOS             0x80
-
-/*****************************************************************************/
-
-/*
- *     IO port configuration register.
- */
-#define        IOPCR_SETCTS            0x00
-#define        IOPCR_SETDTR            0x04
-#define        IOPCR_SETRTS            0x10
-#define        IOPCR_SETDCD            0x00
-
-#define        IOPCR_SETSIGS           (IOPCR_SETRTS | IOPCR_SETRTS | IOPCR_SETDTR | IOPCR_SETDCD)
-
-/*****************************************************************************/
-
-/*
- *     General purpose output select register.
- */
-#define        GPORS_TXC1XA            0x08
-#define        GPORS_TXC16XA           0x09
-#define        GPORS_RXC16XA           0x0a
-#define        GPORS_TXC16XB           0x0b
-#define        GPORS_GPOR3             0x0c
-#define        GPORS_GPOR2             0x0d
-#define        GPORS_GPOR1             0x0e
-#define        GPORS_GPOR0             0x0f
-
-/*****************************************************************************/
-
-/*
- *     General purpose output register.
- */
-#define        GPOR_0                  0x01
-#define        GPOR_1                  0x02
-#define        GPOR_2                  0x04
-#define        GPOR_3                  0x08
-
-/*****************************************************************************/
-
-/*
- *     General purpose output clock register.
- */
-#define        GPORC_0NONE             0x00
-#define        GPORC_0GIN0             0x01
-#define        GPORC_0GIN1             0x02
-#define        GPORC_0IO3A             0x02
-
-#define        GPORC_1NONE             0x00
-#define        GPORC_1GIN0             0x04
-#define        GPORC_1GIN1             0x08
-#define        GPORC_1IO3C             0x0c
-
-#define        GPORC_2NONE             0x00
-#define        GPORC_2GIN0             0x10
-#define        GPORC_2GIN1             0x20
-#define        GPORC_2IO3E             0x20
-
-#define        GPORC_3NONE             0x00
-#define        GPORC_3GIN0             0x40
-#define        GPORC_3GIN1             0x80
-#define        GPORC_3IO3G             0xc0
-
-/*****************************************************************************/
-
-/*
- *     General purpose output data register.
- */
-#define        GPOD_0MASK              0x03
-#define        GPOD_0SET1              0x00
-#define        GPOD_0SET0              0x01
-#define        GPOD_0SETR0             0x02
-#define        GPOD_0SETIO3B           0x03
-
-#define        GPOD_1MASK              0x0c
-#define        GPOD_1SET1              0x00
-#define        GPOD_1SET0              0x04
-#define        GPOD_1SETR0             0x08
-#define        GPOD_1SETIO3D           0x0c
-
-#define        GPOD_2MASK              0x30
-#define        GPOD_2SET1              0x00
-#define        GPOD_2SET0              0x10
-#define        GPOD_2SETR0             0x20
-#define        GPOD_2SETIO3F           0x30
-
-#define        GPOD_3MASK              0xc0
-#define        GPOD_3SET1              0x00
-#define        GPOD_3SET0              0x40
-#define        GPOD_3SETR0             0x80
-#define        GPOD_3SETIO3H           0xc0
-
-/*****************************************************************************/
-#endif
diff --git a/include/linux/serial167.h b/include/linux/serial167.h
deleted file mode 100644 (file)
index 59c81b7..0000000
+++ /dev/null
@@ -1,157 +0,0 @@
-/*
- * serial167.h
- *
- * Richard Hirst [richard@sleepie.demon.co.uk]
- *
- * Based on cyclades.h
- */
-
-struct cyclades_monitor {
-        unsigned long           int_count;
-        unsigned long           char_count;
-        unsigned long           char_max;
-        unsigned long           char_last;
-};
-
-/*
- * This is our internal structure for each serial port's state.
- * 
- * Many fields are paralleled by the structure used by the serial_struct
- * structure.
- *
- * For definitions of the flags field, see tty.h
- */
-
-struct cyclades_port {
-       int                     magic;
-       int                     type;
-       int                     card;
-       int                     line;
-       int                     flags;          /* defined in tty.h */
-       struct tty_struct       *tty;
-       int                     read_status_mask;
-       int                     timeout;
-       int                     xmit_fifo_size;
-       int                     cor1,cor2,cor3,cor4,cor5,cor6,cor7;
-       int                     tbpr,tco,rbpr,rco;
-       int                     ignore_status_mask;
-       int                     close_delay;
-       int                     IER;    /* Interrupt Enable Register */
-       unsigned long           last_active;
-       int                     count;  /* # of fd on device */
-       int                     x_char; /* to be pushed out ASAP */
-       int                     x_break;
-       int                     blocked_open; /* # of blocked opens */
-       unsigned char           *xmit_buf;
-       int                     xmit_head;
-       int                     xmit_tail;
-       int                     xmit_cnt;
-        int                     default_threshold;
-        int                     default_timeout;
-       wait_queue_head_t       open_wait;
-       wait_queue_head_t       close_wait;
-        struct cyclades_monitor mon;
-};
-
-#define CYCLADES_MAGIC  0x4359
-
-#define CYGETMON                0x435901
-#define CYGETTHRESH             0x435902
-#define CYSETTHRESH             0x435903
-#define CYGETDEFTHRESH          0x435904
-#define CYSETDEFTHRESH          0x435905
-#define CYGETTIMEOUT            0x435906
-#define CYSETTIMEOUT            0x435907
-#define CYGETDEFTIMEOUT         0x435908
-#define CYSETDEFTIMEOUT         0x435909
-
-#define CyMaxChipsPerCard 1
-
-/**** cd2401 registers ****/
-
-#define CyGFRCR         (0x81)
-#define CyCCR          (0x13)
-#define      CyCLR_CHAN                (0x40)
-#define      CyINIT_CHAN       (0x20)
-#define      CyCHIP_RESET      (0x10)
-#define      CyENB_XMTR                (0x08)
-#define      CyDIS_XMTR                (0x04)
-#define      CyENB_RCVR                (0x02)
-#define      CyDIS_RCVR                (0x01)
-#define CyCAR          (0xee)
-#define CyIER          (0x11)
-#define      CyMdmCh           (0x80)
-#define      CyRxExc           (0x20)
-#define      CyRxData          (0x08)
-#define      CyTxMpty          (0x02)
-#define      CyTxRdy           (0x01)
-#define CyLICR         (0x26)
-#define CyRISR         (0x89)
-#define      CyTIMEOUT         (0x80)
-#define      CySPECHAR         (0x70)
-#define      CyOVERRUN         (0x08)
-#define      CyPARITY          (0x04)
-#define      CyFRAME           (0x02)
-#define      CyBREAK           (0x01)
-#define CyREOIR                (0x84)
-#define CyTEOIR                (0x85)
-#define CyMEOIR                (0x86)
-#define      CyNOTRANS         (0x08)
-#define CyRFOC         (0x30)
-#define CyRDR          (0xf8)
-#define CyTDR          (0xf8)
-#define CyMISR         (0x8b)
-#define CyRISR         (0x89)
-#define CyTISR         (0x8a)
-#define CyMSVR1                (0xde)
-#define CyMSVR2                (0xdf)
-#define      CyDSR             (0x80)
-#define      CyDCD             (0x40)
-#define      CyCTS             (0x20)
-#define      CyDTR             (0x02)
-#define      CyRTS             (0x01)
-#define CyRTPRL                (0x25)
-#define CyRTPRH                (0x24)
-#define CyCOR1         (0x10)
-#define      CyPARITY_NONE     (0x00)
-#define      CyPARITY_E                (0x40)
-#define      CyPARITY_O                (0xC0)
-#define      Cy_5_BITS         (0x04)
-#define      Cy_6_BITS         (0x05)
-#define      Cy_7_BITS         (0x06)
-#define      Cy_8_BITS         (0x07)
-#define CyCOR2         (0x17)
-#define      CyETC             (0x20)
-#define      CyCtsAE           (0x02)
-#define CyCOR3         (0x16)
-#define      Cy_1_STOP         (0x02)
-#define      Cy_2_STOP         (0x04)
-#define CyCOR4         (0x15)
-#define      CyREC_FIFO                (0x0F)  /* Receive FIFO threshold */
-#define CyCOR5         (0x14)
-#define CyCOR6         (0x18)
-#define CyCOR7         (0x07)
-#define CyRBPR         (0xcb)
-#define CyRCOR         (0xc8)
-#define CyTBPR         (0xc3)
-#define CyTCOR         (0xc0)
-#define CySCHR1                (0x1f)
-#define CySCHR2        (0x1e)
-#define CyTPR          (0xda)
-#define CyPILR1                (0xe3)
-#define CyPILR2                (0xe0)
-#define CyPILR3                (0xe1)
-#define CyCMR          (0x1b)
-#define      CyASYNC           (0x02)
-#define CyLICR          (0x26)
-#define CyLIVR          (0x09)
-#define CySCRL         (0x23)
-#define CySCRH         (0x22)
-#define CyTFTC         (0x80)
-
-
-/* max number of chars in the FIFO */
-
-#define CyMAX_CHAR_FIFO        12
-
-/***************************************************************************/
index a416e92012ef72db74f1d9ffe2c54bbe2c98b217..c174c90fb3fbcbb56abb5096f40ee559a75aeb94 100644 (file)
@@ -65,11 +65,38 @@ enum {
  * platform device.  Using these will make your driver
  * dependent on the 8250 driver.
  */
-struct uart_port;
-struct uart_8250_port;
+
+struct uart_8250_port {
+       struct uart_port        port;
+       struct timer_list       timer;          /* "no irq" timer */
+       struct list_head        list;           /* ports on this IRQ */
+       unsigned short          capabilities;   /* port capabilities */
+       unsigned short          bugs;           /* port bugs */
+       unsigned int            tx_loadsz;      /* transmit fifo load size */
+       unsigned char           acr;
+       unsigned char           ier;
+       unsigned char           lcr;
+       unsigned char           mcr;
+       unsigned char           mcr_mask;       /* mask of user bits */
+       unsigned char           mcr_force;      /* mask of forced bits */
+       unsigned char           cur_iotype;     /* Running I/O type */
+
+       /*
+        * Some bits in registers are cleared on a read, so they must
+        * be saved whenever the register is read but the bits will not
+        * be immediately processed.
+        */
+#define LSR_SAVE_FLAGS UART_LSR_BRK_ERROR_BITS
+       unsigned char           lsr_saved_flags;
+#define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
+       unsigned char           msr_saved_flags;
+
+       /* 8250 specific callbacks */
+       int                     (*dl_read)(struct uart_8250_port *);
+       void                    (*dl_write)(struct uart_8250_port *, int);
+};
 
 int serial8250_register_8250_port(struct uart_8250_port *);
-int serial8250_register_port(struct uart_port *);
 void serial8250_unregister_port(int line);
 void serial8250_suspend_port(int line);
 void serial8250_resume_port(int line);
diff --git a/include/linux/stallion.h b/include/linux/stallion.h
deleted file mode 100644 (file)
index 336af33..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-/*****************************************************************************/
-
-/*
- *     stallion.h  -- stallion multiport serial driver.
- *
- *     Copyright (C) 1996-1998  Stallion Technologies
- *     Copyright (C) 1994-1996  Greg Ungerer.
- *
- *     This program is free software; you can redistribute it and/or modify
- *     it under the terms of the GNU General Public License as published by
- *     the Free Software Foundation; either version 2 of the License, or
- *     (at your option) any later version.
- *
- *     This program is distributed in the hope that it will be useful,
- *     but WITHOUT ANY WARRANTY; without even the implied warranty of
- *     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *     GNU General Public License for more details.
- *
- *     You should have received a copy of the GNU General Public License
- *     along with this program; if not, write to the Free Software
- *     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-/*****************************************************************************/
-#ifndef        _STALLION_H
-#define        _STALLION_H
-/*****************************************************************************/
-
-/*
- *     Define important driver constants here.
- */
-#define        STL_MAXBRDS             4
-#define        STL_MAXPANELS           4
-#define        STL_MAXBANKS            8
-#define        STL_PORTSPERPANEL       16
-#define        STL_MAXPORTS            64
-#define        STL_MAXDEVS             (STL_MAXBRDS * STL_MAXPORTS)
-
-
-/*
- *     Define a set of structures to hold all the board/panel/port info
- *     for our ports. These will be dynamically allocated as required.
- */
-
-/*
- *     Define a ring queue structure for each port. This will hold the
- *     TX data waiting to be output. Characters are fed into this buffer
- *     from the line discipline (or even direct from user space!) and
- *     then fed into the UARTs during interrupts. Will use a classic ring
- *     queue here for this. The good thing about this type of ring queue
- *     is that the head and tail pointers can be updated without interrupt
- *     protection - since "write" code only needs to change the head, and
- *     interrupt code only needs to change the tail.
- */
-struct stlrq {
-       char    *buf;
-       char    *head;
-       char    *tail;
-};
-
-/*
- *     Port, panel and board structures to hold status info about each.
- *     The board structure contains pointers to structures for each panel
- *     connected to it, and in turn each panel structure contains pointers
- *     for each port structure for each port on that panel. Note that
- *     the port structure also contains the board and panel number that it
- *     is associated with, this makes it (fairly) easy to get back to the
- *     board/panel info for a port.
- */
-struct stlport {
-       unsigned long           magic;
-       struct tty_port         port;
-       unsigned int            portnr;
-       unsigned int            panelnr;
-       unsigned int            brdnr;
-       int                     ioaddr;
-       int                     uartaddr;
-       unsigned int            pagenr;
-       unsigned long           istate;
-       int                     baud_base;
-       int                     custom_divisor;
-       int                     close_delay;
-       int                     closing_wait;
-       int                     openwaitcnt;
-       int                     brklen;
-       unsigned int            sigs;
-       unsigned int            rxignoremsk;
-       unsigned int            rxmarkmsk;
-       unsigned int            imr;
-       unsigned int            crenable;
-       unsigned long           clk;
-       unsigned long           hwid;
-       void                    *uartp;
-       comstats_t              stats;
-       struct stlrq            tx;
-};
-
-struct stlpanel {
-       unsigned long   magic;
-       unsigned int    panelnr;
-       unsigned int    brdnr;
-       unsigned int    pagenr;
-       unsigned int    nrports;
-       int             iobase;
-       void            *uartp;
-       void            (*isr)(struct stlpanel *panelp, unsigned int iobase);
-       unsigned int    hwid;
-       unsigned int    ackmask;
-       struct stlport  *ports[STL_PORTSPERPANEL];
-};
-
-struct stlbrd {
-       unsigned long   magic;
-       unsigned int    brdnr;
-       unsigned int    brdtype;
-       unsigned int    state;
-       unsigned int    nrpanels;
-       unsigned int    nrports;
-       unsigned int    nrbnks;
-       int             irq;
-       int             irqtype;
-       int             (*isr)(struct stlbrd *brdp);
-       unsigned int    ioaddr1;
-       unsigned int    ioaddr2;
-       unsigned int    iosize1;
-       unsigned int    iosize2;
-       unsigned int    iostatus;
-       unsigned int    ioctrl;
-       unsigned int    ioctrlval;
-       unsigned int    hwid;
-       unsigned long   clk;
-       unsigned int    bnkpageaddr[STL_MAXBANKS];
-       unsigned int    bnkstataddr[STL_MAXBANKS];
-       struct stlpanel *bnk2panel[STL_MAXBANKS];
-       struct stlpanel *panels[STL_MAXPANELS];
-};
-
-
-/*
- *     Define MAGIC numbers used for above structures.
- */
-#define        STL_PORTMAGIC   0x5a7182c9
-#define        STL_PANELMAGIC  0x7ef621a1
-#define        STL_BOARDMAGIC  0xa2267f52
-
-/*****************************************************************************/
-#endif
index 9f47ab540f65e997b79b0a16c52332c564354234..a39e72325e781a129d05b6936670b66f92071652 100644 (file)
@@ -103,28 +103,28 @@ struct tty_bufhead {
 #define TTY_PARITY     3
 #define TTY_OVERRUN    4
 
-#define INTR_CHAR(tty) ((tty)->termios->c_cc[VINTR])
-#define QUIT_CHAR(tty) ((tty)->termios->c_cc[VQUIT])
-#define ERASE_CHAR(tty) ((tty)->termios->c_cc[VERASE])
-#define KILL_CHAR(tty) ((tty)->termios->c_cc[VKILL])
-#define EOF_CHAR(tty) ((tty)->termios->c_cc[VEOF])
-#define TIME_CHAR(tty) ((tty)->termios->c_cc[VTIME])
-#define MIN_CHAR(tty) ((tty)->termios->c_cc[VMIN])
-#define SWTC_CHAR(tty) ((tty)->termios->c_cc[VSWTC])
-#define START_CHAR(tty) ((tty)->termios->c_cc[VSTART])
-#define STOP_CHAR(tty) ((tty)->termios->c_cc[VSTOP])
-#define SUSP_CHAR(tty) ((tty)->termios->c_cc[VSUSP])
-#define EOL_CHAR(tty) ((tty)->termios->c_cc[VEOL])
-#define REPRINT_CHAR(tty) ((tty)->termios->c_cc[VREPRINT])
-#define DISCARD_CHAR(tty) ((tty)->termios->c_cc[VDISCARD])
-#define WERASE_CHAR(tty) ((tty)->termios->c_cc[VWERASE])
-#define LNEXT_CHAR(tty)        ((tty)->termios->c_cc[VLNEXT])
-#define EOL2_CHAR(tty) ((tty)->termios->c_cc[VEOL2])
-
-#define _I_FLAG(tty, f)        ((tty)->termios->c_iflag & (f))
-#define _O_FLAG(tty, f)        ((tty)->termios->c_oflag & (f))
-#define _C_FLAG(tty, f)        ((tty)->termios->c_cflag & (f))
-#define _L_FLAG(tty, f)        ((tty)->termios->c_lflag & (f))
+#define INTR_CHAR(tty) ((tty)->termios.c_cc[VINTR])
+#define QUIT_CHAR(tty) ((tty)->termios.c_cc[VQUIT])
+#define ERASE_CHAR(tty) ((tty)->termios.c_cc[VERASE])
+#define KILL_CHAR(tty) ((tty)->termios.c_cc[VKILL])
+#define EOF_CHAR(tty) ((tty)->termios.c_cc[VEOF])
+#define TIME_CHAR(tty) ((tty)->termios.c_cc[VTIME])
+#define MIN_CHAR(tty) ((tty)->termios.c_cc[VMIN])
+#define SWTC_CHAR(tty) ((tty)->termios.c_cc[VSWTC])
+#define START_CHAR(tty) ((tty)->termios.c_cc[VSTART])
+#define STOP_CHAR(tty) ((tty)->termios.c_cc[VSTOP])
+#define SUSP_CHAR(tty) ((tty)->termios.c_cc[VSUSP])
+#define EOL_CHAR(tty) ((tty)->termios.c_cc[VEOL])
+#define REPRINT_CHAR(tty) ((tty)->termios.c_cc[VREPRINT])
+#define DISCARD_CHAR(tty) ((tty)->termios.c_cc[VDISCARD])
+#define WERASE_CHAR(tty) ((tty)->termios.c_cc[VWERASE])
+#define LNEXT_CHAR(tty)        ((tty)->termios.c_cc[VLNEXT])
+#define EOL2_CHAR(tty) ((tty)->termios.c_cc[VEOL2])
+
+#define _I_FLAG(tty, f)        ((tty)->termios.c_iflag & (f))
+#define _O_FLAG(tty, f)        ((tty)->termios.c_oflag & (f))
+#define _C_FLAG(tty, f)        ((tty)->termios.c_cflag & (f))
+#define _L_FLAG(tty, f)        ((tty)->termios.c_lflag & (f))
 
 #define I_IGNBRK(tty)  _I_FLAG((tty), IGNBRK)
 #define I_BRKINT(tty)  _I_FLAG((tty), BRKINT)
@@ -271,7 +271,7 @@ struct tty_struct {
        struct mutex termios_mutex;
        spinlock_t ctrl_lock;
        /* Termios values are protected by the termios mutex */
-       struct ktermios *termios, *termios_locked;
+       struct ktermios termios, termios_locked;
        struct termiox *termiox;        /* May be NULL for unsupported */
        char name[64];
        struct pid *pgrp;               /* Protected by ctrl lock */
@@ -423,7 +423,6 @@ extern void tty_unthrottle(struct tty_struct *tty);
 extern int tty_do_resize(struct tty_struct *tty, struct winsize *ws);
 extern void tty_driver_remove_tty(struct tty_driver *driver,
                                  struct tty_struct *tty);
-extern void tty_shutdown(struct tty_struct *tty);
 extern void tty_free_termios(struct tty_struct *tty);
 extern int is_current_pgrp_orphaned(void);
 extern struct pid *tty_get_pgrp(struct tty_struct *tty);
@@ -497,6 +496,9 @@ extern int tty_write_lock(struct tty_struct *tty, int ndelay);
 #define tty_is_writelocked(tty)  (mutex_is_locked(&tty->atomic_write_lock))
 
 extern void tty_port_init(struct tty_port *port);
+extern struct device *tty_port_register_device(struct tty_port *port,
+               struct tty_driver *driver, unsigned index,
+               struct device *device);
 extern int tty_port_alloc_xmit_buf(struct tty_port *port);
 extern void tty_port_free_xmit_buf(struct tty_port *port);
 extern void tty_port_put(struct tty_port *port);
@@ -521,6 +523,8 @@ extern int tty_port_close_start(struct tty_port *port,
 extern void tty_port_close_end(struct tty_port *port, struct tty_struct *tty);
 extern void tty_port_close(struct tty_port *port,
                                struct tty_struct *tty, struct file *filp);
+extern int tty_port_install(struct tty_port *port, struct tty_driver *driver,
+                               struct tty_struct *tty);
 extern int tty_port_open(struct tty_port *port,
                                struct tty_struct *tty, struct file *filp);
 static inline int tty_port_users(struct tty_port *port)
index 6e6dbb7447b6e76beec4a4115d049e6dd00c4735..80e72dc564a5b2de49f8c17c136adb0ace61682d 100644 (file)
  *
  * void (*shutdown)(struct tty_struct * tty);
  *
- *     This routine is called synchronously when a particular tty device
- *     is closed for the last time freeing up the resources.
- *     Note that tty_shutdown() is not called if ops->shutdown is defined.
- *     This means one is responsible to take care of calling ops->remove (e.g.
- *     via tty_driver_remove_tty) and releasing tty->termios.
- *     Note that this hook may be called from *all* the contexts where one
- *     uses tty refcounting (e.g. tty_port_tty_get).
- *
+ *     This routine is called under the tty lock when a particular tty device
+ *     is closed for the last time. It executes before the tty resources
+ *     are freed so may execute while another function holds a tty kref.
  *
  * void (*cleanup)(struct tty_struct * tty);
  *
@@ -313,6 +308,7 @@ struct tty_driver {
         * Pointer to the tty data structures
         */
        struct tty_struct **ttys;
+       struct tty_port **ports;
        struct ktermios **termios;
        void *driver_state;
 
index 59ba38bc400f43d3e87c1502395cef9a54e5811c..80ffde3bb164e2a3a856838f0c8c4c2906bfeaf6 100644 (file)
 /* Same for payload size. See qos.c for the smallest max data size */
 #define IRCOMM_TTY_DATA_UNINITIALISED  (64 - IRCOMM_TTY_HDR_UNINITIALISED)
 
-/* Those are really defined in include/linux/serial.h - Jean II */
-#define ASYNC_B_INITIALIZED    31      /* Serial port was initialized */
-#define ASYNC_B_NORMAL_ACTIVE  29      /* Normal device is active */
-#define ASYNC_B_CLOSING                27      /* Serial port is closing */
-
 /*
  * IrCOMM TTY driver state
  */
 struct ircomm_tty_cb {
        irda_queue_t queue;            /* Must be first */
+       struct tty_port port;
        magic_t magic;
 
        int state;                /* Connect state */
 
-       struct tty_struct *tty;
        struct ircomm_cb *ircomm; /* IrCOMM layer instance */
 
        struct sk_buff *tx_skb;   /* Transmit buffer */
@@ -80,7 +75,6 @@ struct ircomm_tty_cb {
        LOCAL_FLOW flow;          /* IrTTP flow status */
 
        int line;
-       unsigned long flags;
 
        __u8 dlsap_sel;
        __u8 slsap_sel;
@@ -97,19 +91,10 @@ struct ircomm_tty_cb {
        void *skey;
        void *ckey;
 
-       wait_queue_head_t open_wait;
-       wait_queue_head_t close_wait;
        struct timer_list watchdog_timer;
        struct work_struct  tqueue;
 
-        unsigned short    close_delay;
-        unsigned short    closing_wait; /* time to wait before closing */
-
-       int  open_count;
-       int  blocked_open;      /* # of blocked opens */
-
        /* Protect concurent access to :
-        *      o self->open_count
         *      o self->ctrl_skb
         *      o self->tx_skb
         * Maybe other things may gain to be protected as well...
index cb960773c002efafeb45b888ee8f3ba3e9208490..87ddd051881b26756d102d1ed931b230a39622fc 100644 (file)
@@ -861,7 +861,7 @@ static int rfcomm_tty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned l
 
 static void rfcomm_tty_set_termios(struct tty_struct *tty, struct ktermios *old)
 {
-       struct ktermios *new = tty->termios;
+       struct ktermios *new = &tty->termios;
        int old_baud_rate = tty_termios_baud_rate(old);
        int new_baud_rate = tty_termios_baud_rate(new);
 
index 8b915f3ac3b91a6b2471149799117d8bdd5b8b00..30893912835926a2bbc83ce716a1fdbf242c81a4 100644 (file)
@@ -99,7 +99,6 @@ pi_param_info_t ircomm_param_info = { pi_major_call_table, 3, 0x0f, 4 };
  */
 int ircomm_param_request(struct ircomm_tty_cb *self, __u8 pi, int flush)
 {
-       struct tty_struct *tty;
        unsigned long flags;
        struct sk_buff *skb;
        int count;
@@ -109,10 +108,6 @@ int ircomm_param_request(struct ircomm_tty_cb *self, __u8 pi, int flush)
        IRDA_ASSERT(self != NULL, return -1;);
        IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
 
-       tty = self->tty;
-       if (!tty)
-               return 0;
-
        /* Make sure we don't send parameters for raw mode */
        if (self->service_type == IRCOMM_3_WIRE_RAW)
                return 0;
index 6b9d5a0e42f9fb3753e32c0b167e202657b372b3..7a0d6115d06faf13b7d4d9466db0003ef0271804 100644 (file)
@@ -104,6 +104,35 @@ static const struct tty_operations ops = {
 #endif /* CONFIG_PROC_FS */
 };
 
+static void ircomm_port_raise_dtr_rts(struct tty_port *port, int raise)
+{
+       struct ircomm_tty_cb *self = container_of(port, struct ircomm_tty_cb,
+                       port);
+       /*
+        * Here, we use to lock those two guys, but as ircomm_param_request()
+        * does it itself, I don't see the point (and I see the deadlock).
+        * Jean II
+        */
+       if (raise)
+               self->settings.dte |= IRCOMM_RTS | IRCOMM_DTR;
+       else
+               self->settings.dte &= ~(IRCOMM_RTS | IRCOMM_DTR);
+
+       ircomm_param_request(self, IRCOMM_DTE, TRUE);
+}
+
+static int ircomm_port_carrier_raised(struct tty_port *port)
+{
+       struct ircomm_tty_cb *self = container_of(port, struct ircomm_tty_cb,
+                       port);
+       return self->settings.dce & IRCOMM_CD;
+}
+
+static const struct tty_port_operations ircomm_port_ops = {
+       .dtr_rts = ircomm_port_raise_dtr_rts,
+       .carrier_raised = ircomm_port_carrier_raised,
+};
+
 /*
  * Function ircomm_tty_init()
  *
@@ -194,7 +223,7 @@ static int ircomm_tty_startup(struct ircomm_tty_cb *self)
        IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
 
        /* Check if already open */
-       if (test_and_set_bit(ASYNC_B_INITIALIZED, &self->flags)) {
+       if (test_and_set_bit(ASYNCB_INITIALIZED, &self->port.flags)) {
                IRDA_DEBUG(2, "%s(), already open so break out!\n", __func__ );
                return 0;
        }
@@ -231,7 +260,7 @@ static int ircomm_tty_startup(struct ircomm_tty_cb *self)
 
        return 0;
 err:
-       clear_bit(ASYNC_B_INITIALIZED, &self->flags);
+       clear_bit(ASYNCB_INITIALIZED, &self->port.flags);
        return ret;
 }
 
@@ -242,72 +271,62 @@ err:
  *
  */
 static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
-                                     struct file *filp)
+               struct tty_struct *tty, struct file *filp)
 {
+       struct tty_port *port = &self->port;
        DECLARE_WAITQUEUE(wait, current);
        int             retval;
        int             do_clocal = 0, extra_count = 0;
        unsigned long   flags;
-       struct tty_struct *tty;
 
        IRDA_DEBUG(2, "%s()\n", __func__ );
 
-       tty = self->tty;
-
        /*
         * If non-blocking mode is set, or the port is not enabled,
         * then make the check up front and then exit.
         */
        if (filp->f_flags & O_NONBLOCK || tty->flags & (1 << TTY_IO_ERROR)){
                /* nonblock mode is set or port is not enabled */
-               self->flags |= ASYNC_NORMAL_ACTIVE;
+               port->flags |= ASYNC_NORMAL_ACTIVE;
                IRDA_DEBUG(1, "%s(), O_NONBLOCK requested!\n", __func__ );
                return 0;
        }
 
-       if (tty->termios->c_cflag & CLOCAL) {
+       if (tty->termios.c_cflag & CLOCAL) {
                IRDA_DEBUG(1, "%s(), doing CLOCAL!\n", __func__ );
                do_clocal = 1;
        }
 
        /* Wait for carrier detect and the line to become
         * free (i.e., not in use by the callout).  While we are in
-        * this loop, self->open_count is dropped by one, so that
+        * this loop, port->count is dropped by one, so that
         * mgsl_close() knows when to free things.  We restore it upon
         * exit, either normal or abnormal.
         */
 
        retval = 0;
-       add_wait_queue(&self->open_wait, &wait);
+       add_wait_queue(&port->open_wait, &wait);
 
        IRDA_DEBUG(2, "%s(%d):block_til_ready before block on %s open_count=%d\n",
-             __FILE__,__LINE__, tty->driver->name, self->open_count );
+             __FILE__, __LINE__, tty->driver->name, port->count);
 
-       /* As far as I can see, we protect open_count - Jean II */
-       spin_lock_irqsave(&self->spinlock, flags);
+       spin_lock_irqsave(&port->lock, flags);
        if (!tty_hung_up_p(filp)) {
                extra_count = 1;
-               self->open_count--;
+               port->count--;
        }
-       spin_unlock_irqrestore(&self->spinlock, flags);
-       self->blocked_open++;
+       spin_unlock_irqrestore(&port->lock, flags);
+       port->blocked_open++;
 
        while (1) {
-               if (tty->termios->c_cflag & CBAUD) {
-                       /* Here, we use to lock those two guys, but
-                        * as ircomm_param_request() does it itself,
-                        * I don't see the point (and I see the deadlock).
-                        * Jean II */
-                       self->settings.dte |= IRCOMM_RTS + IRCOMM_DTR;
-
-                       ircomm_param_request(self, IRCOMM_DTE, TRUE);
-               }
+               if (tty->termios.c_cflag & CBAUD)
+                       tty_port_raise_dtr_rts(port);
 
                current->state = TASK_INTERRUPTIBLE;
 
                if (tty_hung_up_p(filp) ||
-                   !test_bit(ASYNC_B_INITIALIZED, &self->flags)) {
-                       retval = (self->flags & ASYNC_HUP_NOTIFY) ?
+                   !test_bit(ASYNCB_INITIALIZED, &port->flags)) {
+                       retval = (port->flags & ASYNC_HUP_NOTIFY) ?
                                        -EAGAIN : -ERESTARTSYS;
                        break;
                }
@@ -317,8 +336,8 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
                 * specified, we cannot return before the IrCOMM link is
                 * ready
                 */
-               if (!test_bit(ASYNC_B_CLOSING, &self->flags) &&
-                   (do_clocal || (self->settings.dce & IRCOMM_CD)) &&
+               if (!test_bit(ASYNCB_CLOSING, &port->flags) &&
+                   (do_clocal || tty_port_carrier_raised(port)) &&
                    self->state == IRCOMM_TTY_READY)
                {
                        break;
@@ -330,27 +349,27 @@ static int ircomm_tty_block_til_ready(struct ircomm_tty_cb *self,
                }
 
                IRDA_DEBUG(1, "%s(%d):block_til_ready blocking on %s open_count=%d\n",
-                     __FILE__,__LINE__, tty->driver->name, self->open_count );
+                     __FILE__, __LINE__, tty->driver->name, port->count);
 
                schedule();
        }
 
        __set_current_state(TASK_RUNNING);
-       remove_wait_queue(&self->open_wait, &wait);
+       remove_wait_queue(&port->open_wait, &wait);
 
        if (extra_count) {
                /* ++ is not atomic, so this should be protected - Jean II */
-               spin_lock_irqsave(&self->spinlock, flags);
-               self->open_count++;
-               spin_unlock_irqrestore(&self->spinlock, flags);
+               spin_lock_irqsave(&port->lock, flags);
+               port->count++;
+               spin_unlock_irqrestore(&port->lock, flags);
        }
-       self->blocked_open--;
+       port->blocked_open--;
 
        IRDA_DEBUG(1, "%s(%d):block_til_ready after blocking on %s open_count=%d\n",
-             __FILE__,__LINE__, tty->driver->name, self->open_count);
+             __FILE__, __LINE__, tty->driver->name, port->count);
 
        if (!retval)
-               self->flags |= ASYNC_NORMAL_ACTIVE;
+               port->flags |= ASYNC_NORMAL_ACTIVE;
 
        return retval;
 }
@@ -381,6 +400,8 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
                        return -ENOMEM;
                }
 
+               tty_port_init(&self->port);
+               self->port.ops = &ircomm_port_ops;
                self->magic = IRCOMM_TTY_MAGIC;
                self->flow = FLOW_STOP;
 
@@ -388,13 +409,9 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
                INIT_WORK(&self->tqueue, ircomm_tty_do_softint);
                self->max_header_size = IRCOMM_TTY_HDR_UNINITIALISED;
                self->max_data_size = IRCOMM_TTY_DATA_UNINITIALISED;
-               self->close_delay = 5*HZ/10;
-               self->closing_wait = 30*HZ;
 
                /* Init some important stuff */
                init_timer(&self->watchdog_timer);
-               init_waitqueue_head(&self->open_wait);
-               init_waitqueue_head(&self->close_wait);
                spin_lock_init(&self->spinlock);
 
                /*
@@ -404,31 +421,32 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
                 *
                 * Note this is completely usafe and doesn't work properly
                 */
-               tty->termios->c_iflag = 0;
-               tty->termios->c_oflag = 0;
+               tty->termios.c_iflag = 0;
+               tty->termios.c_oflag = 0;
 
                /* Insert into hash */
+               /* FIXME there is a window from find to here */
                hashbin_insert(ircomm_tty, (irda_queue_t *) self, line, NULL);
        }
        /* ++ is not atomic, so this should be protected - Jean II */
-       spin_lock_irqsave(&self->spinlock, flags);
-       self->open_count++;
+       spin_lock_irqsave(&self->port.lock, flags);
+       self->port.count++;
 
        tty->driver_data = self;
-       self->tty = tty;
-       spin_unlock_irqrestore(&self->spinlock, flags);
+       spin_unlock_irqrestore(&self->port.lock, flags);
+       tty_port_tty_set(&self->port, tty);
 
        IRDA_DEBUG(1, "%s(), %s%d, count = %d\n", __func__ , tty->driver->name,
-                  self->line, self->open_count);
+                  self->line, self->port.count);
 
        /* Not really used by us, but lets do it anyway */
-       self->tty->low_latency = (self->flags & ASYNC_LOW_LATENCY) ? 1 : 0;
+       tty->low_latency = (self->port.flags & ASYNC_LOW_LATENCY) ? 1 : 0;
 
        /*
         * If the port is the middle of closing, bail out now
         */
        if (tty_hung_up_p(filp) ||
-           test_bit(ASYNC_B_CLOSING, &self->flags)) {
+           test_bit(ASYNCB_CLOSING, &self->port.flags)) {
 
                /* Hm, why are we blocking on ASYNC_CLOSING if we
                 * do return -EAGAIN/-ERESTARTSYS below anyway?
@@ -438,14 +456,15 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
                 * probably better sleep uninterruptible?
                 */
 
-               if (wait_event_interruptible(self->close_wait, !test_bit(ASYNC_B_CLOSING, &self->flags))) {
+               if (wait_event_interruptible(self->port.close_wait,
+                               !test_bit(ASYNCB_CLOSING, &self->port.flags))) {
                        IRDA_WARNING("%s - got signal while blocking on ASYNC_CLOSING!\n",
                                     __func__);
                        return -ERESTARTSYS;
                }
 
 #ifdef SERIAL_DO_RESTART
-               return (self->flags & ASYNC_HUP_NOTIFY) ?
+               return (self->port.flags & ASYNC_HUP_NOTIFY) ?
                        -EAGAIN : -ERESTARTSYS;
 #else
                return -EAGAIN;
@@ -469,7 +488,7 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
        if (ret)
                return ret;
 
-       ret = ircomm_tty_block_til_ready(self, filp);
+       ret = ircomm_tty_block_til_ready(self, tty, filp);
        if (ret) {
                IRDA_DEBUG(2,
                      "%s(), returning after block_til_ready with %d\n", __func__ ,
@@ -489,81 +508,22 @@ static int ircomm_tty_open(struct tty_struct *tty, struct file *filp)
 static void ircomm_tty_close(struct tty_struct *tty, struct file *filp)
 {
        struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
-       unsigned long flags;
+       struct tty_port *port = &self->port;
 
        IRDA_DEBUG(0, "%s()\n", __func__ );
 
        IRDA_ASSERT(self != NULL, return;);
        IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
 
-       spin_lock_irqsave(&self->spinlock, flags);
-
-       if (tty_hung_up_p(filp)) {
-               spin_unlock_irqrestore(&self->spinlock, flags);
-
-               IRDA_DEBUG(0, "%s(), returning 1\n", __func__ );
-               return;
-       }
-
-       if ((tty->count == 1) && (self->open_count != 1)) {
-               /*
-                * Uh, oh.  tty->count is 1, which means that the tty
-                * structure will be freed.  state->count should always
-                * be one in these conditions.  If it's greater than
-                * one, we've got real problems, since it means the
-                * serial port won't be shutdown.
-                */
-               IRDA_DEBUG(0, "%s(), bad serial port count; "
-                          "tty->count is 1, state->count is %d\n", __func__ ,
-                          self->open_count);
-               self->open_count = 1;
-       }
-
-       if (--self->open_count < 0) {
-               IRDA_ERROR("%s(), bad serial port count for ttys%d: %d\n",
-                          __func__, self->line, self->open_count);
-               self->open_count = 0;
-       }
-       if (self->open_count) {
-               spin_unlock_irqrestore(&self->spinlock, flags);
-
-               IRDA_DEBUG(0, "%s(), open count > 0\n", __func__ );
+       if (tty_port_close_start(port, tty, filp) == 0)
                return;
-       }
-
-       /* Hum... Should be test_and_set_bit ??? - Jean II */
-       set_bit(ASYNC_B_CLOSING, &self->flags);
-
-       /* We need to unlock here (we were unlocking at the end of this
-        * function), because tty_wait_until_sent() may schedule.
-        * I don't know if the rest should be protected somehow,
-        * so someone should check. - Jean II */
-       spin_unlock_irqrestore(&self->spinlock, flags);
-
-       /*
-        * Now we wait for the transmit buffer to clear; and we notify
-        * the line discipline to only process XON/XOFF characters.
-        */
-       tty->closing = 1;
-       if (self->closing_wait != ASYNC_CLOSING_WAIT_NONE)
-               tty_wait_until_sent_from_close(tty, self->closing_wait);
 
        ircomm_tty_shutdown(self);
 
        tty_driver_flush_buffer(tty);
-       tty_ldisc_flush(tty);
 
-       tty->closing = 0;
-       self->tty = NULL;
-
-       if (self->blocked_open) {
-               if (self->close_delay)
-                       schedule_timeout_interruptible(self->close_delay);
-               wake_up_interruptible(&self->open_wait);
-       }
-
-       self->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING);
-       wake_up_interruptible(&self->close_wait);
+       tty_port_close_end(port, tty);
+       tty_port_tty_set(port, NULL);
 }
 
 /*
@@ -606,7 +566,7 @@ static void ircomm_tty_do_softint(struct work_struct *work)
        if (!self || self->magic != IRCOMM_TTY_MAGIC)
                return;
 
-       tty = self->tty;
+       tty = tty_port_tty_get(&self->port);
        if (!tty)
                return;
 
@@ -627,7 +587,7 @@ static void ircomm_tty_do_softint(struct work_struct *work)
        }
 
        if (tty->hw_stopped)
-               return;
+               goto put;
 
        /* Unlink transmit buffer */
        spin_lock_irqsave(&self->spinlock, flags);
@@ -646,6 +606,8 @@ static void ircomm_tty_do_softint(struct work_struct *work)
 
        /* Check if user (still) wants to be waken up */
        tty_wakeup(tty);
+put:
+       tty_kref_put(tty);
 }
 
 /*
@@ -880,7 +842,7 @@ static void ircomm_tty_throttle(struct tty_struct *tty)
                ircomm_tty_send_xchar(tty, STOP_CHAR(tty));
 
        /* Hardware flow control? */
-       if (tty->termios->c_cflag & CRTSCTS) {
+       if (tty->termios.c_cflag & CRTSCTS) {
                self->settings.dte &= ~IRCOMM_RTS;
                self->settings.dte |= IRCOMM_DELTA_RTS;
 
@@ -912,7 +874,7 @@ static void ircomm_tty_unthrottle(struct tty_struct *tty)
        }
 
        /* Using hardware flow control? */
-       if (tty->termios->c_cflag & CRTSCTS) {
+       if (tty->termios.c_cflag & CRTSCTS) {
                self->settings.dte |= (IRCOMM_RTS|IRCOMM_DELTA_RTS);
 
                ircomm_param_request(self, IRCOMM_DTE, TRUE);
@@ -955,7 +917,7 @@ static void ircomm_tty_shutdown(struct ircomm_tty_cb *self)
 
        IRDA_DEBUG(0, "%s()\n", __func__ );
 
-       if (!test_and_clear_bit(ASYNC_B_INITIALIZED, &self->flags))
+       if (!test_and_clear_bit(ASYNCB_INITIALIZED, &self->port.flags))
                return;
 
        ircomm_tty_detach_cable(self);
@@ -994,6 +956,7 @@ static void ircomm_tty_shutdown(struct ircomm_tty_cb *self)
 static void ircomm_tty_hangup(struct tty_struct *tty)
 {
        struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
+       struct tty_port *port = &self->port;
        unsigned long   flags;
 
        IRDA_DEBUG(0, "%s()\n", __func__ );
@@ -1004,14 +967,17 @@ static void ircomm_tty_hangup(struct tty_struct *tty)
        /* ircomm_tty_flush_buffer(tty); */
        ircomm_tty_shutdown(self);
 
-       /* I guess we need to lock here - Jean II */
-       spin_lock_irqsave(&self->spinlock, flags);
-       self->flags &= ~ASYNC_NORMAL_ACTIVE;
-       self->tty = NULL;
-       self->open_count = 0;
-       spin_unlock_irqrestore(&self->spinlock, flags);
+       spin_lock_irqsave(&port->lock, flags);
+       port->flags &= ~ASYNC_NORMAL_ACTIVE;
+       if (port->tty) {
+               set_bit(TTY_IO_ERROR, &port->tty->flags);
+               tty_kref_put(port->tty);
+       }
+       port->tty = NULL;
+       port->count = 0;
+       spin_unlock_irqrestore(&port->lock, flags);
 
-       wake_up_interruptible(&self->open_wait);
+       wake_up_interruptible(&port->open_wait);
 }
 
 /*
@@ -1071,20 +1037,20 @@ void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self)
        IRDA_ASSERT(self != NULL, return;);
        IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
 
-       tty = self->tty;
+       tty = tty_port_tty_get(&self->port);
 
        status = self->settings.dce;
 
        if (status & IRCOMM_DCE_DELTA_ANY) {
                /*wake_up_interruptible(&self->delta_msr_wait);*/
        }
-       if ((self->flags & ASYNC_CHECK_CD) && (status & IRCOMM_DELTA_CD)) {
+       if ((self->port.flags & ASYNC_CHECK_CD) && (status & IRCOMM_DELTA_CD)) {
                IRDA_DEBUG(2,
                           "%s(), ircomm%d CD now %s...\n", __func__ , self->line,
                           (status & IRCOMM_CD) ? "on" : "off");
 
                if (status & IRCOMM_CD) {
-                       wake_up_interruptible(&self->open_wait);
+                       wake_up_interruptible(&self->port.open_wait);
                } else {
                        IRDA_DEBUG(2,
                                   "%s(), Doing serial hangup..\n", __func__ );
@@ -1092,10 +1058,10 @@ void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self)
                                tty_hangup(tty);
 
                        /* Hangup will remote the tty, so better break out */
-                       return;
+                       goto put;
                }
        }
-       if (self->flags & ASYNC_CTS_FLOW) {
+       if (tty && self->port.flags & ASYNC_CTS_FLOW) {
                if (tty->hw_stopped) {
                        if (status & IRCOMM_CTS) {
                                IRDA_DEBUG(2,
@@ -1103,10 +1069,10 @@ void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self)
                                tty->hw_stopped = 0;
 
                                /* Wake up processes blocked on open */
-                               wake_up_interruptible(&self->open_wait);
+                               wake_up_interruptible(&self->port.open_wait);
 
                                schedule_work(&self->tqueue);
-                               return;
+                               goto put;
                        }
                } else {
                        if (!(status & IRCOMM_CTS)) {
@@ -1116,6 +1082,8 @@ void ircomm_tty_check_modem_status(struct ircomm_tty_cb *self)
                        }
                }
        }
+put:
+       tty_kref_put(tty);
 }
 
 /*
@@ -1128,6 +1096,7 @@ static int ircomm_tty_data_indication(void *instance, void *sap,
                                      struct sk_buff *skb)
 {
        struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
+       struct tty_struct *tty;
 
        IRDA_DEBUG(2, "%s()\n", __func__ );
 
@@ -1135,7 +1104,8 @@ static int ircomm_tty_data_indication(void *instance, void *sap,
        IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return -1;);
        IRDA_ASSERT(skb != NULL, return -1;);
 
-       if (!self->tty) {
+       tty = tty_port_tty_get(&self->port);
+       if (!tty) {
                IRDA_DEBUG(0, "%s(), no tty!\n", __func__ );
                return 0;
        }
@@ -1146,7 +1116,7 @@ static int ircomm_tty_data_indication(void *instance, void *sap,
         * Devices like WinCE can do this, and since they don't send any
         * params, we can just as well declare the hardware for running.
         */
-       if (self->tty->hw_stopped && (self->flow == FLOW_START)) {
+       if (tty->hw_stopped && (self->flow == FLOW_START)) {
                IRDA_DEBUG(0, "%s(), polling for line settings!\n", __func__ );
                ircomm_param_request(self, IRCOMM_POLL, TRUE);
 
@@ -1159,8 +1129,9 @@ static int ircomm_tty_data_indication(void *instance, void *sap,
         * Use flip buffer functions since the code may be called from interrupt
         * context
         */
-       tty_insert_flip_string(self->tty, skb->data, skb->len);
-       tty_flip_buffer_push(self->tty);
+       tty_insert_flip_string(tty, skb->data, skb->len);
+       tty_flip_buffer_push(tty);
+       tty_kref_put(tty);
 
        /* No need to kfree_skb - see ircomm_ttp_data_indication() */
 
@@ -1211,12 +1182,13 @@ static void ircomm_tty_flow_indication(void *instance, void *sap,
        IRDA_ASSERT(self != NULL, return;);
        IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
 
-       tty = self->tty;
+       tty = tty_port_tty_get(&self->port);
 
        switch (cmd) {
        case FLOW_START:
                IRDA_DEBUG(2, "%s(), hw start!\n", __func__ );
-               tty->hw_stopped = 0;
+               if (tty)
+                       tty->hw_stopped = 0;
 
                /* ircomm_tty_do_softint will take care of the rest */
                schedule_work(&self->tqueue);
@@ -1224,15 +1196,19 @@ static void ircomm_tty_flow_indication(void *instance, void *sap,
        default:  /* If we get here, something is very wrong, better stop */
        case FLOW_STOP:
                IRDA_DEBUG(2, "%s(), hw stopped!\n", __func__ );
-               tty->hw_stopped = 1;
+               if (tty)
+                       tty->hw_stopped = 1;
                break;
        }
+
+       tty_kref_put(tty);
        self->flow = cmd;
 }
 
 #ifdef CONFIG_PROC_FS
 static void ircomm_tty_line_info(struct ircomm_tty_cb *self, struct seq_file *m)
 {
+       struct tty_struct *tty;
        char sep;
 
        seq_printf(m, "State: %s\n", ircomm_tty_state[self->state]);
@@ -1328,40 +1304,43 @@ static void ircomm_tty_line_info(struct ircomm_tty_cb *self, struct seq_file *m)
 
        seq_puts(m, "Flags:");
        sep = ' ';
-       if (self->flags & ASYNC_CTS_FLOW) {
+       if (self->port.flags & ASYNC_CTS_FLOW) {
                seq_printf(m, "%cASYNC_CTS_FLOW", sep);
                sep = '|';
        }
-       if (self->flags & ASYNC_CHECK_CD) {
+       if (self->port.flags & ASYNC_CHECK_CD) {
                seq_printf(m, "%cASYNC_CHECK_CD", sep);
                sep = '|';
        }
-       if (self->flags & ASYNC_INITIALIZED) {
+       if (self->port.flags & ASYNC_INITIALIZED) {
                seq_printf(m, "%cASYNC_INITIALIZED", sep);
                sep = '|';
        }
-       if (self->flags & ASYNC_LOW_LATENCY) {
+       if (self->port.flags & ASYNC_LOW_LATENCY) {
                seq_printf(m, "%cASYNC_LOW_LATENCY", sep);
                sep = '|';
        }
-       if (self->flags & ASYNC_CLOSING) {
+       if (self->port.flags & ASYNC_CLOSING) {
                seq_printf(m, "%cASYNC_CLOSING", sep);
                sep = '|';
        }
-       if (self->flags & ASYNC_NORMAL_ACTIVE) {
+       if (self->port.flags & ASYNC_NORMAL_ACTIVE) {
                seq_printf(m, "%cASYNC_NORMAL_ACTIVE", sep);
                sep = '|';
        }
        seq_putc(m, '\n');
 
        seq_printf(m, "Role: %s\n", self->client ? "client" : "server");
-       seq_printf(m, "Open count: %d\n", self->open_count);
+       seq_printf(m, "Open count: %d\n", self->port.count);
        seq_printf(m, "Max data size: %d\n", self->max_data_size);
        seq_printf(m, "Max header size: %d\n", self->max_header_size);
 
-       if (self->tty)
+       tty = tty_port_tty_get(&self->port);
+       if (tty) {
                seq_printf(m, "Hardware: %s\n",
-                              self->tty->hw_stopped ? "Stopped" : "Running");
+                              tty->hw_stopped ? "Stopped" : "Running");
+               tty_kref_put(tty);
+       }
 }
 
 static int ircomm_tty_proc_show(struct seq_file *m, void *v)
index b65d66e0d8174bd49d6301ea1d8444c1f072b7d1..3ab70e7a07157821b3112578528ce63b99c4389c 100644 (file)
@@ -130,6 +130,8 @@ static int (*state[])(struct ircomm_tty_cb *self, IRCOMM_TTY_EVENT event,
  */
 int ircomm_tty_attach_cable(struct ircomm_tty_cb *self)
 {
+       struct tty_struct *tty;
+
        IRDA_DEBUG(0, "%s()\n", __func__ );
 
        IRDA_ASSERT(self != NULL, return -1;);
@@ -142,7 +144,11 @@ int ircomm_tty_attach_cable(struct ircomm_tty_cb *self)
        }
 
        /* Make sure nobody tries to write before the link is up */
-       self->tty->hw_stopped = 1;
+       tty = tty_port_tty_get(&self->port);
+       if (tty) {
+               tty->hw_stopped = 1;
+               tty_kref_put(tty);
+       }
 
        ircomm_tty_ias_register(self);
 
@@ -398,23 +404,26 @@ void ircomm_tty_disconnect_indication(void *instance, void *sap,
                                      struct sk_buff *skb)
 {
        struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) instance;
+       struct tty_struct *tty;
 
        IRDA_DEBUG(2, "%s()\n", __func__ );
 
        IRDA_ASSERT(self != NULL, return;);
        IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
 
-       if (!self->tty)
+       tty = tty_port_tty_get(&self->port);
+       if (!tty)
                return;
 
        /* This will stop control data transfers */
        self->flow = FLOW_STOP;
 
        /* Stop data transfers */
-       self->tty->hw_stopped = 1;
+       tty->hw_stopped = 1;
 
        ircomm_tty_do_event(self, IRCOMM_TTY_DISCONNECT_INDICATION, NULL,
                            NULL);
+       tty_kref_put(tty);
 }
 
 /*
@@ -550,12 +559,15 @@ void ircomm_tty_connect_indication(void *instance, void *sap,
  */
 void ircomm_tty_link_established(struct ircomm_tty_cb *self)
 {
+       struct tty_struct *tty;
+
        IRDA_DEBUG(2, "%s()\n", __func__ );
 
        IRDA_ASSERT(self != NULL, return;);
        IRDA_ASSERT(self->magic == IRCOMM_TTY_MAGIC, return;);
 
-       if (!self->tty)
+       tty = tty_port_tty_get(&self->port);
+       if (!tty)
                return;
 
        del_timer(&self->watchdog_timer);
@@ -566,19 +578,22 @@ void ircomm_tty_link_established(struct ircomm_tty_cb *self)
         * will have to wait for the peer device (DCE) to raise the CTS
         * line.
         */
-       if ((self->flags & ASYNC_CTS_FLOW) && ((self->settings.dce & IRCOMM_CTS) == 0)) {
+       if ((self->port.flags & ASYNC_CTS_FLOW) &&
+                       ((self->settings.dce & IRCOMM_CTS) == 0)) {
                IRDA_DEBUG(0, "%s(), waiting for CTS ...\n", __func__ );
-               return;
+               goto put;
        } else {
                IRDA_DEBUG(1, "%s(), starting hardware!\n", __func__ );
 
-               self->tty->hw_stopped = 0;
+               tty->hw_stopped = 0;
 
                /* Wake up processes blocked on open */
-               wake_up_interruptible(&self->open_wait);
+               wake_up_interruptible(&self->port.open_wait);
        }
 
        schedule_work(&self->tqueue);
+put:
+       tty_kref_put(tty);
 }
 
 /*
@@ -977,14 +992,17 @@ static int ircomm_tty_state_ready(struct ircomm_tty_cb *self,
                ircomm_tty_next_state(self, IRCOMM_TTY_SEARCH);
                ircomm_tty_start_watchdog_timer(self, 3*HZ);
 
-               if (self->flags & ASYNC_CHECK_CD) {
+               if (self->port.flags & ASYNC_CHECK_CD) {
                        /* Drop carrier */
                        self->settings.dce = IRCOMM_DELTA_CD;
                        ircomm_tty_check_modem_status(self);
                } else {
+                       struct tty_struct *tty = tty_port_tty_get(&self->port);
                        IRDA_DEBUG(0, "%s(), hanging up!\n", __func__ );
-                       if (self->tty)
-                               tty_hangup(self->tty);
+                       if (tty) {
+                               tty_hangup(tty);
+                               tty_kref_put(tty);
+                       }
                }
                break;
        default:
index d0667d68351dfc8944c2d694de054232cffefc75..b343f50dc8d72a07b321d9e70eb33e3ed8f62443 100644 (file)
  *    Change speed of the driver. If the remote device is a DCE, then this
  *    should make it change the speed of its serial port
  */
-static void ircomm_tty_change_speed(struct ircomm_tty_cb *self)
+static void ircomm_tty_change_speed(struct ircomm_tty_cb *self,
+               struct tty_struct *tty)
 {
        unsigned int cflag, cval;
        int baud;
 
        IRDA_DEBUG(2, "%s()\n", __func__ );
 
-       if (!self->tty || !self->tty->termios || !self->ircomm)
+       if (!self->ircomm)
                return;
 
-       cflag = self->tty->termios->c_cflag;
+       cflag = tty->termios.c_cflag;
 
        /*  byte size and parity */
        switch (cflag & CSIZE) {
@@ -81,7 +82,7 @@ static void ircomm_tty_change_speed(struct ircomm_tty_cb *self)
                cval |= IRCOMM_PARITY_EVEN;
 
        /* Determine divisor based on baud rate */
-       baud = tty_get_baud_rate(self->tty);
+       baud = tty_get_baud_rate(tty);
        if (!baud)
                baud = 9600;    /* B0 transition handled in rs_set_termios */
 
@@ -90,19 +91,19 @@ static void ircomm_tty_change_speed(struct ircomm_tty_cb *self)
 
        /* CTS flow control flag and modem status interrupts */
        if (cflag & CRTSCTS) {
-               self->flags |= ASYNC_CTS_FLOW;
+               self->port.flags |= ASYNC_CTS_FLOW;
                self->settings.flow_control |= IRCOMM_RTS_CTS_IN;
                /* This got me. Bummer. Jean II */
                if (self->service_type == IRCOMM_3_WIRE_RAW)
                        IRDA_WARNING("%s(), enabling RTS/CTS on link that doesn't support it (3-wire-raw)\n", __func__);
        } else {
-               self->flags &= ~ASYNC_CTS_FLOW;
+               self->port.flags &= ~ASYNC_CTS_FLOW;
                self->settings.flow_control &= ~IRCOMM_RTS_CTS_IN;
        }
        if (cflag & CLOCAL)
-               self->flags &= ~ASYNC_CHECK_CD;
+               self->port.flags &= ~ASYNC_CHECK_CD;
        else
-               self->flags |= ASYNC_CHECK_CD;
+               self->port.flags |= ASYNC_CHECK_CD;
 #if 0
        /*
         * Set up parity check flag
@@ -148,18 +149,18 @@ void ircomm_tty_set_termios(struct tty_struct *tty,
                            struct ktermios *old_termios)
 {
        struct ircomm_tty_cb *self = (struct ircomm_tty_cb *) tty->driver_data;
-       unsigned int cflag = tty->termios->c_cflag;
+       unsigned int cflag = tty->termios.c_cflag;
 
        IRDA_DEBUG(2, "%s()\n", __func__ );
 
        if ((cflag == old_termios->c_cflag) &&
-           (RELEVANT_IFLAG(tty->termios->c_iflag) ==
+           (RELEVANT_IFLAG(tty->termios.c_iflag) ==
             RELEVANT_IFLAG(old_termios->c_iflag)))
        {
                return;
        }
 
-       ircomm_tty_change_speed(self);
+       ircomm_tty_change_speed(self, tty);
 
        /* Handle transition to B0 status */
        if ((old_termios->c_cflag & CBAUD) &&
@@ -172,7 +173,7 @@ void ircomm_tty_set_termios(struct tty_struct *tty,
        if (!(old_termios->c_cflag & CBAUD) &&
            (cflag & CBAUD)) {
                self->settings.dte |= IRCOMM_DTR;
-               if (!(tty->termios->c_cflag & CRTSCTS) ||
+               if (!(tty->termios.c_cflag & CRTSCTS) ||
                    !test_bit(TTY_THROTTLED, &tty->flags)) {
                        self->settings.dte |= IRCOMM_RTS;
                }
@@ -181,7 +182,7 @@ void ircomm_tty_set_termios(struct tty_struct *tty,
 
        /* Handle turning off CRTSCTS */
        if ((old_termios->c_cflag & CRTSCTS) &&
-           !(tty->termios->c_cflag & CRTSCTS))
+           !(tty->termios.c_cflag & CRTSCTS))
        {
                tty->hw_stopped = 0;
                ircomm_tty_start(tty);
@@ -270,10 +271,10 @@ static int ircomm_tty_get_serial_info(struct ircomm_tty_cb *self,
 
        memset(&info, 0, sizeof(info));
        info.line = self->line;
-       info.flags = self->flags;
+       info.flags = self->port.flags;
        info.baud_base = self->settings.data_rate;
-       info.close_delay = self->close_delay;
-       info.closing_wait = self->closing_wait;
+       info.close_delay = self->port.close_delay;
+       info.closing_wait = self->port.closing_wait;
 
        /* For compatibility  */
        info.type = PORT_16550A;