diff options
Diffstat (limited to 'drivers/spi/spi-bcm2835.c')
| -rw-r--r-- | drivers/spi/spi-bcm2835.c | 473 |
1 files changed, 255 insertions, 218 deletions
diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c index 237bd306c268..192cc5ef65fb 100644 --- a/drivers/spi/spi-bcm2835.c +++ b/drivers/spi/spi-bcm2835.c @@ -11,6 +11,7 @@ * spi-atmel.c, Copyright (C) 2006 Atmel Corporation */ +#include <linux/cleanup.h> #include <linux/clk.h> #include <linux/completion.h> #include <linux/debugfs.h> @@ -24,11 +25,12 @@ #include <linux/module.h> #include <linux/of.h> #include <linux/of_address.h> -#include <linux/of_device.h> +#include <linux/platform_device.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/gpio/machine.h> /* FIXME: using GPIO lookup tables */ #include <linux/of_irq.h> +#include <linux/overflow.h> +#include <linux/slab.h> #include <linux/spi/spi.h> /* SPI register offsets */ @@ -68,14 +70,13 @@ #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 4 /* raise as necessary */ #define BCM2835_SPI_MODE_BITS (SPI_CPOL | SPI_CPHA | SPI_CS_HIGH \ | SPI_NO_CS | SPI_3WIRE) #define DRV_NAME "spi-bcm2835" /* define polling limits */ -unsigned int polling_limit_us = 30; +static unsigned int polling_limit_us = 30; module_param(polling_limit_us, uint, 0664); MODULE_PARM_DESC(polling_limit_us, "time in us to run a transfer in polling mode\n"); @@ -84,8 +85,11 @@ MODULE_PARM_DESC(polling_limit_us, * struct bcm2835_spi - BCM2835 SPI controller * @regs: base address of register map * @clk: core clock, divided to calculate serial clock + * @cs_gpio: chip-select GPIO descriptor + * @clk_hz: core clock cached speed * @irq: interrupt, signals TX FIFO empty or RX FIFO ¾ full * @tfr: SPI transfer currently processed + * @ctlr: SPI controller reverse lookup * @tx_buf: pointer whence next transmitted byte is read * @rx_buf: pointer where next received byte is written * @tx_len: remaining bytes to transmit @@ -95,8 +99,6 @@ 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 - * @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 @@ -106,7 +108,7 @@ 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 + * @target: SPI target 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 @@ -114,17 +116,15 @@ MODULE_PARM_DESC(polling_limit_us, * @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; struct clk *clk; + struct gpio_desc *cs_gpio; + unsigned long clk_hz; int irq; struct spi_transfer *tfr; + struct spi_controller *ctlr; const u8 *tx_buf; u8 *rx_buf; int tx_len; @@ -132,7 +132,6 @@ struct bcm2835_spi { int tx_prologue; int rx_prologue; unsigned int tx_spillover; - u32 prepare_cs[BCM2835_SPI_NUM_CS]; struct dentry *debugfs_dir; u64 count_transfer_polling; @@ -140,14 +139,28 @@ struct bcm2835_spi { u64 count_transfer_irq_after_polling; u64 count_transfer_dma; - u8 chip_select; + struct bcm2835_spidev *target; 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]; +}; + +/** + * struct bcm2835_spidev - BCM2835 SPI target + * @prepare_cs: precalculated CS register value for ->prepare_message() + * (uses target-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 target-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; - u32 clear_rx_cs[BCM2835_SPI_NUM_CS] ____cacheline_aligned; + u32 clear_rx_cs ____cacheline_aligned; }; #if defined(CONFIG_DEBUG_FS) @@ -243,13 +256,13 @@ static inline void bcm2835_rd_fifo_count(struct bcm2835_spi *bs, int count) bs->rx_len -= count; - while (count > 0) { + do { val = bcm2835_rd(bs, BCM2835_SPI_FIFO); len = min(count, 4); memcpy(bs->rx_buf, &val, len); bs->rx_buf += len; count -= 4; - } + } while (count > 0); } /** @@ -269,7 +282,7 @@ static inline void bcm2835_wr_fifo_count(struct bcm2835_spi *bs, int count) bs->tx_len -= count; - while (count > 0) { + do { if (bs->tx_buf) { len = min(count, 4); memcpy(&val, bs->tx_buf, len); @@ -279,7 +292,7 @@ static inline void bcm2835_wr_fifo_count(struct bcm2835_spi *bs, int count) } bcm2835_wr(bs, BCM2835_SPI_FIFO, val); count -= 4; - } + } while (count > 0); } /** @@ -308,12 +321,11 @@ static inline void bcm2835_rd_fifo_blind(struct bcm2835_spi *bs, int count) count = min(count, bs->rx_len); bs->rx_len -= count; - while (count) { + do { val = bcm2835_rd(bs, BCM2835_SPI_FIFO); if (bs->rx_buf) *bs->rx_buf++ = val; - count--; - } + } while (--count); } /** @@ -328,16 +340,14 @@ static inline void bcm2835_wr_fifo_blind(struct bcm2835_spi *bs, int count) count = min(count, bs->tx_len); bs->tx_len -= count; - while (count) { + do { val = bs->tx_buf ? *bs->tx_buf++ : 0; bcm2835_wr(bs, BCM2835_SPI_FIFO, val); - count--; - } + } while (--count); } -static void bcm2835_spi_reset_hw(struct spi_controller *ctlr) +static void bcm2835_spi_reset_hw(struct bcm2835_spi *bs) { - struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); /* Disable SPI interrupts and transfer */ @@ -363,10 +373,13 @@ static void bcm2835_spi_reset_hw(struct spi_controller *ctlr) static irqreturn_t bcm2835_spi_interrupt(int irq, void *dev_id) { - struct spi_controller *ctlr = dev_id; - struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); + struct bcm2835_spi *bs = dev_id; u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS); + /* Bail out early if interrupts are not enabled */ + if (!(cs & BCM2835_SPI_CS_INTR)) + return IRQ_NONE; + /* * An interrupt is signaled either if DONE is set (TX FIFO empty) * or if RXR is set (RX FIFO >= ¾ full). @@ -386,9 +399,9 @@ static irqreturn_t bcm2835_spi_interrupt(int irq, void *dev_id) if (!bs->rx_len) { /* Transfer complete - reset SPI HW */ - bcm2835_spi_reset_hw(ctlr); + bcm2835_spi_reset_hw(bs); /* wake up the framework */ - complete(&ctlr->xfer_completion); + spi_finalize_current_transfer(bs->ctlr); } return IRQ_HANDLED; @@ -425,7 +438,7 @@ static int bcm2835_spi_transfer_one_irq(struct spi_controller *ctlr, /** * bcm2835_spi_transfer_prologue() - transfer first few bytes without DMA - * @ctlr: SPI master controller + * @ctlr: SPI host controller * @tfr: SPI transfer * @bs: BCM2835 SPI controller * @cs: CS register @@ -587,7 +600,7 @@ out: /** * bcm2835_spi_dma_rx_done() - callback for DMA RX channel - * @data: SPI master controller + * @data: SPI host controller * * Used for bidirectional and RX-only transfers. */ @@ -607,15 +620,15 @@ static void bcm2835_spi_dma_rx_done(void *data) bcm2835_spi_undo_prologue(bs); /* reset fifo and HW */ - bcm2835_spi_reset_hw(ctlr); + bcm2835_spi_reset_hw(bs); - /* and mark as completed */; - complete(&ctlr->xfer_completion); + /* and mark as completed */ + spi_finalize_current_transfer(ctlr); } /** * bcm2835_spi_dma_tx_done() - callback for DMA TX channel - * @data: SPI master controller + * @data: SPI host controller * * Used for TX-only transfers. */ @@ -626,8 +639,7 @@ static void bcm2835_spi_dma_tx_done(void *data) /* 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]); + bcm2835_wr(bs, BCM2835_SPI_CS, bs->target->clear_rx_cs); bs->tx_dma_active = false; smp_wmb(); @@ -641,25 +653,25 @@ static void bcm2835_spi_dma_tx_done(void *data) dmaengine_terminate_async(ctlr->dma_rx); bcm2835_spi_undo_prologue(bs); - bcm2835_spi_reset_hw(ctlr); - complete(&ctlr->xfer_completion); + bcm2835_spi_reset_hw(bs); + spi_finalize_current_transfer(ctlr); } /** * bcm2835_spi_prepare_sg() - prepare and submit DMA descriptor for sglist - * @ctlr: SPI master controller - * @spi: SPI slave + * @ctlr: SPI host controller * @tfr: SPI transfer * @bs: BCM2835 SPI controller + * @target: BCM2835 SPI target * @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, + struct bcm2835_spidev *target, bool is_tx) { struct dma_chan *chan; @@ -699,7 +711,7 @@ static int bcm2835_spi_prepare_sg(struct spi_controller *ctlr, } else if (!tfr->rx_buf) { desc->callback = bcm2835_spi_dma_tx_done; desc->callback_param = ctlr; - bs->chip_select = spi->chip_select; + bs->target = target; } /* submit it to DMA-engine */ @@ -710,9 +722,9 @@ static int bcm2835_spi_prepare_sg(struct spi_controller *ctlr, /** * bcm2835_spi_transfer_one_dma() - perform SPI transfer using DMA engine - * @ctlr: SPI master controller - * @spi: SPI slave + * @ctlr: SPI host controller * @tfr: SPI transfer + * @target: BCM2835 SPI target * @cs: CS register * * For *bidirectional* transfers (both tx_buf and rx_buf are non-%NULL), set up @@ -724,7 +736,7 @@ static int bcm2835_spi_prepare_sg(struct spi_controller *ctlr, * 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 is called only once, on target 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 @@ -756,8 +768,8 @@ static int bcm2835_spi_prepare_sg(struct spi_controller *ctlr, * 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, + struct bcm2835_spidev *target, u32 cs) { struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); @@ -775,7 +787,7 @@ static int bcm2835_spi_transfer_one_dma(struct spi_controller *ctlr, /* setup tx-DMA */ if (bs->tx_buf) { - ret = bcm2835_spi_prepare_sg(ctlr, spi, tfr, bs, true); + ret = bcm2835_spi_prepare_sg(ctlr, tfr, bs, target, true); } else { cookie = dmaengine_submit(bs->fill_tx_desc); ret = dma_submit_error(cookie); @@ -801,9 +813,9 @@ static int bcm2835_spi_transfer_one_dma(struct spi_controller *ctlr, * this saves 10us or more. */ if (bs->rx_buf) { - ret = bcm2835_spi_prepare_sg(ctlr, spi, tfr, bs, false); + ret = bcm2835_spi_prepare_sg(ctlr, tfr, bs, target, false); } else { - cookie = dmaengine_submit(bs->clear_rx_desc[spi->chip_select]); + cookie = dmaengine_submit(target->clear_rx_desc); ret = dma_submit_error(cookie); } if (ret) { @@ -825,14 +837,14 @@ static int bcm2835_spi_transfer_one_dma(struct spi_controller *ctlr, 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); + bcm2835_spi_reset_hw(bs); } /* wait for wakeup in framework */ return 1; err_reset_hw: - bcm2835_spi_reset_hw(ctlr); + bcm2835_spi_reset_hw(bs); bcm2835_spi_undo_prologue(bs); return ret; } @@ -852,8 +864,6 @@ static bool bcm2835_spi_can_dma(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); @@ -872,17 +882,6 @@ static void bcm2835_dma_release(struct spi_controller *ctlr, 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; } @@ -894,7 +893,7 @@ static int bcm2835_dma_init(struct spi_controller *ctlr, struct device *dev, struct dma_slave_config slave_config; const __be32 *addr; dma_addr_t dma_reg_base; - int ret, i; + int ret; /* base address in dma-space */ addr = of_get_address(ctlr->dev.of_node, 0, NULL, NULL); @@ -908,15 +907,15 @@ static int bcm2835_dma_init(struct spi_controller *ctlr, struct device *dev, /* get tx/rx dma */ ctlr->dma_tx = dma_request_chan(dev, "tx"); if (IS_ERR(ctlr->dma_tx)) { - dev_err(dev, "no tx-dma configuration found - not using dma mode\n"); - ret = PTR_ERR(ctlr->dma_tx); + ret = dev_err_probe(dev, PTR_ERR(ctlr->dma_tx), + "no tx-dma configuration found - not using dma mode\n"); ctlr->dma_tx = NULL; goto err; } ctlr->dma_rx = dma_request_chan(dev, "rx"); if (IS_ERR(ctlr->dma_rx)) { - dev_err(dev, "no rx-dma configuration found - not using dma mode\n"); - ret = PTR_ERR(ctlr->dma_rx); + ret = dev_err_probe(dev, PTR_ERR(ctlr->dma_rx), + "no rx-dma configuration found - not using dma mode\n"); ctlr->dma_rx = NULL; goto err_release; } @@ -974,35 +973,6 @@ static int bcm2835_dma_init(struct spi_controller *ctlr, struct device *dev, 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; - 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 */ ctlr->can_dma = bcm2835_spi_can_dma; @@ -1074,7 +1044,7 @@ static int bcm2835_spi_transfer_one_poll(struct spi_controller *ctlr, } /* Transfer complete - reset SPI HW */ - bcm2835_spi_reset_hw(ctlr); + bcm2835_spi_reset_hw(bs); /* and return without waiting for completion */ return 0; } @@ -1084,19 +1054,19 @@ static int bcm2835_spi_transfer_one(struct spi_controller *ctlr, struct spi_transfer *tfr) { struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); - unsigned long spi_hz, clk_hz, cdiv, spi_used_hz; + struct bcm2835_spidev *target = spi_get_ctldata(spi); + unsigned long spi_hz, cdiv; unsigned long hz_per_byte, byte_limit; - u32 cs = bs->prepare_cs[spi->chip_select]; + u32 cs = target->prepare_cs; /* set clock */ spi_hz = tfr->speed_hz; - clk_hz = clk_get_rate(bs->clk); - if (spi_hz >= clk_hz / 2) { + if (spi_hz >= bs->clk_hz / 2) { cdiv = 2; /* clk_hz/2 is the fastest we can go */ } else if (spi_hz) { /* CDIV must be a multiple of two */ - cdiv = DIV_ROUND_UP(clk_hz, spi_hz); + cdiv = DIV_ROUND_UP(bs->clk_hz, spi_hz); cdiv += (cdiv % 2); if (cdiv >= 65536) @@ -1104,7 +1074,7 @@ static int bcm2835_spi_transfer_one(struct spi_controller *ctlr, } else { cdiv = 0; /* 0 is the slowest we can go */ } - spi_used_hz = cdiv ? (clk_hz / cdiv) : (clk_hz / 65536); + tfr->effective_speed_hz = cdiv ? (bs->clk_hz / cdiv) : (bs->clk_hz / 65536); bcm2835_wr(bs, BCM2835_SPI_CLK, cdiv); /* handle all the 3-wire mode */ @@ -1124,7 +1094,7 @@ static int bcm2835_spi_transfer_one(struct spi_controller *ctlr, * per 300,000 Hz of bus clock. */ hz_per_byte = polling_limit_us ? (9 * 1000000) / polling_limit_us : 0; - byte_limit = hz_per_byte ? spi_used_hz / hz_per_byte : 1; + byte_limit = hz_per_byte ? tfr->effective_speed_hz / hz_per_byte : 1; /* run in polling mode for short transfers */ if (tfr->len < byte_limit) @@ -1135,7 +1105,7 @@ static int bcm2835_spi_transfer_one(struct spi_controller *ctlr, * this 1 idle clock cycle pattern but runs the spi clock without gaps */ 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, target, cs); /* run in interrupt-mode */ return bcm2835_spi_transfer_one_irq(ctlr, spi, tfr, cs, true); @@ -1146,25 +1116,13 @@ 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); - int ret; - - if (ctlr->can_dma) { - /* - * DMA transfers are limited to 16 bit (0 to 65535 bytes) by - * the SPI HW due to DLEN. Split up transfers (32-bit FIFO - * aligned) if the limit is exceeded. - */ - ret = spi_split_transfers_maxsize(ctlr, msg, 65532, - GFP_KERNEL | GFP_DMA); - if (ret) - return ret; - } + struct bcm2835_spidev *target = spi_get_ctldata(spi); /* * 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]); + bcm2835_wr(bs, BCM2835_SPI_CS, target->prepare_cs); return 0; } @@ -1175,31 +1133,122 @@ 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 */ - dmaengine_terminate_sync(ctlr->dma_tx); - bs->tx_dma_active = false; - dmaengine_terminate_sync(ctlr->dma_rx); - bs->rx_dma_active = false; + if (ctlr->dma_tx) { + dmaengine_terminate_sync(ctlr->dma_tx); + bs->tx_dma_active = false; + } + if (ctlr->dma_rx) { + dmaengine_terminate_sync(ctlr->dma_rx); + bs->rx_dma_active = false; + } bcm2835_spi_undo_prologue(bs); /* and reset */ - bcm2835_spi_reset_hw(ctlr); + bcm2835_spi_reset_hw(bs); +} + +static void bcm2835_spi_cleanup(struct spi_device *spi) +{ + struct bcm2835_spidev *target = spi_get_ctldata(spi); + struct spi_controller *ctlr = spi->controller; + struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); + + if (target->clear_rx_desc) + dmaengine_desc_free(target->clear_rx_desc); + + if (target->clear_rx_addr) + dma_unmap_single(ctlr->dma_rx->device->dev, + target->clear_rx_addr, + sizeof(u32), + DMA_TO_DEVICE); + + if (!IS_ERR(bs->cs_gpio)) + gpiod_put(bs->cs_gpio); + spi_set_csgpiod(spi, 0, NULL); + + kfree(target); } -static int chip_match_name(struct gpio_chip *chip, void *data) +static int bcm2835_spi_setup_dma(struct spi_controller *ctlr, + struct spi_device *spi, + struct bcm2835_spi *bs, + struct bcm2835_spidev *target) { - return !strcmp(chip->label, data); + int ret; + + if (!ctlr->dma_rx) + return 0; + + target->clear_rx_addr = dma_map_single(ctlr->dma_rx->device->dev, + &target->clear_rx_cs, + sizeof(u32), + DMA_TO_DEVICE); + if (dma_mapping_error(ctlr->dma_rx->device->dev, target->clear_rx_addr)) { + dev_err(&spi->dev, "cannot map clear_rx_cs\n"); + target->clear_rx_addr = 0; + return -ENOMEM; + } + + target->clear_rx_desc = dmaengine_prep_dma_cyclic(ctlr->dma_rx, + target->clear_rx_addr, + sizeof(u32), 0, + DMA_MEM_TO_DEV, 0); + if (!target->clear_rx_desc) { + dev_err(&spi->dev, "cannot prepare clear_rx_desc\n"); + return -ENOMEM; + } + + ret = dmaengine_desc_set_reuse(target->clear_rx_desc); + if (ret) { + dev_err(&spi->dev, "cannot reuse clear_rx_desc\n"); + return ret; + } + + return 0; +} + +static size_t bcm2835_spi_max_transfer_size(struct spi_device *spi) +{ + /* + * DMA transfers are limited to 16 bit (0 to 65535 bytes) by + * the SPI HW due to DLEN. Split up transfers (32-bit FIFO + * aligned) if the limit is exceeded. + */ + if (spi->controller->can_dma) + return 65532; + + return SIZE_MAX; } static int bcm2835_spi_setup(struct spi_device *spi) { struct spi_controller *ctlr = spi->controller; struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); - struct gpio_chip *chip; - enum gpio_lookup_flags lflags; + struct bcm2835_spidev *target = spi_get_ctldata(spi); + struct gpiod_lookup_table *lookup __free(kfree) = NULL; + const char *pinctrl_compats[] = { + "brcm,bcm2835-gpio", + "brcm,bcm2711-gpio", + "brcm,bcm7211-gpio", + }; + int ret, i; u32 cs; + if (!target) { + target = kzalloc(ALIGN(sizeof(*target), dma_get_cache_alignment()), + GFP_KERNEL); + if (!target) + return -ENOMEM; + + spi_set_ctldata(spi, target); + + ret = bcm2835_spi_setup_dma(ctlr, spi, bs, target); + if (ret) + goto err_cleanup; + } + /* - * Precalculate SPI slave's CS register value for ->prepare_message(): + * Precalculate SPI target's CS register value for ->prepare_message(): * The driver always uses software-controlled GPIO chip select, hence * set the hardware-controlled native chip select to an invalid value * to prevent it from interfering. @@ -1209,20 +1258,19 @@ static int bcm2835_spi_setup(struct spi_device *spi) cs |= BCM2835_SPI_CS_CPOL; if (spi->mode & SPI_CPHA) cs |= BCM2835_SPI_CS_CPHA; - bs->prepare_cs[spi->chip_select] = cs; + target->prepare_cs = cs; /* - * Precalculate SPI slave's CS register value to clear RX FIFO + * Precalculate SPI target's CS register value to clear RX FIFO * in case of a TX-only DMA transfer. */ if (ctlr->dma_rx) { - bs->clear_rx_cs[spi->chip_select] = cs | - BCM2835_SPI_CS_TA | - BCM2835_SPI_CS_DMAEN | - BCM2835_SPI_CS_CLEAR_RX; + target->clear_rx_cs = cs | BCM2835_SPI_CS_TA | + BCM2835_SPI_CS_DMAEN | + BCM2835_SPI_CS_CLEAR_RX; dma_sync_single_for_device(ctlr->dma_rx->device->dev, - bs->clear_rx_addr, - sizeof(bs->clear_rx_cs), + target->clear_rx_addr, + sizeof(u32), DMA_TO_DEVICE); } @@ -1235,56 +1283,67 @@ static int bcm2835_spi_setup(struct spi_device *spi) * The SPI core has successfully requested the CS GPIO line from the * device tree, so we are done. */ - if (spi->cs_gpiod) + if (spi_get_csgpiod(spi, 0)) return 0; - if (spi->chip_select > 1) { + if (spi_get_chipselect(spi, 0) > 1) { /* error in the case of native CS requested with CS > 1 * officially there is a CS2, but it is not documented * which GPIO is connected with that... */ dev_err(&spi->dev, "setup: only two native chip-selects are supported\n"); - return -EINVAL; + ret = -EINVAL; + goto err_cleanup; } - /* - * Translate native CS to GPIO - * - * FIXME: poking around in the gpiolib internals like this is - * not very good practice. Find a way to locate the real problem - * and fix it. Why is the GPIO descriptor in spi->cs_gpiod - * sometimes not assigned correctly? Erroneous device trees? - */ + for (i = 0; i < ARRAY_SIZE(pinctrl_compats); i++) { + if (of_find_compatible_node(NULL, NULL, pinctrl_compats[i])) + break; + } - /* get the gpio chip for the base */ - chip = gpiochip_find("pinctrl-bcm2835", chip_match_name); - if (!chip) + if (i == ARRAY_SIZE(pinctrl_compats)) return 0; /* - * Retrieve the corresponding GPIO line used for CS. - * The inversion semantics will be handled by the GPIO core - * code, so we pass GPIOD_OUT_LOW for "unasserted" and - * the correct flag for inversion semantics. The SPI_CS_HIGH - * on spi->mode cannot be checked for polarity in this case - * as the flag use_gpio_descriptors enforces SPI_CS_HIGH. + * TODO: The code below is a slightly better alternative to the utter + * abuse of the GPIO API that I found here before. It creates a + * temporary lookup table, assigns it to the SPI device, gets the GPIO + * descriptor and then releases the lookup table. + * + * More on the problem that it addresses: + * https://www.spinics.net/lists/linux-gpio/msg36218.html */ - if (of_property_read_bool(spi->dev.of_node, "spi-cs-high")) - lflags = GPIO_ACTIVE_HIGH; - else - lflags = GPIO_ACTIVE_LOW; - spi->cs_gpiod = gpiochip_request_own_desc(chip, 8 - spi->chip_select, - DRV_NAME, - lflags, - GPIOD_OUT_LOW); - if (IS_ERR(spi->cs_gpiod)) - return PTR_ERR(spi->cs_gpiod); + lookup = kzalloc(struct_size(lookup, table, 2), GFP_KERNEL); + if (!lookup) { + ret = -ENOMEM; + goto err_cleanup; + } + + lookup->dev_id = dev_name(&spi->dev); + lookup->table[0] = GPIO_LOOKUP("pinctrl-bcm2835", + 8 - (spi_get_chipselect(spi, 0)), + "cs", GPIO_LOOKUP_FLAGS_DEFAULT); + + gpiod_add_lookup_table(lookup); + + bs->cs_gpio = gpiod_get(&spi->dev, "cs", GPIOD_OUT_LOW); + gpiod_remove_lookup_table(lookup); + if (IS_ERR(bs->cs_gpio)) { + ret = PTR_ERR(bs->cs_gpio); + goto err_cleanup; + } + + spi_set_csgpiod(spi, 0, bs->cs_gpio); /* and set up the "mode" and level */ dev_info(&spi->dev, "setting up native-CS%i to use GPIO\n", - spi->chip_select); + spi_get_chipselect(spi, 0)); return 0; + +err_cleanup: + bcm2835_spi_cleanup(spi); + return ret; } static int bcm2835_spi_probe(struct platform_device *pdev) @@ -1293,8 +1352,7 @@ static int bcm2835_spi_probe(struct platform_device *pdev) struct bcm2835_spi *bs; int err; - ctlr = spi_alloc_master(&pdev->dev, ALIGN(sizeof(*bs), - dma_get_cache_alignment())); + ctlr = devm_spi_alloc_host(&pdev->dev, sizeof(*bs)); if (!ctlr) return -ENOMEM; @@ -1303,49 +1361,45 @@ static int bcm2835_spi_probe(struct platform_device *pdev) ctlr->use_gpio_descriptors = true; ctlr->mode_bits = BCM2835_SPI_MODE_BITS; ctlr->bits_per_word_mask = SPI_BPW_MASK(8); - ctlr->num_chipselect = BCM2835_SPI_NUM_CS; + ctlr->num_chipselect = 3; + ctlr->max_transfer_size = bcm2835_spi_max_transfer_size; ctlr->setup = bcm2835_spi_setup; + ctlr->cleanup = bcm2835_spi_cleanup; ctlr->transfer_one = bcm2835_spi_transfer_one; ctlr->handle_err = bcm2835_spi_handle_err; ctlr->prepare_message = bcm2835_spi_prepare_message; ctlr->dev.of_node = pdev->dev.of_node; bs = spi_controller_get_devdata(ctlr); + bs->ctlr = ctlr; bs->regs = devm_platform_ioremap_resource(pdev, 0); - if (IS_ERR(bs->regs)) { - err = PTR_ERR(bs->regs); - goto out_controller_put; - } + if (IS_ERR(bs->regs)) + return PTR_ERR(bs->regs); - bs->clk = devm_clk_get(&pdev->dev, NULL); - if (IS_ERR(bs->clk)) { - err = PTR_ERR(bs->clk); - if (err == -EPROBE_DEFER) - dev_dbg(&pdev->dev, "could not get clk: %d\n", err); - else - dev_err(&pdev->dev, "could not get clk: %d\n", err); - goto out_controller_put; - } + bs->clk = devm_clk_get_enabled(&pdev->dev, NULL); + if (IS_ERR(bs->clk)) + return dev_err_probe(&pdev->dev, PTR_ERR(bs->clk), + "could not get clk\n"); + + ctlr->max_speed_hz = clk_get_rate(bs->clk) / 2; bs->irq = platform_get_irq(pdev, 0); - if (bs->irq <= 0) { - err = bs->irq ? bs->irq : -ENODEV; - goto out_controller_put; - } + if (bs->irq < 0) + return bs->irq; - clk_prepare_enable(bs->clk); + bs->clk_hz = clk_get_rate(bs->clk); err = bcm2835_dma_init(ctlr, &pdev->dev, bs); if (err) - goto out_clk_disable; + return err; /* initialise the hardware with the default polarities */ bcm2835_wr(bs, BCM2835_SPI_CS, BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX); - err = devm_request_irq(&pdev->dev, bs->irq, bcm2835_spi_interrupt, 0, - dev_name(&pdev->dev), ctlr); + err = devm_request_irq(&pdev->dev, bs->irq, bcm2835_spi_interrupt, + IRQF_SHARED, dev_name(&pdev->dev), bs); if (err) { dev_err(&pdev->dev, "could not request IRQ: %d\n", err); goto out_dma_release; @@ -1364,14 +1418,10 @@ static int bcm2835_spi_probe(struct platform_device *pdev) out_dma_release: bcm2835_dma_release(ctlr, bs); -out_clk_disable: - clk_disable_unprepare(bs->clk); -out_controller_put: - spi_controller_put(ctlr); return err; } -static int bcm2835_spi_remove(struct platform_device *pdev) +static void bcm2835_spi_remove(struct platform_device *pdev) { struct spi_controller *ctlr = platform_get_drvdata(pdev); struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr); @@ -1385,19 +1435,6 @@ static int bcm2835_spi_remove(struct platform_device *pdev) /* Clear FIFOs, and disable the HW block */ bcm2835_wr(bs, BCM2835_SPI_CS, BCM2835_SPI_CS_CLEAR_RX | BCM2835_SPI_CS_CLEAR_TX); - - clk_disable_unprepare(bs->clk); - - return 0; -} - -static void bcm2835_spi_shutdown(struct platform_device *pdev) -{ - int ret; - - ret = bcm2835_spi_remove(pdev); - if (ret) - dev_err(&pdev->dev, "failed to shutdown\n"); } static const struct of_device_id bcm2835_spi_match[] = { @@ -1413,7 +1450,7 @@ static struct platform_driver bcm2835_spi_driver = { }, .probe = bcm2835_spi_probe, .remove = bcm2835_spi_remove, - .shutdown = bcm2835_spi_shutdown, + .shutdown = bcm2835_spi_remove, }; module_platform_driver(bcm2835_spi_driver); |
