diff options
Diffstat (limited to 'drivers/rapidio/devices/tsi721.c')
-rw-r--r-- | drivers/rapidio/devices/tsi721.c | 211 |
1 files changed, 134 insertions, 77 deletions
diff --git a/drivers/rapidio/devices/tsi721.c b/drivers/rapidio/devices/tsi721.c index 30d2072f480b..722246cf20ab 100644 --- a/drivers/rapidio/devices/tsi721.c +++ b/drivers/rapidio/devices/tsi721.c | |||
@@ -108,6 +108,7 @@ static int tsi721_maint_dma(struct tsi721_device *priv, u32 sys_size, | |||
108 | u16 destid, u8 hopcount, u32 offset, int len, | 108 | u16 destid, u8 hopcount, u32 offset, int len, |
109 | u32 *data, int do_wr) | 109 | u32 *data, int do_wr) |
110 | { | 110 | { |
111 | void __iomem *regs = priv->regs + TSI721_DMAC_BASE(priv->mdma.ch_id); | ||
111 | struct tsi721_dma_desc *bd_ptr; | 112 | struct tsi721_dma_desc *bd_ptr; |
112 | u32 rd_count, swr_ptr, ch_stat; | 113 | u32 rd_count, swr_ptr, ch_stat; |
113 | int i, err = 0; | 114 | int i, err = 0; |
@@ -116,10 +117,9 @@ static int tsi721_maint_dma(struct tsi721_device *priv, u32 sys_size, | |||
116 | if (offset > (RIO_MAINT_SPACE_SZ - len) || (len != sizeof(u32))) | 117 | if (offset > (RIO_MAINT_SPACE_SZ - len) || (len != sizeof(u32))) |
117 | return -EINVAL; | 118 | return -EINVAL; |
118 | 119 | ||
119 | bd_ptr = priv->bdma[TSI721_DMACH_MAINT].bd_base; | 120 | bd_ptr = priv->mdma.bd_base; |
120 | 121 | ||
121 | rd_count = ioread32( | 122 | rd_count = ioread32(regs + TSI721_DMAC_DRDCNT); |
122 | priv->regs + TSI721_DMAC_DRDCNT(TSI721_DMACH_MAINT)); | ||
123 | 123 | ||
124 | /* Initialize DMA descriptor */ | 124 | /* Initialize DMA descriptor */ |
125 | bd_ptr[0].type_id = cpu_to_le32((DTYPE2 << 29) | (op << 19) | destid); | 125 | bd_ptr[0].type_id = cpu_to_le32((DTYPE2 << 29) | (op << 19) | destid); |
@@ -134,19 +134,18 @@ static int tsi721_maint_dma(struct tsi721_device *priv, u32 sys_size, | |||
134 | mb(); | 134 | mb(); |
135 | 135 | ||
136 | /* Start DMA operation */ | 136 | /* Start DMA operation */ |
137 | iowrite32(rd_count + 2, | 137 | iowrite32(rd_count + 2, regs + TSI721_DMAC_DWRCNT); |
138 | priv->regs + TSI721_DMAC_DWRCNT(TSI721_DMACH_MAINT)); | 138 | ioread32(regs + TSI721_DMAC_DWRCNT); |
139 | ioread32(priv->regs + TSI721_DMAC_DWRCNT(TSI721_DMACH_MAINT)); | ||
140 | i = 0; | 139 | i = 0; |
141 | 140 | ||
142 | /* Wait until DMA transfer is finished */ | 141 | /* Wait until DMA transfer is finished */ |
143 | while ((ch_stat = ioread32(priv->regs + | 142 | while ((ch_stat = ioread32(regs + TSI721_DMAC_STS)) |
144 | TSI721_DMAC_STS(TSI721_DMACH_MAINT))) & TSI721_DMAC_STS_RUN) { | 143 | & TSI721_DMAC_STS_RUN) { |
145 | udelay(1); | 144 | udelay(1); |
146 | if (++i >= 5000000) { | 145 | if (++i >= 5000000) { |
147 | dev_dbg(&priv->pdev->dev, | 146 | dev_dbg(&priv->pdev->dev, |
148 | "%s : DMA[%d] read timeout ch_status=%x\n", | 147 | "%s : DMA[%d] read timeout ch_status=%x\n", |
149 | __func__, TSI721_DMACH_MAINT, ch_stat); | 148 | __func__, priv->mdma.ch_id, ch_stat); |
150 | if (!do_wr) | 149 | if (!do_wr) |
151 | *data = 0xffffffff; | 150 | *data = 0xffffffff; |
152 | err = -EIO; | 151 | err = -EIO; |
@@ -162,13 +161,10 @@ static int tsi721_maint_dma(struct tsi721_device *priv, u32 sys_size, | |||
162 | __func__, ch_stat); | 161 | __func__, ch_stat); |
163 | dev_dbg(&priv->pdev->dev, "OP=%d : destid=%x hc=%x off=%x\n", | 162 | dev_dbg(&priv->pdev->dev, "OP=%d : destid=%x hc=%x off=%x\n", |
164 | do_wr ? MAINT_WR : MAINT_RD, destid, hopcount, offset); | 163 | do_wr ? MAINT_WR : MAINT_RD, destid, hopcount, offset); |
165 | iowrite32(TSI721_DMAC_INT_ALL, | 164 | iowrite32(TSI721_DMAC_INT_ALL, regs + TSI721_DMAC_INT); |
166 | priv->regs + TSI721_DMAC_INT(TSI721_DMACH_MAINT)); | 165 | iowrite32(TSI721_DMAC_CTL_INIT, regs + TSI721_DMAC_CTL); |
167 | iowrite32(TSI721_DMAC_CTL_INIT, | ||
168 | priv->regs + TSI721_DMAC_CTL(TSI721_DMACH_MAINT)); | ||
169 | udelay(10); | 166 | udelay(10); |
170 | iowrite32(0, priv->regs + | 167 | iowrite32(0, regs + TSI721_DMAC_DWRCNT); |
171 | TSI721_DMAC_DWRCNT(TSI721_DMACH_MAINT)); | ||
172 | udelay(1); | 168 | udelay(1); |
173 | if (!do_wr) | 169 | if (!do_wr) |
174 | *data = 0xffffffff; | 170 | *data = 0xffffffff; |
@@ -184,8 +180,8 @@ static int tsi721_maint_dma(struct tsi721_device *priv, u32 sys_size, | |||
184 | * NOTE: Skipping check and clear FIFO entries because we are waiting | 180 | * NOTE: Skipping check and clear FIFO entries because we are waiting |
185 | * for transfer to be completed. | 181 | * for transfer to be completed. |
186 | */ | 182 | */ |
187 | swr_ptr = ioread32(priv->regs + TSI721_DMAC_DSWP(TSI721_DMACH_MAINT)); | 183 | swr_ptr = ioread32(regs + TSI721_DMAC_DSWP); |
188 | iowrite32(swr_ptr, priv->regs + TSI721_DMAC_DSRP(TSI721_DMACH_MAINT)); | 184 | iowrite32(swr_ptr, regs + TSI721_DMAC_DSRP); |
189 | err_out: | 185 | err_out: |
190 | 186 | ||
191 | return err; | 187 | return err; |
@@ -541,6 +537,22 @@ static irqreturn_t tsi721_irqhandler(int irq, void *ptr) | |||
541 | tsi721_pw_handler(mport); | 537 | tsi721_pw_handler(mport); |
542 | } | 538 | } |
543 | 539 | ||
540 | #ifdef CONFIG_RAPIDIO_DMA_ENGINE | ||
541 | if (dev_int & TSI721_DEV_INT_BDMA_CH) { | ||
542 | int ch; | ||
543 | |||
544 | if (dev_ch_int & TSI721_INT_BDMA_CHAN_M) { | ||
545 | dev_dbg(&priv->pdev->dev, | ||
546 | "IRQ from DMA channel 0x%08x\n", dev_ch_int); | ||
547 | |||
548 | for (ch = 0; ch < TSI721_DMA_MAXCH; ch++) { | ||
549 | if (!(dev_ch_int & TSI721_INT_BDMA_CHAN(ch))) | ||
550 | continue; | ||
551 | tsi721_bdma_handler(&priv->bdma[ch]); | ||
552 | } | ||
553 | } | ||
554 | } | ||
555 | #endif | ||
544 | return IRQ_HANDLED; | 556 | return IRQ_HANDLED; |
545 | } | 557 | } |
546 | 558 | ||
@@ -553,18 +565,26 @@ static void tsi721_interrupts_init(struct tsi721_device *priv) | |||
553 | priv->regs + TSI721_SR_CHINT(IDB_QUEUE)); | 565 | priv->regs + TSI721_SR_CHINT(IDB_QUEUE)); |
554 | iowrite32(TSI721_SR_CHINT_IDBQRCV, | 566 | iowrite32(TSI721_SR_CHINT_IDBQRCV, |
555 | priv->regs + TSI721_SR_CHINTE(IDB_QUEUE)); | 567 | priv->regs + TSI721_SR_CHINTE(IDB_QUEUE)); |
556 | iowrite32(TSI721_INT_SR2PC_CHAN(IDB_QUEUE), | ||
557 | priv->regs + TSI721_DEV_CHAN_INTE); | ||
558 | 568 | ||
559 | /* Enable SRIO MAC interrupts */ | 569 | /* Enable SRIO MAC interrupts */ |
560 | iowrite32(TSI721_RIO_EM_DEV_INT_EN_INT, | 570 | iowrite32(TSI721_RIO_EM_DEV_INT_EN_INT, |
561 | priv->regs + TSI721_RIO_EM_DEV_INT_EN); | 571 | priv->regs + TSI721_RIO_EM_DEV_INT_EN); |
562 | 572 | ||
573 | /* Enable interrupts from channels in use */ | ||
574 | #ifdef CONFIG_RAPIDIO_DMA_ENGINE | ||
575 | intr = TSI721_INT_SR2PC_CHAN(IDB_QUEUE) | | ||
576 | (TSI721_INT_BDMA_CHAN_M & | ||
577 | ~TSI721_INT_BDMA_CHAN(TSI721_DMACH_MAINT)); | ||
578 | #else | ||
579 | intr = TSI721_INT_SR2PC_CHAN(IDB_QUEUE); | ||
580 | #endif | ||
581 | iowrite32(intr, priv->regs + TSI721_DEV_CHAN_INTE); | ||
582 | |||
563 | if (priv->flags & TSI721_USING_MSIX) | 583 | if (priv->flags & TSI721_USING_MSIX) |
564 | intr = TSI721_DEV_INT_SRIO; | 584 | intr = TSI721_DEV_INT_SRIO; |
565 | else | 585 | else |
566 | intr = TSI721_DEV_INT_SR2PC_CH | TSI721_DEV_INT_SRIO | | 586 | intr = TSI721_DEV_INT_SR2PC_CH | TSI721_DEV_INT_SRIO | |
567 | TSI721_DEV_INT_SMSG_CH; | 587 | TSI721_DEV_INT_SMSG_CH | TSI721_DEV_INT_BDMA_CH; |
568 | 588 | ||
569 | iowrite32(intr, priv->regs + TSI721_DEV_INTE); | 589 | iowrite32(intr, priv->regs + TSI721_DEV_INTE); |
570 | ioread32(priv->regs + TSI721_DEV_INTE); | 590 | ioread32(priv->regs + TSI721_DEV_INTE); |
@@ -715,12 +735,29 @@ static int tsi721_enable_msix(struct tsi721_device *priv) | |||
715 | TSI721_MSIX_OMSG_INT(i); | 735 | TSI721_MSIX_OMSG_INT(i); |
716 | } | 736 | } |
717 | 737 | ||
738 | #ifdef CONFIG_RAPIDIO_DMA_ENGINE | ||
739 | /* | ||
740 | * Initialize MSI-X entries for Block DMA Engine: | ||
741 | * this driver supports XXX DMA channels | ||
742 | * (one is reserved for SRIO maintenance transactions) | ||
743 | */ | ||
744 | for (i = 0; i < TSI721_DMA_CHNUM; i++) { | ||
745 | entries[TSI721_VECT_DMA0_DONE + i].entry = | ||
746 | TSI721_MSIX_DMACH_DONE(i); | ||
747 | entries[TSI721_VECT_DMA0_INT + i].entry = | ||
748 | TSI721_MSIX_DMACH_INT(i); | ||
749 | } | ||
750 | #endif /* CONFIG_RAPIDIO_DMA_ENGINE */ | ||
751 | |||
718 | err = pci_enable_msix(priv->pdev, entries, ARRAY_SIZE(entries)); | 752 | err = pci_enable_msix(priv->pdev, entries, ARRAY_SIZE(entries)); |
719 | if (err) { | 753 | if (err) { |
720 | if (err > 0) | 754 | if (err > 0) |
721 | dev_info(&priv->pdev->dev, | 755 | dev_info(&priv->pdev->dev, |
722 | "Only %d MSI-X vectors available, " | 756 | "Only %d MSI-X vectors available, " |
723 | "not using MSI-X\n", err); | 757 | "not using MSI-X\n", err); |
758 | else | ||
759 | dev_err(&priv->pdev->dev, | ||
760 | "Failed to enable MSI-X (err=%d)\n", err); | ||
724 | return err; | 761 | return err; |
725 | } | 762 | } |
726 | 763 | ||
@@ -760,6 +797,22 @@ static int tsi721_enable_msix(struct tsi721_device *priv) | |||
760 | i, pci_name(priv->pdev)); | 797 | i, pci_name(priv->pdev)); |
761 | } | 798 | } |
762 | 799 | ||
800 | #ifdef CONFIG_RAPIDIO_DMA_ENGINE | ||
801 | for (i = 0; i < TSI721_DMA_CHNUM; i++) { | ||
802 | priv->msix[TSI721_VECT_DMA0_DONE + i].vector = | ||
803 | entries[TSI721_VECT_DMA0_DONE + i].vector; | ||
804 | snprintf(priv->msix[TSI721_VECT_DMA0_DONE + i].irq_name, | ||
805 | IRQ_DEVICE_NAME_MAX, DRV_NAME "-dmad%d@pci:%s", | ||
806 | i, pci_name(priv->pdev)); | ||
807 | |||
808 | priv->msix[TSI721_VECT_DMA0_INT + i].vector = | ||
809 | entries[TSI721_VECT_DMA0_INT + i].vector; | ||
810 | snprintf(priv->msix[TSI721_VECT_DMA0_INT + i].irq_name, | ||
811 | IRQ_DEVICE_NAME_MAX, DRV_NAME "-dmai%d@pci:%s", | ||
812 | i, pci_name(priv->pdev)); | ||
813 | } | ||
814 | #endif /* CONFIG_RAPIDIO_DMA_ENGINE */ | ||
815 | |||
763 | return 0; | 816 | return 0; |
764 | } | 817 | } |
765 | #endif /* CONFIG_PCI_MSI */ | 818 | #endif /* CONFIG_PCI_MSI */ |
@@ -888,20 +941,34 @@ static void tsi721_doorbell_free(struct tsi721_device *priv) | |||
888 | priv->idb_base = NULL; | 941 | priv->idb_base = NULL; |
889 | } | 942 | } |
890 | 943 | ||
891 | static int tsi721_bdma_ch_init(struct tsi721_device *priv, int chnum) | 944 | /** |
945 | * tsi721_bdma_maint_init - Initialize maintenance request BDMA channel. | ||
946 | * @priv: pointer to tsi721 private data | ||
947 | * | ||
948 | * Initialize BDMA channel allocated for RapidIO maintenance read/write | ||
949 | * request generation | ||
950 | * Returns %0 on success or %-ENOMEM on failure. | ||
951 | */ | ||
952 | static int tsi721_bdma_maint_init(struct tsi721_device *priv) | ||
892 | { | 953 | { |
893 | struct tsi721_dma_desc *bd_ptr; | 954 | struct tsi721_dma_desc *bd_ptr; |
894 | u64 *sts_ptr; | 955 | u64 *sts_ptr; |
895 | dma_addr_t bd_phys, sts_phys; | 956 | dma_addr_t bd_phys, sts_phys; |
896 | int sts_size; | 957 | int sts_size; |
897 | int bd_num = priv->bdma[chnum].bd_num; | 958 | int bd_num = 2; |
959 | void __iomem *regs; | ||
898 | 960 | ||
899 | dev_dbg(&priv->pdev->dev, "Init Block DMA Engine, CH%d\n", chnum); | 961 | dev_dbg(&priv->pdev->dev, |
962 | "Init Block DMA Engine for Maintenance requests, CH%d\n", | ||
963 | TSI721_DMACH_MAINT); | ||
900 | 964 | ||
901 | /* | 965 | /* |
902 | * Initialize DMA channel for maintenance requests | 966 | * Initialize DMA channel for maintenance requests |
903 | */ | 967 | */ |
904 | 968 | ||
969 | priv->mdma.ch_id = TSI721_DMACH_MAINT; | ||
970 | regs = priv->regs + TSI721_DMAC_BASE(TSI721_DMACH_MAINT); | ||
971 | |||
905 | /* Allocate space for DMA descriptors */ | 972 | /* Allocate space for DMA descriptors */ |
906 | bd_ptr = dma_zalloc_coherent(&priv->pdev->dev, | 973 | bd_ptr = dma_zalloc_coherent(&priv->pdev->dev, |
907 | bd_num * sizeof(struct tsi721_dma_desc), | 974 | bd_num * sizeof(struct tsi721_dma_desc), |
@@ -909,8 +976,9 @@ static int tsi721_bdma_ch_init(struct tsi721_device *priv, int chnum) | |||
909 | if (!bd_ptr) | 976 | if (!bd_ptr) |
910 | return -ENOMEM; | 977 | return -ENOMEM; |
911 | 978 | ||
912 | priv->bdma[chnum].bd_phys = bd_phys; | 979 | priv->mdma.bd_num = bd_num; |
913 | priv->bdma[chnum].bd_base = bd_ptr; | 980 | priv->mdma.bd_phys = bd_phys; |
981 | priv->mdma.bd_base = bd_ptr; | ||
914 | 982 | ||
915 | dev_dbg(&priv->pdev->dev, "DMA descriptors @ %p (phys = %llx)\n", | 983 | dev_dbg(&priv->pdev->dev, "DMA descriptors @ %p (phys = %llx)\n", |
916 | bd_ptr, (unsigned long long)bd_phys); | 984 | bd_ptr, (unsigned long long)bd_phys); |
@@ -927,13 +995,13 @@ static int tsi721_bdma_ch_init(struct tsi721_device *priv, int chnum) | |||
927 | dma_free_coherent(&priv->pdev->dev, | 995 | dma_free_coherent(&priv->pdev->dev, |
928 | bd_num * sizeof(struct tsi721_dma_desc), | 996 | bd_num * sizeof(struct tsi721_dma_desc), |
929 | bd_ptr, bd_phys); | 997 | bd_ptr, bd_phys); |
930 | priv->bdma[chnum].bd_base = NULL; | 998 | priv->mdma.bd_base = NULL; |
931 | return -ENOMEM; | 999 | return -ENOMEM; |
932 | } | 1000 | } |
933 | 1001 | ||
934 | priv->bdma[chnum].sts_phys = sts_phys; | 1002 | priv->mdma.sts_phys = sts_phys; |
935 | priv->bdma[chnum].sts_base = sts_ptr; | 1003 | priv->mdma.sts_base = sts_ptr; |
936 | priv->bdma[chnum].sts_size = sts_size; | 1004 | priv->mdma.sts_size = sts_size; |
937 | 1005 | ||
938 | dev_dbg(&priv->pdev->dev, | 1006 | dev_dbg(&priv->pdev->dev, |
939 | "desc status FIFO @ %p (phys = %llx) size=0x%x\n", | 1007 | "desc status FIFO @ %p (phys = %llx) size=0x%x\n", |
@@ -946,83 +1014,61 @@ static int tsi721_bdma_ch_init(struct tsi721_device *priv, int chnum) | |||
946 | bd_ptr[bd_num - 1].next_hi = cpu_to_le32((u64)bd_phys >> 32); | 1014 | bd_ptr[bd_num - 1].next_hi = cpu_to_le32((u64)bd_phys >> 32); |
947 | 1015 | ||
948 | /* Setup DMA descriptor pointers */ | 1016 | /* Setup DMA descriptor pointers */ |
949 | iowrite32(((u64)bd_phys >> 32), | 1017 | iowrite32(((u64)bd_phys >> 32), regs + TSI721_DMAC_DPTRH); |
950 | priv->regs + TSI721_DMAC_DPTRH(chnum)); | ||
951 | iowrite32(((u64)bd_phys & TSI721_DMAC_DPTRL_MASK), | 1018 | iowrite32(((u64)bd_phys & TSI721_DMAC_DPTRL_MASK), |
952 | priv->regs + TSI721_DMAC_DPTRL(chnum)); | 1019 | regs + TSI721_DMAC_DPTRL); |
953 | 1020 | ||
954 | /* Setup descriptor status FIFO */ | 1021 | /* Setup descriptor status FIFO */ |
955 | iowrite32(((u64)sts_phys >> 32), | 1022 | iowrite32(((u64)sts_phys >> 32), regs + TSI721_DMAC_DSBH); |
956 | priv->regs + TSI721_DMAC_DSBH(chnum)); | ||
957 | iowrite32(((u64)sts_phys & TSI721_DMAC_DSBL_MASK), | 1023 | iowrite32(((u64)sts_phys & TSI721_DMAC_DSBL_MASK), |
958 | priv->regs + TSI721_DMAC_DSBL(chnum)); | 1024 | regs + TSI721_DMAC_DSBL); |
959 | iowrite32(TSI721_DMAC_DSSZ_SIZE(sts_size), | 1025 | iowrite32(TSI721_DMAC_DSSZ_SIZE(sts_size), |
960 | priv->regs + TSI721_DMAC_DSSZ(chnum)); | 1026 | regs + TSI721_DMAC_DSSZ); |
961 | 1027 | ||
962 | /* Clear interrupt bits */ | 1028 | /* Clear interrupt bits */ |
963 | iowrite32(TSI721_DMAC_INT_ALL, | 1029 | iowrite32(TSI721_DMAC_INT_ALL, regs + TSI721_DMAC_INT); |
964 | priv->regs + TSI721_DMAC_INT(chnum)); | ||
965 | 1030 | ||
966 | ioread32(priv->regs + TSI721_DMAC_INT(chnum)); | 1031 | ioread32(regs + TSI721_DMAC_INT); |
967 | 1032 | ||
968 | /* Toggle DMA channel initialization */ | 1033 | /* Toggle DMA channel initialization */ |
969 | iowrite32(TSI721_DMAC_CTL_INIT, priv->regs + TSI721_DMAC_CTL(chnum)); | 1034 | iowrite32(TSI721_DMAC_CTL_INIT, regs + TSI721_DMAC_CTL); |
970 | ioread32(priv->regs + TSI721_DMAC_CTL(chnum)); | 1035 | ioread32(regs + TSI721_DMAC_CTL); |
971 | udelay(10); | 1036 | udelay(10); |
972 | 1037 | ||
973 | return 0; | 1038 | return 0; |
974 | } | 1039 | } |
975 | 1040 | ||
976 | static int tsi721_bdma_ch_free(struct tsi721_device *priv, int chnum) | 1041 | static int tsi721_bdma_maint_free(struct tsi721_device *priv) |
977 | { | 1042 | { |
978 | u32 ch_stat; | 1043 | u32 ch_stat; |
1044 | struct tsi721_bdma_maint *mdma = &priv->mdma; | ||
1045 | void __iomem *regs = priv->regs + TSI721_DMAC_BASE(mdma->ch_id); | ||
979 | 1046 | ||
980 | if (priv->bdma[chnum].bd_base == NULL) | 1047 | if (mdma->bd_base == NULL) |
981 | return 0; | 1048 | return 0; |
982 | 1049 | ||
983 | /* Check if DMA channel still running */ | 1050 | /* Check if DMA channel still running */ |
984 | ch_stat = ioread32(priv->regs + TSI721_DMAC_STS(chnum)); | 1051 | ch_stat = ioread32(regs + TSI721_DMAC_STS); |
985 | if (ch_stat & TSI721_DMAC_STS_RUN) | 1052 | if (ch_stat & TSI721_DMAC_STS_RUN) |
986 | return -EFAULT; | 1053 | return -EFAULT; |
987 | 1054 | ||
988 | /* Put DMA channel into init state */ | 1055 | /* Put DMA channel into init state */ |
989 | iowrite32(TSI721_DMAC_CTL_INIT, | 1056 | iowrite32(TSI721_DMAC_CTL_INIT, regs + TSI721_DMAC_CTL); |
990 | priv->regs + TSI721_DMAC_CTL(chnum)); | ||
991 | 1057 | ||
992 | /* Free space allocated for DMA descriptors */ | 1058 | /* Free space allocated for DMA descriptors */ |
993 | dma_free_coherent(&priv->pdev->dev, | 1059 | dma_free_coherent(&priv->pdev->dev, |
994 | priv->bdma[chnum].bd_num * sizeof(struct tsi721_dma_desc), | 1060 | mdma->bd_num * sizeof(struct tsi721_dma_desc), |
995 | priv->bdma[chnum].bd_base, priv->bdma[chnum].bd_phys); | 1061 | mdma->bd_base, mdma->bd_phys); |
996 | priv->bdma[chnum].bd_base = NULL; | 1062 | mdma->bd_base = NULL; |
997 | 1063 | ||
998 | /* Free space allocated for status FIFO */ | 1064 | /* Free space allocated for status FIFO */ |
999 | dma_free_coherent(&priv->pdev->dev, | 1065 | dma_free_coherent(&priv->pdev->dev, |
1000 | priv->bdma[chnum].sts_size * sizeof(struct tsi721_dma_sts), | 1066 | mdma->sts_size * sizeof(struct tsi721_dma_sts), |
1001 | priv->bdma[chnum].sts_base, priv->bdma[chnum].sts_phys); | 1067 | mdma->sts_base, mdma->sts_phys); |
1002 | priv->bdma[chnum].sts_base = NULL; | 1068 | mdma->sts_base = NULL; |
1003 | return 0; | ||
1004 | } | ||
1005 | |||
1006 | static int tsi721_bdma_init(struct tsi721_device *priv) | ||
1007 | { | ||
1008 | /* Initialize BDMA channel allocated for RapidIO maintenance read/write | ||
1009 | * request generation | ||
1010 | */ | ||
1011 | priv->bdma[TSI721_DMACH_MAINT].bd_num = 2; | ||
1012 | if (tsi721_bdma_ch_init(priv, TSI721_DMACH_MAINT)) { | ||
1013 | dev_err(&priv->pdev->dev, "Unable to initialize maintenance DMA" | ||
1014 | " channel %d, aborting\n", TSI721_DMACH_MAINT); | ||
1015 | return -ENOMEM; | ||
1016 | } | ||
1017 | |||
1018 | return 0; | 1069 | return 0; |
1019 | } | 1070 | } |
1020 | 1071 | ||
1021 | static void tsi721_bdma_free(struct tsi721_device *priv) | ||
1022 | { | ||
1023 | tsi721_bdma_ch_free(priv, TSI721_DMACH_MAINT); | ||
1024 | } | ||
1025 | |||
1026 | /* Enable Inbound Messaging Interrupts */ | 1072 | /* Enable Inbound Messaging Interrupts */ |
1027 | static void | 1073 | static void |
1028 | tsi721_imsg_interrupt_enable(struct tsi721_device *priv, int ch, | 1074 | tsi721_imsg_interrupt_enable(struct tsi721_device *priv, int ch, |
@@ -2035,7 +2081,8 @@ static void tsi721_disable_ints(struct tsi721_device *priv) | |||
2035 | 2081 | ||
2036 | /* Disable all BDMA Channel interrupts */ | 2082 | /* Disable all BDMA Channel interrupts */ |
2037 | for (ch = 0; ch < TSI721_DMA_MAXCH; ch++) | 2083 | for (ch = 0; ch < TSI721_DMA_MAXCH; ch++) |
2038 | iowrite32(0, priv->regs + TSI721_DMAC_INTE(ch)); | 2084 | iowrite32(0, |
2085 | priv->regs + TSI721_DMAC_BASE(ch) + TSI721_DMAC_INTE); | ||
2039 | 2086 | ||
2040 | /* Disable all general BDMA interrupts */ | 2087 | /* Disable all general BDMA interrupts */ |
2041 | iowrite32(0, priv->regs + TSI721_BDMA_INTE); | 2088 | iowrite32(0, priv->regs + TSI721_BDMA_INTE); |
@@ -2104,6 +2151,7 @@ static int __devinit tsi721_setup_mport(struct tsi721_device *priv) | |||
2104 | mport->phy_type = RIO_PHY_SERIAL; | 2151 | mport->phy_type = RIO_PHY_SERIAL; |
2105 | mport->priv = (void *)priv; | 2152 | mport->priv = (void *)priv; |
2106 | mport->phys_efptr = 0x100; | 2153 | mport->phys_efptr = 0x100; |
2154 | priv->mport = mport; | ||
2107 | 2155 | ||
2108 | INIT_LIST_HEAD(&mport->dbells); | 2156 | INIT_LIST_HEAD(&mport->dbells); |
2109 | 2157 | ||
@@ -2129,17 +2177,21 @@ static int __devinit tsi721_setup_mport(struct tsi721_device *priv) | |||
2129 | if (!err) { | 2177 | if (!err) { |
2130 | tsi721_interrupts_init(priv); | 2178 | tsi721_interrupts_init(priv); |
2131 | ops->pwenable = tsi721_pw_enable; | 2179 | ops->pwenable = tsi721_pw_enable; |
2132 | } else | 2180 | } else { |
2133 | dev_err(&pdev->dev, "Unable to get assigned PCI IRQ " | 2181 | dev_err(&pdev->dev, "Unable to get assigned PCI IRQ " |
2134 | "vector %02X err=0x%x\n", pdev->irq, err); | 2182 | "vector %02X err=0x%x\n", pdev->irq, err); |
2183 | goto err_exit; | ||
2184 | } | ||
2135 | 2185 | ||
2186 | #ifdef CONFIG_RAPIDIO_DMA_ENGINE | ||
2187 | tsi721_register_dma(priv); | ||
2188 | #endif | ||
2136 | /* Enable SRIO link */ | 2189 | /* Enable SRIO link */ |
2137 | iowrite32(ioread32(priv->regs + TSI721_DEVCTL) | | 2190 | iowrite32(ioread32(priv->regs + TSI721_DEVCTL) | |
2138 | TSI721_DEVCTL_SRBOOT_CMPL, | 2191 | TSI721_DEVCTL_SRBOOT_CMPL, |
2139 | priv->regs + TSI721_DEVCTL); | 2192 | priv->regs + TSI721_DEVCTL); |
2140 | 2193 | ||
2141 | rio_register_mport(mport); | 2194 | rio_register_mport(mport); |
2142 | priv->mport = mport; | ||
2143 | 2195 | ||
2144 | if (mport->host_deviceid >= 0) | 2196 | if (mport->host_deviceid >= 0) |
2145 | iowrite32(RIO_PORT_GEN_HOST | RIO_PORT_GEN_MASTER | | 2197 | iowrite32(RIO_PORT_GEN_HOST | RIO_PORT_GEN_MASTER | |
@@ -2149,6 +2201,11 @@ static int __devinit tsi721_setup_mport(struct tsi721_device *priv) | |||
2149 | iowrite32(0, priv->regs + (0x100 + RIO_PORT_GEN_CTL_CSR)); | 2201 | iowrite32(0, priv->regs + (0x100 + RIO_PORT_GEN_CTL_CSR)); |
2150 | 2202 | ||
2151 | return 0; | 2203 | return 0; |
2204 | |||
2205 | err_exit: | ||
2206 | kfree(mport); | ||
2207 | kfree(ops); | ||
2208 | return err; | ||
2152 | } | 2209 | } |
2153 | 2210 | ||
2154 | static int __devinit tsi721_probe(struct pci_dev *pdev, | 2211 | static int __devinit tsi721_probe(struct pci_dev *pdev, |
@@ -2294,7 +2351,7 @@ static int __devinit tsi721_probe(struct pci_dev *pdev, | |||
2294 | tsi721_init_pc2sr_mapping(priv); | 2351 | tsi721_init_pc2sr_mapping(priv); |
2295 | tsi721_init_sr2pc_mapping(priv); | 2352 | tsi721_init_sr2pc_mapping(priv); |
2296 | 2353 | ||
2297 | if (tsi721_bdma_init(priv)) { | 2354 | if (tsi721_bdma_maint_init(priv)) { |
2298 | dev_err(&pdev->dev, "BDMA initialization failed, aborting\n"); | 2355 | dev_err(&pdev->dev, "BDMA initialization failed, aborting\n"); |
2299 | err = -ENOMEM; | 2356 | err = -ENOMEM; |
2300 | goto err_unmap_bars; | 2357 | goto err_unmap_bars; |
@@ -2319,7 +2376,7 @@ static int __devinit tsi721_probe(struct pci_dev *pdev, | |||
2319 | err_free_consistent: | 2376 | err_free_consistent: |
2320 | tsi721_doorbell_free(priv); | 2377 | tsi721_doorbell_free(priv); |
2321 | err_free_bdma: | 2378 | err_free_bdma: |
2322 | tsi721_bdma_free(priv); | 2379 | tsi721_bdma_maint_free(priv); |
2323 | err_unmap_bars: | 2380 | err_unmap_bars: |
2324 | if (priv->regs) | 2381 | if (priv->regs) |
2325 | iounmap(priv->regs); | 2382 | iounmap(priv->regs); |