aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
authorEzequiel Garcia <ezequiel.garcia@imgtec.com>2015-04-08 13:03:16 -0400
committerMark Brown <broonie@kernel.org>2015-04-08 16:04:51 -0400
commit8c2c8c03cdcb9b0a75b5585e611715fdd8096c38 (patch)
tree87bfe4fa8dd103b80559e44e94d07bba39aced88 /drivers/spi
parenta25202b04f17830dbf241a24838f8c8575a56611 (diff)
spi: img-spfi: Control CS lines with GPIO
When the CONTINUE bit is set, the interrupt status we are polling to identify if a transaction has finished can be sporadic. Even though the transfer has finished, the interrupt status may erroneously indicate that there is still data in the FIFO. This behaviour causes random timeouts in large PIO transfers. Instead of using the CONTINUE bit to control the CS lines, use the SPI core's CS GPIO handling. Also, now that the CONTINUE bit is not being used, we can poll for the ALLDONE interrupt to indicate transfer completion. Signed-off-by: Sifan Naeem <sifan.naeem@imgtec.com> Signed-off-by: Ezequiel Garcia <ezequiel.garcia@imgtec.com> Signed-off-by: Andrew Bresticker <abrestic@chromium.org> Signed-off-by: Mark Brown <broonie@kernel.org>
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/spi-img-spfi.c92
1 files changed, 44 insertions, 48 deletions
diff --git a/drivers/spi/spi-img-spfi.c b/drivers/spi/spi-img-spfi.c
index dedb7d880ccc..788e2b176a4f 100644
--- a/drivers/spi/spi-img-spfi.c
+++ b/drivers/spi/spi-img-spfi.c
@@ -12,6 +12,7 @@
12#include <linux/clk.h> 12#include <linux/clk.h>
13#include <linux/delay.h> 13#include <linux/delay.h>
14#include <linux/dmaengine.h> 14#include <linux/dmaengine.h>
15#include <linux/gpio.h>
15#include <linux/interrupt.h> 16#include <linux/interrupt.h>
16#include <linux/io.h> 17#include <linux/io.h>
17#include <linux/irq.h> 18#include <linux/irq.h>
@@ -122,35 +123,31 @@ static inline void spfi_start(struct img_spfi *spfi)
122 spfi_writel(spfi, val, SPFI_CONTROL); 123 spfi_writel(spfi, val, SPFI_CONTROL);
123} 124}
124 125
125static inline void spfi_stop(struct img_spfi *spfi)
126{
127 u32 val;
128
129 val = spfi_readl(spfi, SPFI_CONTROL);
130 val &= ~SPFI_CONTROL_SPFI_EN;
131 spfi_writel(spfi, val, SPFI_CONTROL);
132}
133
134static inline void spfi_reset(struct img_spfi *spfi) 126static inline void spfi_reset(struct img_spfi *spfi)
135{ 127{
136 spfi_writel(spfi, SPFI_CONTROL_SOFT_RESET, SPFI_CONTROL); 128 spfi_writel(spfi, SPFI_CONTROL_SOFT_RESET, SPFI_CONTROL);
137 spfi_writel(spfi, 0, SPFI_CONTROL); 129 spfi_writel(spfi, 0, SPFI_CONTROL);
138} 130}
139 131
140static void spfi_flush_tx_fifo(struct img_spfi *spfi) 132static int spfi_wait_all_done(struct img_spfi *spfi)
141{ 133{
142 unsigned long timeout = jiffies + msecs_to_jiffies(10); 134 unsigned long timeout = jiffies + msecs_to_jiffies(50);
143 135
144 spfi_writel(spfi, SPFI_INTERRUPT_SDE, SPFI_INTERRUPT_CLEAR);
145 while (time_before(jiffies, timeout)) { 136 while (time_before(jiffies, timeout)) {
146 if (spfi_readl(spfi, SPFI_INTERRUPT_STATUS) & 137 u32 status = spfi_readl(spfi, SPFI_INTERRUPT_STATUS);
147 SPFI_INTERRUPT_SDE) 138
148 return; 139 if (status & SPFI_INTERRUPT_ALLDONETRIG) {
140 spfi_writel(spfi, SPFI_INTERRUPT_ALLDONETRIG,
141 SPFI_INTERRUPT_CLEAR);
142 return 0;
143 }
149 cpu_relax(); 144 cpu_relax();
150 } 145 }
151 146
152 dev_err(spfi->dev, "Timed out waiting for FIFO to drain\n"); 147 dev_err(spfi->dev, "Timed out waiting for transaction to complete\n");
153 spfi_reset(spfi); 148 spfi_reset(spfi);
149
150 return -ETIMEDOUT;
154} 151}
155 152
156static unsigned int spfi_pio_write32(struct img_spfi *spfi, const u32 *buf, 153static unsigned int spfi_pio_write32(struct img_spfi *spfi, const u32 *buf,
@@ -236,6 +233,7 @@ static int img_spfi_start_pio(struct spi_master *master,
236 const void *tx_buf = xfer->tx_buf; 233 const void *tx_buf = xfer->tx_buf;
237 void *rx_buf = xfer->rx_buf; 234 void *rx_buf = xfer->rx_buf;
238 unsigned long timeout; 235 unsigned long timeout;
236 int ret;
239 237
240 if (tx_buf) 238 if (tx_buf)
241 tx_bytes = xfer->len; 239 tx_bytes = xfer->len;
@@ -268,15 +266,15 @@ static int img_spfi_start_pio(struct spi_master *master,
268 cpu_relax(); 266 cpu_relax();
269 } 267 }
270 268
269 ret = spfi_wait_all_done(spfi);
270 if (ret < 0)
271 return ret;
272
271 if (rx_bytes > 0 || tx_bytes > 0) { 273 if (rx_bytes > 0 || tx_bytes > 0) {
272 dev_err(spfi->dev, "PIO transfer timed out\n"); 274 dev_err(spfi->dev, "PIO transfer timed out\n");
273 return -ETIMEDOUT; 275 return -ETIMEDOUT;
274 } 276 }
275 277
276 if (tx_buf)
277 spfi_flush_tx_fifo(spfi);
278 spfi_stop(spfi);
279
280 return 0; 278 return 0;
281} 279}
282 280
@@ -285,14 +283,12 @@ static void img_spfi_dma_rx_cb(void *data)
285 struct img_spfi *spfi = data; 283 struct img_spfi *spfi = data;
286 unsigned long flags; 284 unsigned long flags;
287 285
288 spin_lock_irqsave(&spfi->lock, flags); 286 spfi_wait_all_done(spfi);
289 287
288 spin_lock_irqsave(&spfi->lock, flags);
290 spfi->rx_dma_busy = false; 289 spfi->rx_dma_busy = false;
291 if (!spfi->tx_dma_busy) { 290 if (!spfi->tx_dma_busy)
292 spfi_stop(spfi);
293 spi_finalize_current_transfer(spfi->master); 291 spi_finalize_current_transfer(spfi->master);
294 }
295
296 spin_unlock_irqrestore(&spfi->lock, flags); 292 spin_unlock_irqrestore(&spfi->lock, flags);
297} 293}
298 294
@@ -301,16 +297,12 @@ static void img_spfi_dma_tx_cb(void *data)
301 struct img_spfi *spfi = data; 297 struct img_spfi *spfi = data;
302 unsigned long flags; 298 unsigned long flags;
303 299
304 spfi_flush_tx_fifo(spfi); 300 spfi_wait_all_done(spfi);
305 301
306 spin_lock_irqsave(&spfi->lock, flags); 302 spin_lock_irqsave(&spfi->lock, flags);
307
308 spfi->tx_dma_busy = false; 303 spfi->tx_dma_busy = false;
309 if (!spfi->rx_dma_busy) { 304 if (!spfi->rx_dma_busy)
310 spfi_stop(spfi);
311 spi_finalize_current_transfer(spfi->master); 305 spi_finalize_current_transfer(spfi->master);
312 }
313
314 spin_unlock_irqrestore(&spfi->lock, flags); 306 spin_unlock_irqrestore(&spfi->lock, flags);
315} 307}
316 308
@@ -445,6 +437,25 @@ static int img_spfi_unprepare(struct spi_master *master,
445 return 0; 437 return 0;
446} 438}
447 439
440static int img_spfi_setup(struct spi_device *spi)
441{
442 int ret;
443
444 ret = gpio_request_one(spi->cs_gpio, (spi->mode & SPI_CS_HIGH) ?
445 GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH,
446 dev_name(&spi->dev));
447 if (ret)
448 dev_err(&spi->dev, "can't request chipselect gpio %d\n",
449 spi->cs_gpio);
450
451 return ret;
452}
453
454static void img_spfi_cleanup(struct spi_device *spi)
455{
456 gpio_free(spi->cs_gpio);
457}
458
448static void img_spfi_config(struct spi_master *master, struct spi_device *spi, 459static void img_spfi_config(struct spi_master *master, struct spi_device *spi,
449 struct spi_transfer *xfer) 460 struct spi_transfer *xfer)
450{ 461{
@@ -480,10 +491,6 @@ static void img_spfi_config(struct spi_master *master, struct spi_device *spi,
480 else if (xfer->tx_nbits == SPI_NBITS_QUAD && 491 else if (xfer->tx_nbits == SPI_NBITS_QUAD &&
481 xfer->rx_nbits == SPI_NBITS_QUAD) 492 xfer->rx_nbits == SPI_NBITS_QUAD)
482 val |= SPFI_CONTROL_TMODE_QUAD << SPFI_CONTROL_TMODE_SHIFT; 493 val |= SPFI_CONTROL_TMODE_QUAD << SPFI_CONTROL_TMODE_SHIFT;
483 val &= ~SPFI_CONTROL_CONTINUE;
484 if (!xfer->cs_change && !list_is_last(&xfer->transfer_list,
485 &master->cur_msg->transfers))
486 val |= SPFI_CONTROL_CONTINUE;
487 spfi_writel(spfi, val, SPFI_CONTROL); 494 spfi_writel(spfi, val, SPFI_CONTROL);
488} 495}
489 496
@@ -510,17 +517,6 @@ static int img_spfi_transfer_one(struct spi_master *master,
510 return ret; 517 return ret;
511} 518}
512 519
513static void img_spfi_set_cs(struct spi_device *spi, bool enable)
514{
515 struct img_spfi *spfi = spi_master_get_devdata(spi->master);
516 u32 val;
517
518 val = spfi_readl(spfi, SPFI_PORT_STATE);
519 val &= ~(SPFI_PORT_STATE_DEV_SEL_MASK << SPFI_PORT_STATE_DEV_SEL_SHIFT);
520 val |= spi->chip_select << SPFI_PORT_STATE_DEV_SEL_SHIFT;
521 spfi_writel(spfi, val, SPFI_PORT_STATE);
522}
523
524static bool img_spfi_can_dma(struct spi_master *master, struct spi_device *spi, 520static bool img_spfi_can_dma(struct spi_master *master, struct spi_device *spi,
525 struct spi_transfer *xfer) 521 struct spi_transfer *xfer)
526{ 522{
@@ -609,13 +605,13 @@ static int img_spfi_probe(struct platform_device *pdev)
609 master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_TX_DUAL | SPI_RX_DUAL; 605 master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_TX_DUAL | SPI_RX_DUAL;
610 if (of_property_read_bool(spfi->dev->of_node, "img,supports-quad-mode")) 606 if (of_property_read_bool(spfi->dev->of_node, "img,supports-quad-mode"))
611 master->mode_bits |= SPI_TX_QUAD | SPI_RX_QUAD; 607 master->mode_bits |= SPI_TX_QUAD | SPI_RX_QUAD;
612 master->num_chipselect = 5;
613 master->dev.of_node = pdev->dev.of_node; 608 master->dev.of_node = pdev->dev.of_node;
614 master->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(8); 609 master->bits_per_word_mask = SPI_BPW_MASK(32) | SPI_BPW_MASK(8);
615 master->max_speed_hz = clk_get_rate(spfi->spfi_clk) / 4; 610 master->max_speed_hz = clk_get_rate(spfi->spfi_clk) / 4;
616 master->min_speed_hz = clk_get_rate(spfi->spfi_clk) / 512; 611 master->min_speed_hz = clk_get_rate(spfi->spfi_clk) / 512;
617 612
618 master->set_cs = img_spfi_set_cs; 613 master->setup = img_spfi_setup;
614 master->cleanup = img_spfi_cleanup;
619 master->transfer_one = img_spfi_transfer_one; 615 master->transfer_one = img_spfi_transfer_one;
620 master->prepare_message = img_spfi_prepare; 616 master->prepare_message = img_spfi_prepare;
621 master->unprepare_message = img_spfi_unprepare; 617 master->unprepare_message = img_spfi_unprepare;