diff options
-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 | ||||
-rw-r--r-- | drivers/sbus/Makefile | 4 | ||||
-rw-r--r-- | drivers/sbus/sbus.c | 170 |
9 files changed, 108 insertions, 286 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); | ||
diff --git a/drivers/sbus/Makefile b/drivers/sbus/Makefile index 56f73318eba2..e94dc25805f9 100644 --- a/drivers/sbus/Makefile +++ b/drivers/sbus/Makefile | |||
@@ -2,8 +2,4 @@ | |||
2 | # Makefile for the linux kernel. | 2 | # Makefile for the linux kernel. |
3 | # | 3 | # |
4 | 4 | ||
5 | ifneq ($(ARCH),m68k) | ||
6 | obj-y := sbus.o | ||
7 | endif | ||
8 | |||
9 | obj-$(CONFIG_SBUSCHAR) += char/ | 5 | obj-$(CONFIG_SBUSCHAR) += char/ |
diff --git a/drivers/sbus/sbus.c b/drivers/sbus/sbus.c deleted file mode 100644 index 399567b7e15e..000000000000 --- a/drivers/sbus/sbus.c +++ /dev/null | |||
@@ -1,170 +0,0 @@ | |||
1 | /* sbus.c: SBus support routines. | ||
2 | * | ||
3 | * Copyright (C) 1995, 2006 David S. Miller (davem@davemloft.net) | ||
4 | */ | ||
5 | |||
6 | #include <linux/kernel.h> | ||
7 | #include <linux/slab.h> | ||
8 | #include <linux/init.h> | ||
9 | #include <linux/device.h> | ||
10 | #include <linux/of_device.h> | ||
11 | |||
12 | #include <asm/system.h> | ||
13 | #include <asm/sbus.h> | ||
14 | #include <asm/dma.h> | ||
15 | #include <asm/oplib.h> | ||
16 | #include <asm/prom.h> | ||
17 | #include <asm/irq.h> | ||
18 | |||
19 | static ssize_t | ||
20 | show_sbusobppath_attr(struct device * dev, struct device_attribute * attr, char * buf) | ||
21 | { | ||
22 | struct sbus_dev *sbus; | ||
23 | |||
24 | sbus = to_sbus_device(dev); | ||
25 | |||
26 | return snprintf (buf, PAGE_SIZE, "%s\n", sbus->ofdev.node->full_name); | ||
27 | } | ||
28 | |||
29 | static DEVICE_ATTR(obppath, S_IRUSR | S_IRGRP | S_IROTH, show_sbusobppath_attr, NULL); | ||
30 | |||
31 | static void __init fill_sbus_device_iommu(struct sbus_dev *sdev) | ||
32 | { | ||
33 | struct of_device *op = of_find_device_by_node(sdev->ofdev.node); | ||
34 | struct dev_archdata *sd, *bus_sd; | ||
35 | struct sbus_bus *sbus; | ||
36 | |||
37 | sbus = sdev->bus; | ||
38 | bus_sd = &sbus->ofdev.dev.archdata; | ||
39 | |||
40 | sd = &sdev->ofdev.dev.archdata; | ||
41 | sd->iommu = bus_sd->iommu; | ||
42 | sd->stc = bus_sd->stc; | ||
43 | |||
44 | sd = &op->dev.archdata; | ||
45 | sd->iommu = bus_sd->iommu; | ||
46 | sd->stc = bus_sd->stc; | ||
47 | } | ||
48 | |||
49 | static void __init fill_sbus_device(struct device_node *dp, struct sbus_dev *sdev) | ||
50 | { | ||
51 | struct dev_archdata *sd; | ||
52 | int err; | ||
53 | |||
54 | sd = &sdev->ofdev.dev.archdata; | ||
55 | sd->prom_node = dp; | ||
56 | sd->op = &sdev->ofdev; | ||
57 | |||
58 | sdev->ofdev.node = dp; | ||
59 | if (sdev->parent) | ||
60 | sdev->ofdev.dev.parent = &sdev->parent->ofdev.dev; | ||
61 | else | ||
62 | sdev->ofdev.dev.parent = &sdev->bus->ofdev.dev; | ||
63 | sdev->ofdev.dev.bus = &sbus_bus_type; | ||
64 | dev_set_name(&sdev->ofdev.dev, "sbus[%08x]", dp->node); | ||
65 | |||
66 | if (of_device_register(&sdev->ofdev) != 0) | ||
67 | printk(KERN_DEBUG "sbus: device registration error for %s!\n", | ||
68 | dp->path_component_name); | ||
69 | |||
70 | /* WE HAVE BEEN INVADED BY ALIENS! */ | ||
71 | err = sysfs_create_file(&sdev->ofdev.dev.kobj, &dev_attr_obppath.attr); | ||
72 | |||
73 | fill_sbus_device_iommu(sdev); | ||
74 | } | ||
75 | |||
76 | static void __init sdev_insert(struct sbus_dev *sdev, struct sbus_dev **root) | ||
77 | { | ||
78 | while (*root) | ||
79 | root = &(*root)->next; | ||
80 | *root = sdev; | ||
81 | sdev->next = NULL; | ||
82 | } | ||
83 | |||
84 | static void __init walk_children(struct device_node *dp, struct sbus_dev *parent, struct sbus_bus *sbus) | ||
85 | { | ||
86 | dp = dp->child; | ||
87 | while (dp) { | ||
88 | struct sbus_dev *sdev; | ||
89 | |||
90 | sdev = kzalloc(sizeof(struct sbus_dev), GFP_ATOMIC); | ||
91 | if (sdev) { | ||
92 | sdev_insert(sdev, &parent->child); | ||
93 | |||
94 | sdev->bus = sbus; | ||
95 | sdev->parent = parent; | ||
96 | |||
97 | fill_sbus_device(dp, sdev); | ||
98 | |||
99 | walk_children(dp, sdev, sbus); | ||
100 | } | ||
101 | dp = dp->sibling; | ||
102 | } | ||
103 | } | ||
104 | |||
105 | static void __init build_one_sbus(struct device_node *dp, int num_sbus) | ||
106 | { | ||
107 | struct device_node *dev_dp; | ||
108 | struct sbus_bus *sbus; | ||
109 | |||
110 | sbus = kzalloc(sizeof(struct sbus_bus), GFP_ATOMIC); | ||
111 | if (!sbus) | ||
112 | return; | ||
113 | |||
114 | sbus_setup_iommu(sbus, dp); | ||
115 | |||
116 | printk("sbus%d: ", num_sbus); | ||
117 | |||
118 | sbus->ofdev.node = dp; | ||
119 | sbus->ofdev.dev.parent = NULL; | ||
120 | sbus->ofdev.dev.bus = &sbus_bus_type; | ||
121 | dev_set_name(&sbus->ofdev.dev, "sbus%d", num_sbus); | ||
122 | |||
123 | if (of_device_register(&sbus->ofdev) != 0) | ||
124 | printk(KERN_DEBUG "sbus: device registration error for %s!\n", | ||
125 | dev_name(&sbus->ofdev.dev)); | ||
126 | |||
127 | dev_dp = dp->child; | ||
128 | while (dev_dp) { | ||
129 | struct sbus_dev *sdev; | ||
130 | |||
131 | sdev = kzalloc(sizeof(struct sbus_dev), GFP_ATOMIC); | ||
132 | if (sdev) { | ||
133 | sdev_insert(sdev, &sbus->devices); | ||
134 | |||
135 | sdev->bus = sbus; | ||
136 | sdev->parent = NULL; | ||
137 | sdev->ofdev.dev.archdata.iommu = | ||
138 | sbus->ofdev.dev.archdata.iommu; | ||
139 | sdev->ofdev.dev.archdata.stc = | ||
140 | sbus->ofdev.dev.archdata.stc; | ||
141 | |||
142 | fill_sbus_device(dev_dp, sdev); | ||
143 | |||
144 | walk_children(dev_dp, sdev, sbus); | ||
145 | } | ||
146 | dev_dp = dev_dp->sibling; | ||
147 | } | ||
148 | } | ||
149 | |||
150 | static int __init sbus_init(void) | ||
151 | { | ||
152 | struct device_node *dp; | ||
153 | const char *sbus_name = "sbus"; | ||
154 | int num_sbus = 0; | ||
155 | |||
156 | if (sparc_cpu_model == sun4d) | ||
157 | sbus_name = "sbi"; | ||
158 | |||
159 | for_each_node_by_name(dp, sbus_name) { | ||
160 | build_one_sbus(dp, num_sbus); | ||
161 | num_sbus++; | ||
162 | |||
163 | } | ||
164 | |||
165 | sbus_arch_postinit(); | ||
166 | |||
167 | return 0; | ||
168 | } | ||
169 | |||
170 | subsys_initcall(sbus_init); | ||