From: "Chang, Rebecca Swee Fun" <[email protected]>

Baytrail has two HSUART controllers which can be PCI or ACPI enumerated.

Signed-off-by: Chang, Rebecca Swee Fun <[email protected]>
---
 ...-Add-support-for-HSUART-controllers-on-In.patch | 1295 ++++++++++++++++++++
 1 file changed, 1295 insertions(+)
 create mode 100644 
meta/cfg/kernel-cache/features/valleyisland-io/0003-serial-8250-Add-support-for-HSUART-controllers-on-In.patch

diff --git 
a/meta/cfg/kernel-cache/features/valleyisland-io/0003-serial-8250-Add-support-for-HSUART-controllers-on-In.patch
 
b/meta/cfg/kernel-cache/features/valleyisland-io/0003-serial-8250-Add-support-for-HSUART-controllers-on-In.patch
new file mode 100644
index 0000000..6f9b8e8
--- /dev/null
+++ 
b/meta/cfg/kernel-cache/features/valleyisland-io/0003-serial-8250-Add-support-for-HSUART-controllers-on-In.patch
@@ -0,0 +1,1295 @@
+serial/8250: Add support for HSUART controllers on Baytrail
+
+Baytrail has two HSUART controllers which can be PCI or ACPI enumerated.
+
+Signed-off-by: Chang, Rebecca Swee Fun <[email protected]>
+---
+ drivers/tty/serial/8250/8250.c       |   72 +++++--
+ drivers/tty/serial/8250/8250.h       |   55 +++++
+ drivers/tty/serial/8250/8250_dma.c   |  222 ++++++++++++++++++++
+ drivers/tty/serial/8250/8250_dw.c    |  378 +++++++++++++++++++++++++++++-----
+ drivers/tty/serial/8250/8250_early.c |    2 +-
+ drivers/tty/serial/8250/8250_pci.c   |  190 +++++++++++++++++
+ drivers/tty/serial/8250/Kconfig      |   10 +-
+ drivers/tty/serial/8250/Makefile     |    1 +
+ include/linux/serial_8250.h          |    4 +
+ 9 files changed, 873 insertions(+), 61 deletions(-)
+ create mode 100644 drivers/tty/serial/8250/8250_dma.c
+
+diff --git a/drivers/tty/serial/8250/8250.c b/drivers/tty/serial/8250/8250.c
+index f932043..469a83c 100644
+--- a/drivers/tty/serial/8250/8250.c
++++ b/drivers/tty/serial/8250/8250.c
+@@ -1341,7 +1341,9 @@ static void serial8250_start_tx(struct uart_port *port)
+       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);
+
+@@ -1397,7 +1399,6 @@ unsigned char
+ 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;
+@@ -1462,7 +1463,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;
+ }
+@@ -1518,6 +1519,10 @@ unsigned int serial8250_modem_status(struct 
uart_8250_port *up)
+       struct uart_port *port = &up->port;
+       unsigned int status = serial_in(up, UART_MSR);
+
++      if (up->ier & UART_IER_MSI && up->mcr & UART_MCR_AFE) {
++              status &= ~(UART_MSR_DCTS);
++              status |= UART_MSR_CTS;
++      }
+       status |= up->msr_saved_flags;
+       up->msr_saved_flags = 0;
+       if (status & UART_MSR_ANY_DELTA && up->ier & UART_IER_MSI &&
+@@ -1547,20 +1552,34 @@ int serial8250_handle_irq(struct uart_port *port, 
unsigned int iir)
+       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;
+
+       spin_lock_irqsave(&port->lock, flags);
+
++      if( (up->port.dev->id == PCI_DEVICE_ID_INTEL_BYT_UART1 ||
++              up->port.dev->id == PCI_DEVICE_ID_INTEL_BYT_UART2) &&
++              (iir & UART_IIR_RLSI) )  {
++
++              readl(port->membase + LPSS_UART_BYTE_CNT);
++              readl(port->membase + LPSS_UART_OVRFLW_INTR_STAT);
++      }
++
+       status = serial_port_in(port, UART_LSR);
+
+       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)
++      if (status & UART_LSR_THRE && (iir & 0x3f) == UART_IIR_THRI)
+               serial8250_tx_chars(up);
+
+       spin_unlock_irqrestore(&port->lock, flags);
+@@ -1991,9 +2010,12 @@ static int serial8250_startup(struct uart_port *port)
+       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)
+@@ -2198,6 +2220,18 @@ dont_test_tx_en:
+       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
+        * anyway, so we don't enable them here.
+@@ -2230,6 +2264,9 @@ static void serial8250_shutdown(struct uart_port *port)
+       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 */
+@@ -2344,7 +2381,7 @@ serial8250_do_set_termios(struct uart_port *port, struct 
ktermios *termios,
+
+       if (up->capabilities & UART_CAP_FIFO && port->fifosize > 1) {
+               fcr = uart_config[port->type].fcr;
+-              if (baud < 2400 || fifo_bug) {
++              if (baud < 2400 && !up->dma || fifo_bug) {
+                       fcr &= ~UART_FCR_TRIGGER_MASK;
+                       fcr |= UART_FCR_TRIGGER_1;
+               }
+@@ -2826,9 +2863,12 @@ static void
+ 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
+@@ -3262,6 +3302,10 @@ int serial8250_register_8250_port(struct uart_8250_port 
*up)
+               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;
+
+@@ -3287,6 +3331,8 @@ int serial8250_register_8250_port(struct uart_8250_port 
*up)
+                       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,
+diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h
+index 12caa12..aa97212 100644
+--- a/drivers/tty/serial/8250/8250.h
++++ b/drivers/tty/serial/8250/8250.h
+@@ -12,6 +12,35 @@
+  */
+
+ #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;
+@@ -59,6 +88,11 @@ struct serial8250_config {
+ #define SERIAL8250_SHARE_IRQS 0
+ #endif
+
++#define PCI_DEVICE_ID_INTEL_BYT_UART1 0x0f0a
++#define PCI_DEVICE_ID_INTEL_BYT_UART2 0x0f0c
++#define LPSS_UART_BYTE_CNT            0x818
++#define LPSS_UART_OVRFLW_INTR_STAT    0x820
++
+ static inline int serial_in(struct uart_8250_port *up, int offset)
+ {
+       return up->port.serial_in(&up->port, offset);
+@@ -143,3 +177,24 @@ static inline int is_omap1510_8250(struct uart_8250_port 
*pt)
+       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
+diff --git a/drivers/tty/serial/8250/8250_dma.c 
b/drivers/tty/serial/8250/8250_dma.c
+new file mode 100644
+index 0000000..29d45e7
+--- /dev/null
++++ b/drivers/tty/serial/8250/8250_dma.c
+@@ -0,0 +1,222 @@
++/*
++ * 8250_dma.c - DMA Engine API support for 8250.c
++ *
++ * Copyright (C) 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
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ */
++#include <linux/tty.h>
++#include <linux/tty_flip.h>
++#include <linux/serial_reg.h>
++#include <linux/dma-mapping.h>
++
++#include "8250.h"
++
++static void __dma_tx_complete(void *param)
++{
++      struct uart_8250_port   *p = param;
++      struct uart_8250_dma    *dma = p->dma;
++      struct circ_buf         *xmit = &p->port.state->xmit;
++
++      dma->tx_running = 0;
++
++      dma_sync_single_for_cpu(dma->txchan->device->dev, dma->tx_addr,
++                              UART_XMIT_SIZE, DMA_TO_DEVICE);
++
++      xmit->tail += dma->tx_size;
++      xmit->tail &= UART_XMIT_SIZE - 1;
++      p->port.icount.tx += dma->tx_size;
++
++      if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
++              uart_write_wakeup(&p->port);
++
++      if (!uart_circ_empty(xmit) && !uart_tx_stopped(&p->port))
++              serial8250_tx_dma(p);
++}
++
++static void __dma_rx_complete(void *param)
++{
++      struct uart_8250_port   *p = param;
++      struct uart_8250_dma    *dma = p->dma;
++      struct tty_port         *tty_port = &p->port.state->port;
++      struct dma_tx_state     state;
++      int                     count;
++
++      dma_sync_single_for_cpu(dma->rxchan->device->dev, dma->rx_addr,
++                              dma->rx_size, DMA_FROM_DEVICE);
++
++      dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state);
++      dmaengine_terminate_all(dma->rxchan);
++
++      count = dma->rx_size - state.residue;
++
++      tty_insert_flip_string(tty_port, dma->rx_buf, count);
++      p->port.icount.rx += count;
++
++      tty_flip_buffer_push(tty_port);
++}
++
++int serial8250_tx_dma(struct uart_8250_port *p)
++{
++      struct uart_8250_dma            *dma = p->dma;
++      struct circ_buf                 *xmit = &p->port.state->xmit;
++      struct dma_async_tx_descriptor  *desc;
++
++      if (uart_tx_stopped(&p->port) || dma->tx_running
++          || uart_circ_empty(xmit))
++              return 0;
++
++      dma->tx_size = CIRC_CNT_TO_END(xmit->head, xmit->tail, UART_XMIT_SIZE);
++
++      desc = dmaengine_prep_slave_single(dma->txchan,
++                                         dma->tx_addr + xmit->tail,
++                                         dma->tx_size, DMA_MEM_TO_DEV,
++                                         DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
++      if (!desc)
++              return -EBUSY;
++
++      dma->tx_running = 1;
++
++      desc->callback = __dma_tx_complete;
++      desc->callback_param = p;
++
++      dma->tx_cookie = dmaengine_submit(desc);
++
++      dma_sync_single_for_device(dma->txchan->device->dev, dma->tx_addr,
++                                 UART_XMIT_SIZE, DMA_TO_DEVICE);
++
++      dma_async_issue_pending(dma->txchan);
++
++      return 0;
++}
++EXPORT_SYMBOL_GPL(serial8250_tx_dma);
++
++int serial8250_rx_dma(struct uart_8250_port *p, unsigned int iir)
++{
++      struct uart_8250_dma            *dma = p->dma;
++      struct dma_async_tx_descriptor  *desc;
++      struct dma_tx_state             state;
++      int                             dma_status;
++
++      dma_status = dmaengine_tx_status(dma->rxchan, dma->rx_cookie, &state);
++
++      switch (iir & 0x3f) {
++      case UART_IIR_RLSI:
++              /* 8250.c handles errors and break interrupts */
++              return -EIO;
++      case UART_IIR_RX_TIMEOUT:
++              /*
++               * If RCVR FIFO trigger level was not reached, complete the
++               * transfer and let 8250.c copy the remaining data.
++               */
++              if (dma_status == DMA_IN_PROGRESS) {
++                      dmaengine_pause(dma->rxchan);
++                      __dma_rx_complete(p);
++              }
++              return -ETIMEDOUT;
++      default:
++              break;
++      }
++
++      if (dma_status)
++              return 0;
++
++      desc = dmaengine_prep_slave_single(dma->rxchan, dma->rx_addr,
++                                         dma->rx_size, DMA_DEV_TO_MEM,
++                                         DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
++      if (!desc)
++              return -EBUSY;
++
++      desc->callback = __dma_rx_complete;
++      desc->callback_param = p;
++
++      dma->rx_cookie = dmaengine_submit(desc);
++
++      dma_sync_single_for_device(dma->rxchan->device->dev, dma->rx_addr,
++                                 dma->rx_size, DMA_FROM_DEVICE);
++
++      dma_async_issue_pending(dma->rxchan);
++
++      return 0;
++}
++EXPORT_SYMBOL_GPL(serial8250_rx_dma);
++
++int serial8250_request_dma(struct uart_8250_port *p)
++{
++      struct uart_8250_dma    *dma = p->dma;
++      dma_cap_mask_t          mask;
++
++      dma->rxconf.src_addr = p->port.mapbase + UART_RX;
++      dma->txconf.dst_addr = p->port.mapbase + UART_TX;
++
++      dma_cap_zero(mask);
++      dma_cap_set(DMA_SLAVE, mask);
++
++      /* Get a channel for RX */
++      dma->rxchan = dma_request_channel(mask, dma->fn, dma->rx_param);
++      if (!dma->rxchan)
++              return -ENODEV;
++
++      dmaengine_slave_config(dma->rxchan, &dma->rxconf);
++
++      /* Get a channel for TX */
++      dma->txchan = dma_request_channel(mask, dma->fn, dma->tx_param);
++      if (!dma->txchan) {
++              dma_release_channel(dma->rxchan);
++              return -ENODEV;
++      }
++
++      dmaengine_slave_config(dma->txchan, &dma->txconf);
++
++      /* RX buffer */
++      if (!dma->rx_size)
++              dma->rx_size = PAGE_SIZE;
++
++      dma->rx_buf = dma_alloc_coherent(dma->rxchan->device->dev, dma->rx_size,
++                                      &dma->rx_addr, GFP_KERNEL);
++      if (!dma->rx_buf) {
++              dma_release_channel(dma->rxchan);
++              dma_release_channel(dma->txchan);
++              return -ENOMEM;
++      }
++
++      /* TX buffer */
++      dma->tx_addr = dma_map_single(dma->txchan->device->dev,
++                                      p->port.state->xmit.buf,
++                                      UART_XMIT_SIZE,
++                                      DMA_TO_DEVICE);
++
++      dev_dbg_ratelimited(p->port.dev, "got both dma channels\n");
++
++      return 0;
++}
++EXPORT_SYMBOL_GPL(serial8250_request_dma);
++
++void serial8250_release_dma(struct uart_8250_port *p)
++{
++      struct uart_8250_dma *dma = p->dma;
++
++      if (!dma)
++              return;
++
++      /* Release RX resources */
++      dmaengine_terminate_all(dma->rxchan);
++      dma_free_coherent(dma->rxchan->device->dev, dma->rx_size, dma->rx_buf,
++                        dma->rx_addr);
++      dma_release_channel(dma->rxchan);
++      dma->rxchan = NULL;
++
++      /* Release TX resources */
++      dmaengine_terminate_all(dma->txchan);
++      dma_unmap_single(dma->txchan->device->dev, dma->tx_addr,
++                       UART_XMIT_SIZE, DMA_TO_DEVICE);
++      dma_release_channel(dma->txchan);
++      dma->txchan = NULL;
++      dma->tx_running = 0;
++
++      dev_dbg_ratelimited(p->port.dev, "dma channels released\n");
++}
++EXPORT_SYMBOL_GPL(serial8250_release_dma);
+diff --git a/drivers/tty/serial/8250/8250_dw.c 
b/drivers/tty/serial/8250/8250_dw.c
+index 096d2ef..1d8ed86 100644
+--- a/drivers/tty/serial/8250/8250_dw.c
++++ b/drivers/tty/serial/8250/8250_dw.c
+@@ -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
+@@ -24,10 +25,42 @@
+ #include <linux/of_platform.h>
+ #include <linux/platform_device.h>
+ #include <linux/slab.h>
++#include <linux/acpi.h>
++#include <linux/pm_runtime.h>
++#include <linux/clk.h>
++
++#include "8250.h"
++
++static bool use_dma = 1;
++module_param(use_dma, bool, 0);
++MODULE_PARM_DESC(use_dma, "use_dma=1 (enable DMA)/use_dma=0(disable DMA)");
++
++/* 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 */
++
++/* 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;
+       int     line;
++      struct clk *clk;
+ };
+
+ static void dw8250_serial_out(struct uart_port *p, int offset, int value)
+@@ -66,19 +99,79 @@ static unsigned int dw8250_serial_in32(struct uart_port 
*p, int offset)
+       return readl(p->membase + offset);
+ }
+
+-/* Offset for the DesignWare's UART Status Register. */
+-#define UART_USR      0x1f
++#define LPSS_PRV_CLK                   0x800
++#define LPSS_PRV_CLK_EN                        (1 << 0)
++#define LPSS_PRV_CLK_M_VAL_SHIFT       1
++#define LPSS_PRV_CLK_N_VAL_SHIFT       16
++#define LPSS_PRV_CLK_UPDATE            (1 << 31)
++
++#define LPSS_HSUART_GENERAL_REG               0x808
++#define LPSS_GENERAL_DIS_RTS_N_OVERRIDE       (1 << 3)
++
++static void
++dw8250_set_termios(struct uart_port *p, struct ktermios *termios,
++                 struct ktermios *old)
++{
++      struct uart_8250_port *up =
++              container_of(p, struct uart_8250_port, port);
++      unsigned int baud = tty_termios_baud_rate(termios);
++      unsigned int m = 6912;
++      unsigned int n = 15625;
++      u32 reg;
++
++      /*
++       * For baud rates 1000000, 2000000 and 4000000 the dividers must be
++       * adjusted.
++       */
++      if (baud == 1000000 || baud == 2000000 || baud == 4000000) {
++              m = 64;
++              n = 100;
++
++              p->uartclk = 64000000;
++      } else if (baud == 3000000){
++              m = 48;
++              n = 100;
++
++              p->uartclk = 48000000;
++      }else {
++              p->uartclk = 44236800;
++      }
++
++      /* Reset the clock */
++      reg = (m << LPSS_PRV_CLK_M_VAL_SHIFT) | (n << LPSS_PRV_CLK_N_VAL_SHIFT);
++      writel(reg, p->membase + LPSS_PRV_CLK);
++      reg |= LPSS_PRV_CLK_EN | LPSS_PRV_CLK_UPDATE;
++      writel(reg, p->membase + LPSS_PRV_CLK);
++
++      /* For BYT, hs-uart is capable of auto flow control */
++      up->capabilities |= UART_CAP_AFE;
++
++      /* If auto-handshake mechanism is not enabled,
++       * disable rts_n override */
++      reg = readl(p->membase + LPSS_HSUART_GENERAL_REG);
++      reg &= ~LPSS_GENERAL_DIS_RTS_N_OVERRIDE;
++      if (termios->c_cflag & CRTSCTS)
++              reg |= LPSS_GENERAL_DIS_RTS_N_OVERRIDE;
++      writel(reg, p->membase + LPSS_HSUART_GENERAL_REG);
++
++      serial8250_do_set_termios(p, termios, old);
++}
+
+ static int dw8250_handle_irq(struct uart_port *p)
+ {
+       struct dw8250_data *d = p->private_data;
+       unsigned int iir = p->serial_in(p, UART_IIR);
+
++      if(iir & UART_IIR_RLSI) {
++              readl(p->membase + LPSS_UART_BYTE_CNT);
++              readl(p->membase + LPSS_UART_OVRFLW_INTR_STAT);
++      }
++
+       if (serial8250_handle_irq(p, iir)) {
+               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, UART_LCR, d->last_lcr);
+
+               return 1;
+@@ -87,61 +180,216 @@ static int dw8250_handle_irq(struct uart_port *p)
+       return 0;
+ }
+
++static void
++dw8250_do_pm(struct uart_port *port, unsigned int state, unsigned int old)
++{
++      if (!state)
++              pm_runtime_get_sync(port->dev);
++
++      serial8250_do_pm(port, state, old);
++
++      if (state)
++              pm_runtime_put_sync_suspend(port->dev);
++}
++
++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)
++{
++      struct dw8250_data *data = p->private_data;
++      acpi_status status;
++
++      p->iotype = UPIO_MEM32;
++      p->serial_in = dw8250_serial_in32;
++      p->serial_out = dw8250_serial_out32;
++      p->set_termios = dw8250_set_termios;
++      p->regshift = 2;
++      p->uartclk = clk_get_rate(data->clk);
++
++      if (use_dma){
++              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;
++              }
++      }
++      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.pm = dw8250_do_pm;
+       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;
++
++      data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
++      if (!data)
++              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;
+-              }
+-      }
+-
+-      if (!of_property_read_u32(np, "reg-shift", &val))
+-              uart.port.regshift = val;
++      uart.port.private_data = data;
+
+-      if (of_property_read_u32(np, "clock-frequency", &val)) {
+-              dev_err(&pdev->dev, "no clock-frequency property set\n");
+-              return -EINVAL;
++      data->clk = devm_clk_get(&pdev->dev, NULL);
++      clk_prepare_enable(data->clk);
++
++      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;
+       }
+-      uart.port.uartclk = val;
+
+       data->line = serial8250_register_8250_port(&uart);
+       if (data->line < 0)
+@@ -149,6 +397,8 @@ static int dw8250_probe(struct platform_device *pdev)
+
+       platform_set_drvdata(pdev, data);
+
++      pm_runtime_forbid(&pdev->dev);
++
+       return 0;
+ }
+
+@@ -156,50 +406,86 @@ static int dw8250_remove(struct platform_device *pdev)
+ {
+       struct dw8250_data *data = platform_get_drvdata(pdev);
+
++      pm_runtime_get_sync(&pdev->dev);
++
+       serial8250_unregister_port(data->line);
++      clk_disable_unprepare(data->clk);
++
++      pm_runtime_disable(&pdev->dev);
++      pm_runtime_put_noidle(&pdev->dev);
+
+       return 0;
+ }
+
+ #ifdef CONFIG_PM
+-static int dw8250_suspend(struct platform_device *pdev, pm_message_t state)
++static int dw8250_suspend(struct device *dev)
+ {
+-      struct dw8250_data *data = platform_get_drvdata(pdev);
++      struct dw8250_data *data = dev_get_drvdata(dev);
+
+       serial8250_suspend_port(data->line);
+
+       return 0;
+ }
+
+-static int dw8250_resume(struct platform_device *pdev)
++static int dw8250_resume(struct device *dev)
+ {
+-      struct dw8250_data *data = platform_get_drvdata(pdev);
++      struct dw8250_data *data = dev_get_drvdata(dev);
+
+       serial8250_resume_port(data->line);
+
+       return 0;
+ }
+-#else
+-#define dw8250_suspend NULL
+-#define dw8250_resume NULL
+ #endif /* CONFIG_PM */
+
+-static const struct of_device_id dw8250_match[] = {
++#ifdef CONFIG_PM_RUNTIME
++static int dw8250_runtime_suspend(struct device *dev)
++{
++      struct dw8250_data *data = dev_get_drvdata(dev);
++
++      clk_disable_unprepare(data->clk);
++
++      return 0;
++}
++
++static int dw8250_runtime_resume(struct device *dev)
++{
++      struct dw8250_data *data = dev_get_drvdata(dev);
++
++      clk_prepare_enable(data->clk);
++
++      return 0;
++}
++#endif
++
++static const struct dev_pm_ops dw8250_pm_ops = {
++      SET_SYSTEM_SLEEP_PM_OPS(dw8250_suspend, dw8250_resume)
++      SET_RUNTIME_PM_OPS(dw8250_runtime_suspend, dw8250_runtime_resume, NULL)
++};
++
++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[] = {
++      { "80860F0A", 0 },
++      { "INT33C4", 0 },
++      { "INT33C5", 0 },
++      { },
++};
++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,
++              .pm             = &dw8250_pm_ops,
++              .of_match_table = dw8250_of_match,
++              .acpi_match_table = ACPI_PTR(dw8250_acpi_match),
+       },
+       .probe                  = dw8250_probe,
+       .remove                 = dw8250_remove,
+-      .suspend                = dw8250_suspend,
+-      .resume                 = dw8250_resume,
+ };
+
+ module_platform_driver(dw8250_platform_driver);
+diff --git a/drivers/tty/serial/8250/8250_early.c 
b/drivers/tty/serial/8250/8250_early.c
+index f53a7db..721904f 100644
+--- a/drivers/tty/serial/8250/8250_early.c
++++ b/drivers/tty/serial/8250/8250_early.c
+@@ -194,7 +194,7 @@ static int __init parse_options(struct 
early_serial8250_device *device,
+               options++;
+               device->baud = simple_strtoul(options, NULL, 0);
+               length = min(strcspn(options, " "), sizeof(device->options));
+-              strncpy(device->options, options, length);
++              strlcpy(device->options, options, length);
+       } else {
+               device->baud = probe_baud(port);
+               snprintf(device->options, sizeof(device->options), "%u",
+diff --git a/drivers/tty/serial/8250/8250_pci.c 
b/drivers/tty/serial/8250/8250_pci.c
+index a27a98e..27b82d4 100644
+--- a/drivers/tty/serial/8250/8250_pci.c
++++ b/drivers/tty/serial/8250/8250_pci.c
+@@ -1077,6 +1077,134 @@ ce4100_serial_setup(struct serial_private *priv,
+       return ret;
+ }
+
++static bool lpss_dma_filter(struct dma_chan *chan, void *param)
++{
++      return chan->chan_id == *(int*)param;
++}
++
++#define PCI_DEVICE_ID_INTEL_HSW_UART1 0x9c63
++#define PCI_DEVICE_ID_INTEL_HSW_UART2 0x9c64
++
++#define LPSS_PRV_CLK                  0x800
++#define LPSS_PRV_CLK_EN                       (1 << 0)
++#define LPSS_PRV_CLK_M_VAL_SHIFT      1
++#define LPSS_PRV_CLK_N_VAL_SHIFT      16
++#define LPSS_PRV_CLK_UPDATE           (1 << 31)
++
++#define LPSS_HSUART_GENERAL_REG               0x808
++#define LPSS_GENERAL_DIS_RTS_N_OVERRIDE       (1 << 3)
++
++static void
++lpss_set_termios(struct uart_port *p, struct ktermios *termios,
++                 struct ktermios *old)
++{
++      struct uart_8250_port *up =
++              container_of(p, struct uart_8250_port, port);
++      unsigned int baud = tty_termios_baud_rate(termios);
++      unsigned int m = 6912;
++      unsigned int n = 15625;
++      u32 reg;
++
++      /*
++       * For baud rates 1000000, 2000000 and 4000000 the dividers must be
++       * adjusted.
++       */
++      if (baud == 1000000 || baud == 2000000 || baud == 4000000) {
++              m = 64;
++              n = 100;
++
++              p->uartclk = 64000000;
++      } else if (baud == 3000000){
++                m = 48;
++                n = 100;
++
++                p->uartclk = 48000000;
++      } else {
++              p->uartclk = 44236800;
++      }
++
++      /* Reset the clock */
++      reg = (m << LPSS_PRV_CLK_M_VAL_SHIFT) | (n << LPSS_PRV_CLK_N_VAL_SHIFT);
++      writel(reg, p->membase + LPSS_PRV_CLK);
++      reg |= LPSS_PRV_CLK_EN | LPSS_PRV_CLK_UPDATE;
++      writel(reg, p->membase + LPSS_PRV_CLK);
++
++      /* For BYT, hs-uart is capable of auto flow control */
++      up->capabilities |= UART_CAP_AFE;
++
++      /*
++       * If auto-handshake mechanism is not enabled,
++       * disable rts_n override
++       */
++      reg = readl(p->membase + LPSS_HSUART_GENERAL_REG);
++      reg &= ~LPSS_GENERAL_DIS_RTS_N_OVERRIDE;
++      if (termios->c_cflag & CRTSCTS)
++              reg |= LPSS_GENERAL_DIS_RTS_N_OVERRIDE;
++      writel(reg, p->membase + LPSS_HSUART_GENERAL_REG);
++
++      serial8250_do_set_termios(p, termios, old);
++}
++
++static int
++lpss_serial_setup(struct serial_private *priv,
++              const struct pciserial_board *board,
++              struct uart_8250_port *port, int idx)
++{
++      struct uart_8250_dma *dma;
++      int ret;
++
++      dma = devm_kzalloc(port->port.dev, sizeof(*dma), GFP_KERNEL);
++      if (!dma)
++              return -ENOMEM;
++
++      switch (priv->dev->device) {
++      case PCI_DEVICE_ID_INTEL_BYT_UART1:
++              dma->rx_chan_id = 3;
++              dma->rxconf.slave_id = dma->rx_chan_id;
++              dma->tx_chan_id = 2;
++              dma->txconf.slave_id = dma->tx_chan_id;
++              break;
++      case PCI_DEVICE_ID_INTEL_BYT_UART2:
++              dma->rx_chan_id = 5;
++              dma->rxconf.slave_id = dma->rx_chan_id;
++              dma->tx_chan_id = 4;
++              dma->txconf.slave_id = dma->tx_chan_id;
++              break;
++      case PCI_DEVICE_ID_INTEL_HSW_UART1:
++              dma->rx_chan_id = 5;
++              dma->rxconf.slave_id = 21;
++              dma->tx_chan_id = 4;
++              dma->txconf.slave_id = 20;
++              break;
++      default:
++              return -EINVAL;
++      }
++
++      dma->rxconf.direction = DMA_DEV_TO_MEM;
++      dma->rxconf.src_addr_width = 1;
++      dma->rxconf.src_maxburst = 16;
++
++      dma->txconf.direction = DMA_MEM_TO_DEV;
++      dma->txconf.dst_addr_width = 1;
++      dma->rxconf.dst_maxburst = 16;
++
++      dma->fn = lpss_dma_filter;
++      dma->rx_param = &dma->rx_chan_id;
++      dma->tx_param = &dma->tx_chan_id;
++
++      ret = pci_default_setup(priv, board, port, idx);
++      port->port.iotype = UPIO_MEM;
++      port->port.type = PORT_16550A;
++      port->port.flags = (port->port.flags | UPF_FIXED_PORT | UPF_FIXED_TYPE);
++      port->port.set_termios = lpss_set_termios;
++      port->port.fifosize = 64;
++      port->tx_loadsz = 64;
++      port->dma = dma;
++      port->port.dev->id = priv->dev->device;
++
++      return ret;
++}
++
+ static int
+ pci_omegapci_setup(struct serial_private *priv,
+                     const struct pciserial_board *board,
+@@ -1409,6 +1537,34 @@ static struct pci_serial_quirk pci_serial_quirks[] 
__refdata = {
+               .subdevice      = PCI_ANY_ID,
+               .setup          = kt_serial_setup,
+       },
++      {
++              .vendor         = PCI_VENDOR_ID_INTEL,
++              .device         = PCI_DEVICE_ID_INTEL_BYT_UART1,
++              .subvendor      = PCI_ANY_ID,
++              .subdevice      = PCI_ANY_ID,
++              .setup          = lpss_serial_setup,
++      },
++      {
++              .vendor         = PCI_VENDOR_ID_INTEL,
++              .device         = PCI_DEVICE_ID_INTEL_BYT_UART2,
++              .subvendor      = PCI_ANY_ID,
++              .subdevice      = PCI_ANY_ID,
++              .setup          = lpss_serial_setup,
++      },
++      {
++              .vendor         = PCI_VENDOR_ID_INTEL,
++              .device         = PCI_DEVICE_ID_INTEL_HSW_UART1,
++              .subvendor      = PCI_ANY_ID,
++              .subdevice      = PCI_ANY_ID,
++              .setup          = lpss_serial_setup,
++      },
++      {
++              .vendor         = PCI_VENDOR_ID_INTEL,
++              .device         = PCI_DEVICE_ID_INTEL_HSW_UART2,
++              .subvendor      = PCI_ANY_ID,
++              .subdevice      = PCI_ANY_ID,
++              .setup          = pci_default_setup,
++      },
+       /*
+        * ITE
+        */
+@@ -2170,6 +2326,8 @@ enum pci_board_num_t {
+       pbn_ADDIDATA_PCIe_4_3906250,
+       pbn_ADDIDATA_PCIe_8_3906250,
+       pbn_ce4100_1_115200,
++      pbn_byt,
++      pbn_hsw,
+       pbn_omegapci,
+       pbn_NETMOS9900_2s_115200,
+       pbn_brcm_trumanage,
+@@ -2906,6 +3064,20 @@ static struct pciserial_board pci_boards[] = {
+               .base_baud      = 921600,
+               .reg_shift      = 2,
+       },
++      [pbn_byt] = {
++              .flags          = FL_BASE0,
++              .num_ports      = 1,
++              .base_baud      = 2764800,
++              .uart_offset    = 0x80,
++              .reg_shift      = 2,
++      },
++      [pbn_hsw] = {
++              .flags          = FL_BASE0,
++              .num_ports      = 1,
++              .base_baud      = 6250000,
++              .uart_offset    = 0x80,
++              .reg_shift      = 2,
++      },
+       [pbn_omegapci] = {
+               .flags          = FL_BASE0,
+               .num_ports      = 8,
+@@ -4493,6 +4665,24 @@ static struct pci_device_id serial_pci_tbl[] = {
+       {       PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_CE4100_UART,
+               PCI_ANY_ID,  PCI_ANY_ID, 0, 0,
+               pbn_ce4100_1_115200 },
++      /* Intel BYT */
++      {       PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT_UART1,
++              PCI_ANY_ID,  PCI_ANY_ID,
++              PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000,
++              pbn_byt },
++      {       PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_BYT_UART2,
++              PCI_ANY_ID,  PCI_ANY_ID,
++              PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000,
++              pbn_byt },
++      /* Intel Haswell-ULT */
++      {       PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HSW_UART1,
++              PCI_ANY_ID,  PCI_ANY_ID,
++              PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000,
++              pbn_hsw },
++      {       PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_HSW_UART2,
++              PCI_ANY_ID,  PCI_ANY_ID,
++              PCI_CLASS_COMMUNICATION_SERIAL << 8, 0xff0000,
++              pbn_hsw },
+
+       /*
+        * Cronyx Omega PCI
+diff --git a/drivers/tty/serial/8250/Kconfig b/drivers/tty/serial/8250/Kconfig
+index c31133a..2748125 100644
+--- a/drivers/tty/serial/8250/Kconfig
++++ b/drivers/tty/serial/8250/Kconfig
+@@ -84,6 +84,14 @@ config SERIAL_8250_GSC
+       depends on SERIAL_8250 && GSC
+       default SERIAL_8250
+
++config SERIAL_8250_DMA
++      bool "DMA support for 16550 compatible UART controllers" if EXPERT
++      depends on SERIAL_8250 && DMADEVICES=y
++      default SERIAL_8250
++      help
++        This builds DMA support that can be used with 8250/16650
++        compatible UART controllers that support DMA signaling.
++
+ config SERIAL_8250_PCI
+       tristate "8250/16550 PCI device support" if EXPERT
+       depends on SERIAL_8250 && PCI
+@@ -265,7 +273,7 @@ config SERIAL_8250_FSL
+
+ config SERIAL_8250_DW
+       tristate "Support for Synopsys DesignWare 8250 quirks"
+-      depends on SERIAL_8250 && OF
++      depends on SERIAL_8250
+       help
+         Selecting this option will enable handling of the extra features
+         present in the Synopsys DesignWare APB UART.
+diff --git a/drivers/tty/serial/8250/Makefile 
b/drivers/tty/serial/8250/Makefile
+index 108fe7f..a23838a 100644
+--- a/drivers/tty/serial/8250/Makefile
++++ b/drivers/tty/serial/8250/Makefile
+@@ -5,6 +5,7 @@
+ obj-$(CONFIG_SERIAL_8250)             += 8250_core.o
+ 8250_core-y                           := 8250.o
+ 8250_core-$(CONFIG_SERIAL_8250_PNP)   += 8250_pnp.o
++8250_core-$(CONFIG_SERIAL_8250_DMA)   += 8250_dma.o
+ obj-$(CONFIG_SERIAL_8250_GSC)         += 8250_gsc.o
+ obj-$(CONFIG_SERIAL_8250_PCI)         += 8250_pci.o
+ obj-$(CONFIG_SERIAL_8250_HP300)               += 8250_hp300.o
+diff --git a/include/linux/serial_8250.h b/include/linux/serial_8250.h
+index c490d20..af47a8a 100644
+--- a/include/linux/serial_8250.h
++++ b/include/linux/serial_8250.h
+@@ -59,6 +59,8 @@ enum {
+       PLAT8250_DEV_SM501,
+ };
+
++struct uart_8250_dma;
++
+ /*
+  * This should be used by drivers which want to register
+  * their own 8250 ports without registering their own
+@@ -91,6 +93,8 @@ struct uart_8250_port {
+ #define MSR_SAVE_FLAGS UART_MSR_ANY_DELTA
+       unsigned char           msr_saved_flags;
+
++      struct uart_8250_dma    *dma;
++
+       /* 8250 specific callbacks */
+       int                     (*dl_read)(struct uart_8250_port *);
+       void                    (*dl_write)(struct uart_8250_port *, int);
+--
+1.7.10.4
+
-- 
1.7.10.4

_______________________________________________
linux-yocto mailing list
[email protected]
https://lists.yoctoproject.org/listinfo/linux-yocto

Reply via email to