Commit ec679bda authored by Lukas Wunner's avatar Lukas Wunner Committed by Mark Brown

spi: bcm2835: Allow arbitrary number of slaves

Since commit 571e31fa ("spi: bcm2835: Cache CS register value for
->prepare_message()"), the number of slaves has been limited by a
compile-time constant.  This was necessitated by statically-sized
arrays in the driver private data which contain per-slave register
values.

As suggested by Mark, move those register values to a per-slave
controller_state which is allocated on ->setup and freed on ->cleanup.
The limitation on the number of slaves is thus lifted.
Signed-off-by: default avatarLukas Wunner <lukas@wunner.de>
Cc: Joe Burmeister <joe.burmeister@devtank.co.uk>
Cc: Phil Elwell <phil@raspberrypi.com>
Link: https://lore.kernel.org/r/a847c01f09400801e74e0630bf5a0197591554da.1622150204.git.lukas@wunner.deSigned-off-by: default avatarMark Brown <broonie@kernel.org>
parent 1a435466
...@@ -68,7 +68,6 @@ ...@@ -68,7 +68,6 @@
#define BCM2835_SPI_FIFO_SIZE 64 #define BCM2835_SPI_FIFO_SIZE 64
#define BCM2835_SPI_FIFO_SIZE_3_4 48 #define BCM2835_SPI_FIFO_SIZE_3_4 48
#define BCM2835_SPI_DMA_MIN_LENGTH 96 #define BCM2835_SPI_DMA_MIN_LENGTH 96
#define BCM2835_SPI_NUM_CS 24 /* raise as necessary */
#define BCM2835_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \ #define BCM2835_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \
| SPI_NO_CS | SPI_3WIRE) | SPI_NO_CS | SPI_3WIRE)
...@@ -96,8 +95,6 @@ MODULE_PARM_DESC(polling_limit_us, ...@@ -96,8 +95,6 @@ MODULE_PARM_DESC(polling_limit_us,
* @rx_prologue: bytes received without DMA if first RX sglist entry's * @rx_prologue: bytes received without DMA if first RX sglist entry's
* length is not a multiple of 4 (to overcome hardware limitation) * length is not a multiple of 4 (to overcome hardware limitation)
* @tx_spillover: whether @tx_prologue spills over to second TX sglist entry * @tx_spillover: whether @tx_prologue spills over to second TX sglist entry
* @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 * @debugfs_dir: the debugfs directory - neede to remove debugfs when
* unloading the module * unloading the module
* @count_transfer_polling: count of how often polling mode is used * @count_transfer_polling: count of how often polling mode is used
...@@ -107,7 +104,7 @@ MODULE_PARM_DESC(polling_limit_us, ...@@ -107,7 +104,7 @@ MODULE_PARM_DESC(polling_limit_us,
* These are counted as well in @count_transfer_polling and * These are counted as well in @count_transfer_polling and
* @count_transfer_irq * @count_transfer_irq
* @count_transfer_dma: count how often dma mode is used * @count_transfer_dma: count how often dma mode is used
* @chip_select: SPI slave currently selected * @slv: SPI slave currently selected
* (used by bcm2835_spi_dma_tx_done() to write @clear_rx_cs) * (used by bcm2835_spi_dma_tx_done() to write @clear_rx_cs)
* @tx_dma_active: whether a TX DMA descriptor is in progress * @tx_dma_active: whether a TX DMA descriptor is in progress
* @rx_dma_active: whether a RX DMA descriptor is in progress * @rx_dma_active: whether a RX DMA descriptor is in progress
...@@ -115,11 +112,6 @@ MODULE_PARM_DESC(polling_limit_us, ...@@ -115,11 +112,6 @@ MODULE_PARM_DESC(polling_limit_us,
* @fill_tx_desc: preallocated TX DMA descriptor used for RX-only transfers * @fill_tx_desc: preallocated TX DMA descriptor used for RX-only transfers
* (cyclically copies from zero page to TX FIFO) * (cyclically copies from zero page to TX FIFO)
* @fill_tx_addr: bus address of zero page * @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 { struct bcm2835_spi {
void __iomem *regs; void __iomem *regs;
...@@ -134,7 +126,6 @@ struct bcm2835_spi { ...@@ -134,7 +126,6 @@ struct bcm2835_spi {
int tx_prologue; int tx_prologue;
int rx_prologue; int rx_prologue;
unsigned int tx_spillover; unsigned int tx_spillover;
u32 prepare_cs[BCM2835_SPI_NUM_CS];
struct dentry *debugfs_dir; struct dentry *debugfs_dir;
u64 count_transfer_polling; u64 count_transfer_polling;
...@@ -142,14 +133,28 @@ struct bcm2835_spi { ...@@ -142,14 +133,28 @@ struct bcm2835_spi {
u64 count_transfer_irq_after_polling; u64 count_transfer_irq_after_polling;
u64 count_transfer_dma; u64 count_transfer_dma;
u8 chip_select; struct bcm2835_spidev *slv;
unsigned int tx_dma_active; unsigned int tx_dma_active;
unsigned int rx_dma_active; unsigned int rx_dma_active;
struct dma_async_tx_descriptor *fill_tx_desc; struct dma_async_tx_descriptor *fill_tx_desc;
dma_addr_t fill_tx_addr; dma_addr_t fill_tx_addr;
struct dma_async_tx_descriptor *clear_rx_desc[BCM2835_SPI_NUM_CS]; };
/**
* struct bcm2835_spidev - BCM2835 SPI slave
* @prepare_cs: precalculated CS register value for ->prepare_message()
* (uses slave-specific clock polarity and phase settings)
* @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_spidev {
u32 prepare_cs;
struct dma_async_tx_descriptor *clear_rx_desc;
dma_addr_t clear_rx_addr; dma_addr_t clear_rx_addr;
u32 clear_rx_cs[BCM2835_SPI_NUM_CS] ____cacheline_aligned; u32 clear_rx_cs ____cacheline_aligned;
}; };
#if defined(CONFIG_DEBUG_FS) #if defined(CONFIG_DEBUG_FS)
...@@ -624,8 +629,7 @@ static void bcm2835_spi_dma_tx_done(void *data) ...@@ -624,8 +629,7 @@ static void bcm2835_spi_dma_tx_done(void *data)
/* busy-wait for TX FIFO to empty */ /* busy-wait for TX FIFO to empty */
while (!(bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_DONE)) while (!(bcm2835_rd(bs, BCM2835_SPI_CS) & BCM2835_SPI_CS_DONE))
bcm2835_wr(bs, BCM2835_SPI_CS, bcm2835_wr(bs, BCM2835_SPI_CS, bs->slv->clear_rx_cs);
bs->clear_rx_cs[bs->chip_select]);
bs->tx_dma_active = false; bs->tx_dma_active = false;
smp_wmb(); smp_wmb();
...@@ -646,18 +650,18 @@ static void bcm2835_spi_dma_tx_done(void *data) ...@@ -646,18 +650,18 @@ static void bcm2835_spi_dma_tx_done(void *data)
/** /**
* bcm2835_spi_prepare_sg() - prepare and submit DMA descriptor for sglist * bcm2835_spi_prepare_sg() - prepare and submit DMA descriptor for sglist
* @ctlr: SPI master controller * @ctlr: SPI master controller
* @spi: SPI slave
* @tfr: SPI transfer * @tfr: SPI transfer
* @bs: BCM2835 SPI controller * @bs: BCM2835 SPI controller
* @slv: BCM2835 SPI slave
* @is_tx: whether to submit DMA descriptor for TX or RX sglist * @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. * Prepare and submit a DMA descriptor for the TX or RX sglist of @tfr.
* Return 0 on success or a negative error number. * Return 0 on success or a negative error number.
*/ */
static int bcm2835_spi_prepare_sg(struct spi_controller *ctlr, static int bcm2835_spi_prepare_sg(struct spi_controller *ctlr,
struct spi_device *spi,
struct spi_transfer *tfr, struct spi_transfer *tfr,
struct bcm2835_spi *bs, struct bcm2835_spi *bs,
struct bcm2835_spidev *slv,
bool is_tx) bool is_tx)
{ {
struct dma_chan *chan; struct dma_chan *chan;
...@@ -697,7 +701,7 @@ static int bcm2835_spi_prepare_sg(struct spi_controller *ctlr, ...@@ -697,7 +701,7 @@ static int bcm2835_spi_prepare_sg(struct spi_controller *ctlr,
} else if (!tfr->rx_buf) { } else if (!tfr->rx_buf) {
desc->callback = bcm2835_spi_dma_tx_done; desc->callback = bcm2835_spi_dma_tx_done;
desc->callback_param = ctlr; desc->callback_param = ctlr;
bs->chip_select = spi->chip_select; bs->slv = slv;
} }
/* submit it to DMA-engine */ /* submit it to DMA-engine */
...@@ -709,8 +713,8 @@ static int bcm2835_spi_prepare_sg(struct spi_controller *ctlr, ...@@ -709,8 +713,8 @@ static int bcm2835_spi_prepare_sg(struct spi_controller *ctlr,
/** /**
* bcm2835_spi_transfer_one_dma() - perform SPI transfer using DMA engine * bcm2835_spi_transfer_one_dma() - perform SPI transfer using DMA engine
* @ctlr: SPI master controller * @ctlr: SPI master controller
* @spi: SPI slave
* @tfr: SPI transfer * @tfr: SPI transfer
* @slv: BCM2835 SPI slave
* @cs: CS register * @cs: CS register
* *
* For *bidirectional* transfers (both tx_buf and rx_buf are non-%NULL), set up * For *bidirectional* transfers (both tx_buf and rx_buf are non-%NULL), set up
...@@ -754,8 +758,8 @@ static int bcm2835_spi_prepare_sg(struct spi_controller *ctlr, ...@@ -754,8 +758,8 @@ static int bcm2835_spi_prepare_sg(struct spi_controller *ctlr,
* performed at the end of an RX-only transfer. * performed at the end of an RX-only transfer.
*/ */
static int bcm2835_spi_transfer_one_dma(struct spi_controller *ctlr, static int bcm2835_spi_transfer_one_dma(struct spi_controller *ctlr,
struct spi_device *spi,
struct spi_transfer *tfr, struct spi_transfer *tfr,
struct bcm2835_spidev *slv,
u32 cs) u32 cs)
{ {
struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
...@@ -773,7 +777,7 @@ static int bcm2835_spi_transfer_one_dma(struct spi_controller *ctlr, ...@@ -773,7 +777,7 @@ static int bcm2835_spi_transfer_one_dma(struct spi_controller *ctlr,
/* setup tx-DMA */ /* setup tx-DMA */
if (bs->tx_buf) { if (bs->tx_buf) {
ret = bcm2835_spi_prepare_sg(ctlr, spi, tfr, bs, true); ret = bcm2835_spi_prepare_sg(ctlr, tfr, bs, slv, true);
} else { } else {
cookie = dmaengine_submit(bs->fill_tx_desc); cookie = dmaengine_submit(bs->fill_tx_desc);
ret = dma_submit_error(cookie); ret = dma_submit_error(cookie);
...@@ -799,9 +803,9 @@ static int bcm2835_spi_transfer_one_dma(struct spi_controller *ctlr, ...@@ -799,9 +803,9 @@ static int bcm2835_spi_transfer_one_dma(struct spi_controller *ctlr,
* this saves 10us or more. * this saves 10us or more.
*/ */
if (bs->rx_buf) { if (bs->rx_buf) {
ret = bcm2835_spi_prepare_sg(ctlr, spi, tfr, bs, false); ret = bcm2835_spi_prepare_sg(ctlr, tfr, bs, slv, false);
} else { } else {
cookie = dmaengine_submit(bs->clear_rx_desc[spi->chip_select]); cookie = dmaengine_submit(slv->clear_rx_desc);
ret = dma_submit_error(cookie); ret = dma_submit_error(cookie);
} }
if (ret) { if (ret) {
...@@ -850,8 +854,6 @@ static bool bcm2835_spi_can_dma(struct spi_controller *ctlr, ...@@ -850,8 +854,6 @@ static bool bcm2835_spi_can_dma(struct spi_controller *ctlr,
static void bcm2835_dma_release(struct spi_controller *ctlr, static void bcm2835_dma_release(struct spi_controller *ctlr,
struct bcm2835_spi *bs) struct bcm2835_spi *bs)
{ {
int i;
if (ctlr->dma_tx) { if (ctlr->dma_tx) {
dmaengine_terminate_sync(ctlr->dma_tx); dmaengine_terminate_sync(ctlr->dma_tx);
...@@ -870,17 +872,6 @@ static void bcm2835_dma_release(struct spi_controller *ctlr, ...@@ -870,17 +872,6 @@ static void bcm2835_dma_release(struct spi_controller *ctlr,
if (ctlr->dma_rx) { if (ctlr->dma_rx) {
dmaengine_terminate_sync(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); dma_release_channel(ctlr->dma_rx);
ctlr->dma_rx = NULL; ctlr->dma_rx = NULL;
} }
...@@ -892,7 +883,7 @@ static int bcm2835_dma_init(struct spi_controller *ctlr, struct device *dev, ...@@ -892,7 +883,7 @@ static int bcm2835_dma_init(struct spi_controller *ctlr, struct device *dev,
struct dma_slave_config slave_config; struct dma_slave_config slave_config;
const __be32 *addr; const __be32 *addr;
dma_addr_t dma_reg_base; dma_addr_t dma_reg_base;
int ret, i; int ret;
/* base address in dma-space */ /* base address in dma-space */
addr = of_get_address(ctlr->dev.of_node, 0, NULL, NULL); addr = of_get_address(ctlr->dev.of_node, 0, NULL, NULL);
...@@ -972,35 +963,6 @@ static int bcm2835_dma_init(struct spi_controller *ctlr, struct device *dev, ...@@ -972,35 +963,6 @@ static int bcm2835_dma_init(struct spi_controller *ctlr, struct device *dev,
if (ret) if (ret)
goto err_config; 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;
ret = -ENOMEM;
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");
ret = -ENOMEM;
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 */ /* all went well, so set can_dma */
ctlr->can_dma = bcm2835_spi_can_dma; ctlr->can_dma = bcm2835_spi_can_dma;
...@@ -1082,9 +1044,10 @@ static int bcm2835_spi_transfer_one(struct spi_controller *ctlr, ...@@ -1082,9 +1044,10 @@ static int bcm2835_spi_transfer_one(struct spi_controller *ctlr,
struct spi_transfer *tfr) struct spi_transfer *tfr)
{ {
struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
struct bcm2835_spidev *slv = spi_get_ctldata(spi);
unsigned long spi_hz, clk_hz, cdiv; unsigned long spi_hz, clk_hz, cdiv;
unsigned long hz_per_byte, byte_limit; unsigned long hz_per_byte, byte_limit;
u32 cs = bs->prepare_cs[spi->chip_select]; u32 cs = slv->prepare_cs;
/* set clock */ /* set clock */
spi_hz = tfr->speed_hz; spi_hz = tfr->speed_hz;
...@@ -1133,7 +1096,7 @@ static int bcm2835_spi_transfer_one(struct spi_controller *ctlr, ...@@ -1133,7 +1096,7 @@ static int bcm2835_spi_transfer_one(struct spi_controller *ctlr,
* this 1 idle clock cycle pattern but runs the spi clock without gaps * this 1 idle clock cycle pattern but runs the spi clock without gaps
*/ */
if (ctlr->can_dma && bcm2835_spi_can_dma(ctlr, spi, tfr)) if (ctlr->can_dma && bcm2835_spi_can_dma(ctlr, spi, tfr))
return bcm2835_spi_transfer_one_dma(ctlr, spi, tfr, cs); return bcm2835_spi_transfer_one_dma(ctlr, tfr, slv, cs);
/* run in interrupt-mode */ /* run in interrupt-mode */
return bcm2835_spi_transfer_one_irq(ctlr, spi, tfr, cs, true); return bcm2835_spi_transfer_one_irq(ctlr, spi, tfr, cs, true);
...@@ -1144,6 +1107,7 @@ static int bcm2835_spi_prepare_message(struct spi_controller *ctlr, ...@@ -1144,6 +1107,7 @@ static int bcm2835_spi_prepare_message(struct spi_controller *ctlr,
{ {
struct spi_device *spi = msg->spi; struct spi_device *spi = msg->spi;
struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
struct bcm2835_spidev *slv = spi_get_ctldata(spi);
int ret; int ret;
if (ctlr->can_dma) { if (ctlr->can_dma) {
...@@ -1162,7 +1126,7 @@ static int bcm2835_spi_prepare_message(struct spi_controller *ctlr, ...@@ -1162,7 +1126,7 @@ static int bcm2835_spi_prepare_message(struct spi_controller *ctlr,
* Set up clock polarity before spi_transfer_one_message() asserts * Set up clock polarity before spi_transfer_one_message() asserts
* chip select to avoid a gratuitous clock signal edge. * chip select to avoid a gratuitous clock signal edge.
*/ */
bcm2835_wr(bs, BCM2835_SPI_CS, bs->prepare_cs[spi->chip_select]); bcm2835_wr(bs, BCM2835_SPI_CS, slv->prepare_cs);
return 0; return 0;
} }
...@@ -1188,17 +1152,81 @@ static int chip_match_name(struct gpio_chip *chip, void *data) ...@@ -1188,17 +1152,81 @@ static int chip_match_name(struct gpio_chip *chip, void *data)
return !strcmp(chip->label, data); return !strcmp(chip->label, data);
} }
static void bcm2835_spi_cleanup(struct spi_device *spi)
{
struct bcm2835_spidev *slv = spi_get_ctldata(spi);
struct spi_controller *ctlr = spi->controller;
if (slv->clear_rx_desc)
dmaengine_desc_free(slv->clear_rx_desc);
if (slv->clear_rx_addr)
dma_unmap_single(ctlr->dma_rx->device->dev,
slv->clear_rx_addr,
sizeof(u32),
DMA_TO_DEVICE);
kfree(slv);
}
static int bcm2835_spi_setup_dma(struct spi_controller *ctlr,
struct spi_device *spi,
struct bcm2835_spi *bs,
struct bcm2835_spidev *slv)
{
int ret;
if (!ctlr->dma_rx)
return 0;
slv->clear_rx_addr = dma_map_single(ctlr->dma_rx->device->dev,
&slv->clear_rx_cs,
sizeof(u32),
DMA_TO_DEVICE);
if (dma_mapping_error(ctlr->dma_rx->device->dev, slv->clear_rx_addr)) {
dev_err(&spi->dev, "cannot map clear_rx_cs\n");
slv->clear_rx_addr = 0;
return -ENOMEM;
}
slv->clear_rx_desc = dmaengine_prep_dma_cyclic(ctlr->dma_rx,
slv->clear_rx_addr,
sizeof(u32), 0,
DMA_MEM_TO_DEV, 0);
if (!slv->clear_rx_desc) {
dev_err(&spi->dev, "cannot prepare clear_rx_desc\n");
return -ENOMEM;
}
ret = dmaengine_desc_set_reuse(slv->clear_rx_desc);
if (ret) {
dev_err(&spi->dev, "cannot reuse clear_rx_desc\n");
return ret;
}
return 0;
}
static int bcm2835_spi_setup(struct spi_device *spi) static int bcm2835_spi_setup(struct spi_device *spi)
{ {
struct spi_controller *ctlr = spi->controller; struct spi_controller *ctlr = spi->controller;
struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
struct bcm2835_spidev *slv = spi_get_ctldata(spi);
struct gpio_chip *chip; struct gpio_chip *chip;
int ret;
u32 cs; u32 cs;
if (spi->chip_select >= BCM2835_SPI_NUM_CS) { if (!slv) {
dev_err(&spi->dev, "only %d chip-selects supported\n", slv = kzalloc(ALIGN(sizeof(*slv), dma_get_cache_alignment()),
BCM2835_SPI_NUM_CS - 1); GFP_KERNEL);
return -EINVAL; if (!slv)
return -ENOMEM;
spi_set_ctldata(spi, slv);
ret = bcm2835_spi_setup_dma(ctlr, spi, bs, slv);
if (ret)
goto err_cleanup;
} }
/* /*
...@@ -1212,20 +1240,19 @@ static int bcm2835_spi_setup(struct spi_device *spi) ...@@ -1212,20 +1240,19 @@ static int bcm2835_spi_setup(struct spi_device *spi)
cs |= BCM2835_SPI_CS_CPOL; cs |= BCM2835_SPI_CS_CPOL;
if (spi->mode & SPI_CPHA) if (spi->mode & SPI_CPHA)
cs |= BCM2835_SPI_CS_CPHA; cs |= BCM2835_SPI_CS_CPHA;
bs->prepare_cs[spi->chip_select] = cs; slv->prepare_cs = cs;
/* /*
* Precalculate SPI slave's CS register value to clear RX FIFO * Precalculate SPI slave's CS register value to clear RX FIFO
* in case of a TX-only DMA transfer. * in case of a TX-only DMA transfer.
*/ */
if (ctlr->dma_rx) { if (ctlr->dma_rx) {
bs->clear_rx_cs[spi->chip_select] = cs | slv->clear_rx_cs = cs | BCM2835_SPI_CS_TA |
BCM2835_SPI_CS_TA | BCM2835_SPI_CS_DMAEN |
BCM2835_SPI_CS_DMAEN | BCM2835_SPI_CS_CLEAR_RX;
BCM2835_SPI_CS_CLEAR_RX;
dma_sync_single_for_device(ctlr->dma_rx->device->dev, dma_sync_single_for_device(ctlr->dma_rx->device->dev,
bs->clear_rx_addr, slv->clear_rx_addr,
sizeof(bs->clear_rx_cs), sizeof(u32),
DMA_TO_DEVICE); DMA_TO_DEVICE);
} }
...@@ -1247,7 +1274,8 @@ static int bcm2835_spi_setup(struct spi_device *spi) ...@@ -1247,7 +1274,8 @@ static int bcm2835_spi_setup(struct spi_device *spi)
*/ */
dev_err(&spi->dev, dev_err(&spi->dev,
"setup: only two native chip-selects are supported\n"); "setup: only two native chip-selects are supported\n");
return -EINVAL; ret = -EINVAL;
goto err_cleanup;
} }
/* /*
...@@ -1268,14 +1296,20 @@ static int bcm2835_spi_setup(struct spi_device *spi) ...@@ -1268,14 +1296,20 @@ static int bcm2835_spi_setup(struct spi_device *spi)
DRV_NAME, DRV_NAME,
GPIO_LOOKUP_FLAGS_DEFAULT, GPIO_LOOKUP_FLAGS_DEFAULT,
GPIOD_OUT_LOW); GPIOD_OUT_LOW);
if (IS_ERR(spi->cs_gpiod)) if (IS_ERR(spi->cs_gpiod)) {
return PTR_ERR(spi->cs_gpiod); ret = PTR_ERR(spi->cs_gpiod);
goto err_cleanup;
}
/* and set up the "mode" and level */ /* and set up the "mode" and level */
dev_info(&spi->dev, "setting up native-CS%i to use GPIO\n", dev_info(&spi->dev, "setting up native-CS%i to use GPIO\n",
spi->chip_select); spi->chip_select);
return 0; return 0;
err_cleanup:
bcm2835_spi_cleanup(spi);
return ret;
} }
static int bcm2835_spi_probe(struct platform_device *pdev) static int bcm2835_spi_probe(struct platform_device *pdev)
...@@ -1284,8 +1318,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev) ...@@ -1284,8 +1318,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev)
struct bcm2835_spi *bs; struct bcm2835_spi *bs;
int err; int err;
ctlr = devm_spi_alloc_master(&pdev->dev, ALIGN(sizeof(*bs), ctlr = devm_spi_alloc_master(&pdev->dev, sizeof(*bs));
dma_get_cache_alignment()));
if (!ctlr) if (!ctlr)
return -ENOMEM; return -ENOMEM;
...@@ -1296,6 +1329,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev) ...@@ -1296,6 +1329,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev)
ctlr->bits_per_word_mask = SPI_BPW_MASK(8); ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
ctlr->num_chipselect = 3; ctlr->num_chipselect = 3;
ctlr->setup = bcm2835_spi_setup; ctlr->setup = bcm2835_spi_setup;
ctlr->cleanup = bcm2835_spi_cleanup;
ctlr->transfer_one = bcm2835_spi_transfer_one; ctlr->transfer_one = bcm2835_spi_transfer_one;
ctlr->handle_err = bcm2835_spi_handle_err; ctlr->handle_err = bcm2835_spi_handle_err;
ctlr->prepare_message = bcm2835_spi_prepare_message; ctlr->prepare_message = bcm2835_spi_prepare_message;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment