void __init pcibios_init(void) { pci_controller_probe(); if (pci_controller_root == NULL) return; pci_scan_each_controller_bus(); if (pci_device_reorder) pci_reorder_devs(); isa_init(); ebus_init(); rs_init(); clock_probe(); power_init(); }
__initfunc(void ebus_init(void)) { struct linux_prom_pci_registers regs[PROMREG_MAX]; struct linux_pbm_info *pbm; struct linux_ebus_device *dev; struct linux_ebus *ebus; struct pci_dev *pdev; struct pcidev_cookie *cookie; char lbuf[128]; unsigned long addr, *base; unsigned short pci_command; int nd, len, ebusnd; int reg, rng, nreg; int num_ebus = 0; if (!pci_present()) return; pdev = pci_find_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, 0); if (!pdev) { printk("ebus: No EBus's found.\n"); #ifdef PROM_DEBUG dprintf("ebus: No EBus's found.\n"); #endif return; } cookie = pdev->sysdata; ebusnd = cookie->prom_node; ebus_chain = ebus = (struct linux_ebus *) ebus_alloc(sizeof(struct linux_ebus)); ebus->next = 0; while (ebusnd) { 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; strcpy(ebus->prom_name, lbuf); ebus->self = pdev; ebus->parent = pbm = cookie->pbm; /* Enable BUS Master. */ pci_read_config_word(pdev, PCI_COMMAND, &pci_command); pci_command |= PCI_COMMAND_MASTER; pci_write_config_word(pdev, PCI_COMMAND, pci_command); len = prom_getproperty(ebusnd, "reg", (void *)regs, sizeof(regs)); if (len == 0 || len == -1) { prom_printf("%s: can't find reg property\n", __FUNCTION__); prom_halt(); } nreg = len / sizeof(struct linux_prom_pci_registers); base = &ebus->self->base_address[0]; for (reg = 0; reg < nreg; reg++) { if (!(regs[reg].phys_hi & 0x03000000)) continue; for (rng = 0; rng < pbm->num_pbm_ranges; rng++) { struct linux_prom_pci_ranges *rp = &pbm->pbm_ranges[rng]; if ((rp->child_phys_hi ^ regs[reg].phys_hi) & 0x03000000) continue; addr = (u64)regs[reg].phys_lo; addr += (u64)regs[reg].phys_mid << 32UL; addr += (u64)rp->parent_phys_lo; 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); prom_ebus_intmap_init(ebus); nd = prom_getchild(ebusnd); if (!nd) goto next_ebus; ebus->devices = (struct linux_ebus_device *) ebus_alloc(sizeof(struct linux_ebus_device)); dev = ebus->devices; dev->next = 0; dev->children = 0; dev->bus = ebus; fill_ebus_device(nd, dev); while ((nd = prom_getsibling(nd))) { dev->next = (struct linux_ebus_device *) ebus_alloc(sizeof(struct linux_ebus_device)); dev = dev->next; dev->next = 0; dev->children = 0; dev->bus = ebus; fill_ebus_device(nd, dev); } next_ebus: pdev = pci_find_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, pdev); if (!pdev) break; cookie = pdev->sysdata; ebusnd = cookie->prom_node; ebus->next = (struct linux_ebus *) ebus_alloc(sizeof(struct linux_ebus)); ebus = ebus->next; ebus->next = 0; ++num_ebus; } #ifdef CONFIG_SUN_OPENPROMIO openprom_init(); #endif #ifdef CONFIG_SPARCAUDIO sparcaudio_init(); #endif #ifdef CONFIG_SUN_BPP bpp_init(); #endif #ifdef CONFIG_SUN_AUXIO auxio_probe(); #endif #ifdef CONFIG_ENVCTRL envctrl_init(); #endif #ifdef CONFIG_OBP_FLASH flash_init(); #endif clock_probe(); }
void __init sbus_time_init(void) { unsigned int year, mon, day, hour, min, sec; struct mostek48t02 *mregs; #ifdef CONFIG_SUN4 int temp; struct intersil *iregs; #endif BTFIXUPSET_CALL(bus_do_settimeofday, sbus_do_settimeofday, BTFIXUPCALL_NORM); btfixup(); if (ARCH_SUN4) sun4_clock_probe(); else clock_probe(); sparc_init_timers(timer_interrupt); #ifdef CONFIG_SUN4 if(idprom->id_machtype == (SM_SUN4 | SM_4_330)) { #endif mregs = (struct mostek48t02 *)mstk48t02_regs; if(!mregs) { prom_printf("Something wrong, clock regs not mapped yet.\n"); prom_halt(); } spin_lock_irq(&mostek_lock); mregs->creg |= MSTK_CREG_READ; sec = MSTK_REG_SEC(mregs); min = MSTK_REG_MIN(mregs); hour = MSTK_REG_HOUR(mregs); day = MSTK_REG_DOM(mregs); mon = MSTK_REG_MONTH(mregs); year = MSTK_CVT_YEAR( MSTK_REG_YEAR(mregs) ); xtime.tv_sec = mktime(year, mon, day, hour, min, sec); xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ); set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); mregs->creg &= ~MSTK_CREG_READ; spin_unlock_irq(&mostek_lock); #ifdef CONFIG_SUN4 } else if(idprom->id_machtype == (SM_SUN4 | SM_4_260) ) { /* initialise the intersil on sun4 */ iregs=intersil_clock; if(!iregs) { prom_printf("Something wrong, clock regs not mapped yet.\n"); prom_halt(); } intersil_intr(intersil_clock,INTERSIL_INT_100HZ); disable_pil_irq(10); intersil_stop(iregs); intersil_read_intr(intersil_clock, temp); temp = iregs->clk.int_csec; sec = iregs->clk.int_sec; min = iregs->clk.int_min; hour = iregs->clk.int_hour; day = iregs->clk.int_day; mon = iregs->clk.int_month; year = MSTK_CVT_YEAR(iregs->clk.int_year); enable_pil_irq(10); intersil_start(iregs); xtime.tv_sec = mktime(year, mon, day, hour, min, sec); xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ); set_normalized_timespec(&wall_to_monotonic, -xtime.tv_sec, -xtime.tv_nsec); printk("%u/%u/%u %u:%u:%u\n",day,mon,year,hour,min,sec); } #endif /* Now that OBP ticker has been silenced, it is safe to enable IRQ. */ local_irq_enable(); }
void __init ebus_init(void) { struct pci_pbm_info *pbm; struct linux_ebus_device *dev; struct linux_ebus *ebus; struct pci_dev *pdev; struct pcidev_cookie *cookie; int nd, ebusnd; int num_ebus = 0; if (!pci_present()) return; pdev = pci_find_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, 0); if (!pdev) { printk("ebus: No EBus's found.\n"); return; } cookie = pdev->sysdata; ebusnd = cookie->prom_node; ebus_chain = ebus = ebus_alloc(sizeof(struct linux_ebus)); ebus->next = 0; while (ebusnd) { /* SUNW,pci-qfe uses four empty ebuses on it. I think we should not consider them here, as they have half of the properties this code expects and once we do PCI hot-plug, we'd have to tweak with the ebus_chain in the runtime after initialization. -jj */ if (!prom_getchild (ebusnd)) { pdev = pci_find_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, pdev); if (!pdev) { if (ebus == ebus_chain) { ebus_chain = NULL; printk("ebus: No EBus's found.\n"); return; } break; } cookie = pdev->sysdata; ebusnd = cookie->prom_node; continue; } printk("ebus%d:", num_ebus); prom_getstring(ebusnd, "name", ebus->prom_name, sizeof(ebus->prom_name)); ebus->index = num_ebus; ebus->prom_node = ebusnd; ebus->self = pdev; ebus->parent = pbm = cookie->pbm; ebus_ranges_init(ebus); ebus_intmap_init(ebus); nd = prom_getchild(ebusnd); if (!nd) goto next_ebus; ebus->devices = ebus_alloc(sizeof(struct linux_ebus_device)); dev = ebus->devices; dev->next = 0; dev->children = 0; dev->bus = ebus; fill_ebus_device(nd, dev); while ((nd = prom_getsibling(nd))) { dev->next = ebus_alloc(sizeof(struct linux_ebus_device)); dev = dev->next; dev->next = 0; dev->children = 0; dev->bus = ebus; fill_ebus_device(nd, dev); } next_ebus: printk("\n"); pdev = pci_find_device(PCI_VENDOR_ID_SUN, PCI_DEVICE_ID_SUN_EBUS, pdev); if (!pdev) break; cookie = pdev->sysdata; ebusnd = cookie->prom_node; ebus->next = ebus_alloc(sizeof(struct linux_ebus)); ebus = ebus->next; ebus->next = 0; ++num_ebus; } #ifdef CONFIG_SUN_AUXIO auxio_probe(); #endif clock_probe(); power_init(); }
void __init sbus_init(void) { int nd, this_sbus, sbus_devs, topnd, iommund; unsigned int sbus_clock; struct sbus_bus *sbus; struct sbus_dev *this_dev; int num_sbus = 0; /* How many did we find? */ #ifndef __sparc_v9__ register_proc_sparc_ioport(); #endif #ifdef CONFIG_SUN4 return sun4_dvma_init(); #endif topnd = prom_getchild(prom_root_node); /* Finding the first sbus is a special case... */ iommund = 0; if(sparc_cpu_model == sun4u) { nd = prom_searchsiblings(topnd, "sbus"); if(nd == 0) { #ifdef CONFIG_PCI if (!pcibios_present()) { prom_printf("Neither SBUS nor PCI found.\n"); prom_halt(); } else { #ifdef __sparc_v9__ firetruck_init(); #endif } return; #else prom_printf("YEEE, UltraSparc sbus not found\n"); prom_halt(); #endif } } else if(sparc_cpu_model == sun4d) { if((iommund = prom_searchsiblings(topnd, "io-unit")) == 0 || (nd = prom_getchild(iommund)) == 0 || (nd = prom_searchsiblings(nd, "sbi")) == 0) { panic("sbi not found"); } } else if((nd = prom_searchsiblings(topnd, "sbus")) == 0) { if((iommund = prom_searchsiblings(topnd, "iommu")) == 0 || (nd = prom_getchild(iommund)) == 0 || (nd = prom_searchsiblings(nd, "sbus")) == 0) { #ifdef CONFIG_PCI if (!pcibios_present()) { prom_printf("Neither SBUS nor PCI found.\n"); prom_halt(); } return; #else /* No reason to run further - the data access trap will occur. */ panic("sbus not found"); #endif } } /* Ok, we've found the first one, allocate first SBus struct * and place in chain. */ sbus = sbus_root = kmalloc(sizeof(struct sbus_bus), GFP_ATOMIC); sbus->next = NULL; sbus->prom_node = nd; this_sbus = nd; if(iommund && sparc_cpu_model != sun4u && sparc_cpu_model != sun4d) iommu_init(iommund, sbus); /* Loop until we find no more SBUS's */ while(this_sbus) { #ifdef __sparc_v9__ /* IOMMU hides inside SBUS/SYSIO prom node on Ultra. */ if(sparc_cpu_model == sun4u) { extern void sbus_iommu_init(int prom_node, struct sbus_bus *sbus); sbus_iommu_init(this_sbus, sbus); } #endif #ifndef __sparc_v9__ if (sparc_cpu_model == sun4d) iounit_init(this_sbus, iommund, sbus); #endif printk("sbus%d: ", num_sbus); sbus_clock = prom_getint(this_sbus, "clock-frequency"); if(sbus_clock == -1) sbus_clock = (25*1000*1000); printk("Clock %d.%d MHz\n", (int) ((sbus_clock/1000)/1000), (int) (((sbus_clock/1000)%1000 != 0) ? (((sbus_clock/1000)%1000) + 1000) : 0)); prom_getstring(this_sbus, "name", sbus->prom_name, sizeof(sbus->prom_name)); sbus->clock_freq = sbus_clock; #ifndef __sparc_v9__ if (sparc_cpu_model == sun4d) { sbus->devid = prom_getint(iommund, "device-id"); sbus->board = prom_getint(iommund, "board#"); } #endif sbus_bus_ranges_init(iommund, sbus); sbus_devs = prom_getchild(this_sbus); if (!sbus_devs) { sbus->devices = NULL; goto next_bus; } sbus->devices = kmalloc(sizeof(struct sbus_dev), GFP_ATOMIC); this_dev = sbus->devices; this_dev->next = NULL; this_dev->bus = sbus; this_dev->parent = NULL; fill_sbus_device(sbus_devs, this_dev); /* Should we traverse for children? */ if(prom_getchild(sbus_devs)) { /* Allocate device node */ this_dev->child = kmalloc(sizeof(struct sbus_dev), GFP_ATOMIC); /* Fill it */ this_dev->child->bus = sbus; this_dev->child->next = 0; fill_sbus_device(prom_getchild(sbus_devs), this_dev->child); sbus_do_child_siblings(prom_getchild(sbus_devs), this_dev->child, this_dev, sbus); } else { this_dev->child = NULL; } while((sbus_devs = prom_getsibling(sbus_devs)) != 0) { /* Allocate device node */ this_dev->next = kmalloc(sizeof(struct sbus_dev), GFP_ATOMIC); this_dev = this_dev->next; this_dev->next = NULL; /* Fill it */ this_dev->bus = sbus; this_dev->parent = NULL; fill_sbus_device(sbus_devs, this_dev); /* Is there a child node hanging off of us? */ if(prom_getchild(sbus_devs)) { /* Get new device struct */ this_dev->child = kmalloc(sizeof(struct sbus_dev), GFP_ATOMIC); /* Fill it */ this_dev->child->bus = sbus; this_dev->child->next = 0; fill_sbus_device(prom_getchild(sbus_devs), this_dev->child); sbus_do_child_siblings(prom_getchild(sbus_devs), this_dev->child, this_dev, sbus); } else { this_dev->child = NULL; } } /* Walk all devices and apply parent ranges. */ sbus_fixup_all_regs(sbus->devices); dvma_init(sbus); next_bus: num_sbus++; if(sparc_cpu_model == sun4u) { this_sbus = prom_getsibling(this_sbus); if(!this_sbus) break; this_sbus = prom_searchsiblings(this_sbus, "sbus"); } else if(sparc_cpu_model == sun4d) { iommund = prom_getsibling(iommund); if(!iommund) break; iommund = prom_searchsiblings(iommund, "io-unit"); if(!iommund) break; this_sbus = prom_searchsiblings(prom_getchild(iommund), "sbi"); } else { this_sbus = prom_getsibling(this_sbus); if(!this_sbus) break; this_sbus = prom_searchsiblings(this_sbus, "sbus"); } if(this_sbus) { sbus->next = kmalloc(sizeof(struct sbus_bus), GFP_ATOMIC); sbus = sbus->next; sbus->next = NULL; sbus->prom_node = this_sbus; } else { break; } } /* while(this_sbus) */ if (sparc_cpu_model == sun4d) { extern void sun4d_init_sbi_irq(void); sun4d_init_sbi_irq(); } rs_init(); #ifdef __sparc_v9__ if (sparc_cpu_model == sun4u) { firetruck_init(); } #endif #ifdef CONFIG_SUN_AUXIO if (sparc_cpu_model == sun4u) auxio_probe (); #endif #ifdef __sparc_v9__ if (sparc_cpu_model == sun4u) { extern void clock_probe(void); clock_probe(); } #endif }