diff options
author | David S. Miller <davem@davemloft.net> | 2008-08-26 01:47:20 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-08-29 05:13:11 -0400 |
commit | e003934876e75f96f1445565d8c9084c07943253 (patch) | |
tree | ef44d634c4c1c98248bf3976a9ab0fa7231fd393 /arch/sparc/mm/iommu.c | |
parent | 334ae614772b1147435dce9be3911f9040dff0d9 (diff) |
sparc32: Make IOMMU and IO-UNIT init work with device nodes.
And stick the iommu archdata pointer into the generic OF device tree
of_device struct as well.
We still have to pass the sbus_bus object down into the routines so
that the SBUS bus objects get the iommu cookies set properly. After
drivers get converted to being pure OF drivers, that can go away.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc/mm/iommu.c')
-rw-r--r-- | arch/sparc/mm/iommu.c | 35 |
1 files changed, 20 insertions, 15 deletions
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. */ |