diff options
author | Srinivasarao P <spathi@codeaurora.org> | 2019-09-11 10:07:56 +0530 |
---|---|---|
committer | Srinivasarao P <spathi@codeaurora.org> | 2019-09-11 10:08:38 +0530 |
commit | 79fcbddd736bfcc606ccf4555d0879af3b20da26 (patch) | |
tree | 34256cc6ab4ab9ce971a80b91127579b3157d916 /drivers/spi | |
parent | 4bd32b7ba749e007b5e2962e12c13afadee1e193 (diff) | |
parent | da6d147f98d198c3d9059e609ca492a4824d9ef5 (diff) |
Merge android-4.4.192 (da6d147) into msm-4.4
* refs/heads/tmp-da6d147
Linux 4.4.192
net: stmmac: dwmac-rk: Don't fail if phy regulator is absent
net: fix skb use after free in netpoll
Revert "x86/apic: Include the LDR when clearing out APIC registers"
spi: bcm2835aux: fix corruptions for longer spi transfers
spi: bcm2835aux: remove dangerous uncontrolled read of fifo
spi: bcm2835aux: unifying code between polling and interrupt driven code
spi: bcm2835aux: ensure interrupts are enabled for shared handler
libceph: allow ceph_buffer_put() to receive a NULL ceph_buffer
KVM: arm/arm64: Only skip MMIO insn once
ceph: fix buffer free while holding i_ceph_lock in __ceph_setxattr()
IB/mlx4: Fix memory leaks
Tools: hv: kvp: eliminate 'may be used uninitialized' warning
ravb: Fix use-after-free ravb_tstamp_skb
wimax/i2400m: fix a memory leak bug
net: kalmia: fix memory leaks
cx82310_eth: fix a memory leak bug
net: myri10ge: fix memory leaks
cxgb4: fix a memory leak bug
gpio: Fix build error of function redefinition
ibmveth: Convert multicast list size for little-endian system
Bluetooth: btqca: Add a short delay before downloading the NVM
net: tc35815: Explicitly check NET_IP_ALIGN is not zero in tc35815_rx
net: tundra: tsi108: use spin_lock_irqsave instead of spin_lock_irq in IRQ context
Change-Id: I5109a0608129d345ee2a16a1315ef2edab23545a
Signed-off-by: Srinivasarao P <spathi@codeaurora.org>
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/spi-bcm2835aux.c | 57 |
1 files changed, 20 insertions, 37 deletions
diff --git a/drivers/spi/spi-bcm2835aux.c b/drivers/spi/spi-bcm2835aux.c index 7de6f8472a81..ca655593c5e0 100644 --- a/drivers/spi/spi-bcm2835aux.c +++ b/drivers/spi/spi-bcm2835aux.c @@ -181,19 +181,14 @@ 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; + u32 stat = bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT); /* check if we have data to read */ - while (bs->rx_len && - (!(bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT) & - BCM2835_AUX_SPI_STAT_RX_EMPTY))) { + for (; bs->rx_len && (stat & BCM2835_AUX_SPI_STAT_RX_LVL); + stat = bcm2835aux_rd(bs, BCM2835_AUX_SPI_STAT)) bcm2835aux_rd_fifo(bs); - ret = IRQ_HANDLED; - } /* check if we have data to write */ while (bs->tx_len && @@ -201,16 +196,21 @@ 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); /* and if rx_len is 0 then wake up completion and disable spi */ if (!bs->rx_len) { @@ -218,8 +218,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, @@ -265,7 +264,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]); @@ -276,24 +274,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)) { |