diff options
Diffstat (limited to 'arch/sparc/mm/iommu.c')
-rw-r--r-- | arch/sparc/mm/iommu.c | 40 |
1 files changed, 21 insertions, 19 deletions
diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c index 2970cea877b1..7c55450b55b9 100644 --- a/arch/sparc/mm/iommu.c +++ b/arch/sparc/mm/iommu.c | |||
@@ -55,33 +55,20 @@ 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 iommu_init(struct device_node *parent, struct sbus_bus *sbus) | 58 | static void __init sbus_iommu_init(struct of_device *op) |
59 | { | 59 | { |
60 | struct of_device *parent_op, *op; | ||
61 | struct iommu_struct *iommu; | 60 | struct iommu_struct *iommu; |
62 | unsigned int impl, vers; | 61 | unsigned int impl, vers; |
63 | unsigned long *bitmap; | 62 | unsigned long *bitmap; |
64 | unsigned long tmp; | 63 | unsigned long tmp; |
65 | 64 | ||
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 | } | ||
77 | |||
78 | iommu = kmalloc(sizeof(struct iommu_struct), GFP_ATOMIC); | 65 | iommu = kmalloc(sizeof(struct iommu_struct), GFP_ATOMIC); |
79 | if (!iommu) { | 66 | if (!iommu) { |
80 | prom_printf("Unable to allocate iommu structure\n"); | 67 | prom_printf("Unable to allocate iommu structure\n"); |
81 | prom_halt(); | 68 | prom_halt(); |
82 | } | 69 | } |
83 | 70 | ||
84 | iommu->regs = of_ioremap(&parent_op->resource[0], 0, PAGE_SIZE * 3, | 71 | iommu->regs = of_ioremap(&op->resource[0], 0, PAGE_SIZE * 3, |
85 | "iommu_regs"); | 72 | "iommu_regs"); |
86 | if (!iommu->regs) { | 73 | if (!iommu->regs) { |
87 | prom_printf("Cannot map IOMMU registers\n"); | 74 | prom_printf("Cannot map IOMMU registers\n"); |
@@ -132,14 +119,29 @@ void __init iommu_init(struct device_node *parent, struct sbus_bus *sbus) | |||
132 | else | 119 | else |
133 | iommu->usemap.num_colors = 1; | 120 | iommu->usemap.num_colors = 1; |
134 | 121 | ||
135 | printk("IOMMU: impl %d vers %d table 0x%p[%d B] map [%d b]\n", | 122 | printk(KERN_INFO "IOMMU: impl %d vers %d table 0x%p[%d B] map [%d b]\n", |
136 | impl, vers, iommu->page_table, | 123 | impl, vers, iommu->page_table, |
137 | (int)(IOMMU_NPTES*sizeof(iopte_t)), (int)IOMMU_NPTES); | 124 | (int)(IOMMU_NPTES*sizeof(iopte_t)), (int)IOMMU_NPTES); |
138 | 125 | ||
139 | sbus->ofdev.dev.archdata.iommu = iommu; | ||
140 | op->dev.archdata.iommu = iommu; | 126 | op->dev.archdata.iommu = iommu; |
141 | } | 127 | } |
142 | 128 | ||
129 | static int __init iommu_init(void) | ||
130 | { | ||
131 | struct device_node *dp; | ||
132 | |||
133 | for_each_node_by_name(dp, "iommu") { | ||
134 | struct of_device *op = of_find_device_by_node(dp); | ||
135 | |||
136 | sbus_iommu_init(op); | ||
137 | of_propagate_archdata(op); | ||
138 | } | ||
139 | |||
140 | return 0; | ||
141 | } | ||
142 | |||
143 | subsys_initcall(iommu_init); | ||
144 | |||
143 | /* This begs to be btfixup-ed by srmmu. */ | 145 | /* This begs to be btfixup-ed by srmmu. */ |
144 | /* Flush the iotlb entries to ram. */ | 146 | /* Flush the iotlb entries to ram. */ |
145 | /* This could be better if we didn't have to flush whole pages. */ | 147 | /* This could be better if we didn't have to flush whole pages. */ |