1 /* sbus.c: SBus support routines.
3 * Copyright (C) 1995, 2006 David S. Miller (davem@davemloft.net)
6 #include <linux/kernel.h>
7 #include <linux/slab.h>
8 #include <linux/init.h>
9 #include <linux/device.h>
11 #include <asm/system.h>
14 #include <asm/oplib.h>
16 #include <asm/of_device.h>
21 show_sbusobppath_attr(struct device
* dev
, struct device_attribute
* attr
, char * buf
)
23 struct sbus_dev
*sbus
;
25 sbus
= to_sbus_device(dev
);
27 return snprintf (buf
, PAGE_SIZE
, "%s\n", sbus
->ofdev
.node
->full_name
);
30 static DEVICE_ATTR(obppath
, S_IRUSR
| S_IRGRP
| S_IROTH
, show_sbusobppath_attr
, NULL
);
32 struct sbus_bus
*sbus_root
;
34 static void __init
fill_sbus_device(struct device_node
*dp
, struct sbus_dev
*sdev
)
40 sdev
->prom_node
= dp
->node
;
41 strcpy(sdev
->prom_name
, dp
->name
);
43 pval
= of_get_property(dp
, "reg", &len
);
44 sdev
->num_registers
= 0;
46 memcpy(sdev
->reg_addrs
, pval
, len
);
49 len
/ sizeof(struct linux_prom_registers
);
51 base
= (unsigned long) sdev
->reg_addrs
[0].phys_addr
;
53 /* Compute the slot number. */
54 if (base
>= SUN_SBUS_BVADDR
&& sparc_cpu_model
== sun4m
)
55 sdev
->slot
= sbus_dev_slot(base
);
57 sdev
->slot
= sdev
->reg_addrs
[0].which_io
;
60 pval
= of_get_property(dp
, "ranges", &len
);
61 sdev
->num_device_ranges
= 0;
63 memcpy(sdev
->device_ranges
, pval
, len
);
64 sdev
->num_device_ranges
=
65 len
/ sizeof(struct linux_prom_ranges
);
68 sbus_fill_device_irq(sdev
);
70 sdev
->ofdev
.node
= dp
;
72 sdev
->ofdev
.dev
.parent
= &sdev
->parent
->ofdev
.dev
;
74 sdev
->ofdev
.dev
.parent
= &sdev
->bus
->ofdev
.dev
;
75 sdev
->ofdev
.dev
.bus
= &sbus_bus_type
;
76 sprintf(sdev
->ofdev
.dev
.bus_id
, "sbus[%08x]", dp
->node
);
78 if (of_device_register(&sdev
->ofdev
) != 0)
79 printk(KERN_DEBUG
"sbus: device registration error for %s!\n",
80 dp
->path_component_name
);
82 /* WE HAVE BEEN INVADED BY ALIENS! */
83 err
= sysfs_create_file(&sdev
->ofdev
.dev
.kobj
, &dev_attr_obppath
.attr
);
86 static void __init
sbus_bus_ranges_init(struct device_node
*dp
, struct sbus_bus
*sbus
)
91 pval
= of_get_property(dp
, "ranges", &len
);
92 sbus
->num_sbus_ranges
= 0;
94 memcpy(sbus
->sbus_ranges
, pval
, len
);
95 sbus
->num_sbus_ranges
=
96 len
/ sizeof(struct linux_prom_ranges
);
98 sbus_arch_bus_ranges_init(dp
->parent
, sbus
);
102 static void __init
__apply_ranges_to_regs(struct linux_prom_ranges
*ranges
,
104 struct linux_prom_registers
*regs
,
110 for (regnum
= 0; regnum
< num_regs
; regnum
++) {
113 for (rngnum
= 0; rngnum
< num_ranges
; rngnum
++) {
114 if (regs
[regnum
].which_io
== ranges
[rngnum
].ot_child_space
)
117 if (rngnum
== num_ranges
) {
118 /* We used to flag this as an error. Actually
119 * some devices do not report the regs as we expect.
120 * For example, see SUNW,pln device. In that case
121 * the reg property is in a format internal to that
122 * node, ie. it is not in the SBUS register space
127 regs
[regnum
].which_io
= ranges
[rngnum
].ot_parent_space
;
128 regs
[regnum
].phys_addr
-= ranges
[rngnum
].ot_child_base
;
129 regs
[regnum
].phys_addr
+= ranges
[rngnum
].ot_parent_base
;
134 static void __init
__fixup_regs_sdev(struct sbus_dev
*sdev
)
136 if (sdev
->num_registers
!= 0) {
137 struct sbus_dev
*parent
= sdev
->parent
;
140 while (parent
!= NULL
) {
141 __apply_ranges_to_regs(parent
->device_ranges
,
142 parent
->num_device_ranges
,
144 sdev
->num_registers
);
146 parent
= parent
->parent
;
149 __apply_ranges_to_regs(sdev
->bus
->sbus_ranges
,
150 sdev
->bus
->num_sbus_ranges
,
152 sdev
->num_registers
);
154 for (i
= 0; i
< sdev
->num_registers
; i
++) {
155 struct resource
*res
= &sdev
->resource
[i
];
157 res
->start
= sdev
->reg_addrs
[i
].phys_addr
;
158 res
->end
= (res
->start
+
159 (unsigned long)sdev
->reg_addrs
[i
].reg_size
- 1UL);
160 res
->flags
= IORESOURCE_IO
|
161 (sdev
->reg_addrs
[i
].which_io
& 0xff);
166 static void __init
sbus_fixup_all_regs(struct sbus_dev
*first_sdev
)
168 struct sbus_dev
*sdev
;
170 for (sdev
= first_sdev
; sdev
; sdev
= sdev
->next
) {
172 sbus_fixup_all_regs(sdev
->child
);
173 __fixup_regs_sdev(sdev
);
177 /* We preserve the "probe order" of these bus and device lists to give
178 * the same ordering as the old code.
180 static void __init
sbus_insert(struct sbus_bus
*sbus
, struct sbus_bus
**root
)
183 root
= &(*root
)->next
;
188 static void __init
sdev_insert(struct sbus_dev
*sdev
, struct sbus_dev
**root
)
191 root
= &(*root
)->next
;
196 static void __init
walk_children(struct device_node
*dp
, struct sbus_dev
*parent
, struct sbus_bus
*sbus
)
200 struct sbus_dev
*sdev
;
202 sdev
= kzalloc(sizeof(struct sbus_dev
), GFP_ATOMIC
);
204 sdev_insert(sdev
, &parent
->child
);
207 sdev
->parent
= parent
;
209 fill_sbus_device(dp
, sdev
);
211 walk_children(dp
, sdev
, sbus
);
217 static void __init
build_one_sbus(struct device_node
*dp
, int num_sbus
)
219 struct sbus_bus
*sbus
;
220 unsigned int sbus_clock
;
221 struct device_node
*dev_dp
;
223 sbus
= kzalloc(sizeof(struct sbus_bus
), GFP_ATOMIC
);
227 sbus_insert(sbus
, &sbus_root
);
228 sbus
->prom_node
= dp
->node
;
230 sbus_setup_iommu(sbus
, dp
);
232 printk("sbus%d: ", num_sbus
);
234 sbus_clock
= of_getintprop_default(dp
, "clock-frequency",
236 sbus
->clock_freq
= sbus_clock
;
238 printk("Clock %d.%d MHz\n", (int) ((sbus_clock
/1000)/1000),
239 (int) (((sbus_clock
/1000)%1000 != 0) ?
240 (((sbus_clock
/1000)%1000) + 1000) : 0));
242 strcpy(sbus
->prom_name
, dp
->name
);
244 sbus_setup_arch_props(sbus
, dp
);
246 sbus_bus_ranges_init(dp
, sbus
);
248 sbus
->ofdev
.node
= dp
;
249 sbus
->ofdev
.dev
.parent
= NULL
;
250 sbus
->ofdev
.dev
.bus
= &sbus_bus_type
;
251 sprintf(sbus
->ofdev
.dev
.bus_id
, "sbus%d", num_sbus
);
253 if (of_device_register(&sbus
->ofdev
) != 0)
254 printk(KERN_DEBUG
"sbus: device registration error for %s!\n",
255 sbus
->ofdev
.dev
.bus_id
);
259 struct sbus_dev
*sdev
;
261 sdev
= kzalloc(sizeof(struct sbus_dev
), GFP_ATOMIC
);
263 sdev_insert(sdev
, &sbus
->devices
);
267 fill_sbus_device(dev_dp
, sdev
);
269 walk_children(dev_dp
, sdev
, sbus
);
271 dev_dp
= dev_dp
->sibling
;
274 sbus_fixup_all_regs(sbus
->devices
);
279 static int __init
sbus_init(void)
281 struct device_node
*dp
;
282 const char *sbus_name
= "sbus";
285 if (sbus_arch_preinit())
288 if (sparc_cpu_model
== sun4d
)
291 for_each_node_by_name(dp
, sbus_name
) {
292 build_one_sbus(dp
, num_sbus
);
297 sbus_arch_postinit();
302 subsys_initcall(sbus_init
);