diff options
author | David S. Miller <davem@davemloft.net> | 2008-08-27 07:54:04 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-08-29 05:15:21 -0400 |
commit | 046e26a8ba10b8ceff822f8d91451ab6c1e08c4e (patch) | |
tree | 92e95380c0f7f6c5257023a59b88d4221d3f9744 /arch | |
parent | 5059625ed8862e897760b86effff0f8a35989c0d (diff) |
sparc: Remove generic SBUS probing layer.
The individual SBUS IOMMU arch code now sets the IOMMU information
directly into the OF device objects.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch')
-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/include/asm/irq_64.h | 1 | ||||
-rw-r--r-- | arch/sparc/kernel/ioport.c | 23 | ||||
-rw-r--r-- | arch/sparc/mm/io-unit.c | 30 | ||||
-rw-r--r-- | arch/sparc/mm/iommu.c | 40 | ||||
-rw-r--r-- | arch/sparc64/kernel/sbus.c | 122 |
7 files changed, 108 insertions, 112 deletions
diff --git a/arch/sparc/include/asm/io-unit.h b/arch/sparc/include/asm/io-unit.h index 5df63ef95cf2..96823b47fd45 100644 --- a/arch/sparc/include/asm/io-unit.h +++ b/arch/sparc/include/asm/io-unit.h | |||
@@ -59,6 +59,4 @@ 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 | |||
64 | #endif /* !(_SPARC_IO_UNIT_H) */ | 62 | #endif /* !(_SPARC_IO_UNIT_H) */ |
diff --git a/arch/sparc/include/asm/iommu_32.h b/arch/sparc/include/asm/iommu_32.h index 6b115a174c0c..70c589c05a10 100644 --- a/arch/sparc/include/asm/iommu_32.h +++ b/arch/sparc/include/asm/iommu_32.h | |||
@@ -118,6 +118,4 @@ 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 | |||
123 | #endif /* !(_SPARC_IOMMU_H) */ | 121 | #endif /* !(_SPARC_IOMMU_H) */ |
diff --git a/arch/sparc/include/asm/irq_64.h b/arch/sparc/include/asm/irq_64.h index e3dd9303643d..71673eca3660 100644 --- a/arch/sparc/include/asm/irq_64.h +++ b/arch/sparc/include/asm/irq_64.h | |||
@@ -56,7 +56,6 @@ extern unsigned int sun4u_build_msi(u32 portid, unsigned int *virt_irq_p, | |||
56 | unsigned long imap_base, | 56 | unsigned long imap_base, |
57 | unsigned long iclr_base); | 57 | unsigned long iclr_base); |
58 | extern void sun4u_destroy_msi(unsigned int virt_irq); | 58 | extern void sun4u_destroy_msi(unsigned int virt_irq); |
59 | extern unsigned int sbus_build_irq(void *sbus, unsigned int ino); | ||
60 | 59 | ||
61 | extern unsigned char virt_irq_alloc(unsigned int dev_handle, | 60 | extern unsigned char virt_irq_alloc(unsigned int dev_handle, |
62 | unsigned int dev_ino); | 61 | unsigned int dev_ino); |
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index 24645f9f56f5..bca2d6fd5c4c 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c | |||
@@ -377,22 +377,6 @@ void sbus_dma_sync_single_for_device(struct device *dev, dma_addr_t ba, size_t s | |||
377 | { | 377 | { |
378 | } | 378 | } |
379 | 379 | ||
380 | /* Support code for sbus_init(). */ | ||
381 | void __init sbus_setup_iommu(struct sbus_bus *sbus, struct device_node *dp) | ||
382 | { | ||
383 | #ifndef CONFIG_SUN4 | ||
384 | struct device_node *parent = dp->parent; | ||
385 | |||
386 | if (sparc_cpu_model != sun4d && | ||
387 | parent != NULL && | ||
388 | !strcmp(parent->name, "iommu")) | ||
389 | iommu_init(parent, sbus); | ||
390 | |||
391 | if (sparc_cpu_model == sun4d) | ||
392 | iounit_init(sbus); | ||
393 | #endif | ||
394 | } | ||
395 | |||
396 | static int __init sparc_register_ioport(void) | 380 | static int __init sparc_register_ioport(void) |
397 | { | 381 | { |
398 | register_proc_sparc_ioport(); | 382 | register_proc_sparc_ioport(); |
@@ -402,13 +386,6 @@ static int __init sparc_register_ioport(void) | |||
402 | 386 | ||
403 | arch_initcall(sparc_register_ioport); | 387 | arch_initcall(sparc_register_ioport); |
404 | 388 | ||
405 | void __init sbus_arch_postinit(void) | ||
406 | { | ||
407 | if (sparc_cpu_model == sun4d) { | ||
408 | extern void sun4d_init_sbi_irq(void); | ||
409 | sun4d_init_sbi_irq(); | ||
410 | } | ||
411 | } | ||
412 | #endif /* CONFIG_SBUS */ | 389 | #endif /* CONFIG_SBUS */ |
413 | 390 | ||
414 | #ifdef CONFIG_PCI | 391 | #ifdef CONFIG_PCI |
diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c index 0f97ab30df3f..caf551ad9d8c 100644 --- a/arch/sparc/mm/io-unit.c +++ b/arch/sparc/mm/io-unit.c | |||
@@ -34,18 +34,10 @@ | |||
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 iounit_init(struct sbus_bus *sbus) | 37 | static void __init iounit_iommu_init(struct of_device *op) |
38 | { | 38 | { |
39 | struct device_node *dp = sbus->ofdev.node; | ||
40 | struct iounit_struct *iounit; | 39 | struct iounit_struct *iounit; |
41 | iopte_t *xpt, *xptend; | 40 | iopte_t *xpt, *xptend; |
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 | } | ||
49 | 41 | ||
50 | iounit = kzalloc(sizeof(struct iounit_struct), GFP_ATOMIC); | 42 | iounit = kzalloc(sizeof(struct iounit_struct), GFP_ATOMIC); |
51 | if (!iounit) { | 43 | if (!iounit) { |
@@ -66,7 +58,6 @@ void __init iounit_init(struct sbus_bus *sbus) | |||
66 | prom_halt(); | 58 | prom_halt(); |
67 | } | 59 | } |
68 | 60 | ||
69 | sbus->ofdev.dev.archdata.iommu = iounit; | ||
70 | op->dev.archdata.iommu = iounit; | 61 | op->dev.archdata.iommu = iounit; |
71 | iounit->page_table = xpt; | 62 | iounit->page_table = xpt; |
72 | spin_lock_init(&iounit->lock); | 63 | spin_lock_init(&iounit->lock); |
@@ -76,6 +67,25 @@ void __init iounit_init(struct sbus_bus *sbus) | |||
76 | iopte_val(*xpt++) = 0; | 67 | iopte_val(*xpt++) = 0; |
77 | } | 68 | } |
78 | 69 | ||
70 | static int __init iounit_init(void) | ||
71 | { | ||
72 | extern void sun4d_init_sbi_irq(void); | ||
73 | struct device_node *dp; | ||
74 | |||
75 | for_each_node_by_name(dp, "sbi") { | ||
76 | struct of_device *op = of_find_device_by_node(dp); | ||
77 | |||
78 | iounit_iommu_init(op); | ||
79 | of_propagate_archdata(op); | ||
80 | } | ||
81 | |||
82 | sun4d_init_sbi_irq(); | ||
83 | |||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | subsys_initcall(iounit_init); | ||
88 | |||
79 | /* One has to hold iounit->lock to call this */ | 89 | /* One has to hold iounit->lock to call this */ |
80 | static unsigned long iounit_get_area(struct iounit_struct *iounit, unsigned long vaddr, int size) | 90 | static unsigned long iounit_get_area(struct iounit_struct *iounit, unsigned long vaddr, int size) |
81 | { | 91 | { |
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. */ |
diff --git a/arch/sparc64/kernel/sbus.c b/arch/sparc64/kernel/sbus.c index 0b3e7bc96f61..60605eaf49bb 100644 --- a/arch/sparc64/kernel/sbus.c +++ b/arch/sparc64/kernel/sbus.c | |||
@@ -201,10 +201,9 @@ static unsigned long sysio_imap_to_iclr(unsigned long imap) | |||
201 | return imap + diff; | 201 | return imap + diff; |
202 | } | 202 | } |
203 | 203 | ||
204 | unsigned int sbus_build_irq(void *buscookie, unsigned int ino) | 204 | static unsigned int sbus_build_irq(struct of_device *op, unsigned int ino) |
205 | { | 205 | { |
206 | struct sbus_bus *sbus = (struct sbus_bus *)buscookie; | 206 | struct iommu *iommu = op->dev.archdata.iommu; |
207 | struct iommu *iommu = sbus->ofdev.dev.archdata.iommu; | ||
208 | unsigned long reg_base = iommu->write_complete_reg - 0x2000UL; | 207 | unsigned long reg_base = iommu->write_complete_reg - 0x2000UL; |
209 | unsigned long imap, iclr; | 208 | unsigned long imap, iclr; |
210 | int sbus_level = 0; | 209 | int sbus_level = 0; |
@@ -265,12 +264,12 @@ unsigned int sbus_build_irq(void *buscookie, unsigned int ino) | |||
265 | #define SYSIO_UEAFSR_RESV2 0x0000001fffffffffUL /* Reserved */ | 264 | #define SYSIO_UEAFSR_RESV2 0x0000001fffffffffUL /* Reserved */ |
266 | static irqreturn_t sysio_ue_handler(int irq, void *dev_id) | 265 | static irqreturn_t sysio_ue_handler(int irq, void *dev_id) |
267 | { | 266 | { |
268 | struct sbus_bus *sbus = dev_id; | 267 | struct of_device *op = dev_id; |
269 | struct iommu *iommu = sbus->ofdev.dev.archdata.iommu; | 268 | struct iommu *iommu = op->dev.archdata.iommu; |
270 | unsigned long reg_base = iommu->write_complete_reg - 0x2000UL; | 269 | unsigned long reg_base = iommu->write_complete_reg - 0x2000UL; |
271 | unsigned long afsr_reg, afar_reg; | 270 | unsigned long afsr_reg, afar_reg; |
272 | unsigned long afsr, afar, error_bits; | 271 | unsigned long afsr, afar, error_bits; |
273 | int reported; | 272 | int reported, portid; |
274 | 273 | ||
275 | afsr_reg = reg_base + SYSIO_UE_AFSR; | 274 | afsr_reg = reg_base + SYSIO_UE_AFSR; |
276 | afar_reg = reg_base + SYSIO_UE_AFAR; | 275 | afar_reg = reg_base + SYSIO_UE_AFAR; |
@@ -285,9 +284,11 @@ static irqreturn_t sysio_ue_handler(int irq, void *dev_id) | |||
285 | SYSIO_UEAFSR_SPIO | SYSIO_UEAFSR_SDRD | SYSIO_UEAFSR_SDWR); | 284 | SYSIO_UEAFSR_SPIO | SYSIO_UEAFSR_SDRD | SYSIO_UEAFSR_SDWR); |
286 | upa_writeq(error_bits, afsr_reg); | 285 | upa_writeq(error_bits, afsr_reg); |
287 | 286 | ||
287 | portid = of_getintprop_default(op->node, "portid", -1); | ||
288 | |||
288 | /* Log the error. */ | 289 | /* Log the error. */ |
289 | printk("SYSIO[%x]: Uncorrectable ECC Error, primary error type[%s]\n", | 290 | printk("SYSIO[%x]: Uncorrectable ECC Error, primary error type[%s]\n", |
290 | sbus->portid, | 291 | portid, |
291 | (((error_bits & SYSIO_UEAFSR_PPIO) ? | 292 | (((error_bits & SYSIO_UEAFSR_PPIO) ? |
292 | "PIO" : | 293 | "PIO" : |
293 | ((error_bits & SYSIO_UEAFSR_PDRD) ? | 294 | ((error_bits & SYSIO_UEAFSR_PDRD) ? |
@@ -295,12 +296,12 @@ static irqreturn_t sysio_ue_handler(int irq, void *dev_id) | |||
295 | ((error_bits & SYSIO_UEAFSR_PDWR) ? | 296 | ((error_bits & SYSIO_UEAFSR_PDWR) ? |
296 | "DVMA Write" : "???"))))); | 297 | "DVMA Write" : "???"))))); |
297 | printk("SYSIO[%x]: DOFF[%lx] SIZE[%lx] MID[%lx]\n", | 298 | printk("SYSIO[%x]: DOFF[%lx] SIZE[%lx] MID[%lx]\n", |
298 | sbus->portid, | 299 | portid, |
299 | (afsr & SYSIO_UEAFSR_DOFF) >> 45UL, | 300 | (afsr & SYSIO_UEAFSR_DOFF) >> 45UL, |
300 | (afsr & SYSIO_UEAFSR_SIZE) >> 42UL, | 301 | (afsr & SYSIO_UEAFSR_SIZE) >> 42UL, |
301 | (afsr & SYSIO_UEAFSR_MID) >> 37UL); | 302 | (afsr & SYSIO_UEAFSR_MID) >> 37UL); |
302 | printk("SYSIO[%x]: AFAR[%016lx]\n", sbus->portid, afar); | 303 | printk("SYSIO[%x]: AFAR[%016lx]\n", portid, afar); |
303 | printk("SYSIO[%x]: Secondary UE errors [", sbus->portid); | 304 | printk("SYSIO[%x]: Secondary UE errors [", portid); |
304 | reported = 0; | 305 | reported = 0; |
305 | if (afsr & SYSIO_UEAFSR_SPIO) { | 306 | if (afsr & SYSIO_UEAFSR_SPIO) { |
306 | reported++; | 307 | reported++; |
@@ -337,12 +338,12 @@ static irqreturn_t sysio_ue_handler(int irq, void *dev_id) | |||
337 | #define SYSIO_CEAFSR_RESV2 0x0000001fffffffffUL /* Reserved */ | 338 | #define SYSIO_CEAFSR_RESV2 0x0000001fffffffffUL /* Reserved */ |
338 | static irqreturn_t sysio_ce_handler(int irq, void *dev_id) | 339 | static irqreturn_t sysio_ce_handler(int irq, void *dev_id) |
339 | { | 340 | { |
340 | struct sbus_bus *sbus = dev_id; | 341 | struct of_device *op = dev_id; |
341 | struct iommu *iommu = sbus->ofdev.dev.archdata.iommu; | 342 | struct iommu *iommu = op->dev.archdata.iommu; |
342 | unsigned long reg_base = iommu->write_complete_reg - 0x2000UL; | 343 | unsigned long reg_base = iommu->write_complete_reg - 0x2000UL; |
343 | unsigned long afsr_reg, afar_reg; | 344 | unsigned long afsr_reg, afar_reg; |
344 | unsigned long afsr, afar, error_bits; | 345 | unsigned long afsr, afar, error_bits; |
345 | int reported; | 346 | int reported, portid; |
346 | 347 | ||
347 | afsr_reg = reg_base + SYSIO_CE_AFSR; | 348 | afsr_reg = reg_base + SYSIO_CE_AFSR; |
348 | afar_reg = reg_base + SYSIO_CE_AFAR; | 349 | afar_reg = reg_base + SYSIO_CE_AFAR; |
@@ -357,8 +358,10 @@ static irqreturn_t sysio_ce_handler(int irq, void *dev_id) | |||
357 | SYSIO_CEAFSR_SPIO | SYSIO_CEAFSR_SDRD | SYSIO_CEAFSR_SDWR); | 358 | SYSIO_CEAFSR_SPIO | SYSIO_CEAFSR_SDRD | SYSIO_CEAFSR_SDWR); |
358 | upa_writeq(error_bits, afsr_reg); | 359 | upa_writeq(error_bits, afsr_reg); |
359 | 360 | ||
361 | portid = of_getintprop_default(op->node, "portid", -1); | ||
362 | |||
360 | printk("SYSIO[%x]: Correctable ECC Error, primary error type[%s]\n", | 363 | printk("SYSIO[%x]: Correctable ECC Error, primary error type[%s]\n", |
361 | sbus->portid, | 364 | portid, |
362 | (((error_bits & SYSIO_CEAFSR_PPIO) ? | 365 | (((error_bits & SYSIO_CEAFSR_PPIO) ? |
363 | "PIO" : | 366 | "PIO" : |
364 | ((error_bits & SYSIO_CEAFSR_PDRD) ? | 367 | ((error_bits & SYSIO_CEAFSR_PDRD) ? |
@@ -370,14 +373,14 @@ static irqreturn_t sysio_ce_handler(int irq, void *dev_id) | |||
370 | * XXX UDB CE trap handler does... -DaveM | 373 | * XXX UDB CE trap handler does... -DaveM |
371 | */ | 374 | */ |
372 | printk("SYSIO[%x]: DOFF[%lx] ECC Syndrome[%lx] Size[%lx] MID[%lx]\n", | 375 | printk("SYSIO[%x]: DOFF[%lx] ECC Syndrome[%lx] Size[%lx] MID[%lx]\n", |
373 | sbus->portid, | 376 | portid, |
374 | (afsr & SYSIO_CEAFSR_DOFF) >> 45UL, | 377 | (afsr & SYSIO_CEAFSR_DOFF) >> 45UL, |
375 | (afsr & SYSIO_CEAFSR_ESYND) >> 48UL, | 378 | (afsr & SYSIO_CEAFSR_ESYND) >> 48UL, |
376 | (afsr & SYSIO_CEAFSR_SIZE) >> 42UL, | 379 | (afsr & SYSIO_CEAFSR_SIZE) >> 42UL, |
377 | (afsr & SYSIO_CEAFSR_MID) >> 37UL); | 380 | (afsr & SYSIO_CEAFSR_MID) >> 37UL); |
378 | printk("SYSIO[%x]: AFAR[%016lx]\n", sbus->portid, afar); | 381 | printk("SYSIO[%x]: AFAR[%016lx]\n", portid, afar); |
379 | 382 | ||
380 | printk("SYSIO[%x]: Secondary CE errors [", sbus->portid); | 383 | printk("SYSIO[%x]: Secondary CE errors [", portid); |
381 | reported = 0; | 384 | reported = 0; |
382 | if (afsr & SYSIO_CEAFSR_SPIO) { | 385 | if (afsr & SYSIO_CEAFSR_SPIO) { |
383 | reported++; | 386 | reported++; |
@@ -414,11 +417,11 @@ static irqreturn_t sysio_ce_handler(int irq, void *dev_id) | |||
414 | #define SYSIO_SBAFSR_RESV3 0x0000001fffffffffUL /* Reserved */ | 417 | #define SYSIO_SBAFSR_RESV3 0x0000001fffffffffUL /* Reserved */ |
415 | static irqreturn_t sysio_sbus_error_handler(int irq, void *dev_id) | 418 | static irqreturn_t sysio_sbus_error_handler(int irq, void *dev_id) |
416 | { | 419 | { |
417 | struct sbus_bus *sbus = dev_id; | 420 | struct of_device *op = dev_id; |
418 | struct iommu *iommu = sbus->ofdev.dev.archdata.iommu; | 421 | struct iommu *iommu = op->dev.archdata.iommu; |
419 | unsigned long afsr_reg, afar_reg, reg_base; | 422 | unsigned long afsr_reg, afar_reg, reg_base; |
420 | unsigned long afsr, afar, error_bits; | 423 | unsigned long afsr, afar, error_bits; |
421 | int reported; | 424 | int reported, portid; |
422 | 425 | ||
423 | reg_base = iommu->write_complete_reg - 0x2000UL; | 426 | reg_base = iommu->write_complete_reg - 0x2000UL; |
424 | afsr_reg = reg_base + SYSIO_SBUS_AFSR; | 427 | afsr_reg = reg_base + SYSIO_SBUS_AFSR; |
@@ -433,9 +436,11 @@ static irqreturn_t sysio_sbus_error_handler(int irq, void *dev_id) | |||
433 | SYSIO_SBAFSR_SLE | SYSIO_SBAFSR_STO | SYSIO_SBAFSR_SBERR); | 436 | SYSIO_SBAFSR_SLE | SYSIO_SBAFSR_STO | SYSIO_SBAFSR_SBERR); |
434 | upa_writeq(error_bits, afsr_reg); | 437 | upa_writeq(error_bits, afsr_reg); |
435 | 438 | ||
439 | portid = of_getintprop_default(op->node, "portid", -1); | ||
440 | |||
436 | /* Log the error. */ | 441 | /* Log the error. */ |
437 | printk("SYSIO[%x]: SBUS Error, primary error type[%s] read(%d)\n", | 442 | printk("SYSIO[%x]: SBUS Error, primary error type[%s] read(%d)\n", |
438 | sbus->portid, | 443 | portid, |
439 | (((error_bits & SYSIO_SBAFSR_PLE) ? | 444 | (((error_bits & SYSIO_SBAFSR_PLE) ? |
440 | "Late PIO Error" : | 445 | "Late PIO Error" : |
441 | ((error_bits & SYSIO_SBAFSR_PTO) ? | 446 | ((error_bits & SYSIO_SBAFSR_PTO) ? |
@@ -444,11 +449,11 @@ static irqreturn_t sysio_sbus_error_handler(int irq, void *dev_id) | |||
444 | "Error Ack" : "???")))), | 449 | "Error Ack" : "???")))), |
445 | (afsr & SYSIO_SBAFSR_RD) ? 1 : 0); | 450 | (afsr & SYSIO_SBAFSR_RD) ? 1 : 0); |
446 | printk("SYSIO[%x]: size[%lx] MID[%lx]\n", | 451 | printk("SYSIO[%x]: size[%lx] MID[%lx]\n", |
447 | sbus->portid, | 452 | portid, |
448 | (afsr & SYSIO_SBAFSR_SIZE) >> 42UL, | 453 | (afsr & SYSIO_SBAFSR_SIZE) >> 42UL, |
449 | (afsr & SYSIO_SBAFSR_MID) >> 37UL); | 454 | (afsr & SYSIO_SBAFSR_MID) >> 37UL); |
450 | printk("SYSIO[%x]: AFAR[%016lx]\n", sbus->portid, afar); | 455 | printk("SYSIO[%x]: AFAR[%016lx]\n", portid, afar); |
451 | printk("SYSIO[%x]: Secondary SBUS errors [", sbus->portid); | 456 | printk("SYSIO[%x]: Secondary SBUS errors [", portid); |
452 | reported = 0; | 457 | reported = 0; |
453 | if (afsr & SYSIO_SBAFSR_SLE) { | 458 | if (afsr & SYSIO_SBAFSR_SLE) { |
454 | reported++; | 459 | reported++; |
@@ -480,34 +485,37 @@ static irqreturn_t sysio_sbus_error_handler(int irq, void *dev_id) | |||
480 | #define SYSIO_CE_INO 0x35 | 485 | #define SYSIO_CE_INO 0x35 |
481 | #define SYSIO_SBUSERR_INO 0x36 | 486 | #define SYSIO_SBUSERR_INO 0x36 |
482 | 487 | ||
483 | static void __init sysio_register_error_handlers(struct sbus_bus *sbus) | 488 | static void __init sysio_register_error_handlers(struct of_device *op) |
484 | { | 489 | { |
485 | struct iommu *iommu = sbus->ofdev.dev.archdata.iommu; | 490 | struct iommu *iommu = op->dev.archdata.iommu; |
486 | unsigned long reg_base = iommu->write_complete_reg - 0x2000UL; | 491 | unsigned long reg_base = iommu->write_complete_reg - 0x2000UL; |
487 | unsigned int irq; | 492 | unsigned int irq; |
488 | u64 control; | 493 | u64 control; |
494 | int portid; | ||
495 | |||
496 | portid = of_getintprop_default(op->node, "portid", -1); | ||
489 | 497 | ||
490 | irq = sbus_build_irq(sbus, SYSIO_UE_INO); | 498 | irq = sbus_build_irq(op, SYSIO_UE_INO); |
491 | if (request_irq(irq, sysio_ue_handler, 0, | 499 | if (request_irq(irq, sysio_ue_handler, 0, |
492 | "SYSIO_UE", sbus) < 0) { | 500 | "SYSIO_UE", op) < 0) { |
493 | prom_printf("SYSIO[%x]: Cannot register UE interrupt.\n", | 501 | prom_printf("SYSIO[%x]: Cannot register UE interrupt.\n", |
494 | sbus->portid); | 502 | portid); |
495 | prom_halt(); | 503 | prom_halt(); |
496 | } | 504 | } |
497 | 505 | ||
498 | irq = sbus_build_irq(sbus, SYSIO_CE_INO); | 506 | irq = sbus_build_irq(op, SYSIO_CE_INO); |
499 | if (request_irq(irq, sysio_ce_handler, 0, | 507 | if (request_irq(irq, sysio_ce_handler, 0, |
500 | "SYSIO_CE", sbus) < 0) { | 508 | "SYSIO_CE", op) < 0) { |
501 | prom_printf("SYSIO[%x]: Cannot register CE interrupt.\n", | 509 | prom_printf("SYSIO[%x]: Cannot register CE interrupt.\n", |
502 | sbus->portid); | 510 | portid); |
503 | prom_halt(); | 511 | prom_halt(); |
504 | } | 512 | } |
505 | 513 | ||
506 | irq = sbus_build_irq(sbus, SYSIO_SBUSERR_INO); | 514 | irq = sbus_build_irq(op, SYSIO_SBUSERR_INO); |
507 | if (request_irq(irq, sysio_sbus_error_handler, 0, | 515 | if (request_irq(irq, sysio_sbus_error_handler, 0, |
508 | "SYSIO_SBERR", sbus) < 0) { | 516 | "SYSIO_SBERR", op) < 0) { |
509 | prom_printf("SYSIO[%x]: Cannot register SBUS Error interrupt.\n", | 517 | prom_printf("SYSIO[%x]: Cannot register SBUS Error interrupt.\n", |
510 | sbus->portid); | 518 | portid); |
511 | prom_halt(); | 519 | prom_halt(); |
512 | } | 520 | } |
513 | 521 | ||
@@ -523,19 +531,15 @@ static void __init sysio_register_error_handlers(struct sbus_bus *sbus) | |||
523 | } | 531 | } |
524 | 532 | ||
525 | /* Boot time initialization. */ | 533 | /* Boot time initialization. */ |
526 | static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus) | 534 | static void __init sbus_iommu_init(struct of_device *op) |
527 | { | 535 | { |
528 | const struct linux_prom64_registers *pr; | 536 | const struct linux_prom64_registers *pr; |
529 | struct device_node *dp; | 537 | struct device_node *dp = op->node; |
530 | struct iommu *iommu; | 538 | struct iommu *iommu; |
531 | struct strbuf *strbuf; | 539 | struct strbuf *strbuf; |
532 | unsigned long regs, reg_base; | 540 | unsigned long regs, reg_base; |
541 | int i, portid; | ||
533 | u64 control; | 542 | u64 control; |
534 | int i; | ||
535 | |||
536 | dp = of_find_node_by_phandle(__node); | ||
537 | |||
538 | sbus->portid = of_getintprop_default(dp, "upa-portid", -1); | ||
539 | 543 | ||
540 | pr = of_get_property(dp, "reg", NULL); | 544 | pr = of_get_property(dp, "reg", NULL); |
541 | if (!pr) { | 545 | if (!pr) { |
@@ -552,9 +556,9 @@ static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus) | |||
552 | if (!strbuf) | 556 | if (!strbuf) |
553 | goto fatal_memory_error; | 557 | goto fatal_memory_error; |
554 | 558 | ||
555 | sbus->ofdev.dev.archdata.iommu = iommu; | 559 | op->dev.archdata.iommu = iommu; |
556 | sbus->ofdev.dev.archdata.stc = strbuf; | 560 | op->dev.archdata.stc = strbuf; |
557 | sbus->ofdev.dev.archdata.numa_node = -1; | 561 | op->dev.archdata.numa_node = -1; |
558 | 562 | ||
559 | reg_base = regs + SYSIO_IOMMUREG_BASE; | 563 | reg_base = regs + SYSIO_IOMMUREG_BASE; |
560 | iommu->iommu_control = reg_base + IOMMU_CONTROL; | 564 | iommu->iommu_control = reg_base + IOMMU_CONTROL; |
@@ -582,8 +586,9 @@ static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus) | |||
582 | */ | 586 | */ |
583 | iommu->write_complete_reg = regs + 0x2000UL; | 587 | iommu->write_complete_reg = regs + 0x2000UL; |
584 | 588 | ||
585 | printk("SYSIO: UPA portID %x, at %016lx\n", | 589 | portid = of_getintprop_default(op->node, "portid", -1); |
586 | sbus->portid, regs); | 590 | printk(KERN_INFO "SYSIO: UPA portID %x, at %016lx\n", |
591 | portid, regs); | ||
587 | 592 | ||
588 | /* Setup for TSB_SIZE=7, TBW_SIZE=0, MMU_DE=1, MMU_EN=1 */ | 593 | /* Setup for TSB_SIZE=7, TBW_SIZE=0, MMU_DE=1, MMU_EN=1 */ |
589 | if (iommu_table_init(iommu, IO_TSB_SIZE, MAP_BASE, 0xffffffff, -1)) | 594 | if (iommu_table_init(iommu, IO_TSB_SIZE, MAP_BASE, 0xffffffff, -1)) |
@@ -641,23 +646,30 @@ static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus) | |||
641 | 646 | ||
642 | /* Now some Xfire specific grot... */ | 647 | /* Now some Xfire specific grot... */ |
643 | if (this_is_starfire) | 648 | if (this_is_starfire) |
644 | starfire_hookup(sbus->portid); | 649 | starfire_hookup(portid); |
645 | 650 | ||
646 | sysio_register_error_handlers(sbus); | 651 | sysio_register_error_handlers(op); |
647 | return; | 652 | return; |
648 | 653 | ||
649 | fatal_memory_error: | 654 | fatal_memory_error: |
650 | prom_printf("sbus_iommu_init: Fatal memory allocation error.\n"); | 655 | prom_printf("sbus_iommu_init: Fatal memory allocation error.\n"); |
651 | } | 656 | } |
652 | 657 | ||
653 | void __init sbus_setup_iommu(struct sbus_bus *sbus, struct device_node *dp) | 658 | static int __init sbus_init(void) |
654 | { | ||
655 | sbus_iommu_init(dp->node, sbus); | ||
656 | } | ||
657 | |||
658 | void __init sbus_arch_postinit(void) | ||
659 | { | 659 | { |
660 | extern void firetruck_init(void); | 660 | extern void firetruck_init(void); |
661 | struct device_node *dp; | ||
662 | |||
663 | for_each_node_by_name(dp, "sbus") { | ||
664 | struct of_device *op = of_find_device_by_node(dp); | ||
665 | |||
666 | sbus_iommu_init(op); | ||
667 | of_propagate_archdata(op); | ||
668 | } | ||
661 | 669 | ||
662 | firetruck_init(); | 670 | firetruck_init(); |
671 | |||
672 | return 0; | ||
663 | } | 673 | } |
674 | |||
675 | subsys_initcall(sbus_init); | ||