提交 9a1870ce 编写于 作者: A Andy Shevchenko 提交者: Vinod Koul

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: NAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Acked-by: NGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: NVinod Koul <vinod.koul@intel.com>
上级 b279c492
......@@ -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;
......
......@@ -216,10 +216,7 @@ static void dw8250_set_termios(struct uart_port *p, struct ktermios *termios,
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;
......
......@@ -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;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册