aboutsummaryrefslogtreecommitdiff
path: root/drivers/tty/serial/8250/8250_pci.c
diff options
context:
space:
mode:
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>2014-08-19 20:29:22 +0300
committerVinod Koul <vinod.koul@intel.com>2014-09-11 11:48:36 +0530
commit9a1870ce812e13091c21af36d4dc1cd29077966d (patch)
tree45eb5fb233e7f6b6a1f683780ca6b8de03cd6a37 /drivers/tty/serial/8250/8250_pci.c
parentb279c4922e9242b4b1a04da7fa5622f2323c85de (diff)
serial: 8250: don't use slave_id of dma_slave_config
That field has been deprecated in favour of getting the necessary information from ACPI or DT. However, we still need to deal systems that are PCI only (no ACPI to back up) like Intel Bay Trail. In order to support such systems, we explicitly bind setup() to the appropriate DMA filter function and its corresponding parameter. Then when serial8250_request_dma() doesn't find the channel via ACPI or DT, it falls back to use the given filter function. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> Signed-off-by: Vinod Koul <vinod.koul@intel.com>
Diffstat (limited to 'drivers/tty/serial/8250/8250_pci.c')
-rw-r--r--drivers/tty/serial/8250/8250_pci.c51
1 files changed, 40 insertions, 11 deletions
diff --git a/drivers/tty/serial/8250/8250_pci.c b/drivers/tty/serial/8250/8250_pci.c
index 61830b1792eb..a00c9de814d1 100644
--- a/drivers/tty/serial/8250/8250_pci.c
+++ b/drivers/tty/serial/8250/8250_pci.c
@@ -25,6 +25,9 @@
#include <asm/byteorder.h>
#include <asm/io.h>
+#include <linux/dmaengine.h>
+#include <linux/platform_data/dma-dw.h>
+
#include "8250.h"
/*
@@ -1427,7 +1430,13 @@ byt_set_termios(struct uart_port *p, struct ktermios *termios,
static bool byt_dma_filter(struct dma_chan *chan, void *param)
{
- return chan->chan_id == *(int *)param;
+ struct dw_dma_slave *dws = param;
+
+ if (dws->dma_dev != chan->device->dev)
+ return false;
+
+ chan->private = dws;
+ return true;
}
static int
@@ -1435,35 +1444,55 @@ byt_serial_setup(struct serial_private *priv,
const struct pciserial_board *board,
struct uart_8250_port *port, int idx)
{
+ struct pci_dev *pdev = priv->dev;
+ struct device *dev = port->port.dev;
struct uart_8250_dma *dma;
+ struct dw_dma_slave *tx_param, *rx_param;
+ struct pci_dev *dma_dev;
int ret;
- dma = devm_kzalloc(port->port.dev, sizeof(*dma), GFP_KERNEL);
+ dma = devm_kzalloc(dev, sizeof(*dma), GFP_KERNEL);
if (!dma)
return -ENOMEM;
- switch (priv->dev->device) {
+ tx_param = devm_kzalloc(dev, sizeof(*tx_param), GFP_KERNEL);
+ if (!tx_param)
+ return -ENOMEM;
+
+ rx_param = devm_kzalloc(dev, sizeof(*rx_param), GFP_KERNEL);
+ if (!rx_param)
+ return -ENOMEM;
+
+ switch (pdev->device) {
case PCI_DEVICE_ID_INTEL_BYT_UART1:
- dma->rx_chan_id = 3;
- dma->tx_chan_id = 2;
+ rx_param->src_id = 3;
+ tx_param->dst_id = 2;
break;
case PCI_DEVICE_ID_INTEL_BYT_UART2:
- dma->rx_chan_id = 5;
- dma->tx_chan_id = 4;
+ rx_param->src_id = 5;
+ tx_param->dst_id = 4;
break;
default:
return -EINVAL;
}
- dma->rxconf.slave_id = dma->rx_chan_id;
+ rx_param->src_master = 1;
+ rx_param->dst_master = 0;
+
dma->rxconf.src_maxburst = 16;
- dma->txconf.slave_id = dma->tx_chan_id;
+ tx_param->src_master = 1;
+ tx_param->dst_master = 0;
+
dma->txconf.dst_maxburst = 16;
+ dma_dev = pci_get_slot(pdev->bus, PCI_DEVFN(PCI_SLOT(pdev->devfn), 0));
+ rx_param->dma_dev = &dma_dev->dev;
+ tx_param->dma_dev = &dma_dev->dev;
+
dma->fn = byt_dma_filter;
- dma->rx_param = &dma->rx_chan_id;
- dma->tx_param = &dma->tx_chan_id;
+ dma->rx_param = rx_param;
+ dma->tx_param = tx_param;
ret = pci_default_setup(priv, board, port, idx);
port->port.iotype = UPIO_MEM;