diff options
-rw-r--r-- | arch/sparc/include/asm/io-unit.h | 2 | ||||
-rw-r--r-- | arch/sparc/include/asm/iommu_32.h | 2 | ||||
-rw-r--r-- | arch/sparc/kernel/ioport.c | 17 | ||||
-rw-r--r-- | arch/sparc/mm/io-unit.c | 29 | ||||
-rw-r--r-- | arch/sparc/mm/iommu.c | 35 |
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) |
60 | extern __u32 iounit_map_dma_page(__u32, void *, struct sbus_bus *); | 60 | extern __u32 iounit_map_dma_page(__u32, void *, struct sbus_bus *); |
61 | 61 | ||
62 | extern 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 | ||
121 | extern 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 | ||
37 | void __init | 37 | void __init iounit_init(struct sbus_bus *sbus) |
38 | iounit_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 | ||
58 | void __init | 58 | void __init iommu_init(struct device_node *parent, struct sbus_bus *sbus) |
59 | iommu_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. */ |