Commit 576c352e89e57cfa6c9f493e549d10d86f60a0cf

Authored by David S. Miller
Committed by David S. Miller
1 parent fd53143116

[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>

Showing 5 changed files with 293 additions and 327 deletions Side-by-side Diff

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