aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/sparc/include/asm/io-unit.h2
-rw-r--r--arch/sparc/include/asm/iommu_32.h2
-rw-r--r--arch/sparc/kernel/ioport.c17
-rw-r--r--arch/sparc/mm/io-unit.c29
-rw-r--r--arch/sparc/mm/iommu.c35
5 files changed, 45 insertions, 40 deletions
diff --git a/arch/sparc/include/asm/io-unit.h b/arch/sparc/include/asm/io-unit.h
index 96823b47fd45..5df63ef95cf2 100644
--- a/arch/sparc/include/asm/io-unit.h
+++ b/arch/sparc/include/asm/io-unit.h
@@ -59,4 +59,6 @@ extern __u32 iounit_map_dma_init(struct sbus_bus *, int);
59#define iounit_map_dma_finish(sbus, addr, len) mmu_release_scsi_one(addr, len, sbus) 59#define iounit_map_dma_finish(sbus, addr, len) mmu_release_scsi_one(addr, len, sbus)
60extern __u32 iounit_map_dma_page(__u32, void *, struct sbus_bus *); 60extern __u32 iounit_map_dma_page(__u32, void *, struct sbus_bus *);
61 61
62extern void iounit_init(struct sbus_bus *sbus);
63
62#endif /* !(_SPARC_IO_UNIT_H) */ 64#endif /* !(_SPARC_IO_UNIT_H) */
diff --git a/arch/sparc/include/asm/iommu_32.h b/arch/sparc/include/asm/iommu_32.h
index 70c589c05a10..6b115a174c0c 100644
--- a/arch/sparc/include/asm/iommu_32.h
+++ b/arch/sparc/include/asm/iommu_32.h
@@ -118,4 +118,6 @@ static inline void iommu_invalidate_page(struct iommu_regs *regs, unsigned long
118 regs->pageflush = (ba & PAGE_MASK); 118 regs->pageflush = (ba & PAGE_MASK);
119} 119}
120 120
121extern void iommu_init(struct device_node *dp, struct sbus_bus *sbus);
122
121#endif /* !(_SPARC_IOMMU_H) */ 123#endif /* !(_SPARC_IOMMU_H) */
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index 2a8a847764d8..f6158c4a3995 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -46,6 +46,8 @@
46#include <asm/page.h> 46#include <asm/page.h>
47#include <asm/pgalloc.h> 47#include <asm/pgalloc.h>
48#include <asm/dma.h> 48#include <asm/dma.h>
49#include <asm/iommu.h>
50#include <asm/io-unit.h>
49 51
50#define mmu_inval_dma_area(p, l) /* Anton pulled it out for 2.4.0-xx */ 52#define mmu_inval_dma_area(p, l) /* Anton pulled it out for 2.4.0-xx */
51 53
@@ -515,18 +517,11 @@ void __init sbus_setup_iommu(struct sbus_bus *sbus, struct device_node *dp)
515 517
516 if (sparc_cpu_model != sun4d && 518 if (sparc_cpu_model != sun4d &&
517 parent != NULL && 519 parent != NULL &&
518 !strcmp(parent->name, "iommu")) { 520 !strcmp(parent->name, "iommu"))
519 extern void iommu_init(int iommu_node, struct sbus_bus *sbus); 521 iommu_init(parent, sbus);
520 522
521 iommu_init(parent->node, sbus); 523 if (sparc_cpu_model == sun4d)
522 } 524 iounit_init(sbus);
523
524 if (sparc_cpu_model == sun4d) {
525 extern void iounit_init(int sbi_node, int iounit_node,
526 struct sbus_bus *sbus);
527
528 iounit_init(dp->node, parent->node, sbus);
529 }
530#endif 525#endif
531} 526}
532 527
diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c
index f167835db3df..1093514a5773 100644
--- a/arch/sparc/mm/io-unit.c
+++ b/arch/sparc/mm/io-unit.c
@@ -34,13 +34,18 @@
34#define IOPERM (IOUPTE_CACHE | IOUPTE_WRITE | IOUPTE_VALID) 34#define IOPERM (IOUPTE_CACHE | IOUPTE_WRITE | IOUPTE_VALID)
35#define MKIOPTE(phys) __iopte((((phys)>>4) & IOUPTE_PAGE) | IOPERM) 35#define MKIOPTE(phys) __iopte((((phys)>>4) & IOUPTE_PAGE) | IOPERM)
36 36
37void __init 37void __init iounit_init(struct sbus_bus *sbus)
38iounit_init(int sbi_node, int io_node, struct sbus_bus *sbus)
39{ 38{
40 iopte_t *xpt, *xptend; 39 struct device_node *dp = sbus->ofdev.node;
41 struct iounit_struct *iounit; 40 struct iounit_struct *iounit;
42 struct linux_prom_registers iommu_promregs[PROMREG_MAX]; 41 iopte_t *xpt, *xptend;
43 struct resource r; 42 struct of_device *op;
43
44 op = of_find_device_by_node(dp);
45 if (!op) {
46 prom_printf("SUN4D: Cannot find SBI of_device.\n");
47 prom_halt();
48 }
44 49
45 iounit = kzalloc(sizeof(struct iounit_struct), GFP_ATOMIC); 50 iounit = kzalloc(sizeof(struct iounit_struct), GFP_ATOMIC);
46 if (!iounit) { 51 if (!iounit) {
@@ -55,18 +60,14 @@ iounit_init(int sbi_node, int io_node, struct sbus_bus *sbus)
55 iounit->rotor[1] = IOUNIT_BMAP2_START; 60 iounit->rotor[1] = IOUNIT_BMAP2_START;
56 iounit->rotor[2] = IOUNIT_BMAPM_START; 61 iounit->rotor[2] = IOUNIT_BMAPM_START;
57 62
58 xpt = NULL; 63 xpt = of_ioremap(&op->resource[2], 0, PAGE_SIZE * 16, "XPT");
59 if(prom_getproperty(sbi_node, "reg", (void *) iommu_promregs, 64 if (!xpt) {
60 sizeof(iommu_promregs)) != -1) { 65 prom_printf("SUN4D: Cannot map External Page Table.");
61 prom_apply_generic_ranges(io_node, 0, iommu_promregs, 3); 66 prom_halt();
62 memset(&r, 0, sizeof(r));
63 r.flags = iommu_promregs[2].which_io;
64 r.start = iommu_promregs[2].phys_addr;
65 xpt = (iopte_t *) sbus_ioremap(&r, 0, PAGE_SIZE * 16, "XPT");
66 } 67 }
67 if(!xpt) panic("Cannot map External Page Table.");
68 68
69 sbus->ofdev.dev.archdata.iommu = iounit; 69 sbus->ofdev.dev.archdata.iommu = iounit;
70 op->dev.archdata.iommu = iounit;
70 iounit->page_table = xpt; 71 iounit->page_table = xpt;
71 spin_lock_init(&iounit->lock); 72 spin_lock_init(&iounit->lock);
72 73
diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c
index 4b934270f05e..a86c9f552fa1 100644
--- a/arch/sparc/mm/iommu.c
+++ b/arch/sparc/mm/iommu.c
@@ -55,30 +55,34 @@ static pgprot_t dvma_prot; /* Consistent mapping pte flags */
55#define IOPERM (IOPTE_CACHE | IOPTE_WRITE | IOPTE_VALID) 55#define IOPERM (IOPTE_CACHE | IOPTE_WRITE | IOPTE_VALID)
56#define MKIOPTE(pfn, perm) (((((pfn)<<8) & IOPTE_PAGE) | (perm)) & ~IOPTE_WAZ) 56#define MKIOPTE(pfn, perm) (((((pfn)<<8) & IOPTE_PAGE) | (perm)) & ~IOPTE_WAZ)
57 57
58void __init 58void __init iommu_init(struct device_node *parent, struct sbus_bus *sbus)
59iommu_init(int iommund, struct sbus_bus *sbus)
60{ 59{
61 unsigned int impl, vers; 60 struct of_device *parent_op, *op;
62 unsigned long tmp;
63 struct iommu_struct *iommu; 61 struct iommu_struct *iommu;
64 struct linux_prom_registers iommu_promregs[PROMREG_MAX]; 62 unsigned int impl, vers;
65 struct resource r;
66 unsigned long *bitmap; 63 unsigned long *bitmap;
64 unsigned long tmp;
65
66 parent_op = of_find_device_by_node(parent);
67 if (!parent_op) {
68 prom_printf("Unable to find IOMMU of_device\n");
69 prom_halt();
70 }
71
72 op = of_find_device_by_node(sbus->ofdev.node);
73 if (!op) {
74 prom_printf("Unable to find SBUS of_device\n");
75 prom_halt();
76 }
67 77
68 iommu = kmalloc(sizeof(struct iommu_struct), GFP_ATOMIC); 78 iommu = kmalloc(sizeof(struct iommu_struct), GFP_ATOMIC);
69 if (!iommu) { 79 if (!iommu) {
70 prom_printf("Unable to allocate iommu structure\n"); 80 prom_printf("Unable to allocate iommu structure\n");
71 prom_halt(); 81 prom_halt();
72 } 82 }
73 iommu->regs = NULL; 83
74 if (prom_getproperty(iommund, "reg", (void *) iommu_promregs, 84 iommu->regs = of_ioremap(&parent_op->resource[0], 0, PAGE_SIZE * 3,
75 sizeof(iommu_promregs)) != -1) { 85 "iommu_regs");
76 memset(&r, 0, sizeof(r));
77 r.flags = iommu_promregs[0].which_io;
78 r.start = iommu_promregs[0].phys_addr;
79 iommu->regs = (struct iommu_regs *)
80 sbus_ioremap(&r, 0, PAGE_SIZE * 3, "iommu_regs");
81 }
82 if (!iommu->regs) { 86 if (!iommu->regs) {
83 prom_printf("Cannot map IOMMU registers\n"); 87 prom_printf("Cannot map IOMMU registers\n");
84 prom_halt(); 88 prom_halt();
@@ -133,6 +137,7 @@ iommu_init(int iommund, struct sbus_bus *sbus)
133 (int)(IOMMU_NPTES*sizeof(iopte_t)), (int)IOMMU_NPTES); 137 (int)(IOMMU_NPTES*sizeof(iopte_t)), (int)IOMMU_NPTES);
134 138
135 sbus->ofdev.dev.archdata.iommu = iommu; 139 sbus->ofdev.dev.archdata.iommu = iommu;
140 op->dev.archdata.iommu = iommu;
136} 141}
137 142
138/* This begs to be btfixup-ed by srmmu. */ 143/* This begs to be btfixup-ed by srmmu. */