summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>2014-08-19 21:29:22 +0400
committerVinod Koul <vinod.koul@intel.com>2014-09-11 10:18:36 +0400
commit9a1870ce812e13091c21af36d4dc1cd29077966d (patch)
tree45eb5fb233e7f6b6a1f683780ca6b8de03cd6a37
parentb279c4922e9242b4b1a04da7fa5622f2323c85de (diff)
downloadlinux-9a1870ce812e13091c21af36d4dc1cd29077966d.tar.xz
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>
-rw-r--r--drivers/tty/serial/8250/8250.h6
-rw-r--r--drivers/tty/serial/8250/8250_dw.c7
-rw-r--r--drivers/tty/serial/8250/8250_pci.c51
3 files changed, 44 insertions, 20 deletions
diff --git a/drivers/tty/serial/8250/8250.h b/drivers/tty/serial/8250/8250.h
index 1b08c918cd51..c3c70913e040 100644
--- a/drivers/tty/serial/8250/8250.h
+++ b/drivers/tty/serial/8250/8250.h
@@ -16,13 +16,13 @@
#include <linux/dmaengine.h>
struct uart_8250_dma {
+ /* Filter function */
dma_filter_fn fn;
+
+ /* Parameter to the filter function */
void *rx_param;
void *tx_param;
- int rx_chan_id;
- int tx_chan_id;
-
struct dma_slave_config rxconf;
struct dma_slave_config txconf;
diff --git a/drivers/tty/serial/8250/8250_dw.c b/drivers/tty/serial/8250/8250_dw.c
index 4db7987ec225..6664de2cdfdb 100644
--- a/drivers/tty/serial/8250/8250_dw.c
+++ b/drivers/tty/serial/8250/8250_dw.c
@@ -216,10 +216,7 @@ out:
static bool dw8250_dma_filter(struct dma_chan *chan, void *param)
{
- struct dw8250_data *data = param;
-
- return chan->chan_id == data->dma.tx_chan_id ||
- chan->chan_id == data->dma.rx_chan_id;
+ return false;
}
static void dw8250_setup_port(struct uart_8250_port *up)
@@ -399,8 +396,6 @@ static int dw8250_probe(struct platform_device *pdev)
if (!IS_ERR(data->rst))
reset_control_deassert(data->rst);
- data->dma.rx_chan_id = -1;
- data->dma.tx_chan_id = -1;
data->dma.rx_param = data;
data->dma.tx_param = data;
data->dma.fn = dw8250_dma_filter;
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;