Merge branch 'tty-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 7 Jan 2011 22:39:20 +0000 (14:39 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 7 Jan 2011 22:39:20 +0000 (14:39 -0800)
* 'tty-next' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/tty-2.6: (36 commits)
  serial: apbuart: Fixup apbuart_console_init()
  TTY: Add tty ioctl to figure device node of the system console.
  tty: add 'active' sysfs attribute to tty0 and console device
  drivers: serial: apbuart: Handle OF failures gracefully
  Serial: Avoid unbalanced IRQ wake disable during resume
  tty: fix typos/errors in tty_driver.h comments
  pch_uart : fix warnings for 64bit compile
  8250: fix uninitialized FIFOs
  ip2: fix compiler warning on ip2main_pci_tbl
  specialix: fix compiler warning on specialix_pci_tbl
  rocket: fix compiler warning on rocket_pci_ids
  8250: add a UPIO_DWAPB32 for 32 bit accesses
  8250: use container_of() instead of casting
  serial: omap-serial: Add support for kernel debugger
  serial: fix pch_uart kconfig & build
  drivers: char: hvc: add arm JTAG DCC console support
  RS485 documentation: add 16C950 UART description
  serial: ifx6x60: fix memory leak
  serial: ifx6x60: free IRQ on error
  Serial: EG20T: add PCH_UART driver
  ...

Fixed up conflicts in drivers/serial/apbuart.c with evil merge that
makes the code look fairly sane (unlike either side).

1  2 
drivers/char/specialix.c
drivers/serial/8250.c
drivers/serial/8250_pci.c
drivers/serial/apbuart.c
drivers/serial/omap-serial.c
drivers/serial/serial_core.c
drivers/tty/n_gsm.c
drivers/tty/tty_io.c
fs/compat_ioctl.c
kernel/printk.c

diff --combined drivers/char/specialix.c
@@@ -87,6 -87,7 +87,6 @@@
  #include <linux/tty_flip.h>
  #include <linux/mm.h>
  #include <linux/serial.h>
 -#include <linux/smp_lock.h>
  #include <linux/fcntl.h>
  #include <linux/major.h>
  #include <linux/delay.h>
@@@ -2355,7 -2356,7 +2355,7 @@@ static void __exit specialix_exit_modul
        func_exit();
  }
  
- static struct pci_device_id specialx_pci_tbl[] __devinitdata = {
+ static struct pci_device_id specialx_pci_tbl[] __devinitdata __used = {
        { PCI_DEVICE(PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_SPECIALIX_IO8) },
        { }
  };
diff --combined drivers/serial/8250.c
@@@ -454,21 -454,40 +454,40 @@@ static void tsi_serial_out(struct uart_
                writeb(value, p->membase + offset);
  }
  
+ /* Save the LCR value so it can be re-written when a Busy Detect IRQ occurs. */
+ static inline void dwapb_save_out_value(struct uart_port *p, int offset,
+                                       int value)
+ {
+       struct uart_8250_port *up =
+               container_of(p, struct uart_8250_port, port);
+       if (offset == UART_LCR)
+               up->lcr = value;
+ }
+ /* Read the IER to ensure any interrupt is cleared before returning from ISR. */
+ static inline void dwapb_check_clear_ier(struct uart_port *p, int offset)
+ {
+       if (offset == UART_TX || offset == UART_IER)
+               p->serial_in(p, UART_IER);
+ }
  static void dwapb_serial_out(struct uart_port *p, int offset, int value)
  {
        int save_offset = offset;
        offset = map_8250_out_reg(p, offset) << p->regshift;
-       /* Save the LCR value so it can be re-written when a
-        * Busy Detect interrupt occurs. */
-       if (save_offset == UART_LCR) {
-               struct uart_8250_port *up = (struct uart_8250_port *)p;
-               up->lcr = value;
-       }
+       dwapb_save_out_value(p, save_offset, value);
        writeb(value, p->membase + offset);
-       /* Read the IER to ensure any interrupt is cleared before
-        * returning from ISR. */
-       if (save_offset == UART_TX || save_offset == UART_IER)
-               value = p->serial_in(p, UART_IER);
+       dwapb_check_clear_ier(p, save_offset);
+ }
+ static void dwapb32_serial_out(struct uart_port *p, int offset, int value)
+ {
+       int save_offset = offset;
+       offset = map_8250_out_reg(p, offset) << p->regshift;
+       dwapb_save_out_value(p, save_offset, value);
+       writel(value, p->membase + offset);
+       dwapb_check_clear_ier(p, save_offset);
  }
  
  static unsigned int io_serial_in(struct uart_port *p, int offset)
@@@ -485,7 -504,8 +504,8 @@@ static void io_serial_out(struct uart_p
  
  static void set_io_from_upio(struct uart_port *p)
  {
-       struct uart_8250_port *up = (struct uart_8250_port *)p;
+       struct uart_8250_port *up =
+               container_of(p, struct uart_8250_port, port);
        switch (p->iotype) {
        case UPIO_HUB6:
                p->serial_in = hub6_serial_in;
                p->serial_out = dwapb_serial_out;
                break;
  
+       case UPIO_DWAPB32:
+               p->serial_in = mem32_serial_in;
+               p->serial_out = dwapb32_serial_out;
+               break;
        default:
                p->serial_in = io_serial_in;
                p->serial_out = io_serial_out;
@@@ -536,6 -561,7 +561,7 @@@ serial_out_sync(struct uart_8250_port *
        case UPIO_MEM32:
        case UPIO_AU:
        case UPIO_DWAPB:
+       case UPIO_DWAPB32:
                p->serial_out(p, offset, value);
                p->serial_in(p, UART_LCR);      /* safe, no side-effects */
                break;
@@@ -653,13 -679,13 +679,13 @@@ static void serial8250_set_sleep(struc
  {
        if (p->capabilities & UART_CAP_SLEEP) {
                if (p->capabilities & UART_CAP_EFR) {
 -                      serial_outp(p, UART_LCR, 0xBF);
 +                      serial_outp(p, UART_LCR, UART_LCR_CONF_MODE_B);
                        serial_outp(p, UART_EFR, UART_EFR_ECB);
                        serial_outp(p, UART_LCR, 0);
                }
                serial_outp(p, UART_IER, sleep ? UART_IERX_SLEEP : 0);
                if (p->capabilities & UART_CAP_EFR) {
 -                      serial_outp(p, UART_LCR, 0xBF);
 +                      serial_outp(p, UART_LCR, UART_LCR_CONF_MODE_B);
                        serial_outp(p, UART_EFR, 0);
                        serial_outp(p, UART_LCR, 0);
                }
@@@ -752,7 -778,7 +778,7 @@@ static int size_fifo(struct uart_8250_p
        serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO |
                    UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT);
        serial_outp(up, UART_MCR, UART_MCR_LOOP);
 -      serial_outp(up, UART_LCR, UART_LCR_DLAB);
 +      serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A);
        old_dl = serial_dl_read(up);
        serial_dl_write(up, 0x0001);
        serial_outp(up, UART_LCR, 0x03);
                serial_inp(up, UART_RX);
        serial_outp(up, UART_FCR, old_fcr);
        serial_outp(up, UART_MCR, old_mcr);
 -      serial_outp(up, UART_LCR, UART_LCR_DLAB);
 +      serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A);
        serial_dl_write(up, old_dl);
        serial_outp(up, UART_LCR, old_lcr);
  
@@@ -782,7 -808,7 +808,7 @@@ static unsigned int autoconfig_read_div
        unsigned int id;
  
        old_lcr = serial_inp(p, UART_LCR);
 -      serial_outp(p, UART_LCR, UART_LCR_DLAB);
 +      serial_outp(p, UART_LCR, UART_LCR_CONF_MODE_A);
  
        old_dll = serial_inp(p, UART_DLL);
        old_dlm = serial_inp(p, UART_DLM);
@@@ -836,7 -862,7 +862,7 @@@ static void autoconfig_has_efr(struct u
         * recommended for new designs).
         */
        up->acr = 0;
 -      serial_out(up, UART_LCR, 0xBF);
 +      serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
        serial_out(up, UART_EFR, UART_EFR_ECB);
        serial_out(up, UART_LCR, 0x00);
        id1 = serial_icr_read(up, UART_ID1);
@@@ -945,7 -971,7 +971,7 @@@ static void autoconfig_16550a(struct ua
         * Check for presence of the EFR when DLAB is set.
         * Only ST16C650V1 UARTs pass this test.
         */
 -      serial_outp(up, UART_LCR, UART_LCR_DLAB);
 +      serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A);
        if (serial_in(up, UART_EFR) == 0) {
                serial_outp(up, UART_EFR, 0xA8);
                if (serial_in(up, UART_EFR) != 0) {
         * Maybe it requires 0xbf to be written to the LCR.
         * (other ST16C650V2 UARTs, TI16C752A, etc)
         */
 -      serial_outp(up, UART_LCR, 0xBF);
 +      serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
        if (serial_in(up, UART_EFR) == 0 && !broken_efr(up)) {
                DEBUG_AUTOCONF("EFRv2 ");
                autoconfig_has_efr(up);
        serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
        status1 = serial_in(up, UART_IIR) >> 5;
        serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
 -      serial_outp(up, UART_LCR, UART_LCR_DLAB);
 +      serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_A);
        serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO | UART_FCR7_64BYTE);
        status2 = serial_in(up, UART_IIR) >> 5;
        serial_outp(up, UART_FCR, UART_FCR_ENABLE_FIFO);
@@@ -1183,7 -1209,7 +1209,7 @@@ static void autoconfig(struct uart_8250
         * We also initialise the EFR (if any) to zero for later.  The
         * EFR occupies the same register location as the FCR and IIR.
         */
 -      serial_outp(up, UART_LCR, 0xBF);
 +      serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
        serial_outp(up, UART_EFR, 0);
        serial_outp(up, UART_LCR, 0);
  
@@@ -1319,7 -1345,8 +1345,8 @@@ static inline void __stop_tx(struct uar
  
  static void serial8250_stop_tx(struct uart_port *port)
  {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
  
        __stop_tx(up);
  
@@@ -1336,7 -1363,8 +1363,8 @@@ static void transmit_chars(struct uart_
  
  static void serial8250_start_tx(struct uart_port *port)
  {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
  
        if (!(up->ier & UART_IER_THRI)) {
                up->ier |= UART_IER_THRI;
  
  static void serial8250_stop_rx(struct uart_port *port)
  {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
  
        up->ier &= ~UART_IER_RLSI;
        up->port.read_status_mask &= ~UART_LSR_DR;
  
  static void serial8250_enable_ms(struct uart_port *port)
  {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
  
        /* no MSR capabilities */
        if (up->bugs & UART_BUG_NOMSR)
@@@ -1581,7 -1611,8 +1611,8 @@@ static irqreturn_t serial8250_interrupt
                        handled = 1;
  
                        end = NULL;
-               } else if (up->port.iotype == UPIO_DWAPB &&
+               } else if ((up->port.iotype == UPIO_DWAPB ||
+                           up->port.iotype == UPIO_DWAPB32) &&
                          (iir & UART_IIR_BUSY) == UART_IIR_BUSY) {
                        /* The DesignWare APB UART has an Busy Detect (0x07)
                         * interrupt meaning an LCR write attempt occured while the
@@@ -1781,7 -1812,8 +1812,8 @@@ static void serial8250_backup_timeout(u
  
  static unsigned int serial8250_tx_empty(struct uart_port *port)
  {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
        unsigned long flags;
        unsigned int lsr;
  
  
  static unsigned int serial8250_get_mctrl(struct uart_port *port)
  {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
        unsigned int status;
        unsigned int ret;
  
  
  static void serial8250_set_mctrl(struct uart_port *port, unsigned int mctrl)
  {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
        unsigned char mcr = 0;
  
        if (mctrl & TIOCM_RTS)
  
  static void serial8250_break_ctl(struct uart_port *port, int break_state)
  {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
        unsigned long flags;
  
        spin_lock_irqsave(&up->port.lock, flags);
@@@ -1890,7 -1925,8 +1925,8 @@@ static void wait_for_xmitr(struct uart_
  
  static int serial8250_get_poll_char(struct uart_port *port)
  {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
        unsigned char lsr = serial_inp(up, UART_LSR);
  
        if (!(lsr & UART_LSR_DR))
@@@ -1904,7 -1940,8 +1940,8 @@@ static void serial8250_put_poll_char(st
                         unsigned char c)
  {
        unsigned int ier;
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
  
        /*
         *      First save the IER then disable the interrupts
  
  static int serial8250_startup(struct uart_port *port)
  {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
        unsigned long flags;
        unsigned char lsr, iir;
        int retval;
  
+       up->port.fifosize = uart_config[up->port.type].fifo_size;
+       up->tx_loadsz = uart_config[up->port.type].tx_loadsz;
        up->capabilities = uart_config[up->port.type].flags;
        up->mcr = 0;
  
        if (up->port.type == PORT_16C950) {
                /* Wake up and initialize UART */
                up->acr = 0;
 -              serial_outp(up, UART_LCR, 0xBF);
 +              serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
                serial_outp(up, UART_EFR, UART_EFR_ECB);
                serial_outp(up, UART_IER, 0);
                serial_outp(up, UART_LCR, 0);
        if (up->port.type == PORT_16850) {
                unsigned char fctr;
  
 -              serial_outp(up, UART_LCR, 0xbf);
 +              serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
  
                fctr = serial_inp(up, UART_FCTR) & ~(UART_FCTR_RX|UART_FCTR_TX);
                serial_outp(up, UART_FCTR, fctr | UART_FCTR_TRGD | UART_FCTR_RX);
@@@ -2166,7 -2206,8 +2206,8 @@@ dont_test_tx_en
  
  static void serial8250_shutdown(struct uart_port *port)
  {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
        unsigned long flags;
  
        /*
@@@ -2235,7 -2276,8 +2276,8 @@@ voi
  serial8250_do_set_termios(struct uart_port *port, struct ktermios *termios,
                          struct ktermios *old)
  {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
        unsigned char cval, fcr = 0;
        unsigned long flags;
        unsigned int baud, quot;
                if (termios->c_cflag & CRTSCTS)
                        efr |= UART_EFR_CTS;
  
 -              serial_outp(up, UART_LCR, 0xBF);
 +              serial_outp(up, UART_LCR, UART_LCR_CONF_MODE_B);
                serial_outp(up, UART_EFR, efr);
        }
  
@@@ -2435,7 -2477,8 +2477,8 @@@ serial8250_set_ldisc(struct uart_port *
  void serial8250_do_pm(struct uart_port *port, unsigned int state,
                      unsigned int oldstate)
  {
-       struct uart_8250_port *p = (struct uart_8250_port *)port;
+       struct uart_8250_port *p =
+               container_of(port, struct uart_8250_port, port);
  
        serial8250_set_sleep(p, state != 0);
  }
@@@ -2476,6 -2519,7 +2519,7 @@@ static int serial8250_request_std_resou
        case UPIO_MEM32:
        case UPIO_MEM:
        case UPIO_DWAPB:
+       case UPIO_DWAPB32:
                if (!up->port.mapbase)
                        break;
  
@@@ -2513,6 -2557,7 +2557,7 @@@ static void serial8250_release_std_reso
        case UPIO_MEM32:
        case UPIO_MEM:
        case UPIO_DWAPB:
+       case UPIO_DWAPB32:
                if (!up->port.mapbase)
                        break;
  
@@@ -2566,7 -2611,8 +2611,8 @@@ static void serial8250_release_rsa_reso
  
  static void serial8250_release_port(struct uart_port *port)
  {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
  
        serial8250_release_std_resource(up);
        if (up->port.type == PORT_RSA)
  
  static int serial8250_request_port(struct uart_port *port)
  {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
        int ret = 0;
  
        ret = serial8250_request_std_resource(up);
  
  static void serial8250_config_port(struct uart_port *port, int flags)
  {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
        int probeflags = PROBE_ANY;
        int ret;
  
@@@ -2771,7 -2819,8 +2819,8 @@@ serial8250_register_ports(struct uart_d
  
  static void serial8250_console_putchar(struct uart_port *port, int ch)
  {
-       struct uart_8250_port *up = (struct uart_8250_port *)port;
+       struct uart_8250_port *up =
+               container_of(port, struct uart_8250_port, port);
  
        wait_for_xmitr(up, UART_LSR_THRE);
        serial_out(up, UART_TX, ch);
@@@ -2872,7 -2921,7 +2921,7 @@@ static struct console serial8250_consol
        .device         = uart_console_device,
        .setup          = serial8250_console_setup,
        .early_setup    = serial8250_console_early_setup,
 -      .flags          = CON_PRINTBUFFER,
 +      .flags          = CON_PRINTBUFFER | CON_ANYTIME,
        .index          = -1,
        .data           = &serial8250_reg,
  };
@@@ -957,6 -957,22 +957,22 @@@ pci_default_setup(struct serial_privat
        return setup_port(priv, port, bar, offset, board->reg_shift);
  }
  
+ static int
+ ce4100_serial_setup(struct serial_private *priv,
+                 const struct pciserial_board *board,
+                 struct uart_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;
+       return ret;
+ }
  static int skip_tx_en_setup(struct serial_private *priv,
                        const struct pciserial_board *board,
                        struct uart_port *port, int idx)
  #define PCI_SUBDEVICE_ID_POCTAL232    0x0308
  #define PCI_SUBDEVICE_ID_POCTAL422    0x0408
  #define PCI_VENDOR_ID_ADVANTECH               0x13fe
+ #define PCI_DEVICE_ID_INTEL_CE4100_UART 0x2e66
  #define PCI_DEVICE_ID_ADVANTECH_PCI3620       0x3620
  #define PCI_DEVICE_ID_TITAN_200I      0x8028
  #define PCI_DEVICE_ID_TITAN_400I      0x8048
@@@ -1072,6 -1089,13 +1089,13 @@@ static struct pci_serial_quirk pci_seri
                .subdevice      = PCI_ANY_ID,
                .setup          = skip_tx_en_setup,
        },
+       {
+               .vendor         = PCI_VENDOR_ID_INTEL,
+               .device         = PCI_DEVICE_ID_INTEL_CE4100_UART,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = ce4100_serial_setup,
+       },
        /*
         * ITE
         */
@@@ -1592,6 -1616,7 +1616,7 @@@ enum pci_board_num_t 
        pbn_ADDIDATA_PCIe_2_3906250,
        pbn_ADDIDATA_PCIe_4_3906250,
        pbn_ADDIDATA_PCIe_8_3906250,
+       pbn_ce4100_1_115200,
  };
  
  /*
@@@ -2281,12 -2306,16 +2306,18 @@@ static struct pciserial_board pci_board
                .uart_offset    = 0x200,
                .first_offset   = 0x1000,
        },
+       [pbn_ce4100_1_115200] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 1,
+               .base_baud      = 921600,
+               .reg_shift      = 2,
+       },
  };
  
  static const struct pci_device_id softmodem_blacklist[] = {
        { PCI_VDEVICE(AL, 0x5457), }, /* ALi Corporation M5457 AC'97 Modem */
 +      { PCI_VDEVICE(MOTOROLA, 0x3052), }, /* Motorola Si3052-based modem */
 +      { PCI_DEVICE(0x1543, 0x3052), }, /* Si3052-based modem, default IDs */
  };
  
  /*
@@@ -2865,9 -2894,6 +2896,9 @@@ static struct pci_device_id serial_pci_
                PCI_SUBVENDOR_ID_SIIG, PCI_SUBDEVICE_ID_SIIG_QUARTET_SERIAL,
                0, 0,
                pbn_b0_4_1152000 },
 +      {       PCI_VENDOR_ID_OXSEMI, 0x9505,
 +              PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 +              pbn_b0_bt_2_921600 },
  
                /*
                 * The below card is a little controversial since it is the
        {       PCI_VENDOR_ID_NETMOS, PCI_DEVICE_ID_NETMOS_9865,
                0xA000, 0x3004,
                0, 0, pbn_b0_bt_4_115200 },
+       /* Intel CE4100 */
+       {       PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CE4100_UART,
+               PCI_ANY_ID,  PCI_ANY_ID, 0, 0,
+               pbn_ce4100_1_115200 },
  
        /*
         * These entries match devices with class COMMUNICATION_SERIAL,
diff --combined drivers/serial/apbuart.c
@@@ -26,7 -26,6 +26,7 @@@
  #include <linux/of.h>
  #include <linux/of_device.h>
  #include <linux/of_platform.h>
 +#include <linux/of_irq.h>
  #include <linux/platform_device.h>
  #include <linux/io.h>
  #include <linux/serial_core.h>
@@@ -521,11 -520,12 +521,12 @@@ static struct console grlib_apbuart_con
  };
  
  
- static void grlib_apbuart_configure(void);
+ static int grlib_apbuart_configure(void);
  
  static int __init apbuart_console_init(void)
  {
-       grlib_apbuart_configure();
+       if (grlib_apbuart_configure())
+               return -ENODEV;
        register_console(&grlib_apbuart_console);
        return 0;
  }
@@@ -574,15 -574,13 +575,15 @@@ static int __devinit apbuart_probe(stru
        printk(KERN_INFO "grlib-apbuart at 0x%llx, irq %d\n",
               (unsigned long long) port->mapbase, port->irq);
        return 0;
 -
  }
  
  static struct of_device_id __initdata apbuart_match[] = {
        {
         .name = "GAISLER_APBUART",
         },
 +      {
 +       .name = "01_00c",
 +       },
        {},
  };
  
@@@ -596,57 -594,44 +597,49 @@@ static struct of_platform_driver grlib_
  };
  
  
- static void grlib_apbuart_configure(void)
+ static int grlib_apbuart_configure(void)
  {
-       static int enum_done;
        struct device_node *np, *rp;
-       struct uart_port *port = NULL;
        const u32 *prop;
-       int freq_khz;
-       int v = 0, d = 0;
-       unsigned int addr;
-       int irq, line;
-       struct amba_prom_registers *regs;
-       if (enum_done)
-               return;
+       int freq_khz, line = 0;
  
        /* Get bus frequency */
        rp = of_find_node_by_path("/");
+       if (!rp)
+               return -ENODEV;
        rp = of_get_next_child(rp, NULL);
+       if (!rp)
+               return -ENODEV;
        prop = of_get_property(rp, "clock-frequency", NULL);
+       if (!prop)
+               return -ENODEV;
        freq_khz = *prop;
  
-       line = 0;
        for_each_matching_node(np, apbuart_match) {
 -              const int *irqs = of_get_property(np, "interrupts", NULL);
++              const int *irqs, *ampopts;
+               const struct amba_prom_registers *regs;
+               struct uart_port *port;
+               unsigned long addr;
  
-               int *vendor = (int *) of_get_property(np, "vendor", NULL);
-               int *device = (int *) of_get_property(np, "device", NULL);
-               int *irqs = (int *) of_get_property(np, "interrupts", NULL);
-               int *ampopts = (int *) of_get_property(np, "ampopts", NULL);
-               regs = (struct amba_prom_registers *)
-                   of_get_property(np, "reg", NULL);
++              ampopts = of_get_property(np, "ampopts", NULL);
 +              if (ampopts && (*ampopts == 0))
 +                      continue; /* Ignore if used by another OS instance */
-               if (vendor)
-                       v = *vendor;
-               if (device)
-                       d = *device;
++
++              irqs = of_get_property(np, "interrupts", NULL);
+               regs = of_get_property(np, "reg", NULL);
  
                if (!irqs || !regs)
-                       return;
 -                      return -ENODEV;
++                      continue;
  
                grlib_apbuart_nodes[line] = np;
  
                addr = regs->phys_addr;
-               irq = *irqs;
  
                port = &grlib_apbuart_ports[line];
  
                port->mapbase = addr;
                port->membase = ioremap(addr, sizeof(struct grlib_apbuart_regs_map));
-               port->irq = irq;
+               port->irq = *irqs;
                port->iotype = UPIO_MEM;
                port->ops = &grlib_apbuart_ops;
                port->flags = UPF_BOOT_AUTOCONF;
                /* We support maximum UART_NR uarts ... */
                if (line == UART_NR)
                        break;
        }
  
-       enum_done = 1;
        grlib_apbuart_driver.nr = grlib_apbuart_port_nr = line;
+       return line ? 0 : -ENODEV;
  }
  
  static int __init grlib_apbuart_init(void)
        int ret;
  
        /* Find all APBUARTS in device the tree and initialize their ports */
-       grlib_apbuart_configure();
+       ret = grlib_apbuart_configure();
+       if (ret)
+               return ret;
  
        printk(KERN_INFO "Serial: GRLIB APBUART driver\n");
  
@@@ -570,7 -570,7 +570,7 @@@ serial_omap_configure_xonxof
        unsigned char efr = 0;
  
        up->lcr = serial_in(up, UART_LCR);
 -      serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB);
 +      serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
        up->efr = serial_in(up, UART_EFR);
        serial_out(up, UART_EFR, up->efr & ~UART_EFR_ECB);
  
                efr |= OMAP_UART_SW_RX;
  
        serial_out(up, UART_EFR, up->efr | UART_EFR_ECB);
 -      serial_out(up, UART_LCR, UART_LCR_DLAB);
 +      serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
  
        up->mcr = serial_in(up, UART_MCR);
  
                up->mcr |= UART_MCR_XONANY;
  
        serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR);
 -      serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB);
 +      serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
        serial_out(up, UART_TI752_TCR, OMAP_UART_TCR_TRIG);
        /* Enable special char function UARTi.EFR_REG[5] and
         * load the new software flow control mode IXON or IXOFF
         * and restore the UARTi.EFR_REG[4] ENHANCED_EN value.
         */
        serial_out(up, UART_EFR, efr | UART_EFR_SCD);
 -      serial_out(up, UART_LCR, UART_LCR_DLAB);
 +      serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
  
        serial_out(up, UART_MCR, up->mcr & ~UART_MCR_TCRTLR);
        serial_out(up, UART_LCR, up->lcr);
@@@ -724,22 -724,22 +724,22 @@@ serial_omap_set_termios(struct uart_por
         * baud clock is not running
         * DLL_REG and DLH_REG set to 0.
         */
 -      serial_out(up, UART_LCR, UART_LCR_DLAB);
 +      serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
        serial_out(up, UART_DLL, 0);
        serial_out(up, UART_DLM, 0);
        serial_out(up, UART_LCR, 0);
  
 -      serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB);
 +      serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
  
        up->efr = serial_in(up, UART_EFR);
        serial_out(up, UART_EFR, up->efr | UART_EFR_ECB);
  
 -      serial_out(up, UART_LCR, UART_LCR_DLAB);
 +      serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
        up->mcr = serial_in(up, UART_MCR);
        serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR);
        /* FIFO ENABLE, DMA MODE */
        serial_out(up, UART_FCR, up->fcr);
 -      serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB);
 +      serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
  
        if (up->use_dma) {
                serial_out(up, UART_TI752_TLR, 0);
        }
  
        serial_out(up, UART_EFR, up->efr);
 -      serial_out(up, UART_LCR, UART_LCR_DLAB);
 +      serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
        serial_out(up, UART_MCR, up->mcr);
  
        /* Protocol, Baud Rate, and Interrupt Settings */
  
 -      serial_out(up, UART_OMAP_MDR1, OMAP_MDR1_DISABLE);
 -      serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB);
 +      serial_out(up, UART_OMAP_MDR1, UART_OMAP_MDR1_DISABLE);
 +      serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
  
        up->efr = serial_in(up, UART_EFR);
        serial_out(up, UART_EFR, up->efr | UART_EFR_ECB);
  
        serial_out(up, UART_LCR, 0);
        serial_out(up, UART_IER, 0);
 -      serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB);
 +      serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
  
        serial_out(up, UART_DLL, quot & 0xff);          /* LS of divisor */
        serial_out(up, UART_DLM, quot >> 8);            /* MS of divisor */
  
        serial_out(up, UART_LCR, 0);
        serial_out(up, UART_IER, up->ier);
 -      serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB);
 +      serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
  
        serial_out(up, UART_EFR, up->efr);
        serial_out(up, UART_LCR, cval);
  
        if (baud > 230400 && baud != 3000000)
 -              serial_out(up, UART_OMAP_MDR1, OMAP_MDR1_MODE13X);
 +              serial_out(up, UART_OMAP_MDR1, UART_OMAP_MDR1_13X_MODE);
        else
 -              serial_out(up, UART_OMAP_MDR1, OMAP_MDR1_MODE16X);
 +              serial_out(up, UART_OMAP_MDR1, UART_OMAP_MDR1_16X_MODE);
  
        /* Hardware Flow Control Configuration */
  
        if (termios->c_cflag & CRTSCTS) {
                efr |= (UART_EFR_CTS | UART_EFR_RTS);
 -              serial_out(up, UART_LCR, UART_LCR_DLAB);
 +              serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
  
                up->mcr = serial_in(up, UART_MCR);
                serial_out(up, UART_MCR, up->mcr | UART_MCR_TCRTLR);
  
 -              serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB);
 +              serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
                up->efr = serial_in(up, UART_EFR);
                serial_out(up, UART_EFR, up->efr | UART_EFR_ECB);
  
                serial_out(up, UART_TI752_TCR, OMAP_UART_TCR_TRIG);
                serial_out(up, UART_EFR, efr); /* Enable AUTORTS and AUTOCTS */
 -              serial_out(up, UART_LCR, UART_LCR_DLAB);
 +              serial_out(up, UART_LCR, UART_LCR_CONF_MODE_A);
                serial_out(up, UART_MCR, up->mcr | UART_MCR_RTS);
                serial_out(up, UART_LCR, cval);
        }
@@@ -815,13 -815,13 +815,13 @@@ serial_omap_pm(struct uart_port *port, 
        unsigned char efr;
  
        dev_dbg(up->port.dev, "serial_omap_pm+%d\n", up->pdev->id);
 -      serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB);
 +      serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
        efr = serial_in(up, UART_EFR);
        serial_out(up, UART_EFR, efr | UART_EFR_ECB);
        serial_out(up, UART_LCR, 0);
  
        serial_out(up, UART_IER, (state != 0) ? UART_IERX_SLEEP : 0);
 -      serial_out(up, UART_LCR, OMAP_UART_LCR_CONF_MDB);
 +      serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B);
        serial_out(up, UART_EFR, efr);
        serial_out(up, UART_LCR, 0);
        /* Enable module level wake up */
@@@ -866,12 -866,6 +866,6 @@@ serial_omap_type(struct uart_port *port
        return up->name;
  }
  
- #ifdef CONFIG_SERIAL_OMAP_CONSOLE
- static struct uart_omap_port *serial_omap_console_ports[4];
- static struct uart_driver serial_omap_reg;
  #define BOTH_EMPTY (UART_LSR_TEMT | UART_LSR_THRE)
  
  static inline void wait_for_xmitr(struct uart_omap_port *up)
        }
  }
  
+ #ifdef CONFIG_CONSOLE_POLL
+ static void serial_omap_poll_put_char(struct uart_port *port, unsigned char ch)
+ {
+       struct uart_omap_port *up = (struct uart_omap_port *)port;
+       wait_for_xmitr(up);
+       serial_out(up, UART_TX, ch);
+ }
+ static int serial_omap_poll_get_char(struct uart_port *port)
+ {
+       struct uart_omap_port *up = (struct uart_omap_port *)port;
+       unsigned int status = serial_in(up, UART_LSR);
+       if (!(status & UART_LSR_DR))
+               return NO_POLL_CHAR;
+       return serial_in(up, UART_RX);
+ }
+ #endif /* CONFIG_CONSOLE_POLL */
+ #ifdef CONFIG_SERIAL_OMAP_CONSOLE
+ static struct uart_omap_port *serial_omap_console_ports[4];
+ static struct uart_driver serial_omap_reg;
  static void serial_omap_console_putchar(struct uart_port *port, int ch)
  {
        struct uart_omap_port *up = (struct uart_omap_port *)port;
@@@ -1022,6 -1044,10 +1044,10 @@@ static struct uart_ops serial_omap_pop
        .request_port   = serial_omap_request_port,
        .config_port    = serial_omap_config_port,
        .verify_port    = serial_omap_verify_port,
+ #ifdef CONFIG_CONSOLE_POLL
+       .poll_put_char  = serial_omap_poll_put_char,
+       .poll_get_char  = serial_omap_poll_get_char,
+ #endif
  };
  
  static struct uart_driver serial_omap_reg = {
@@@ -29,6 -29,7 +29,6 @@@
  #include <linux/console.h>
  #include <linux/proc_fs.h>
  #include <linux/seq_file.h>
 -#include <linux/smp_lock.h>
  #include <linux/device.h>
  #include <linux/serial.h> /* for serial_state and serial_icounter_struct */
  #include <linux/serial_core.h>
@@@ -1985,7 -1986,8 +1985,8 @@@ int uart_suspend_port(struct uart_drive
  
        tty_dev = device_find_child(uport->dev, &match, serial_match_port);
        if (device_may_wakeup(tty_dev)) {
-               enable_irq_wake(uport->irq);
+               if (!enable_irq_wake(uport->irq))
+                       uport->irq_wake = 1;
                put_device(tty_dev);
                mutex_unlock(&port->mutex);
                return 0;
@@@ -2051,7 -2053,10 +2052,10 @@@ int uart_resume_port(struct uart_drive
  
        tty_dev = device_find_child(uport->dev, &match, serial_match_port);
        if (!uport->suspended && device_may_wakeup(tty_dev)) {
-               disable_irq_wake(uport->irq);
+               if (uport->irq_wake) {
+                       disable_irq_wake(uport->irq);
+                       uport->irq_wake = 0;
+               }
                mutex_unlock(&port->mutex);
                return 0;
        }
@@@ -2134,6 -2139,7 +2138,7 @@@ uart_report_port(struct uart_driver *dr
        case UPIO_AU:
        case UPIO_TSI:
        case UPIO_DWAPB:
+       case UPIO_DWAPB32:
                snprintf(address, sizeof(address),
                         "MMIO 0x%llx", (unsigned long long)port->mapbase);
                break;
@@@ -2554,6 -2560,7 +2559,7 @@@ int uart_match_port(struct uart_port *p
        case UPIO_AU:
        case UPIO_TSI:
        case UPIO_DWAPB:
+       case UPIO_DWAPB32:
                return (port1->mapbase == port2->mapbase);
        }
        return 0;
diff --combined drivers/tty/n_gsm.c
@@@ -19,7 -19,7 +19,7 @@@
   *
   * TO DO:
   *    Mostly done:    ioctls for setting modes/timing
-  *    Partly done:    hooks so you can pull off frames to non tty devs
+  *    Partly done:    hooks so you can pull off frames to non tty devs
   *    Restart DLCI 0 when it closes ?
   *    Test basic encoding
   *    Improve the tx engine
@@@ -73,8 -73,10 +73,10 @@@ module_param(debug, int, 0600)
  #define T2    (2 * HZ)
  #endif
  
- /* Semi-arbitary buffer size limits. 0710 is normally run with 32-64 byte
-    limits so this is plenty */
+ /*
+  * Semi-arbitary buffer size limits. 0710 is normally run with 32-64 byte
+  * limits so this is plenty
+  */
  #define MAX_MRU 512
  #define MAX_MTU 512
  
@@@ -184,6 -186,9 +186,9 @@@ struct gsm_mux 
  #define GSM_DATA              5
  #define GSM_FCS                       6
  #define GSM_OVERRUN           7
+ #define GSM_LEN0              8
+ #define GSM_LEN1              9
+ #define GSM_SSOF              10
        unsigned int len;
        unsigned int address;
        unsigned int count;
        int encoding;
        u8 control;
        u8 fcs;
+       u8 received_fcs;
        u8 *txframe;                    /* TX framing buffer */
  
        /* Methods for the receiver side */
@@@ -286,7 -292,7 +292,7 @@@ static spinlock_t gsm_mux_lock
  #define MDM_DV                        0x40
  
  #define GSM0_SOF              0xF9
- #define GSM1_SOF              0x7E
+ #define GSM1_SOF              0x7E
  #define GSM1_ESCAPE           0x7D
  #define GSM1_ESCAPE_BITS      0x20
  #define XON                   0x11
@@@ -429,61 -435,63 +435,63 @@@ static void gsm_print_packet(const cha
        if (!(debug & 1))
                return;
  
-       printk(KERN_INFO "%s %d) %c: ", hdr, addr, "RC"[cr]);
+       pr_info("%s %d) %c: ", hdr, addr, "RC"[cr]);
  
        switch (control & ~PF) {
        case SABM:
-               printk(KERN_CONT "SABM");
+               pr_cont("SABM");
                break;
        case UA:
-               printk(KERN_CONT "UA");
+               pr_cont("UA");
                break;
        case DISC:
-               printk(KERN_CONT "DISC");
+               pr_cont("DISC");
                break;
        case DM:
-               printk(KERN_CONT "DM");
+               pr_cont("DM");
                break;
        case UI:
-               printk(KERN_CONT "UI");
+               pr_cont("UI");
                break;
        case UIH:
-               printk(KERN_CONT "UIH");
+               pr_cont("UIH");
                break;
        default:
                if (!(control & 0x01)) {
-                       printk(KERN_CONT "I N(S)%d N(R)%d",
-                               (control & 0x0E) >> 1, (control & 0xE)>> 5);
+                       pr_cont("I N(S)%d N(R)%d",
+                               (control & 0x0E) >> 1, (control & 0xE) >> 5);
                } else switch (control & 0x0F) {
-               case RR:
-                       printk("RR(%d)", (control & 0xE0) >> 5);
-                       break;
-               case RNR:
-                       printk("RNR(%d)", (control & 0xE0) >> 5);
-                       break;
-               case REJ:
-                       printk("REJ(%d)", (control & 0xE0) >> 5);
-                       break;
-               default:
-                       printk(KERN_CONT "[%02X]", control);
+                       case RR:
+                               pr_cont("RR(%d)", (control & 0xE0) >> 5);
+                               break;
+                       case RNR:
+                               pr_cont("RNR(%d)", (control & 0xE0) >> 5);
+                               break;
+                       case REJ:
+                               pr_cont("REJ(%d)", (control & 0xE0) >> 5);
+                               break;
+                       default:
+                               pr_cont("[%02X]", control);
                }
        }
  
        if (control & PF)
-               printk(KERN_CONT "(P)");
+               pr_cont("(P)");
        else
-               printk(KERN_CONT "(F)");
+               pr_cont("(F)");
  
        if (dlen) {
                int ct = 0;
                while (dlen--) {
-                       if (ct % 8 == 0)
-                               printk(KERN_CONT "\n    ");
-                       printk(KERN_CONT "%02X ", *data++);
+                       if (ct % 8 == 0) {
+                               pr_cont("\n");
+                               pr_debug("    ");
+                       }
+                       pr_cont("%02X ", *data++);
                        ct++;
                }
        }
-       printk(KERN_CONT "\n");
+       pr_cont("\n");
  }
  
  
@@@ -522,11 -530,13 +530,13 @@@ static void hex_packet(const unsigned c
  {
        int i;
        for (i = 0; i < len; i++) {
-               if (i && (i % 16) == 0)
-                       printk("\n");
-               printk("%02X ", *p++);
+               if (i && (i % 16) == 0) {
+                       pr_cont("\n");
+                       pr_debug("");
+               }
+               pr_cont("%02X ", *p++);
        }
-       printk("\n");
+       pr_cont("\n");
  }
  
  /**
@@@ -676,7 -686,7 +686,7 @@@ static void gsm_data_kick(struct gsm_mu
                }
  
                if (debug & 4) {
-                       printk("gsm_data_kick: \n");
+                       pr_debug("gsm_data_kick:\n");
                        hex_packet(gsm->txframe, len);
                }
  
@@@ -716,8 -726,8 +726,8 @@@ static void __gsm_data_queue(struct gsm
                if (msg->len < 128)
                        *--dp = (msg->len << 1) | EA;
                else {
 -                      *--dp = (msg->len >> 6) | EA;
 -                      *--dp = (msg->len & 127) << 1;
 +                      *--dp = (msg->len >> 7);        /* bits 7 - 15 */
 +                      *--dp = (msg->len & 127) << 1;  /* bits 0 - 6 */
                }
        }
  
@@@ -968,8 -978,6 +978,8 @@@ static void gsm_control_reply(struct gs
  {
        struct gsm_msg *msg;
        msg = gsm_data_alloc(gsm, 0, dlen + 2, gsm->ftype);
 +      if (msg == NULL)
 +              return;
        msg->data[0] = (cmd & 0xFE) << 1 | EA;  /* Clear C/R */
        msg->data[1] = (dlen << 1) | EA;
        memcpy(msg->data + 2, data, dlen);
@@@ -1231,7 -1239,7 +1241,7 @@@ static void gsm_control_response(struc
  }
  
  /**
-  *    gsm_control_transmit    -       send control packet
+  *    gsm_control_transmit    -       send control packet
   *    @gsm: gsm mux
   *    @ctrl: frame to send
   *
@@@ -1361,7 -1369,7 +1371,7 @@@ static void gsm_dlci_close(struct gsm_d
  {
        del_timer(&dlci->t1);
        if (debug & 8)
-               printk("DLCI %d goes closed.\n", dlci->addr);
+               pr_debug("DLCI %d goes closed.\n", dlci->addr);
        dlci->state = DLCI_CLOSED;
        if (dlci->addr != 0) {
                struct tty_struct  *tty = tty_port_tty_get(&dlci->port);
@@@ -1392,7 -1400,7 +1402,7 @@@ static void gsm_dlci_open(struct gsm_dl
        /* This will let a tty open continue */
        dlci->state = DLCI_OPEN;
        if (debug & 8)
-               printk("DLCI %d goes open.\n", dlci->addr);
+               pr_debug("DLCI %d goes open.\n", dlci->addr);
        wake_up(&dlci->gsm->event);
  }
  
@@@ -1494,29 -1502,29 +1504,29 @@@ static void gsm_dlci_data(struct gsm_dl
        unsigned int modem = 0;
  
        if (debug & 16)
-               printk("%d bytes for tty %p\n", len, tty);
+               pr_debug("%d bytes for tty %p\n", len, tty);
        if (tty) {
                switch (dlci->adaption)  {
-                       /* Unsupported types */
-                       /* Packetised interruptible data */
-                       case 4:
-                               break;
-                       /* Packetised uininterruptible voice/data */
-                       case 3:
-                               break;
-                       /* Asynchronous serial with line state in each frame */
-                       case 2:
-                               while (gsm_read_ea(&modem, *data++) == 0) {
-                                       len--;
-                                       if (len == 0)
-                                               return;
-                               }
-                               gsm_process_modem(tty, dlci, modem);
-                       /* Line state will go via DLCI 0 controls only */
-                       case 1:
-                       default:
-                               tty_insert_flip_string(tty, data, len);
-                               tty_flip_buffer_push(tty);
+               /* Unsupported types */
+               /* Packetised interruptible data */
+               case 4:
+                       break;
+               /* Packetised uininterruptible voice/data */
+               case 3:
+                       break;
+               /* Asynchronous serial with line state in each frame */
+               case 2:
+                       while (gsm_read_ea(&modem, *data++) == 0) {
+                               len--;
+                               if (len == 0)
+                                       return;
+                       }
+                       gsm_process_modem(tty, dlci, modem);
+               /* Line state will go via DLCI 0 controls only */
+               case 1:
+               default:
+                       tty_insert_flip_string(tty, data, len);
+                       tty_flip_buffer_push(tty);
                }
                tty_kref_put(tty);
        }
@@@ -1625,7 -1633,6 +1635,6 @@@ static void gsm_dlci_free(struct gsm_dl
        kfree(dlci);
  }
  
  /*
   *    LAPBish link layer logic
   */
@@@ -1650,10 -1657,12 +1659,12 @@@ static void gsm_queue(struct gsm_mux *g
  
        if ((gsm->control & ~PF) == UI)
                gsm->fcs = gsm_fcs_add_block(gsm->fcs, gsm->buf, gsm->len);
+       /* generate final CRC with received FCS */
+       gsm->fcs = gsm_fcs_add(gsm->fcs, gsm->received_fcs);
        if (gsm->fcs != GOOD_FCS) {
                gsm->bad_fcs++;
                if (debug & 4)
-                       printk("BAD FCS %02x\n", gsm->fcs);
+                       pr_debug("BAD FCS %02x\n", gsm->fcs);
                return;
        }
        address = gsm->address >> 1;
@@@ -1748,6 -1757,8 +1759,8 @@@ invalid
  
  static void gsm0_receive(struct gsm_mux *gsm, unsigned char c)
  {
+       unsigned int len;
        switch (gsm->state) {
        case GSM_SEARCH:        /* SOF marker */
                if (c == GSM0_SOF) {
                        gsm->len = 0;
                        gsm->fcs = INIT_FCS;
                }
-               break;          /* Address EA */
-       case GSM_ADDRESS:
+               break;
+       case GSM_ADDRESS:       /* Address EA */
                gsm->fcs = gsm_fcs_add(gsm->fcs, c);
                if (gsm_read_ea(&gsm->address, c))
                        gsm->state = GSM_CONTROL;
        case GSM_CONTROL:       /* Control Byte */
                gsm->fcs = gsm_fcs_add(gsm->fcs, c);
                gsm->control = c;
-               gsm->state = GSM_LEN;
+               gsm->state = GSM_LEN0;
                break;
-       case GSM_LEN          /* Length EA */
+       case GSM_LEN0:          /* Length EA */
                gsm->fcs = gsm_fcs_add(gsm->fcs, c);
                if (gsm_read_ea(&gsm->len, c)) {
                        if (gsm->len > gsm->mru) {
                                break;
                        }
                        gsm->count = 0;
-                       gsm->state = GSM_DATA;
+                       if (!gsm->len)
+                               gsm->state = GSM_FCS;
+                       else
+                               gsm->state = GSM_DATA;
+                       break;
+               }
+               gsm->state = GSM_LEN1;
+               break;
+       case GSM_LEN1:
+               gsm->fcs = gsm_fcs_add(gsm->fcs, c);
+               len = c;
+               gsm->len |= len << 7;
+               if (gsm->len > gsm->mru) {
+                       gsm->bad_size++;
+                       gsm->state = GSM_SEARCH;
+                       break;
                }
+               gsm->count = 0;
+               if (!gsm->len)
+                       gsm->state = GSM_FCS;
+               else
+                       gsm->state = GSM_DATA;
                break;
        case GSM_DATA:          /* Data */
                gsm->buf[gsm->count++] = c;
                        gsm->state = GSM_FCS;
                break;
        case GSM_FCS:           /* FCS follows the packet */
-               gsm->fcs = c;
+               gsm->received_fcs = c;
+               if (c == GSM0_SOF) {
+                       gsm->state = GSM_SEARCH;
+                       break;
+               }
                gsm_queue(gsm);
-               /* And then back for the next frame */
-               gsm->state = GSM_SEARCH;
+               gsm->state = GSM_SSOF;
+               break;
+       case GSM_SSOF:
+               if (c == GSM0_SOF) {
+                       gsm->state = GSM_SEARCH;
+                       break;
+               }
                break;
        }
  }
  
  /**
-  *    gsm0_receive    -       perform processing for non-transparency
+  *    gsm1_receive    -       perform processing for non-transparency
   *    @gsm: gsm data for this ldisc instance
   *    @c: character
   *
@@@ -1856,7 -1896,7 +1898,7 @@@ static void gsm1_receive(struct gsm_mu
                gsm->state = GSM_DATA;
                break;
        case GSM_DATA:          /* Data */
-               if (gsm->count > gsm->mru ) {   /* Allow one for the FCS */
+               if (gsm->count > gsm->mru) {    /* Allow one for the FCS */
                        gsm->state = GSM_OVERRUN;
                        gsm->bad_size++;
                } else
@@@ -2034,9 -2074,6 +2076,6 @@@ struct gsm_mux *gsm_alloc_mux(void
  }
  EXPORT_SYMBOL_GPL(gsm_alloc_mux);
  
  /**
   *    gsmld_output            -       write to link
   *    @gsm: our mux
@@@ -2054,7 -2091,7 +2093,7 @@@ static int gsmld_output(struct gsm_mux 
                return -ENOSPC;
        }
        if (debug & 4) {
-               printk("-->%d bytes out\n", len);
+               pr_debug("-->%d bytes out\n", len);
                hex_packet(data, len);
        }
        gsm->tty->ops->write(gsm->tty, data, len);
@@@ -2111,7 -2148,7 +2150,7 @@@ static void gsmld_receive_buf(struct tt
        char flags;
  
        if (debug & 4) {
-               printk("Inbytes %dd\n", count);
+               pr_debug("Inbytes %dd\n", count);
                hex_packet(cp, count);
        }
  
                        gsm->error(gsm, *dp, flags);
                        break;
                default:
-                       printk(KERN_ERR "%s: unknown flag %d\n",
+                       WARN_ONCE("%s: unknown flag %d\n",
                               tty_name(tty, buf), flags);
                        break;
                }
@@@ -2323,7 -2360,7 +2362,7 @@@ static int gsmld_config(struct tty_stru
        int need_restart = 0;
  
        /* Stuff we don't support yet - UI or I frame transport, windowing */
-       if ((c->adaption !=1 && c->adaption != 2) || c->k)
+       if ((c->adaption != 1 && c->adaption != 2) || c->k)
                return -EOPNOTSUPP;
        /* Check the MRU/MTU range looks sane */
        if (c->mru > MAX_MRU || c->mtu > MAX_MTU || c->mru < 8 || c->mtu < 8)
        gsm->mru = c->mru;
        gsm->encoding = c->encapsulation;
        gsm->adaption = c->adaption;
 +      gsm->n2 = c->n2;
  
        if (c->i == 1)
                gsm->ftype = UIH;
@@@ -2418,7 -2454,7 +2457,7 @@@ static int gsmld_ioctl(struct tty_struc
                        c.i = 1;
                else
                        c.i = 2;
-               printk("Ftype %d i %d\n", gsm->ftype, c.i);
+               pr_debug("Ftype %d i %d\n", gsm->ftype, c.i);
                c.mru = gsm->mru;
                c.mtu = gsm->mtu;
                c.k = 0;
@@@ -2712,14 -2748,15 +2751,15 @@@ static int __init gsm_init(void
        /* Fill in our line protocol discipline, and register it */
        int status = tty_register_ldisc(N_GSM0710, &tty_ldisc_packet);
        if (status != 0) {
-               printk(KERN_ERR "n_gsm: can't register line discipline (err = %d)\n", status);
+               pr_err("n_gsm: can't register line discipline (err = %d)\n",
+                                                               status);
                return status;
        }
  
        gsm_tty_driver = alloc_tty_driver(256);
        if (!gsm_tty_driver) {
                tty_unregister_ldisc(N_GSM0710);
-               printk(KERN_ERR "gsm_init: tty allocation failed.\n");
+               pr_err("gsm_init: tty allocation failed.\n");
                return -EINVAL;
        }
        gsm_tty_driver->owner   = THIS_MODULE;
        gsm_tty_driver->type            = TTY_DRIVER_TYPE_SERIAL;
        gsm_tty_driver->subtype = SERIAL_TYPE_NORMAL;
        gsm_tty_driver->flags   = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV
-                                                       | TTY_DRIVER_HARDWARE_BREAK;
+                                               | TTY_DRIVER_HARDWARE_BREAK;
        gsm_tty_driver->init_termios    = tty_std_termios;
        /* Fixme */
        gsm_tty_driver->init_termios.c_lflag &= ~ECHO;
        if (tty_register_driver(gsm_tty_driver)) {
                put_tty_driver(gsm_tty_driver);
                tty_unregister_ldisc(N_GSM0710);
-               printk(KERN_ERR "gsm_init: tty registration failed.\n");
+               pr_err("gsm_init: tty registration failed.\n");
                return -EBUSY;
        }
-       printk(KERN_INFO "gsm_init: loaded as %d,%d.\n", gsm_tty_driver->major, gsm_tty_driver->minor_start);
+       pr_debug("gsm_init: loaded as %d,%d.\n",
+                       gsm_tty_driver->major, gsm_tty_driver->minor_start);
        return 0;
  }
  
@@@ -2752,10 -2790,10 +2793,10 @@@ static void __exit gsm_exit(void
  {
        int status = tty_unregister_ldisc(N_GSM0710);
        if (status != 0)
-               printk(KERN_ERR "n_gsm: can't unregister line discipline (err = %d)\n", status);
+               pr_err("n_gsm: can't unregister line discipline (err = %d)\n",
+                                                               status);
        tty_unregister_driver(gsm_tty_driver);
        put_tty_driver(gsm_tty_driver);
-       printk(KERN_INFO "gsm_init: unloaded.\n");
  }
  
  module_init(gsm_init);
diff --combined drivers/tty/tty_io.c
@@@ -559,9 -559,6 +559,9 @@@ void __tty_hangup(struct tty_struct *tt
  
        tty_lock();
  
 +      /* some functions below drop BTM, so we need this bit */
 +      set_bit(TTY_HUPPING, &tty->flags);
 +
        /* inuse_filps is protected by the single tty lock,
           this really needs to change if we want to flush the
           workqueue with the lock held */
        }
        spin_unlock(&tty_files_lock);
  
 +      /*
 +       * it drops BTM and thus races with reopen
 +       * we protect the race by TTY_HUPPING
 +       */
        tty_ldisc_hangup(tty);
  
        read_lock(&tasklist_lock);
        tty->session = NULL;
        tty->pgrp = NULL;
        tty->ctrl_status = 0;
 -      set_bit(TTY_HUPPED, &tty->flags);
        spin_unlock_irqrestore(&tty->ctrl_lock, flags);
  
        /* Account for the p->signal references we killed */
         * can't yet guarantee all that.
         */
        set_bit(TTY_HUPPED, &tty->flags);
 +      clear_bit(TTY_HUPPING, &tty->flags);
        tty_ldisc_enable(tty);
  
        tty_unlock();
@@@ -1317,9 -1310,7 +1317,9 @@@ static int tty_reopen(struct tty_struc
  {
        struct tty_driver *driver = tty->driver;
  
 -      if (test_bit(TTY_CLOSING, &tty->flags))
 +      if (test_bit(TTY_CLOSING, &tty->flags) ||
 +                      test_bit(TTY_HUPPING, &tty->flags) ||
 +                      test_bit(TTY_LDISC_CHANGING, &tty->flags))
                return -EIO;
  
        if (driver->type == TTY_DRIVER_TYPE_PTY &&
@@@ -2627,6 -2618,11 +2627,11 @@@ long tty_ioctl(struct file *file, unsig
                return put_user(tty->ldisc->ops->num, (int __user *)p);
        case TIOCSETD:
                return tiocsetd(tty, p);
+       case TIOCGDEV:
+       {
+               unsigned int ret = new_encode_dev(tty_devnum(real_tty));
+               return put_user(ret, (unsigned int __user *)p);
+       }
        /*
         * Break handling
         */
@@@ -3241,9 -3237,45 +3246,45 @@@ static int __init tty_class_init(void
  postcore_initcall(tty_class_init);
  
  /* 3/2004 jmc: why do these devices exist? */
  static struct cdev tty_cdev, console_cdev;
  
+ static ssize_t show_cons_active(struct device *dev,
+                               struct device_attribute *attr, char *buf)
+ {
+       struct console *cs[16];
+       int i = 0;
+       struct console *c;
+       ssize_t count = 0;
+       acquire_console_sem();
+       for (c = console_drivers; c; c = c->next) {
+               if (!c->device)
+                       continue;
+               if (!c->write)
+                       continue;
+               if ((c->flags & CON_ENABLED) == 0)
+                       continue;
+               cs[i++] = c;
+               if (i >= ARRAY_SIZE(cs))
+                       break;
+       }
+       while (i--)
+               count += sprintf(buf + count, "%s%d%c",
+                                cs[i]->name, cs[i]->index, i ? ' ':'\n');
+       release_console_sem();
+       return count;
+ }
+ static DEVICE_ATTR(active, S_IRUGO, show_cons_active, NULL);
+ static struct device *consdev;
+ void console_sysfs_notify(void)
+ {
+       if (consdev)
+               sysfs_notify(&consdev->kobj, NULL, "active");
+ }
  /*
   * Ok, now we can initialize the rest of the tty devices and can count
   * on memory allocations, interrupts etc..
@@@ -3254,15 -3286,18 +3295,18 @@@ int __init tty_init(void
        if (cdev_add(&tty_cdev, MKDEV(TTYAUX_MAJOR, 0), 1) ||
            register_chrdev_region(MKDEV(TTYAUX_MAJOR, 0), 1, "/dev/tty") < 0)
                panic("Couldn't register /dev/tty driver\n");
-       device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL,
-                             "tty");
+       device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 0), NULL, "tty");
  
        cdev_init(&console_cdev, &console_fops);
        if (cdev_add(&console_cdev, MKDEV(TTYAUX_MAJOR, 1), 1) ||
            register_chrdev_region(MKDEV(TTYAUX_MAJOR, 1), 1, "/dev/console") < 0)
                panic("Couldn't register /dev/console driver\n");
-       device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL,
+       consdev = device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 1), NULL,
                              "console");
+       if (IS_ERR(consdev))
+               consdev = NULL;
+       else
+               device_create_file(consdev, &dev_attr_active);
  
  #ifdef CONFIG_VT
        vty_init(&console_fops);
diff --combined fs/compat_ioctl.c
@@@ -19,6 -19,7 +19,6 @@@
  #include <linux/compiler.h>
  #include <linux/sched.h>
  #include <linux/smp.h>
 -#include <linux/smp_lock.h>
  #include <linux/ioctl.h>
  #include <linux/if.h>
  #include <linux/if_bridge.h>
@@@ -42,7 -43,7 +42,7 @@@
  #include <linux/tty.h>
  #include <linux/vt_kern.h>
  #include <linux/fb.h>
 -#include <linux/videodev.h>
 +#include <linux/videodev2.h>
  #include <linux/netdevice.h>
  #include <linux/raw.h>
  #include <linux/blkdev.h>
@@@ -836,6 -837,7 +836,7 @@@ COMPATIBLE_IOCTL(TCSETSW
  COMPATIBLE_IOCTL(TCSETSF)
  COMPATIBLE_IOCTL(TIOCLINUX)
  COMPATIBLE_IOCTL(TIOCSBRK)
+ COMPATIBLE_IOCTL(TIOCGDEV)
  COMPATIBLE_IOCTL(TIOCCBRK)
  COMPATIBLE_IOCTL(TIOCGSID)
  COMPATIBLE_IOCTL(TIOCGICOUNT)
diff --combined kernel/printk.c
  
  #include <asm/uaccess.h>
  
- /*
-  * for_each_console() allows you to iterate on each console
-  */
- #define for_each_console(con) \
-       for (con = console_drivers; con != NULL; con = con->next)
  /*
   * Architectures can override it:
   */
@@@ -261,12 -255,6 +255,12 @@@ static inline void boot_delay_msec(void
  }
  #endif
  
 +#ifdef CONFIG_SECURITY_DMESG_RESTRICT
 +int dmesg_restrict = 1;
 +#else
 +int dmesg_restrict;
 +#endif
 +
  int do_syslog(int type, char __user *buf, int len, bool from_file)
  {
        unsigned i, j, limit, count;
        char c;
        int error = 0;
  
 -      error = security_syslog(type, from_file);
 +      /*
 +       * If this is from /proc/kmsg we only do the capabilities checks
 +       * at open time.
 +       */
 +      if (type == SYSLOG_ACTION_OPEN || !from_file) {
 +              if (dmesg_restrict && !capable(CAP_SYS_ADMIN))
 +                      return -EPERM;
 +              if ((type != SYSLOG_ACTION_READ_ALL &&
 +                   type != SYSLOG_ACTION_SIZE_BUFFER) &&
 +                  !capable(CAP_SYS_ADMIN))
 +                      return -EPERM;
 +      }
 +
 +      error = security_syslog(type);
        if (error)
                return error;
  
@@@ -1074,23 -1049,21 +1068,23 @@@ static DEFINE_PER_CPU(int, printk_pendi
  
  void printk_tick(void)
  {
 -      if (__get_cpu_var(printk_pending)) {
 -              __get_cpu_var(printk_pending) = 0;
 +      if (__this_cpu_read(printk_pending)) {
 +              __this_cpu_write(printk_pending, 0);
                wake_up_interruptible(&log_wait);
        }
  }
  
  int printk_needs_cpu(int cpu)
  {
 -      return per_cpu(printk_pending, cpu);
 +      if (cpu_is_offline(cpu))
 +              printk_tick();
 +      return __this_cpu_read(printk_pending);
  }
  
  void wake_up_klogd(void)
  {
        if (waitqueue_active(&log_wait))
 -              __raw_get_cpu_var(printk_pending) = 1;
 +              this_cpu_write(printk_pending, 1);
  }
  
  /**
@@@ -1359,6 -1332,7 +1353,7 @@@ void register_console(struct console *n
                spin_unlock_irqrestore(&logbuf_lock, flags);
        }
        release_console_sem();
+       console_sysfs_notify();
  
        /*
         * By unregistering the bootconsoles after we enable the real console
@@@ -1417,6 -1391,7 +1412,7 @@@ int unregister_console(struct console *
                console_drivers->flags |= CON_CONSDEV;
  
        release_console_sem();
+       console_sysfs_notify();
        return res;
  }
  EXPORT_SYMBOL(unregister_console);