aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-bcm2835.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi/spi-bcm2835.c')
-rw-r--r--drivers/spi/spi-bcm2835.c328
1 files changed, 204 insertions, 124 deletions
diff --git a/drivers/spi/spi-bcm2835.c b/drivers/spi/spi-bcm2835.c
index 402c1efcd762..6f243a90c844 100644
--- a/drivers/spi/spi-bcm2835.c
+++ b/drivers/spi/spi-bcm2835.c
@@ -13,6 +13,7 @@
#include <linux/clk.h>
#include <linux/completion.h>
+#include <linux/debugfs.h>
#include <linux/delay.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
@@ -64,14 +65,18 @@
#define BCM2835_SPI_FIFO_SIZE 64
#define BCM2835_SPI_FIFO_SIZE_3_4 48
-#define BCM2835_SPI_POLLING_LIMIT_US 30
-#define BCM2835_SPI_POLLING_JIFFIES 2
#define BCM2835_SPI_DMA_MIN_LENGTH 96
#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;
+module_param(polling_limit_us, uint, 0664);
+MODULE_PARM_DESC(polling_limit_us,
+ "time in us to run a transfer in polling mode\n");
+
/**
* struct bcm2835_spi - BCM2835 SPI controller
* @regs: base address of register map
@@ -88,6 +93,15 @@
* 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
+ * @debugfs_dir: the debugfs directory - neede to remove debugfs when
+ * unloading the module
+ * @count_transfer_polling: count of how often polling mode is used
+ * @count_transfer_irq: count of how often interrupt mode is used
+ * @count_transfer_irq_after_polling: count of how often we fall back to
+ * interrupt mode after starting in polling mode.
+ * These are counted as well in @count_transfer_polling and
+ * @count_transfer_irq
+ * @count_transfer_dma: count how often dma mode is used
*/
struct bcm2835_spi {
void __iomem *regs;
@@ -102,8 +116,55 @@ struct bcm2835_spi {
int rx_prologue;
unsigned int tx_spillover;
unsigned int dma_pending;
+
+ struct dentry *debugfs_dir;
+ u64 count_transfer_polling;
+ u64 count_transfer_irq;
+ u64 count_transfer_irq_after_polling;
+ u64 count_transfer_dma;
};
+#if defined(CONFIG_DEBUG_FS)
+static void bcm2835_debugfs_create(struct bcm2835_spi *bs,
+ const char *dname)
+{
+ char name[64];
+ struct dentry *dir;
+
+ /* get full name */
+ snprintf(name, sizeof(name), "spi-bcm2835-%s", dname);
+
+ /* the base directory */
+ dir = debugfs_create_dir(name, NULL);
+ bs->debugfs_dir = dir;
+
+ /* the counters */
+ debugfs_create_u64("count_transfer_polling", 0444, dir,
+ &bs->count_transfer_polling);
+ debugfs_create_u64("count_transfer_irq", 0444, dir,
+ &bs->count_transfer_irq);
+ debugfs_create_u64("count_transfer_irq_after_polling", 0444, dir,
+ &bs->count_transfer_irq_after_polling);
+ debugfs_create_u64("count_transfer_dma", 0444, dir,
+ &bs->count_transfer_dma);
+}
+
+static void bcm2835_debugfs_remove(struct bcm2835_spi *bs)
+{
+ debugfs_remove_recursive(bs->debugfs_dir);
+ bs->debugfs_dir = NULL;
+}
+#else
+static void bcm2835_debugfs_create(struct bcm2835_spi *bs,
+ const char *dname)
+{
+}
+
+static void bcm2835_debugfs_remove(struct bcm2835_spi *bs)
+{
+}
+#endif /* CONFIG_DEBUG_FS */
+
static inline u32 bcm2835_rd(struct bcm2835_spi *bs, unsigned reg)
{
return readl(bs->regs + reg);
@@ -248,9 +309,9 @@ static inline void bcm2835_wr_fifo_blind(struct bcm2835_spi *bs, int count)
}
}
-static void bcm2835_spi_reset_hw(struct spi_master *master)
+static void bcm2835_spi_reset_hw(struct spi_controller *ctlr)
{
- struct bcm2835_spi *bs = spi_master_get_devdata(master);
+ struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS);
/* Disable SPI interrupts and transfer */
@@ -269,8 +330,8 @@ static void bcm2835_spi_reset_hw(struct spi_master *master)
static irqreturn_t bcm2835_spi_interrupt(int irq, void *dev_id)
{
- struct spi_master *master = dev_id;
- struct bcm2835_spi *bs = spi_master_get_devdata(master);
+ struct spi_controller *ctlr = dev_id;
+ struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS);
/*
@@ -292,20 +353,23 @@ static irqreturn_t bcm2835_spi_interrupt(int irq, void *dev_id)
if (!bs->rx_len) {
/* Transfer complete - reset SPI HW */
- bcm2835_spi_reset_hw(master);
+ bcm2835_spi_reset_hw(ctlr);
/* wake up the framework */
- complete(&master->xfer_completion);
+ complete(&ctlr->xfer_completion);
}
return IRQ_HANDLED;
}
-static int bcm2835_spi_transfer_one_irq(struct spi_master *master,
+static int bcm2835_spi_transfer_one_irq(struct spi_controller *ctlr,
struct spi_device *spi,
struct spi_transfer *tfr,
u32 cs, bool fifo_empty)
{
- struct bcm2835_spi *bs = spi_master_get_devdata(master);
+ struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
+
+ /* update usage statistics */
+ bs->count_transfer_irq++;
/*
* Enable HW block, but with interrupts still disabled.
@@ -328,7 +392,7 @@ static int bcm2835_spi_transfer_one_irq(struct spi_master *master,
/**
* bcm2835_spi_transfer_prologue() - transfer first few bytes without DMA
- * @master: SPI master
+ * @ctlr: SPI master controller
* @tfr: SPI transfer
* @bs: BCM2835 SPI controller
* @cs: CS register
@@ -372,7 +436,7 @@ static int bcm2835_spi_transfer_one_irq(struct spi_master *master,
* be transmitted in 32-bit width to ensure that the following DMA transfer can
* pick up the residue in the RX FIFO in ungarbled form.
*/
-static void bcm2835_spi_transfer_prologue(struct spi_master *master,
+static void bcm2835_spi_transfer_prologue(struct spi_controller *ctlr,
struct spi_transfer *tfr,
struct bcm2835_spi *bs,
u32 cs)
@@ -413,9 +477,9 @@ static void bcm2835_spi_transfer_prologue(struct spi_master *master,
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(master);
+ bcm2835_spi_reset_hw(ctlr);
- dma_sync_single_for_device(master->dma_rx->device->dev,
+ dma_sync_single_for_device(ctlr->dma_rx->device->dev,
sg_dma_address(&tfr->rx_sg.sgl[0]),
bs->rx_prologue, DMA_FROM_DEVICE);
@@ -479,11 +543,11 @@ static void bcm2835_spi_undo_prologue(struct bcm2835_spi *bs)
static void bcm2835_spi_dma_done(void *data)
{
- struct spi_master *master = data;
- struct bcm2835_spi *bs = spi_master_get_devdata(master);
+ struct spi_controller *ctlr = data;
+ struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
/* reset fifo and HW */
- bcm2835_spi_reset_hw(master);
+ bcm2835_spi_reset_hw(ctlr);
/* and terminate tx-dma as we do not have an irq for it
* because when the rx dma will terminate and this callback
@@ -491,15 +555,15 @@ static void bcm2835_spi_dma_done(void *data)
* situation otherwise...
*/
if (cmpxchg(&bs->dma_pending, true, false)) {
- dmaengine_terminate_async(master->dma_tx);
+ dmaengine_terminate_async(ctlr->dma_tx);
bcm2835_spi_undo_prologue(bs);
}
/* and mark as completed */;
- complete(&master->xfer_completion);
+ complete(&ctlr->xfer_completion);
}
-static int bcm2835_spi_prepare_sg(struct spi_master *master,
+static int bcm2835_spi_prepare_sg(struct spi_controller *ctlr,
struct spi_transfer *tfr,
bool is_tx)
{
@@ -514,14 +578,14 @@ static int bcm2835_spi_prepare_sg(struct spi_master *master,
if (is_tx) {
dir = DMA_MEM_TO_DEV;
- chan = master->dma_tx;
+ chan = ctlr->dma_tx;
nents = tfr->tx_sg.nents;
sgl = tfr->tx_sg.sgl;
flags = 0 /* no tx interrupt */;
} else {
dir = DMA_DEV_TO_MEM;
- chan = master->dma_rx;
+ chan = ctlr->dma_rx;
nents = tfr->rx_sg.nents;
sgl = tfr->rx_sg.sgl;
flags = DMA_PREP_INTERRUPT;
@@ -534,7 +598,7 @@ static int bcm2835_spi_prepare_sg(struct spi_master *master,
/* set callback for rx */
if (!is_tx) {
desc->callback = bcm2835_spi_dma_done;
- desc->callback_param = master;
+ desc->callback_param = ctlr;
}
/* submit it to DMA-engine */
@@ -543,27 +607,30 @@ static int bcm2835_spi_prepare_sg(struct spi_master *master,
return dma_submit_error(cookie);
}
-static int bcm2835_spi_transfer_one_dma(struct spi_master *master,
+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_master_get_devdata(master);
+ struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
int ret;
+ /* update usage statistics */
+ bs->count_transfer_dma++;
+
/*
* Transfer first few bytes without DMA if length of first TX or RX
* sglist entry is not a multiple of 4 bytes (hardware limitation).
*/
- bcm2835_spi_transfer_prologue(master, tfr, bs, cs);
+ bcm2835_spi_transfer_prologue(ctlr, tfr, bs, cs);
/* setup tx-DMA */
- ret = bcm2835_spi_prepare_sg(master, tfr, true);
+ ret = bcm2835_spi_prepare_sg(ctlr, tfr, true);
if (ret)
goto err_reset_hw;
/* start TX early */
- dma_async_issue_pending(master->dma_tx);
+ dma_async_issue_pending(ctlr->dma_tx);
/* mark as dma pending */
bs->dma_pending = 1;
@@ -579,27 +646,27 @@ static int bcm2835_spi_transfer_one_dma(struct spi_master *master,
* mapping of the rx buffers still takes place
* this saves 10us or more.
*/
- ret = bcm2835_spi_prepare_sg(master, tfr, false);
+ ret = bcm2835_spi_prepare_sg(ctlr, tfr, false);
if (ret) {
/* need to reset on errors */
- dmaengine_terminate_sync(master->dma_tx);
+ dmaengine_terminate_sync(ctlr->dma_tx);
bs->dma_pending = false;
goto err_reset_hw;
}
/* start rx dma late */
- dma_async_issue_pending(master->dma_rx);
+ dma_async_issue_pending(ctlr->dma_rx);
/* wait for wakeup in framework */
return 1;
err_reset_hw:
- bcm2835_spi_reset_hw(master);
+ bcm2835_spi_reset_hw(ctlr);
bcm2835_spi_undo_prologue(bs);
return ret;
}
-static bool bcm2835_spi_can_dma(struct spi_master *master,
+static bool bcm2835_spi_can_dma(struct spi_controller *ctlr,
struct spi_device *spi,
struct spi_transfer *tfr)
{
@@ -611,21 +678,21 @@ static bool bcm2835_spi_can_dma(struct spi_master *master,
return true;
}
-static void bcm2835_dma_release(struct spi_master *master)
+static void bcm2835_dma_release(struct spi_controller *ctlr)
{
- if (master->dma_tx) {
- dmaengine_terminate_sync(master->dma_tx);
- dma_release_channel(master->dma_tx);
- master->dma_tx = NULL;
+ if (ctlr->dma_tx) {
+ dmaengine_terminate_sync(ctlr->dma_tx);
+ dma_release_channel(ctlr->dma_tx);
+ ctlr->dma_tx = NULL;
}
- if (master->dma_rx) {
- dmaengine_terminate_sync(master->dma_rx);
- dma_release_channel(master->dma_rx);
- master->dma_rx = NULL;
+ if (ctlr->dma_rx) {
+ dmaengine_terminate_sync(ctlr->dma_rx);
+ dma_release_channel(ctlr->dma_rx);
+ ctlr->dma_rx = NULL;
}
}
-static void bcm2835_dma_init(struct spi_master *master, struct device *dev)
+static void bcm2835_dma_init(struct spi_controller *ctlr, struct device *dev)
{
struct dma_slave_config slave_config;
const __be32 *addr;
@@ -633,7 +700,7 @@ static void bcm2835_dma_init(struct spi_master *master, struct device *dev)
int ret;
/* base address in dma-space */
- addr = of_get_address(master->dev.of_node, 0, NULL, NULL);
+ addr = of_get_address(ctlr->dev.of_node, 0, NULL, NULL);
if (!addr) {
dev_err(dev, "could not get DMA-register address - not using dma mode\n");
goto err;
@@ -641,38 +708,36 @@ static void bcm2835_dma_init(struct spi_master *master, struct device *dev)
dma_reg_base = be32_to_cpup(addr);
/* get tx/rx dma */
- master->dma_tx = dma_request_slave_channel(dev, "tx");
- if (!master->dma_tx) {
+ ctlr->dma_tx = dma_request_slave_channel(dev, "tx");
+ if (!ctlr->dma_tx) {
dev_err(dev, "no tx-dma configuration found - not using dma mode\n");
goto err;
}
- master->dma_rx = dma_request_slave_channel(dev, "rx");
- if (!master->dma_rx) {
+ ctlr->dma_rx = dma_request_slave_channel(dev, "rx");
+ if (!ctlr->dma_rx) {
dev_err(dev, "no rx-dma configuration found - not using dma mode\n");
goto err_release;
}
/* configure DMAs */
- slave_config.direction = DMA_MEM_TO_DEV;
slave_config.dst_addr = (u32)(dma_reg_base + BCM2835_SPI_FIFO);
slave_config.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
- ret = dmaengine_slave_config(master->dma_tx, &slave_config);
+ ret = dmaengine_slave_config(ctlr->dma_tx, &slave_config);
if (ret)
goto err_config;
- slave_config.direction = DMA_DEV_TO_MEM;
slave_config.src_addr = (u32)(dma_reg_base + BCM2835_SPI_FIFO);
slave_config.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
- ret = dmaengine_slave_config(master->dma_rx, &slave_config);
+ ret = dmaengine_slave_config(ctlr->dma_rx, &slave_config);
if (ret)
goto err_config;
/* all went well, so set can_dma */
- master->can_dma = bcm2835_spi_can_dma;
+ ctlr->can_dma = bcm2835_spi_can_dma;
/* need to do TX AND RX DMA, so we need dummy buffers */
- master->flags = SPI_MASTER_MUST_RX | SPI_MASTER_MUST_TX;
+ ctlr->flags = SPI_CONTROLLER_MUST_RX | SPI_CONTROLLER_MUST_TX;
return;
@@ -680,20 +745,22 @@ err_config:
dev_err(dev, "issue configuring dma: %d - not using DMA mode\n",
ret);
err_release:
- bcm2835_dma_release(master);
+ bcm2835_dma_release(ctlr);
err:
return;
}
-static int bcm2835_spi_transfer_one_poll(struct spi_master *master,
+static int bcm2835_spi_transfer_one_poll(struct spi_controller *ctlr,
struct spi_device *spi,
struct spi_transfer *tfr,
- u32 cs,
- unsigned long long xfer_time_us)
+ u32 cs)
{
- struct bcm2835_spi *bs = spi_master_get_devdata(master);
+ struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
unsigned long timeout;
+ /* update usage statistics */
+ bs->count_transfer_polling++;
+
/* enable HW block without interrupts */
bcm2835_wr(bs, BCM2835_SPI_CS, cs | BCM2835_SPI_CS_TA);
@@ -703,8 +770,8 @@ static int bcm2835_spi_transfer_one_poll(struct spi_master *master,
*/
bcm2835_wr_fifo_blind(bs, BCM2835_SPI_FIFO_SIZE);
- /* set the timeout */
- timeout = jiffies + BCM2835_SPI_POLLING_JIFFIES;
+ /* set the timeout to at least 2 jiffies */
+ timeout = jiffies + 2 + HZ * polling_limit_us / 1000000;
/* loop until finished the transfer */
while (bs->rx_len) {
@@ -723,25 +790,28 @@ static int bcm2835_spi_transfer_one_poll(struct spi_master *master,
jiffies - timeout,
bs->tx_len, bs->rx_len);
/* fall back to interrupt mode */
- return bcm2835_spi_transfer_one_irq(master, spi,
+
+ /* update usage statistics */
+ bs->count_transfer_irq_after_polling++;
+
+ return bcm2835_spi_transfer_one_irq(ctlr, spi,
tfr, cs, false);
}
}
/* Transfer complete - reset SPI HW */
- bcm2835_spi_reset_hw(master);
+ bcm2835_spi_reset_hw(ctlr);
/* and return without waiting for completion */
return 0;
}
-static int bcm2835_spi_transfer_one(struct spi_master *master,
+static int bcm2835_spi_transfer_one(struct spi_controller *ctlr,
struct spi_device *spi,
struct spi_transfer *tfr)
{
- struct bcm2835_spi *bs = spi_master_get_devdata(master);
- unsigned long spi_hz, clk_hz, cdiv;
- unsigned long spi_used_hz;
- unsigned long long xfer_time_us;
+ 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);
/* set clock */
@@ -782,42 +852,49 @@ static int bcm2835_spi_transfer_one(struct spi_master *master,
bs->tx_len = tfr->len;
bs->rx_len = tfr->len;
- /* calculate the estimated time in us the transfer runs */
- xfer_time_us = (unsigned long long)tfr->len
- * 9 /* clocks/byte - SPI-HW waits 1 clock after each byte */
- * 1000000;
- do_div(xfer_time_us, spi_used_hz);
+ /* Calculate the estimated time in us the transfer runs. Note that
+ * there is 1 idle clocks cycles after each byte getting transferred
+ * so we have 9 cycles/byte. This is used to find the number of Hz
+ * per byte per polling limit. E.g., we can transfer 1 byte in 30 us
+ * 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;
- /* for short requests run polling*/
- if (xfer_time_us <= BCM2835_SPI_POLLING_LIMIT_US)
- return bcm2835_spi_transfer_one_poll(master, spi, tfr,
- cs, xfer_time_us);
+ /* run in polling mode for short transfers */
+ if (tfr->len < byte_limit)
+ return bcm2835_spi_transfer_one_poll(ctlr, spi, tfr, cs);
- /* run in dma mode if conditions are right */
- if (master->can_dma && bcm2835_spi_can_dma(master, spi, tfr))
- return bcm2835_spi_transfer_one_dma(master, spi, tfr, cs);
+ /* run in dma mode if conditions are right
+ * Note that unlike poll or interrupt mode DMA mode does not have
+ * 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);
/* run in interrupt-mode */
- return bcm2835_spi_transfer_one_irq(master, spi, tfr, cs, true);
+ return bcm2835_spi_transfer_one_irq(ctlr, spi, tfr, cs, true);
}
-static int bcm2835_spi_prepare_message(struct spi_master *master,
+static int bcm2835_spi_prepare_message(struct spi_controller *ctlr,
struct spi_message *msg)
{
struct spi_device *spi = msg->spi;
- struct bcm2835_spi *bs = spi_master_get_devdata(master);
+ struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
u32 cs = bcm2835_rd(bs, BCM2835_SPI_CS);
int ret;
- /*
- * 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(master, msg, 65532,
- GFP_KERNEL | GFP_DMA);
- if (ret)
- return 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;
+ }
cs &= ~(BCM2835_SPI_CS_CPOL | BCM2835_SPI_CS_CPHA);
@@ -831,19 +908,19 @@ static int bcm2835_spi_prepare_message(struct spi_master *master,
return 0;
}
-static void bcm2835_spi_handle_err(struct spi_master *master,
+static void bcm2835_spi_handle_err(struct spi_controller *ctlr,
struct spi_message *msg)
{
- struct bcm2835_spi *bs = spi_master_get_devdata(master);
+ 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(master->dma_tx);
- dmaengine_terminate_sync(master->dma_rx);
+ dmaengine_terminate_sync(ctlr->dma_tx);
+ dmaengine_terminate_sync(ctlr->dma_rx);
bcm2835_spi_undo_prologue(bs);
}
/* and reset */
- bcm2835_spi_reset_hw(master);
+ bcm2835_spi_reset_hw(ctlr);
}
static int chip_match_name(struct gpio_chip *chip, void *data)
@@ -900,85 +977,88 @@ static int bcm2835_spi_setup(struct spi_device *spi)
static int bcm2835_spi_probe(struct platform_device *pdev)
{
- struct spi_master *master;
+ struct spi_controller *ctlr;
struct bcm2835_spi *bs;
struct resource *res;
int err;
- master = spi_alloc_master(&pdev->dev, sizeof(*bs));
- if (!master) {
- dev_err(&pdev->dev, "spi_alloc_master() failed\n");
+ ctlr = spi_alloc_master(&pdev->dev, sizeof(*bs));
+ if (!ctlr)
return -ENOMEM;
- }
- platform_set_drvdata(pdev, master);
+ platform_set_drvdata(pdev, ctlr);
- master->mode_bits = BCM2835_SPI_MODE_BITS;
- master->bits_per_word_mask = SPI_BPW_MASK(8);
- master->num_chipselect = 3;
- master->setup = bcm2835_spi_setup;
- master->transfer_one = bcm2835_spi_transfer_one;
- master->handle_err = bcm2835_spi_handle_err;
- master->prepare_message = bcm2835_spi_prepare_message;
- master->dev.of_node = pdev->dev.of_node;
+ ctlr->mode_bits = BCM2835_SPI_MODE_BITS;
+ ctlr->bits_per_word_mask = SPI_BPW_MASK(8);
+ ctlr->num_chipselect = 3;
+ ctlr->setup = bcm2835_spi_setup;
+ 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_master_get_devdata(master);
+ bs = spi_controller_get_devdata(ctlr);
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
bs->regs = devm_ioremap_resource(&pdev->dev, res);
if (IS_ERR(bs->regs)) {
err = PTR_ERR(bs->regs);
- goto out_master_put;
+ goto out_controller_put;
}
bs->clk = devm_clk_get(&pdev->dev, NULL);
if (IS_ERR(bs->clk)) {
err = PTR_ERR(bs->clk);
dev_err(&pdev->dev, "could not get clk: %d\n", err);
- goto out_master_put;
+ goto out_controller_put;
}
bs->irq = platform_get_irq(pdev, 0);
if (bs->irq <= 0) {
dev_err(&pdev->dev, "could not get IRQ: %d\n", bs->irq);
err = bs->irq ? bs->irq : -ENODEV;
- goto out_master_put;
+ goto out_controller_put;
}
clk_prepare_enable(bs->clk);
- bcm2835_dma_init(master, &pdev->dev);
+ bcm2835_dma_init(ctlr, &pdev->dev);
/* 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), master);
+ dev_name(&pdev->dev), ctlr);
if (err) {
dev_err(&pdev->dev, "could not request IRQ: %d\n", err);
goto out_clk_disable;
}
- err = devm_spi_register_master(&pdev->dev, master);
+ err = devm_spi_register_controller(&pdev->dev, ctlr);
if (err) {
- dev_err(&pdev->dev, "could not register SPI master: %d\n", err);
+ dev_err(&pdev->dev, "could not register SPI controller: %d\n",
+ err);
goto out_clk_disable;
}
+ bcm2835_debugfs_create(bs, dev_name(&pdev->dev));
+
return 0;
out_clk_disable:
clk_disable_unprepare(bs->clk);
-out_master_put:
- spi_master_put(master);
+out_controller_put:
+ spi_controller_put(ctlr);
return err;
}
static int bcm2835_spi_remove(struct platform_device *pdev)
{
- struct spi_master *master = platform_get_drvdata(pdev);
- struct bcm2835_spi *bs = spi_master_get_devdata(master);
+ struct spi_controller *ctlr = platform_get_drvdata(pdev);
+ struct bcm2835_spi *bs = spi_controller_get_devdata(ctlr);
+
+ bcm2835_debugfs_remove(bs);
/* Clear FIFOs, and disable the HW block */
bcm2835_wr(bs, BCM2835_SPI_CS,
@@ -986,7 +1066,7 @@ static int bcm2835_spi_remove(struct platform_device *pdev)
clk_disable_unprepare(bs->clk);
- bcm2835_dma_release(master);
+ bcm2835_dma_release(ctlr);
return 0;
}