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>
10 #include <linux/device.h>
12 #include <asm/system.h>
15 #include <asm/oplib.h>
17 #include <asm/of_device.h>
22 show_sbusobppath_attr(struct device
* dev
, struct device_attribute
* attr
, char * buf
)
24 struct sbus_dev
*sbus
;
26 sbus
= to_sbus_device(dev
);
28 return snprintf (buf
, PAGE_SIZE
, "%s\n", sbus
->ofdev
.node
->full_name
);
31 static DEVICE_ATTR(obppath
, S_IRUSR
| S_IRGRP
| S_IROTH
, show_sbusobppath_attr
, NULL
);
33 struct sbus_bus
*sbus_root
;
35 static void __init
fill_sbus_device(struct device_node
*dp
, struct sbus_dev
*sdev
)
41 sdev
->prom_node
= dp
->node
;
42 strcpy(sdev
->prom_name
, dp
->name
);
44 pval
= of_get_property(dp
, "reg", &len
);
45 sdev
->num_registers
= 0;
47 memcpy(sdev
->reg_addrs
, pval
, len
);
50 len
/ sizeof(struct linux_prom_registers
);
52 base
= (unsigned long) sdev
->reg_addrs
[0].phys_addr
;
54 /* Compute the slot number. */
55 if (base
>= SUN_SBUS_BVADDR
&& sparc_cpu_model
== sun4m
)
56 sdev
->slot
= sbus_dev_slot(base
);
58 sdev
->slot
= sdev
->reg_addrs
[0].which_io
;
61 pval
= of_get_property(dp
, "ranges", &len
);
62 sdev
->num_device_ranges
= 0;
64 memcpy(sdev
->device_ranges
, pval
, len
);
65 sdev
->num_device_ranges
=
66 len
/ sizeof(struct linux_prom_ranges
);
69 sbus_fill_device_irq(sdev
);
71 sdev
->ofdev
.node
= dp
;
73 sdev
->ofdev
.dev
.parent
= &sdev
->parent
->ofdev
.dev
;
75 sdev
->ofdev
.dev
.parent
= &sdev
->bus
->ofdev
.dev
;
76 sdev
->ofdev
.dev
.bus
= &sbus_bus_type
;
77 sprintf(sdev
->ofdev
.dev
.bus_id
, "sbus[%08x]", dp
->node
);
79 if (of_device_register(&sdev
->ofdev
) != 0)
80 printk(KERN_DEBUG
"sbus: device registration error for %s!\n",
81 dp
->path_component_name
);
83 /* WE HAVE BEEN INVADED BY ALIENS! */
84 err
= sysfs_create_file(&sdev
->ofdev
.dev
.kobj
, &dev_attr_obppath
.attr
);
87 static void __init
sbus_bus_ranges_init(struct device_node
*dp
, struct sbus_bus
*sbus
)
92 pval
= of_get_property(dp
, "ranges", &len
);
93 sbus
->num_sbus_ranges
= 0;
95 memcpy(sbus
->sbus_ranges
, pval
, len
);
96 sbus
->num_sbus_ranges
=
97 len
/ sizeof(struct linux_prom_ranges
);
99 sbus_arch_bus_ranges_init(dp
->parent
, sbus
);
103 static void __init
__apply_ranges_to_regs(struct linux_prom_ranges
*ranges
,
105 struct linux_prom_registers
*regs
,
111 for (regnum
= 0; regnum
< num_regs
; regnum
++) {
114 for (rngnum
= 0; rngnum
< num_ranges
; rngnum
++) {
115 if (regs
[regnum
].which_io
== ranges
[rngnum
].ot_child_space
)
118 if (rngnum
== num_ranges
) {
119 /* We used to flag this as an error. Actually
120 * some devices do not report the regs as we expect.
121 * For example, see SUNW,pln device. In that case
122 * the reg property is in a format internal to that
123 * node, ie. it is not in the SBUS register space
128 regs
[regnum
].which_io
= ranges
[rngnum
].ot_parent_space
;
129 regs
[regnum
].phys_addr
-= ranges
[rngnum
].ot_child_base
;
130 regs
[regnum
].phys_addr
+= ranges
[rngnum
].ot_parent_base
;
135 static void __init
__fixup_regs_sdev(struct sbus_dev
*sdev
)
137 if (sdev
->num_registers
!= 0) {
138 struct sbus_dev
*parent
= sdev
->parent
;
141 while (parent
!= NULL
) {
142 __apply_ranges_to_regs(parent
->device_ranges
,
143 parent
->num_device_ranges
,
145 sdev
->num_registers
);
147 parent
= parent
->parent
;
150 __apply_ranges_to_regs(sdev
->bus
->sbus_ranges
,
151 sdev
->bus
->num_sbus_ranges
,
153 sdev
->num_registers
);
155 for (i
= 0; i
< sdev
->num_registers
; i
++) {
156 struct resource
*res
= &sdev
->resource
[i
];
158 res
->start
= sdev
->reg_addrs
[i
].phys_addr
;
159 res
->end
= (res
->start
+
160 (unsigned long)sdev
->reg_addrs
[i
].reg_size
- 1UL);
161 res
->flags
= IORESOURCE_IO
|
162 (sdev
->reg_addrs
[i
].which_io
& 0xff);
167 static void __init
sbus_fixup_all_regs(struct sbus_dev
*first_sdev
)
169 struct sbus_dev
*sdev
;
171 for (sdev
= first_sdev
; sdev
; sdev
= sdev
->next
) {
173 sbus_fixup_all_regs(sdev
->child
);
174 __fixup_regs_sdev(sdev
);
178 /* We preserve the "probe order" of these bus and device lists to give
179 * the same ordering as the old code.
181 static void __init
sbus_insert(struct sbus_bus
*sbus
, struct sbus_bus
**root
)
184 root
= &(*root
)->next
;
189 static void __init
sdev_insert(struct sbus_dev
*sdev
, struct sbus_dev
**root
)
192 root
= &(*root
)->next
;
197 static void __init
walk_children(struct device_node
*dp
, struct sbus_dev
*parent
, struct sbus_bus
*sbus
)
201 struct sbus_dev
*sdev
;
203 sdev
= kzalloc(sizeof(struct sbus_dev
), GFP_ATOMIC
);
205 sdev_insert(sdev
, &parent
->child
);
208 sdev
->parent
= parent
;
210 fill_sbus_device(dp
, sdev
);
212 walk_children(dp
, sdev
, sbus
);
218 static void __init
build_one_sbus(struct device_node
*dp
, int num_sbus
)
220 struct sbus_bus
*sbus
;
221 unsigned int sbus_clock
;
222 struct device_node
*dev_dp
;
224 sbus
= kzalloc(sizeof(struct sbus_bus
), GFP_ATOMIC
);
228 sbus_insert(sbus
, &sbus_root
);
229 sbus
->prom_node
= dp
->node
;
231 sbus_setup_iommu(sbus
, dp
);
233 printk("sbus%d: ", num_sbus
);
235 sbus_clock
= of_getintprop_default(dp
, "clock-frequency",
237 sbus
->clock_freq
= sbus_clock
;
239 printk("Clock %d.%d MHz\n", (int) ((sbus_clock
/1000)/1000),
240 (int) (((sbus_clock
/1000)%1000 != 0) ?
241 (((sbus_clock
/1000)%1000) + 1000) : 0));
243 strcpy(sbus
->prom_name
, dp
->name
);
245 sbus_setup_arch_props(sbus
, dp
);
247 sbus_bus_ranges_init(dp
, sbus
);
249 sbus
->ofdev
.node
= dp
;
250 sbus
->ofdev
.dev
.parent
= NULL
;
251 sbus
->ofdev
.dev
.bus
= &sbus_bus_type
;
252 sprintf(sbus
->ofdev
.dev
.bus_id
, "sbus%d", num_sbus
);
254 if (of_device_register(&sbus
->ofdev
) != 0)
255 printk(KERN_DEBUG
"sbus: device registration error for %s!\n",
256 sbus
->ofdev
.dev
.bus_id
);
260 struct sbus_dev
*sdev
;
262 sdev
= kzalloc(sizeof(struct sbus_dev
), GFP_ATOMIC
);
264 sdev_insert(sdev
, &sbus
->devices
);
268 fill_sbus_device(dev_dp
, sdev
);
270 walk_children(dev_dp
, sdev
, sbus
);
272 dev_dp
= dev_dp
->sibling
;
275 sbus_fixup_all_regs(sbus
->devices
);
280 static int __init
sbus_init(void)
282 struct device_node
*dp
;
283 const char *sbus_name
= "sbus";
286 if (sbus_arch_preinit())
289 if (sparc_cpu_model
== sun4d
)
292 for_each_node_by_name(dp
, sbus_name
) {
293 build_one_sbus(dp
, num_sbus
);
298 sbus_arch_postinit();
303 subsys_initcall(sbus_init
);