summaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/spi-pxa2xx-dma.c15
-rw-r--r--drivers/spi/spi-pxa2xx-pci.c101
-rw-r--r--drivers/spi/spi-pxa2xx.c2
3 files changed, 86 insertions, 32 deletions
diff --git a/drivers/spi/spi-pxa2xx-dma.c b/drivers/spi/spi-pxa2xx-dma.c
index c41ff14..62a9297 100644
--- a/drivers/spi/spi-pxa2xx-dma.c
+++ b/drivers/spi/spi-pxa2xx-dma.c
@@ -157,7 +157,6 @@ static struct dma_async_tx_descriptor *
pxa2xx_spi_dma_prepare_one(struct driver_data *drv_data,
enum dma_transfer_direction dir)
{
- struct pxa2xx_spi_master *pdata = drv_data->master_info;
struct chip_data *chip = drv_data->cur_chip;
enum dma_slave_buswidth width;
struct dma_slave_config cfg;
@@ -184,7 +183,6 @@ pxa2xx_spi_dma_prepare_one(struct driver_data *drv_data,
cfg.dst_addr = drv_data->ssdr_physical;
cfg.dst_addr_width = width;
cfg.dst_maxburst = chip->dma_burst_size;
- cfg.slave_id = pdata->tx_slave_id;
sgt = &drv_data->tx_sgt;
nents = drv_data->tx_nents;
@@ -193,7 +191,6 @@ pxa2xx_spi_dma_prepare_one(struct driver_data *drv_data,
cfg.src_addr = drv_data->ssdr_physical;
cfg.src_addr_width = width;
cfg.src_maxburst = chip->dma_burst_size;
- cfg.slave_id = pdata->rx_slave_id;
sgt = &drv_data->rx_sgt;
nents = drv_data->rx_nents;
@@ -210,14 +207,6 @@ pxa2xx_spi_dma_prepare_one(struct driver_data *drv_data,
DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
}
-static bool pxa2xx_spi_dma_filter(struct dma_chan *chan, void *param)
-{
- const struct pxa2xx_spi_master *pdata = param;
-
- return chan->chan_id == pdata->tx_chan_id ||
- chan->chan_id == pdata->rx_chan_id;
-}
-
bool pxa2xx_spi_dma_is_possible(size_t len)
{
return len <= MAX_DMA_LEN;
@@ -321,12 +310,12 @@ int pxa2xx_spi_dma_setup(struct driver_data *drv_data)
return -ENOMEM;
drv_data->tx_chan = dma_request_slave_channel_compat(mask,
- pxa2xx_spi_dma_filter, pdata, dev, "tx");
+ pdata->dma_filter, pdata->tx_param, dev, "tx");
if (!drv_data->tx_chan)
return -ENODEV;
drv_data->rx_chan = dma_request_slave_channel_compat(mask,
- pxa2xx_spi_dma_filter, pdata, dev, "rx");
+ pdata->dma_filter, pdata->rx_param, dev, "rx");
if (!drv_data->rx_chan) {
dma_release_channel(drv_data->tx_chan);
drv_data->tx_chan = NULL;
diff --git a/drivers/spi/spi-pxa2xx-pci.c b/drivers/spi/spi-pxa2xx-pci.c
index 536c863..6beee8c 100644
--- a/drivers/spi/spi-pxa2xx-pci.c
+++ b/drivers/spi/spi-pxa2xx-pci.c
@@ -10,42 +10,87 @@
#include <linux/clk.h>
#include <linux/clk-provider.h>
+#include <linux/dmaengine.h>
+#include <linux/platform_data/dma-dw.h>
+
enum {
PORT_CE4100,
PORT_BYT,
+ PORT_BSW0,
+ PORT_BSW1,
+ PORT_BSW2,
};
struct pxa_spi_info {
enum pxa_ssp_type type;
int port_id;
int num_chipselect;
- int tx_slave_id;
- int tx_chan_id;
- int rx_slave_id;
- int rx_chan_id;
unsigned long max_clk_rate;
+
+ /* DMA channel request parameters */
+ void *tx_param;
+ void *rx_param;
};
+static struct dw_dma_slave byt_tx_param = { .dst_id = 0 };
+static struct dw_dma_slave byt_rx_param = { .src_id = 1 };
+
+static struct dw_dma_slave bsw0_tx_param = { .dst_id = 0 };
+static struct dw_dma_slave bsw0_rx_param = { .src_id = 1 };
+static struct dw_dma_slave bsw1_tx_param = { .dst_id = 6 };
+static struct dw_dma_slave bsw1_rx_param = { .src_id = 7 };
+static struct dw_dma_slave bsw2_tx_param = { .dst_id = 8 };
+static struct dw_dma_slave bsw2_rx_param = { .src_id = 9 };
+
+static bool lpss_dma_filter(struct dma_chan *chan, void *param)
+{
+ struct dw_dma_slave *dws = param;
+
+ if (dws->dma_dev != chan->device->dev)
+ return false;
+
+ chan->private = dws;
+ return true;
+}
+
static struct pxa_spi_info spi_info_configs[] = {
[PORT_CE4100] = {
.type = PXA25x_SSP,
.port_id = -1,
.num_chipselect = -1,
- .tx_slave_id = -1,
- .tx_chan_id = -1,
- .rx_slave_id = -1,
- .rx_chan_id = -1,
.max_clk_rate = 3686400,
},
[PORT_BYT] = {
.type = LPSS_SSP,
.port_id = 0,
.num_chipselect = 1,
- .tx_slave_id = 0,
- .tx_chan_id = 0,
- .rx_slave_id = 1,
- .rx_chan_id = 1,
.max_clk_rate = 50000000,
+ .tx_param = &byt_tx_param,
+ .rx_param = &byt_rx_param,
+ },
+ [PORT_BSW0] = {
+ .type = LPSS_SSP,
+ .port_id = 0,
+ .num_chipselect = 1,
+ .max_clk_rate = 50000000,
+ .tx_param = &bsw0_tx_param,
+ .rx_param = &bsw0_rx_param,
+ },
+ [PORT_BSW1] = {
+ .type = LPSS_SSP,
+ .port_id = 1,
+ .num_chipselect = 1,
+ .max_clk_rate = 50000000,
+ .tx_param = &bsw1_tx_param,
+ .rx_param = &bsw1_rx_param,
+ },
+ [PORT_BSW2] = {
+ .type = LPSS_SSP,
+ .port_id = 2,
+ .num_chipselect = 1,
+ .max_clk_rate = 50000000,
+ .tx_param = &bsw2_tx_param,
+ .rx_param = &bsw2_rx_param,
},
};
@@ -59,6 +104,7 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev,
struct ssp_device *ssp;
struct pxa_spi_info *c;
char buf[40];
+ struct pci_dev *dma_dev;
ret = pcim_enable_device(dev);
if (ret)
@@ -73,11 +119,29 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev,
memset(&spi_pdata, 0, sizeof(spi_pdata));
spi_pdata.num_chipselect = (c->num_chipselect > 0) ?
c->num_chipselect : dev->devfn;
- spi_pdata.tx_slave_id = c->tx_slave_id;
- spi_pdata.tx_chan_id = c->tx_chan_id;
- spi_pdata.rx_slave_id = c->rx_slave_id;
- spi_pdata.rx_chan_id = c->rx_chan_id;
- spi_pdata.enable_dma = c->rx_slave_id >= 0 && c->tx_slave_id >= 0;
+
+ dma_dev = pci_get_slot(dev->bus, PCI_DEVFN(PCI_SLOT(dev->devfn), 0));
+
+ if (c->tx_param) {
+ struct dw_dma_slave *slave = c->tx_param;
+
+ slave->dma_dev = &dma_dev->dev;
+ slave->src_master = 1;
+ slave->dst_master = 0;
+ }
+
+ if (c->rx_param) {
+ struct dw_dma_slave *slave = c->rx_param;
+
+ slave->dma_dev = &dma_dev->dev;
+ slave->src_master = 1;
+ slave->dst_master = 0;
+ }
+
+ spi_pdata.dma_filter = lpss_dma_filter;
+ spi_pdata.tx_param = c->tx_param;
+ spi_pdata.rx_param = c->rx_param;
+ spi_pdata.enable_dma = c->rx_param && c->tx_param;
ssp = &spi_pdata.ssp;
ssp->phys_base = pci_resource_start(dev, 0);
@@ -128,6 +192,9 @@ static void pxa2xx_spi_pci_remove(struct pci_dev *dev)
static const struct pci_device_id pxa2xx_spi_pci_devices[] = {
{ PCI_VDEVICE(INTEL, 0x2e6a), PORT_CE4100 },
{ PCI_VDEVICE(INTEL, 0x0f0e), PORT_BYT },
+ { PCI_VDEVICE(INTEL, 0x228e), PORT_BSW0 },
+ { PCI_VDEVICE(INTEL, 0x2290), PORT_BSW1 },
+ { PCI_VDEVICE(INTEL, 0x22ac), PORT_BSW2 },
{ },
};
MODULE_DEVICE_TABLE(pci, pxa2xx_spi_pci_devices);
diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c
index 46f45ca..d8a105f 100644
--- a/drivers/spi/spi-pxa2xx.c
+++ b/drivers/spi/spi-pxa2xx.c
@@ -1062,8 +1062,6 @@ pxa2xx_spi_acpi_get_pdata(struct platform_device *pdev)
pdata->num_chipselect = 1;
pdata->enable_dma = true;
- pdata->tx_chan_id = -1;
- pdata->rx_chan_id = -1;
return pdata;
}
OpenPOWER on IntegriCloud