diff options
author | Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com> | 2015-01-28 07:23:45 -0500 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2015-01-28 14:42:42 -0500 |
commit | d9f5881242db8f9dc8a262c4bc613ba6fcb66bfc (patch) | |
tree | 1070b4310e8c2626725e9b54b31caf338dbd8cb5 | |
parent | 5fe11cc09ce81b000b1deadcdec3813fcb423c8c (diff) |
spi/xilinx: Do not inhibit transmission in polling mode
When no irq is used, there is no need to inhibit the transmission for
every transaction. This inhibition was implemented to avoid a race
condition with the irq handler.
Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com>
Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r-- | drivers/spi/spi-xilinx.c | 25 |
1 files changed, 15 insertions, 10 deletions
diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c index f21e857d54b1..6656b2c82693 100644 --- a/drivers/spi/spi-xilinx.c +++ b/drivers/spi/spi-xilinx.c | |||
@@ -163,6 +163,7 @@ static void xspi_rx32(struct xilinx_spi *xspi) | |||
163 | static void xspi_init_hw(struct xilinx_spi *xspi) | 163 | static void xspi_init_hw(struct xilinx_spi *xspi) |
164 | { | 164 | { |
165 | void __iomem *regs_base = xspi->regs; | 165 | void __iomem *regs_base = xspi->regs; |
166 | u32 inhibit; | ||
166 | 167 | ||
167 | /* Reset the SPI device */ | 168 | /* Reset the SPI device */ |
168 | xspi->write_fn(XIPIF_V123B_RESET_MASK, | 169 | xspi->write_fn(XIPIF_V123B_RESET_MASK, |
@@ -173,16 +174,19 @@ static void xspi_init_hw(struct xilinx_spi *xspi) | |||
173 | xspi->write_fn(XSPI_INTR_TX_EMPTY, | 174 | xspi->write_fn(XSPI_INTR_TX_EMPTY, |
174 | regs_base + XIPIF_V123B_IIER_OFFSET); | 175 | regs_base + XIPIF_V123B_IIER_OFFSET); |
175 | /* Enable the global IPIF interrupt */ | 176 | /* Enable the global IPIF interrupt */ |
176 | if (xspi->irq >= 0) | 177 | if (xspi->irq >= 0) { |
177 | xspi->write_fn(XIPIF_V123B_GINTR_ENABLE, | 178 | xspi->write_fn(XIPIF_V123B_GINTR_ENABLE, |
178 | regs_base + XIPIF_V123B_DGIER_OFFSET); | 179 | regs_base + XIPIF_V123B_DGIER_OFFSET); |
179 | else | 180 | inhibit = XSPI_CR_TRANS_INHIBIT; |
181 | } else { | ||
180 | xspi->write_fn(0, regs_base + XIPIF_V123B_DGIER_OFFSET); | 182 | xspi->write_fn(0, regs_base + XIPIF_V123B_DGIER_OFFSET); |
183 | inhibit = 0; | ||
184 | } | ||
181 | /* Deselect the slave on the SPI bus */ | 185 | /* Deselect the slave on the SPI bus */ |
182 | xspi->write_fn(0xffff, regs_base + XSPI_SSR_OFFSET); | 186 | xspi->write_fn(0xffff, regs_base + XSPI_SSR_OFFSET); |
183 | /* Disable the transmitter, enable Manual Slave Select Assertion, | 187 | /* Disable the transmitter, enable Manual Slave Select Assertion, |
184 | * put SPI controller into master mode, and enable it */ | 188 | * put SPI controller into master mode, and enable it */ |
185 | xspi->write_fn(XSPI_CR_TRANS_INHIBIT | XSPI_CR_MANUAL_SSELECT | | 189 | xspi->write_fn(inhibit | XSPI_CR_MANUAL_SSELECT | |
186 | XSPI_CR_MASTER_MODE | XSPI_CR_ENABLE | XSPI_CR_TXFIFO_RESET | | 190 | XSPI_CR_MASTER_MODE | XSPI_CR_ENABLE | XSPI_CR_TXFIFO_RESET | |
187 | XSPI_CR_RXFIFO_RESET, regs_base + XSPI_CR_OFFSET); | 191 | XSPI_CR_RXFIFO_RESET, regs_base + XSPI_CR_OFFSET); |
188 | } | 192 | } |
@@ -252,7 +256,7 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) | |||
252 | reinit_completion(&xspi->done); | 256 | reinit_completion(&xspi->done); |
253 | 257 | ||
254 | while (xspi->remaining_bytes) { | 258 | while (xspi->remaining_bytes) { |
255 | u16 cr; | 259 | u16 cr = 0; |
256 | int n_words; | 260 | int n_words; |
257 | 261 | ||
258 | n_words = (xspi->remaining_bytes * 8) / xspi->bits_per_word; | 262 | n_words = (xspi->remaining_bytes * 8) / xspi->bits_per_word; |
@@ -263,13 +267,13 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) | |||
263 | /* Start the transfer by not inhibiting the transmitter any | 267 | /* Start the transfer by not inhibiting the transmitter any |
264 | * longer | 268 | * longer |
265 | */ | 269 | */ |
266 | cr = xspi->read_fn(xspi->regs + XSPI_CR_OFFSET) & | ||
267 | ~XSPI_CR_TRANS_INHIBIT; | ||
268 | xspi->write_fn(cr, xspi->regs + XSPI_CR_OFFSET); | ||
269 | 270 | ||
270 | if (xspi->irq >= 0) | 271 | if (xspi->irq >= 0) { |
272 | cr = xspi->read_fn(xspi->regs + XSPI_CR_OFFSET) & | ||
273 | ~XSPI_CR_TRANS_INHIBIT; | ||
274 | xspi->write_fn(cr, xspi->regs + XSPI_CR_OFFSET); | ||
271 | wait_for_completion(&xspi->done); | 275 | wait_for_completion(&xspi->done); |
272 | else | 276 | } else |
273 | while (!(xspi->read_fn(xspi->regs + XSPI_SR_OFFSET) & | 277 | while (!(xspi->read_fn(xspi->regs + XSPI_SR_OFFSET) & |
274 | XSPI_SR_TX_EMPTY_MASK)) | 278 | XSPI_SR_TX_EMPTY_MASK)) |
275 | ; | 279 | ; |
@@ -279,7 +283,8 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t) | |||
279 | * transmitter while the Isr refills the transmit register/FIFO, | 283 | * transmitter while the Isr refills the transmit register/FIFO, |
280 | * or make sure it is stopped if we're done. | 284 | * or make sure it is stopped if we're done. |
281 | */ | 285 | */ |
282 | xspi->write_fn(cr | XSPI_CR_TRANS_INHIBIT, | 286 | if (xspi->irq >= 0) |
287 | xspi->write_fn(cr | XSPI_CR_TRANS_INHIBIT, | ||
283 | xspi->regs + XSPI_CR_OFFSET); | 288 | xspi->regs + XSPI_CR_OFFSET); |
284 | 289 | ||
285 | /* Read out all the data from the Rx FIFO */ | 290 | /* Read out all the data from the Rx FIFO */ |