diff options
author | Andy Shevchenko <andriy.shevchenko@linux.intel.com> | 2015-03-02 07:58:56 -0500 |
---|---|---|
committer | Mark Brown <broonie@kernel.org> | 2015-03-06 15:29:03 -0500 |
commit | 0b2e8915ead06b21d8f2360bfc28e747c4c0df8c (patch) | |
tree | 167bb3806be464fcb50cae5769da30ba280f829b | |
parent | 45746e82cf89f432f9c986a52137d8a64b78aba9 (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.c | 38 |
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; |