aboutsummaryrefslogtreecommitdiffstats
path: root/arch/sparc64/kernel/isa.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@sunset.davemloft.net>2006-06-22 22:12:03 -0400
committerDavid S. Miller <davem@sunset.davemloft.net>2006-06-24 02:15:28 -0400
commit690c8fd31f1e35985d0f35772fde514da59ec9d1 (patch)
tree8a5a0036b3780a9eb315ea2201a2562570de1ebe /arch/sparc64/kernel/isa.c
parentde8d28b16f5614aeb12bb69c8f9a38578b8d3ada (diff)
[SPARC64]: Use in-kernel PROM tree for EBUS and ISA.
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'arch/sparc64/kernel/isa.c')
-rw-r--r--arch/sparc64/kernel/isa.c144
1 files changed, 57 insertions, 87 deletions
diff --git a/arch/sparc64/kernel/isa.c b/arch/sparc64/kernel/isa.c
index ae02c3820eab..8c8c5a491ad6 100644
--- a/arch/sparc64/kernel/isa.c
+++ b/arch/sparc64/kernel/isa.c
@@ -15,23 +15,19 @@ static void __init fatal_err(const char *reason)
15static void __init report_dev(struct sparc_isa_device *isa_dev, int child) 15static void __init report_dev(struct sparc_isa_device *isa_dev, int child)
16{ 16{
17 if (child) 17 if (child)
18 printk(" (%s)", isa_dev->prom_name); 18 printk(" (%s)", isa_dev->prom_node->name);
19 else 19 else
20 printk(" [%s", isa_dev->prom_name); 20 printk(" [%s", isa_dev->prom_node->name);
21} 21}
22 22
23static void __init isa_dev_get_resource(struct sparc_isa_device *isa_dev, 23static struct linux_prom_registers * __init
24 struct linux_prom_registers *pregs, 24isa_dev_get_resource(struct sparc_isa_device *isa_dev)
25 int pregs_size)
26{ 25{
26 struct linux_prom_registers *pregs;
27 unsigned long base, len; 27 unsigned long base, len;
28 int prop_len; 28 int prop_len;
29 29
30 prop_len = prom_getproperty(isa_dev->prom_node, "reg", 30 pregs = of_get_property(isa_dev->prom_node, "reg", &prop_len);
31 (char *) pregs, pregs_size);
32
33 if (prop_len <= 0)
34 return;
35 31
36 /* Only the first one is interesting. */ 32 /* Only the first one is interesting. */
37 len = pregs[0].reg_size; 33 len = pregs[0].reg_size;
@@ -42,10 +38,12 @@ static void __init isa_dev_get_resource(struct sparc_isa_device *isa_dev,
42 isa_dev->resource.start = base; 38 isa_dev->resource.start = base;
43 isa_dev->resource.end = (base + len - 1UL); 39 isa_dev->resource.end = (base + len - 1UL);
44 isa_dev->resource.flags = IORESOURCE_IO; 40 isa_dev->resource.flags = IORESOURCE_IO;
45 isa_dev->resource.name = isa_dev->prom_name; 41 isa_dev->resource.name = isa_dev->prom_node->name;
46 42
47 request_resource(&isa_dev->bus->parent->io_space, 43 request_resource(&isa_dev->bus->parent->io_space,
48 &isa_dev->resource); 44 &isa_dev->resource);
45
46 return pregs;
49} 47}
50 48
51/* I can't believe they didn't put a real INO in the isa device 49/* I can't believe they didn't put a real INO in the isa device
@@ -98,8 +96,8 @@ static void __init isa_dev_get_irq(struct sparc_isa_device *isa_dev,
98{ 96{
99 int irq_prop; 97 int irq_prop;
100 98
101 irq_prop = prom_getintdefault(isa_dev->prom_node, 99 irq_prop = of_getintprop_default(isa_dev->prom_node,
102 "interrupts", -1); 100 "interrupts", -1);
103 if (irq_prop <= 0) { 101 if (irq_prop <= 0) {
104 goto no_irq; 102 goto no_irq;
105 } else { 103 } else {
@@ -141,16 +139,15 @@ no_irq:
141 139
142static void __init isa_fill_children(struct sparc_isa_device *parent_isa_dev) 140static void __init isa_fill_children(struct sparc_isa_device *parent_isa_dev)
143{ 141{
144 int node = prom_getchild(parent_isa_dev->prom_node); 142 struct device_node *dp = parent_isa_dev->prom_node->child;
145 143
146 if (node == 0) 144 if (!dp)
147 return; 145 return;
148 146
149 printk(" ->"); 147 printk(" ->");
150 while (node != 0) { 148 while (dp) {
151 struct linux_prom_registers regs[PROMREG_MAX]; 149 struct linux_prom_registers *regs;
152 struct sparc_isa_device *isa_dev; 150 struct sparc_isa_device *isa_dev;
153 int prop_len;
154 151
155 isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL); 152 isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL);
156 if (!isa_dev) { 153 if (!isa_dev) {
@@ -165,40 +162,24 @@ static void __init isa_fill_children(struct sparc_isa_device *parent_isa_dev)
165 parent_isa_dev->child = isa_dev; 162 parent_isa_dev->child = isa_dev;
166 163
167 isa_dev->bus = parent_isa_dev->bus; 164 isa_dev->bus = parent_isa_dev->bus;
168 isa_dev->prom_node = node; 165 isa_dev->prom_node = dp;
169 prop_len = prom_getproperty(node, "name",
170 (char *) isa_dev->prom_name,
171 sizeof(isa_dev->prom_name));
172 if (prop_len <= 0) {
173 fatal_err("cannot get child isa_dev OBP node name");
174 prom_halt();
175 }
176
177 prop_len = prom_getproperty(node, "compatible",
178 (char *) isa_dev->compatible,
179 sizeof(isa_dev->compatible));
180 166
181 /* Not having this is OK. */ 167 regs = isa_dev_get_resource(isa_dev);
182 if (prop_len <= 0)
183 isa_dev->compatible[0] = '\0';
184
185 isa_dev_get_resource(isa_dev, regs, sizeof(regs));
186 isa_dev_get_irq(isa_dev, regs); 168 isa_dev_get_irq(isa_dev, regs);
187 169
188 report_dev(isa_dev, 1); 170 report_dev(isa_dev, 1);
189 171
190 node = prom_getsibling(node); 172 dp = dp->sibling;
191 } 173 }
192} 174}
193 175
194static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br) 176static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br)
195{ 177{
196 int node = prom_getchild(isa_br->prom_node); 178 struct device_node *dp = isa_br->prom_node->child;
197 179
198 while (node != 0) { 180 while (dp) {
199 struct linux_prom_registers regs[PROMREG_MAX]; 181 struct linux_prom_registers *regs;
200 struct sparc_isa_device *isa_dev; 182 struct sparc_isa_device *isa_dev;
201 int prop_len;
202 183
203 isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL); 184 isa_dev = kmalloc(sizeof(*isa_dev), GFP_KERNEL);
204 if (!isa_dev) { 185 if (!isa_dev) {
@@ -222,24 +203,9 @@ static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br)
222 } 203 }
223 204
224 isa_dev->bus = isa_br; 205 isa_dev->bus = isa_br;
225 isa_dev->prom_node = node; 206 isa_dev->prom_node = dp;
226 prop_len = prom_getproperty(node, "name",
227 (char *) isa_dev->prom_name,
228 sizeof(isa_dev->prom_name));
229 if (prop_len <= 0) {
230 fatal_err("cannot get isa_dev OBP node name");
231 prom_halt();
232 }
233
234 prop_len = prom_getproperty(node, "compatible",
235 (char *) isa_dev->compatible,
236 sizeof(isa_dev->compatible));
237
238 /* Not having this is OK. */
239 if (prop_len <= 0)
240 isa_dev->compatible[0] = '\0';
241 207
242 isa_dev_get_resource(isa_dev, regs, sizeof(regs)); 208 regs = isa_dev_get_resource(isa_dev);
243 isa_dev_get_irq(isa_dev, regs); 209 isa_dev_get_irq(isa_dev, regs);
244 210
245 report_dev(isa_dev, 0); 211 report_dev(isa_dev, 0);
@@ -248,10 +214,40 @@ static void __init isa_fill_devices(struct sparc_isa_bridge *isa_br)
248 214
249 printk("]"); 215 printk("]");
250 216
251 node = prom_getsibling(node); 217 dp = dp->sibling;
252 } 218 }
253} 219}
254 220
221static void __init get_bridge_props(struct sparc_isa_bridge *isa_br)
222{
223 struct device_node *dp = isa_br->prom_node;
224 void *pval;
225 int len;
226
227 pval = of_get_property(dp, "ranges", &len);
228 if (pval) {
229 memcpy(isa_br->isa_ranges, pval, len);
230 isa_br->num_isa_ranges =
231 len / sizeof(struct linux_prom_isa_ranges);
232 } else {
233 isa_br->num_isa_ranges = 0;
234 }
235
236 pval = of_get_property(dp, "interrupt-map", &len);
237 if (pval) {
238 memcpy(isa_br->isa_intmap, pval, len);
239 isa_br->num_isa_intmap =
240 (len / sizeof(struct linux_prom_isa_intmap));
241 } else {
242 isa_br->num_isa_intmap = 0;
243 }
244
245 pval = of_get_property(dp, "interrupt-map-mask", &len);
246 if (pval)
247 memcpy(&isa_br->isa_intmask, pval,
248 sizeof(isa_br->isa_intmask));
249}
250
255void __init isa_init(void) 251void __init isa_init(void)
256{ 252{
257 struct pci_dev *pdev; 253 struct pci_dev *pdev;
@@ -266,7 +262,6 @@ void __init isa_init(void)
266 struct pcidev_cookie *pdev_cookie; 262 struct pcidev_cookie *pdev_cookie;
267 struct pci_pbm_info *pbm; 263 struct pci_pbm_info *pbm;
268 struct sparc_isa_bridge *isa_br; 264 struct sparc_isa_bridge *isa_br;
269 int prop_len;
270 265
271 pdev_cookie = pdev->sysdata; 266 pdev_cookie = pdev->sysdata;
272 if (!pdev_cookie) { 267 if (!pdev_cookie) {
@@ -291,34 +286,9 @@ void __init isa_init(void)
291 isa_br->parent = pbm; 286 isa_br->parent = pbm;
292 isa_br->self = pdev; 287 isa_br->self = pdev;
293 isa_br->index = index++; 288 isa_br->index = index++;
294 isa_br->prom_node = pdev_cookie->prom_node->node; 289 isa_br->prom_node = pdev_cookie->prom_node;
295 strncpy(isa_br->prom_name, pdev_cookie->prom_node->name, 290
296 sizeof(isa_br->prom_name)); 291 get_bridge_props(isa_br);
297
298 prop_len = prom_getproperty(isa_br->prom_node,
299 "ranges",
300 (char *) isa_br->isa_ranges,
301 sizeof(isa_br->isa_ranges));
302 if (prop_len <= 0)
303 isa_br->num_isa_ranges = 0;
304 else
305 isa_br->num_isa_ranges =
306 (prop_len / sizeof(struct linux_prom_isa_ranges));
307
308 prop_len = prom_getproperty(isa_br->prom_node,
309 "interrupt-map",
310 (char *) isa_br->isa_intmap,
311 sizeof(isa_br->isa_intmap));
312 if (prop_len <= 0)
313 isa_br->num_isa_intmap = 0;
314 else
315 isa_br->num_isa_intmap =
316 (prop_len / sizeof(struct linux_prom_isa_intmap));
317
318 prop_len = prom_getproperty(isa_br->prom_node,
319 "interrupt-map-mask",
320 (char *) &(isa_br->isa_intmask),
321 sizeof(isa_br->isa_intmask));
322 292
323 printk("isa%d:", isa_br->index); 293 printk("isa%d:", isa_br->index);
324 294