diff options
Diffstat (limited to 'arch/sparc/mm')
-rw-r--r-- | arch/sparc/mm/io-unit.c | 29 | ||||
-rw-r--r-- | arch/sparc/mm/iommu.c | 35 |
2 files changed, 35 insertions, 29 deletions
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. */ |