patch-2.1.51 linux/arch/sparc64/kernel/ebus.c
Next file: linux/arch/sparc64/kernel/entry.S
Previous file: linux/arch/sparc64/kernel/dtlb_prot.S
Back to the patch index
Back to the overall index
- Lines: 170
- Date:
Sat Aug 16 09:51:08 1997
- Orig file:
v2.1.50/linux/arch/sparc64/kernel/ebus.c
- Orig date:
Wed Dec 31 16:00:00 1969
diff -u --recursive --new-file v2.1.50/linux/arch/sparc64/kernel/ebus.c linux/arch/sparc64/kernel/ebus.c
@@ -0,0 +1,169 @@
+/* $Id: ebus.c,v 1.2 1997/08/15 06:44:13 davem Exp $
+ * ebus.c: PCI to EBus bridge device.
+ *
+ * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be)
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include <asm/system.h>
+#include <asm/pbm.h>
+#include <asm/ebus.h>
+#include <asm/oplib.h>
+#include <asm/bpp.h>
+
+struct linux_ebus *ebus_chain = 0;
+
+static char lbuf[128];
+
+extern void prom_ebus_ranges_init(struct linux_ebus *);
+
+#ifdef CONFIG_SUN_OPENPROMIO
+extern int openprom_init(void);
+#endif
+#ifdef CONFIG_SUN_MOSTEK_RTC
+extern int rtc_init(void);
+#endif
+#ifdef CONFIG_SPARCAUDIO
+extern int sparcaudio_init(void);
+#endif
+#ifdef CONFIG_SUN_AUXIO
+extern void auxio_probe(void);
+#endif
+
+__initfunc(void fill_ebus_device(int node, struct linux_ebus_device *dev))
+{
+ int irqs[PROMINTR_MAX];
+ int i, len;
+
+ dev->prom_node = node;
+ prom_getstring(node, "name", lbuf, sizeof(lbuf));
+ strcpy(dev->prom_name, lbuf);
+
+ len = prom_getproperty(node, "reg", (void *)dev->regs,
+ sizeof(dev->regs));
+ if (len % sizeof(struct linux_prom_registers)) {
+ prom_printf("UGH: proplen for %s was %d, need multiple of %d\n",
+ dev->prom_name, len,
+ (int)sizeof(struct linux_prom_registers));
+ panic(__FUNCTION__);
+ }
+ dev->num_registers = len / sizeof(struct linux_prom_registers);
+
+ prom_apply_ebus_ranges(dev->parent, dev->regs, dev->num_registers);
+#if 0 /* XXX No longer exists/needed in new framework... */
+ prom_apply_pbm_ranges(dev->parent->parent, dev->regs,
+ dev->num_registers);
+#endif
+
+ len = prom_getproperty(node, "interrupts", (char *)&irqs, sizeof(irqs));
+ if ((len == -1) || (len == 0)) {
+ dev->irqs[0].pri = 0;
+ dev->num_irqs = 0;
+ } else {
+ dev->num_irqs = len / sizeof(irqs[0]);
+ for (i = 0; i < dev->num_irqs; i++)
+ dev->irqs[i].pri = irqs[i];
+ }
+
+ printk("Found '%s' at %x.%08x", dev->prom_name,
+ dev->regs[0].which_io, dev->regs[0].phys_addr);
+ if (dev->num_irqs) {
+ printk(" IRQ%s", dev->num_irqs > 1 ? "s" : "");
+ for (i = 0; i < dev->num_irqs; i++)
+ printk(" %03x", dev->irqs[i].pri);
+ }
+ printk("\n");
+}
+
+__initfunc(unsigned long ebus_init(unsigned long memory_start,
+ unsigned long memory_end))
+{
+ struct linux_ebus_device *dev;
+ struct linux_ebus *ebus;
+ int nd, ebusnd, topnd;
+ int num_ebus = 0;
+
+#ifndef CONFIG_PCI
+ return memory_start;
+#endif
+
+ memory_start = ((memory_start + 7) & (~7));
+
+ topnd = psycho_root->pbm_B.prom_node;
+ if (!topnd)
+ return memory_start;
+
+ ebusnd = prom_searchsiblings(prom_getchild(topnd), "ebus");
+ if (ebusnd == 0) {
+ printk("EBUS: No EBUS's found.\n");
+ return memory_start;
+ }
+
+ ebus_chain = ebus = (struct linux_ebus *)memory_start;
+ memory_start += sizeof(struct linux_ebus);
+ ebus->next = 0;
+
+ while (ebusnd) {
+ printk("ebus%d: ", num_ebus);
+
+ prom_getstring(ebusnd, "name", lbuf, sizeof(lbuf));
+ ebus->prom_node = ebusnd;
+ strcpy(ebus->prom_name, lbuf);
+ ebus->parent = &psycho_root->pbm_B;
+
+ prom_ebus_ranges_init(ebus);
+
+ nd = prom_getchild(ebusnd);
+ ebus->devices = (struct linux_ebus_device *)memory_start;
+ memory_start += sizeof(struct linux_ebus_device);
+
+ dev = ebus->devices;
+ dev->next = 0;
+ dev->parent = ebus;
+ fill_ebus_device(nd, dev);
+
+ while ((nd = prom_getsibling(nd))) {
+ dev->next = (struct linux_ebus_device *)memory_start;
+ memory_start += sizeof(struct linux_ebus_device);
+
+ dev = dev->next;
+ dev->next = 0;
+ dev->parent = ebus;
+ fill_ebus_device(nd, dev);
+ }
+
+ ebusnd = prom_searchsiblings(prom_getsibling(ebusnd), "ebus");
+ ++num_ebus;
+ }
+
+#ifdef CONFIG_SUN_OPENPROMIO
+ openprom_init();
+#endif
+#ifdef CONFIG_SUN_MOSTEK_RTC
+ rtc_init();
+#endif
+#ifdef CONFIG_SPARCAUDIO
+ sparcaudio_init();
+#endif
+#ifdef CONFIG_SUN_BPP
+ bpp_init();
+#endif
+#ifdef CONFIG_SUN_AUXIO
+ if (sparc_cpu_model == sun4u)
+ auxio_probe();
+#endif
+#ifdef __sparc_v9__
+ if (sparc_cpu_model == sun4u) {
+ extern void sun4u_start_timers(void);
+ extern void clock_probe(void);
+
+ sun4u_start_timers();
+ clock_probe();
+ }
+#endif
+ return memory_start;
+}
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov