aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/spi/spi_imx.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/spi/spi_imx.c')
-rw-r--r--drivers/spi/spi_imx.c223
1 files changed, 114 insertions, 109 deletions
diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c
index d4ba640366b6..c730d05bfeb6 100644
--- a/drivers/spi/spi_imx.c
+++ b/drivers/spi/spi_imx.c
@@ -270,19 +270,26 @@ struct chip_data {
270 270
271static void pump_messages(struct work_struct *work); 271static void pump_messages(struct work_struct *work);
272 272
273static int flush(struct driver_data *drv_data) 273static void flush(struct driver_data *drv_data)
274{ 274{
275 unsigned long limit = loops_per_jiffy << 1;
276 void __iomem *regs = drv_data->regs; 275 void __iomem *regs = drv_data->regs;
277 volatile u32 d; 276 u32 control;
278 277
279 dev_dbg(&drv_data->pdev->dev, "flush\n"); 278 dev_dbg(&drv_data->pdev->dev, "flush\n");
279
280 /* Wait for end of transaction */
280 do { 281 do {
281 while (readl(regs + SPI_INT_STATUS) & SPI_STATUS_RR) 282 control = readl(regs + SPI_CONTROL);
282 d = readl(regs + SPI_RXDATA); 283 } while (control & SPI_CONTROL_XCH);
283 } while ((readl(regs + SPI_CONTROL) & SPI_CONTROL_XCH) && limit--); 284
285 /* Release chip select if requested, transfer delays are
286 handled in pump_transfers */
287 if (drv_data->cs_change)
288 drv_data->cs_control(SPI_CS_DEASSERT);
284 289
285 return limit; 290 /* Disable SPI to flush FIFOs */
291 writel(control & ~SPI_CONTROL_SPIEN, regs + SPI_CONTROL);
292 writel(control, regs + SPI_CONTROL);
286} 293}
287 294
288static void restore_state(struct driver_data *drv_data) 295static void restore_state(struct driver_data *drv_data)
@@ -570,6 +577,7 @@ static void giveback(struct spi_message *message, struct driver_data *drv_data)
570 writel(0, regs + SPI_INT_STATUS); 577 writel(0, regs + SPI_INT_STATUS);
571 writel(0, regs + SPI_DMA); 578 writel(0, regs + SPI_DMA);
572 579
580 /* Unconditioned deselct */
573 drv_data->cs_control(SPI_CS_DEASSERT); 581 drv_data->cs_control(SPI_CS_DEASSERT);
574 582
575 message->state = NULL; 583 message->state = NULL;
@@ -592,13 +600,10 @@ static void dma_err_handler(int channel, void *data, int errcode)
592 /* Disable both rx and tx dma channels */ 600 /* Disable both rx and tx dma channels */
593 imx_dma_disable(drv_data->rx_channel); 601 imx_dma_disable(drv_data->rx_channel);
594 imx_dma_disable(drv_data->tx_channel); 602 imx_dma_disable(drv_data->tx_channel);
595
596 if (flush(drv_data) == 0)
597 dev_err(&drv_data->pdev->dev,
598 "dma_err_handler - flush failed\n");
599
600 unmap_dma_buffers(drv_data); 603 unmap_dma_buffers(drv_data);
601 604
605 flush(drv_data);
606
602 msg->state = ERROR_STATE; 607 msg->state = ERROR_STATE;
603 tasklet_schedule(&drv_data->pump_transfers); 608 tasklet_schedule(&drv_data->pump_transfers);
604} 609}
@@ -612,8 +617,7 @@ static void dma_tx_handler(int channel, void *data)
612 imx_dma_disable(channel); 617 imx_dma_disable(channel);
613 618
614 /* Now waits for TX FIFO empty */ 619 /* Now waits for TX FIFO empty */
615 writel(readl(drv_data->regs + SPI_INT_STATUS) | SPI_INTEN_TE, 620 writel(SPI_INTEN_TE, drv_data->regs + SPI_INT_STATUS);
616 drv_data->regs + SPI_INT_STATUS);
617} 621}
618 622
619static irqreturn_t dma_transfer(struct driver_data *drv_data) 623static irqreturn_t dma_transfer(struct driver_data *drv_data)
@@ -621,19 +625,18 @@ static irqreturn_t dma_transfer(struct driver_data *drv_data)
621 u32 status; 625 u32 status;
622 struct spi_message *msg = drv_data->cur_msg; 626 struct spi_message *msg = drv_data->cur_msg;
623 void __iomem *regs = drv_data->regs; 627 void __iomem *regs = drv_data->regs;
624 unsigned long limit;
625 628
626 status = readl(regs + SPI_INT_STATUS); 629 status = readl(regs + SPI_INT_STATUS);
627 630
628 if ((status & SPI_INTEN_RO) && (status & SPI_STATUS_RO)) { 631 if ((status & (SPI_INTEN_RO | SPI_STATUS_RO))
632 == (SPI_INTEN_RO | SPI_STATUS_RO)) {
629 writel(status & ~SPI_INTEN, regs + SPI_INT_STATUS); 633 writel(status & ~SPI_INTEN, regs + SPI_INT_STATUS);
630 634
635 imx_dma_disable(drv_data->tx_channel);
631 imx_dma_disable(drv_data->rx_channel); 636 imx_dma_disable(drv_data->rx_channel);
632 unmap_dma_buffers(drv_data); 637 unmap_dma_buffers(drv_data);
633 638
634 if (flush(drv_data) == 0) 639 flush(drv_data);
635 dev_err(&drv_data->pdev->dev,
636 "dma_transfer - flush failed\n");
637 640
638 dev_warn(&drv_data->pdev->dev, 641 dev_warn(&drv_data->pdev->dev,
639 "dma_transfer - fifo overun\n"); 642 "dma_transfer - fifo overun\n");
@@ -649,20 +652,17 @@ static irqreturn_t dma_transfer(struct driver_data *drv_data)
649 652
650 if (drv_data->rx) { 653 if (drv_data->rx) {
651 /* Wait end of transfer before read trailing data */ 654 /* Wait end of transfer before read trailing data */
652 limit = loops_per_jiffy << 1; 655 while (readl(regs + SPI_CONTROL) & SPI_CONTROL_XCH)
653 while ((readl(regs + SPI_CONTROL) & SPI_CONTROL_XCH) && 656 cpu_relax();
654 limit--);
655
656 if (limit == 0)
657 dev_err(&drv_data->pdev->dev,
658 "dma_transfer - end of tx failed\n");
659 else
660 dev_dbg(&drv_data->pdev->dev,
661 "dma_transfer - end of tx\n");
662 657
663 imx_dma_disable(drv_data->rx_channel); 658 imx_dma_disable(drv_data->rx_channel);
664 unmap_dma_buffers(drv_data); 659 unmap_dma_buffers(drv_data);
665 660
661 /* Release chip select if requested, transfer delays are
662 handled in pump_transfers() */
663 if (drv_data->cs_change)
664 drv_data->cs_control(SPI_CS_DEASSERT);
665
666 /* Calculate number of trailing data and read them */ 666 /* Calculate number of trailing data and read them */
667 dev_dbg(&drv_data->pdev->dev, 667 dev_dbg(&drv_data->pdev->dev,
668 "dma_transfer - test = 0x%08X\n", 668 "dma_transfer - test = 0x%08X\n",
@@ -676,19 +676,12 @@ static irqreturn_t dma_transfer(struct driver_data *drv_data)
676 /* Write only transfer */ 676 /* Write only transfer */
677 unmap_dma_buffers(drv_data); 677 unmap_dma_buffers(drv_data);
678 678
679 if (flush(drv_data) == 0) 679 flush(drv_data);
680 dev_err(&drv_data->pdev->dev,
681 "dma_transfer - flush failed\n");
682 } 680 }
683 681
684 /* End of transfer, update total byte transfered */ 682 /* End of transfer, update total byte transfered */
685 msg->actual_length += drv_data->len; 683 msg->actual_length += drv_data->len;
686 684
687 /* Release chip select if requested, transfer delays are
688 handled in pump_transfers() */
689 if (drv_data->cs_change)
690 drv_data->cs_control(SPI_CS_DEASSERT);
691
692 /* Move to next transfer */ 685 /* Move to next transfer */
693 msg->state = next_transfer(drv_data); 686 msg->state = next_transfer(drv_data);
694 687
@@ -711,44 +704,43 @@ static irqreturn_t interrupt_wronly_transfer(struct driver_data *drv_data)
711 704
712 status = readl(regs + SPI_INT_STATUS); 705 status = readl(regs + SPI_INT_STATUS);
713 706
714 while (status & SPI_STATUS_TH) { 707 if (status & SPI_INTEN_TE) {
708 /* TXFIFO Empty Interrupt on the last transfered word */
709 writel(status & ~SPI_INTEN, regs + SPI_INT_STATUS);
715 dev_dbg(&drv_data->pdev->dev, 710 dev_dbg(&drv_data->pdev->dev,
716 "interrupt_wronly_transfer - status = 0x%08X\n", status); 711 "interrupt_wronly_transfer - end of tx\n");
717 712
718 /* Pump data */ 713 flush(drv_data);
719 if (write(drv_data)) {
720 writel(readl(regs + SPI_INT_STATUS) & ~SPI_INTEN,
721 regs + SPI_INT_STATUS);
722 714
723 dev_dbg(&drv_data->pdev->dev, 715 /* Update total byte transfered */
724 "interrupt_wronly_transfer - end of tx\n"); 716 msg->actual_length += drv_data->len;
725 717
726 if (flush(drv_data) == 0) 718 /* Move to next transfer */
727 dev_err(&drv_data->pdev->dev, 719 msg->state = next_transfer(drv_data);
728 "interrupt_wronly_transfer - "
729 "flush failed\n");
730 720
731 /* End of transfer, update total byte transfered */ 721 /* Schedule transfer tasklet */
732 msg->actual_length += drv_data->len; 722 tasklet_schedule(&drv_data->pump_transfers);
733 723
734 /* Release chip select if requested, transfer delays are 724 return IRQ_HANDLED;
735 handled in pump_transfers */ 725 } else {
736 if (drv_data->cs_change) 726 while (status & SPI_STATUS_TH) {
737 drv_data->cs_control(SPI_CS_DEASSERT); 727 dev_dbg(&drv_data->pdev->dev,
728 "interrupt_wronly_transfer - status = 0x%08X\n",
729 status);
738 730
739 /* Move to next transfer */ 731 /* Pump data */
740 msg->state = next_transfer(drv_data); 732 if (write(drv_data)) {
733 /* End of TXFIFO writes,
734 now wait until TXFIFO is empty */
735 writel(SPI_INTEN_TE, regs + SPI_INT_STATUS);
736 return IRQ_HANDLED;
737 }
741 738
742 /* Schedule transfer tasklet */ 739 status = readl(regs + SPI_INT_STATUS);
743 tasklet_schedule(&drv_data->pump_transfers);
744 740
745 return IRQ_HANDLED; 741 /* We did something */
742 handled = IRQ_HANDLED;
746 } 743 }
747
748 status = readl(regs + SPI_INT_STATUS);
749
750 /* We did something */
751 handled = IRQ_HANDLED;
752 } 744 }
753 745
754 return handled; 746 return handled;
@@ -758,45 +750,31 @@ static irqreturn_t interrupt_transfer(struct driver_data *drv_data)
758{ 750{
759 struct spi_message *msg = drv_data->cur_msg; 751 struct spi_message *msg = drv_data->cur_msg;
760 void __iomem *regs = drv_data->regs; 752 void __iomem *regs = drv_data->regs;
761 u32 status; 753 u32 status, control;
762 irqreturn_t handled = IRQ_NONE; 754 irqreturn_t handled = IRQ_NONE;
763 unsigned long limit; 755 unsigned long limit;
764 756
765 status = readl(regs + SPI_INT_STATUS); 757 status = readl(regs + SPI_INT_STATUS);
766 758
767 while (status & (SPI_STATUS_TH | SPI_STATUS_RO)) { 759 if (status & SPI_INTEN_TE) {
760 /* TXFIFO Empty Interrupt on the last transfered word */
761 writel(status & ~SPI_INTEN, regs + SPI_INT_STATUS);
768 dev_dbg(&drv_data->pdev->dev, 762 dev_dbg(&drv_data->pdev->dev,
769 "interrupt_transfer - status = 0x%08X\n", status); 763 "interrupt_transfer - end of tx\n");
770
771 if (status & SPI_STATUS_RO) {
772 writel(readl(regs + SPI_INT_STATUS) & ~SPI_INTEN,
773 regs + SPI_INT_STATUS);
774
775 dev_warn(&drv_data->pdev->dev,
776 "interrupt_transfer - fifo overun\n"
777 " data not yet written = %d\n"
778 " data not yet read = %d\n",
779 data_to_write(drv_data),
780 data_to_read(drv_data));
781
782 if (flush(drv_data) == 0)
783 dev_err(&drv_data->pdev->dev,
784 "interrupt_transfer - flush failed\n");
785
786 msg->state = ERROR_STATE;
787 tasklet_schedule(&drv_data->pump_transfers);
788 764
789 return IRQ_HANDLED; 765 if (msg->state == ERROR_STATE) {
790 } 766 /* RXFIFO overrun was detected and message aborted */
791 767 flush(drv_data);
792 /* Pump data */ 768 } else {
793 read(drv_data); 769 /* Wait for end of transaction */
794 if (write(drv_data)) { 770 do {
795 writel(readl(regs + SPI_INT_STATUS) & ~SPI_INTEN, 771 control = readl(regs + SPI_CONTROL);
796 regs + SPI_INT_STATUS); 772 } while (control & SPI_CONTROL_XCH);
797 773
798 dev_dbg(&drv_data->pdev->dev, 774 /* Release chip select if requested, transfer delays are
799 "interrupt_transfer - end of tx\n"); 775 handled in pump_transfers */
776 if (drv_data->cs_change)
777 drv_data->cs_control(SPI_CS_DEASSERT);
800 778
801 /* Read trailing bytes */ 779 /* Read trailing bytes */
802 limit = loops_per_jiffy << 1; 780 limit = loops_per_jiffy << 1;
@@ -810,27 +788,54 @@ static irqreturn_t interrupt_transfer(struct driver_data *drv_data)
810 dev_dbg(&drv_data->pdev->dev, 788 dev_dbg(&drv_data->pdev->dev,
811 "interrupt_transfer - end of rx\n"); 789 "interrupt_transfer - end of rx\n");
812 790
813 /* End of transfer, update total byte transfered */ 791 /* Update total byte transfered */
814 msg->actual_length += drv_data->len; 792 msg->actual_length += drv_data->len;
815 793
816 /* Release chip select if requested, transfer delays are
817 handled in pump_transfers */
818 if (drv_data->cs_change)
819 drv_data->cs_control(SPI_CS_DEASSERT);
820
821 /* Move to next transfer */ 794 /* Move to next transfer */
822 msg->state = next_transfer(drv_data); 795 msg->state = next_transfer(drv_data);
796 }
823 797
824 /* Schedule transfer tasklet */ 798 /* Schedule transfer tasklet */
825 tasklet_schedule(&drv_data->pump_transfers); 799 tasklet_schedule(&drv_data->pump_transfers);
826 800
827 return IRQ_HANDLED; 801 return IRQ_HANDLED;
828 } 802 } else {
803 while (status & (SPI_STATUS_TH | SPI_STATUS_RO)) {
804 dev_dbg(&drv_data->pdev->dev,
805 "interrupt_transfer - status = 0x%08X\n",
806 status);
807
808 if (status & SPI_STATUS_RO) {
809 /* RXFIFO overrun, abort message end wait
810 until TXFIFO is empty */
811 writel(SPI_INTEN_TE, regs + SPI_INT_STATUS);
812
813 dev_warn(&drv_data->pdev->dev,
814 "interrupt_transfer - fifo overun\n"
815 " data not yet written = %d\n"
816 " data not yet read = %d\n",
817 data_to_write(drv_data),
818 data_to_read(drv_data));
819
820 msg->state = ERROR_STATE;
821
822 return IRQ_HANDLED;
823 }
829 824
830 status = readl(regs + SPI_INT_STATUS); 825 /* Pump data */
826 read(drv_data);
827 if (write(drv_data)) {
828 /* End of TXFIFO writes,
829 now wait until TXFIFO is empty */
830 writel(SPI_INTEN_TE, regs + SPI_INT_STATUS);
831 return IRQ_HANDLED;
832 }
831 833
832 /* We did something */ 834 status = readl(regs + SPI_INT_STATUS);
833 handled = IRQ_HANDLED; 835
836 /* We did something */
837 handled = IRQ_HANDLED;
838 }
834 } 839 }
835 840
836 return handled; 841 return handled;