aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi
diff options
context:
space:
mode:
authorSebastian Andrzej Siewior <bigeasy@linutronix.de>2010-11-22 20:12:17 -0500
committerSebastian Andrzej Siewior <bigeasy@linutronix.de>2010-12-02 11:55:13 -0500
commit579d3bb2ac1a351bbf536480a9ab38199bbf901d (patch)
tree7bea16be4415566fa430df5dcb25290411dec815 /drivers/spi
parent2a8626a9e2d86d114a2d9f813a1acebf9d53dd10 (diff)
spi/pxa2xx: Modify RX-Tresh instead of busy-loop for the remaining RX bytes.
After all TX bytes are sent, the driver spins while the SPI core is busy and then it spins for a "short" period of time until RX bytes are available. On Sodavile the busy flag disappears pretty quick and after that it takes approx ~130ms (sometimes less but not much) until there are bytes available in the RX FIFO. This patch removes the busy loop and modifies the RX threshould so we get woken up once the remainings bytes arrived. Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de> Signed-off-by: Dirk Brandewie <dirk.brandewie@gmail.com>
Diffstat (limited to 'drivers/spi')
-rw-r--r--drivers/spi/pxa2xx_spi.c56
1 files changed, 39 insertions, 17 deletions
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c
index a54685bb7e53..9ca6454cfadc 100644
--- a/drivers/spi/pxa2xx_spi.c
+++ b/drivers/spi/pxa2xx_spi.c
@@ -660,13 +660,25 @@ static irqreturn_t dma_transfer(struct driver_data *drv_data)
660 return IRQ_NONE; 660 return IRQ_NONE;
661} 661}
662 662
663static void reset_sccr1(struct driver_data *drv_data)
664{
665 void __iomem *reg = drv_data->ioaddr;
666 struct chip_data *chip = drv_data->cur_chip;
667 u32 sccr1_reg;
668
669 sccr1_reg = read_SSCR1(reg) & ~drv_data->int_cr1;
670 sccr1_reg &= ~SSCR1_RFT;
671 sccr1_reg |= chip->threshold;
672 write_SSCR1(sccr1_reg, reg);
673}
674
663static void int_error_stop(struct driver_data *drv_data, const char* msg) 675static void int_error_stop(struct driver_data *drv_data, const char* msg)
664{ 676{
665 void __iomem *reg = drv_data->ioaddr; 677 void __iomem *reg = drv_data->ioaddr;
666 678
667 /* Stop and reset SSP */ 679 /* Stop and reset SSP */
668 write_SSSR_CS(drv_data, drv_data->clear_sr); 680 write_SSSR_CS(drv_data, drv_data->clear_sr);
669 write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg); 681 reset_sccr1(drv_data);
670 if (!pxa25x_ssp_comp(drv_data)) 682 if (!pxa25x_ssp_comp(drv_data))
671 write_SSTO(0, reg); 683 write_SSTO(0, reg);
672 flush(drv_data); 684 flush(drv_data);
@@ -684,7 +696,7 @@ static void int_transfer_complete(struct driver_data *drv_data)
684 696
685 /* Stop SSP */ 697 /* Stop SSP */
686 write_SSSR_CS(drv_data, drv_data->clear_sr); 698 write_SSSR_CS(drv_data, drv_data->clear_sr);
687 write_SSCR1(read_SSCR1(reg) & ~drv_data->int_cr1, reg); 699 reset_sccr1(drv_data);
688 if (!pxa25x_ssp_comp(drv_data)) 700 if (!pxa25x_ssp_comp(drv_data))
689 write_SSTO(0, reg); 701 write_SSTO(0, reg);
690 702
@@ -739,24 +751,34 @@ static irqreturn_t interrupt_transfer(struct driver_data *drv_data)
739 } 751 }
740 752
741 if (drv_data->tx == drv_data->tx_end) { 753 if (drv_data->tx == drv_data->tx_end) {
742 write_SSCR1(read_SSCR1(reg) & ~SSCR1_TIE, reg); 754 u32 bytes_left;
743 /* PXA25x_SSP has no timeout, read trailing bytes */ 755 u32 sccr1_reg;
756
757 sccr1_reg = read_SSCR1(reg);
758 sccr1_reg &= ~SSCR1_TIE;
759
760 /*
761 * PXA25x_SSP has no timeout, set up rx threshould for the
762 * remaing RX bytes.
763 */
744 if (pxa25x_ssp_comp(drv_data)) { 764 if (pxa25x_ssp_comp(drv_data)) {
745 if (!wait_ssp_rx_stall(reg)) 765
746 { 766 sccr1_reg &= ~SSCR1_RFT;
747 int_error_stop(drv_data, "interrupt_transfer: " 767
748 "rx stall failed"); 768 bytes_left = drv_data->rx_end - drv_data->rx;
749 return IRQ_HANDLED; 769 switch (drv_data->n_bytes) {
750 } 770 case 4:
751 if (!drv_data->read(drv_data)) 771 bytes_left >>= 1;
752 { 772 case 2:
753 int_error_stop(drv_data, 773 bytes_left >>= 1;
754 "interrupt_transfer: "
755 "trailing byte read failed");
756 return IRQ_HANDLED;
757 } 774 }
758 int_transfer_complete(drv_data); 775
776 if (bytes_left > RX_THRESH_DFLT)
777 bytes_left = RX_THRESH_DFLT;
778
779 sccr1_reg |= SSCR1_RxTresh(bytes_left);
759 } 780 }
781 write_SSCR1(sccr1_reg, reg);
760 } 782 }
761 783
762 /* We did something */ 784 /* We did something */