aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAndy Shevchenko <andriy.shevchenko@linux.intel.com>2015-03-02 07:58:56 -0500
committerMark Brown <broonie@kernel.org>2015-03-06 15:29:03 -0500
commit0b2e8915ead06b21d8f2360bfc28e747c4c0df8c (patch)
tree167bb3806be464fcb50cae5769da30ba280f829b
parent45746e82cf89f432f9c986a52137d8a64b78aba9 (diff)
spi: dw: program registers as soon as possible
This patch refactors the code in pump_transfers() to reprogram the registers immediately when we have a new configuration data. The behaviour is slightly modified: - chip is always disabled and reenabled - CTRL0 is always reprogrammed This change allows to do a further refactoring and simplier conversion to use SPI core DMA routines in the future. Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com> Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--drivers/spi/spi-dw.c38
1 files changed, 15 insertions, 23 deletions
diff --git a/drivers/spi/spi-dw.c b/drivers/spi/spi-dw.c
index 321965607fc0..9a855bb00694 100644
--- a/drivers/spi/spi-dw.c
+++ b/drivers/spi/spi-dw.c
@@ -409,6 +409,8 @@ static void pump_transfers(unsigned long data)
409 if (chip != dws->prev_chip) 409 if (chip != dws->prev_chip)
410 cs_change = 1; 410 cs_change = 1;
411 411
412 spi_enable_chip(dws, 0);
413
412 cr0 = chip->cr0; 414 cr0 = chip->cr0;
413 415
414 /* Handle per transfer options for bpw and speed */ 416 /* Handle per transfer options for bpw and speed */
@@ -423,6 +425,8 @@ static void pump_transfers(unsigned long data)
423 425
424 chip->speed_hz = speed; 426 chip->speed_hz = speed;
425 chip->clk_div = clk_div; 427 chip->clk_div = clk_div;
428
429 spi_set_clk(dws, chip->clk_div);
426 } 430 }
427 } 431 }
428 if (transfer->bits_per_word) { 432 if (transfer->bits_per_word) {
@@ -451,44 +455,32 @@ static void pump_transfers(unsigned long data)
451 cr0 |= (chip->tmode << SPI_TMOD_OFFSET); 455 cr0 |= (chip->tmode << SPI_TMOD_OFFSET);
452 } 456 }
453 457
458 dw_writew(dws, DW_SPI_CTRL0, cr0);
459 spi_chip_sel(dws, spi, 1);
460
454 /* Check if current transfer is a DMA transaction */ 461 /* Check if current transfer is a DMA transaction */
455 dws->dma_mapped = map_dma_buffers(dws); 462 dws->dma_mapped = map_dma_buffers(dws);
456 463
464 /* For poll mode just disable all interrupts */
465 spi_mask_intr(dws, 0xff);
466
457 /* 467 /*
458 * Interrupt mode 468 * Interrupt mode
459 * we only need set the TXEI IRQ, as TX/RX always happen syncronizely 469 * we only need set the TXEI IRQ, as TX/RX always happen syncronizely
460 */ 470 */
461 if (!dws->dma_mapped && !chip->poll_mode) { 471 if (!dws->dma_mapped && !chip->poll_mode) {
462 txlevel = min_t(u16, dws->fifo_len / 2, dws->len / dws->n_bytes); 472 txlevel = min_t(u16, dws->fifo_len / 2, dws->len / dws->n_bytes);
473 dw_writew(dws, DW_SPI_TXFLTR, txlevel);
463 474
475 /* Set the interrupt mask */
464 imask |= SPI_INT_TXEI | SPI_INT_TXOI | 476 imask |= SPI_INT_TXEI | SPI_INT_TXOI |
465 SPI_INT_RXUI | SPI_INT_RXOI; 477 SPI_INT_RXUI | SPI_INT_RXOI;
478 spi_umask_intr(dws, imask);
479
466 dws->transfer_handler = interrupt_transfer; 480 dws->transfer_handler = interrupt_transfer;
467 } 481 }
468 482
469 /* 483 spi_enable_chip(dws, 1);
470 * Reprogram registers only if
471 * 1. chip select changes
472 * 2. clk_div is changed
473 * 3. control value changes
474 */
475 if (dw_readw(dws, DW_SPI_CTRL0) != cr0 || cs_change || clk_div || imask) {
476 spi_enable_chip(dws, 0);
477
478 dw_writew(dws, DW_SPI_CTRL0, cr0);
479
480 spi_set_clk(dws, chip->clk_div);
481 spi_chip_sel(dws, spi, 1);
482
483 /* Set the interrupt mask, for poll mode just disable all int */
484 spi_mask_intr(dws, 0xff);
485 if (imask)
486 spi_umask_intr(dws, imask);
487 if (txlevel)
488 dw_writew(dws, DW_SPI_TXFLTR, txlevel);
489
490 spi_enable_chip(dws, 1);
491 }
492 484
493 if (cs_change) 485 if (cs_change)
494 dws->prev_chip = chip; 486 dws->prev_chip = chip;