diff options
Diffstat (limited to 'arch/sparc64/kernel/sbus.c')
| -rw-r--r-- | arch/sparc64/kernel/sbus.c | 31 |
1 files changed, 23 insertions, 8 deletions
diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c index 14d9c3a21b9a..76ea6455433f 100644 --- a/arch/sparc64/kernel/sbus.c +++ b/arch/sparc64/kernel/sbus.c | |||
| @@ -117,19 +117,34 @@ static void iommu_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages | |||
| 117 | 117 | ||
| 118 | #define STRBUF_TAG_VALID 0x02UL | 118 | #define STRBUF_TAG_VALID 0x02UL |
| 119 | 119 | ||
| 120 | static void strbuf_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages) | 120 | static void sbus_strbuf_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages) |
| 121 | { | 121 | { |
| 122 | unsigned long n; | ||
| 123 | int limit; | ||
| 124 | |||
| 122 | iommu->strbuf_flushflag = 0UL; | 125 | iommu->strbuf_flushflag = 0UL; |
| 123 | while (npages--) | 126 | n = npages; |
| 124 | upa_writeq(base + (npages << IO_PAGE_SHIFT), | 127 | while (n--) |
| 128 | upa_writeq(base + (n << IO_PAGE_SHIFT), | ||
| 125 | iommu->strbuf_regs + STRBUF_PFLUSH); | 129 | iommu->strbuf_regs + STRBUF_PFLUSH); |
| 126 | 130 | ||
| 127 | /* Whoopee cushion! */ | 131 | /* Whoopee cushion! */ |
| 128 | upa_writeq(__pa(&iommu->strbuf_flushflag), | 132 | upa_writeq(__pa(&iommu->strbuf_flushflag), |
| 129 | iommu->strbuf_regs + STRBUF_FSYNC); | 133 | iommu->strbuf_regs + STRBUF_FSYNC); |
| 130 | upa_readq(iommu->sbus_control_reg); | 134 | upa_readq(iommu->sbus_control_reg); |
| 131 | while (iommu->strbuf_flushflag == 0UL) | 135 | |
| 136 | limit = 100000; | ||
| 137 | while (iommu->strbuf_flushflag == 0UL) { | ||
| 138 | limit--; | ||
| 139 | if (!limit) | ||
| 140 | break; | ||
| 141 | udelay(1); | ||
| 132 | membar("#LoadLoad"); | 142 | membar("#LoadLoad"); |
| 143 | } | ||
| 144 | if (!limit) | ||
| 145 | printk(KERN_WARNING "sbus_strbuf_flush: flushflag timeout " | ||
| 146 | "vaddr[%08x] npages[%ld]\n", | ||
| 147 | base, npages); | ||
| 133 | } | 148 | } |
| 134 | 149 | ||
| 135 | static iopte_t *alloc_streaming_cluster(struct sbus_iommu *iommu, unsigned long npages) | 150 | static iopte_t *alloc_streaming_cluster(struct sbus_iommu *iommu, unsigned long npages) |
| @@ -406,7 +421,7 @@ void sbus_unmap_single(struct sbus_dev *sdev, dma_addr_t dma_addr, size_t size, | |||
| 406 | 421 | ||
| 407 | spin_lock_irqsave(&iommu->lock, flags); | 422 | spin_lock_irqsave(&iommu->lock, flags); |
| 408 | free_streaming_cluster(iommu, dma_base, size >> IO_PAGE_SHIFT); | 423 | free_streaming_cluster(iommu, dma_base, size >> IO_PAGE_SHIFT); |
| 409 | strbuf_flush(iommu, dma_base, size >> IO_PAGE_SHIFT); | 424 | sbus_strbuf_flush(iommu, dma_base, size >> IO_PAGE_SHIFT); |
| 410 | spin_unlock_irqrestore(&iommu->lock, flags); | 425 | spin_unlock_irqrestore(&iommu->lock, flags); |
| 411 | } | 426 | } |
| 412 | 427 | ||
| @@ -569,7 +584,7 @@ void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sg, int nents, int | |||
| 569 | iommu = sdev->bus->iommu; | 584 | iommu = sdev->bus->iommu; |
| 570 | spin_lock_irqsave(&iommu->lock, flags); | 585 | spin_lock_irqsave(&iommu->lock, flags); |
| 571 | free_streaming_cluster(iommu, dvma_base, size >> IO_PAGE_SHIFT); | 586 | free_streaming_cluster(iommu, dvma_base, size >> IO_PAGE_SHIFT); |
| 572 | strbuf_flush(iommu, dvma_base, size >> IO_PAGE_SHIFT); | 587 | sbus_strbuf_flush(iommu, dvma_base, size >> IO_PAGE_SHIFT); |
| 573 | spin_unlock_irqrestore(&iommu->lock, flags); | 588 | spin_unlock_irqrestore(&iommu->lock, flags); |
| 574 | } | 589 | } |
| 575 | 590 | ||
| @@ -581,7 +596,7 @@ void sbus_dma_sync_single_for_cpu(struct sbus_dev *sdev, dma_addr_t base, size_t | |||
| 581 | size = (IO_PAGE_ALIGN(base + size) - (base & IO_PAGE_MASK)); | 596 | size = (IO_PAGE_ALIGN(base + size) - (base & IO_PAGE_MASK)); |
| 582 | 597 | ||
| 583 | spin_lock_irqsave(&iommu->lock, flags); | 598 | spin_lock_irqsave(&iommu->lock, flags); |
| 584 | strbuf_flush(iommu, base & IO_PAGE_MASK, size >> IO_PAGE_SHIFT); | 599 | sbus_strbuf_flush(iommu, base & IO_PAGE_MASK, size >> IO_PAGE_SHIFT); |
| 585 | spin_unlock_irqrestore(&iommu->lock, flags); | 600 | spin_unlock_irqrestore(&iommu->lock, flags); |
| 586 | } | 601 | } |
| 587 | 602 | ||
| @@ -605,7 +620,7 @@ void sbus_dma_sync_sg_for_cpu(struct sbus_dev *sdev, struct scatterlist *sg, int | |||
| 605 | size = IO_PAGE_ALIGN(sg[i].dma_address + sg[i].dma_length) - base; | 620 | size = IO_PAGE_ALIGN(sg[i].dma_address + sg[i].dma_length) - base; |
| 606 | 621 | ||
| 607 | spin_lock_irqsave(&iommu->lock, flags); | 622 | spin_lock_irqsave(&iommu->lock, flags); |
| 608 | strbuf_flush(iommu, base, size >> IO_PAGE_SHIFT); | 623 | sbus_strbuf_flush(iommu, base, size >> IO_PAGE_SHIFT); |
| 609 | spin_unlock_irqrestore(&iommu->lock, flags); | 624 | spin_unlock_irqrestore(&iommu->lock, flags); |
| 610 | } | 625 | } |
| 611 | 626 | ||
