[SPARC64]: Convert SBUS over to generic iommu/strbuf structs.

Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c
index 279758d..3b05428 100644
--- a/arch/sparc64/kernel/sbus.c
+++ b/arch/sparc64/kernel/sbus.c
@@ -26,17 +26,9 @@
 
 #define MAP_BASE	((u32)0xc0000000)
 
-struct sbus_iommu {
-	spinlock_t		lock;
-
-	struct iommu_arena	arena;
-
-	iopte_t			*page_table;
-	unsigned long		strbuf_regs;
-	unsigned long		iommu_regs;
-	unsigned long		sbus_control_reg;
-
-	volatile unsigned long	strbuf_flushflag;
+struct sbus_info {
+	struct iommu	iommu;
+	struct strbuf	strbuf;
 };
 
 /* Offsets from iommu_regs */
@@ -52,16 +44,17 @@
 
 #define IOMMU_DRAM_VALID	(1UL << 30UL)
 
-static void __iommu_flushall(struct sbus_iommu *iommu)
+static void __iommu_flushall(struct iommu *iommu)
 {
-	unsigned long tag = iommu->iommu_regs + IOMMU_TAGDIAG;
+	unsigned long tag;
 	int entry;
 
+	tag = iommu->iommu_control + (IOMMU_TAGDIAG - IOMMU_CONTROL);
 	for (entry = 0; entry < 16; entry++) {
 		upa_writeq(0, tag);
 		tag += 8UL;
 	}
-	upa_readq(iommu->sbus_control_reg);
+	upa_readq(iommu->write_complete_reg);
 }
 
 /* Offsets from strbuf_regs */
@@ -76,15 +69,14 @@
 
 #define STRBUF_TAG_VALID	0x02UL
 
-static void sbus_strbuf_flush(struct sbus_iommu *iommu, u32 base, unsigned long npages, int direction)
+static void sbus_strbuf_flush(struct iommu *iommu, struct strbuf *strbuf, u32 base, unsigned long npages, int direction)
 {
 	unsigned long n;
 	int limit;
 
 	n = npages;
 	while (n--)
-		upa_writeq(base + (n << IO_PAGE_SHIFT),
-			   iommu->strbuf_regs + STRBUF_PFLUSH);
+		upa_writeq(base + (n << IO_PAGE_SHIFT), strbuf->strbuf_pflush);
 
 	/* If the device could not have possibly put dirty data into
 	 * the streaming cache, no flush-flag synchronization needs
@@ -93,15 +85,14 @@
 	if (direction == SBUS_DMA_TODEVICE)
 		return;
 
-	iommu->strbuf_flushflag = 0UL;
+	*(strbuf->strbuf_flushflag) = 0UL;
 
 	/* Whoopee cushion! */
-	upa_writeq(__pa(&iommu->strbuf_flushflag),
-		   iommu->strbuf_regs + STRBUF_FSYNC);
-	upa_readq(iommu->sbus_control_reg);
+	upa_writeq(strbuf->strbuf_flushflag_pa, strbuf->strbuf_fsync);
+	upa_readq(iommu->write_complete_reg);
 
 	limit = 100000;
-	while (iommu->strbuf_flushflag == 0UL) {
+	while (*(strbuf->strbuf_flushflag) == 0UL) {
 		limit--;
 		if (!limit)
 			break;
@@ -115,7 +106,7 @@
 }
 
 /* Based largely upon the ppc64 iommu allocator.  */
-static long sbus_arena_alloc(struct sbus_iommu *iommu, unsigned long npages)
+static long sbus_arena_alloc(struct iommu *iommu, unsigned long npages)
 {
 	struct iommu_arena *arena = &iommu->arena;
 	unsigned long n, i, start, end, limit;
@@ -164,7 +155,7 @@
 		__clear_bit(i, arena->map);
 }
 
-static void sbus_iommu_table_init(struct sbus_iommu *iommu, unsigned int tsbsize)
+static void sbus_iommu_table_init(struct iommu *iommu, unsigned int tsbsize)
 {
 	unsigned long tsbbase, order, sz, num_tsb_entries;
 
@@ -172,13 +163,14 @@
 
 	/* Setup initial software IOMMU state. */
 	spin_lock_init(&iommu->lock);
+	iommu->page_table_map_base = MAP_BASE;
 
 	/* Allocate and initialize the free area map.  */
 	sz = num_tsb_entries / 8;
 	sz = (sz + 7UL) & ~7UL;
 	iommu->arena.map = kzalloc(sz, GFP_KERNEL);
 	if (!iommu->arena.map) {
-		prom_printf("PCI_IOMMU: Error, kmalloc(arena.map) failed.\n");
+		prom_printf("SBUS_IOMMU: Error, kmalloc(arena.map) failed.\n");
 		prom_halt();
 	}
 	iommu->arena.limit = num_tsb_entries;
@@ -194,7 +186,7 @@
 	memset(iommu->page_table, 0, tsbsize);
 }
 
-static inline iopte_t *alloc_npages(struct sbus_iommu *iommu, unsigned long npages)
+static inline iopte_t *alloc_npages(struct iommu *iommu, unsigned long npages)
 {
 	long entry;
 
@@ -205,14 +197,15 @@
 	return iommu->page_table + entry;
 }
 
-static inline void free_npages(struct sbus_iommu *iommu, dma_addr_t base, unsigned long npages)
+static inline void free_npages(struct iommu *iommu, dma_addr_t base, unsigned long npages)
 {
 	sbus_arena_free(&iommu->arena, base >> IO_PAGE_SHIFT, npages);
 }
 
 void *sbus_alloc_consistent(struct sbus_dev *sdev, size_t size, dma_addr_t *dvma_addr)
 {
-	struct sbus_iommu *iommu;
+	struct sbus_info *info;
+	struct iommu *iommu;
 	iopte_t *iopte;
 	unsigned long flags, order, first_page;
 	void *ret;
@@ -228,7 +221,8 @@
 		return NULL;
 	memset((char *)first_page, 0, PAGE_SIZE << order);
 
-	iommu = sdev->bus->iommu;
+	info = sdev->bus->iommu;
+	iommu = &info->iommu;
 
 	spin_lock_irqsave(&iommu->lock, flags);
 	iopte = alloc_npages(iommu, size >> IO_PAGE_SHIFT);
@@ -239,7 +233,7 @@
 		return NULL;
 	}
 
-	*dvma_addr = (MAP_BASE +
+	*dvma_addr = (iommu->page_table_map_base +
 		      ((iopte - iommu->page_table) << IO_PAGE_SHIFT));
 	ret = (void *) first_page;
 	npages = size >> IO_PAGE_SHIFT;
@@ -257,18 +251,20 @@
 
 void sbus_free_consistent(struct sbus_dev *sdev, size_t size, void *cpu, dma_addr_t dvma)
 {
-	struct sbus_iommu *iommu;
+	struct sbus_info *info;
+	struct iommu *iommu;
 	iopte_t *iopte;
 	unsigned long flags, order, npages;
 
 	npages = IO_PAGE_ALIGN(size) >> IO_PAGE_SHIFT;
-	iommu = sdev->bus->iommu;
+	info = sdev->bus->iommu;
+	iommu = &info->iommu;
 	iopte = iommu->page_table +
-		((dvma - MAP_BASE) >> IO_PAGE_SHIFT);
+		((dvma - iommu->page_table_map_base) >> IO_PAGE_SHIFT);
 
 	spin_lock_irqsave(&iommu->lock, flags);
 
-	free_npages(iommu, dvma - MAP_BASE, npages);
+	free_npages(iommu, dvma - iommu->page_table_map_base, npages);
 
 	spin_unlock_irqrestore(&iommu->lock, flags);
 
@@ -279,14 +275,16 @@
 
 dma_addr_t sbus_map_single(struct sbus_dev *sdev, void *ptr, size_t sz, int direction)
 {
-	struct sbus_iommu *iommu;
+	struct sbus_info *info;
+	struct iommu *iommu;
 	iopte_t *base;
 	unsigned long flags, npages, oaddr;
 	unsigned long i, base_paddr;
 	u32 bus_addr, ret;
 	unsigned long iopte_protection;
 
-	iommu = sdev->bus->iommu;
+	info = sdev->bus->iommu;
+	iommu = &info->iommu;
 
 	if (unlikely(direction == SBUS_DMA_NONE))
 		BUG();
@@ -302,7 +300,7 @@
 	if (unlikely(!base))
 		BUG();
 
-	bus_addr = (MAP_BASE +
+	bus_addr = (iommu->page_table_map_base +
 		    ((base - iommu->page_table) << IO_PAGE_SHIFT));
 	ret = bus_addr | (oaddr & ~IO_PAGE_MASK);
 	base_paddr = __pa(oaddr & IO_PAGE_MASK);
@@ -319,7 +317,9 @@
 
 void sbus_unmap_single(struct sbus_dev *sdev, dma_addr_t bus_addr, size_t sz, int direction)
 {
-	struct sbus_iommu *iommu = sdev->bus->iommu;
+	struct sbus_info *info = sdev->bus->iommu;
+	struct iommu *iommu = &info->iommu;
+	struct strbuf *strbuf = &info->strbuf;
 	iopte_t *base;
 	unsigned long flags, npages, i;
 
@@ -329,15 +329,15 @@
 	npages = IO_PAGE_ALIGN(bus_addr + sz) - (bus_addr & IO_PAGE_MASK);
 	npages >>= IO_PAGE_SHIFT;
 	base = iommu->page_table +
-		((bus_addr - MAP_BASE) >> IO_PAGE_SHIFT);
+		((bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT);
 
 	bus_addr &= IO_PAGE_MASK;
 
 	spin_lock_irqsave(&iommu->lock, flags);
-	sbus_strbuf_flush(iommu, bus_addr, npages, direction);
+	sbus_strbuf_flush(iommu, strbuf, bus_addr, npages, direction);
 	for (i = 0; i < npages; i++)
 		iopte_val(base[i]) = 0UL;
-	free_npages(iommu, bus_addr - MAP_BASE, npages);
+	free_npages(iommu, bus_addr - iommu->page_table_map_base, npages);
 	spin_unlock_irqrestore(&iommu->lock, flags);
 }
 
@@ -419,7 +419,8 @@
 
 int sbus_map_sg(struct sbus_dev *sdev, struct scatterlist *sglist, int nelems, int direction)
 {
-	struct sbus_iommu *iommu;
+	struct sbus_info *info;
+	struct iommu *iommu;
 	unsigned long flags, npages, iopte_protection;
 	iopte_t *base;
 	u32 dma_base;
@@ -436,7 +437,8 @@
 		return 1;
 	}
 
-	iommu = sdev->bus->iommu;
+	info = sdev->bus->iommu;
+	iommu = &info->iommu;
 
 	if (unlikely(direction == SBUS_DMA_NONE))
 		BUG();
@@ -450,7 +452,7 @@
 	if (unlikely(base == NULL))
 		BUG();
 
-	dma_base = MAP_BASE +
+	dma_base = iommu->page_table_map_base +
 		((base - iommu->page_table) << IO_PAGE_SHIFT);
 
 	/* Normalize DVMA addresses. */
@@ -479,7 +481,9 @@
 
 void sbus_unmap_sg(struct sbus_dev *sdev, struct scatterlist *sglist, int nelems, int direction)
 {
-	struct sbus_iommu *iommu;
+	struct sbus_info *info;
+	struct iommu *iommu;
+	struct strbuf *strbuf;
 	iopte_t *base;
 	unsigned long flags, i, npages;
 	u32 bus_addr;
@@ -487,7 +491,9 @@
 	if (unlikely(direction == SBUS_DMA_NONE))
 		BUG();
 
-	iommu = sdev->bus->iommu;
+	info = sdev->bus->iommu;
+	iommu = &info->iommu;
+	strbuf = &info->strbuf;
 
 	bus_addr = sglist->dma_address & IO_PAGE_MASK;
 
@@ -499,29 +505,33 @@
 		  bus_addr) >> IO_PAGE_SHIFT;
 
 	base = iommu->page_table +
-		((bus_addr - MAP_BASE) >> IO_PAGE_SHIFT);
+		((bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT);
 
 	spin_lock_irqsave(&iommu->lock, flags);
-	sbus_strbuf_flush(iommu, bus_addr, npages, direction);
+	sbus_strbuf_flush(iommu, strbuf, bus_addr, npages, direction);
 	for (i = 0; i < npages; i++)
 		iopte_val(base[i]) = 0UL;
-	free_npages(iommu, bus_addr - MAP_BASE, npages);
+	free_npages(iommu, bus_addr - iommu->page_table_map_base, npages);
 	spin_unlock_irqrestore(&iommu->lock, flags);
 }
 
 void sbus_dma_sync_single_for_cpu(struct sbus_dev *sdev, dma_addr_t bus_addr, size_t sz, int direction)
 {
-	struct sbus_iommu *iommu;
+	struct sbus_info *info;
+	struct iommu *iommu;
+	struct strbuf *strbuf;
 	unsigned long flags, npages;
 
-	iommu = sdev->bus->iommu;
+	info = sdev->bus->iommu;
+	iommu = &info->iommu;
+	strbuf = &info->strbuf;
 
 	npages = IO_PAGE_ALIGN(bus_addr + sz) - (bus_addr & IO_PAGE_MASK);
 	npages >>= IO_PAGE_SHIFT;
 	bus_addr &= IO_PAGE_MASK;
 
 	spin_lock_irqsave(&iommu->lock, flags);
-	sbus_strbuf_flush(iommu, bus_addr, npages, direction);
+	sbus_strbuf_flush(iommu, strbuf, bus_addr, npages, direction);
 	spin_unlock_irqrestore(&iommu->lock, flags);
 }
 
@@ -531,11 +541,15 @@
 
 void sbus_dma_sync_sg_for_cpu(struct sbus_dev *sdev, struct scatterlist *sglist, int nelems, int direction)
 {
-	struct sbus_iommu *iommu;
+	struct sbus_info *info;
+	struct iommu *iommu;
+	struct strbuf *strbuf;
 	unsigned long flags, npages, i;
 	u32 bus_addr;
 
-	iommu = sdev->bus->iommu;
+	info = sdev->bus->iommu;
+	iommu = &info->iommu;
+	strbuf = &info->strbuf;
 
 	bus_addr = sglist[0].dma_address & IO_PAGE_MASK;
 	for (i = 0; i < nelems; i++) {
@@ -547,7 +561,7 @@
 		  - bus_addr) >> IO_PAGE_SHIFT;
 
 	spin_lock_irqsave(&iommu->lock, flags);
-	sbus_strbuf_flush(iommu, bus_addr, npages, direction);
+	sbus_strbuf_flush(iommu, strbuf, bus_addr, npages, direction);
 	spin_unlock_irqrestore(&iommu->lock, flags);
 }
 
@@ -558,12 +572,13 @@
 /* Enable 64-bit DVMA mode for the given device. */
 void sbus_set_sbus64(struct sbus_dev *sdev, int bursts)
 {
-	struct sbus_iommu *iommu = sdev->bus->iommu;
+	struct sbus_info *info = sdev->bus->iommu;
+	struct iommu *iommu = &info->iommu;
 	int slot = sdev->slot;
 	unsigned long cfg_reg;
 	u64 val;
 
-	cfg_reg = iommu->sbus_control_reg;
+	cfg_reg = iommu->write_complete_reg;
 	switch (slot) {
 	case 0:
 		cfg_reg += 0x20UL;
@@ -698,8 +713,9 @@
 unsigned int sbus_build_irq(void *buscookie, unsigned int ino)
 {
 	struct sbus_bus *sbus = (struct sbus_bus *)buscookie;
-	struct sbus_iommu *iommu = sbus->iommu;
-	unsigned long reg_base = iommu->sbus_control_reg - 0x2000UL;
+	struct sbus_info *info = sbus->iommu;
+	struct iommu *iommu = &info->iommu;
+	unsigned long reg_base = iommu->write_complete_reg - 0x2000UL;
 	unsigned long imap, iclr;
 	int sbus_level = 0;
 
@@ -760,8 +776,9 @@
 static irqreturn_t sysio_ue_handler(int irq, void *dev_id)
 {
 	struct sbus_bus *sbus = dev_id;
-	struct sbus_iommu *iommu = sbus->iommu;
-	unsigned long reg_base = iommu->sbus_control_reg - 0x2000UL;
+	struct sbus_info *info = sbus->iommu;
+	struct iommu *iommu = &info->iommu;
+	unsigned long reg_base = iommu->write_complete_reg - 0x2000UL;
 	unsigned long afsr_reg, afar_reg;
 	unsigned long afsr, afar, error_bits;
 	int reported;
@@ -832,8 +849,9 @@
 static irqreturn_t sysio_ce_handler(int irq, void *dev_id)
 {
 	struct sbus_bus *sbus = dev_id;
-	struct sbus_iommu *iommu = sbus->iommu;
-	unsigned long reg_base = iommu->sbus_control_reg - 0x2000UL;
+	struct sbus_info *info = sbus->iommu;
+	struct iommu *iommu = &info->iommu;
+	unsigned long reg_base = iommu->write_complete_reg - 0x2000UL;
 	unsigned long afsr_reg, afar_reg;
 	unsigned long afsr, afar, error_bits;
 	int reported;
@@ -909,12 +927,13 @@
 static irqreturn_t sysio_sbus_error_handler(int irq, void *dev_id)
 {
 	struct sbus_bus *sbus = dev_id;
-	struct sbus_iommu *iommu = sbus->iommu;
+	struct sbus_info *info = sbus->iommu;
+	struct iommu *iommu = &info->iommu;
 	unsigned long afsr_reg, afar_reg, reg_base;
 	unsigned long afsr, afar, error_bits;
 	int reported;
 
-	reg_base = iommu->sbus_control_reg - 0x2000UL;
+	reg_base = iommu->write_complete_reg - 0x2000UL;
 	afsr_reg = reg_base + SYSIO_SBUS_AFSR;
 	afar_reg = reg_base + SYSIO_SBUS_AFAR;
 
@@ -976,8 +995,9 @@
 
 static void __init sysio_register_error_handlers(struct sbus_bus *sbus)
 {
-	struct sbus_iommu *iommu = sbus->iommu;
-	unsigned long reg_base = iommu->sbus_control_reg - 0x2000UL;
+	struct sbus_info *info = sbus->iommu;
+	struct iommu *iommu = &info->iommu;
+	unsigned long reg_base = iommu->write_complete_reg - 0x2000UL;
 	unsigned int irq;
 	u64 control;
 
@@ -1011,9 +1031,9 @@
 		    SYSIO_ECNTRL_CEEN),
 		   reg_base + ECC_CONTROL);
 
-	control = upa_readq(iommu->sbus_control_reg);
+	control = upa_readq(iommu->write_complete_reg);
 	control |= 0x100UL; /* SBUS Error Interrupt Enable */
-	upa_writeq(control, iommu->sbus_control_reg);
+	upa_writeq(control, iommu->write_complete_reg);
 }
 
 /* Boot time initialization. */
@@ -1021,8 +1041,10 @@
 {
 	const struct linux_prom64_registers *pr;
 	struct device_node *dp;
-	struct sbus_iommu *iommu;
-	unsigned long regs;
+	struct sbus_info *info;
+	struct iommu *iommu;
+	struct strbuf *strbuf;
+	unsigned long regs, reg_base;
 	u64 control;
 	int i;
 
@@ -1037,33 +1059,42 @@
 	}
 	regs = pr->phys_addr;
 
-	iommu = kmalloc(sizeof(*iommu) + SMP_CACHE_BYTES, GFP_ATOMIC);
-	if (iommu == NULL) {
-		prom_printf("sbus_iommu_init: Fatal error, kmalloc(iommu) failed\n");
+	info = kzalloc(sizeof(*info), GFP_ATOMIC);
+	if (info == NULL) {
+		prom_printf("sbus_iommu_init: Fatal error, "
+			    "kmalloc(info) failed\n");
 		prom_halt();
 	}
 
-	/* Align on E$ line boundary. */
-	iommu = (struct sbus_iommu *)
-		(((unsigned long)iommu + (SMP_CACHE_BYTES - 1UL)) &
-		 ~(SMP_CACHE_BYTES - 1UL));
+	iommu = &info->iommu;
+	strbuf = &info->strbuf;
 
-	memset(iommu, 0, sizeof(*iommu));
+	reg_base = regs + SYSIO_IOMMUREG_BASE;
+	iommu->iommu_control = reg_base + IOMMU_CONTROL;
+	iommu->iommu_tsbbase = reg_base + IOMMU_TSBBASE;
+	iommu->iommu_flush = reg_base + IOMMU_FLUSH;
 
-	/* Setup spinlock. */
-	spin_lock_init(&iommu->lock);
+	reg_base = regs + SYSIO_STRBUFREG_BASE;
+	strbuf->strbuf_control = reg_base + STRBUF_CONTROL;
+	strbuf->strbuf_pflush = reg_base + STRBUF_PFLUSH;
+	strbuf->strbuf_fsync = reg_base + STRBUF_FSYNC;
 
-	/* Init register offsets. */
-	iommu->iommu_regs = regs + SYSIO_IOMMUREG_BASE;
-	iommu->strbuf_regs = regs + SYSIO_STRBUFREG_BASE;
+	strbuf->strbuf_enabled = 1;
+
+	strbuf->strbuf_flushflag = (volatile unsigned long *)
+		((((unsigned long)&strbuf->__flushflag_buf[0])
+		  + 63UL)
+		 & ~63UL);
+	strbuf->strbuf_flushflag_pa = (unsigned long)
+		__pa(strbuf->strbuf_flushflag);
 
 	/* The SYSIO SBUS control register is used for dummy reads
 	 * in order to ensure write completion.
 	 */
-	iommu->sbus_control_reg = regs + 0x2000UL;
+	iommu->write_complete_reg = regs + 0x2000UL;
 
 	/* Link into SYSIO software state. */
-	sbus->iommu = iommu;
+	sbus->iommu = info;
 
 	printk("SYSIO: UPA portID %x, at %016lx\n",
 	       sbus->portid, regs);
@@ -1071,40 +1102,44 @@
 	/* Setup for TSB_SIZE=7, TBW_SIZE=0, MMU_DE=1, MMU_EN=1 */
 	sbus_iommu_table_init(iommu, IO_TSB_SIZE);
 
-	control = upa_readq(iommu->iommu_regs + IOMMU_CONTROL);
+	control = upa_readq(iommu->iommu_control);
 	control = ((7UL << 16UL)	|
 		   (0UL << 2UL)		|
 		   (1UL << 1UL)		|
 		   (1UL << 0UL));
-	upa_writeq(control, iommu->iommu_regs + IOMMU_CONTROL);
+	upa_writeq(control, iommu->iommu_control);
 
 	/* Clean out any cruft in the IOMMU using
 	 * diagnostic accesses.
 	 */
 	for (i = 0; i < 16; i++) {
-		unsigned long dram = iommu->iommu_regs + IOMMU_DRAMDIAG;
-		unsigned long tag = iommu->iommu_regs + IOMMU_TAGDIAG;
+		unsigned long dram, tag;
+
+		dram = iommu->iommu_control + (IOMMU_DRAMDIAG - IOMMU_CONTROL);
+		tag = iommu->iommu_control + (IOMMU_TAGDIAG - IOMMU_CONTROL);
 
 		dram += (unsigned long)i * 8UL;
 		tag += (unsigned long)i * 8UL;
 		upa_writeq(0, dram);
 		upa_writeq(0, tag);
 	}
-	upa_readq(iommu->sbus_control_reg);
+	upa_readq(iommu->write_complete_reg);
 
 	/* Give the TSB to SYSIO. */
-	upa_writeq(__pa(iommu->page_table), iommu->iommu_regs + IOMMU_TSBBASE);
+	upa_writeq(__pa(iommu->page_table), iommu->iommu_tsbbase);
 
 	/* Setup streaming buffer, DE=1 SB_EN=1 */
 	control = (1UL << 1UL) | (1UL << 0UL);
-	upa_writeq(control, iommu->strbuf_regs + STRBUF_CONTROL);
+	upa_writeq(control, strbuf->strbuf_control);
 
 	/* Clear out the tags using diagnostics. */
 	for (i = 0; i < 16; i++) {
 		unsigned long ptag, ltag;
 
-		ptag = iommu->strbuf_regs + STRBUF_PTAGDIAG;
-		ltag = iommu->strbuf_regs + STRBUF_LTAGDIAG;
+		ptag = strbuf->strbuf_control +
+			(STRBUF_PTAGDIAG - STRBUF_CONTROL);
+		ltag = strbuf->strbuf_control +
+			(STRBUF_LTAGDIAG - STRBUF_CONTROL);
 		ptag += (unsigned long)i * 8UL;
 		ltag += (unsigned long)i * 8UL;
 
@@ -1113,9 +1148,9 @@
 	}
 
 	/* Enable DVMA arbitration for all devices/slots. */
-	control = upa_readq(iommu->sbus_control_reg);
+	control = upa_readq(iommu->write_complete_reg);
 	control |= 0x3fUL;
-	upa_writeq(control, iommu->sbus_control_reg);
+	upa_writeq(control, iommu->write_complete_reg);
 
 	/* Now some Xfire specific grot... */
 	if (this_is_starfire)