diff options
Diffstat (limited to 'arch/sparc64/kernel/ebus.c')
-rw-r--r-- | arch/sparc64/kernel/ebus.c | 76 |
1 files changed, 57 insertions, 19 deletions
diff --git a/arch/sparc64/kernel/ebus.c b/arch/sparc64/kernel/ebus.c index f484cfef8..02faf4e3c 100644 --- a/arch/sparc64/kernel/ebus.c +++ b/arch/sparc64/kernel/ebus.c @@ -1,4 +1,4 @@ -/* $Id: ebus.c,v 1.8 1997/09/05 22:59:39 ecd Exp $ +/* $Id: ebus.c,v 1.17 1998/01/10 18:26:13 ecd Exp $ * ebus.c: PCI to EBus bridge device. * * Copyright (C) 1997 Eddie C. Dost (ecd@skynet.be) @@ -17,8 +17,15 @@ #include <asm/oplib.h> #include <asm/bpp.h> +#undef PROM_DEBUG #undef DEBUG_FILL_EBUS_DEV +#ifdef PROM_DEBUG +#define dprintf prom_printf +#else +#define dprintf printk +#endif + struct linux_ebus *ebus_chain = 0; extern void prom_ebus_ranges_init(struct linux_ebus *); @@ -36,8 +43,12 @@ extern int sparcaudio_init(void); #ifdef CONFIG_SUN_AUXIO extern void auxio_probe(void); #endif +#ifdef CONFIG_OBP_FLASH +extern int flash_init(void); +#endif -extern unsigned int psycho_irq_build(unsigned int full_ino); +extern unsigned int psycho_irq_build(struct linux_pbm_info *pbm, + unsigned int full_ino); static inline unsigned long ebus_alloc(unsigned long *memory_start, size_t size) @@ -47,6 +58,7 @@ ebus_alloc(unsigned long *memory_start, size_t size) *memory_start = (*memory_start + 7) & ~(7); mem = *memory_start; *memory_start += size; + memset((void *)mem, 0, size); return mem; } @@ -79,19 +91,19 @@ __initfunc(void fill_ebus_child(int node, struct linux_ebus_child *dev)) } else { dev->num_irqs = len / sizeof(irqs[0]); for (i = 0; i < dev->num_irqs; i++) - dev->irqs[i] = psycho_irq_build(irqs[i]); + dev->irqs[i] = psycho_irq_build(dev->bus->parent, irqs[i]); } #ifdef DEBUG_FILL_EBUS_DEV - printk("child '%s': address%s\n", dev->prom_name, + dprintf("child '%s': address%s\n", dev->prom_name, dev->num_addrs > 1 ? "es" : ""); for (i = 0; i < dev->num_addrs; i++) - printk(" %016lx\n", dev->base_address[i]); + dprintf(" %016lx\n", dev->base_address[i]); if (dev->num_irqs) { - printk(" IRQ%s", dev->num_irqs > 1 ? "s" : ""); + dprintf(" IRQ%s", dev->num_irqs > 1 ? "s" : ""); for (i = 0; i < dev->num_irqs; i++) - printk(" %08x", dev->irqs[i]); - printk("\n"); + dprintf(" %08x", dev->irqs[i]); + dprintf("\n"); } #endif } @@ -121,7 +133,7 @@ __initfunc(unsigned long fill_ebus_device(int node, struct linux_ebus_device *de for (i = 0; i < dev->num_addrs; i++) { n = (regs[i].which_io - 0x10) >> 2; - dev->base_address[i] = dev->parent->self->base_address[n]; + dev->base_address[i] = dev->bus->self->base_address[n]; dev->base_address[i] += (unsigned long)regs[i].phys_addr; } @@ -131,19 +143,19 @@ __initfunc(unsigned long fill_ebus_device(int node, struct linux_ebus_device *de } else { dev->num_irqs = len / sizeof(irqs[0]); for (i = 0; i < dev->num_irqs; i++) - dev->irqs[i] = psycho_irq_build(irqs[i]); + dev->irqs[i] = psycho_irq_build(dev->bus->parent, irqs[i]); } #ifdef DEBUG_FILL_EBUS_DEV - printk("'%s': address%s\n", dev->prom_name, + dprintf("'%s': address%s\n", dev->prom_name, dev->num_addrs > 1 ? "es" : ""); for (i = 0; i < dev->num_addrs; i++) - printk(" %016lx\n", dev->base_address[i]); + dprintf(" %016lx\n", dev->base_address[i]); if (dev->num_irqs) { - printk(" IRQ%s", dev->num_irqs > 1 ? "s" : ""); + dprintf(" IRQ%s", dev->num_irqs > 1 ? "s" : ""); for (i = 0; i < dev->num_irqs; i++) - printk(" %08x", dev->irqs[i]); - printk("\n"); + dprintf(" %08x", dev->irqs[i]); + dprintf("\n"); } #endif if ((node = prom_getchild(node))) { @@ -153,6 +165,7 @@ __initfunc(unsigned long fill_ebus_device(int node, struct linux_ebus_device *de child = dev->children; child->next = 0; child->parent = dev; + child->bus = dev->bus; fill_ebus_child(node, child); while ((node = prom_getsibling(node))) { @@ -162,6 +175,7 @@ __initfunc(unsigned long fill_ebus_device(int node, struct linux_ebus_device *de child = child->next; child->next = 0; child->parent = dev; + child->bus = dev->bus; fill_ebus_child(node, child); } } @@ -195,6 +209,9 @@ __initfunc(unsigned long ebus_init(unsigned long memory_start, } if (!pdev) { printk("ebus: No EBus's found.\n"); +#ifdef PROM_DEBUG + dprintf("ebus: No EBus's found.\n"); +#endif return memory_start; } @@ -206,7 +223,10 @@ __initfunc(unsigned long ebus_init(unsigned long memory_start, ebus->next = 0; while (ebusnd) { - printk("ebus%d:\n", num_ebus); + printk("ebus%d:", num_ebus); +#ifdef PROM_DEBUG + dprintf("ebus%d:", num_ebus); +#endif prom_getstring(ebusnd, "name", lbuf, sizeof(lbuf)); ebus->prom_node = ebusnd; @@ -250,20 +270,34 @@ __initfunc(unsigned long ebus_init(unsigned long memory_start, addr += (u64)rp->parent_phys_hi << 32UL; *base++ = (unsigned long)__va(addr); + printk(" %lx[%x]", (unsigned long)__va(addr), + regs[reg].size_lo); +#ifdef PROM_DEBUG + dprintf(" %lx[%x]", (unsigned long)__va(addr), + regs[reg].size_lo); +#endif break; } } + printk("\n"); +#ifdef PROM_DEBUG + dprintf("\n"); +#endif prom_ebus_ranges_init(ebus); nd = prom_getchild(ebusnd); + if (!nd) + goto next_ebus; + ebus->devices = (struct linux_ebus_device *) - ebus_alloc(&memory_start, sizeof(struct linux_ebus_device)); + ebus_alloc(&memory_start, + sizeof(struct linux_ebus_device)); dev = ebus->devices; dev->next = 0; dev->children = 0; - dev->parent = ebus; + dev->bus = ebus; memory_start = fill_ebus_device(nd, dev, memory_start); while ((nd = prom_getsibling(nd))) { @@ -273,10 +307,11 @@ __initfunc(unsigned long ebus_init(unsigned long memory_start, dev = dev->next; dev->next = 0; dev->children = 0; - dev->parent = ebus; + dev->bus = ebus; memory_start = fill_ebus_device(nd, dev, memory_start); } + next_ebus: for (pdev = pdev->next; pdev; pdev = pdev->next) { if ((pdev->vendor == PCI_VENDOR_ID_SUN) && (pdev->device == PCI_DEVICE_ID_SUN_EBUS)) @@ -313,6 +348,9 @@ __initfunc(unsigned long ebus_init(unsigned long memory_start, if (sparc_cpu_model == sun4u) auxio_probe(); #endif +#ifdef CONFIG_OBP_FLASH + flash_init(); +#endif #ifdef __sparc_v9__ if (sparc_cpu_model == sun4u) { extern void sun4u_start_timers(void); |