diff options
author | Brian Niebuhr <bniebuhr@efjohnson.com> | 2010-08-23 07:09:19 -0400 |
---|---|---|
committer | Sekhar Nori <nsekhar@ti.com> | 2010-11-18 08:08:30 -0500 |
commit | 839c996ca8dd56f9ea80d7fc0c8b18b01394c82a (patch) | |
tree | f8c66ef8f4eaabfb9e4de0e7ca2bbf6038d5536a /drivers | |
parent | cf90fe73504764cbcc2552c7ea69b1866059db30 (diff) |
spi: davinci: simplify poll mode transfers
Use the fact that the get_tx and get_rx can now cope with
NULL buffer pointers to simplify the poll mode transfer
code.
While at it, check for SPI errors every transfer rather than
at the end of the whole transfer.
Signed-off-by: Brian Niebuhr <bniebuhr@efjohnson.com>
Tested-By: Michael Williamson <michael.williamson@criticallink.com>
Signed-off-by: Sekhar Nori <nsekhar@ti.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/spi/davinci_spi.c | 96 |
1 files changed, 41 insertions, 55 deletions
diff --git a/drivers/spi/davinci_spi.c b/drivers/spi/davinci_spi.c index 198f062da370..cd37697850cf 100644 --- a/drivers/spi/davinci_spi.c +++ b/drivers/spi/davinci_spi.c | |||
@@ -91,6 +91,10 @@ | |||
91 | #define SPIFLG_BITERR_MASK BIT(4) | 91 | #define SPIFLG_BITERR_MASK BIT(4) |
92 | #define SPIFLG_OVRRUN_MASK BIT(6) | 92 | #define SPIFLG_OVRRUN_MASK BIT(6) |
93 | #define SPIFLG_BUF_INIT_ACTIVE_MASK BIT(24) | 93 | #define SPIFLG_BUF_INIT_ACTIVE_MASK BIT(24) |
94 | #define SPIFLG_ERROR_MASK (SPIFLG_DLEN_ERR_MASK \ | ||
95 | | SPIFLG_TIMEOUT_MASK | SPIFLG_PARERR_MASK \ | ||
96 | | SPIFLG_DESYNC_MASK | SPIFLG_BITERR_MASK \ | ||
97 | | SPIFLG_OVRRUN_MASK) | ||
94 | 98 | ||
95 | #define SPIINT_DMA_REQ_EN BIT(16) | 99 | #define SPIINT_DMA_REQ_EN BIT(16) |
96 | 100 | ||
@@ -601,10 +605,10 @@ static int davinci_spi_check_error(struct davinci_spi *davinci_spi, | |||
601 | static int davinci_spi_bufs_pio(struct spi_device *spi, struct spi_transfer *t) | 605 | static int davinci_spi_bufs_pio(struct spi_device *spi, struct spi_transfer *t) |
602 | { | 606 | { |
603 | struct davinci_spi *davinci_spi; | 607 | struct davinci_spi *davinci_spi; |
604 | int status, count, ret; | 608 | int ret; |
605 | u8 conv; | 609 | int rcount, wcount; |
606 | u32 tx_data, data1_reg_val; | 610 | u32 tx_data, data1_reg_val; |
607 | u32 buf_val, flg_val; | 611 | u32 errors = 0; |
608 | struct davinci_spi_platform_data *pdata; | 612 | struct davinci_spi_platform_data *pdata; |
609 | 613 | ||
610 | davinci_spi = spi_master_get_devdata(spi->master); | 614 | davinci_spi = spi_master_get_devdata(spi->master); |
@@ -612,70 +616,51 @@ static int davinci_spi_bufs_pio(struct spi_device *spi, struct spi_transfer *t) | |||
612 | 616 | ||
613 | davinci_spi->tx = t->tx_buf; | 617 | davinci_spi->tx = t->tx_buf; |
614 | davinci_spi->rx = t->rx_buf; | 618 | davinci_spi->rx = t->rx_buf; |
615 | 619 | wcount = t->len / davinci_spi->bytes_per_word[spi->chip_select]; | |
616 | /* convert len to words based on bits_per_word */ | 620 | rcount = wcount; |
617 | conv = davinci_spi->bytes_per_word[spi->chip_select]; | ||
618 | data1_reg_val = ioread32(davinci_spi->base + SPIDAT1); | ||
619 | 621 | ||
620 | ret = davinci_spi_bufs_prep(spi, davinci_spi); | 622 | ret = davinci_spi_bufs_prep(spi, davinci_spi); |
621 | if (ret) | 623 | if (ret) |
622 | return ret; | 624 | return ret; |
623 | 625 | ||
626 | data1_reg_val = ioread32(davinci_spi->base + SPIDAT1); | ||
627 | |||
624 | /* Enable SPI */ | 628 | /* Enable SPI */ |
625 | set_io_bits(davinci_spi->base + SPIGCR1, SPIGCR1_SPIENA_MASK); | 629 | set_io_bits(davinci_spi->base + SPIGCR1, SPIGCR1_SPIENA_MASK); |
626 | 630 | ||
627 | count = t->len / conv; | ||
628 | |||
629 | clear_io_bits(davinci_spi->base + SPIINT, SPIINT_MASKALL); | 631 | clear_io_bits(davinci_spi->base + SPIINT, SPIINT_MASKALL); |
630 | 632 | ||
631 | /* Determine the command to execute READ or WRITE */ | 633 | /* start the transfer */ |
632 | if (t->tx_buf) { | 634 | wcount--; |
635 | tx_data = davinci_spi->get_tx(davinci_spi); | ||
636 | data1_reg_val &= 0xFFFF0000; | ||
637 | data1_reg_val |= tx_data & 0xFFFF; | ||
638 | iowrite32(data1_reg_val, davinci_spi->base + SPIDAT1); | ||
633 | 639 | ||
634 | while (1) { | 640 | while (rcount > 0 || wcount > 0) { |
635 | tx_data = davinci_spi->get_tx(davinci_spi); | ||
636 | 641 | ||
637 | data1_reg_val &= ~(0xFFFF); | 642 | u32 buf, status; |
638 | data1_reg_val |= (0xFFFF & tx_data); | ||
639 | |||
640 | buf_val = ioread32(davinci_spi->base + SPIBUF); | ||
641 | if ((buf_val & SPIBUF_TXFULL_MASK) == 0) { | ||
642 | iowrite32(data1_reg_val, | ||
643 | davinci_spi->base + SPIDAT1); | ||
644 | |||
645 | count--; | ||
646 | } | ||
647 | while (ioread32(davinci_spi->base + SPIBUF) | ||
648 | & SPIBUF_RXEMPTY_MASK) | ||
649 | cpu_relax(); | ||
650 | |||
651 | /* getting the returned byte */ | ||
652 | if (t->rx_buf) { | ||
653 | buf_val = ioread32(davinci_spi->base + SPIBUF); | ||
654 | davinci_spi->get_rx(buf_val, davinci_spi); | ||
655 | } | ||
656 | if (count <= 0) | ||
657 | break; | ||
658 | } | ||
659 | } else { | ||
660 | while (1) { | ||
661 | /* keeps the serial clock going */ | ||
662 | if ((ioread32(davinci_spi->base + SPIBUF) | ||
663 | & SPIBUF_TXFULL_MASK) == 0) | ||
664 | iowrite32(data1_reg_val, | ||
665 | davinci_spi->base + SPIDAT1); | ||
666 | 643 | ||
667 | while (ioread32(davinci_spi->base + SPIBUF) & | 644 | buf = ioread32(davinci_spi->base + SPIBUF); |
668 | SPIBUF_RXEMPTY_MASK) | ||
669 | cpu_relax(); | ||
670 | 645 | ||
671 | flg_val = ioread32(davinci_spi->base + SPIFLG); | 646 | if (!(buf & SPIBUF_RXEMPTY_MASK)) { |
672 | buf_val = ioread32(davinci_spi->base + SPIBUF); | 647 | davinci_spi->get_rx(buf & 0xFFFF, davinci_spi); |
648 | rcount--; | ||
649 | } | ||
673 | 650 | ||
674 | davinci_spi->get_rx(buf_val, davinci_spi); | 651 | status = ioread32(davinci_spi->base + SPIFLG); |
675 | 652 | ||
676 | count--; | 653 | if (unlikely(status & SPIFLG_ERROR_MASK)) { |
677 | if (count <= 0) | 654 | errors = status & SPIFLG_ERROR_MASK; |
678 | break; | 655 | break; |
656 | } | ||
657 | |||
658 | if (wcount > 0 && !(buf & SPIBUF_TXFULL_MASK)) { | ||
659 | wcount--; | ||
660 | tx_data = davinci_spi->get_tx(davinci_spi); | ||
661 | data1_reg_val &= ~0xFFFF; | ||
662 | data1_reg_val |= 0xFFFF & tx_data; | ||
663 | iowrite32(data1_reg_val, davinci_spi->base + SPIDAT1); | ||
679 | } | 664 | } |
680 | } | 665 | } |
681 | 666 | ||
@@ -683,11 +668,12 @@ static int davinci_spi_bufs_pio(struct spi_device *spi, struct spi_transfer *t) | |||
683 | * Check for bit error, desync error,parity error,timeout error and | 668 | * Check for bit error, desync error,parity error,timeout error and |
684 | * receive overflow errors | 669 | * receive overflow errors |
685 | */ | 670 | */ |
686 | status = ioread32(davinci_spi->base + SPIFLG); | 671 | if (errors) { |
687 | 672 | ret = davinci_spi_check_error(davinci_spi, errors); | |
688 | ret = davinci_spi_check_error(davinci_spi, status); | 673 | WARN(!ret, "%s: error reported but no error found!\n", |
689 | if (ret != 0) | 674 | dev_name(&spi->dev)); |
690 | return ret; | 675 | return ret; |
676 | } | ||
691 | 677 | ||
692 | return t->len; | 678 | return t->len; |
693 | } | 679 | } |