Commit d7e58ad7 authored by Martin Sperl's avatar Martin Sperl Committed by Kleber Sacilotto de Souza

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

BugLink: https://bugs.launchpad.net/bugs/1845374

[ Upstream commit 7188a6f0 ]

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>
Signed-off-by: default avatarConnor Kuehl <connor.kuehl@canonical.com>
Signed-off-by: default avatarKhalid Elmously <khalid.elmously@canonical.com>
parent 9fabc03c
...@@ -181,23 +181,13 @@ static void bcm2835aux_spi_reset_hw(struct bcm2835aux_spi *bs) ...@@ -181,23 +181,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 */
...@@ -206,7 +196,6 @@ static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id) ...@@ -206,7 +196,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" */
...@@ -214,8 +203,21 @@ static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id) ...@@ -214,8 +203,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);
/* and if rx_len is 0 then wake up completion and disable spi */ /* and if rx_len is 0 then wake up completion and disable spi */
if (!bs->rx_len) { if (!bs->rx_len) {
...@@ -223,8 +225,7 @@ static irqreturn_t bcm2835aux_spi_interrupt(int irq, void *dev_id) ...@@ -223,8 +225,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,
...@@ -270,7 +271,6 @@ static int bcm2835aux_spi_transfer_one_poll(struct spi_master *master, ...@@ -270,7 +271,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]);
...@@ -281,24 +281,9 @@ static int bcm2835aux_spi_transfer_one_poll(struct spi_master *master, ...@@ -281,24 +281,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 */
if ((bs->tx_len) && (!(stat & BCM2835_AUX_SPI_STAT_TX_FULL))) {
bcm2835aux_wr_fifo(bs);
continue;
}
/* read data from fifo for both cases */ /* do common fifo handling */
if (!(stat & BCM2835_AUX_SPI_STAT_RX_EMPTY)) { bcm2835aux_spi_transfer_helper(bs);
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)) {
......
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