Skip to content

Commit

Permalink
spi: bcm2835aux: unifying code between polling and interrupt driven code
Browse files Browse the repository at this point in the history
Sharing more code between polling and interrupt-driven mode.

Signed-off-by: Martin Sperl <kernel@martin.sperl.org>
Acked-by: Stefan Wahren <stefan.wahren@i2se.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
  • Loading branch information
Martin Sperl authored and Mark Brown committed Apr 3, 2019
1 parent 4610964 commit 7188a6f
Showing 1 changed file with 18 additions and 33 deletions.
51 changes: 18 additions & 33 deletions drivers/spi/spi-bcm2835aux.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,23 +178,13 @@ static void bcm2835aux_spi_reset_hw(struct bcm2835aux_spi *bs)
BCM2835_AUX_SPI_CNTL0_CLEARFIFO);
}

static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id)
static void bcm2835aux_spi_transfer_helper(struct bcm2835aux_spi *bs)
{
struct spi_master *master = dev_id;
struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
irqreturn_t ret = IRQ_NONE;

/* IRQ may be shared, so return if our interrupts are disabled */
if (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_CNTL1) &
(BCM2835_AUX_SPI_CNTL1_TXEMPTY | BCM2835_AUX_SPI_CNTL1_IDLE)))
return ret;

/* check if we have data to read */
while (bs->rx_len &&
(!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) &
BCM2835_AUX_SPI_STAT_RX_EMPTY))) {
bcm2835aux_rd_fifo(bs);
ret = IRQ_HANDLED;
}

/* check if we have data to write */
Expand All @@ -203,16 +193,28 @@ static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id)
(!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) &
BCM2835_AUX_SPI_STAT_TX_FULL))) {
bcm2835aux_wr_fifo(bs);
ret = IRQ_HANDLED;
}

/* and check if we have reached "done" */
while (bs->rx_len &&
(!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) &
BCM2835_AUX_SPI_STAT_BUSY))) {
bcm2835aux_rd_fifo(bs);
ret = IRQ_HANDLED;
}
}

static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id)
{
struct spi_master *master = dev_id;
struct bcm2835aux_spi *bs = spi_master_get_devdata(master);

/* IRQ may be shared, so return if our interrupts are disabled */
if (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_CNTL1) &
(BCM2835_AUX_SPI_CNTL1_TXEMPTY | BCM2835_AUX_SPI_CNTL1_IDLE)))
return IRQ_NONE;

/* do common fifo handling */
bcm2835aux_spi_transfer_helper(bs);

if (!bs->tx_len) {
/* disable tx fifo empty interrupt */
Expand All @@ -226,8 +228,7 @@ static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id)
complete(&master->xfer_completion);
}

/* and return */
return ret;
return IRQ_HANDLED;
}

static int __bcm2835aux_spi_transfer_one_irq(struct spi_master *master,
Expand Down Expand Up @@ -273,7 +274,6 @@ static int bcm2835aux_spi_transfer_one_poll(struct spi_master *master,
{
struct bcm2835aux_spi *bs = spi_master_get_devdata(master);
unsigned long timeout;
u32 stat;

/* configure spi */
bcm2835aux_wr(bs, BCM2835_AUX_SPI_CNTL1, bs->cntl[1]);
Expand All @@ -284,24 +284,9 @@ static int bcm2835aux_spi_transfer_one_poll(struct spi_master *master,

/* loop until finished the transfer */
while (bs->rx_len) {
/* read status */
stat = bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT);

/* fill in tx fifo with remaining data */
if ((bs->tx_len) && (!(stat & BCM2835_AUX_SPI_STAT_TX_FULL))) {
bcm2835aux_wr_fifo(bs);
continue;
}

/* read data from fifo for both cases */
if (!(stat & BCM2835_AUX_SPI_STAT_RX_EMPTY)) {
bcm2835aux_rd_fifo(bs);
continue;
}
if (!(stat & BCM2835_AUX_SPI_STAT_BUSY)) {
bcm2835aux_rd_fifo(bs);
continue;
}
/* do common fifo handling */
bcm2835aux_spi_transfer_helper(bs);

/* there is still data pending to read check the timeout */
if (bs->rx_len && time_after(jiffies, timeout)) {
Expand Down

0 comments on commit 7188a6f

Please sign in to comment.