aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi-xilinx.c
diff options
context:
space:
mode:
authorRicardo Ribalda Delgado <ricardo.ribalda@gmail.com>2015-01-28 07:23:54 -0500
committerMark Brown <broonie@kernel.org>2015-01-28 14:42:43 -0500
commit22417352f6b7f623495cc426680de75d725197df (patch)
treeed7f3c42cdfbf86bceb7f69da03bea06aad6b316 /drivers/spi/spi-xilinx.c
parentb563bfb8d76762fe5a4db1e4f983f3647d60e456 (diff)
spi/xilinx: Use polling mode on small transfers
Small transfers generally can be accomplished faster in polling mode. This patch select the transfer which size is bellow the buffer size to be done on polling mode Suggested-by: Mark Brown <broonie@kernel.org> Signed-off-by: Ricardo Ribalda Delgado <ricardo.ribalda@gmail.com> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/spi/spi-xilinx.c')
-rw-r--r--drivers/spi/spi-xilinx.c43
1 files changed, 25 insertions, 18 deletions
diff --git a/drivers/spi/spi-xilinx.c b/drivers/spi/spi-xilinx.c
index 026f4c59a941..337fda4e78a6 100644
--- a/drivers/spi/spi-xilinx.c
+++ b/drivers/spi/spi-xilinx.c
@@ -128,7 +128,6 @@ static void xilinx_spi_rx(struct xilinx_spi *xspi)
128static void xspi_init_hw(struct xilinx_spi *xspi) 128static void xspi_init_hw(struct xilinx_spi *xspi)
129{ 129{
130 void __iomem *regs_base = xspi->regs; 130 void __iomem *regs_base = xspi->regs;
131 u32 inhibit;
132 131
133 /* Reset the SPI device */ 132 /* Reset the SPI device */
134 xspi->write_fn(XIPIF_V123B_RESET_MASK, 133 xspi->write_fn(XIPIF_V123B_RESET_MASK,
@@ -138,22 +137,15 @@ static void xspi_init_hw(struct xilinx_spi *xspi)
138 */ 137 */
139 xspi->write_fn(XSPI_INTR_TX_EMPTY, 138 xspi->write_fn(XSPI_INTR_TX_EMPTY,
140 regs_base + XIPIF_V123B_IIER_OFFSET); 139 regs_base + XIPIF_V123B_IIER_OFFSET);
141 /* Enable the global IPIF interrupt */ 140 /* Disable the global IPIF interrupt */
142 if (xspi->irq >= 0) { 141 xspi->write_fn(0, regs_base + XIPIF_V123B_DGIER_OFFSET);
143 xspi->write_fn(XIPIF_V123B_GINTR_ENABLE,
144 regs_base + XIPIF_V123B_DGIER_OFFSET);
145 inhibit = XSPI_CR_TRANS_INHIBIT;
146 } else {
147 xspi->write_fn(0, regs_base + XIPIF_V123B_DGIER_OFFSET);
148 inhibit = 0;
149 }
150 /* Deselect the slave on the SPI bus */ 142 /* Deselect the slave on the SPI bus */
151 xspi->write_fn(0xffff, regs_base + XSPI_SSR_OFFSET); 143 xspi->write_fn(0xffff, regs_base + XSPI_SSR_OFFSET);
152 /* Disable the transmitter, enable Manual Slave Select Assertion, 144 /* Disable the transmitter, enable Manual Slave Select Assertion,
153 * put SPI controller into master mode, and enable it */ 145 * put SPI controller into master mode, and enable it */
154 xspi->write_fn(inhibit | XSPI_CR_MANUAL_SSELECT | 146 xspi->write_fn(XSPI_CR_MANUAL_SSELECT | XSPI_CR_MASTER_MODE |
155 XSPI_CR_MASTER_MODE | XSPI_CR_ENABLE | XSPI_CR_TXFIFO_RESET | 147 XSPI_CR_ENABLE | XSPI_CR_TXFIFO_RESET | XSPI_CR_RXFIFO_RESET,
156 XSPI_CR_RXFIFO_RESET, regs_base + XSPI_CR_OFFSET); 148 regs_base + XSPI_CR_OFFSET);
157} 149}
158 150
159static void xilinx_spi_chipselect(struct spi_device *spi, int is_on) 151static void xilinx_spi_chipselect(struct spi_device *spi, int is_on)
@@ -212,6 +204,8 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
212{ 204{
213 struct xilinx_spi *xspi = spi_master_get_devdata(spi->master); 205 struct xilinx_spi *xspi = spi_master_get_devdata(spi->master);
214 int remaining_words; /* the number of words left to transfer */ 206 int remaining_words; /* the number of words left to transfer */
207 bool use_irq = false;
208 u16 cr = 0;
215 209
216 /* We get here with transmitter inhibited */ 210 /* We get here with transmitter inhibited */
217 211
@@ -220,8 +214,20 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
220 remaining_words = t->len / xspi->bytes_per_word; 214 remaining_words = t->len / xspi->bytes_per_word;
221 reinit_completion(&xspi->done); 215 reinit_completion(&xspi->done);
222 216
217 if (xspi->irq >= 0 && remaining_words > xspi->buffer_size) {
218 use_irq = true;
219 xspi->write_fn(XSPI_INTR_TX_EMPTY,
220 xspi->regs + XIPIF_V123B_IISR_OFFSET);
221 /* Enable the global IPIF interrupt */
222 xspi->write_fn(XIPIF_V123B_GINTR_ENABLE,
223 xspi->regs + XIPIF_V123B_DGIER_OFFSET);
224 /* Inhibit irq to avoid spurious irqs on tx_empty*/
225 cr = xspi->read_fn(xspi->regs + XSPI_CR_OFFSET);
226 xspi->write_fn(cr | XSPI_CR_TRANS_INHIBIT,
227 xspi->regs + XSPI_CR_OFFSET);
228 }
229
223 while (remaining_words) { 230 while (remaining_words) {
224 u16 cr = 0;
225 int n_words, tx_words, rx_words; 231 int n_words, tx_words, rx_words;
226 232
227 n_words = min(remaining_words, xspi->buffer_size); 233 n_words = min(remaining_words, xspi->buffer_size);
@@ -234,9 +240,7 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
234 * longer 240 * longer
235 */ 241 */
236 242
237 if (xspi->irq >= 0) { 243 if (use_irq) {
238 cr = xspi->read_fn(xspi->regs + XSPI_CR_OFFSET) &
239 ~XSPI_CR_TRANS_INHIBIT;
240 xspi->write_fn(cr, xspi->regs + XSPI_CR_OFFSET); 244 xspi->write_fn(cr, xspi->regs + XSPI_CR_OFFSET);
241 wait_for_completion(&xspi->done); 245 wait_for_completion(&xspi->done);
242 } else 246 } else
@@ -249,7 +253,7 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
249 * transmitter while the Isr refills the transmit register/FIFO, 253 * transmitter while the Isr refills the transmit register/FIFO,
250 * or make sure it is stopped if we're done. 254 * or make sure it is stopped if we're done.
251 */ 255 */
252 if (xspi->irq >= 0) 256 if (use_irq)
253 xspi->write_fn(cr | XSPI_CR_TRANS_INHIBIT, 257 xspi->write_fn(cr | XSPI_CR_TRANS_INHIBIT,
254 xspi->regs + XSPI_CR_OFFSET); 258 xspi->regs + XSPI_CR_OFFSET);
255 259
@@ -261,6 +265,9 @@ static int xilinx_spi_txrx_bufs(struct spi_device *spi, struct spi_transfer *t)
261 remaining_words -= n_words; 265 remaining_words -= n_words;
262 } 266 }
263 267
268 if (use_irq)
269 xspi->write_fn(0, xspi->regs + XIPIF_V123B_DGIER_OFFSET);
270
264 return t->len; 271 return t->len;
265} 272}
266 273