spi: bcm2835aux: unifying code between polling and interrupt driven code
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>
This commit is contained in:
parent
4610964805
commit
7188a6f0ee
@ -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)) {
|
||||||
|
Loading…
Reference in New Issue
Block a user