* add p cc
[mascara-docs.git] / i386 / linux / linux-2.3.21 / arch / sparc / kernel / ebus.c
blobd0a9c622a11319051e91d37d4a9eb854ed4e18ae
1 /* $Id: ebus.c,v 1.4 1999/08/31 06:54:19 davem Exp $
2 * ebus.c: PCI to EBus bridge device.
4 * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
6 * Adopted for sparc by V. Roganov and G. Raiko.
7 * Fixes for different platforms by Pete Zaitcev.
8 */
10 #include <linux/config.h>
11 #include <linux/kernel.h>
12 #include <linux/types.h>
13 #include <linux/init.h>
14 #include <linux/malloc.h>
15 #include <linux/string.h>
17 #include <asm/system.h>
18 #include <asm/page.h>
19 #include <asm/pbm.h>
20 #include <asm/ebus.h>
21 #include <asm/io.h>
22 #include <asm/oplib.h>
23 #include <asm/bpp.h>
25 #undef PROM_DEBUG
26 #undef DEBUG_FILL_EBUS_DEV
28 #ifdef PROM_DEBUG
29 #define dprintk prom_printf
30 #else
31 #define dprintk printk
32 #endif
34 struct linux_ebus *ebus_chain = 0;
36 #ifdef CONFIG_SUN_OPENPROMIO
37 extern int openprom_init(void);
38 #endif
39 #ifdef CONFIG_SPARCAUDIO
40 extern int sparcaudio_init(void);
41 #endif
42 #ifdef CONFIG_SUN_AUXIO
43 extern void auxio_probe(void);
44 #endif
45 #ifdef CONFIG_OBP_FLASH
46 extern int flash_init(void);
47 #endif
48 #ifdef CONFIG_ENVCTRL
49 extern int envctrl_init(void);
50 #endif
52 /* We are together with pcic.c under CONFIG_PCI. */
53 extern unsigned int pcic_pin_to_irq(unsigned int, char *name);
55 static inline unsigned long ebus_alloc(size_t size)
57 return (unsigned long)kmalloc(size, GFP_ATOMIC);
60 void __init fill_ebus_child(int node, struct linux_prom_registers *preg,
61 struct linux_ebus_child *dev)
63 int regs[PROMREG_MAX];
64 int irqs[PROMREG_MAX];
65 char lbuf[128];
66 int i, len;
68 dev->prom_node = node;
69 prom_getstring(node, "name", lbuf, sizeof(lbuf));
70 strcpy(dev->prom_name, lbuf);
72 len = prom_getproperty(node, "reg", (void *)regs, sizeof(regs));
73 if (len == -1) len = 0;
74 dev->num_addrs = len / sizeof(regs[0]);
76 for (i = 0; i < dev->num_addrs; i++) {
77 if (regs[i] >= dev->parent->num_addrs) {
78 prom_printf("UGH: property for %s was %d, need < %d\n",
79 dev->prom_name, len, dev->parent->num_addrs);
80 panic(__FUNCTION__);
82 dev->base_address[i] = dev->parent->base_address[regs[i]];
86 * Houston, we have a problem...
87 * Sometimes PROM supplies absolutely meaningless properties.
88 * Still, we take what it gives since we have nothing better.
89 * Children of ebus may be wired on any input pin of PCIC.
91 len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs));
92 if ((len == -1) || (len == 0)) {
93 dev->num_irqs = 0;
94 dev->irqs[0] = 0;
95 if (dev->parent->num_irqs != 0) {
96 dev->num_irqs = 1;
97 dev->irqs[0] = dev->parent->irqs[0];
98 /* P3 remove */ printk("EBUS: dev %s irq %d from parent\n", dev->prom_name, dev->irqs[0]);
100 } else {
101 dev->num_irqs = len / sizeof(irqs[0]);
102 if (irqs[0] == 0 || irqs[0] >= 8) {
104 * XXX Zero is a valid pin number...
105 * This works as long as Ebus is not wired to INTA#.
107 printk("EBUS: %s got bad irq %d from PROM\n",
108 dev->prom_name, irqs[0]);
109 dev->num_irqs = 0;
110 dev->irqs[0] = 0;
111 } else {
112 dev->irqs[0] = pcic_pin_to_irq(irqs[0], dev->prom_name);
113 /* P3 remove */ printk("EBUS: dev %s irq %d from PROM\n", dev->prom_name, dev->irqs[0]);
117 #ifdef DEBUG_FILL_EBUS_DEV
118 dprintk("child '%s': address%s\n", dev->prom_name,
119 dev->num_addrs > 1 ? "es" : "");
120 for (i = 0; i < dev->num_addrs; i++)
121 dprintk(" %016lx\n", dev->base_address[i]);
122 if (dev->num_irqs) {
123 dprintk(" IRQ%s", dev->num_irqs > 1 ? "s" : "");
124 for (i = 0; i < dev->num_irqs; i++)
125 dprintk(" %08x", dev->irqs[i]);
126 dprintk("\n");
128 #endif
131 void __init fill_ebus_device(int node, struct linux_ebus_device *dev)
133 struct linux_prom_registers regs[PROMREG_MAX];
134 struct linux_ebus_child *child;
135 int irqs[PROMINTR_MAX];
136 char lbuf[128];
137 int i, n, len;
139 dev->prom_node = node;
140 prom_getstring(node, "name", lbuf, sizeof(lbuf));
141 strcpy(dev->prom_name, lbuf);
143 len = prom_getproperty(node, "reg", (void *)regs, sizeof(regs));
144 if (len % sizeof(struct linux_prom_registers)) {
145 prom_printf("UGH: proplen for %s was %d, need multiple of %d\n",
146 dev->prom_name, len,
147 (int)sizeof(struct linux_prom_registers));
148 panic(__FUNCTION__);
150 dev->num_addrs = len / sizeof(struct linux_prom_registers);
152 for (i = 0; i < dev->num_addrs; i++) {
154 * XXX Collect JE-1 PROM
156 * Example - JS-E with 3.11:
157 * /ebus
158 * regs
159 * 0x00000000, 0x0, 0x00000000, 0x0, 0x00000000,
160 * 0x82000010, 0x0, 0xf0000000, 0x0, 0x01000000,
161 * 0x82000014, 0x0, 0x38800000, 0x0, 0x00800000,
162 * ranges
163 * 0x00, 0x00000000, 0x02000010, 0x0, 0x0, 0x01000000,
164 * 0x01, 0x01000000, 0x02000014, 0x0, 0x0, 0x00800000,
165 * /ebus/8042
166 * regs
167 * 0x00000001, 0x00300060, 0x00000008,
168 * 0x00000001, 0x00300060, 0x00000008,
170 n = regs[i].which_io;
171 if (n >= 4) {
172 /* XXX This is copied from old JE-1 by Gleb. */
173 n = (regs[i].which_io - 0x10) >> 2;
174 } else {
178 dev->base_address[i] = dev->bus->self->base_address[n];
179 dev->base_address[i] += regs[i].phys_addr;
181 if (dev->base_address[i]) {
182 dev->base_address[i] =
183 (unsigned long)sparc_alloc_io (dev->base_address[i], 0,
184 regs[i].reg_size,
185 dev->prom_name, 0, 0);
186 #if 0
188 * This release_region() screwes those who do sparc_alloc_io().
189 * Change drivers which do check_region(). See drivers/block/floppy.c.
191 /* Some drivers call 'check_region', so we release it */
192 release_region(dev->base_address[i] & PAGE_MASK, PAGE_SIZE);
193 #endif
195 if (dev->base_address[i] == 0 ) {
196 panic("ebus: unable sparc_alloc_io for dev %s",
197 dev->prom_name);
202 len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs));
203 if ((len == -1) || (len == 0)) {
204 dev->num_irqs = 0;
205 if ((dev->irqs[0] = dev->bus->self->irq) != 0) {
206 dev->num_irqs = 1;
207 /* P3 remove */ printk("EBUS: child %s irq %d from parent\n", dev->prom_name, dev->irqs[0]);
209 } else {
210 dev->num_irqs = 1; /* dev->num_irqs = len / sizeof(irqs[0]); */
211 if (irqs[0] == 0 || irqs[0] >= 8) {
212 /* See above for the parent. XXX */
213 printk("EBUS: %s got bad irq %d from PROM\n",
214 dev->prom_name, irqs[0]);
215 dev->num_irqs = 0;
216 dev->irqs[0] = 0;
217 } else {
218 dev->irqs[0] = pcic_pin_to_irq(irqs[0], dev->prom_name);
219 /* P3 remove */ printk("EBUS: child %s irq %d from PROM\n", dev->prom_name, dev->irqs[0]);
223 #ifdef DEBUG_FILL_EBUS_DEV
224 dprintk("'%s': address%s\n", dev->prom_name,
225 dev->num_addrs > 1 ? "es" : "");
226 for (i = 0; i < dev->num_addrs; i++)
227 dprintk(" %016lx\n", dev->base_address[i]);
228 if (dev->num_irqs) {
229 dprintk(" IRQ%s", dev->num_irqs > 1 ? "s" : "");
230 for (i = 0; i < dev->num_irqs; i++)
231 dprintk(" %08x", dev->irqs[i]);
232 dprintk("\n");
234 #endif
235 if ((node = prom_getchild(node))) {
236 dev->children = (struct linux_ebus_child *)
237 ebus_alloc(sizeof(struct linux_ebus_child));
239 child = dev->children;
240 child->next = 0;
241 child->parent = dev;
242 child->bus = dev->bus;
243 fill_ebus_child(node, &regs[0], child);
245 while ((node = prom_getsibling(node))) {
246 child->next = (struct linux_ebus_child *)
247 ebus_alloc(sizeof(struct linux_ebus_child));
249 child = child->next;
250 child->next = 0;
251 child->parent = dev;
252 child->bus = dev->bus;
253 fill_ebus_child(node, &regs[0], child);
258 void __init ebus_init(void)
260 struct linux_prom_pci_registers regs[PROMREG_MAX];
261 struct linux_pbm_info *pbm;
262 struct linux_ebus_device *dev;
263 struct linux_ebus *ebus;
264 struct pci_dev *pdev;
265 struct pcidev_cookie *cookie;
266 char lbuf[128];
267 unsigned long addr, *base;
268 unsigned short pci_command;
269 int nd, len, ebusnd;
270 int reg, nreg;
271 int num_ebus = 0;
273 if (!pci_present())
274 return;
276 pdev = pci_find_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, 0);
277 if (!pdev) {
278 #ifdef PROM_DEBUG
279 dprintk("ebus: No EBus's found.\n");
280 #endif
281 return;
283 cookie = pdev->sysdata;
284 ebusnd = cookie->prom_node;
286 ebus_chain = ebus = (struct linux_ebus *)
287 ebus_alloc(sizeof(struct linux_ebus));
288 ebus->next = 0;
290 while (ebusnd) {
291 #ifdef PROM_DEBUG
292 dprintk("ebus%d:", num_ebus);
293 #endif
295 prom_getstring(ebusnd, "name", lbuf, sizeof(lbuf));
296 ebus->prom_node = ebusnd;
297 strcpy(ebus->prom_name, lbuf);
298 ebus->self = pdev;
299 ebus->parent = pbm = cookie->pbm;
301 /* Enable BUS Master. */
302 pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
303 pci_command |= PCI_COMMAND_MASTER;
304 pci_write_config_word(pdev, PCI_COMMAND, pci_command);
306 len = prom_getproperty(ebusnd, "reg", (void *)regs,
307 sizeof(regs));
308 if (len == 0 || len == -1) {
309 prom_printf("%s: can't find reg property\n",
310 __FUNCTION__);
311 prom_halt();
313 nreg = len / sizeof(struct linux_prom_pci_registers);
315 base = &ebus->self->base_address[0];
316 for (reg = 0; reg < nreg; reg++) {
317 if (!(regs[reg].which_io & 0x03000000))
318 continue;
320 addr = regs[reg].phys_lo;
321 *base++ = addr;
322 #ifdef PROM_DEBUG
323 dprintk(" %lx[%x]", addr, regs[reg].size_lo);
324 #endif
326 #ifdef PROM_DEBUG
327 dprintk("\n");
328 #endif
330 nd = prom_getchild(ebusnd);
331 if (!nd)
332 goto next_ebus;
334 ebus->devices = (struct linux_ebus_device *)
335 ebus_alloc(sizeof(struct linux_ebus_device));
337 dev = ebus->devices;
338 dev->next = 0;
339 dev->children = 0;
340 dev->bus = ebus;
341 fill_ebus_device(nd, dev);
343 while ((nd = prom_getsibling(nd))) {
344 dev->next = (struct linux_ebus_device *)
345 ebus_alloc(sizeof(struct linux_ebus_device));
347 dev = dev->next;
348 dev->next = 0;
349 dev->children = 0;
350 dev->bus = ebus;
351 fill_ebus_device(nd, dev);
354 next_ebus:
355 pdev = pci_find_device(PCI_VENDOR_ID_SUN,
356 PCI_DEVICE_ID_SUN_EBUS, pdev);
357 if (!pdev)
358 break;
360 cookie = pdev->sysdata;
361 ebusnd = cookie->prom_node;
363 ebus->next = (struct linux_ebus *)
364 ebus_alloc(sizeof(struct linux_ebus));
365 ebus = ebus->next;
366 ebus->next = 0;
367 ++num_ebus;
370 #ifdef CONFIG_SUN_OPENPROMIO
371 openprom_init();
372 #endif
374 #ifdef CONFIG_SPARCAUDIO
375 sparcaudio_init();
376 #endif
377 #ifdef CONFIG_SUN_BPP
378 bpp_init();
379 #endif
380 #ifdef CONFIG_SUN_AUXIO
381 auxio_probe();
382 #endif
383 #ifdef CONFIG_ENVCTRL
384 envctrl_init();
385 #endif
386 #ifdef CONFIG_OBP_FLASH
387 flash_init();
388 #endif