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>
11 #include <asm/system.h>
14 #include <asm/oplib.h>
16 #include <asm/of_device.h>
20 struct sbus_bus
*sbus_root
;
22 static void __init
fill_sbus_device(struct device_node
*dp
, struct sbus_dev
*sdev
)
28 sdev
->prom_node
= dp
->node
;
29 strcpy(sdev
->prom_name
, dp
->name
);
31 pval
= of_get_property(dp
, "reg", &len
);
32 sdev
->num_registers
= 0;
34 memcpy(sdev
->reg_addrs
, pval
, len
);
37 len
/ sizeof(struct linux_prom_registers
);
39 base
= (unsigned long) sdev
->reg_addrs
[0].phys_addr
;
41 /* Compute the slot number. */
42 if (base
>= SUN_SBUS_BVADDR
&& sparc_cpu_model
== sun4m
)
43 sdev
->slot
= sbus_dev_slot(base
);
45 sdev
->slot
= sdev
->reg_addrs
[0].which_io
;
48 pval
= of_get_property(dp
, "ranges", &len
);
49 sdev
->num_device_ranges
= 0;
51 memcpy(sdev
->device_ranges
, pval
, len
);
52 sdev
->num_device_ranges
=
53 len
/ sizeof(struct linux_prom_ranges
);
56 sbus_fill_device_irq(sdev
);
58 sdev
->ofdev
.node
= dp
;
60 sdev
->ofdev
.dev
.parent
= &sdev
->parent
->ofdev
.dev
;
62 sdev
->ofdev
.dev
.parent
= &sdev
->bus
->ofdev
.dev
;
63 sdev
->ofdev
.dev
.bus
= &sbus_bus_type
;
64 sprintf(sdev
->ofdev
.dev
.bus_id
, "sbus[%08x]", dp
->node
);
66 if (of_device_register(&sdev
->ofdev
) != 0)
67 printk(KERN_DEBUG
"sbus: device registration error for %s!\n",
68 dp
->path_component_name
);
71 static void __init
sbus_bus_ranges_init(struct device_node
*dp
, struct sbus_bus
*sbus
)
76 pval
= of_get_property(dp
, "ranges", &len
);
77 sbus
->num_sbus_ranges
= 0;
79 memcpy(sbus
->sbus_ranges
, pval
, len
);
80 sbus
->num_sbus_ranges
=
81 len
/ sizeof(struct linux_prom_ranges
);
83 sbus_arch_bus_ranges_init(dp
->parent
, sbus
);
87 static void __init
__apply_ranges_to_regs(struct linux_prom_ranges
*ranges
,
89 struct linux_prom_registers
*regs
,
95 for (regnum
= 0; regnum
< num_regs
; regnum
++) {
98 for (rngnum
= 0; rngnum
< num_ranges
; rngnum
++) {
99 if (regs
[regnum
].which_io
== ranges
[rngnum
].ot_child_space
)
102 if (rngnum
== num_ranges
) {
103 /* We used to flag this as an error. Actually
104 * some devices do not report the regs as we expect.
105 * For example, see SUNW,pln device. In that case
106 * the reg property is in a format internal to that
107 * node, ie. it is not in the SBUS register space
112 regs
[regnum
].which_io
= ranges
[rngnum
].ot_parent_space
;
113 regs
[regnum
].phys_addr
-= ranges
[rngnum
].ot_child_base
;
114 regs
[regnum
].phys_addr
+= ranges
[rngnum
].ot_parent_base
;
119 static void __init
__fixup_regs_sdev(struct sbus_dev
*sdev
)
121 if (sdev
->num_registers
!= 0) {
122 struct sbus_dev
*parent
= sdev
->parent
;
125 while (parent
!= NULL
) {
126 __apply_ranges_to_regs(parent
->device_ranges
,
127 parent
->num_device_ranges
,
129 sdev
->num_registers
);
131 parent
= parent
->parent
;
134 __apply_ranges_to_regs(sdev
->bus
->sbus_ranges
,
135 sdev
->bus
->num_sbus_ranges
,
137 sdev
->num_registers
);
139 for (i
= 0; i
< sdev
->num_registers
; i
++) {
140 struct resource
*res
= &sdev
->resource
[i
];
142 res
->start
= sdev
->reg_addrs
[i
].phys_addr
;
143 res
->end
= (res
->start
+
144 (unsigned long)sdev
->reg_addrs
[i
].reg_size
- 1UL);
145 res
->flags
= IORESOURCE_IO
|
146 (sdev
->reg_addrs
[i
].which_io
& 0xff);
151 static void __init
sbus_fixup_all_regs(struct sbus_dev
*first_sdev
)
153 struct sbus_dev
*sdev
;
155 for (sdev
= first_sdev
; sdev
; sdev
= sdev
->next
) {
157 sbus_fixup_all_regs(sdev
->child
);
158 __fixup_regs_sdev(sdev
);
162 /* We preserve the "probe order" of these bus and device lists to give
163 * the same ordering as the old code.
165 static void __init
sbus_insert(struct sbus_bus
*sbus
, struct sbus_bus
**root
)
168 root
= &(*root
)->next
;
173 static void __init
sdev_insert(struct sbus_dev
*sdev
, struct sbus_dev
**root
)
176 root
= &(*root
)->next
;
181 static void __init
walk_children(struct device_node
*dp
, struct sbus_dev
*parent
, struct sbus_bus
*sbus
)
185 struct sbus_dev
*sdev
;
187 sdev
= kzalloc(sizeof(struct sbus_dev
), GFP_ATOMIC
);
189 sdev_insert(sdev
, &parent
->child
);
192 sdev
->parent
= parent
;
194 fill_sbus_device(dp
, sdev
);
196 walk_children(dp
, sdev
, sbus
);
202 static void __init
build_one_sbus(struct device_node
*dp
, int num_sbus
)
204 struct sbus_bus
*sbus
;
205 unsigned int sbus_clock
;
206 struct device_node
*dev_dp
;
208 sbus
= kzalloc(sizeof(struct sbus_bus
), GFP_ATOMIC
);
212 sbus_insert(sbus
, &sbus_root
);
213 sbus
->prom_node
= dp
->node
;
215 sbus_setup_iommu(sbus
, dp
);
217 printk("sbus%d: ", num_sbus
);
219 sbus_clock
= of_getintprop_default(dp
, "clock-frequency",
221 sbus
->clock_freq
= sbus_clock
;
223 printk("Clock %d.%d MHz\n", (int) ((sbus_clock
/1000)/1000),
224 (int) (((sbus_clock
/1000)%1000 != 0) ?
225 (((sbus_clock
/1000)%1000) + 1000) : 0));
227 strcpy(sbus
->prom_name
, dp
->name
);
229 sbus_setup_arch_props(sbus
, dp
);
231 sbus_bus_ranges_init(dp
, sbus
);
233 sbus
->ofdev
.node
= dp
;
234 sbus
->ofdev
.dev
.parent
= NULL
;
235 sbus
->ofdev
.dev
.bus
= &sbus_bus_type
;
236 sprintf(sbus
->ofdev
.dev
.bus_id
, "sbus%d", num_sbus
);
238 if (of_device_register(&sbus
->ofdev
) != 0)
239 printk(KERN_DEBUG
"sbus: device registration error for %s!\n",
240 sbus
->ofdev
.dev
.bus_id
);
244 struct sbus_dev
*sdev
;
246 sdev
= kzalloc(sizeof(struct sbus_dev
), GFP_ATOMIC
);
248 sdev_insert(sdev
, &sbus
->devices
);
252 fill_sbus_device(dev_dp
, sdev
);
254 walk_children(dev_dp
, sdev
, sbus
);
256 dev_dp
= dev_dp
->sibling
;
259 sbus_fixup_all_regs(sbus
->devices
);
264 static int __init
sbus_init(void)
266 struct device_node
*dp
;
267 const char *sbus_name
= "sbus";
270 if (sbus_arch_preinit())
273 if (sparc_cpu_model
== sun4d
)
276 for_each_node_by_name(dp
, sbus_name
) {
277 build_one_sbus(dp
, num_sbus
);
282 sbus_arch_postinit();
287 subsys_initcall(sbus_init
);
This page took 0.036552 seconds and 5 git commands to generate.