Merge 3.8-rc5 into tty-next
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 25 Jan 2013 21:27:36 +0000 (13:27 -0800)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 25 Jan 2013 21:27:36 +0000 (13:27 -0800)
This resolves a number of tty driver merge issues found in linux-next

Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
18 files changed:
1  2 
drivers/s390/char/con3215.c
drivers/staging/fwserial/Kconfig
drivers/staging/fwserial/fwserial.c
drivers/staging/sb105x/Kconfig
drivers/tty/pty.c
drivers/tty/serial/8250/8250.c
drivers/tty/serial/8250/8250.h
drivers/tty/serial/8250/8250_dw.c
drivers/tty/serial/8250/8250_pci.c
drivers/tty/serial/ifx6x60.c
drivers/tty/serial/mxs-auart.c
drivers/tty/serial/samsung.c
drivers/tty/serial/vt8500_serial.c
drivers/usb/class/cdc-acm.c
drivers/usb/gadget/u_serial.c
drivers/usb/serial/ftdi_sio.c
drivers/usb/serial/io_ti.c
include/uapi/linux/serial_core.h

index 2f58e9fde156297b06dae7f6e6badd977d765603,33b7141a182f6ef369ef9475f1a9f5293561cd2c..7b00fa634d40bf96ac5fe119431a562871a92b57
@@@ -44,6 -44,7 +44,7 @@@
  #define RAW3215_NR_CCWS           3
  #define RAW3215_TIMEOUT           HZ/10     /* time for delayed output */
  
+ #define RAW3215_FIXED     1         /* 3215 console device is not be freed */
  #define RAW3215_WORKING           4         /* set if a request is being worked on */
  #define RAW3215_THROTTLED   8       /* set if reading is disabled */
  #define RAW3215_STOPPED           16        /* set if writing is disabled */
@@@ -411,9 -412,8 +412,9 @@@ static void raw3215_irq(struct ccw_devi
                                break;
  
                        case CTRLCHAR_CTRL:
 -                              tty_insert_flip_char(tty, cchar, TTY_NORMAL);
 -                              tty_flip_buffer_push(tty);
 +                              tty_insert_flip_char(&raw->port, cchar,
 +                                              TTY_NORMAL);
 +                              tty_flip_buffer_push(&raw->port);
                                break;
  
                        case CTRLCHAR_NONE:
                                        count++;
                                } else
                                        count -= 2;
 -                              tty_insert_flip_string(tty, raw->inbuf, count);
 -                              tty_flip_buffer_push(tty);
 +                              tty_insert_flip_string(&raw->port, raw->inbuf,
 +                                              count);
 +                              tty_flip_buffer_push(&raw->port);
                                break;
                        }
                } else if (req->type == RAW3215_WRITE) {
@@@ -632,7 -631,8 +633,8 @@@ static void raw3215_shutdown(struct raw
        DECLARE_WAITQUEUE(wait, current);
        unsigned long flags;
  
-       if (!(raw->port.flags & ASYNC_INITIALIZED))
+       if (!(raw->port.flags & ASYNC_INITIALIZED) ||
+           (raw->flags & RAW3215_FIXED))
                return;
        /* Wait for outstanding requests, then free irq */
        spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
@@@ -807,7 -807,7 +809,7 @@@ static struct ccw_driver raw3215_ccw_dr
        .freeze         = &raw3215_pm_stop,
        .thaw           = &raw3215_pm_start,
        .restore        = &raw3215_pm_start,
-       .int_class      = IOINT_C15,
+       .int_class      = IRQIO_C15,
  };
  
  #ifdef CONFIG_TN3215_CONSOLE
@@@ -929,6 -929,8 +931,8 @@@ static int __init con3215_init(void
        dev_set_drvdata(&cdev->dev, raw);
        cdev->handler = raw3215_irq;
  
+       raw->flags |= RAW3215_FIXED;
        /* Request the console irq */
        if (raw3215_startup(raw) != 0) {
                raw3215_free_info(raw);
@@@ -968,7 -970,7 +972,7 @@@ static int tty3215_open(struct tty_stru
  
        tty_port_tty_set(&raw->port, tty);
  
 -      tty->low_latency = 0;  /* don't use bottom half for pushing chars */
 +      raw->port.low_latency = 0; /* don't use bottom half for pushing chars */
        /*
         * Start up 3215 device
         */
index 9cdb3cdc4b667eeb53d7624207fa9786a1c8687e,b2f8331e4acf90005887a7f1e5947d0c7b560aea..a0812d99136f5e171c277e88f637579cfea4c71c
@@@ -1,9 -1,11 +1,11 @@@
  config FIREWIRE_SERIAL
         tristate "TTY over Firewire"
 -       depends on FIREWIRE
 +       depends on FIREWIRE && TTY
         help
            This enables TTY over IEEE 1394, providing high-speed serial
-         connectivity to cabled peers.
+         connectivity to cabled peers. This driver implements a
+         ad-hoc transport protocol and is currently limited to
+         Linux-to-Linux communication.
  
          To compile this driver as a module, say M here:  the module will
          be called firewire-serial.
index b403393c49c3d6d217729304759ce139976f6523,d03a7f57e8d475ceddedb052d42b3077c2a7745d..e5e8f2f36e0ce72a530564d81d9970695999977d
@@@ -179,7 -179,7 +179,7 @@@ static void dump_profile(struct seq_fil
  /* Returns the max receive packet size for the given card */
  static inline int device_max_receive(struct fw_device *fw_device)
  {
-       return 1 <<  (clamp_t(int, fw_device->max_rec, 8U, 13U) + 1);
+       return 1 <<  (clamp_t(int, fw_device->max_rec, 8U, 11U) + 1);
  }
  
  static void fwtty_log_tx_error(struct fwtty_port *port, int rcode)
@@@ -489,11 -489,16 +489,11 @@@ static void fwtty_do_hangup(struct work
  static void fwtty_emit_breaks(struct work_struct *work)
  {
        struct fwtty_port *port = to_port(to_delayed_work(work), emit_breaks);
 -      struct tty_struct *tty;
        static const char buf[16];
        unsigned long now = jiffies;
        unsigned long elapsed = now - port->break_last;
        int n, t, c, brk = 0;
  
 -      tty = tty_port_tty_get(&port->port);
 -      if (!tty)
 -              return;
 -
        /* generate breaks at the line rate (but at least 1) */
        n = (elapsed * port->cps) / HZ + 1;
        port->break_last = now;
  
        while (n) {
                t = min(n, 16);
 -              c = tty_insert_flip_string_fixed_flag(tty, buf, TTY_BREAK, t);
 +              c = tty_insert_flip_string_fixed_flag(&port->port, buf,
 +                              TTY_BREAK, t);
                n -= c;
                brk += c;
                if (c < t)
                        break;
        }
 -      tty_flip_buffer_push(tty);
 -
 -      tty_kref_put(tty);
 +      tty_flip_buffer_push(&port->port);
  
        if (port->mstatus & (UART_LSR_BI << 24))
                schedule_delayed_work(&port->emit_breaks, FREQ_BREAKS);
@@@ -523,9 -529,13 +523,9 @@@ static void fwtty_pushrx(struct work_st
        struct buffered_rx *buf, *next;
        int n, c = 0;
  
 -      tty = tty_port_tty_get(&port->port);
 -      if (!tty)
 -              return;
 -
        spin_lock_bh(&port->lock);
        list_for_each_entry_safe(buf, next, &port->buf_list, list) {
 -              n = tty_insert_flip_string_fixed_flag(tty, buf->data,
 +              n = tty_insert_flip_string_fixed_flag(&port->port, buf->data,
                                                      TTY_NORMAL, buf->n);
                c += n;
                port->buffered -= n;
                                memmove(buf->data, buf->data + n, buf->n - n);
                                buf->n -= n;
                        }
 -                      __fwtty_throttle(port, tty);
 +                      tty = tty_port_tty_get(&port->port);
 +                      if (tty) {
 +                              __fwtty_throttle(port, tty);
 +                              tty_kref_put(tty);
 +                      }
                        break;
                } else {
                        list_del(&buf->list);
                }
        }
        if (c > 0)
 -              tty_flip_buffer_push(tty);
 +              tty_flip_buffer_push(&port->port);
  
        if (list_empty(&port->buf_list))
                clear_bit(BUFFERING_RX, &port->flags);
        spin_unlock_bh(&port->lock);
 -
 -      tty_kref_put(tty);
  }
  
  static int fwtty_buffer_rx(struct fwtty_port *port, unsigned char *d, size_t n)
@@@ -585,6 -593,10 +585,6 @@@ static int fwtty_rx(struct fwtty_port *
        unsigned lsr;
        int err = 0;
  
 -      tty = tty_port_tty_get(&port->port);
 -      if (!tty)
 -              return -ENOENT;
 -
        fwtty_dbg(port, "%d", n);
        profile_size_distrib(port->stats.reads, n);
  
  
        lsr &= port->status_mask;
        if (lsr & ~port->ignore_mask & UART_LSR_OE) {
 -              if (!tty_insert_flip_char(tty, 0, TTY_OVERRUN)) {
 +              if (!tty_insert_flip_char(&port->port, 0, TTY_OVERRUN)) {
                        err = -EIO;
                        goto out;
                }
        }
  
        if (!test_bit(BUFFERING_RX, &port->flags)) {
 -              c = tty_insert_flip_string_fixed_flag(tty, data, TTY_NORMAL, n);
 +              c = tty_insert_flip_string_fixed_flag(&port->port, data,
 +                              TTY_NORMAL, n);
                if (c > 0)
 -                      tty_flip_buffer_push(tty);
 +                      tty_flip_buffer_push(&port->port);
                n -= c;
  
                if (n) {
                        /* start buffering and throttling */
                        n -= fwtty_buffer_rx(port, &data[c], n);
  
 -                      spin_lock_bh(&port->lock);
 -                      __fwtty_throttle(port, tty);
 -                      spin_unlock_bh(&port->lock);
 +                      tty = tty_port_tty_get(&port->port);
 +                      if (tty) {
 +                              spin_lock_bh(&port->lock);
 +                              __fwtty_throttle(port, tty);
 +                              spin_unlock_bh(&port->lock);
 +                              tty_kref_put(tty);
 +                      }
                }
        } else
                n -= fwtty_buffer_rx(port, data, n);
        }
  
  out:
 -      tty_kref_put(tty);
 -
        port->icount.rx += len;
        port->stats.lost += n;
        return err;
index 6a2e1b78e8440c51ade7a64b28d97443fae37f59,1facad625554b0b88baf67c70e4a33b46d77560b..245e7847a35423f1d51f44feecc48ae46df8dbca
@@@ -1,7 -1,8 +1,7 @@@
  config SB105X
        tristate "SystemBase PCI Multiport UART"
        select SERIAL_CORE
-       depends on PCI && TTY && BROKEN
 -      depends on PCI
 -      depends on X86
++      depends on PCI && X86 && TTY && BROKEN
        help
          A driver for the SystemBase Multi-2/PCI serial card
  
diff --combined drivers/tty/pty.c
index 40ff2bf68b436c7e150b8fdc27ac45208e385d9e,79ff3a5e925d6fdc252c6aa6d2f066e959e4637f..755600f6120f9e896bce0bb66a937b4d33815b8e
@@@ -47,6 -47,7 +47,6 @@@ static void pty_close(struct tty_struc
        /* Review - krefs on tty_link ?? */
        if (!tty->link)
                return;
 -      tty->link->packet = 0;
        set_bit(TTY_OTHER_CLOSED, &tty->link->flags);
        wake_up_interruptible(&tty->link->read_wait);
        wake_up_interruptible(&tty->link->write_wait);
@@@ -54,9 -55,9 +54,9 @@@
                set_bit(TTY_OTHER_CLOSED, &tty->flags);
  #ifdef CONFIG_UNIX98_PTYS
                if (tty->driver == ptm_driver) {
 -                      mutex_lock(&devpts_mutex);
 +                      mutex_lock(&devpts_mutex);
                        devpts_pty_kill(tty->link->driver_data);
 -                      mutex_unlock(&devpts_mutex);
 +                      mutex_unlock(&devpts_mutex);
                }
  #endif
                tty_unlock(tty);
@@@ -119,10 -120,10 +119,10 @@@ static int pty_write(struct tty_struct 
  
        if (c > 0) {
                /* Stuff the data into the input queue of the other end */
 -              c = tty_insert_flip_string(to, buf, c);
 +              c = tty_insert_flip_string(to->port, buf, c);
                /* And shovel */
                if (c) {
 -                      tty_flip_buffer_push(to);
 +                      tty_flip_buffer_push(to->port);
                        tty_wakeup(tty);
                }
        }
@@@ -440,6 -441,8 +440,8 @@@ static int pty_bsd_ioctl(struct tty_str
                return pty_get_pktmode(tty, (int __user *)arg);
        case TIOCSIG:    /* Send signal to other side of pty */
                return pty_signal(tty, (int) arg);
+       case TIOCGPTN: /* TTY returns ENOTTY, but glibc expects EINVAL here */
+               return -EINVAL;
        }
        return -ENOIOCTLCMD;
  }
@@@ -660,7 -663,7 +662,7 @@@ static const struct tty_operations pty_
   *    Allocate a unix98 pty master device from the ptmx driver.
   *
   *    Locking: tty_mutex protects the init_dev work. tty->count should
 - *            protect the rest.
 + *            protect the rest.
   *            allocated_ptys_lock handles the list of free pty numbers
   */
  
@@@ -794,7 -797,7 +796,7 @@@ static void __init unix98_pty_init(void
        cdev_init(&ptmx_cdev, &ptmx_fops);
        if (cdev_add(&ptmx_cdev, MKDEV(TTYAUX_MAJOR, 2), 1) ||
            register_chrdev_region(MKDEV(TTYAUX_MAJOR, 2), 1, "/dev/ptmx") < 0)
 -              panic("Couldn't register /dev/ptmx driver\n");
 +              panic("Couldn't register /dev/ptmx driver");
        device_create(tty_class, NULL, MKDEV(TTYAUX_MAJOR, 2), NULL, "ptmx");
  }
  
index cb7db5a8ae9295d25ff560626ddd2215a2c65075,f9320437a64971c605b3e153d2a8aa4b160155bf..24939ca3eedc7ed66dbd20e18d79a2d7abecf108
@@@ -239,6 -239,13 +239,6 @@@ static const struct serial8250_config u
                .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
                .flags          = UART_CAP_FIFO | UART_CAP_UUE | UART_CAP_RTOIE,
        },
 -      [PORT_RM9000] = {
 -              .name           = "RM9000",
 -              .fifo_size      = 16,
 -              .tx_loadsz      = 16,
 -              .fcr            = UART_FCR_ENABLE_FIFO | UART_FCR_R_TRIG_10,
 -              .flags          = UART_CAP_FIFO,
 -      },
        [PORT_OCTEON] = {
                .name           = "OCTEON",
                .fifo_size      = 64,
                                  UART_FCR_R_TRIG_00 | UART_FCR_T_TRIG_00,
                .flags          = UART_CAP_FIFO,
        },
+       [PORT_BRCM_TRUMANAGE] = {
+               .name           = "TruManage",
+               .fifo_size      = 1,
+               .tx_loadsz      = 1024,
+               .flags          = UART_CAP_HFIFO,
+       },
        [PORT_8250_CIR] = {
                .name           = "CIR port"
        }
@@@ -357,6 -370,56 +363,6 @@@ static void au_serial_dl_write(struct u
  
  #endif
  
 -#ifdef CONFIG_SERIAL_8250_RM9K
 -
 -static const u8
 -      regmap_in[8] = {
 -              [UART_RX]       = 0x00,
 -              [UART_IER]      = 0x0c,
 -              [UART_IIR]      = 0x14,
 -              [UART_LCR]      = 0x1c,
 -              [UART_MCR]      = 0x20,
 -              [UART_LSR]      = 0x24,
 -              [UART_MSR]      = 0x28,
 -              [UART_SCR]      = 0x2c
 -      },
 -      regmap_out[8] = {
 -              [UART_TX]       = 0x04,
 -              [UART_IER]      = 0x0c,
 -              [UART_FCR]      = 0x18,
 -              [UART_LCR]      = 0x1c,
 -              [UART_MCR]      = 0x20,
 -              [UART_LSR]      = 0x24,
 -              [UART_MSR]      = 0x28,
 -              [UART_SCR]      = 0x2c
 -      };
 -
 -static unsigned int rm9k_serial_in(struct uart_port *p, int offset)
 -{
 -      offset = regmap_in[offset] << p->regshift;
 -      return readl(p->membase + offset);
 -}
 -
 -static void rm9k_serial_out(struct uart_port *p, int offset, int value)
 -{
 -      offset = regmap_out[offset] << p->regshift;
 -      writel(value, p->membase + offset);
 -}
 -
 -static int rm9k_serial_dl_read(struct uart_8250_port *up)
 -{
 -      return ((__raw_readl(up->port.membase + 0x10) << 8) |
 -              (__raw_readl(up->port.membase + 0x08) & 0xff)) & 0xffff;
 -}
 -
 -static void rm9k_serial_dl_write(struct uart_8250_port *up, int value)
 -{
 -      __raw_writel(value, up->port.membase + 0x08);
 -      __raw_writel(value >> 8, up->port.membase + 0x10);
 -}
 -
 -#endif
 -
  static unsigned int hub6_serial_in(struct uart_port *p, int offset)
  {
        offset = offset << p->regshift;
@@@ -434,6 -497,15 +440,6 @@@ static void set_io_from_upio(struct uar
                p->serial_out = mem32_serial_out;
                break;
  
 -#ifdef CONFIG_SERIAL_8250_RM9K
 -      case UPIO_RM9000:
 -              p->serial_in = rm9k_serial_in;
 -              p->serial_out = rm9k_serial_out;
 -              up->dl_read = rm9k_serial_dl_read;
 -              up->dl_write = rm9k_serial_dl_write;
 -              break;
 -#endif
 -
  #ifdef CONFIG_MIPS_ALCHEMY
        case UPIO_AU:
                p->serial_in = au_serial_in;
@@@ -1269,9 -1341,7 +1275,9 @@@ static void serial8250_start_tx(struct 
        struct uart_8250_port *up =
                container_of(port, struct uart_8250_port, port);
  
 -      if (!(up->ier & UART_IER_THRI)) {
 +      if (up->dma && !serial8250_tx_dma(up)) {
 +              return;
 +      } else if (!(up->ier & UART_IER_THRI)) {
                up->ier |= UART_IER_THRI;
                serial_port_out(port, UART_IER, up->ier);
  
                        unsigned char lsr;
                        lsr = serial_in(up, UART_LSR);
                        up->lsr_saved_flags |= lsr & LSR_SAVE_FLAGS;
 -                      if ((port->type == PORT_RM9000) ?
 -                              (lsr & UART_LSR_THRE) :
 -                              (lsr & UART_LSR_TEMT))
 +                      if (lsr & UART_LSR_TEMT)
                                serial8250_tx_chars(up);
                }
        }
@@@ -1325,6 -1397,7 +1331,6 @@@ unsigned cha
  serial8250_rx_chars(struct uart_8250_port *up, unsigned char lsr)
  {
        struct uart_port *port = &up->port;
 -      struct tty_struct *tty = port->state->port.tty;
        unsigned char ch;
        int max_count = 256;
        char flag;
@@@ -1389,7 -1462,7 +1395,7 @@@ ignore_char
                lsr = serial_in(up, UART_LSR);
        } while ((lsr & (UART_LSR_DR | UART_LSR_BI)) && (max_count-- > 0));
        spin_unlock(&port->lock);
 -      tty_flip_buffer_push(tty);
 +      tty_flip_buffer_push(&port->state->port);
        spin_lock(&port->lock);
        return lsr;
  }
@@@ -1423,6 -1496,11 +1429,11 @@@ void serial8250_tx_chars(struct uart_82
                port->icount.tx++;
                if (uart_circ_empty(xmit))
                        break;
+               if (up->capabilities & UART_CAP_HFIFO) {
+                       if ((serial_port_in(port, UART_LSR) & BOTH_EMPTY) !=
+                           BOTH_EMPTY)
+                               break;
+               }
        } while (--count > 0);
  
        if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
@@@ -1469,7 -1547,6 +1480,7 @@@ int serial8250_handle_irq(struct uart_p
        unsigned long flags;
        struct uart_8250_port *up =
                container_of(port, struct uart_8250_port, port);
 +      int dma_err = 0;
  
        if (iir & UART_IIR_NO_INT)
                return 0;
  
        DEBUG_INTR("status = %x...", status);
  
 -      if (status & (UART_LSR_DR | UART_LSR_BI))
 -              status = serial8250_rx_chars(up, status);
 +      if (status & (UART_LSR_DR | UART_LSR_BI)) {
 +              if (up->dma)
 +                      dma_err = serial8250_rx_dma(up, iir);
 +
 +              if (!up->dma || dma_err)
 +                      status = serial8250_rx_chars(up, status);
 +      }
        serial8250_modem_status(up);
        if (status & UART_LSR_THRE)
                serial8250_tx_chars(up);
@@@ -1919,12 -1991,9 +1930,12 @@@ static int serial8250_startup(struct ua
        if (port->type == PORT_8250_CIR)
                return -ENODEV;
  
 -      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;
 +      if (!port->fifosize)
 +              port->fifosize = uart_config[port->type].fifo_size;
 +      if (!up->tx_loadsz)
 +              up->tx_loadsz = uart_config[port->type].tx_loadsz;
 +      if (!up->capabilities)
 +              up->capabilities = uart_config[port->type].flags;
        up->mcr = 0;
  
        if (port->iotype != up->cur_iotype)
@@@ -2128,18 -2197,6 +2139,18 @@@ dont_test_tx_en
        up->lsr_saved_flags = 0;
        up->msr_saved_flags = 0;
  
 +      /*
 +       * Request DMA channels for both RX and TX.
 +       */
 +      if (up->dma) {
 +              retval = serial8250_request_dma(up);
 +              if (retval) {
 +                      pr_warn_ratelimited("ttyS%d - failed to request DMA\n",
 +                                          serial_index(port));
 +                      up->dma = NULL;
 +              }
 +      }
 +
        /*
         * Finally, enable interrupts.  Note: Modem status interrupts
         * are set via set_termios(), which will be occurring imminently
@@@ -2173,9 -2230,6 +2184,9 @@@ static void serial8250_shutdown(struct 
        up->ier = 0;
        serial_port_out(port, UART_IER, 0);
  
 +      if (up->dma)
 +              serial8250_release_dma(up);
 +
        spin_lock_irqsave(&port->lock, flags);
        if (port->flags & UPF_FOURPORT) {
                /* reset interrupts on the AST Fourport board */
@@@ -2772,12 -2826,9 +2783,12 @@@ static voi
  serial8250_init_fixed_type_port(struct uart_8250_port *up, unsigned int type)
  {
        up->port.type = type;
 -      up->port.fifosize = uart_config[type].fifo_size;
 -      up->capabilities = uart_config[type].flags;
 -      up->tx_loadsz = uart_config[type].tx_loadsz;
 +      if (!up->port.fifosize)
 +              up->port.fifosize = uart_config[type].fifo_size;
 +      if (!up->tx_loadsz)
 +              up->tx_loadsz = uart_config[type].tx_loadsz;
 +      if (!up->capabilities)
 +              up->capabilities = uart_config[type].flags;
  }
  
  static void __init
@@@ -3211,10 -3262,6 +3222,10 @@@ int serial8250_register_8250_port(struc
                uart->bugs              = up->bugs;
                uart->port.mapbase      = up->port.mapbase;
                uart->port.private_data = up->port.private_data;
 +              uart->port.fifosize     = up->port.fifosize;
 +              uart->tx_loadsz         = up->tx_loadsz;
 +              uart->capabilities      = up->capabilities;
 +
                if (up->port.dev)
                        uart->port.dev = up->port.dev;
  
                        uart->dl_read = up->dl_read;
                if (up->dl_write)
                        uart->dl_write = up->dl_write;
 +              if (up->dma)
 +                      uart->dma = up->dma;
  
                if (serial8250_isa_config != NULL)
                        serial8250_isa_config(0, &uart->port,
index 363d549d2e0dc1763595242ea32601b62d37bb1b,12caa1292b75c20b3d8221d4576a6f97c69db3d4..34eb676916fe372e43a948895b512bc5ca51ed09
   */
  
  #include <linux/serial_8250.h>
 +#include <linux/dmaengine.h>
 +
 +struct uart_8250_dma {
 +      dma_filter_fn           fn;
 +      void                    *rx_param;
 +      void                    *tx_param;
 +
 +      int                     rx_chan_id;
 +      int                     tx_chan_id;
 +
 +      struct dma_slave_config rxconf;
 +      struct dma_slave_config txconf;
 +
 +      struct dma_chan         *rxchan;
 +      struct dma_chan         *txchan;
 +
 +      dma_addr_t              rx_addr;
 +      dma_addr_t              tx_addr;
 +
 +      dma_cookie_t            rx_cookie;
 +      dma_cookie_t            tx_cookie;
 +
 +      void                    *rx_buf;
 +
 +      size_t                  rx_size;
 +      size_t                  tx_size;
 +
 +      unsigned char           tx_running:1;
 +};
  
  struct old_serial_port {
        unsigned int uart;
@@@ -69,6 -40,7 +69,7 @@@ struct serial8250_config 
  #define UART_CAP_AFE  (1 << 11)       /* MCR-based hw flow control */
  #define UART_CAP_UUE  (1 << 12)       /* UART needs IER bit 6 set (Xscale) */
  #define UART_CAP_RTOIE        (1 << 13)       /* UART needs IER bit 4 set (Xscale, Tegra) */
+ #define UART_CAP_HFIFO        (1 << 14)       /* UART has a "hidden" FIFO */
  
  #define UART_BUG_QUOT (1 << 0)        /* UART has buggy quot LSB */
  #define UART_BUG_TXEN (1 << 1)        /* UART has buggy TX IIR status */
@@@ -171,24 -143,3 +172,24 @@@ static inline int is_omap1510_8250(stru
        return 0;
  }
  #endif
 +
 +#ifdef CONFIG_SERIAL_8250_DMA
 +extern int serial8250_tx_dma(struct uart_8250_port *);
 +extern int serial8250_rx_dma(struct uart_8250_port *, unsigned int iir);
 +extern int serial8250_request_dma(struct uart_8250_port *);
 +extern void serial8250_release_dma(struct uart_8250_port *);
 +#else
 +static inline int serial8250_tx_dma(struct uart_8250_port *p)
 +{
 +      return -1;
 +}
 +static inline int serial8250_rx_dma(struct uart_8250_port *p, unsigned int iir)
 +{
 +      return -1;
 +}
 +static inline int serial8250_request_dma(struct uart_8250_port *p)
 +{
 +      return -1;
 +}
 +static inline void serial8250_release_dma(struct uart_8250_port *p) { }
 +#endif
index 117bb8b0359830c647b2f4c394c2006828fe8a35,096d2ef48b32f6b62abfe5c220a44440545fb0b4..db0e66f6dd0e3a4458521546cfb11cdc0fccf0dc
@@@ -2,7 -2,6 +2,7 @@@
   * Synopsys DesignWare 8250 driver.
   *
   * Copyright 2011 Picochip, Jamie Iles.
 + * Copyright 2013 Intel Corporation
   *
   * 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
  #include <linux/of_platform.h>
  #include <linux/platform_device.h>
  #include <linux/slab.h>
 +#include <linux/acpi.h>
 +
 +#include "8250.h"
 +
 +/* Offsets for the DesignWare specific registers */
 +#define DW_UART_USR   0x1f /* UART Status Register */
 +#define DW_UART_CPR   0xf4 /* Component Parameter Register */
 +#define DW_UART_UCV   0xf8 /* UART Component Version */
 +
 +/* Intel Low Power Subsystem specific */
 +#define LPSS_PRV_CLOCK_PARAMS 0x800
 +
 +/* Component Parameter Register bits */
 +#define DW_UART_CPR_ABP_DATA_WIDTH    (3 << 0)
 +#define DW_UART_CPR_AFCE_MODE         (1 << 4)
 +#define DW_UART_CPR_THRE_MODE         (1 << 5)
 +#define DW_UART_CPR_SIR_MODE          (1 << 6)
 +#define DW_UART_CPR_SIR_LP_MODE               (1 << 7)
 +#define DW_UART_CPR_ADDITIONAL_FEATURES       (1 << 8)
 +#define DW_UART_CPR_FIFO_ACCESS               (1 << 9)
 +#define DW_UART_CPR_FIFO_STAT         (1 << 10)
 +#define DW_UART_CPR_SHADOW            (1 << 11)
 +#define DW_UART_CPR_ENCODED_PARMS     (1 << 12)
 +#define DW_UART_CPR_DMA_EXTRA         (1 << 13)
 +#define DW_UART_CPR_FIFO_MODE         (0xff << 16)
 +/* Helper for fifo size calculation */
 +#define DW_UART_CPR_FIFO_SIZE(a)      (((a >> 16) & 0xff) * 16)
 +
  
  struct dw8250_data {
        int     last_lcr;
@@@ -95,6 -66,9 +95,6 @@@ static unsigned int dw8250_serial_in32(
        return readl(p->membase + offset);
  }
  
 -/* Offset for the DesignWare's UART Status Register. */
 -#define UART_USR      0x1f
 -
  static int dw8250_handle_irq(struct uart_port *p)
  {
        struct dw8250_data *d = p->private_data;
                return 1;
        } else if ((iir & UART_IIR_BUSY) == UART_IIR_BUSY) {
                /* Clear the USR and write the LCR again. */
 -              (void)p->serial_in(p, UART_USR);
 +              (void)p->serial_in(p, DW_UART_USR);
-               p->serial_out(p, d->last_lcr, UART_LCR);
+               p->serial_out(p, UART_LCR, d->last_lcr);
  
                return 1;
        }
        return 0;
  }
  
 +static int dw8250_probe_of(struct uart_port *p)
 +{
 +      struct device_node      *np = p->dev->of_node;
 +      u32                     val;
 +
 +      if (!of_property_read_u32(np, "reg-io-width", &val)) {
 +              switch (val) {
 +              case 1:
 +                      break;
 +              case 4:
 +                      p->iotype = UPIO_MEM32;
 +                      p->serial_in = dw8250_serial_in32;
 +                      p->serial_out = dw8250_serial_out32;
 +                      break;
 +              default:
 +                      dev_err(p->dev, "unsupported reg-io-width (%u)\n", val);
 +                      return -EINVAL;
 +              }
 +      }
 +
 +      if (!of_property_read_u32(np, "reg-shift", &val))
 +              p->regshift = val;
 +
 +      if (of_property_read_u32(np, "clock-frequency", &val)) {
 +              dev_err(p->dev, "no clock-frequency property set\n");
 +              return -EINVAL;
 +      }
 +      p->uartclk = val;
 +
 +      return 0;
 +}
 +
 +#ifdef CONFIG_ACPI
 +static bool dw8250_acpi_dma_filter(struct dma_chan *chan, void *parm)
 +{
 +      return chan->chan_id == *(int *)parm;
 +}
 +
 +static acpi_status
 +dw8250_acpi_walk_resource(struct acpi_resource *res, void *data)
 +{
 +      struct uart_port                *p = data;
 +      struct uart_8250_port           *port;
 +      struct uart_8250_dma            *dma;
 +      struct acpi_resource_fixed_dma  *fixed_dma;
 +      struct dma_slave_config         *slave;
 +
 +      port = container_of(p, struct uart_8250_port, port);
 +
 +      switch (res->type) {
 +      case ACPI_RESOURCE_TYPE_FIXED_DMA:
 +              fixed_dma = &res->data.fixed_dma;
 +
 +              /* TX comes first */
 +              if (!port->dma) {
 +                      dma = devm_kzalloc(p->dev, sizeof(*dma), GFP_KERNEL);
 +                      if (!dma)
 +                              return AE_NO_MEMORY;
 +
 +                      port->dma = dma;
 +                      slave = &dma->txconf;
 +
 +                      slave->direction        = DMA_MEM_TO_DEV;
 +                      slave->dst_addr_width   = DMA_SLAVE_BUSWIDTH_1_BYTE;
 +                      slave->slave_id         = fixed_dma->request_lines;
 +                      slave->dst_maxburst     = port->tx_loadsz / 4;
 +
 +                      dma->tx_chan_id         = fixed_dma->channels;
 +                      dma->tx_param           = &dma->tx_chan_id;
 +                      dma->fn                 = dw8250_acpi_dma_filter;
 +              } else {
 +                      dma = port->dma;
 +                      slave = &dma->rxconf;
 +
 +                      slave->direction        = DMA_DEV_TO_MEM;
 +                      slave->src_addr_width   = DMA_SLAVE_BUSWIDTH_1_BYTE;
 +                      slave->slave_id         = fixed_dma->request_lines;
 +                      slave->src_maxburst     = p->fifosize / 4;
 +
 +                      dma->rx_chan_id         = fixed_dma->channels;
 +                      dma->rx_param           = &dma->rx_chan_id;
 +              }
 +
 +              break;
 +      }
 +
 +      return AE_OK;
 +}
 +
 +static int dw8250_probe_acpi(struct uart_port *p)
 +{
 +      const struct acpi_device_id *id;
 +      acpi_status status;
 +      u32 reg;
 +
 +      id = acpi_match_device(p->dev->driver->acpi_match_table, p->dev);
 +      if (!id)
 +              return -ENODEV;
 +
 +      p->iotype = UPIO_MEM32;
 +      p->serial_in = dw8250_serial_in32;
 +      p->serial_out = dw8250_serial_out32;
 +      p->regshift = 2;
 +      p->uartclk = (unsigned int)id->driver_data;
 +
 +      status = acpi_walk_resources(ACPI_HANDLE(p->dev), METHOD_NAME__CRS,
 +                                   dw8250_acpi_walk_resource, p);
 +      if (ACPI_FAILURE(status)) {
 +              dev_err_ratelimited(p->dev, "%s failed \"%s\"\n", __func__,
 +                                  acpi_format_exception(status));
 +              return -ENODEV;
 +      }
 +
 +      /* Fix Haswell issue where the clocks do not get enabled */
 +      if (!strcmp(id->id, "INT33C4") || !strcmp(id->id, "INT33C5")) {
 +              reg = readl(p->membase + LPSS_PRV_CLOCK_PARAMS);
 +              writel(reg | 1, p->membase + LPSS_PRV_CLOCK_PARAMS);
 +      }
 +
 +      return 0;
 +}
 +#else
 +static inline int dw8250_probe_acpi(struct uart_port *p)
 +{
 +      return -ENODEV;
 +}
 +#endif /* CONFIG_ACPI */
 +
 +static void dw8250_setup_port(struct uart_8250_port *up)
 +{
 +      struct uart_port        *p = &up->port;
 +      u32                     reg = readl(p->membase + DW_UART_UCV);
 +
 +      /*
 +       * If the Component Version Register returns zero, we know that
 +       * ADDITIONAL_FEATURES are not enabled. No need to go any further.
 +       */
 +      if (!reg)
 +              return;
 +
 +      dev_dbg_ratelimited(p->dev, "Designware UART version %c.%c%c\n",
 +              (reg >> 24) & 0xff, (reg >> 16) & 0xff, (reg >> 8) & 0xff);
 +
 +      reg = readl(p->membase + DW_UART_CPR);
 +      if (!reg)
 +              return;
 +
 +      /* Select the type based on fifo */
 +      if (reg & DW_UART_CPR_FIFO_MODE) {
 +              p->type = PORT_16550A;
 +              p->flags |= UPF_FIXED_TYPE;
 +              p->fifosize = DW_UART_CPR_FIFO_SIZE(reg);
 +              up->tx_loadsz = p->fifosize;
 +      }
 +}
 +
  static int dw8250_probe(struct platform_device *pdev)
  {
        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;
 -      u32 val;
        struct dw8250_data *data;
 +      int err;
  
        if (!regs || !irq) {
                dev_err(&pdev->dev, "no registers/irq defined\n");
                return -EINVAL;
        }
  
 -      data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
 -      if (!data)
 -              return -ENOMEM;
 -      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;
 +      uart.port.flags = UPF_SHARE_IRQ | UPF_BOOT_AUTOCONF | UPF_FIXED_PORT;
        uart.port.dev = &pdev->dev;
  
 +      uart.port.membase = ioremap(regs->start, resource_size(regs));
 +      if (!uart.port.membase)
 +              return -ENOMEM;
 +
        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:
 -                      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",
 -                              val);
 -                      return -EINVAL;
 -              }
 +
 +      dw8250_setup_port(&uart);
 +
 +      if (pdev->dev.of_node) {
 +              err = dw8250_probe_of(&uart.port);
 +              if (err)
 +                      return err;
 +      } else if (ACPI_HANDLE(&pdev->dev)) {
 +              err = dw8250_probe_acpi(&uart.port);
 +              if (err)
 +                      return err;
 +      } else {
 +              return -ENODEV;
        }
  
 -      if (!of_property_read_u32(np, "reg-shift", &val))
 -              uart.port.regshift = val;
 +      data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
 +      if (!data)
 +              return -ENOMEM;
  
 -      if (of_property_read_u32(np, "clock-frequency", &val)) {
 -              dev_err(&pdev->dev, "no clock-frequency property set\n");
 -              return -EINVAL;
 -      }
 -      uart.port.uartclk = val;
 +      uart.port.private_data = data;
  
        data->line = serial8250_register_8250_port(&uart);
        if (data->line < 0)
@@@ -359,25 -184,17 +359,25 @@@ static int dw8250_resume(struct platfor
  #define dw8250_resume NULL
  #endif /* CONFIG_PM */
  
 -static const struct of_device_id dw8250_match[] = {
 +static const struct of_device_id dw8250_of_match[] = {
        { .compatible = "snps,dw-apb-uart" },
        { /* Sentinel */ }
  };
 -MODULE_DEVICE_TABLE(of, dw8250_match);
 +MODULE_DEVICE_TABLE(of, dw8250_of_match);
 +
 +static const struct acpi_device_id dw8250_acpi_match[] = {
 +      { "INT33C4", 100000000 },
 +      { "INT33C5", 100000000 },
 +      { },
 +};
 +MODULE_DEVICE_TABLE(acpi, dw8250_acpi_match);
  
  static struct platform_driver dw8250_platform_driver = {
        .driver = {
                .name           = "dw-apb-uart",
                .owner          = THIS_MODULE,
 -              .of_match_table = dw8250_match,
 +              .of_match_table = dw8250_of_match,
 +              .acpi_match_table = ACPI_PTR(dw8250_acpi_match),
        },
        .probe                  = dw8250_probe,
        .remove                 = dw8250_remove,
index 3b0cc3a09deb9ace5d47349e4cf89bff7ee47332,a27a98e1b0667fc8bfd7e379eaaaa1cfa6c9229a..3cb333242912ae55dfca8e0f6cab49029386fe3d
@@@ -1040,253 -1040,6 +1040,253 @@@ static int pci_asix_setup(struct serial
        return pci_default_setup(priv, board, port, idx);
  }
  
 +/* Quatech devices have their own extra interface features */
 +
 +struct quatech_feature {
 +      u16 devid;
 +      bool amcc;
 +};
 +
 +#define QPCR_TEST_FOR1                0x3F
 +#define QPCR_TEST_GET1                0x00
 +#define QPCR_TEST_FOR2                0x40
 +#define QPCR_TEST_GET2                0x40
 +#define QPCR_TEST_FOR3                0x80
 +#define QPCR_TEST_GET3                0x40
 +#define QPCR_TEST_FOR4                0xC0
 +#define QPCR_TEST_GET4                0x80
 +
 +#define QOPR_CLOCK_X1         0x0000
 +#define QOPR_CLOCK_X2         0x0001
 +#define QOPR_CLOCK_X4         0x0002
 +#define QOPR_CLOCK_X8         0x0003
 +#define QOPR_CLOCK_RATE_MASK  0x0003
 +
 +
 +static struct quatech_feature quatech_cards[] = {
 +      { PCI_DEVICE_ID_QUATECH_QSC100,   1 },
 +      { PCI_DEVICE_ID_QUATECH_DSC100,   1 },
 +      { PCI_DEVICE_ID_QUATECH_DSC100E,  0 },
 +      { PCI_DEVICE_ID_QUATECH_DSC200,   1 },
 +      { PCI_DEVICE_ID_QUATECH_DSC200E,  0 },
 +      { PCI_DEVICE_ID_QUATECH_ESC100D,  1 },
 +      { PCI_DEVICE_ID_QUATECH_ESC100M,  1 },
 +      { PCI_DEVICE_ID_QUATECH_QSCP100,  1 },
 +      { PCI_DEVICE_ID_QUATECH_DSCP100,  1 },
 +      { PCI_DEVICE_ID_QUATECH_QSCP200,  1 },
 +      { PCI_DEVICE_ID_QUATECH_DSCP200,  1 },
 +      { PCI_DEVICE_ID_QUATECH_ESCLP100, 0 },
 +      { PCI_DEVICE_ID_QUATECH_QSCLP100, 0 },
 +      { PCI_DEVICE_ID_QUATECH_DSCLP100, 0 },
 +      { PCI_DEVICE_ID_QUATECH_SSCLP100, 0 },
 +      { PCI_DEVICE_ID_QUATECH_QSCLP200, 0 },
 +      { PCI_DEVICE_ID_QUATECH_DSCLP200, 0 },
 +      { PCI_DEVICE_ID_QUATECH_SSCLP200, 0 },
 +      { PCI_DEVICE_ID_QUATECH_SPPXP_100, 0 },
 +      { 0, }
 +};
 +
 +static int pci_quatech_amcc(u16 devid)
 +{
 +      struct quatech_feature *qf = &quatech_cards[0];
 +      while (qf->devid) {
 +              if (qf->devid == devid)
 +                      return qf->amcc;
 +              qf++;
 +      }
 +      pr_err("quatech: unknown port type '0x%04X'.\n", devid);
 +      return 0;
 +};
 +
 +static int pci_quatech_rqopr(struct uart_8250_port *port)
 +{
 +      unsigned long base = port->port.iobase;
 +      u8 LCR, val;
 +
 +      LCR = inb(base + UART_LCR);
 +      outb(0xBF, base + UART_LCR);
 +      val = inb(base + UART_SCR);
 +      outb(LCR, base + UART_LCR);
 +      return val;
 +}
 +
 +static void pci_quatech_wqopr(struct uart_8250_port *port, u8 qopr)
 +{
 +      unsigned long base = port->port.iobase;
 +      u8 LCR, val;
 +
 +      LCR = inb(base + UART_LCR);
 +      outb(0xBF, base + UART_LCR);
 +      val = inb(base + UART_SCR);
 +      outb(qopr, base + UART_SCR);
 +      outb(LCR, base + UART_LCR);
 +}
 +
 +static int pci_quatech_rqmcr(struct uart_8250_port *port)
 +{
 +      unsigned long base = port->port.iobase;
 +      u8 LCR, val, qmcr;
 +
 +      LCR = inb(base + UART_LCR);
 +      outb(0xBF, base + UART_LCR);
 +      val = inb(base + UART_SCR);
 +      outb(val | 0x10, base + UART_SCR);
 +      qmcr = inb(base + UART_MCR);
 +      outb(val, base + UART_SCR);
 +      outb(LCR, base + UART_LCR);
 +
 +      return qmcr;
 +}
 +
 +static void pci_quatech_wqmcr(struct uart_8250_port *port, u8 qmcr)
 +{
 +      unsigned long base = port->port.iobase;
 +      u8 LCR, val;
 +
 +      LCR = inb(base + UART_LCR);
 +      outb(0xBF, base + UART_LCR);
 +      val = inb(base + UART_SCR);
 +      outb(val | 0x10, base + UART_SCR);
 +      outb(qmcr, base + UART_MCR);
 +      outb(val, base + UART_SCR);
 +      outb(LCR, base + UART_LCR);
 +}
 +
 +static int pci_quatech_has_qmcr(struct uart_8250_port *port)
 +{
 +      unsigned long base = port->port.iobase;
 +      u8 LCR, val;
 +
 +      LCR = inb(base + UART_LCR);
 +      outb(0xBF, base + UART_LCR);
 +      val = inb(base + UART_SCR);
 +      if (val & 0x20) {
 +              outb(0x80, UART_LCR);
 +              if (!(inb(UART_SCR) & 0x20)) {
 +                      outb(LCR, base + UART_LCR);
 +                      return 1;
 +              }
 +      }
 +      return 0;
 +}
 +
 +static int pci_quatech_test(struct uart_8250_port *port)
 +{
 +      u8 reg;
 +      u8 qopr = pci_quatech_rqopr(port);
 +      pci_quatech_wqopr(port, qopr & QPCR_TEST_FOR1);
 +      reg = pci_quatech_rqopr(port) & 0xC0;
 +      if (reg != QPCR_TEST_GET1)
 +              return -EINVAL;
 +      pci_quatech_wqopr(port, (qopr & QPCR_TEST_FOR1)|QPCR_TEST_FOR2);
 +      reg = pci_quatech_rqopr(port) & 0xC0;
 +      if (reg != QPCR_TEST_GET2)
 +              return -EINVAL;
 +      pci_quatech_wqopr(port, (qopr & QPCR_TEST_FOR1)|QPCR_TEST_FOR3);
 +      reg = pci_quatech_rqopr(port) & 0xC0;
 +      if (reg != QPCR_TEST_GET3)
 +              return -EINVAL;
 +      pci_quatech_wqopr(port, (qopr & QPCR_TEST_FOR1)|QPCR_TEST_FOR4);
 +      reg = pci_quatech_rqopr(port) & 0xC0;
 +      if (reg != QPCR_TEST_GET4)
 +              return -EINVAL;
 +
 +      pci_quatech_wqopr(port, qopr);
 +      return 0;
 +}
 +
 +static int pci_quatech_clock(struct uart_8250_port *port)
 +{
 +      u8 qopr, reg, set;
 +      unsigned long clock;
 +
 +      if (pci_quatech_test(port) < 0)
 +              return 1843200;
 +
 +      qopr = pci_quatech_rqopr(port);
 +
 +      pci_quatech_wqopr(port, qopr & ~QOPR_CLOCK_X8);
 +      reg = pci_quatech_rqopr(port);
 +      if (reg & QOPR_CLOCK_X8) {
 +              clock = 1843200;
 +              goto out;
 +      }
 +      pci_quatech_wqopr(port, qopr | QOPR_CLOCK_X8);
 +      reg = pci_quatech_rqopr(port);
 +      if (!(reg & QOPR_CLOCK_X8)) {
 +              clock = 1843200;
 +              goto out;
 +      }
 +      reg &= QOPR_CLOCK_X8;
 +      if (reg == QOPR_CLOCK_X2) {
 +              clock =  3685400;
 +              set = QOPR_CLOCK_X2;
 +      } else if (reg == QOPR_CLOCK_X4) {
 +              clock = 7372800;
 +              set = QOPR_CLOCK_X4;
 +      } else if (reg == QOPR_CLOCK_X8) {
 +              clock = 14745600;
 +              set = QOPR_CLOCK_X8;
 +      } else {
 +              clock = 1843200;
 +              set = QOPR_CLOCK_X1;
 +      }
 +      qopr &= ~QOPR_CLOCK_RATE_MASK;
 +      qopr |= set;
 +
 +out:
 +      pci_quatech_wqopr(port, qopr);
 +      return clock;
 +}
 +
 +static int pci_quatech_rs422(struct uart_8250_port *port)
 +{
 +      u8 qmcr;
 +      int rs422 = 0;
 +
 +      if (!pci_quatech_has_qmcr(port))
 +              return 0;
 +      qmcr = pci_quatech_rqmcr(port);
 +      pci_quatech_wqmcr(port, 0xFF);
 +      if (pci_quatech_rqmcr(port))
 +              rs422 = 1;
 +      pci_quatech_wqmcr(port, qmcr);
 +      return rs422;
 +}
 +
 +static int pci_quatech_init(struct pci_dev *dev)
 +{
 +      if (pci_quatech_amcc(dev->device)) {
 +              unsigned long base = pci_resource_start(dev, 0);
 +              if (base) {
 +                      u32 tmp;
 +                      outl(inl(base + 0x38), base + 0x38);
 +                      tmp = inl(base + 0x3c);
 +                      outl(tmp | 0x01000000, base + 0x3c);
 +                      outl(tmp, base + 0x3c);
 +              }
 +      }
 +      return 0;
 +}
 +
 +static int pci_quatech_setup(struct serial_private *priv,
 +                const struct pciserial_board *board,
 +                struct uart_8250_port *port, int idx)
 +{
 +      /* Needed by pci_quatech calls below */
 +      port->port.iobase = pci_resource_start(priv->dev, FL_GET_BASE(board->flags));
 +      /* Set up the clocking */
 +      port->port.uartclk = pci_quatech_clock(port);
 +      /* For now just warn about RS422 */
 +      if (pci_quatech_rs422(port))
 +              pr_warn("quatech: software control of RS422 features not currently supported.\n");
 +      return pci_default_setup(priv, board, port, idx);
 +}
 +
 +static void pci_quatech_exit(struct pci_dev *dev)
 +{
 +}
 +
  static int pci_default_setup(struct serial_private *priv,
                  const struct pciserial_board *board,
                  struct uart_8250_port *port, int idx)
@@@ -1332,6 -1085,18 +1332,18 @@@ pci_omegapci_setup(struct serial_privat
        return setup_port(priv, port, 2, idx * 8, 0);
  }
  
+ static int
+ pci_brcm_trumanage_setup(struct serial_private *priv,
+                        const struct pciserial_board *board,
+                        struct uart_8250_port *port, int idx)
+ {
+       int ret = pci_default_setup(priv, board, port, idx);
+       port->port.type = PORT_BRCM_TRUMANAGE;
+       port->port.flags = (port->port.flags | UPF_FIXED_PORT | UPF_FIXED_TYPE);
+       return ret;
+ }
  static int skip_tx_en_setup(struct serial_private *priv,
                        const struct pciserial_board *board,
                        struct uart_8250_port *port, int idx)
@@@ -1548,9 -1313,10 +1560,10 @@@ pci_wch_ch353_setup(struct serial_priva
  #define PCI_VENDOR_ID_AGESTAR         0x5372
  #define PCI_DEVICE_ID_AGESTAR_9375    0x6872
  #define PCI_VENDOR_ID_ASIX            0x9710
- #define PCI_DEVICE_ID_COMMTECH_4222PCIE 0x0019
  #define PCI_DEVICE_ID_COMMTECH_4224PCIE       0x0020
  #define PCI_DEVICE_ID_COMMTECH_4228PCIE       0x0021
+ #define PCI_DEVICE_ID_COMMTECH_4222PCIE       0x0022
+ #define PCI_DEVICE_ID_BROADCOM_TRUMANAGE 0x160a
  
  
  /* Unknown vendors/cards - this should not be in linux/pci_ids.h */
@@@ -1775,16 -1541,6 +1788,16 @@@ static struct pci_serial_quirk pci_seri
                .setup          = pci_ni8430_setup,
                .exit           = pci_ni8430_exit,
        },
 +      /* Quatech */
 +      {
 +              .vendor         = PCI_VENDOR_ID_QUATECH,
 +              .device         = PCI_ANY_ID,
 +              .subvendor      = PCI_ANY_ID,
 +              .subdevice      = PCI_ANY_ID,
 +              .init           = pci_quatech_init,
 +              .setup          = pci_quatech_setup,
 +              .exit           = pci_quatech_exit,
 +      },
        /*
         * Panacom
         */
                .subdevice      = PCI_ANY_ID,
                .setup          = pci_xr17v35x_setup,
        },
+       /*
+        * Broadcom TruManage (NetXtreme)
+        */
+       {
+               .vendor         = PCI_VENDOR_ID_BROADCOM,
+               .device         = PCI_DEVICE_ID_BROADCOM_TRUMANAGE,
+               .subvendor      = PCI_ANY_ID,
+               .subdevice      = PCI_ANY_ID,
+               .setup          = pci_brcm_trumanage_setup,
+       },
        /*
         * Default "match everything" terminator entry
         */
@@@ -2405,6 -2172,7 +2429,7 @@@ enum pci_board_num_t 
        pbn_ce4100_1_115200,
        pbn_omegapci,
        pbn_NETMOS9900_2s_115200,
+       pbn_brcm_trumanage,
  };
  
  /*
@@@ -2503,7 -2271,7 +2528,7 @@@ static struct pciserial_board pci_board
  
        [pbn_b0_8_1152000_200] = {
                .flags          = FL_BASE0,
-               .num_ports      = 2,
+               .num_ports      = 8,
                .base_baud      = 1152000,
                .uart_offset    = 0x200,
        },
                .num_ports      = 2,
                .base_baud      = 115200,
        },
+       [pbn_brcm_trumanage] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 1,
+               .reg_shift      = 2,
+               .base_baud      = 115200,
+       },
  };
  
  static const struct pci_device_id blacklist[] = {
@@@ -3732,70 -3506,18 +3763,70 @@@ static struct pci_device_id serial_pci_
        {       PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_ROMULUS,
                0x10b5, 0x106a, 0, 0,
                pbn_plx_romulus },
 +      /*
 +       * Quatech cards. These actually have configurable clocks but for
 +       * now we just use the default.
 +       *
 +       * 100 series are RS232, 200 series RS422,
 +       */
        {       PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSC100,
                PCI_ANY_ID, PCI_ANY_ID, 0, 0,
                pbn_b1_4_115200 },
        {       PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC100,
                PCI_ANY_ID, PCI_ANY_ID, 0, 0,
                pbn_b1_2_115200 },
 +      {       PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC100E,
 +              PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 +              pbn_b2_2_115200 },
 +      {       PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC200,
 +              PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 +              pbn_b1_2_115200 },
 +      {       PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSC200E,
 +              PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 +              pbn_b2_2_115200 },
 +      {       PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSC200,
 +              PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 +              pbn_b1_4_115200 },
        {       PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100D,
                PCI_ANY_ID, PCI_ANY_ID, 0, 0,
                pbn_b1_8_115200 },
        {       PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESC100M,
                PCI_ANY_ID, PCI_ANY_ID, 0, 0,
                pbn_b1_8_115200 },
 +      {       PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSCP100,
 +              PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 +              pbn_b1_4_115200 },
 +      {       PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSCP100,
 +              PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 +              pbn_b1_2_115200 },
 +      {       PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSCP200,
 +              PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 +              pbn_b1_4_115200 },
 +      {       PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSCP200,
 +              PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 +              pbn_b1_2_115200 },
 +      {       PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSCLP100,
 +              PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 +              pbn_b2_4_115200 },
 +      {       PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSCLP100,
 +              PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 +              pbn_b2_2_115200 },
 +      {       PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SSCLP100,
 +              PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 +              pbn_b2_1_115200 },
 +      {       PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_QSCLP200,
 +              PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 +              pbn_b2_4_115200 },
 +      {       PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_DSCLP200,
 +              PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 +              pbn_b2_2_115200 },
 +      {       PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_SSCLP200,
 +              PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 +              pbn_b2_1_115200 },
 +      {       PCI_VENDOR_ID_QUATECH, PCI_DEVICE_ID_QUATECH_ESCLP100,
 +              PCI_ANY_ID, PCI_ANY_ID, 0, 0,
 +              pbn_b0_8_115200 },
 +
        {       PCI_VENDOR_ID_SPECIALIX, PCI_DEVICE_ID_OXSEMI_16PCI954,
                PCI_VENDOR_ID_SPECIALIX, PCI_SUBDEVICE_ID_SPECIALIX_SPEED4,
                0, 0,
                PCI_ANY_ID, PCI_ANY_ID, 0, 0,
                pbn_omegapci },
  
+       /*
+        * Broadcom TruManage
+        */
+       {       PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_BROADCOM_TRUMANAGE,
+               PCI_ANY_ID, PCI_ANY_ID, 0, 0,
+               pbn_brcm_trumanage },
        /*
         * AgeStar as-prs2-009
         */
index f083641bf475429773b2843384bd12261266d9a5,8cb6d8d66a1362b1b2f5566a875c1f56248a3b29..68d7ce997ede999fce550d0b6d1ccd6d0e9032be
@@@ -481,6 -481,7 +481,6 @@@ static int ifx_spi_prepare_tx_buffer(st
        unsigned char *tx_buffer;
  
        tx_buffer = ifx_dev->tx_buffer;
 -      memset(tx_buffer, 0, IFX_SPI_TRANSFER_SIZE);
  
        /* make room for required SPI header */
        tx_buffer += IFX_SPI_HEADER_OVERHEAD;
@@@ -614,7 -615,7 +614,7 @@@ static int ifx_port_activate(struct tty
        tty->driver_data = ifx_dev;
  
        /* allows flip string push from int context */
 -      tty->low_latency = 1;
 +      port->low_latency = 1;
  
        /* set flag to allows data transfer */
        set_bit(IFX_SPI_STATE_IO_AVAILABLE, &ifx_dev->flags);
@@@ -636,6 -637,7 +636,7 @@@ static void ifx_port_shutdown(struct tt
  
        clear_bit(IFX_SPI_STATE_IO_AVAILABLE, &ifx_dev->flags);
        mrdy_set_low(ifx_dev);
+       del_timer(&ifx_dev->spi_timer);
        clear_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags);
        tasklet_kill(&ifx_dev->io_work_tasklet);
  }
@@@ -668,8 -670,12 +669,8 @@@ static const struct tty_operations ifx_
  static void ifx_spi_insert_flip_string(struct ifx_spi_device *ifx_dev,
                                    unsigned char *chars, size_t size)
  {
 -      struct tty_struct *tty = tty_port_tty_get(&ifx_dev->tty_port);
 -      if (!tty)
 -              return;
 -      tty_insert_flip_string(tty, chars, size);
 -      tty_flip_buffer_push(tty);
 -      tty_kref_put(tty);
 +      tty_insert_flip_string(&ifx_dev->tty_port, chars, size);
 +      tty_flip_buffer_push(&ifx_dev->tty_port);
  }
  
  /**
@@@ -805,7 -811,8 +806,8 @@@ static void ifx_spi_io(unsigned long da
                ifx_dev->spi_xfer.cs_change = 0;
                ifx_dev->spi_xfer.speed_hz = ifx_dev->spi_dev->max_speed_hz;
                /* ifx_dev->spi_xfer.speed_hz = 390625; */
-               ifx_dev->spi_xfer.bits_per_word = spi_bpw;
+               ifx_dev->spi_xfer.bits_per_word =
+                       ifx_dev->spi_dev->bits_per_word;
  
                ifx_dev->spi_xfer.tx_buf = ifx_dev->tx_buffer;
                ifx_dev->spi_xfer.rx_buf = ifx_dev->rx_buffer;
index df0ba32f88adb964d0e89e5fa7d4aad566accd04,e55615eb34ad32037cf78dc18aef63a00373e1ee..d549fe1fa42abdce8611645d1038dfb11b5e0654
@@@ -253,7 -253,7 +253,7 @@@ static void mxs_auart_tx_chars(struct m
        struct circ_buf *xmit = &s->port.state->xmit;
  
        if (auart_dma_enabled(s)) {
-               int i = 0;
+               u32 i = 0;
                int size;
                void *buffer = s->tx_dma_buf;
  
@@@ -364,6 -364,7 +364,6 @@@ out
  
  static void mxs_auart_rx_chars(struct mxs_auart_port *s)
  {
 -      struct tty_struct *tty = s->port.state->port.tty;
        u32 stat = 0;
  
        for (;;) {
        }
  
        writel(stat, s->port.membase + AUART_STAT);
 -      tty_flip_buffer_push(tty);
 +      tty_flip_buffer_push(&s->port.state->port);
  }
  
  static int mxs_auart_request_port(struct uart_port *u)
@@@ -411,10 -412,12 +411,12 @@@ static void mxs_auart_set_mctrl(struct 
  
        u32 ctrl = readl(u->membase + AUART_CTRL2);
  
-       ctrl &= ~AUART_CTRL2_RTSEN;
+       ctrl &= ~(AUART_CTRL2_RTSEN | AUART_CTRL2_RTS);
        if (mctrl & TIOCM_RTS) {
                if (tty_port_cts_enabled(&u->state->port))
                        ctrl |= AUART_CTRL2_RTSEN;
+               else
+                       ctrl |= AUART_CTRL2_RTS;
        }
  
        s->ctrl = mctrl;
@@@ -456,7 -459,7 +458,7 @@@ static int mxs_auart_dma_prep_rx(struc
  static void dma_rx_callback(void *arg)
  {
        struct mxs_auart_port *s = (struct mxs_auart_port *) arg;
 -      struct tty_struct *tty = s->port.state->port.tty;
 +      struct tty_port *port = &s->port.state->port;
        int count;
        u32 stat;
  
                        AUART_STAT_PERR | AUART_STAT_FERR);
  
        count = stat & AUART_STAT_RXCOUNT_MASK;
 -      tty_insert_flip_string(tty, s->rx_dma_buf, count);
 +      tty_insert_flip_string(port, s->rx_dma_buf, count);
  
        writel(stat, s->port.membase + AUART_STAT);
 -      tty_flip_buffer_push(tty);
 +      tty_flip_buffer_push(port);
  
        /* start the next DMA for RX. */
        mxs_auart_dma_prep_rx(s);
@@@ -549,7 -552,7 +551,7 @@@ static int mxs_auart_dma_init(struct mx
                return 0;
  
        /* We do not get the right DMA channels. */
 -      if (s->dma_channel_rx == -1 || s->dma_channel_rx == -1)
 +      if (s->dma_channel_rx == -1 || s->dma_channel_tx == -1)
                return -EINVAL;
  
        /* init for RX */
index 3aa3c4c83f8bffda27602c3dfc498272d635ad78,e514b3a4dc572069da4df72cba488f6be9cd1c98..2769a38d15b68db5ecf040c17dd3c5fb33226168
@@@ -47,6 -47,7 +47,6 @@@
  #include <asm/irq.h>
  
  #include <mach/hardware.h>
 -#include <mach/map.h>
  
  #include <plat/regs-serial.h>
  #include <plat/clock.h>
@@@ -220,6 -221,7 +220,6 @@@ s3c24xx_serial_rx_chars(int irq, void *
  {
        struct s3c24xx_uart_port *ourport = dev_id;
        struct uart_port *port = &ourport->port;
 -      struct tty_struct *tty = port->state->port.tty;
        unsigned int ufcon, ch, flag, ufstat, uerstat;
        unsigned long flags;
        int max_count = 64;
   ignore_char:
                continue;
        }
 -      tty_flip_buffer_push(tty);
 +      tty_flip_buffer_push(&port->state->port);
  
   out:
        spin_unlock_irqrestore(&port->lock, flags);
@@@ -1004,7 -1006,6 +1004,6 @@@ static void s3c24xx_serial_resetport(st
  
        ucon &= ucon_mask;
        wr_regl(port, S3C2410_UCON,  ucon | cfg->ucon);
-       wr_regl(port, S3C2410_ULCON, cfg->ulcon);
  
        /* reset both fifos */
        wr_regl(port, S3C2410_UFCON, cfg->ufcon | S3C2410_UFCON_RESETBOTH);
@@@ -1142,13 -1143,8 +1141,13 @@@ static int s3c24xx_serial_init_port(str
  
        dbg("resource %p (%lx..%lx)\n", res, res->start, res->end);
  
 +      port->membase = devm_ioremap(port->dev, res->start, resource_size(res));
 +      if (!port->membase) {
 +              dev_err(port->dev, "failed to remap controller address\n");
 +              return -EBUSY;
 +      }
 +
        port->mapbase = res->start;
 -      port->membase = S3C_VA_UART + (res->start & 0xfffff);
        ret = platform_get_irq(platdev, 0);
        if (ret < 0)
                port->irq = 0;
@@@ -1728,6 -1724,8 +1727,6 @@@ static const struct of_device_id s3c24x
        {},
  };
  MODULE_DEVICE_TABLE(of, s3c24xx_uart_dt_match);
 -#else
 -#define s3c24xx_uart_dt_match NULL
  #endif
  
  static struct platform_driver samsung_serial_driver = {
                .name   = "samsung-uart",
                .owner  = THIS_MODULE,
                .pm     = SERIAL_SAMSUNG_PM_OPS,
 -              .of_match_table = s3c24xx_uart_dt_match,
 +              .of_match_table = of_match_ptr(s3c24xx_uart_dt_match),
        },
  };
  
index 5fb59c53abf988e9d486d6b926507c146ddcef4f,d5ed9f61300562c8febbb8a8095304a1c9955899..a3f9dd5c9dff40dacf86966ae3d6ff1335055f97
@@@ -136,14 -136,22 +136,14 @@@ static void vt8500_enable_ms(struct uar
  
  static void handle_rx(struct uart_port *port)
  {
 -      struct tty_struct *tty = tty_port_tty_get(&port->state->port);
 -      if (!tty) {
 -              /* Discard data: no tty available */
 -              int count = (vt8500_read(port, VT8500_URFIDX) & 0x1f00) >> 8;
 -              u16 ch;
 -              while (count--)
 -                      ch = readw(port->membase + VT8500_RXFIFO);
 -              return;
 -      }
 +      struct tty_port *tport = &port->state->port;
  
        /*
         * Handle overrun
         */
        if ((vt8500_read(port, VT8500_URISR) & RXOVER)) {
                port->icount.overrun++;
 -              tty_insert_flip_char(tty, 0, TTY_OVERRUN);
 +              tty_insert_flip_char(tport, 0, TTY_OVERRUN);
        }
  
        /* and now the main RX loop */
                port->icount.rx++;
  
                if (!uart_handle_sysrq_char(port, c))
 -                      tty_insert_flip_char(tty, c, flag);
 +                      tty_insert_flip_char(tport, c, flag);
        }
  
 -      tty_flip_buffer_push(tty);
 -      tty_kref_put(tty);
 +      tty_flip_buffer_push(tport);
  }
  
  static void handle_tx(struct uart_port *port)
@@@ -560,7 -569,7 +560,7 @@@ static int vt8500_serial_probe(struct p
  
        if (np)
                port = of_alias_get_id(np, "serial");
 -              if (port > VT8500_MAX_PORTS)
 +              if (port >= VT8500_MAX_PORTS)
                        port = -1;
        else
                port = -1;
                                        sizeof(vt8500_ports_in_use));
        }
  
 -      if (port > VT8500_MAX_PORTS)
 +      if (port >= VT8500_MAX_PORTS)
                return -ENODEV;
  
        /* reserve the port id */
                return -EBUSY;
        }
  
 -      vt8500_port = kzalloc(sizeof(struct vt8500_port), GFP_KERNEL);
 +      vt8500_port = devm_kzalloc(&pdev->dev, sizeof(struct vt8500_port),
 +                                 GFP_KERNEL);
        if (!vt8500_port)
                return -ENOMEM;
  
 +      vt8500_port->uart.membase = devm_request_and_ioremap(&pdev->dev, mmres);
 +      if (!vt8500_port->uart.membase)
 +              return -EADDRNOTAVAIL;
 +
 +      vt8500_port->clk = of_clk_get(pdev->dev.of_node, 0);
 +      if (IS_ERR(vt8500_port->clk)) {
 +              dev_err(&pdev->dev, "failed to get clock\n");
 +              return  -EINVAL;
 +      }
 +
 +      ret = clk_prepare_enable(vt8500_port->clk);
 +      if (ret) {
 +              dev_err(&pdev->dev, "failed to enable clock\n");
 +              return ret;
 +      }
 +
        vt8500_port->uart.type = PORT_VT8500;
        vt8500_port->uart.iotype = UPIO_MEM;
        vt8500_port->uart.mapbase = mmres->start;
        vt8500_port->uart.line = port;
        vt8500_port->uart.dev = &pdev->dev;
        vt8500_port->uart.flags = UPF_IOREMAP | UPF_BOOT_AUTOCONF;
-       vt8500_port->uart.uartclk = clk_get_rate(vt8500_port->clk);
+       vt8500_port->clk = of_clk_get(pdev->dev.of_node, 0);
+       if (!IS_ERR(vt8500_port->clk)) {
+               vt8500_port->uart.uartclk = clk_get_rate(vt8500_port->clk);
+       } else {
+               /* use the default of 24Mhz if not specified and warn */
+               pr_warn("%s: serial clock source not specified\n", __func__);
+               vt8500_port->uart.uartclk = 24000000;
+       }
  
        snprintf(vt8500_port->name, sizeof(vt8500_port->name),
                 "VT8500 UART%d", pdev->id);
  
 -      vt8500_port->uart.membase = ioremap(mmres->start, resource_size(mmres));
 -      if (!vt8500_port->uart.membase) {
 -              ret = -ENOMEM;
 -              goto err;
 -      }
 -
        vt8500_uart_ports[port] = vt8500_port;
  
        uart_add_one_port(&vt8500_uart_driver, &vt8500_port->uart);
        platform_set_drvdata(pdev, vt8500_port);
  
        return 0;
 -
 -err:
 -      kfree(vt8500_port);
 -      return ret;
  }
  
  static int vt8500_serial_remove(struct platform_device *pdev)
        struct vt8500_port *vt8500_port = platform_get_drvdata(pdev);
  
        platform_set_drvdata(pdev, NULL);
 +      clk_disable_unprepare(vt8500_port->clk);
        uart_remove_one_port(&vt8500_uart_driver, &vt8500_port->uart);
 -      kfree(vt8500_port);
  
        return 0;
  }
index 15b36e2efa85be6cf59fe2310ed9acb6e4bbeb44,2d92cce260d7fd646d13d69e01f2152bbd43a487..8ac25adf31b41d857a6919299f1848cf2ee43710
@@@ -410,12 -410,19 +410,12 @@@ static int acm_submit_read_urbs(struct 
  
  static void acm_process_read_urb(struct acm *acm, struct urb *urb)
  {
 -      struct tty_struct *tty;
 -
        if (!urb->actual_length)
                return;
  
 -      tty = tty_port_tty_get(&acm->port);
 -      if (!tty)
 -              return;
 -
 -      tty_insert_flip_string(tty, urb->transfer_buffer, urb->actual_length);
 -      tty_flip_buffer_push(tty);
 -
 -      tty_kref_put(tty);
 +      tty_insert_flip_string(&acm->port, urb->transfer_buffer,
 +                      urb->actual_length);
 +      tty_flip_buffer_push(&acm->port);
  }
  
  static void acm_read_bulk_callback(struct urb *urb)
@@@ -1595,6 -1602,9 +1595,9 @@@ static const struct usb_device_id acm_i
        { USB_DEVICE(0x0572, 0x1340), /* Conexant CX93010-2x UCMxx */
        .driver_info = NO_UNION_NORMAL,
        },
+       { USB_DEVICE(0x05f9, 0x4002), /* PSC Scanning, Magellan 800i */
+       .driver_info = NO_UNION_NORMAL,
+       },
        { USB_DEVICE(0x1bbb, 0x0003), /* Alcatel OT-I650 */
        .driver_info = NO_UNION_NORMAL, /* reports zero length descriptor */
        },
index ca4fc3d3e7ff12e67dc0108fb1bdb6691d067ad0,598dcc1212f0bb231830f0022961f67e37b6b0fa..46b1cc773ab866d96ec123d18bb7d46d98f69a0c
@@@ -495,8 -495,12 +495,8 @@@ static void gs_rx_push(unsigned long _p
  
                req = list_first_entry(queue, struct usb_request, list);
  
 -              /* discard data if tty was closed */
 -              if (!tty)
 -                      goto recycle;
 -
                /* leave data queued if tty was rx throttled */
 -              if (test_bit(TTY_THROTTLED, &tty->flags))
 +              if (tty && test_bit(TTY_THROTTLED, &tty->flags))
                        break;
  
                switch (req->status) {
                                size -= n;
                        }
  
 -                      count = tty_insert_flip_string(tty, packet, size);
 +                      count = tty_insert_flip_string(&port->port, packet,
 +                                      size);
                        if (count)
                                do_push = true;
                        if (count != size) {
                        }
                        port->n_read = 0;
                }
 -recycle:
 +
                list_move(&req->list, &port->read_pool);
                port->read_started--;
        }
        /* Push from tty to ldisc; without low_latency set this is handled by
         * a workqueue, so we won't get callbacks and can hold port_lock
         */
 -      if (tty && do_push)
 -              tty_flip_buffer_push(tty);
 +      if (do_push)
 +              tty_flip_buffer_push(&port->port);
  
  
        /* We want our data queue to become empty ASAP, keeping data
@@@ -884,7 -887,7 +884,7 @@@ static void gs_close(struct tty_struct 
        pr_debug("gs_close: ttyGS%d (%p,%p) done!\n",
                        port->port_num, tty, file);
  
-       wake_up_interruptible(&port->port.close_wait);
+       wake_up(&port->port.close_wait);
  exit:
        spin_unlock_irq(&port->port_lock);
  }
index a96083b7fabc671eea72137aac03789f7a69b413,ba68835d06a6ba1a957aee83239346d62268dcc6..eaa038d032b85b427f635791168e770a58795916
@@@ -875,6 -875,8 +875,8 @@@ static struct usb_device_id id_table_co
        { USB_DEVICE(FTDI_VID, FTDI_DISTORTEC_JTAG_LOCK_PICK_PID),
                .driver_info = (kernel_ulong_t)&ftdi_jtag_quirk },
        { USB_DEVICE(FTDI_VID, FTDI_LUMEL_PD12_PID) },
+       /* Crucible Devices */
+       { USB_DEVICE(FTDI_VID, FTDI_CT_COMET_PID) },
        { },                                    /* Optional parameter entry */
        { }                                     /* Terminating entry */
  };
@@@ -1958,8 -1960,9 +1960,8 @@@ static int ftdi_prepare_write_buffer(st
  
  #define FTDI_RS_ERR_MASK (FTDI_RS_BI | FTDI_RS_PE | FTDI_RS_FE | FTDI_RS_OE)
  
 -static int ftdi_process_packet(struct tty_struct *tty,
 -              struct usb_serial_port *port, struct ftdi_private *priv,
 -              char *packet, int len)
 +static int ftdi_process_packet(struct usb_serial_port *port,
 +              struct ftdi_private *priv, char *packet, int len)
  {
        int i;
        char status;
                /* Overrun is special, not associated with a char */
                if (packet[1] & FTDI_RS_OE) {
                        priv->icount.overrun++;
 -                      tty_insert_flip_char(tty, 0, TTY_OVERRUN);
 +                      tty_insert_flip_char(&port->port, 0, TTY_OVERRUN);
                }
        }
  
        if (port->port.console && port->sysrq) {
                for (i = 0; i < len; i++, ch++) {
                        if (!usb_serial_handle_sysrq_char(port, *ch))
 -                              tty_insert_flip_char(tty, *ch, flag);
 +                              tty_insert_flip_char(&port->port, *ch, flag);
                }
        } else {
 -              tty_insert_flip_string_fixed_flag(tty, ch, flag, len);
 +              tty_insert_flip_string_fixed_flag(&port->port, ch, flag, len);
        }
  
        return len;
  static void ftdi_process_read_urb(struct urb *urb)
  {
        struct usb_serial_port *port = urb->context;
 -      struct tty_struct *tty;
        struct ftdi_private *priv = usb_get_serial_port_data(port);
        char *data = (char *)urb->transfer_buffer;
        int i;
        int len;
        int count = 0;
  
 -      tty = tty_port_tty_get(&port->port);
 -      if (!tty)
 -              return;
 -
        for (i = 0; i < urb->actual_length; i += priv->max_packet_size) {
                len = min_t(int, urb->actual_length - i, priv->max_packet_size);
 -              count += ftdi_process_packet(tty, port, priv, &data[i], len);
 +              count += ftdi_process_packet(port, priv, &data[i], len);
        }
  
        if (count)
 -              tty_flip_buffer_push(tty);
 -      tty_kref_put(tty);
 +              tty_flip_buffer_push(&port->port);
  }
  
  static void ftdi_break_ctl(struct tty_struct *tty, int break_state)
index d6485be49ebf48b99e45437af501c2385d806a88,82afc4d6a327d6bdbebc4707507684c966f11f9f..b5ab0a54b6b6624195419de00a6054f075c682bd
@@@ -201,8 -201,8 +201,8 @@@ static int closing_wait = EDGE_CLOSING_
  static bool ignore_cpu_rev;
  static int default_uart_mode;         /* RS232 */
  
 -static void edge_tty_recv(struct device *dev, struct tty_struct *tty,
 -                        unsigned char *data, int length);
 +static void edge_tty_recv(struct usb_serial_port *port, unsigned char *data,
 +              int length);
  
  static void stop_read(struct edgeport_port *edge_port);
  static int restart_read(struct edgeport_port *edge_port);
@@@ -530,6 -530,9 +530,9 @@@ static void chase_port(struct edgeport_
        wait_queue_t wait;
        unsigned long flags;
  
+       if (!tty)
+               return;
        if (!timeout)
                timeout = (HZ * EDGE_CLOSING_WAIT)/100;
  
@@@ -1540,6 -1543,7 +1543,6 @@@ static void handle_new_lsr(struct edgep
        struct async_icount *icount;
        __u8 new_lsr = (__u8)(lsr & (__u8)(LSR_OVER_ERR | LSR_PAR_ERR |
                                                LSR_FRM_ERR | LSR_BREAK));
 -      struct tty_struct *tty;
  
        dev_dbg(&edge_port->port->dev, "%s - %02x\n", __func__, new_lsr);
  
                new_lsr &= (__u8)(LSR_OVER_ERR | LSR_BREAK);
  
        /* Place LSR data byte into Rx buffer */
 -      if (lsr_data) {
 -              tty = tty_port_tty_get(&edge_port->port->port);
 -              if (tty) {
 -                      edge_tty_recv(&edge_port->port->dev, tty, &data, 1);
 -                      tty_kref_put(tty);
 -              }
 -      }
 +      if (lsr_data)
 +              edge_tty_recv(edge_port->port, &data, 1);
  
        /* update input line counters */
        icount = &edge_port->icount;
@@@ -1670,6 -1679,7 +1673,6 @@@ static void edge_bulk_in_callback(struc
        struct edgeport_port *edge_port = urb->context;
        struct device *dev = &edge_port->port->dev;
        unsigned char *data = urb->transfer_buffer;
 -      struct tty_struct *tty;
        int retval = 0;
        int port_number;
        int status = urb->status;
                ++data;
        }
  
 -      tty = tty_port_tty_get(&edge_port->port->port);
 -      if (tty && urb->actual_length) {
 +      if (urb->actual_length) {
                usb_serial_debug_data(dev, __func__, urb->actual_length, data);
                if (edge_port->close_pending)
                        dev_dbg(dev, "%s - close pending, dropping data on the floor\n",
                                                                __func__);
                else
 -                      edge_tty_recv(dev, tty, data, urb->actual_length);
 +                      edge_tty_recv(edge_port->port, data,
 +                                      urb->actual_length);
                edge_port->icount.rx += urb->actual_length;
        }
 -      tty_kref_put(tty);
  
  exit:
        /* continue read unless stopped */
                dev_err(dev, "%s - usb_submit_urb failed with result %d\n", __func__, retval);
  }
  
 -static void edge_tty_recv(struct device *dev, struct tty_struct *tty,
 -                                      unsigned char *data, int length)
 +static void edge_tty_recv(struct usb_serial_port *port, unsigned char *data,
 +              int length)
  {
        int queued;
  
 -      queued = tty_insert_flip_string(tty, data, length);
 +      queued = tty_insert_flip_string(&port->port, data, length);
        if (queued < length)
 -              dev_err(dev, "%s - dropping data, %d bytes lost\n",
 +              dev_err(&port->dev, "%s - dropping data, %d bytes lost\n",
                        __func__, length - queued);
 -      tty_flip_buffer_push(tty);
 +      tty_flip_buffer_push(&port->port);
  }
  
  static void edge_bulk_out_callback(struct urb *urb)
index 9dd47a5697268f45b259f971924a0af680d22053,2c6c85f18ea027440761c780134bb757b0c53c8e..08464ef2c72c6711d38c635b14810b0b45987172
@@@ -50,7 -50,8 +50,8 @@@
  #define PORT_LPC3220  22      /* NXP LPC32xx SoC "Standard" UART */
  #define PORT_8250_CIR 23      /* CIR infrared port, has its own driver */
  #define PORT_XR17V35X 24      /* Exar XR17V35x UARTs */
- #define PORT_MAX_8250 24      /* max port ID */
+ #define PORT_BRCM_TRUMANAGE   24
+ #define PORT_MAX_8250 25      /* max port ID */
  
  /*
   * ARM specific type numbers.  These are not currently guaranteed
  /* ARC (Synopsys) on-chip UART */
  #define PORT_ARC       101
  
 +/* Rocketport EXPRESS/INFINITY */
 +#define PORT_RP2      102
 +
  #endif /* _UAPILINUX_SERIAL_CORE_H */
This page took 0.265276 seconds and 5 git commands to generate.