* better
[mascara-docs.git] / i386 / linux-2.3.21 / arch / sparc64 / kernel / ebus.c
blob0b3d1600711e4efcda00dc089484a5e09c6da6eb
1 /* $Id: ebus.c,v 1.44 1999/09/05 09:28:09 ecd Exp $
2 * ebus.c: PCI to EBus bridge device.
4 * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
5 * Copyright (C) 1999 David S. Miller (davem@redhat.com)
6 */
8 #include <linux/config.h>
9 #include <linux/kernel.h>
10 #include <linux/types.h>
11 #include <linux/init.h>
12 #include <linux/malloc.h>
13 #include <linux/string.h>
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>
23 struct linux_ebus *ebus_chain = 0;
25 extern void prom_ebus_ranges_init(struct linux_ebus *);
26 extern void prom_ebus_intmap_init(struct linux_ebus *);
28 #ifdef CONFIG_SUN_OPENPROMIO
29 extern int openprom_init(void);
30 #endif
31 #ifdef CONFIG_SUN_AUXIO
32 extern void auxio_probe(void);
33 #endif
34 #ifdef CONFIG_OBP_FLASH
35 extern int flash_init(void);
36 #endif
37 #ifdef CONFIG_ENVCTRL
38 extern int envctrl_init(void);
39 #endif
41 static inline void *ebus_alloc(size_t size)
43 void *mem;
45 mem = kmalloc(size, GFP_ATOMIC);
46 if (!mem)
47 panic(__FUNCTION__ ": out of memory");
48 memset((char *)mem, 0, size);
49 return mem;
52 void __init ebus_intmap_match(struct linux_ebus *ebus,
53 struct linux_prom_registers *reg,
54 int *interrupt)
56 unsigned int hi, lo, irq;
57 int i;
59 if (!ebus->num_ebus_intmap)
60 return;
62 hi = reg->which_io & ebus->ebus_intmask.phys_hi;
63 lo = reg->phys_addr & ebus->ebus_intmask.phys_lo;
64 irq = *interrupt & ebus->ebus_intmask.interrupt;
65 for (i = 0; i < ebus->num_ebus_intmap; i++) {
66 if ((ebus->ebus_intmap[i].phys_hi == hi) &&
67 (ebus->ebus_intmap[i].phys_lo == lo) &&
68 (ebus->ebus_intmap[i].interrupt == irq)) {
69 *interrupt = ebus->ebus_intmap[i].cinterrupt;
70 return;
74 prom_printf("ebus: IRQ [%08x.%08x.%08x] not found in interrupt-map\n",
75 reg->which_io, reg->phys_addr, *interrupt);
76 prom_halt();
79 void __init fill_ebus_child(int node, struct linux_prom_registers *preg,
80 struct linux_ebus_child *dev, int non_standard_regs)
82 int regs[PROMREG_MAX];
83 int irqs[PROMREG_MAX];
84 int i, len;
86 dev->prom_node = node;
87 prom_getstring(node, "name", dev->prom_name, sizeof(dev->prom_name));
88 printk(" (%s)", dev->prom_name);
90 len = prom_getproperty(node, "reg", (void *)regs, sizeof(regs));
91 dev->num_addrs = len / sizeof(regs[0]);
93 if (non_standard_regs) {
94 /* This is to handle reg properties which are not
95 * in the parent relative format. One example are
96 * children of the i2c device on CompactPCI systems.
98 * So, for such devices we just record the property
99 * raw in the child resources.
101 for (i = 0; i < dev->num_addrs; i++)
102 dev->resource[i].start = regs[i];
103 } else {
104 for (i = 0; i < dev->num_addrs; i++) {
105 int rnum = regs[i];
106 if (rnum >= dev->parent->num_addrs) {
107 prom_printf("UGH: property for %s was %d, need < %d\n",
108 dev->prom_name, len, dev->parent->num_addrs);
109 panic(__FUNCTION__);
111 dev->resource[i].start = dev->parent->resource[i].start;
112 dev->resource[i].end = dev->parent->resource[i].end;
113 dev->resource[i].flags = IORESOURCE_MEM;
114 dev->resource[i].name = dev->prom_name;
118 len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs));
119 if ((len == -1) || (len == 0)) {
120 dev->num_irqs = 0;
122 * Oh, well, some PROMs don't export interrupts
123 * property to children of EBus devices...
125 * Be smart about PS/2 keyboard and mouse.
127 if (!strcmp(dev->parent->prom_name, "8042")) {
128 if (!strcmp(dev->prom_name, "kb_ps2")) {
129 dev->num_irqs = 1;
130 dev->irqs[0] = dev->parent->irqs[0];
131 } else {
132 dev->num_irqs = 1;
133 dev->irqs[0] = dev->parent->irqs[1];
136 } else {
137 dev->num_irqs = len / sizeof(irqs[0]);
138 for (i = 0; i < dev->num_irqs; i++) {
139 struct pci_pbm_info *pbm = dev->bus->parent;
140 struct pci_controller_info *p = pbm->parent;
142 ebus_intmap_match(dev->bus, preg, &irqs[i]);
143 dev->irqs[i] = p->irq_build(p, dev->bus->self, irqs[i]);
148 static int __init child_regs_nonstandard(struct linux_ebus_device *dev)
150 if (!strcmp(dev->prom_name, "i2c"))
151 return 1;
152 return 0;
155 void __init fill_ebus_device(int node, struct linux_ebus_device *dev)
157 struct linux_prom_registers regs[PROMREG_MAX];
158 struct linux_ebus_child *child;
159 int irqs[PROMINTR_MAX];
160 int i, n, len;
162 dev->prom_node = node;
163 prom_getstring(node, "name", dev->prom_name, sizeof(dev->prom_name));
164 printk(" [%s", dev->prom_name);
166 len = prom_getproperty(node, "reg", (void *)regs, sizeof(regs));
167 if (len % sizeof(struct linux_prom_registers)) {
168 prom_printf("UGH: proplen for %s was %d, need multiple of %d\n",
169 dev->prom_name, len,
170 (int)sizeof(struct linux_prom_registers));
171 prom_halt();
173 dev->num_addrs = len / sizeof(struct linux_prom_registers);
175 for (i = 0; i < dev->num_addrs; i++) {
176 n = (regs[i].which_io - 0x10) >> 2;
178 dev->resource[i].start = dev->bus->self->resource[n].start;
179 dev->resource[i].start += (unsigned long)regs[i].phys_addr;
180 dev->resource[i].end =
181 (dev->resource[i].start + (unsigned long)regs[i].reg_size - 1UL);
182 dev->resource[i].flags = IORESOURCE_MEM;
183 dev->resource[i].name = dev->prom_name;
184 request_resource(&dev->bus->self->resource[n],
185 &dev->resource[i]);
188 len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs));
189 if ((len == -1) || (len == 0)) {
190 dev->num_irqs = 0;
191 } else {
192 dev->num_irqs = len / sizeof(irqs[0]);
193 for (i = 0; i < dev->num_irqs; i++) {
194 struct pci_pbm_info *pbm = dev->bus->parent;
195 struct pci_controller_info *p = pbm->parent;
197 ebus_intmap_match(dev->bus, &regs[0], &irqs[i]);
198 dev->irqs[i] = p->irq_build(p, dev->bus->self, irqs[i]);
202 if ((node = prom_getchild(node))) {
203 printk(" ->");
204 dev->children = ebus_alloc(sizeof(struct linux_ebus_child));
206 child = dev->children;
207 child->next = 0;
208 child->parent = dev;
209 child->bus = dev->bus;
210 fill_ebus_child(node, &regs[0],
211 child, child_regs_nonstandard(dev));
213 while ((node = prom_getsibling(node))) {
214 child->next = ebus_alloc(sizeof(struct linux_ebus_child));
216 child = child->next;
217 child->next = 0;
218 child->parent = dev;
219 child->bus = dev->bus;
220 fill_ebus_child(node, &regs[0],
221 child, child_regs_nonstandard(dev));
224 printk("]");
227 extern void clock_probe(void);
228 extern void power_init(void);
230 void __init ebus_init(void)
232 struct pci_pbm_info *pbm;
233 struct linux_ebus_device *dev;
234 struct linux_ebus *ebus;
235 struct pci_dev *pdev;
236 struct pcidev_cookie *cookie;
237 unsigned short pci_command;
238 int nd, ebusnd;
239 int num_ebus = 0;
241 if (!pci_present())
242 return;
244 pdev = pci_find_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, 0);
245 if (!pdev) {
246 printk("ebus: No EBus's found.\n");
247 return;
250 cookie = pdev->sysdata;
251 ebusnd = cookie->prom_node;
253 ebus_chain = ebus = ebus_alloc(sizeof(struct linux_ebus));
254 ebus->next = 0;
256 while (ebusnd) {
257 /* SUNW,pci-qfe uses four empty ebuses on it.
258 I think we should not consider them here,
259 as they have half of the properties this
260 code expects and once we do PCI hot-plug,
261 we'd have to tweak with the ebus_chain
262 in the runtime after initialization. -jj */
263 if (!prom_getchild (ebusnd)) {
264 pdev = pci_find_device(PCI_VENDOR_ID_SUN,
265 PCI_DEVICE_ID_SUN_EBUS, pdev);
266 if (!pdev) {
267 if (ebus == ebus_chain) {
268 ebus_chain = NULL;
269 printk("ebus: No EBus's found.\n");
270 return;
272 break;
275 cookie = pdev->sysdata;
276 ebusnd = cookie->prom_node;
277 continue;
279 printk("ebus%d:", num_ebus);
281 prom_getstring(ebusnd, "name", ebus->prom_name, sizeof(ebus->prom_name));
282 ebus->index = num_ebus;
283 ebus->prom_node = ebusnd;
284 ebus->self = pdev;
285 ebus->parent = pbm = cookie->pbm;
287 /* Enable BUS Master. */
288 pci_read_config_word(pdev, PCI_COMMAND, &pci_command);
289 pci_command |= PCI_COMMAND_MASTER;
290 pci_write_config_word(pdev, PCI_COMMAND, pci_command);
292 /* Set reasonable cache line size and latency timer values. */
293 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64);
295 /* NOTE: Cache line size is in 32-bit word units. */
296 pci_write_config_byte(pdev, PCI_CACHE_LINE_SIZE, 64/sizeof(u32));
298 prom_ebus_ranges_init(ebus);
299 prom_ebus_intmap_init(ebus);
301 nd = prom_getchild(ebusnd);
302 if (!nd)
303 goto next_ebus;
305 ebus->devices = ebus_alloc(sizeof(struct linux_ebus_device));
307 dev = ebus->devices;
308 dev->next = 0;
309 dev->children = 0;
310 dev->bus = ebus;
311 fill_ebus_device(nd, dev);
313 while ((nd = prom_getsibling(nd))) {
314 dev->next = ebus_alloc(sizeof(struct linux_ebus_device));
316 dev = dev->next;
317 dev->next = 0;
318 dev->children = 0;
319 dev->bus = ebus;
320 fill_ebus_device(nd, dev);
323 next_ebus:
324 printk("\n");
326 pdev = pci_find_device(PCI_VENDOR_ID_SUN,
327 PCI_DEVICE_ID_SUN_EBUS, pdev);
328 if (!pdev)
329 break;
331 cookie = pdev->sysdata;
332 ebusnd = cookie->prom_node;
334 ebus->next = ebus_alloc(sizeof(struct linux_ebus));
335 ebus = ebus->next;
336 ebus->next = 0;
337 ++num_ebus;
340 #ifdef CONFIG_SUN_OPENPROMIO
341 openprom_init();
342 #endif
343 #ifdef CONFIG_SUN_BPP
344 bpp_init();
345 #endif
346 #ifdef CONFIG_SUN_AUXIO
347 auxio_probe();
348 #endif
349 #ifdef CONFIG_ENVCTRL
350 envctrl_init();
351 #endif
352 #ifdef CONFIG_OBP_FLASH
353 flash_init();
354 #endif
355 clock_probe();
356 power_init();