Commit aa62325d authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'spi-v5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi

Pull spi updates from Mark Brown:
 "The big theme for this release has been performance, we've had a
  series of unrelated overhauls of a few drivers all with a big
  peformance component.

  Otherwise it's been relatively quiet, highlights include:

   - A big overhaul of the spi-fsl-dspi driver improving the code
     quality, performance and stability from Vladimir Oltean.

   - A big performance enhancement for the bc2835 (Raspberry Pi) driver
     for unidirectional transfers from Lukas Wunner.

   - Improved performance on small transfers for the uniphier driver
     from Keiji Hayashibara.

   - Lots of coccinelle generated cleanups from Yue Haibing.

   - New device support for Freescale ls2080a and Nuvoton NPCM FIU"

* tag 'spi-v5.4' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/spi: (102 commits)
  spi: mediatek: support large PA
  spi: mediatek: add spi support for mt6765 IC
  dt-bindings: spi: update bindings for MT6765 SoC
  spi: bcm2835: Speed up RX-only DMA transfers by zero-filling TX FIFO
  spi: bcm2835: Speed up TX-only DMA transfers by clearing RX FIFO
  dmaengine: bcm2835: Avoid accessing memory when copying zeroes
  spi: bcm2835: Cache CS register value for ->prepare_message()
  dmaengine: bcm2835: Document struct bcm2835_dmadev
  spi: Guarantee cacheline alignment of driver-private data
  dmaengine: bcm2835: Allow reusable descriptors
  dmaengine: bcm2835: Allow cyclic transactions without interrupt
  spi: bcm2835: Drop dma_pending flag
  spi: bcm2835: Work around DONE bit erratum
  spi-gpio: Use PTR_ERR_OR_ZERO() in spi_gpio_request()
  spi: Use an abbreviated pointer to ctlr->cur_msg in __spi_pump_messages
  spi: npcm-fiu: remove set but not used variable 'retlen'
  spi: fsl-spi: use devm_platform_ioremap_resource() to simplify code
  spi: zynq-qspi: use devm_platform_ioremap_resource() to simplify code
  spi: zynqmp: use devm_platform_ioremap_resource() to simplify code
  spi: xlp: use devm_platform_ioremap_resource() to simplify code
  ...
parents c4d11ccb b769c5ba
......@@ -25,7 +25,9 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/machine.h> /* FIXME: using chip internals */
#include <linux/gpio/driver.h> /* FIXME: using chip internals */
#include <linux/of_irq.h>
#include <linux/spi/spi.h>
......@@ -66,6 +68,7 @@
#define BCM2835_SPI_FIFO_SIZE 64
#define BCM2835_SPI_FIFO_SIZE_3_4 48
#define BCM2835_SPI_DMA_MIN_LENGTH 96
#define BCM2835_SPI_NUM_CS 3 /* raise as necessary */
#define BCM2835_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \
| SPI_NO_CS | SPI_3WIRE)
......@@ -92,7 +95,8 @@ MODULE_PARM_DESC(polling_limit_us,
* @rx_prologue: bytes received without DMA if first RX sglist entry's
* length is not a multiple of 4 (to overcome hardware limitation)
* @tx_spillover: whether @tx_prologue spills over to second TX sglist entry
* @dma_pending: whether a DMA transfer is in progress
* @prepare_cs: precalculated CS register value for ->prepare_message()
* (uses slave-specific clock polarity and phase settings)
* @debugfs_dir: the debugfs directory - neede to remove debugfs when
* unloading the module
* @count_transfer_polling: count of how often polling mode is used
......@@ -102,6 +106,19 @@ MODULE_PARM_DESC(polling_limit_us,
* These are counted as well in @count_transfer_polling and
* @count_transfer_irq
* @count_transfer_dma: count how often dma mode is used
* @chip_select: SPI slave currently selected
* (used by bcm2835_spi_dma_tx_done() to write @clear_rx_cs)
* @tx_dma_active: whether a TX DMA descriptor is in progress
* @rx_dma_active: whether a RX DMA descriptor is in progress
* (used by bcm2835_spi_dma_tx_done() to handle a race)
* @fill_tx_desc: preallocated TX DMA descriptor used for RX-only transfers
* (cyclically copies from zero page to TX FIFO)
* @fill_tx_addr: bus address of zero page
* @clear_rx_desc: preallocated RX DMA descriptor used for TX-only transfers
* (cyclically clears RX FIFO by writing @clear_rx_cs to CS register)
* @clear_rx_addr: bus address of @clear_rx_cs
* @clear_rx_cs: precalculated CS register value to clear RX FIFO
* (uses slave-specific clock polarity and phase settings)
*/
struct bcm2835_spi {
void __iomem *regs;
......@@ -115,13 +132,22 @@ struct bcm2835_spi {
int tx_prologue;
int rx_prologue;
unsigned int tx_spillover;
unsigned int dma_pending;
u32 prepare_cs[BCM2835_SPI_NUM_CS];
struct dentry *debugfs_dir;
u64 count_transfer_polling;
u64 count_transfer_irq;
u64 count_transfer_irq_after_polling;
u64 count_transfer_dma;
u8 chip_select;
unsigned int tx_dma_active;
unsigned int rx_dma_active;
struct dma_async_tx_descriptor *fill_tx_desc;
dma_addr_t fill_tx_addr;
struct dma_async_tx_descriptor *clear_rx_desc[BCM2835_SPI_NUM_CS];
dma_addr_t clear_rx_addr;
u32 clear_rx_cs[BCM2835_SPI_NUM_CS] ____cacheline_aligned;
};
#if defined(CONFIG_DEBUG_FS)
......@@ -319,6 +345,13 @@ static void bcm2835_spi_reset_hw(struct spi_controller *ctlr)
BCM2835_SPI_CS_INTD |
BCM2835_SPI_CS_DMAEN |
BCM2835_SPI_CS_TA);
/*
* Transmission sometimes breaks unless the DONE bit is written at the
* end of every transfer. The spec says it's a RO bit. Either the
* spec is wrong and the bit is actually of type RW1C, or it's a
* hardware erratum.
*/
cs |= BCM2835_SPI_CS_DONE;
/* and reset RX/TX FIFOS */
cs |= BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX;
......@@ -448,14 +481,14 @@ static void bcm2835_spi_transfer_prologue(struct spi_controller *ctlr,
bs->rx_prologue = 0;
bs->tx_spillover = false;
if (!sg_is_last(&tfr->tx_sg.sgl[0]))
if (bs->tx_buf && !sg_is_last(&tfr->tx_sg.sgl[0]))
bs->tx_prologue = sg_dma_len(&tfr->tx_sg.sgl[0]) & 3;
if (!sg_is_last(&tfr->rx_sg.sgl[0])) {
if (bs->rx_buf && !sg_is_last(&tfr->rx_sg.sgl[0])) {
bs->rx_prologue = sg_dma_len(&tfr->rx_sg.sgl[0]) & 3;
if (bs->rx_prologue > bs->tx_prologue) {
if (sg_is_last(&tfr->tx_sg.sgl[0])) {
if (!bs->tx_buf || sg_is_last(&tfr->tx_sg.sgl[0])) {
bs->tx_prologue = bs->rx_prologue;
} else {
bs->tx_prologue += 4;
......@@ -477,7 +510,9 @@ static void bcm2835_spi_transfer_prologue(struct spi_controller *ctlr,
bcm2835_wr_fifo_count(bs, bs->rx_prologue);
bcm2835_wait_tx_fifo_empty(bs);
bcm2835_rd_fifo_count(bs, bs->rx_prologue);
bcm2835_spi_reset_hw(ctlr);
bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_CLEAR_RX
| BCM2835_SPI_CS_CLEAR_TX
| BCM2835_SPI_CS_DONE);
dma_sync_single_for_device(ctlr->dma_rx->device->dev,
sg_dma_address(&tfr->rx_sg.sgl[0]),
......@@ -487,6 +522,9 @@ static void bcm2835_spi_transfer_prologue(struct spi_controller *ctlr,
sg_dma_len(&tfr->rx_sg.sgl[0]) -= bs->rx_prologue;
}
if (!bs->tx_buf)
return;
/*
* Write remaining TX prologue. Adjust first entry in TX sglist.
* Also adjust second entry if prologue spills over to it.
......@@ -498,7 +536,8 @@ static void bcm2835_spi_transfer_prologue(struct spi_controller *ctlr,
| BCM2835_SPI_CS_DMAEN);
bcm2835_wr_fifo_count(bs, tx_remaining);
bcm2835_wait_tx_fifo_empty(bs);
bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_CLEAR_TX);
bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_CLEAR_TX
| BCM2835_SPI_CS_DONE);
}
if (likely(!bs->tx_spillover)) {
......@@ -531,6 +570,9 @@ static void bcm2835_spi_undo_prologue(struct bcm2835_spi *bs)
sg_dma_len(&tfr->rx_sg.sgl[0]) += bs->rx_prologue;
}
if (!bs->tx_buf)
goto out;
if (likely(!bs->tx_spillover)) {
sg_dma_address(&tfr->tx_sg.sgl[0]) -= bs->tx_prologue;
sg_dma_len(&tfr->tx_sg.sgl[0]) += bs->tx_prologue;
......@@ -539,32 +581,85 @@ static void bcm2835_spi_undo_prologue(struct bcm2835_spi *bs)
sg_dma_address(&tfr->tx_sg.sgl[1]) -= 4;
sg_dma_len(&tfr->tx_sg.sgl[1]) += 4;
}
out:
bs->tx_prologue = 0;
}
static void bcm2835_spi_dma_done(void *data)
/**
* bcm2835_spi_dma_rx_done() - callback for DMA RX channel
* @data: SPI master controller
*
* Used for bidirectional and RX-only transfers.
*/
static void bcm2835_spi_dma_rx_done(void *data)
{
struct spi_controller *ctlr = data;
struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
/* reset fifo and HW */
bcm2835_spi_reset_hw(ctlr);
/* and terminate tx-dma as we do not have an irq for it
/* terminate tx-dma as we do not have an irq for it
* because when the rx dma will terminate and this callback
* is called the tx-dma must have finished - can't get to this
* situation otherwise...
*/
if (cmpxchg(&bs->dma_pending, true, false)) {
dmaengine_terminate_async(ctlr->dma_tx);
bcm2835_spi_undo_prologue(bs);
}
dmaengine_terminate_async(ctlr->dma_tx);
bs->tx_dma_active = false;
bs->rx_dma_active = false;
bcm2835_spi_undo_prologue(bs);
/* reset fifo and HW */
bcm2835_spi_reset_hw(ctlr);
/* and mark as completed */;
complete(&ctlr->xfer_completion);
}
/**
* bcm2835_spi_dma_tx_done() - callback for DMA TX channel
* @data: SPI master controller
*
* Used for TX-only transfers.
*/
static void bcm2835_spi_dma_tx_done(void *data)
{
struct spi_controller *ctlr = data;
struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
/* busy-wait for TX FIFO to empty */
while (!(bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_DONE))
bcm2835_wr(bs, BCM2835_SPI_CS,
bs->clear_rx_cs[bs->chip_select]);
bs->tx_dma_active = false;
smp_wmb();
/*
* In case of a very short transfer, RX DMA may not have been
* issued yet. The onus is then on bcm2835_spi_transfer_one_dma()
* to terminate it immediately after issuing.
*/
if (cmpxchg(&bs->rx_dma_active, true, false))
dmaengine_terminate_async(ctlr->dma_rx);
bcm2835_spi_undo_prologue(bs);
bcm2835_spi_reset_hw(ctlr);
complete(&ctlr->xfer_completion);
}
/**
* bcm2835_spi_prepare_sg() - prepare and submit DMA descriptor for sglist
* @ctlr: SPI master controller
* @spi: SPI slave
* @tfr: SPI transfer
* @bs: BCM2835 SPI controller
* @is_tx: whether to submit DMA descriptor for TX or RX sglist
*
* Prepare and submit a DMA descriptor for the TX or RX sglist of @tfr.
* Return 0 on success or a negative error number.
*/
static int bcm2835_spi_prepare_sg(struct spi_controller *ctlr,
struct spi_device *spi,
struct spi_transfer *tfr,
struct bcm2835_spi *bs,
bool is_tx)
{
struct dma_chan *chan;
......@@ -581,8 +676,7 @@ static int bcm2835_spi_prepare_sg(struct spi_controller *ctlr,
chan = ctlr->dma_tx;
nents = tfr->tx_sg.nents;
sgl = tfr->tx_sg.sgl;
flags = 0 /* no tx interrupt */;
flags = tfr->rx_buf ? 0 : DMA_PREP_INTERRUPT;
} else {
dir = DMA_DEV_TO_MEM;
chan = ctlr->dma_rx;
......@@ -595,10 +689,17 @@ static int bcm2835_spi_prepare_sg(struct spi_controller *ctlr,
if (!desc)
return -EINVAL;
/* set callback for rx */
/*
* Completion is signaled by the RX channel for bidirectional and
* RX-only transfers; else by the TX channel for TX-only transfers.
*/
if (!is_tx) {
desc->callback = bcm2835_spi_dma_done;
desc->callback = bcm2835_spi_dma_rx_done;
desc->callback_param = ctlr;
} else if (!tfr->rx_buf) {
desc->callback = bcm2835_spi_dma_tx_done;
desc->callback_param = ctlr;
bs->chip_select = spi->chip_select;
}
/* submit it to DMA-engine */
......@@ -607,12 +708,60 @@ static int bcm2835_spi_prepare_sg(struct spi_controller *ctlr,
return dma_submit_error(cookie);
}
/**
* bcm2835_spi_transfer_one_dma() - perform SPI transfer using DMA engine
* @ctlr: SPI master controller
* @spi: SPI slave
* @tfr: SPI transfer
* @cs: CS register
*
* For *bidirectional* transfers (both tx_buf and rx_buf are non-%NULL), set up
* the TX and RX DMA channel to copy between memory and FIFO register.
*
* For *TX-only* transfers (rx_buf is %NULL), copying the RX FIFO's contents to
* memory is pointless. However not reading the RX FIFO isn't an option either
* because transmission is halted once it's full. As a workaround, cyclically
* clear the RX FIFO by setting the CLEAR_RX bit in the CS register.
*
* The CS register value is precalculated in bcm2835_spi_setup(). Normally
* this is called only once, on slave registration. A DMA descriptor to write
* this value is preallocated in bcm2835_dma_init(). All that's left to do
* when performing a TX-only transfer is to submit this descriptor to the RX
* DMA channel. Latency is thereby minimized. The descriptor does not
* generate any interrupts while running. It must be terminated once the
* TX DMA channel is done.
*
* Clearing the RX FIFO is paced by the DREQ signal. The signal is asserted
* when the RX FIFO becomes half full, i.e. 32 bytes. (Tuneable with the DC
* register.) Reading 32 bytes from the RX FIFO would normally require 8 bus
* accesses, whereas clearing it requires only 1 bus access. So an 8-fold
* reduction in bus traffic and thus energy consumption is achieved.
*
* For *RX-only* transfers (tx_buf is %NULL), fill the TX FIFO by cyclically
* copying from the zero page. The DMA descriptor to do this is preallocated
* in bcm2835_dma_init(). It must be terminated once the RX DMA channel is
* done and can then be reused.
*
* The BCM2835 DMA driver autodetects when a transaction copies from the zero
* page and utilizes the DMA controller's ability to synthesize zeroes instead
* of copying them from memory. This reduces traffic on the memory bus. The
* feature is not available on so-called "lite" channels, but normally TX DMA
* is backed by a full-featured channel.
*
* Zero-filling the TX FIFO is paced by the DREQ signal. Unfortunately the
* BCM2835 SPI controller continues to assert DREQ even after the DLEN register
* has been counted down to zero (hardware erratum). Thus, when the transfer
* has finished, the DMA engine zero-fills the TX FIFO until it is half full.
* (Tuneable with the DC register.) So up to 9 gratuitous bus accesses are
* performed at the end of an RX-only transfer.
*/
static int bcm2835_spi_transfer_one_dma(struct spi_controller *ctlr,
struct spi_device *spi,
struct spi_transfer *tfr,
u32 cs)
{
struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
dma_cookie_t cookie;
int ret;
/* update usage statistics */
......@@ -625,16 +774,15 @@ static int bcm2835_spi_transfer_one_dma(struct spi_controller *ctlr,
bcm2835_spi_transfer_prologue(ctlr, tfr, bs, cs);
/* setup tx-DMA */
ret = bcm2835_spi_prepare_sg(ctlr, tfr, true);
if (bs->tx_buf) {
ret = bcm2835_spi_prepare_sg(ctlr, spi, tfr, bs, true);
} else {
cookie = dmaengine_submit(bs->fill_tx_desc);
ret = dma_submit_error(cookie);
}
if (ret)
goto err_reset_hw;
/* start TX early */
dma_async_issue_pending(ctlr->dma_tx);
/* mark as dma pending */
bs->dma_pending = 1;
/* set the DMA length */
bcm2835_wr(bs, BCM2835_SPI_DLEN, bs->tx_len);
......@@ -642,20 +790,43 @@ static int bcm2835_spi_transfer_one_dma(struct spi_controller *ctlr,
bcm2835_wr(bs, BCM2835_SPI_CS,
cs | BCM2835_SPI_CS_TA | BCM2835_SPI_CS_DMAEN);
bs->tx_dma_active = true;
smp_wmb();
/* start TX early */
dma_async_issue_pending(ctlr->dma_tx);
/* setup rx-DMA late - to run transfers while
* mapping of the rx buffers still takes place
* this saves 10us or more.
*/
ret = bcm2835_spi_prepare_sg(ctlr, tfr, false);
if (bs->rx_buf) {
ret = bcm2835_spi_prepare_sg(ctlr, spi, tfr, bs, false);
} else {
cookie = dmaengine_submit(bs->clear_rx_desc[spi->chip_select]);
ret = dma_submit_error(cookie);
}
if (ret) {
/* need to reset on errors */
dmaengine_terminate_sync(ctlr->dma_tx);
bs->dma_pending = false;
bs->tx_dma_active = false;
goto err_reset_hw;
}
/* start rx dma late */
dma_async_issue_pending(ctlr->dma_rx);
bs->rx_dma_active = true;
smp_mb();
/*
* In case of a very short TX-only transfer, bcm2835_spi_dma_tx_done()
* may run before RX DMA is issued. Terminate RX DMA if so.
*/
if (!bs->rx_buf && !bs->tx_dma_active &&
cmpxchg(&bs->rx_dma_active, true, false)) {
dmaengine_terminate_async(ctlr->dma_rx);
bcm2835_spi_reset_hw(ctlr);
}
/* wait for wakeup in framework */
return 1;
......@@ -678,26 +849,52 @@ static bool bcm2835_spi_can_dma(struct spi_controller *ctlr,
return true;
}
static void bcm2835_dma_release(struct spi_controller *ctlr)
static void bcm2835_dma_release(struct spi_controller *ctlr,
struct bcm2835_spi *bs)
{
int i;
if (ctlr->dma_tx) {
dmaengine_terminate_sync(ctlr->dma_tx);
if (bs->fill_tx_desc)
dmaengine_desc_free(bs->fill_tx_desc);
if (bs->fill_tx_addr)
dma_unmap_page_attrs(ctlr->dma_tx->device->dev,
bs->fill_tx_addr, sizeof(u32),
DMA_TO_DEVICE,
DMA_ATTR_SKIP_CPU_SYNC);
dma_release_channel(ctlr->dma_tx);
ctlr->dma_tx = NULL;
}
if (ctlr->dma_rx) {
dmaengine_terminate_sync(ctlr->dma_rx);
for (i = 0; i < BCM2835_SPI_NUM_CS; i++)
if (bs->clear_rx_desc[i])
dmaengine_desc_free(bs->clear_rx_desc[i]);
if (bs->clear_rx_addr)
dma_unmap_single(ctlr->dma_rx->device->dev,
bs->clear_rx_addr,
sizeof(bs->clear_rx_cs),
DMA_TO_DEVICE);
dma_release_channel(ctlr->dma_rx);
ctlr->dma_rx = NULL;
}
}
static void bcm2835_dma_init(struct spi_controller *ctlr, struct device *dev)
static void bcm2835_dma_init(struct spi_controller *ctlr, struct device *dev,
struct bcm2835_spi *bs)
{
struct dma_slave_config slave_config;
const __be32 *addr;
dma_addr_t dma_reg_base;
int ret;
int ret, i;
/* base address in dma-space */
addr = of_get_address(ctlr->dev.of_node, 0, NULL, NULL);
......@@ -719,7 +916,11 @@ static void bcm2835_dma_init(struct spi_controller *ctlr, struct device *dev)
goto err_release;
}
/* configure DMAs */
/*
* The TX DMA channel either copies a transfer's TX buffer to the FIFO
* or, in case of an RX-only transfer, cyclically copies from the zero
* page to the FIFO using a preallocated, reusable descriptor.
*/
slave_config.dst_addr = (u32)(dma_reg_base + BCM2835_SPI_FIFO);
slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
......@@ -727,17 +928,74 @@ static void bcm2835_dma_init(struct spi_controller *ctlr, struct device *dev)
if (ret)
goto err_config;
bs->fill_tx_addr = dma_map_page_attrs(ctlr->dma_tx->device->dev,
ZERO_PAGE(0), 0, sizeof(u32),
DMA_TO_DEVICE,
DMA_ATTR_SKIP_CPU_SYNC);
if (dma_mapping_error(ctlr->dma_tx->device->dev, bs->fill_tx_addr)) {
dev_err(dev, "cannot map zero page - not using DMA mode\n");
bs->fill_tx_addr = 0;
goto err_release;
}
bs->fill_tx_desc = dmaengine_prep_dma_cyclic(ctlr->dma_tx,
bs->fill_tx_addr,
sizeof(u32), 0,
DMA_MEM_TO_DEV, 0);
if (!bs->fill_tx_desc) {
dev_err(dev, "cannot prepare fill_tx_desc - not using DMA mode\n");
goto err_release;
}
ret = dmaengine_desc_set_reuse(bs->fill_tx_desc);
if (ret) {
dev_err(dev, "cannot reuse fill_tx_desc - not using DMA mode\n");
goto err_release;
}
/*
* The RX DMA channel is used bidirectionally: It either reads the
* RX FIFO or, in case of a TX-only transfer, cyclically writes a
* precalculated value to the CS register to clear the RX FIFO.
*/
slave_config.src_addr = (u32)(dma_reg_base + BCM2835_SPI_FIFO);
slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
slave_config.dst_addr = (u32)(dma_reg_base + BCM2835_SPI_CS);
slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
ret = dmaengine_slave_config(ctlr->dma_rx, &slave_config);
if (ret)
goto err_config;
bs->clear_rx_addr = dma_map_single(ctlr->dma_rx->device->dev,
bs->clear_rx_cs,
sizeof(bs->clear_rx_cs),
DMA_TO_DEVICE);
if (dma_mapping_error(ctlr->dma_rx->device->dev, bs->clear_rx_addr)) {
dev_err(dev, "cannot map clear_rx_cs - not using DMA mode\n");
bs->clear_rx_addr = 0;
goto err_release;
}
for (i = 0; i < BCM2835_SPI_NUM_CS; i++) {
bs->clear_rx_desc[i] = dmaengine_prep_dma_cyclic(ctlr->dma_rx,
bs->clear_rx_addr + i * sizeof(u32),
sizeof(u32), 0,
DMA_MEM_TO_DEV, 0);
if (!bs->clear_rx_desc[i]) {
dev_err(dev, "cannot prepare clear_rx_desc - not using DMA mode\n");
goto err_release;
}
ret = dmaengine_desc_set_reuse(bs->clear_rx_desc[i]);
if (ret) {
dev_err(dev, "cannot reuse clear_rx_desc - not using DMA mode\n");
goto err_release;
}
}
/* all went well, so set can_dma */
ctlr->can_dma = bcm2835_spi_can_dma;
/* need to do TX AND RX DMA, so we need dummy buffers */
ctlr->flags = SPI_CONTROLLER_MUST_RX | SPI_CONTROLLER_MUST_TX;
return;
......@@ -745,7 +1003,7 @@ err_config:
dev_err(dev, "issue configuring dma: %d - not using DMA mode\n",
ret);
err_release:
bcm2835_dma_release(ctlr);
bcm2835_dma_release(ctlr, bs);
err:
return;
}
......@@ -812,7 +1070,7 @@ static int bcm2835_spi_transfer_one(struct spi_controller *ctlr,
struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
unsigned long spi_hz, clk_hz, cdiv, spi_used_hz;
unsigned long hz_per_byte, byte_limit;
u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS);
u32 cs = bs->prepare_cs[spi->chip_select];
/* set clock */
spi_hz = tfr->speed_hz;
......@@ -834,18 +1092,8 @@ static int bcm2835_spi_transfer_one(struct spi_controller *ctlr,
bcm2835_wr(bs, BCM2835_SPI_CLK, cdiv);
/* handle all the 3-wire mode */
if (spi->mode & SPI_3WIRE && tfr->rx_buf &&
tfr->rx_buf != ctlr->dummy_rx)
if (spi->mode & SPI_3WIRE && tfr->rx_buf)
cs |= BCM2835_SPI_CS_REN;
else
cs &= ~BCM2835_SPI_CS_REN;
/*
* The driver always uses software-controlled GPIO Chip Select.
* Set the hardware-controlled native Chip Select to an invalid
* value to prevent it from interfering.
*/
cs |= BCM2835_SPI_CS_CS_10 | BCM2835_SPI_CS_CS_01;
/* set transmit buffers and length */
bs->tx_buf = tfr->tx_buf;
......@@ -882,7 +1130,6 @@ static int bcm2835_spi_prepare_message(struct spi_controller *ctlr,
{
struct spi_device *spi = msg->spi;
struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS);
int ret;
if (ctlr->can_dma) {
......@@ -897,14 +1144,11 @@ static int bcm2835_spi_prepare_message(struct spi_controller *ctlr,
return ret;
}
cs &= ~(BCM2835_SPI_CS_CPOL | BCM2835_SPI_CS_CPHA);
if (spi->mode & SPI_CPOL)
cs |= BCM2835_SPI_CS_CPOL;
if (spi->mode & SPI_CPHA)
cs |= BCM2835_SPI_CS_CPHA;
bcm2835_wr(bs, BCM2835_SPI_CS, cs);
/*
* Set up clock polarity before spi_transfer_one_message() asserts
* chip select to avoid a gratuitous clock signal edge.
*/
bcm2835_wr(bs, BCM2835_SPI_CS, bs->prepare_cs[spi->chip_select]);
return 0;
}
......@@ -915,11 +1159,12 @@ static void bcm2835_spi_handle_err(struct spi_controller *ctlr,
struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
/* if an error occurred and we have an active dma, then terminate */
if (cmpxchg(&bs->dma_pending, true, false)) {
dmaengine_terminate_sync(ctlr->dma_tx);
dmaengine_terminate_sync(ctlr->dma_rx);
bcm2835_spi_undo_prologue(bs);
}
dmaengine_terminate_sync(ctlr->dma_tx);
bs->tx_dma_active = false;
dmaengine_terminate_sync(ctlr->dma_rx);
bs->rx_dma_active = false;
bcm2835_spi_undo_prologue(bs);
/* and reset */
bcm2835_spi_reset_hw(ctlr);
}
......@@ -931,14 +1176,50 @@ static int chip_match_name(struct gpio_chip *chip, void *data)
static int bcm2835_spi_setup(struct spi_device *spi)
{
int err;