Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[SBUS]: Rewrite and plug into of_device framework.

I severely apologize, I was still learning how to program
in C when I wrote this stuff 10 years ago...

Signed-off-by: David S. Miller <davem@davemloft.net>

authored by

David S. Miller and committed by
David S. Miller
576c352e fd531431

+301 -335
+85
arch/sparc/kernel/ioport.c
··· 39 39 #include <asm/io.h> 40 40 #include <asm/vaddrs.h> 41 41 #include <asm/oplib.h> 42 + #include <asm/prom.h> 43 + #include <asm/sbus.h> 42 44 #include <asm/page.h> 43 45 #include <asm/pgalloc.h> 44 46 #include <asm/dma.h> ··· 459 457 void sbus_dma_sync_sg_for_device(struct sbus_dev *sdev, struct scatterlist *sg, int n, int direction) 460 458 { 461 459 printk("sbus_dma_sync_sg_for_device: not implemented yet\n"); 460 + } 461 + 462 + /* Support code for sbus_init(). */ 463 + /* 464 + * XXX This functions appears to be a distorted version of 465 + * prom_sbus_ranges_init(), with all sun4d stuff cut away. 466 + * Ask DaveM what is going on here, how is sun4d supposed to work... XXX 467 + */ 468 + /* added back sun4d patch from Thomas Bogendoerfer - should be OK (crn) */ 469 + void __init sbus_arch_bus_ranges_init(struct device_node *pn, struct sbus_bus *sbus) 470 + { 471 + int parent_node = pn->node; 472 + 473 + if (sparc_cpu_model == sun4d) { 474 + struct linux_prom_ranges iounit_ranges[PROMREG_MAX]; 475 + int num_iounit_ranges, len; 476 + 477 + len = prom_getproperty(parent_node, "ranges", 478 + (char *) iounit_ranges, 479 + sizeof (iounit_ranges)); 480 + if (len != -1) { 481 + num_iounit_ranges = 482 + (len / sizeof(struct linux_prom_ranges)); 483 + prom_adjust_ranges(sbus->sbus_ranges, 484 + sbus->num_sbus_ranges, 485 + iounit_ranges, num_iounit_ranges); 486 + } 487 + } 488 + } 489 + 490 + void __init sbus_setup_iommu(struct sbus_bus *sbus, struct device_node *dp) 491 + { 492 + struct device_node *parent = dp->parent; 493 + 494 + if (sparc_cpu_model != sun4d && 495 + parent != NULL && 496 + !strcmp(parent->name, "iommu")) { 497 + extern void iommu_init(int iommu_node, struct sbus_bus *sbus); 498 + 499 + iommu_init(parent->node, sbus); 500 + } 501 + 502 + if (sparc_cpu_model == sun4d) { 503 + extern void iounit_init(int sbi_node, int iounit_node, 504 + struct sbus_bus *sbus); 505 + 506 + iounit_init(dp->node, parent->node, sbus); 507 + } 508 + } 509 + 510 + void __init sbus_setup_arch_props(struct sbus_bus *sbus, struct device_node *dp) 511 + { 512 + if (sparc_cpu_model == sun4d) { 513 + struct device_node *parent = dp->parent; 514 + 515 + sbus->devid = of_getintprop_default(parent, "device-id", 0); 516 + sbus->board = of_getintprop_default(parent, "board#", 0); 517 + } 518 + } 519 + 520 + int __init sbus_arch_preinit(void) 521 + { 522 + extern void register_proc_sparc_ioport(void); 523 + 524 + register_proc_sparc_ioport(); 525 + 526 + #ifdef CONFIG_SUN4 527 + { 528 + extern void sun4_dvma_init(void); 529 + sun4_dvma_init(); 530 + } 531 + return 1; 532 + #else 533 + return 0; 534 + #endif 535 + } 536 + 537 + void __init sbus_arch_postinit(void) 538 + { 539 + if (sparc_cpu_model == sun4d) { 540 + extern void sun4d_init_sbi_irq(void); 541 + sun4d_init_sbi_irq(); 542 + } 462 543 } 463 544 #endif /* CONFIG_SBUS */ 464 545
+30 -1
arch/sparc64/kernel/sbus.c
··· 1099 1099 } 1100 1100 1101 1101 /* Boot time initialization. */ 1102 - void __init sbus_iommu_init(int __node, struct sbus_bus *sbus) 1102 + static void __init sbus_iommu_init(int __node, struct sbus_bus *sbus) 1103 1103 { 1104 1104 struct linux_prom64_registers *pr; 1105 1105 struct device_node *dp; ··· 1246 1246 1247 1247 sdev->irqs[0] = sbus_build_irq(sdev->bus, pri); 1248 1248 } 1249 + } 1250 + 1251 + void __init sbus_arch_bus_ranges_init(struct device_node *pn, struct sbus_bus *sbus) 1252 + { 1253 + } 1254 + 1255 + void __init sbus_setup_iommu(struct sbus_bus *sbus, struct device_node *dp) 1256 + { 1257 + sbus_iommu_init(dp->node, sbus); 1258 + } 1259 + 1260 + void __init sbus_setup_arch_props(struct sbus_bus *sbus, struct device_node *dp) 1261 + { 1262 + } 1263 + 1264 + int __init sbus_arch_preinit(void) 1265 + { 1266 + return 0; 1267 + } 1268 + 1269 + void __init sbus_arch_postinit(void) 1270 + { 1271 + extern void firetruck_init(void); 1272 + extern void auxio_probe(void); 1273 + extern void clock_probe(void); 1274 + 1275 + firetruck_init(); 1276 + auxio_probe(); 1277 + clock_probe(); 1249 1278 }
+147 -318
drivers/sbus/sbus.c
··· 13 13 #include <asm/sbus.h> 14 14 #include <asm/dma.h> 15 15 #include <asm/oplib.h> 16 + #include <asm/prom.h> 17 + #include <asm/of_device.h> 16 18 #include <asm/bpp.h> 17 19 #include <asm/irq.h> 18 20 19 21 struct sbus_bus *sbus_root; 20 22 21 - #ifdef CONFIG_PCI 22 - extern int pcic_present(void); 23 - #endif 24 - 25 - static void __init fill_sbus_device(int prom_node, struct sbus_dev *sdev) 23 + static void __init fill_sbus_device(struct device_node *dp, struct sbus_dev *sdev) 26 24 { 27 - unsigned long address, base; 25 + unsigned long base; 26 + void *pval; 28 27 int len; 29 28 30 - sdev->prom_node = prom_node; 31 - prom_getstring(prom_node, "name", 32 - sdev->prom_name, sizeof(sdev->prom_name)); 33 - address = prom_getint(prom_node, "address"); 34 - len = prom_getproperty(prom_node, "reg", 35 - (char *) sdev->reg_addrs, 36 - sizeof(sdev->reg_addrs)); 29 + sdev->prom_node = dp->node; 30 + strcpy(sdev->prom_name, dp->name); 31 + 32 + pval = of_get_property(dp, "reg", &len); 37 33 sdev->num_registers = 0; 38 - if (len != -1) { 34 + if (pval) { 35 + memcpy(sdev->reg_addrs, pval, len); 36 + 39 37 sdev->num_registers = 40 38 len / sizeof(struct linux_prom_registers); 41 - sdev->ranges_applied = 0; 42 39 43 40 base = (unsigned long) sdev->reg_addrs[0].phys_addr; 44 41 ··· 46 49 sdev->slot = sdev->reg_addrs[0].which_io; 47 50 } 48 51 49 - len = prom_getproperty(prom_node, "ranges", 50 - (char *)sdev->device_ranges, 51 - sizeof(sdev->device_ranges)); 52 + pval = of_get_property(dp, "ranges", &len); 52 53 sdev->num_device_ranges = 0; 53 - if (len != -1) 54 + if (pval) { 55 + memcpy(sdev->device_ranges, pval, len); 54 56 sdev->num_device_ranges = 55 57 len / sizeof(struct linux_prom_ranges); 58 + } 56 59 57 60 sbus_fill_device_irq(sdev); 61 + 62 + sdev->ofdev.node = dp; 63 + if (sdev->parent) 64 + sdev->ofdev.dev.parent = &sdev->parent->ofdev.dev; 65 + else 66 + sdev->ofdev.dev.parent = &sdev->bus->ofdev.dev; 67 + sdev->ofdev.dev.bus = &sbus_bus_type; 68 + strcpy(sdev->ofdev.dev.bus_id, dp->path_component_name); 69 + 70 + if (of_device_register(&sdev->ofdev) != 0) 71 + printk(KERN_DEBUG "sbus: device registration error for %s!\n", 72 + sdev->ofdev.dev.bus_id); 58 73 } 59 74 60 - /* This routine gets called from whoever needs the sbus first, to scan 61 - * the SBus device tree. Currently it just prints out the devices 62 - * found on the bus and builds trees of SBUS structs and attached 63 - * devices. 64 - */ 65 - 66 - extern void iommu_init(int iommu_node, struct sbus_bus *sbus); 67 - extern void iounit_init(int sbi_node, int iounit_node, struct sbus_bus *sbus); 68 - void sun4_init(void); 69 - #ifdef CONFIG_SUN_AUXIO 70 - extern void auxio_probe(void); 71 - #endif 72 - 73 - static void __init sbus_do_child_siblings(int start_node, 74 - struct sbus_dev *child, 75 - struct sbus_dev *parent, 76 - struct sbus_bus *sbus) 75 + static void __init sbus_bus_ranges_init(struct device_node *dp, struct sbus_bus *sbus) 77 76 { 78 - struct sbus_dev *this_dev = child; 79 - int this_node = start_node; 80 - 81 - /* Child already filled in, just need to traverse siblings. */ 82 - child->child = NULL; 83 - child->parent = parent; 84 - while((this_node = prom_getsibling(this_node)) != 0) { 85 - this_dev->next = kmalloc(sizeof(struct sbus_dev), GFP_ATOMIC); 86 - this_dev = this_dev->next; 87 - this_dev->next = NULL; 88 - this_dev->parent = parent; 89 - 90 - this_dev->bus = sbus; 91 - fill_sbus_device(this_node, this_dev); 92 - 93 - if(prom_getchild(this_node)) { 94 - this_dev->child = kmalloc(sizeof(struct sbus_dev), 95 - GFP_ATOMIC); 96 - this_dev->child->bus = sbus; 97 - this_dev->child->next = NULL; 98 - fill_sbus_device(prom_getchild(this_node), this_dev->child); 99 - sbus_do_child_siblings(prom_getchild(this_node), 100 - this_dev->child, this_dev, sbus); 101 - } else { 102 - this_dev->child = NULL; 103 - } 104 - } 105 - } 106 - 107 - /* 108 - * XXX This functions appears to be a distorted version of 109 - * prom_sbus_ranges_init(), with all sun4d stuff cut away. 110 - * Ask DaveM what is going on here, how is sun4d supposed to work... XXX 111 - */ 112 - /* added back sun4d patch from Thomas Bogendoerfer - should be OK (crn) */ 113 - 114 - static void __init sbus_bus_ranges_init(int parent_node, struct sbus_bus *sbus) 115 - { 77 + void *pval; 116 78 int len; 117 79 118 - len = prom_getproperty(sbus->prom_node, "ranges", 119 - (char *) sbus->sbus_ranges, 120 - sizeof(sbus->sbus_ranges)); 121 - if (len == -1 || len == 0) { 122 - sbus->num_sbus_ranges = 0; 123 - return; 124 - } 125 - sbus->num_sbus_ranges = len / sizeof(struct linux_prom_ranges); 126 - #ifdef CONFIG_SPARC32 127 - if (sparc_cpu_model == sun4d) { 128 - struct linux_prom_ranges iounit_ranges[PROMREG_MAX]; 129 - int num_iounit_ranges; 80 + pval = of_get_property(dp, "ranges", &len); 81 + sbus->num_sbus_ranges = 0; 82 + if (pval) { 83 + memcpy(sbus->sbus_ranges, pval, len); 84 + sbus->num_sbus_ranges = 85 + len / sizeof(struct linux_prom_ranges); 130 86 131 - len = prom_getproperty(parent_node, "ranges", 132 - (char *) iounit_ranges, 133 - sizeof (iounit_ranges)); 134 - if (len != -1) { 135 - num_iounit_ranges = (len/sizeof(struct linux_prom_ranges)); 136 - prom_adjust_ranges (sbus->sbus_ranges, sbus->num_sbus_ranges, iounit_ranges, num_iounit_ranges); 137 - } 87 + sbus_arch_bus_ranges_init(dp->parent, sbus); 138 88 } 139 - #endif 140 89 } 141 90 142 91 static void __init __apply_ranges_to_regs(struct linux_prom_ranges *ranges, ··· 160 217 } 161 218 } 162 219 163 - extern void register_proc_sparc_ioport(void); 164 - extern void firetruck_init(void); 220 + /* We preserve the "probe order" of these bus and device lists to give 221 + * the same ordering as the old code. 222 + */ 223 + static void __init sbus_insert(struct sbus_bus *sbus, struct sbus_bus **root) 224 + { 225 + while (*root) 226 + root = &(*root)->next; 227 + *root = sbus; 228 + sbus->next = NULL; 229 + } 165 230 166 - #ifdef CONFIG_SUN4 167 - extern void sun4_dvma_init(void); 168 - #endif 231 + static void __init sdev_insert(struct sbus_dev *sdev, struct sbus_dev **root) 232 + { 233 + while (*root) 234 + root = &(*root)->next; 235 + *root = sdev; 236 + sdev->next = NULL; 237 + } 238 + 239 + static void __init walk_children(struct device_node *dp, struct sbus_dev *parent, struct sbus_bus *sbus) 240 + { 241 + dp = dp->child; 242 + while (dp) { 243 + struct sbus_dev *sdev; 244 + 245 + sdev = kzalloc(sizeof(struct sbus_dev), GFP_ATOMIC); 246 + if (sdev) { 247 + sdev_insert(sdev, &parent->child); 248 + 249 + sdev->bus = sbus; 250 + sdev->parent = parent; 251 + 252 + fill_sbus_device(dp, sdev); 253 + 254 + walk_children(dp, sdev, sbus); 255 + } 256 + dp = dp->sibling; 257 + } 258 + } 259 + 260 + static void __init build_one_sbus(struct device_node *dp, int num_sbus) 261 + { 262 + struct sbus_bus *sbus; 263 + unsigned int sbus_clock; 264 + struct device_node *dev_dp; 265 + 266 + sbus = kzalloc(sizeof(struct sbus_bus), GFP_ATOMIC); 267 + if (!sbus) 268 + return; 269 + 270 + sbus_insert(sbus, &sbus_root); 271 + sbus->prom_node = dp->node; 272 + 273 + sbus_setup_iommu(sbus, dp); 274 + 275 + printk("sbus%d: ", num_sbus); 276 + 277 + sbus_clock = of_getintprop_default(dp, "clock-frequency", 278 + (25*1000*1000)); 279 + sbus->clock_freq = sbus_clock; 280 + 281 + printk("Clock %d.%d MHz\n", (int) ((sbus_clock/1000)/1000), 282 + (int) (((sbus_clock/1000)%1000 != 0) ? 283 + (((sbus_clock/1000)%1000) + 1000) : 0)); 284 + 285 + strcpy(sbus->prom_name, dp->name); 286 + 287 + sbus_setup_arch_props(sbus, dp); 288 + 289 + sbus_bus_ranges_init(dp, sbus); 290 + 291 + sbus->ofdev.node = dp; 292 + sbus->ofdev.dev.parent = NULL; 293 + sbus->ofdev.dev.bus = &sbus_bus_type; 294 + strcpy(sbus->ofdev.dev.bus_id, dp->path_component_name); 295 + 296 + if (of_device_register(&sbus->ofdev) != 0) 297 + printk(KERN_DEBUG "sbus: device registration error for %s!\n", 298 + sbus->ofdev.dev.bus_id); 299 + 300 + dev_dp = dp->child; 301 + while (dev_dp) { 302 + struct sbus_dev *sdev; 303 + 304 + sdev = kzalloc(sizeof(struct sbus_dev), GFP_ATOMIC); 305 + if (sdev) { 306 + sdev_insert(sdev, &sbus->devices); 307 + 308 + sdev->bus = sbus; 309 + sdev->parent = NULL; 310 + fill_sbus_device(dev_dp, sdev); 311 + 312 + walk_children(dev_dp, sdev, sbus); 313 + } 314 + dev_dp = dev_dp->sibling; 315 + } 316 + 317 + sbus_fixup_all_regs(sbus->devices); 318 + 319 + dvma_init(sbus); 320 + } 169 321 170 322 static int __init sbus_init(void) 171 323 { 172 - int nd, this_sbus, sbus_devs, topnd, iommund; 173 - unsigned int sbus_clock; 174 - struct sbus_bus *sbus; 175 - struct sbus_dev *this_dev; 176 - int num_sbus = 0; /* How many did we find? */ 324 + struct device_node *dp; 325 + const char *sbus_name = "sbus"; 326 + int num_sbus = 0; 177 327 178 - #ifdef CONFIG_SPARC32 179 - register_proc_sparc_ioport(); 180 - #endif 328 + if (sbus_arch_preinit()) 329 + return 0; 181 330 182 - #ifdef CONFIG_SUN4 183 - sun4_dvma_init(); 184 - return 0; 185 - #endif 331 + if (sparc_cpu_model == sun4d) 332 + sbus_name = "sbi"; 186 333 187 - topnd = prom_getchild(prom_root_node); 188 - 189 - /* Finding the first sbus is a special case... */ 190 - iommund = 0; 191 - if(sparc_cpu_model == sun4u) { 192 - nd = prom_searchsiblings(topnd, "sbus"); 193 - if(nd == 0) { 194 - #ifdef CONFIG_PCI 195 - if (!pcic_present()) { 196 - prom_printf("Neither SBUS nor PCI found.\n"); 197 - prom_halt(); 198 - } else { 199 - #ifdef CONFIG_SPARC64 200 - firetruck_init(); 201 - #endif 202 - } 203 - return 0; 204 - #else 205 - prom_printf("YEEE, UltraSparc sbus not found\n"); 206 - prom_halt(); 207 - #endif 208 - } 209 - } else if(sparc_cpu_model == sun4d) { 210 - if((iommund = prom_searchsiblings(topnd, "io-unit")) == 0 || 211 - (nd = prom_getchild(iommund)) == 0 || 212 - (nd = prom_searchsiblings(nd, "sbi")) == 0) { 213 - panic("sbi not found"); 214 - } 215 - } else if((nd = prom_searchsiblings(topnd, "sbus")) == 0) { 216 - if((iommund = prom_searchsiblings(topnd, "iommu")) == 0 || 217 - (nd = prom_getchild(iommund)) == 0 || 218 - (nd = prom_searchsiblings(nd, "sbus")) == 0) { 219 - #ifdef CONFIG_PCI 220 - if (!pcic_present()) { 221 - prom_printf("Neither SBUS nor PCI found.\n"); 222 - prom_halt(); 223 - } 224 - return 0; 225 - #else 226 - /* No reason to run further - the data access trap will occur. */ 227 - panic("sbus not found"); 228 - #endif 229 - } 230 - } 231 - 232 - /* Ok, we've found the first one, allocate first SBus struct 233 - * and place in chain. 234 - */ 235 - sbus = sbus_root = kmalloc(sizeof(struct sbus_bus), GFP_ATOMIC); 236 - sbus->next = NULL; 237 - sbus->prom_node = nd; 238 - this_sbus = nd; 239 - 240 - if(iommund && sparc_cpu_model != sun4u && sparc_cpu_model != sun4d) 241 - iommu_init(iommund, sbus); 242 - 243 - /* Loop until we find no more SBUS's */ 244 - while(this_sbus) { 245 - #ifdef CONFIG_SPARC64 246 - /* IOMMU hides inside SBUS/SYSIO prom node on Ultra. */ 247 - if(sparc_cpu_model == sun4u) { 248 - extern void sbus_iommu_init(int prom_node, struct sbus_bus *sbus); 249 - 250 - sbus_iommu_init(this_sbus, sbus); 251 - } 252 - #endif /* CONFIG_SPARC64 */ 253 - 254 - #ifdef CONFIG_SPARC32 255 - if (sparc_cpu_model == sun4d) 256 - iounit_init(this_sbus, iommund, sbus); 257 - #endif /* CONFIG_SPARC32 */ 258 - printk("sbus%d: ", num_sbus); 259 - sbus_clock = prom_getint(this_sbus, "clock-frequency"); 260 - if(sbus_clock == -1) 261 - sbus_clock = (25*1000*1000); 262 - printk("Clock %d.%d MHz\n", (int) ((sbus_clock/1000)/1000), 263 - (int) (((sbus_clock/1000)%1000 != 0) ? 264 - (((sbus_clock/1000)%1000) + 1000) : 0)); 265 - 266 - prom_getstring(this_sbus, "name", 267 - sbus->prom_name, sizeof(sbus->prom_name)); 268 - sbus->clock_freq = sbus_clock; 269 - #ifdef CONFIG_SPARC32 270 - if (sparc_cpu_model == sun4d) { 271 - sbus->devid = prom_getint(iommund, "device-id"); 272 - sbus->board = prom_getint(iommund, "board#"); 273 - } 274 - #endif 275 - 276 - sbus_bus_ranges_init(iommund, sbus); 277 - 278 - sbus_devs = prom_getchild(this_sbus); 279 - if (!sbus_devs) { 280 - sbus->devices = NULL; 281 - goto next_bus; 282 - } 283 - 284 - sbus->devices = kmalloc(sizeof(struct sbus_dev), GFP_ATOMIC); 285 - 286 - this_dev = sbus->devices; 287 - this_dev->next = NULL; 288 - 289 - this_dev->bus = sbus; 290 - this_dev->parent = NULL; 291 - fill_sbus_device(sbus_devs, this_dev); 292 - 293 - /* Should we traverse for children? */ 294 - if(prom_getchild(sbus_devs)) { 295 - /* Allocate device node */ 296 - this_dev->child = kmalloc(sizeof(struct sbus_dev), 297 - GFP_ATOMIC); 298 - /* Fill it */ 299 - this_dev->child->bus = sbus; 300 - this_dev->child->next = NULL; 301 - fill_sbus_device(prom_getchild(sbus_devs), 302 - this_dev->child); 303 - sbus_do_child_siblings(prom_getchild(sbus_devs), 304 - this_dev->child, 305 - this_dev, 306 - sbus); 307 - } else { 308 - this_dev->child = NULL; 309 - } 310 - 311 - while((sbus_devs = prom_getsibling(sbus_devs)) != 0) { 312 - /* Allocate device node */ 313 - this_dev->next = kmalloc(sizeof(struct sbus_dev), 314 - GFP_ATOMIC); 315 - this_dev = this_dev->next; 316 - this_dev->next = NULL; 317 - 318 - /* Fill it */ 319 - this_dev->bus = sbus; 320 - this_dev->parent = NULL; 321 - fill_sbus_device(sbus_devs, this_dev); 322 - 323 - /* Is there a child node hanging off of us? */ 324 - if(prom_getchild(sbus_devs)) { 325 - /* Get new device struct */ 326 - this_dev->child = kmalloc(sizeof(struct sbus_dev), 327 - GFP_ATOMIC); 328 - /* Fill it */ 329 - this_dev->child->bus = sbus; 330 - this_dev->child->next = NULL; 331 - fill_sbus_device(prom_getchild(sbus_devs), 332 - this_dev->child); 333 - sbus_do_child_siblings(prom_getchild(sbus_devs), 334 - this_dev->child, 335 - this_dev, 336 - sbus); 337 - } else { 338 - this_dev->child = NULL; 339 - } 340 - } 341 - 342 - /* Walk all devices and apply parent ranges. */ 343 - sbus_fixup_all_regs(sbus->devices); 344 - 345 - dvma_init(sbus); 346 - next_bus: 334 + for_each_node_by_name(dp, sbus_name) { 335 + build_one_sbus(dp, num_sbus); 347 336 num_sbus++; 348 - if(sparc_cpu_model == sun4u) { 349 - this_sbus = prom_getsibling(this_sbus); 350 - if(!this_sbus) 351 - break; 352 - this_sbus = prom_searchsiblings(this_sbus, "sbus"); 353 - } else if(sparc_cpu_model == sun4d) { 354 - iommund = prom_getsibling(iommund); 355 - if(!iommund) 356 - break; 357 - iommund = prom_searchsiblings(iommund, "io-unit"); 358 - if(!iommund) 359 - break; 360 - this_sbus = prom_searchsiblings(prom_getchild(iommund), "sbi"); 361 - } else { 362 - this_sbus = prom_getsibling(this_sbus); 363 - if(!this_sbus) 364 - break; 365 - this_sbus = prom_searchsiblings(this_sbus, "sbus"); 366 - } 367 - if(this_sbus) { 368 - sbus->next = kmalloc(sizeof(struct sbus_bus), GFP_ATOMIC); 369 - sbus = sbus->next; 370 - sbus->next = NULL; 371 - sbus->prom_node = this_sbus; 372 - } else { 373 - break; 374 - } 375 - } /* while(this_sbus) */ 376 337 377 - if (sparc_cpu_model == sun4d) { 378 - extern void sun4d_init_sbi_irq(void); 379 - sun4d_init_sbi_irq(); 380 338 } 381 - 382 - #ifdef CONFIG_SPARC64 383 - if (sparc_cpu_model == sun4u) { 384 - firetruck_init(); 385 - } 386 - #endif 387 - #ifdef CONFIG_SUN_AUXIO 388 - if (sparc_cpu_model == sun4u) 389 - auxio_probe (); 390 - #endif 391 - #ifdef CONFIG_SPARC64 392 - if (sparc_cpu_model == sun4u) { 393 - extern void clock_probe(void); 394 339 395 - clock_probe(); 396 - } 397 - #endif 340 + sbus_arch_postinit(); 398 341 399 342 return 0; 400 343 }
+19 -8
include/asm-sparc/sbus.h
··· 11 11 #include <linux/ioport.h> 12 12 13 13 #include <asm/oplib.h> 14 - /* #include <asm/iommu.h> */ /* Unused since we use opaque iommu (|io-unit) */ 14 + #include <asm/prom.h> 15 + #include <asm/of_device.h> 15 16 #include <asm/scatterlist.h> 16 17 17 18 /* We scan which devices are on the SBus using the PROM node device ··· 43 42 44 43 /* Linux SBUS device tables */ 45 44 struct sbus_dev { 46 - struct sbus_bus *bus; /* Back ptr to sbus */ 47 - struct sbus_dev *next; /* next device on this SBus or null */ 48 - struct sbus_dev *child; /* For ledma and espdma on sun4m */ 49 - struct sbus_dev *parent; /* Parent device if not toplevel */ 50 - int prom_node; /* PROM device tree node for this device */ 51 - char prom_name[64]; /* PROM device name */ 45 + struct of_device ofdev; 46 + struct sbus_bus *bus; 47 + struct sbus_dev *next; 48 + struct sbus_dev *child; 49 + struct sbus_dev *parent; 50 + int prom_node; 51 + char prom_name[64]; 52 52 int slot; 53 53 54 54 struct resource resource[PROMREG_MAX]; 55 55 56 56 struct linux_prom_registers reg_addrs[PROMREG_MAX]; 57 - int num_registers, ranges_applied; 57 + int num_registers; 58 58 59 59 struct linux_prom_ranges device_ranges[PROMREG_MAX]; 60 60 int num_device_ranges; ··· 63 61 unsigned int irqs[4]; 64 62 int num_irqs; 65 63 }; 64 + #define to_sbus_device(d) container_of(d, struct sbus_dev, ofdev.dev) 66 65 67 66 /* This struct describes the SBus(s) found on this machine. */ 68 67 struct sbus_bus { 68 + struct of_device ofdev; 69 69 void *iommu; /* Opaque IOMMU cookie */ 70 70 struct sbus_dev *devices; /* Link to devices on this SBus */ 71 71 struct sbus_bus *next; /* next SBus, if more than one SBus */ ··· 81 77 int devid; 82 78 int board; 83 79 }; 80 + #define to_sbus(d) container_of(d, struct sbus_bus, ofdev.dev) 84 81 85 82 extern struct sbus_bus *sbus_root; 86 83 ··· 144 139 */ 145 140 BTFIXUPDEF_CALL(unsigned int, sbint_to_irq, struct sbus_dev *sdev, unsigned int) 146 141 #define sbint_to_irq(sdev, sbint) BTFIXUP_CALL(sbint_to_irq)(sdev, sbint) 142 + 143 + extern void sbus_arch_bus_ranges_init(struct device_node *, struct sbus_bus *); 144 + extern void sbus_setup_iommu(struct sbus_bus *, struct device_node *); 145 + extern void sbus_setup_arch_props(struct sbus_bus *, struct device_node *); 146 + extern int sbus_arch_preinit(void); 147 + extern void sbus_arch_postinit(void); 147 148 148 149 #endif /* !(_SPARC_SBUS_H) */
+20 -8
include/asm-sparc64/sbus.h
··· 11 11 #include <linux/ioport.h> 12 12 13 13 #include <asm/oplib.h> 14 + #include <asm/prom.h> 15 + #include <asm/of_device.h> 14 16 #include <asm/iommu.h> 15 17 #include <asm/scatterlist.h> 16 18 ··· 44 42 45 43 /* Linux SBUS device tables */ 46 44 struct sbus_dev { 47 - struct sbus_bus *bus; /* Our toplevel parent SBUS */ 48 - struct sbus_dev *next; /* Chain of siblings */ 49 - struct sbus_dev *child; /* Chain of children */ 50 - struct sbus_dev *parent;/* Parent device if not toplevel*/ 51 - int prom_node; /* OBP node of this device */ 52 - char prom_name[64]; /* OBP device name property */ 53 - int slot; /* SBUS slot number */ 45 + struct of_device ofdev; 46 + struct sbus_bus *bus; 47 + struct sbus_dev *next; 48 + struct sbus_dev *child; 49 + struct sbus_dev *parent; 50 + int prom_node; 51 + char prom_name[64]; 52 + int slot; 54 53 55 54 struct resource resource[PROMREG_MAX]; 56 55 57 56 struct linux_prom_registers reg_addrs[PROMREG_MAX]; 58 - int num_registers, ranges_applied; 57 + int num_registers; 59 58 60 59 struct linux_prom_ranges device_ranges[PROMREG_MAX]; 61 60 int num_device_ranges; ··· 64 61 unsigned int irqs[4]; 65 62 int num_irqs; 66 63 }; 64 + #define to_sbus_device(d) container_of(d, struct sbus_dev, ofdev.dev) 67 65 68 66 /* This struct describes the SBus(s) found on this machine. */ 69 67 struct sbus_bus { 68 + struct of_device ofdev; 70 69 void *iommu; /* Opaque IOMMU cookie */ 71 70 struct sbus_dev *devices; /* Tree of SBUS devices */ 72 71 struct sbus_bus *next; /* Next SBUS in system */ ··· 82 77 int portid; 83 78 void *starfire_cookie; 84 79 }; 80 + #define to_sbus(d) container_of(d, struct sbus_bus, ofdev.dev) 85 81 86 82 extern struct sbus_bus *sbus_root; 87 83 ··· 125 119 extern void sbus_dma_sync_sg_for_cpu(struct sbus_dev *, struct scatterlist *, int, int); 126 120 #define sbus_dma_sync_sg sbus_dma_sync_sg_for_cpu 127 121 extern void sbus_dma_sync_sg_for_device(struct sbus_dev *, struct scatterlist *, int, int); 122 + 123 + extern void sbus_arch_bus_ranges_init(struct device_node *, struct sbus_bus *); 124 + extern void sbus_setup_iommu(struct sbus_bus *, struct device_node *); 125 + extern void sbus_setup_arch_props(struct sbus_bus *, struct device_node *); 126 + extern int sbus_arch_preinit(void); 127 + extern void sbus_arch_postinit(void); 128 128 129 129 #endif /* !(_SPARC64_SBUS_H) */