File: /usr/src/linux/arch/sparc64/kernel/ebus.c
1 /* $Id: ebus.c,v 1.63 2001/06/08 02:27:16 davem Exp $
2 * ebus.c: PCI to EBus bridge device.
3 *
4 * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
5 * Copyright (C) 1999 David S. Miller (davem@redhat.com)
6 */
7
8 #include <linux/config.h>
9 #include <linux/kernel.h>
10 #include <linux/types.h>
11 #include <linux/init.h>
12 #include <linux/slab.h>
13 #include <linux/string.h>
14
15 #include <asm/system.h>
16 #include <asm/page.h>
17 #include <asm/pbm.h>
18 #include <asm/ebus.h>
19 #include <asm/oplib.h>
20 #include <asm/bpp.h>
21 #include <asm/irq.h>
22
23 struct linux_ebus *ebus_chain = 0;
24
25 #ifdef CONFIG_SUN_AUXIO
26 extern void auxio_probe(void);
27 #endif
28
29 static inline void *ebus_alloc(size_t size)
30 {
31 void *mem;
32
33 mem = kmalloc(size, GFP_ATOMIC);
34 if (!mem)
35 panic(__FUNCTION__ ": out of memory");
36 memset((char *)mem, 0, size);
37 return mem;
38 }
39
40 static void __init ebus_ranges_init(struct linux_ebus *ebus)
41 {
42 int success;
43
44 ebus->num_ebus_ranges = 0;
45 success = prom_getproperty(ebus->prom_node, "ranges",
46 (char *)ebus->ebus_ranges,
47 sizeof(ebus->ebus_ranges));
48 if (success != -1)
49 ebus->num_ebus_ranges = (success/sizeof(struct linux_prom_ebus_ranges));
50 }
51
52 static void __init ebus_intmap_init(struct linux_ebus *ebus)
53 {
54 int success;
55
56 ebus->num_ebus_intmap = 0;
57 success = prom_getproperty(ebus->prom_node, "interrupt-map",
58 (char *)ebus->ebus_intmap,
59 sizeof(ebus->ebus_intmap));
60 if (success == -1)
61 return;
62
63 ebus->num_ebus_intmap = (success/sizeof(struct linux_prom_ebus_intmap));
64
65 success = prom_getproperty(ebus->prom_node, "interrupt-map-mask",
66 (char *)&ebus->ebus_intmask,
67 sizeof(ebus->ebus_intmask));
68 if (success == -1) {
69 prom_printf("%s: can't get interrupt-map-mask\n", __FUNCTION__);
70 prom_halt();
71 }
72 }
73
74 int __init ebus_intmap_match(struct linux_ebus *ebus,
75 struct linux_prom_registers *reg,
76 int *interrupt)
77 {
78 unsigned int hi, lo, irq;
79 int i;
80
81 if (!ebus->num_ebus_intmap)
82 return 0;
83
84 hi = reg->which_io & ebus->ebus_intmask.phys_hi;
85 lo = reg->phys_addr & ebus->ebus_intmask.phys_lo;
86 irq = *interrupt & ebus->ebus_intmask.interrupt;
87 for (i = 0; i < ebus->num_ebus_intmap; i++) {
88 if ((ebus->ebus_intmap[i].phys_hi == hi) &&
89 (ebus->ebus_intmap[i].phys_lo == lo) &&
90 (ebus->ebus_intmap[i].interrupt == irq)) {
91 *interrupt = ebus->ebus_intmap[i].cinterrupt;
92 return 0;
93 }
94 }
95 return -1;
96 }
97
98 void __init fill_ebus_child(int node, struct linux_prom_registers *preg,
99 struct linux_ebus_child *dev, int non_standard_regs)
100 {
101 int regs[PROMREG_MAX];
102 int irqs[PROMREG_MAX];
103 int i, len;
104
105 dev->prom_node = node;
106 prom_getstring(node, "name", dev->prom_name, sizeof(dev->prom_name));
107 printk(" (%s)", dev->prom_name);
108
109 len = prom_getproperty(node, "reg", (void *)regs, sizeof(regs));
110 dev->num_addrs = len / sizeof(regs[0]);
111
112 if (non_standard_regs) {
113 /* This is to handle reg properties which are not
114 * in the parent relative format. One example are
115 * children of the i2c device on CompactPCI systems.
116 *
117 * So, for such devices we just record the property
118 * raw in the child resources.
119 */
120 for (i = 0; i < dev->num_addrs; i++)
121 dev->resource[i].start = regs[i];
122 } else {
123 for (i = 0; i < dev->num_addrs; i++) {
124 int rnum = regs[i];
125 if (rnum >= dev->parent->num_addrs) {
126 prom_printf("UGH: property for %s was %d, need < %d\n",
127 dev->prom_name, len, dev->parent->num_addrs);
128 panic(__FUNCTION__);
129 }
130 dev->resource[i].start = dev->parent->resource[i].start;
131 dev->resource[i].end = dev->parent->resource[i].end;
132 dev->resource[i].flags = IORESOURCE_MEM;
133 dev->resource[i].name = dev->prom_name;
134 }
135 }
136
137 len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs));
138 if ((len == -1) || (len == 0)) {
139 dev->num_irqs = 0;
140 /*
141 * Oh, well, some PROMs don't export interrupts
142 * property to children of EBus devices...
143 *
144 * Be smart about PS/2 keyboard and mouse.
145 */
146 if (!strcmp(dev->parent->prom_name, "8042")) {
147 if (!strcmp(dev->prom_name, "kb_ps2")) {
148 dev->num_irqs = 1;
149 dev->irqs[0] = dev->parent->irqs[0];
150 } else {
151 dev->num_irqs = 1;
152 dev->irqs[0] = dev->parent->irqs[1];
153 }
154 }
155 } else {
156 dev->num_irqs = len / sizeof(irqs[0]);
157 for (i = 0; i < dev->num_irqs; i++) {
158 struct pci_pbm_info *pbm = dev->bus->parent;
159 struct pci_controller_info *p = pbm->parent;
160
161 if (ebus_intmap_match(dev->bus, preg, &irqs[i]) != -1) {
162 dev->irqs[i] = p->irq_build(pbm,
163 dev->bus->self,
164 irqs[i]);
165 } else {
166 /* If we get a bogus interrupt property, just
167 * record the raw value instead of punting.
168 */
169 dev->irqs[i] = irqs[i];
170 }
171 }
172 }
173 }
174
175 static int __init child_regs_nonstandard(struct linux_ebus_device *dev)
176 {
177 if (!strcmp(dev->prom_name, "i2c"))
178 return 1;
179 return 0;
180 }
181
182 void __init fill_ebus_device(int node, struct linux_ebus_device *dev)
183 {
184 struct linux_prom_registers regs[PROMREG_MAX];
185 struct linux_ebus_child *child;
186 int irqs[PROMINTR_MAX];
187 int i, n, len;
188
189 dev->prom_node = node;
190 prom_getstring(node, "name", dev->prom_name, sizeof(dev->prom_name));
191 printk(" [%s", dev->prom_name);
192
193 len = prom_getproperty(node, "reg", (void *)regs, sizeof(regs));
194 if (len == -1) {
195 dev->num_addrs = 0;
196 goto probe_interrupts;
197 }
198
199 if (len % sizeof(struct linux_prom_registers)) {
200 prom_printf("UGH: proplen for %s was %d, need multiple of %d\n",
201 dev->prom_name, len,
202 (int)sizeof(struct linux_prom_registers));
203 prom_halt();
204 }
205 dev->num_addrs = len / sizeof(struct linux_prom_registers);
206
207 for (i = 0; i < dev->num_addrs; i++) {
208 if (dev->bus->is_rio == 0)
209 n = (regs[i].which_io - 0x10) >> 2;
210 else
211 n = regs[i].which_io;
212
213 dev->resource[i].start = dev->bus->self->resource[n].start;
214 dev->resource[i].start += (unsigned long)regs[i].phys_addr;
215 dev->resource[i].end =
216 (dev->resource[i].start + (unsigned long)regs[i].reg_size - 1UL);
217 dev->resource[i].flags = IORESOURCE_MEM;
218 dev->resource[i].name = dev->prom_name;
219 request_resource(&dev->bus->self->resource[n],
220 &dev->resource[i]);
221 }
222
223 probe_interrupts:
224 len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs));
225 if ((len == -1) || (len == 0)) {
226 dev->num_irqs = 0;
227 } else {
228 dev->num_irqs = len / sizeof(irqs[0]);
229 for (i = 0; i < dev->num_irqs; i++) {
230 struct pci_pbm_info *pbm = dev->bus->parent;
231 struct pci_controller_info *p = pbm->parent;
232
233 if (ebus_intmap_match(dev->bus, ®s[0], &irqs[i]) != -1) {
234 dev->irqs[i] = p->irq_build(pbm,
235 dev->bus->self,
236 irqs[i]);
237 } else {
238 /* If we get a bogus interrupt property, just
239 * record the raw value instead of punting.
240 */
241 dev->irqs[i] = irqs[i];
242 }
243 }
244 }
245
246 if ((node = prom_getchild(node))) {
247 printk(" ->");
248 dev->children = ebus_alloc(sizeof(struct linux_ebus_child));
249
250 child = dev->children;
251 child->next = 0;
252 child->parent = dev;
253 child->bus = dev->bus;
254 fill_ebus_child(node, ®s[0],
255 child, child_regs_nonstandard(dev));
256
257 while ((node = prom_getsibling(node))) {
258 child->next = ebus_alloc(sizeof(struct linux_ebus_child));
259
260 child = child->next;
261 child->next = 0;
262 child->parent = dev;
263 child->bus = dev->bus;
264 fill_ebus_child(node, ®s[0],
265 child, child_regs_nonstandard(dev));
266 }
267 }
268 printk("]");
269 }
270
271
272 void __init ebus_init(void)
273 {
274 struct pci_pbm_info *pbm;
275 struct linux_ebus_device *dev;
276 struct linux_ebus *ebus;
277 struct pci_dev *pdev;
278 struct pcidev_cookie *cookie;
279 int nd, ebusnd, is_rio;
280 int num_ebus = 0;
281
282 if (!pci_present())
283 return;
284
285 is_rio = 0;
286 pdev = pci_find_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, 0);
287 if (!pdev) {
288 pdev = pci_find_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_RIO_EBUS, 0);
289 is_rio = 1;
290 }
291 if (!pdev) {
292 printk("ebus: No EBus's found.\n");
293 return;
294 }
295
296 cookie = pdev->sysdata;
297 ebusnd = cookie->prom_node;
298
299 ebus_chain = ebus = ebus_alloc(sizeof(struct linux_ebus));
300 ebus->next = 0;
301 ebus->is_rio = is_rio;
302
303 while (ebusnd) {
304 /* SUNW,pci-qfe uses four empty ebuses on it.
305 I think we should not consider them here,
306 as they have half of the properties this
307 code expects and once we do PCI hot-plug,
308 we'd have to tweak with the ebus_chain
309 in the runtime after initialization. -jj */
310 if (!prom_getchild (ebusnd)) {
311 struct pci_dev *orig_pdev = pdev;
312
313 is_rio = 0;
314 pdev = pci_find_device(PCI_VENDOR_ID_SUN,
315 PCI_DEVICE_ID_SUN_EBUS, orig_pdev);
316 if (!pdev) {
317 pdev = pci_find_device(PCI_VENDOR_ID_SUN,
318 PCI_DEVICE_ID_SUN_RIO_EBUS, orig_pdev);
319 is_rio = 1;
320 }
321 if (!pdev) {
322 if (ebus == ebus_chain) {
323 ebus_chain = NULL;
324 printk("ebus: No EBus's found.\n");
325 return;
326 }
327 break;
328 }
329 ebus->is_rio = is_rio;
330 cookie = pdev->sysdata;
331 ebusnd = cookie->prom_node;
332 continue;
333 }
334 printk("ebus%d:", num_ebus);
335
336 prom_getstring(ebusnd, "name", ebus->prom_name, sizeof(ebus->prom_name));
337 ebus->index = num_ebus;
338 ebus->prom_node = ebusnd;
339 ebus->self = pdev;
340 ebus->parent = pbm = cookie->pbm;
341
342 ebus_ranges_init(ebus);
343 ebus_intmap_init(ebus);
344
345 nd = prom_getchild(ebusnd);
346 if (!nd)
347 goto next_ebus;
348
349 ebus->devices = ebus_alloc(sizeof(struct linux_ebus_device));
350
351 dev = ebus->devices;
352 dev->next = 0;
353 dev->children = 0;
354 dev->bus = ebus;
355 fill_ebus_device(nd, dev);
356
357 while ((nd = prom_getsibling(nd))) {
358 dev->next = ebus_alloc(sizeof(struct linux_ebus_device));
359
360 dev = dev->next;
361 dev->next = 0;
362 dev->children = 0;
363 dev->bus = ebus;
364 fill_ebus_device(nd, dev);
365 }
366
367 next_ebus:
368 printk("\n");
369
370 {
371 struct pci_dev *orig_pdev = pdev;
372
373 is_rio = 0;
374 pdev = pci_find_device(PCI_VENDOR_ID_SUN,
375 PCI_DEVICE_ID_SUN_EBUS, orig_pdev);
376 if (!pdev) {
377 pdev = pci_find_device(PCI_VENDOR_ID_SUN,
378 PCI_DEVICE_ID_SUN_RIO_EBUS, orig_pdev);
379 is_rio = 1;
380 }
381 if (!pdev)
382 break;
383 }
384
385 cookie = pdev->sysdata;
386 ebusnd = cookie->prom_node;
387
388 ebus->next = ebus_alloc(sizeof(struct linux_ebus));
389 ebus = ebus->next;
390 ebus->next = 0;
391 ebus->is_rio = is_rio;
392 ++num_ebus;
393 }
394
395 #ifdef CONFIG_SUN_AUXIO
396 auxio_probe();
397 #endif
398 }
399