Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9a4506b6 authored by Mark Brown's avatar Mark Brown
Browse files

Merge remote-tracking branches 'spi/topic/pxa2xx', 'spi/topic/rockchip',...

Merge remote-tracking branches 'spi/topic/pxa2xx', 'spi/topic/rockchip', 'spi/topic/s3c64xx', 'spi/topic/sh' and 'spi/topic/sh-msiof' into spi-next
Loading
Loading
Loading
Loading
+7 −4
Original line number Diff line number Diff line
@@ -6,10 +6,13 @@ and display controllers using the SPI communication interface.
Required Properties:

- compatible: should be one of the following.
    "rockchip,rk3066-spi" for rk3066.
    "rockchip,rk3188-spi", "rockchip,rk3066-spi" for rk3188.
    "rockchip,rk3288-spi", "rockchip,rk3066-spi" for rk3288.
    "rockchip,rk3399-spi", "rockchip,rk3066-spi" for rk3399.
    "rockchip,rk3036-spi" for rk3036 SoCS.
    "rockchip,rk3066-spi" for rk3066 SoCs.
    "rockchip,rk3188-spi" for rk3188 SoCs.
    "rockchip,rk3228-spi" for rk3228 SoCS.
    "rockchip,rk3288-spi" for rk3288 SoCs.
    "rockchip,rk3368-spi" for rk3368 SoCs.
    "rockchip,rk3399-spi" for rk3399 SoCs.
- reg: physical base address of the controller and length of memory mapped
       region.
- interrupts: The interrupt number to the cpu. The interrupt specifier format
+14 −1
Original line number Diff line number Diff line
@@ -9,7 +9,8 @@ Required SoC Specific Properties:
    - samsung,s3c2443-spi: for s3c2443, s3c2416 and s3c2450 platforms
    - samsung,s3c6410-spi: for s3c6410 platforms
    - samsung,s5pv210-spi: for s5pv210 and s5pc110 platforms
    - samsung,exynos7-spi: for exynos7 platforms
    - samsung,exynos5433-spi: for exynos5433 compatible controllers
    - samsung,exynos7-spi: for exynos7 platforms <DEPRECATED>

- reg: physical base address of the controller and length of memory mapped
  region.
@@ -23,6 +24,15 @@ Required SoC Specific Properties:
- dma-names: Names for the dma channels. There must be at least one channel
  named "tx" for transmit and named "rx" for receive.

- clocks: specifies the clock IDs provided to the SPI controller; they are
  required for interacting with the controller itself, for synchronizing the bus
  and as I/O clock (the latter is required by exynos5433 and exynos7).

- clock-names: string names of the clocks in the 'clocks' property; for all the
  the devices the names must be "spi", "spi_busclkN" (where N is determined by
  "samsung,spi-src-clk"), while Exynos5433 should specify a third clock
  "spi_ioclk" for the I/O clock.

Required Board Specific Properties:

- #address-cells: should be 1.
@@ -40,6 +50,9 @@ Optional Board Specific Properties:

- cs-gpios: should specify GPIOs used for chipselects (see spi-bus.txt)

- no-cs-readback: the CS line is disconnected, therefore the device should not
  operate based on CS signalling.

SPI Controller specific data in SPI slave nodes:

- The spi slave nodes should provide the following information which is required
+29 −141
Original line number Diff line number Diff line
@@ -20,79 +20,6 @@

#include "spi-pxa2xx.h"

static int pxa2xx_spi_map_dma_buffer(struct driver_data *drv_data,
				     enum dma_data_direction dir)
{
	int i, nents, len = drv_data->len;
	struct scatterlist *sg;
	struct device *dmadev;
	struct sg_table *sgt;
	void *buf, *pbuf;

	if (dir == DMA_TO_DEVICE) {
		dmadev = drv_data->tx_chan->device->dev;
		sgt = &drv_data->tx_sgt;
		buf = drv_data->tx;
	} else {
		dmadev = drv_data->rx_chan->device->dev;
		sgt = &drv_data->rx_sgt;
		buf = drv_data->rx;
	}

	nents = DIV_ROUND_UP(len, SZ_2K);
	if (nents != sgt->nents) {
		int ret;

		sg_free_table(sgt);
		ret = sg_alloc_table(sgt, nents, GFP_ATOMIC);
		if (ret)
			return ret;
	}

	pbuf = buf;
	for_each_sg(sgt->sgl, sg, sgt->nents, i) {
		size_t bytes = min_t(size_t, len, SZ_2K);

		sg_set_buf(sg, pbuf, bytes);
		pbuf += bytes;
		len -= bytes;
	}

	nents = dma_map_sg(dmadev, sgt->sgl, sgt->nents, dir);
	if (!nents)
		return -ENOMEM;

	return nents;
}

static void pxa2xx_spi_unmap_dma_buffer(struct driver_data *drv_data,
					enum dma_data_direction dir)
{
	struct device *dmadev;
	struct sg_table *sgt;

	if (dir == DMA_TO_DEVICE) {
		dmadev = drv_data->tx_chan->device->dev;
		sgt = &drv_data->tx_sgt;
	} else {
		dmadev = drv_data->rx_chan->device->dev;
		sgt = &drv_data->rx_sgt;
	}

	dma_unmap_sg(dmadev, sgt->sgl, sgt->nents, dir);
}

static void pxa2xx_spi_unmap_dma_buffers(struct driver_data *drv_data)
{
	if (!drv_data->dma_mapped)
		return;

	pxa2xx_spi_unmap_dma_buffer(drv_data, DMA_FROM_DEVICE);
	pxa2xx_spi_unmap_dma_buffer(drv_data, DMA_TO_DEVICE);

	drv_data->dma_mapped = 0;
}

static void pxa2xx_spi_dma_transfer_complete(struct driver_data *drv_data,
					     bool error)
{
@@ -125,8 +52,6 @@ static void pxa2xx_spi_dma_transfer_complete(struct driver_data *drv_data,
			pxa2xx_spi_write(drv_data, SSTO, 0);

		if (!error) {
			pxa2xx_spi_unmap_dma_buffers(drv_data);

			msg->actual_length += drv_data->len;
			msg->state = pxa2xx_spi_next_transfer(drv_data);
		} else {
@@ -152,11 +77,12 @@ pxa2xx_spi_dma_prepare_one(struct driver_data *drv_data,
			   enum dma_transfer_direction dir)
{
	struct chip_data *chip = drv_data->cur_chip;
	struct spi_transfer *xfer = drv_data->cur_transfer;
	enum dma_slave_buswidth width;
	struct dma_slave_config cfg;
	struct dma_chan *chan;
	struct sg_table *sgt;
	int nents, ret;
	int ret;

	switch (drv_data->n_bytes) {
	case 1:
@@ -178,17 +104,15 @@ pxa2xx_spi_dma_prepare_one(struct driver_data *drv_data,
		cfg.dst_addr_width = width;
		cfg.dst_maxburst = chip->dma_burst_size;

		sgt = &drv_data->tx_sgt;
		nents = drv_data->tx_nents;
		chan = drv_data->tx_chan;
		sgt = &xfer->tx_sg;
		chan = drv_data->master->dma_tx;
	} else {
		cfg.src_addr = drv_data->ssdr_physical;
		cfg.src_addr_width = width;
		cfg.src_maxburst = chip->dma_burst_size;

		sgt = &drv_data->rx_sgt;
		nents = drv_data->rx_nents;
		chan = drv_data->rx_chan;
		sgt = &xfer->rx_sg;
		chan = drv_data->master->dma_rx;
	}

	ret = dmaengine_slave_config(chan, &cfg);
@@ -197,46 +121,10 @@ pxa2xx_spi_dma_prepare_one(struct driver_data *drv_data,
		return NULL;
	}

	return dmaengine_prep_slave_sg(chan, sgt->sgl, nents, dir,
	return dmaengine_prep_slave_sg(chan, sgt->sgl, sgt->nents, dir,
				       DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
}

bool pxa2xx_spi_dma_is_possible(size_t len)
{
	return len <= MAX_DMA_LEN;
}

int pxa2xx_spi_map_dma_buffers(struct driver_data *drv_data)
{
	const struct chip_data *chip = drv_data->cur_chip;
	int ret;

	if (!chip->enable_dma)
		return 0;

	/* Don't bother with DMA if we can't do even a single burst */
	if (drv_data->len < chip->dma_burst_size)
		return 0;

	ret = pxa2xx_spi_map_dma_buffer(drv_data, DMA_TO_DEVICE);
	if (ret <= 0) {
		dev_warn(&drv_data->pdev->dev, "failed to DMA map TX\n");
		return 0;
	}

	drv_data->tx_nents = ret;

	ret = pxa2xx_spi_map_dma_buffer(drv_data, DMA_FROM_DEVICE);
	if (ret <= 0) {
		pxa2xx_spi_unmap_dma_buffer(drv_data, DMA_TO_DEVICE);
		dev_warn(&drv_data->pdev->dev, "failed to DMA map RX\n");
		return 0;
	}

	drv_data->rx_nents = ret;
	return 1;
}

irqreturn_t pxa2xx_spi_dma_transfer(struct driver_data *drv_data)
{
	u32 status;
@@ -245,8 +133,8 @@ irqreturn_t pxa2xx_spi_dma_transfer(struct driver_data *drv_data)
	if (status & SSSR_ROR) {
		dev_err(&drv_data->pdev->dev, "FIFO overrun\n");

		dmaengine_terminate_async(drv_data->rx_chan);
		dmaengine_terminate_async(drv_data->tx_chan);
		dmaengine_terminate_async(drv_data->master->dma_rx);
		dmaengine_terminate_async(drv_data->master->dma_tx);

		pxa2xx_spi_dma_transfer_complete(drv_data, true);
		return IRQ_HANDLED;
@@ -285,16 +173,15 @@ int pxa2xx_spi_dma_prepare(struct driver_data *drv_data, u32 dma_burst)
	return 0;

err_rx:
	dmaengine_terminate_async(drv_data->tx_chan);
	dmaengine_terminate_async(drv_data->master->dma_tx);
err_tx:
	pxa2xx_spi_unmap_dma_buffers(drv_data);
	return err;
}

void pxa2xx_spi_dma_start(struct driver_data *drv_data)
{
	dma_async_issue_pending(drv_data->rx_chan);
	dma_async_issue_pending(drv_data->tx_chan);
	dma_async_issue_pending(drv_data->master->dma_rx);
	dma_async_issue_pending(drv_data->master->dma_tx);

	atomic_set(&drv_data->dma_running, 1);
}
@@ -303,21 +190,22 @@ int pxa2xx_spi_dma_setup(struct driver_data *drv_data)
{
	struct pxa2xx_spi_master *pdata = drv_data->master_info;
	struct device *dev = &drv_data->pdev->dev;
	struct spi_master *master = drv_data->master;
	dma_cap_mask_t mask;

	dma_cap_zero(mask);
	dma_cap_set(DMA_SLAVE, mask);

	drv_data->tx_chan = dma_request_slave_channel_compat(mask,
	master->dma_tx = dma_request_slave_channel_compat(mask,
				pdata->dma_filter, pdata->tx_param, dev, "tx");
	if (!drv_data->tx_chan)
	if (!master->dma_tx)
		return -ENODEV;

	drv_data->rx_chan = dma_request_slave_channel_compat(mask,
	master->dma_rx = dma_request_slave_channel_compat(mask,
				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;
	if (!master->dma_rx) {
		dma_release_channel(master->dma_tx);
		master->dma_tx = NULL;
		return -ENODEV;
	}

@@ -326,17 +214,17 @@ int pxa2xx_spi_dma_setup(struct driver_data *drv_data)

void pxa2xx_spi_dma_release(struct driver_data *drv_data)
{
	if (drv_data->rx_chan) {
		dmaengine_terminate_sync(drv_data->rx_chan);
		dma_release_channel(drv_data->rx_chan);
		sg_free_table(&drv_data->rx_sgt);
		drv_data->rx_chan = NULL;
	struct spi_master *master = drv_data->master;

	if (master->dma_rx) {
		dmaengine_terminate_sync(master->dma_rx);
		dma_release_channel(master->dma_rx);
		master->dma_rx = NULL;
	}
	if (drv_data->tx_chan) {
		dmaengine_terminate_sync(drv_data->tx_chan);
		dma_release_channel(drv_data->tx_chan);
		sg_free_table(&drv_data->tx_sgt);
		drv_data->tx_chan = NULL;
	if (master->dma_tx) {
		dmaengine_terminate_sync(master->dma_tx);
		dma_release_channel(master->dma_tx);
		master->dma_tx = NULL;
	}
}

+82 −46
Original line number Diff line number Diff line
/*
 * CE4100's SPI device is more or less the same one as found on PXA
 *
 * Copyright (C) 2016, Intel Corporation
 */
#include <linux/clk-provider.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/of_device.h>
#include <linux/module.h>
#include <linux/spi/pxa2xx_spi.h>
#include <linux/clk-provider.h>

#include <linux/dmaengine.h>
#include <linux/platform_data/dma-dw.h>

enum {
	PORT_CE4100,
	PORT_QUARK_X1000,
	PORT_BYT,
	PORT_MRFLD,
	PORT_BSW0,
	PORT_BSW1,
	PORT_BSW2,
	PORT_QUARK_X1000,
	PORT_CE4100,
	PORT_LPT,
};

@@ -29,8 +31,11 @@ struct pxa_spi_info {
	unsigned long max_clk_rate;

	/* DMA channel request parameters */
	bool (*dma_filter)(struct dma_chan *chan, void *param);
	void *tx_param;
	void *rx_param;

	int (*setup)(struct pci_dev *pdev, struct pxa_spi_info *c);
};

static struct dw_dma_slave byt_tx_param = { .dst_id = 0 };
@@ -57,6 +62,56 @@ static bool lpss_dma_filter(struct dma_chan *chan, void *param)
	return true;
}

static int lpss_spi_setup(struct pci_dev *dev, struct pxa_spi_info *c)
{
	struct pci_dev *dma_dev;

	c->num_chipselect = 1;
	c->max_clk_rate = 50000000;

	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->m_master = 0;
		slave->p_master = 1;
	}

	if (c->rx_param) {
		struct dw_dma_slave *slave = c->rx_param;

		slave->dma_dev = &dma_dev->dev;
		slave->m_master = 0;
		slave->p_master = 1;
	}

	c->dma_filter = lpss_dma_filter;
	return 0;
}

static int mrfld_spi_setup(struct pci_dev *dev, struct pxa_spi_info *c)
{
	switch (PCI_FUNC(dev->devfn)) {
	case 0:
		c->port_id = 3;
		c->num_chipselect = 1;
		break;
	case 1:
		c->port_id = 5;
		c->num_chipselect = 4;
		break;
	case 2:
		c->port_id = 6;
		c->num_chipselect = 1;
		break;
	default:
		return -ENODEV;
	}
	return 0;
}

static struct pxa_spi_info spi_info_configs[] = {
	[PORT_CE4100] = {
		.type = PXA25x_SSP,
@@ -67,35 +122,36 @@ static struct pxa_spi_info spi_info_configs[] = {
	[PORT_BYT] = {
		.type = LPSS_BYT_SSP,
		.port_id = 0,
		.num_chipselect = 1,
		.max_clk_rate = 50000000,
		.setup = lpss_spi_setup,
		.tx_param = &byt_tx_param,
		.rx_param = &byt_rx_param,
	},
	[PORT_BSW0] = {
		.type = LPSS_BYT_SSP,
		.type = LPSS_BSW_SSP,
		.port_id = 0,
		.num_chipselect = 1,
		.max_clk_rate = 50000000,
		.setup = lpss_spi_setup,
		.tx_param = &bsw0_tx_param,
		.rx_param = &bsw0_rx_param,
	},
	[PORT_BSW1] = {
		.type = LPSS_BYT_SSP,
		.type = LPSS_BSW_SSP,
		.port_id = 1,
		.num_chipselect = 1,
		.max_clk_rate = 50000000,
		.setup = lpss_spi_setup,
		.tx_param = &bsw1_tx_param,
		.rx_param = &bsw1_rx_param,
	},
	[PORT_BSW2] = {
		.type = LPSS_BYT_SSP,
		.type = LPSS_BSW_SSP,
		.port_id = 2,
		.num_chipselect = 1,
		.max_clk_rate = 50000000,
		.setup = lpss_spi_setup,
		.tx_param = &bsw2_tx_param,
		.rx_param = &bsw2_rx_param,
	},
	[PORT_MRFLD] = {
		.type = PXA27x_SSP,
		.max_clk_rate = 25000000,
		.setup = mrfld_spi_setup,
	},
	[PORT_QUARK_X1000] = {
		.type = QUARK_X1000_SSP,
		.port_id = -1,
@@ -105,8 +161,7 @@ static struct pxa_spi_info spi_info_configs[] = {
	[PORT_LPT] = {
		.type = LPSS_LPT_SSP,
		.port_id = 0,
		.num_chipselect = 1,
		.max_clk_rate = 50000000,
		.setup = lpss_spi_setup,
		.tx_param = &lpt_tx_param,
		.rx_param = &lpt_rx_param,
	},
@@ -122,7 +177,6 @@ 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)
@@ -133,30 +187,15 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev,
		return ret;

	c = &spi_info_configs[ent->driver_data];

	memset(&spi_pdata, 0, sizeof(spi_pdata));
	spi_pdata.num_chipselect = (c->num_chipselect > 0) ?
					c->num_chipselect : dev->devfn;

	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->m_master = 0;
		slave->p_master = 1;
	}

	if (c->rx_param) {
		struct dw_dma_slave *slave = c->rx_param;

		slave->dma_dev = &dma_dev->dev;
		slave->m_master = 0;
		slave->p_master = 1;
	if (c->setup) {
		ret = c->setup(dev, c);
		if (ret)
			return ret;
	}

	spi_pdata.dma_filter = lpss_dma_filter;
	memset(&spi_pdata, 0, sizeof(spi_pdata));
	spi_pdata.num_chipselect = (c->num_chipselect > 0) ? c->num_chipselect : dev->devfn;
	spi_pdata.dma_filter = c->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;
@@ -164,10 +203,6 @@ static int pxa2xx_spi_pci_probe(struct pci_dev *dev,
	ssp = &spi_pdata.ssp;
	ssp->phys_base = pci_resource_start(dev, 0);
	ssp->mmio_base = pcim_iomap_table(dev)[0];
	if (!ssp->mmio_base) {
		dev_err(&dev->dev, "failed to ioremap() registers\n");
		return -EIO;
	}
	ssp->irq = dev->irq;
	ssp->port_id = (c->port_id >= 0) ? c->port_id : dev->devfn;
	ssp->type = c->type;
@@ -208,12 +243,13 @@ 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, 0x0935), PORT_QUARK_X1000 },
	{ PCI_VDEVICE(INTEL, 0x0f0e), PORT_BYT },
	{ PCI_VDEVICE(INTEL, 0x1194), PORT_MRFLD },
	{ PCI_VDEVICE(INTEL, 0x228e), PORT_BSW0 },
	{ PCI_VDEVICE(INTEL, 0x2290), PORT_BSW1 },
	{ PCI_VDEVICE(INTEL, 0x22ac), PORT_BSW2 },
	{ PCI_VDEVICE(INTEL, 0x2e6a), PORT_CE4100 },
	{ PCI_VDEVICE(INTEL, 0x9ce6), PORT_LPT },
	{ },
};
+28 −18
Original line number Diff line number Diff line
@@ -919,9 +919,21 @@ static unsigned int pxa2xx_ssp_get_clk_div(struct driver_data *drv_data,
	return clk_div << 8;
}

static bool pxa2xx_spi_can_dma(struct spi_master *master,
			       struct spi_device *spi,
			       struct spi_transfer *xfer)
{
	struct chip_data *chip = spi_get_ctldata(spi);

	return chip->enable_dma &&
	       xfer->len <= MAX_DMA_LEN &&
	       xfer->len >= chip->dma_burst_size;
}

static void pump_transfers(unsigned long data)
{
	struct driver_data *drv_data = (struct driver_data *)data;
	struct spi_master *master = drv_data->master;
	struct spi_message *message = NULL;
	struct spi_transfer *transfer = NULL;
	struct spi_transfer *previous = NULL;
@@ -935,6 +947,7 @@ static void pump_transfers(unsigned long data)
	u32 dma_burst = drv_data->cur_chip->dma_burst_size;
	u32 change_mask = pxa2xx_spi_get_ssrc1_change_mask(drv_data);
	int err;
	int dma_mapped;

	/* Get current state information */
	message = drv_data->cur_msg;
@@ -969,7 +982,7 @@ static void pump_transfers(unsigned long data)
	}

	/* Check if we can DMA this transfer */
	if (!pxa2xx_spi_dma_is_possible(transfer->len) && chip->enable_dma) {
	if (transfer->len > MAX_DMA_LEN && chip->enable_dma) {

		/* reject already-mapped transfers; PIO won't always work */
		if (message->is_dma_mapped
@@ -1046,10 +1059,10 @@ static void pump_transfers(unsigned long data)

	message->state = RUNNING_STATE;

	drv_data->dma_mapped = 0;
	if (pxa2xx_spi_dma_is_possible(drv_data->len))
		drv_data->dma_mapped = pxa2xx_spi_map_dma_buffers(drv_data);
	if (drv_data->dma_mapped) {
	dma_mapped = master->can_dma &&
		     master->can_dma(master, message->spi, transfer) &&
		     master->cur_msg_mapped;
	if (dma_mapped) {

		/* Ensure we have the correct interrupt handler */
		drv_data->transfer_handler = pxa2xx_spi_dma_transfer;
@@ -1079,14 +1092,14 @@ static void pump_transfers(unsigned long data)
	cr0 = pxa2xx_configure_sscr0(drv_data, clk_div, bits);
	if (!pxa25x_ssp_comp(drv_data))
		dev_dbg(&message->spi->dev, "%u Hz actual, %s\n",
			drv_data->master->max_speed_hz
			master->max_speed_hz
				/ (1 + ((cr0 & SSCR0_SCR(0xfff)) >> 8)),
			drv_data->dma_mapped ? "DMA" : "PIO");
			dma_mapped ? "DMA" : "PIO");
	else
		dev_dbg(&message->spi->dev, "%u Hz actual, %s\n",
			drv_data->master->max_speed_hz / 2
			master->max_speed_hz / 2
				/ (1 + ((cr0 & SSCR0_SCR(0x0ff)) >> 8)),
			drv_data->dma_mapped ? "DMA" : "PIO");
			dma_mapped ? "DMA" : "PIO");

	if (is_lpss_ssp(drv_data)) {
		if ((pxa2xx_spi_read(drv_data, SSIRF) & 0xff)
@@ -1247,7 +1260,7 @@ static int setup(struct spi_device *spi)
			chip->frm = spi->chip_select;
		} else
			chip->gpio_cs = -1;
		chip->enable_dma = 0;
		chip->enable_dma = drv_data->master_info->enable_dma;
		chip->timeout = TIMOUT_DFLT;
	}

@@ -1266,17 +1279,9 @@ static int setup(struct spi_device *spi)
			tx_hi_thres = chip_info->tx_hi_threshold;
		if (chip_info->rx_threshold)
			rx_thres = chip_info->rx_threshold;
		chip->enable_dma = drv_data->master_info->enable_dma;
		chip->dma_threshold = 0;
		if (chip_info->enable_loopback)
			chip->cr1 = SSCR1_LBM;
	} else if (ACPI_HANDLE(&spi->dev)) {
		/*
		 * Slave devices enumerated from ACPI namespace don't
		 * usually have chip_info but we still might want to use
		 * DMA with them.
		 */
		chip->enable_dma = drv_data->master_info->enable_dma;
	}

	chip->lpss_rx_threshold = SSIRF_RxThresh(rx_thres);
@@ -1396,6 +1401,9 @@ static const struct pci_device_id pxa2xx_spi_pci_compound_match[] = {
	/* SPT-H */
	{ PCI_VDEVICE(INTEL, 0xa129), LPSS_SPT_SSP },
	{ PCI_VDEVICE(INTEL, 0xa12a), LPSS_SPT_SSP },
	/* KBL-H */
	{ PCI_VDEVICE(INTEL, 0xa2a9), LPSS_SPT_SSP },
	{ PCI_VDEVICE(INTEL, 0xa2aa), LPSS_SPT_SSP },
	/* BXT A-Step */
	{ PCI_VDEVICE(INTEL, 0x0ac2), LPSS_BXT_SSP },
	{ PCI_VDEVICE(INTEL, 0x0ac4), LPSS_BXT_SSP },
@@ -1608,6 +1616,8 @@ static int pxa2xx_spi_probe(struct platform_device *pdev)
		if (status) {
			dev_dbg(dev, "no DMA channels available, using PIO\n");
			platform_info->enable_dma = false;
		} else {
			master->can_dma = pxa2xx_spi_can_dma;
		}
	}

Loading