Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3bd81fd4 authored by Martin Sperl's avatar Martin Sperl Committed by Greg Kroah-Hartman
Browse files

spi: bcm2835aux: unifying code between polling and interrupt driven code



[ Upstream commit 7188a6f0eee3f1fae5d826cfc6d569657ff950ec ]

Sharing more code between polling and interrupt-driven mode.

Signed-off-by: default avatarMartin Sperl <kernel@martin.sperl.org>
Acked-by: default avatarStefan Wahren <stefan.wahren@i2se.com>
Signed-off-by: default avatarMark Brown <broonie@kernel.org>
Signed-off-by: default avatarSasha Levin <sashal@kernel.org>
parent 2aeaba90
Loading
Loading
Loading
Loading
+18 −33
Original line number Original line Diff line number Diff line
@@ -178,23 +178,13 @@ static void bcm2835aux_spi_reset_hw(struct bcm2835aux_spi *bs)
		      BCM2835_AUX_SPI_CNTL0_CLEARFIFO);
		      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 */
	/* check if we have data to read */
	while (bs->rx_len &&
	while (bs->rx_len &&
	       (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) &
	       (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) &
		  BCM2835_AUX_SPI_STAT_RX_EMPTY))) {
		  BCM2835_AUX_SPI_STAT_RX_EMPTY))) {
		bcm2835aux_rd_fifo(bs);
		bcm2835aux_rd_fifo(bs);
		ret = IRQ_HANDLED;
	}
	}


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


	/* and check if we have reached "done" */
	/* and check if we have reached "done" */
@@ -211,8 +200,21 @@ static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id)
	       (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) &
	       (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) &
		  BCM2835_AUX_SPI_STAT_BUSY))) {
		  BCM2835_AUX_SPI_STAT_BUSY))) {
		bcm2835aux_rd_fifo(bs);
		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) {
	if (!bs->tx_len) {
		/* disable tx fifo empty interrupt */
		/* disable tx fifo empty interrupt */
@@ -226,8 +228,7 @@ static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id)
		complete(&master->xfer_completion);
		complete(&master->xfer_completion);
	}
	}


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


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


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


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


		/* fill in tx fifo with remaining data */
		/* do common fifo handling */
		if ((bs->tx_len) && (!(stat & BCM2835_AUX_SPI_STAT_TX_FULL))) {
		bcm2835aux_spi_transfer_helper(bs);
			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;
		}


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