diff options
Diffstat (limited to 'arch/powerpc/sysdev/dart_iommu.c')
| -rw-r--r-- | arch/powerpc/sysdev/dart_iommu.c | 36 | 
1 files changed, 23 insertions, 13 deletions
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c index 17cf15ec38b..9e5353ff6d1 100644 --- a/arch/powerpc/sysdev/dart_iommu.c +++ b/arch/powerpc/sysdev/dart_iommu.c @@ -43,7 +43,6 @@  #include <asm/iommu.h>  #include <asm/pci-bridge.h>  #include <asm/machdep.h> -#include <asm/abs_addr.h>  #include <asm/cacheflush.h>  #include <asm/ppc-pci.h> @@ -74,11 +73,16 @@ static int dart_is_u4;  #define DBG(...) +static DEFINE_SPINLOCK(invalidate_lock); +  static inline void dart_tlb_invalidate_all(void)  {  	unsigned long l = 0;  	unsigned int reg, inv_bit;  	unsigned long limit; +	unsigned long flags; + +	spin_lock_irqsave(&invalidate_lock, flags);  	DBG("dart: flush\n"); @@ -111,12 +115,17 @@ retry:  			panic("DART: TLB did not flush after waiting a long "  			      "time. Buggy U3 ?");  	} + +	spin_unlock_irqrestore(&invalidate_lock, flags);  }  static inline void dart_tlb_invalidate_one(unsigned long bus_rpn)  {  	unsigned int reg;  	unsigned int l, limit; +	unsigned long flags; + +	spin_lock_irqsave(&invalidate_lock, flags);  	reg = DART_CNTL_U4_ENABLE | DART_CNTL_U4_IONE |  		(bus_rpn & DART_CNTL_U4_IONE_MASK); @@ -138,6 +147,8 @@ wait_more:  			panic("DART: TLB did not flush after waiting a long "  			      "time. Buggy U4 ?");  	} + +	spin_unlock_irqrestore(&invalidate_lock, flags);  }  static void dart_flush(struct iommu_table *tbl) @@ -167,7 +178,7 @@ static int dart_build(struct iommu_table *tbl, long index,  	 */  	l = npages;  	while (l--) { -		rpn = virt_to_abs(uaddr) >> DART_PAGE_SHIFT; +		rpn = __pa(uaddr) >> DART_PAGE_SHIFT;  		*(dp++) = DARTMAP_VALID | (rpn & DARTMAP_RPNMASK); @@ -239,12 +250,12 @@ static int __init dart_init(struct device_node *dart_node)  					 DARTMAP_RPNMASK);  	/* Map in DART registers */ -	dart = ioremap(r.start, r.end - r.start + 1); +	dart = ioremap(r.start, resource_size(&r));  	if (dart == NULL)  		panic("DART: Cannot map registers!");  	/* Map in DART table */ -	dart_vbase = ioremap(virt_to_abs(dart_tablebase), dart_tablesize); +	dart_vbase = ioremap(__pa(dart_tablebase), dart_tablesize);  	/* Fill initial table */  	for (i = 0; i < dart_tablesize/4; i++) @@ -281,6 +292,7 @@ static void iommu_table_dart_setup(void)  	iommu_table_dart.it_offset = 0;  	/* it_size is in number of entries */  	iommu_table_dart.it_size = dart_tablesize / sizeof(u32); +	iommu_table_dart.it_page_shift = IOMMU_PAGE_SHIFT_4K;  	/* Initialize the common IOMMU code */  	iommu_table_dart.it_base = (unsigned long)dart_vbase; @@ -312,17 +324,10 @@ static void pci_dma_dev_setup_dart(struct pci_dev *dev)  static void pci_dma_bus_setup_dart(struct pci_bus *bus)  { -	struct device_node *dn; -  	if (!iommu_table_dart_inited) {  		iommu_table_dart_inited = 1;  		iommu_table_dart_setup();  	} - -	dn = pci_bus_to_OF_node(bus); - -	if (dn) -		PCI_DN(dn)->iommu_table = &iommu_table_dart;  }  static bool dart_device_on_pcie(struct device *dev) @@ -373,7 +378,7 @@ void __init iommu_init_early_dart(void)  	if (dn == NULL) {  		dn = of_find_compatible_node(NULL, "dart", "u4-dart");  		if (dn == NULL) -			goto bail; +			return;	/* use default direct_dma_ops */  		dart_is_u4 = 1;  	} @@ -470,7 +475,12 @@ void __init alloc_dart_table(void)  	 * will blow up an entire large page anyway in the kernel mapping  	 */  	dart_tablebase = (unsigned long) -		abs_to_virt(memblock_alloc_base(1UL<<24, 1UL<<24, 0x80000000L)); +		__va(memblock_alloc_base(1UL<<24, 1UL<<24, 0x80000000L)); +	/* +	 * The DART space is later unmapped from the kernel linear mapping and +	 * accessing dart_tablebase during kmemleak scanning will fault. +	 */ +	kmemleak_no_scan((void *)dart_tablebase);  	printk(KERN_INFO "DART table allocated at: %lx\n", dart_tablebase);  }  | 
