summaryrefslogtreecommitdiff
path: root/drivers/spi
diff options
context:
space:
mode:
authorSrinivasarao P <spathi@codeaurora.org>2019-09-11 10:07:56 +0530
committerSrinivasarao P <spathi@codeaurora.org>2019-09-11 10:08:38 +0530
commit79fcbddd736bfcc606ccf4555d0879af3b20da26 (patch)
tree34256cc6ab4ab9ce971a80b91127579b3157d916 /drivers/spi
parent4bd32b7ba749e007b5e2962e12c13afadee1e193 (diff)
parentda6d147f98d198c3d9059e609ca492a4824d9ef5 (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.c57
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)) {