aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/spi/spi-davinci.txt30
-rw-r--r--Documentation/spi/spi-summary6
-rw-r--r--drivers/spi/Kconfig2
-rw-r--r--drivers/spi/spi-davinci.c55
-rw-r--r--drivers/spi/spi-dw-mid.c65
-rw-r--r--drivers/spi/spi-dw-pci.c67
-rw-r--r--drivers/spi/spi-dw.c48
-rw-r--r--drivers/spi/spi-dw.h11
-rw-r--r--drivers/spi/spi-fsl-cpm.c14
-rw-r--r--drivers/spi/spi-fsl-dspi.c18
-rw-r--r--drivers/spi/spi-fsl-espi.c12
-rw-r--r--drivers/spi/spi-fsl-lib.c6
-rw-r--r--drivers/spi/spi-fsl-spi.c22
13 files changed, 211 insertions, 145 deletions
diff --git a/Documentation/devicetree/bindings/spi/spi-davinci.txt b/Documentation/devicetree/bindings/spi/spi-davinci.txt
index f80887bca0d6..12ecfe9e3599 100644
--- a/Documentation/devicetree/bindings/spi/spi-davinci.txt
+++ b/Documentation/devicetree/bindings/spi/spi-davinci.txt
@@ -1,5 +1,10 @@
Davinci SPI controller device bindings
+Links on DM:
+Keystone 2 - http://www.ti.com/lit/ug/sprugp2a/sprugp2a.pdf
+dm644x - http://www.ti.com/lit/ug/sprue32a/sprue32a.pdf
+OMAP-L138/da830 - http://www.ti.com/lit/ug/spruh77a/spruh77a.pdf
+
Required properties:
- #address-cells: number of cells required to define a chip select
address on the SPI bus. Should be set to 1.
@@ -24,6 +29,30 @@ Optional:
cs-gpios = <0>, <0>, <0>, <&gpio1 30 0>, <&gpio1 31 0>;
where first three are internal CS and last two are GPIO CS.
+Optional properties for slave devices:
+SPI slave nodes can contain the following properties.
+Not all SPI Peripherals from Texas Instruments support this.
+Please check SPI peripheral documentation for a device before using these.
+
+- ti,spi-wdelay : delay between transmission of words
+ (SPIFMTn.WDELAY, SPIDAT1.WDEL) must be specified in number of SPI module
+ clock periods.
+
+ delay = WDELAY * SPI_module_clock_period + 2 * SPI_module_clock_period
+
+Below is timing diagram which shows functional meaning of
+"ti,spi-wdelay" parameter.
+
+ +-+ +-+ +-+ +-+ +-+ +-+ +-+ +-+
+SPI_CLK | | | | | | | | | | | | | | | |
+ +----------+ +-+ +-+ +-+ +-+ +---------------------------+ +-+ +-+ +-
+
+SPI_SOMI/SIMO+-----------------+ +-----------
+ +----------+ word1 +---------------------------+word2
+ +-----------------+ +-----------
+ WDELAY
+ <-------------------------->
+
Example of a NOR flash slave device (n25q032) connected to DaVinci
SPI controller device over the SPI bus.
@@ -43,6 +72,7 @@ spi0:spi@20BF0000 {
compatible = "st,m25p32";
spi-max-frequency = <25000000>;
reg = <0>;
+ ti,spi-wdelay = <8>;
partition@0 {
label = "u-boot-spl";
diff --git a/Documentation/spi/spi-summary b/Documentation/spi/spi-summary
index 7982bcc4d151..d29734bff28c 100644
--- a/Documentation/spi/spi-summary
+++ b/Documentation/spi/spi-summary
@@ -601,13 +601,13 @@ THANKS TO
Contributors to Linux-SPI discussions include (in alphabetical order,
by last name):
+Mark Brown
David Brownell
Russell King
+Grant Likely
Dmitry Pervushin
Stephen Street
Mark Underwood
Andrew Victor
-Vitaly Wool
-Grant Likely
-Mark Brown
Linus Walleij
+Vitaly Wool
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index a862a1c8eb29..c4f19887987b 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -602,7 +602,7 @@ config SPI_DW_PCI
depends on SPI_DESIGNWARE && PCI
config SPI_DW_MID_DMA
- bool "DMA support for DW SPI controller on Intel Moorestown platform"
+ bool "DMA support for DW SPI controller on Intel MID platform"
depends on SPI_DW_PCI && INTEL_MID_DMAC
config SPI_DW_MMIO
diff --git a/drivers/spi/spi-davinci.c b/drivers/spi/spi-davinci.c
index 63c82a61c975..63700ab7bd9f 100644
--- a/drivers/spi/spi-davinci.c
+++ b/drivers/spi/spi-davinci.c
@@ -65,6 +65,7 @@
/* SPIDAT1 (upper 16 bit defines) */
#define SPIDAT1_CSHOLD_MASK BIT(12)
+#define SPIDAT1_WDEL BIT(10)
/* SPIGCR1 */
#define SPIGCR1_CLKMOD_MASK BIT(1)
@@ -213,6 +214,7 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value)
{
struct davinci_spi *dspi;
struct davinci_spi_platform_data *pdata;
+ struct davinci_spi_config *spicfg = spi->controller_data;
u8 chip_sel = spi->chip_select;
u16 spidat1 = CS_DEFAULT;
bool gpio_chipsel = false;
@@ -227,6 +229,10 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value)
gpio = spi->cs_gpio;
}
+ /* program delay transfers if tx_delay is non zero */
+ if (spicfg->wdelay)
+ spidat1 |= SPIDAT1_WDEL;
+
/*
* Board specific chip select logic decides the polarity and cs
* line for the controller
@@ -241,9 +247,9 @@ static void davinci_spi_chipselect(struct spi_device *spi, int value)
spidat1 |= SPIDAT1_CSHOLD_MASK;
spidat1 &= ~(0x1 << chip_sel);
}
-
- iowrite16(spidat1, dspi->base + SPIDAT1 + 2);
}
+
+ iowrite16(spidat1, dspi->base + SPIDAT1 + 2);
}
/**
@@ -289,7 +295,7 @@ static int davinci_spi_setup_transfer(struct spi_device *spi,
int prescale;
dspi = spi_master_get_devdata(spi->master);
- spicfg = (struct davinci_spi_config *)spi->controller_data;
+ spicfg = spi->controller_data;
if (!spicfg)
spicfg = &davinci_spi_default_cfg;
@@ -337,6 +343,14 @@ static int davinci_spi_setup_transfer(struct spi_device *spi,
spifmt |= SPIFMT_PHASE_MASK;
/*
+ * Assume wdelay is used only on SPI peripherals that has this field
+ * in SPIFMTn register and when it's configured from board file or DT.
+ */
+ if (spicfg->wdelay)
+ spifmt |= ((spicfg->wdelay << SPIFMT_WDELAY_SHIFT)
+ & SPIFMT_WDELAY_MASK);
+
+ /*
* Version 1 hardware supports two basic SPI modes:
* - Standard SPI mode uses 4 pins, with chipselect
* - 3 pin SPI is a 4 pin variant without CS (SPI_NO_CS)
@@ -353,9 +367,6 @@ static int davinci_spi_setup_transfer(struct spi_device *spi,
u32 delay = 0;
- spifmt |= ((spicfg->wdelay << SPIFMT_WDELAY_SHIFT)
- & SPIFMT_WDELAY_MASK);
-
if (spicfg->odd_parity)
spifmt |= SPIFMT_ODD_PARITY_MASK;
@@ -387,6 +398,26 @@ static int davinci_spi_setup_transfer(struct spi_device *spi,
return 0;
}
+static int davinci_spi_of_setup(struct spi_device *spi)
+{
+ struct davinci_spi_config *spicfg = spi->controller_data;
+ struct device_node *np = spi->dev.of_node;
+ u32 prop;
+
+ if (spicfg == NULL && np) {
+ spicfg = kzalloc(sizeof(*spicfg), GFP_KERNEL);
+ if (!spicfg)
+ return -ENOMEM;
+ *spicfg = davinci_spi_default_cfg;
+ /* override with dt configured values */
+ if (!of_property_read_u32(np, "ti,spi-wdelay", &prop))
+ spicfg->wdelay = (u8)prop;
+ spi->controller_data = spicfg;
+ }
+
+ return 0;
+}
+
/**
* davinci_spi_setup - This functions will set default transfer method
* @spi: spi device on which data transfer to be done
@@ -437,7 +468,16 @@ static int davinci_spi_setup(struct spi_device *spi)
else
clear_io_bits(dspi->base + SPIGCR1, SPIGCR1_LOOPBACK_MASK);
- return retval;
+ return davinci_spi_of_setup(spi);
+}
+
+static void davinci_spi_cleanup(struct spi_device *spi)
+{
+ struct davinci_spi_config *spicfg = spi->controller_data;
+
+ spi->controller_data = NULL;
+ if (spi->dev.of_node)
+ kfree(spicfg);
}
static int davinci_spi_check_error(struct davinci_spi *dspi, int int_status)
@@ -951,6 +991,7 @@ static int davinci_spi_probe(struct platform_device *pdev)
master->num_chipselect = pdata->num_chipselect;
master->bits_per_word_mask = SPI_BPW_RANGE_MASK(2, 16);
master->setup = davinci_spi_setup;
+ master->cleanup = davinci_spi_cleanup;
dspi->bitbang.chipselect = davinci_spi_chipselect;
dspi->bitbang.setup_transfer = davinci_spi_setup_transfer;
diff --git a/drivers/spi/spi-dw-mid.c b/drivers/spi/spi-dw-mid.c
index 6d207afec8cb..46c6d58e1fda 100644
--- a/drivers/spi/spi-dw-mid.c
+++ b/drivers/spi/spi-dw-mid.c
@@ -1,7 +1,7 @@
/*
* Special handling for DW core on Intel MID platform
*
- * Copyright (c) 2009, Intel Corporation.
+ * Copyright (c) 2009, 2014 Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -11,10 +11,6 @@
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <linux/dma-mapping.h>
@@ -39,22 +35,25 @@ static bool mid_spi_dma_chan_filter(struct dma_chan *chan, void *param)
{
struct dw_spi *dws = param;
- return dws->dmac && (&dws->dmac->dev == chan->device->dev);
+ return dws->dma_dev == chan->device->dev;
}
static int mid_spi_dma_init(struct dw_spi *dws)
{
struct mid_dma *dw_dma = dws->dma_priv;
+ struct pci_dev *dma_dev;
struct intel_mid_dma_slave *rxs, *txs;
dma_cap_mask_t mask;
/*
* Get pci device for DMA controller, currently it could only
- * be the DMA controller of either Moorestown or Medfield
+ * be the DMA controller of Medfield
*/
- dws->dmac = pci_get_device(PCI_VENDOR_ID_INTEL, 0x0813, NULL);
- if (!dws->dmac)
- dws->dmac = pci_get_device(PCI_VENDOR_ID_INTEL, 0x0827, NULL);
+ dma_dev = pci_get_device(PCI_VENDOR_ID_INTEL, 0x0827, NULL);
+ if (!dma_dev)
+ return -ENODEV;
+
+ dws->dma_dev = &dma_dev->dev;
dma_cap_zero(mask);
dma_cap_set(DMA_SLAVE, mask);
@@ -83,13 +82,18 @@ static int mid_spi_dma_init(struct dw_spi *dws)
free_rxchan:
dma_release_channel(dws->rxchan);
err_exit:
- return -1;
-
+ return -EBUSY;
}
static void mid_spi_dma_exit(struct dw_spi *dws)
{
+ if (!dws->dma_inited)
+ return;
+
+ dmaengine_terminate_all(dws->txchan);
dma_release_channel(dws->txchan);
+
+ dmaengine_terminate_all(dws->rxchan);
dma_release_channel(dws->rxchan);
}
@@ -109,8 +113,7 @@ static void dw_spi_dma_done(void *arg)
static int mid_spi_dma_transfer(struct dw_spi *dws, int cs_change)
{
- struct dma_async_tx_descriptor *txdesc = NULL, *rxdesc = NULL;
- struct dma_chan *txchan, *rxchan;
+ struct dma_async_tx_descriptor *txdesc, *rxdesc;
struct dma_slave_config txconf, rxconf;
u16 dma_ctrl = 0;
@@ -120,37 +123,34 @@ static int mid_spi_dma_transfer(struct dw_spi *dws, int cs_change)
dw_writew(dws, DW_SPI_DMARDLR, 0xf);
dw_writew(dws, DW_SPI_DMATDLR, 0x10);
if (dws->tx_dma)
- dma_ctrl |= 0x2;
+ dma_ctrl |= SPI_DMA_TDMAE;
if (dws->rx_dma)
- dma_ctrl |= 0x1;
+ dma_ctrl |= SPI_DMA_RDMAE;
dw_writew(dws, DW_SPI_DMACR, dma_ctrl);
spi_enable_chip(dws, 1);
}
dws->dma_chan_done = 0;
- txchan = dws->txchan;
- rxchan = dws->rxchan;
/* 2. Prepare the TX dma transfer */
txconf.direction = DMA_MEM_TO_DEV;
txconf.dst_addr = dws->dma_addr;
txconf.dst_maxburst = LNW_DMA_MSIZE_16;
txconf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
- txconf.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
+ txconf.dst_addr_width = dws->dma_width;
txconf.device_fc = false;
- txchan->device->device_control(txchan, DMA_SLAVE_CONFIG,
- (unsigned long) &txconf);
+ dmaengine_slave_config(dws->txchan, &txconf);
memset(&dws->tx_sgl, 0, sizeof(dws->tx_sgl));
dws->tx_sgl.dma_address = dws->tx_dma;
dws->tx_sgl.length = dws->len;
- txdesc = dmaengine_prep_slave_sg(txchan,
+ txdesc = dmaengine_prep_slave_sg(dws->txchan,
&dws->tx_sgl,
1,
DMA_MEM_TO_DEV,
- DMA_PREP_INTERRUPT);
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
txdesc->callback = dw_spi_dma_done;
txdesc->callback_param = dws;
@@ -159,27 +159,30 @@ static int mid_spi_dma_transfer(struct dw_spi *dws, int cs_change)
rxconf.src_addr = dws->dma_addr;
rxconf.src_maxburst = LNW_DMA_MSIZE_16;
rxconf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
- rxconf.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
+ rxconf.src_addr_width = dws->dma_width;
rxconf.device_fc = false;
- rxchan->device->device_control(rxchan, DMA_SLAVE_CONFIG,
- (unsigned long) &rxconf);
+ dmaengine_slave_config(dws->rxchan, &rxconf);
memset(&dws->rx_sgl, 0, sizeof(dws->rx_sgl));
dws->rx_sgl.dma_address = dws->rx_dma;
dws->rx_sgl.length = dws->len;
- rxdesc = dmaengine_prep_slave_sg(rxchan,
+ rxdesc = dmaengine_prep_slave_sg(dws->rxchan,
&dws->rx_sgl,
1,
DMA_DEV_TO_MEM,
- DMA_PREP_INTERRUPT);
+ DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
rxdesc->callback = dw_spi_dma_done;
rxdesc->callback_param = dws;
/* rx must be started before tx due to spi instinct */
- rxdesc->tx_submit(rxdesc);
- txdesc->tx_submit(txdesc);
+ dmaengine_submit(rxdesc);
+ dma_async_issue_pending(dws->rxchan);
+
+ dmaengine_submit(txdesc);
+ dma_async_issue_pending(dws->txchan);
+
return 0;
}
@@ -190,7 +193,7 @@ static struct dw_spi_dma_ops mid_dma_ops = {
};
#endif
-/* Some specific info for SPI0 controller on Moorestown */
+/* Some specific info for SPI0 controller on Intel MID */
/* HW info for MRST CLk Control Unit, one 32b reg */
#define MRST_SPI_CLK_BASE 100000000 /* 100m */
diff --git a/drivers/spi/spi-dw-pci.c b/drivers/spi/spi-dw-pci.c
index e14960470d8d..ba68da12cdf0 100644
--- a/drivers/spi/spi-dw-pci.c
+++ b/drivers/spi/spi-dw-pci.c
@@ -1,7 +1,7 @@
/*
* PCI interface driver for DW SPI Core
*
- * Copyright (c) 2009, Intel Corporation.
+ * Copyright (c) 2009, 2014 Intel Corporation.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -11,10 +11,6 @@
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <linux/interrupt.h>
@@ -32,17 +28,22 @@ struct dw_spi_pci {
struct dw_spi dws;
};
-static int spi_pci_probe(struct pci_dev *pdev,
- const struct pci_device_id *ent)
+struct spi_pci_desc {
+ int (*setup)(struct dw_spi *);
+};
+
+static struct spi_pci_desc spi_pci_mid_desc = {
+ .setup = dw_spi_mid_init,
+};
+
+static int spi_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
{
struct dw_spi_pci *dwpci;
struct dw_spi *dws;
+ struct spi_pci_desc *desc = (struct spi_pci_desc *)ent->driver_data;
int pci_bar = 0;
int ret;
- dev_info(&pdev->dev, "found PCI SPI controller(ID: %04x:%04x)\n",
- pdev->vendor, pdev->device);
-
ret = pcim_enable_device(pdev);
if (ret)
return ret;
@@ -58,7 +59,7 @@ static int spi_pci_probe(struct pci_dev *pdev,
/* Get basic io resource and map it */
dws->paddr = pci_resource_start(pdev, pci_bar);
- ret = pcim_iomap_regions(pdev, 1, dev_name(&pdev->dev));
+ ret = pcim_iomap_regions(pdev, 1 << pci_bar, pci_name(pdev));
if (ret)
return ret;
@@ -69,11 +70,11 @@ static int spi_pci_probe(struct pci_dev *pdev,
dws->irq = pdev->irq;
/*
- * Specific handling for Intel MID paltforms, like dma setup,
+ * Specific handling for paltforms, like dma setup,
* clock rate, FIFO depth.
*/
- if (pdev->device == 0x0800) {
- ret = dw_spi_mid_init(dws);
+ if (desc && desc->setup) {
+ ret = desc->setup(dws);
if (ret)
return ret;
}
@@ -85,6 +86,9 @@ static int spi_pci_probe(struct pci_dev *pdev,
/* PCI hook and SPI hook use the same drv data */
pci_set_drvdata(pdev, dwpci);
+ dev_info(&pdev->dev, "found PCI SPI controller(ID: %04x:%04x)\n",
+ pdev->vendor, pdev->device);
+
return 0;
}
@@ -95,41 +99,29 @@ static void spi_pci_remove(struct pci_dev *pdev)
dw_spi_remove_host(&dwpci->dws);
}
-#ifdef CONFIG_PM
-static int spi_suspend(struct pci_dev *pdev, pm_message_t state)
+#ifdef CONFIG_PM_SLEEP
+static int spi_suspend(struct device *dev)
{
+ struct pci_dev *pdev = to_pci_dev(dev);
struct dw_spi_pci *dwpci = pci_get_drvdata(pdev);
- int ret;
- ret = dw_spi_suspend_host(&dwpci->dws);
- if (ret)
- return ret;
- pci_save_state(pdev);
- pci_disable_device(pdev);
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
- return ret;
+ return dw_spi_suspend_host(&dwpci->dws);
}
-static int spi_resume(struct pci_dev *pdev)
+static int spi_resume(struct device *dev)
{
+ struct pci_dev *pdev = to_pci_dev(dev);
struct dw_spi_pci *dwpci = pci_get_drvdata(pdev);
- int ret;
- pci_set_power_state(pdev, PCI_D0);
- pci_restore_state(pdev);
- ret = pci_enable_device(pdev);
- if (ret)
- return ret;
return dw_spi_resume_host(&dwpci->dws);
}
-#else
-#define spi_suspend NULL
-#define spi_resume NULL
#endif
+static SIMPLE_DEV_PM_OPS(dw_spi_pm_ops, spi_suspend, spi_resume);
+
static const struct pci_device_id pci_ids[] = {
/* Intel MID platform SPI controller 0 */
- { PCI_DEVICE(PCI_VENDOR_ID_INTEL, 0x0800) },
+ { PCI_VDEVICE(INTEL, 0x0800), (kernel_ulong_t)&spi_pci_mid_desc},
{},
};
@@ -138,8 +130,9 @@ static struct pci_driver dw_spi_driver = {
.id_table = pci_ids,
.probe = spi_pci_probe,
.remove = spi_pci_remove,
- .suspend = spi_suspend,
- .resume = spi_resume,
+ .driver = {
+ .pm = &dw_spi_pm_ops,
+ },
};
module_pci_driver(dw_spi_driver);
diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c
index 33117fbbf689..729215885250 100644
--- a/drivers/spi/spi-dw.c
+++ b/drivers/spi/spi-dw.c
@@ -11,10 +11,6 @@
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
- *
- * You should have received a copy of the GNU General Public License along with
- * this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include <linux/dma-mapping.h>
@@ -59,22 +55,20 @@ struct chip_data {
#ifdef CONFIG_DEBUG_FS
#define SPI_REGS_BUFSIZE 1024
-static ssize_t spi_show_regs(struct file *file, char __user *user_buf,
- size_t count, loff_t *ppos)
+static ssize_t dw_spi_show_regs(struct file *file, char __user *user_buf,
+ size_t count, loff_t *ppos)
{
- struct dw_spi *dws;
+ struct dw_spi *dws = file->private_data;
char *buf;
u32 len = 0;
ssize_t ret;
- dws = file->private_data;
-
buf = kzalloc(SPI_REGS_BUFSIZE, GFP_KERNEL);
if (!buf)
return 0;
len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
- "MRST SPI0 registers:\n");
+ "%s registers:\n", dev_name(&dws->master->dev));
len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
"=================================\n");
len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
@@ -110,41 +104,41 @@ static ssize_t spi_show_regs(struct file *file, char __user *user_buf,
len += snprintf(buf + len, SPI_REGS_BUFSIZE - len,
"=================================\n");
- ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
+ ret = simple_read_from_buffer(user_buf, count, ppos, buf, len);
kfree(buf);
return ret;
}
-static const struct file_operations mrst_spi_regs_ops = {
+static const struct file_operations dw_spi_regs_ops = {
.owner = THIS_MODULE,
.open = simple_open,
- .read = spi_show_regs,
+ .read = dw_spi_show_regs,
.llseek = default_llseek,
};
-static int mrst_spi_debugfs_init(struct dw_spi *dws)
+static int dw_spi_debugfs_init(struct dw_spi *dws)
{
- dws->debugfs = debugfs_create_dir("mrst_spi", NULL);
+ dws->debugfs = debugfs_create_dir("dw_spi", NULL);
if (!dws->debugfs)
return -ENOMEM;
debugfs_create_file("registers", S_IFREG | S_IRUGO,
- dws->debugfs, (void *)dws, &mrst_spi_regs_ops);
+ dws->debugfs, (void *)dws, &dw_spi_regs_ops);
return 0;
}
-static void mrst_spi_debugfs_remove(struct dw_spi *dws)
+static void dw_spi_debugfs_remove(struct dw_spi *dws)
{
debugfs_remove_recursive(dws->debugfs);
}
#else
-static inline int mrst_spi_debugfs_init(struct dw_spi *dws)
+static inline int dw_spi_debugfs_init(struct dw_spi *dws)
{
return 0;
}
-static inline void mrst_spi_debugfs_remove(struct dw_spi *dws)
+static inline void dw_spi_debugfs_remove(struct dw_spi *dws)
{
}
#endif /* CONFIG_DEBUG_FS */
@@ -396,7 +390,7 @@ static void pump_transfers(unsigned long data)
goto early_exit;
}
- /* Delay if requested at end of transfer*/
+ /* Delay if requested at end of transfer */
if (message->state == RUNNING_STATE) {
previous = list_entry(transfer->transfer_list.prev,
struct spi_transfer,
@@ -525,7 +519,7 @@ static int dw_spi_transfer_one_message(struct spi_master *master,
struct dw_spi *dws = spi_master_get_devdata(master);
dws->cur_msg = msg;
- /* Initial message state*/
+ /* Initial message state */
dws->cur_msg->state = START_STATE;
dws->cur_transfer = list_entry(dws->cur_msg->transfers.next,
struct spi_transfer,
@@ -596,6 +590,9 @@ static int dw_spi_setup(struct spi_device *spi)
| (spi->mode << SPI_MODE_OFFSET)
| (chip->tmode << SPI_TMOD_OFFSET);
+ if (spi->mode & SPI_LOOP)
+ chip->cr0 |= 1 << SPI_SRL_OFFSET;
+
if (gpio_is_valid(spi->cs_gpio)) {
ret = gpio_direction_output(spi->cs_gpio,
!(spi->mode & SPI_CS_HIGH));
@@ -655,8 +652,7 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
dws->prev_chip = NULL;
dws->dma_inited = 0;
dws->dma_addr = (dma_addr_t)(dws->paddr + 0x60);
- snprintf(dws->name, sizeof(dws->name), "dw_spi%d",
- dws->bus_num);
+ snprintf(dws->name, sizeof(dws->name), "dw_spi%d", dws->bus_num);
ret = devm_request_irq(dev, dws->irq, dw_spi_irq, IRQF_SHARED,
dws->name, dws);
@@ -665,7 +661,7 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
goto err_free_master;
}
- master->mode_bits = SPI_CPOL | SPI_CPHA;
+ master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LOOP;
master->bits_per_word_mask = SPI_BPW_MASK(8) | SPI_BPW_MASK(16);
master->bus_num = dws->bus_num;
master->num_chipselect = dws->num_cs;
@@ -694,7 +690,7 @@ int dw_spi_add_host(struct device *dev, struct dw_spi *dws)
goto err_dma_exit;
}
- mrst_spi_debugfs_init(dws);
+ dw_spi_debugfs_init(dws);
return 0;
err_dma_exit:
@@ -711,7 +707,7 @@ void dw_spi_remove_host(struct dw_spi *dws)
{
if (!dws)
return;
- mrst_spi_debugfs_remove(dws);
+ dw_spi_debugfs_remove(dws);
if (dws->dma_ops && dws->dma_ops->dma_exit)
dws->dma_ops->dma_exit(dws);
diff --git a/drivers/spi/spi-dw.h b/drivers/spi/spi-dw.h
index 6d2acad34f64..83a103a76481 100644
--- a/drivers/spi/spi-dw.h
+++ b/drivers/spi/spi-dw.h
@@ -74,6 +74,10 @@
#define SPI_INT_RXFI (1 << 4)
#define SPI_INT_MSTI (1 << 5)
+/* Bit fields in DMACR */
+#define SPI_DMA_RDMAE (1 << 0)
+#define SPI_DMA_TDMAE (1 << 1)
+
/* TX RX interrupt level threshold, max can be 256 */
#define SPI_INT_THRESHOLD 32
@@ -140,7 +144,6 @@ struct dw_spi {
dma_addr_t dma_addr; /* phy address of the Data register */
struct dw_spi_dma_ops *dma_ops;
void *dma_priv; /* platform relate info */
- struct pci_dev *dmac;
/* Bus interface info */
void *priv;
@@ -217,11 +220,11 @@ static inline void spi_umask_intr(struct dw_spi *dws, u32 mask)
* Each SPI slave device to work with dw_api controller should
* has such a structure claiming its working mode (PIO/DMA etc),
* which can be save in the "controller_data" member of the
- * struct spi_device
+ * struct spi_device.
*/
struct dw_spi_chip {
- u8 poll_mode; /* 0 for contoller polling mode */
- u8 type; /* SPI/SSP/Micrwire */
+ u8 poll_mode; /* 1 for controller polling mode */
+ u8 type; /* SPI/SSP/MicroWire */
u8 enable_dma;
void (*cs_control)(u32 command);
};
diff --git a/drivers/spi/spi-fsl-cpm.c b/drivers/spi/spi-fsl-cpm.c
index 54b06376f03c..c5dd20beee22 100644
--- a/drivers/spi/spi-fsl-cpm.c
+++ b/drivers/spi/spi-fsl-cpm.c
@@ -15,17 +15,17 @@
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/spi/spi.h>
-#include <linux/fsl_devices.h>
-#include <linux/dma-mapping.h>
-#include <linux/of_address.h>
#include <asm/cpm.h>
#include <asm/qe.h>
+#include <linux/dma-mapping.h>
+#include <linux/fsl_devices.h>
+#include <linux/kernel.h>
+#include <linux/of_address.h>
+#include <linux/spi/spi.h>
+#include <linux/types.h>
-#include "spi-fsl-lib.h"
#include "spi-fsl-cpm.h"
+#include "spi-fsl-lib.h"
#include "spi-fsl-spi.h"
/* CPM1 and CPM2 are mutually exclusive. */
diff --git a/drivers/spi/spi-fsl-dspi.c b/drivers/spi/spi-fsl-dspi.c
index 5021ddf03f60..63c3859d24cf 100644
--- a/drivers/spi/spi-fsl-dspi.c
+++ b/drivers/spi/spi-fsl-dspi.c
@@ -13,22 +13,22 @@
*
*/
+#include <linux/clk.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/errno.h>
+#include <linux/interrupt.h>
+#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
-#include <linux/interrupt.h>
-#include <linux/errno.h>
+#include <linux/of.h>
+#include <linux/of_device.h>
#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
#include <linux/regmap.h>
#include <linux/sched.h>
-#include <linux/delay.h>
-#include <linux/io.h>
-#include <linux/clk.h>
-#include <linux/err.h>
#include <linux/spi/spi.h>
#include <linux/spi/spi_bitbang.h>
-#include <linux/pm_runtime.h>
-#include <linux/of.h>
-#include <linux/of_device.h>
#define DRIVER_NAME "fsl-dspi"
diff --git a/drivers/spi/spi-fsl-espi.c b/drivers/spi/spi-fsl-espi.c
index 429e11190265..a7f94b6a9e70 100644
--- a/drivers/spi/spi-fsl-espi.c
+++ b/drivers/spi/spi-fsl-espi.c
@@ -8,19 +8,19 @@
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
-#include <linux/module.h>
#include <linux/delay.h>
-#include <linux/irq.h>
-#include <linux/spi/spi.h>
-#include <linux/platform_device.h>
+#include <linux/err.h>
#include <linux/fsl_devices.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/module.h>
#include <linux/mm.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/of_platform.h>
-#include <linux/interrupt.h>
-#include <linux/err.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
#include <sysdev/fsl_soc.h>
#include "spi-fsl-lib.h"
diff --git a/drivers/spi/spi-fsl-lib.c b/drivers/spi/spi-fsl-lib.c
index e0b773fc29cb..5ddb5b098e4e 100644
--- a/drivers/spi/spi-fsl-lib.c
+++ b/drivers/spi/spi-fsl-lib.c
@@ -16,10 +16,10 @@
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
-#include <linux/fsl_devices.h>
#include <linux/dma-mapping.h>
+#include <linux/fsl_devices.h>
+#include <linux/interrupt.h>
+#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/of_platform.h>
#include <linux/spi/spi.h>
diff --git a/drivers/spi/spi-fsl-spi.c b/drivers/spi/spi-fsl-spi.c
index 590f31bc0aba..ed792880c9d6 100644
--- a/drivers/spi/spi-fsl-spi.c
+++ b/drivers/spi/spi-fsl-spi.c
@@ -19,25 +19,25 @@
* Free Software Foundation; either version 2 of the License, or (at your
* option) any later version.
*/
-#include <linux/module.h>
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/interrupt.h>
#include <linux/delay.h>
-#include <linux/irq.h>
-#include <linux/spi/spi.h>
-#include <linux/spi/spi_bitbang.h>
-#include <linux/platform_device.h>
-#include <linux/fsl_devices.h>
#include <linux/dma-mapping.h>
+#include <linux/fsl_devices.h>
+#include <linux/gpio.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/kernel.h>
#include <linux/mm.h>
+#include <linux/module.h>
#include <linux/mutex.h>
#include <linux/of.h>
-#include <linux/of_platform.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
-#include <linux/gpio.h>
#include <linux/of_gpio.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/spi/spi.h>
+#include <linux/spi/spi_bitbang.h>
+#include <linux/types.h>
#include "spi-fsl-lib.h"
#include "spi-fsl-cpm.h"