aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-08-26 01:47:20 -0400
committerDavid S. Miller <davem@davemloft.net>2008-08-29 05:13:11 -0400
commite003934876e75f96f1445565d8c9084c07943253 (patch)
treeef44d634c4c1c98248bf3976a9ab0fa7231fd393 /arch
parent334ae614772b1147435dce9be3911f9040dff0d9 (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')
-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. */