/* * Initialize handlers for the set of interrupts caused by hardware errors * and power system events. */ void init_ras_IRQ(void) { struct device_node *np; unsigned int *ireg, len, i; if((np = find_path_device("/event-sources/internal-errors")) && (ireg = (unsigned int *)get_property(np, "open-pic-interrupt", &len))) { for(i=0; i<(len / sizeof(*ireg)); i++) { request_irq(virt_irq_create_mapping(*(ireg)) + NUM_8259_INTERRUPTS, &ras_error_interrupt, 0, "RAS_ERROR", NULL); ireg++; } } if((np = find_path_device("/event-sources/epow-events")) && (ireg = (unsigned int *)get_property(np, "open-pic-interrupt", &len))) { for(i=0; i<(len / sizeof(*ireg)); i++) { request_irq(virt_irq_create_mapping(*(ireg)) + NUM_8259_INTERRUPTS, &ras_epow_interrupt, 0, "RAS_EPOW", NULL); ireg++; } } }
int chrp_get_cpuinfo(char *buffer) { int i, len, sdramen; unsigned int t; struct device_node *root; const char *model = ""; root = find_path_device("/"); if (root) model = get_property(root, "model", NULL); len = sprintf(buffer,"machine\t\t: CHRP %s\n", model); /* longtrail (goldengate) stuff */ if ( !strncmp( model, "IBM,LongTrail", 9 ) ) { /* VLSI VAS96011/12 `Golden Gate 2' */ /* Memory banks */ sdramen = (in_le32((unsigned *)(GG2_PCI_CONFIG_BASE+ GG2_PCI_DRAM_CTRL)) >>31) & 1; for (i = 0; i < (sdramen ? 4 : 6); i++) { t = in_le32((unsigned *)(GG2_PCI_CONFIG_BASE+ GG2_PCI_DRAM_BANK0+ i*4)); if (!(t & 1)) continue; switch ((t>>8) & 0x1f) { case 0x1f: model = "4 MB"; break; case 0x1e: model = "8 MB"; break; case 0x1c: model = "16 MB"; break; case 0x18: model = "32 MB"; break; case 0x10: model = "64 MB"; break; case 0x00: model = "128 MB"; break; default: model = "Reserved"; break; } len += sprintf(buffer+len, "memory bank %d\t: %s %s\n", i, model, gg2_memtypes[sdramen ? 1 : ((t>>1) & 3)]); } /* L2 cache */ t = in_le32((unsigned *)(GG2_PCI_CONFIG_BASE+GG2_PCI_CC_CTRL)); len += sprintf(buffer+len, "board l2\t: %s %s (%s)\n", gg2_cachesizes[(t>>7) & 3], gg2_cachetypes[(t>>2) & 3], gg2_cachemodes[t & 3]); }
static int get_eventscan_parms(void) { struct device_node *node; int *ip; node = find_path_device("/rtas"); ip = (int *)get_property(node, "rtas-event-scan-rate", NULL); if (ip == NULL) { printk(KERN_ERR "rtasd: no rtas-event-scan-rate\n"); return -1; } rtas_event_scan_rate = *ip; DEBUG("rtas-event-scan-rate %d\n", rtas_event_scan_rate); ip = (int *)get_property(node, "rtas-error-log-max", NULL); if (ip == NULL) { printk(KERN_ERR "rtasd: no rtas-error-log-max\n"); return -1; } rtas_error_log_max = *ip; DEBUG("rtas-error-log-max %d\n", rtas_error_log_max); if (rtas_error_log_max > RTAS_ERROR_LOG_MAX) { printk(KERN_ERR "rtasd: truncated error log from %d to %d bytes\n", rtas_error_log_max, RTAS_ERROR_LOG_MAX); rtas_error_log_max = RTAS_ERROR_LOG_MAX; } return 0; }
/* This is called early in setup.c. * Use it to setup page table ppc_md stuff as well as udbg. */ void pSeriesLP_init_early(void) { pSeries_lpar_mm_init(); ppc_md.tce_build = tce_build_pSeriesLP; ppc_md.tce_free_one = tce_free_one_pSeriesLP; #ifdef CONFIG_SMP smp_init_pSeries(); #endif pSeries_pcibios_init_early(); /* The keyboard is not useful in the LPAR environment. * Leave all the interfaces NULL. */ /* lookup the first virtual terminal number in case we don't have a com port. * Zero is probably correct in case someone calls udbg before the init. * The property is a pair of numbers. The first is the starting termno (the * one we use) and the second is the number of terminals. */ u32 *termno; struct device_node *np = find_path_device("/rtas"); if (np) { termno = (u32 *)get_property(np, "ibm,termno", 0); if (termno) vtermno = termno[0]; } ppc_md.udbg_putc = udbg_putcLP; ppc_md.udbg_getc = udbg_getcLP; ppc_md.udbg_getc_poll = udbg_getc_pollLP; }
/* * Indicates whether the root node has a given value in its * compatible property. */ int machine_is_compatible(const char *compat) { struct device_node *root; root = find_path_device("/"); if (root == 0) return 0; return device_is_compatible(root, compat); }
static int __init briq_panel_init(void) { struct device_node *root = find_path_device("/"); const char *machine; int i; machine = get_property(root, "model", NULL); if (!machine || strncmp(machine, "TotalImpact,BRIQ-1", 18) != 0) return -ENODEV; printk(KERN_INFO "briq_panel: v%s Dr. Karsten Jeppesen ([email protected])\n", BRIQ_PANEL_VER); if (!request_region(BRIQ_PANEL_VFD_IOPORT, 4, "BRIQ Front Panel")) return -EBUSY; if (!request_region(BRIQ_PANEL_LED_IOPORT, 2, "BRIQ Front Panel")) { release_region(BRIQ_PANEL_VFD_IOPORT, 4); return -EBUSY; } ledpb = inb(BRIQ_PANEL_LED_IOPORT) & 0x000c; if (misc_register(&briq_panel_miscdev) < 0) { release_region(BRIQ_PANEL_VFD_IOPORT, 4); release_region(BRIQ_PANEL_LED_IOPORT, 2); return -EBUSY; } outb(0x38, BRIQ_PANEL_VFD_IOPORT); /* Function set */ outb(0x01, BRIQ_PANEL_VFD_IOPORT); /* Clear display */ outb(0x0c, BRIQ_PANEL_VFD_IOPORT); /* Display on */ outb(0x06, BRIQ_PANEL_VFD_IOPORT); /* Entry normal */ for (i=0; i<40; i++) vfd[i]=' '; #ifndef MODULE vfd[0] = 'L'; vfd[1] = 'o'; vfd[2] = 'a'; vfd[3] = 'd'; vfd[4] = 'i'; vfd[5] = 'n'; vfd[6] = 'g'; vfd[7] = ' '; vfd[8] = '.'; vfd[9] = '.'; vfd[10] = '.'; #endif /* !MODULE */ update_vfd(); return 0; }
static int mambonet_probedev(int devno, void *buf) { struct device_node *mambo; struct device_node *net; unsigned int *reg; mambo = find_path_device("/mambo"); if (mambo == NULL) { return -1; } net = find_path_device("/mambo/bogus-net@0"); if (net == NULL) { return -1; } reg = (unsigned int *)get_property(net, "reg", 0); if (*reg != devno) { return -1; } return MamboBogusNetProbe(devno, buf); }
/* Marvell Discovery II based Pegasos 2 */ static void __init setup_peg2(struct pci_controller *hose, struct device_node *dev) { struct device_node *root = find_path_device("/"); struct device_node *rtas; rtas = of_find_node_by_name (root, "rtas"); if (rtas) { hose->ops = &rtas_pci_ops; } else { printk ("RTAS supporting Pegasos OF not found, please upgrade" " your firmware\n"); } pci_assign_all_buses = 1; }
int hvc_count(int *start_termno) { u32 *termno; struct device_node *dn; if ((dn = find_path_device("/rtas")) != NULL) { if ((termno = (u32 *)get_property(dn, "ibm,termno", 0)) != NULL) { if (start_termno) *start_termno = termno[0]; return termno[1]; } } return 0; }
/* * Called on initialization to set up the /proc/device-tree subtree */ void proc_device_tree_init(void) { struct device_node *root; if ( !have_of ) return; proc_device_tree = proc_mkdir("device-tree", 0); if (proc_device_tree == 0) return; root = find_path_device("/"); if (root == 0) { printk(KERN_ERR "/proc/device-tree: can't find root\n"); return; } add_node(root, proc_device_tree); }
static int __init smt_setup(void) { struct device_node *options; const unsigned int *val; unsigned int cpu; if (!cpu_has_feature(CPU_FTR_SMT)) return -ENODEV; options = find_path_device("/options"); if (!options) return -ENODEV; val = of_get_property(options, "ibm,smt-snooze-delay", NULL); if (!smt_snooze_cmdline && val) { for_each_possible_cpu(cpu) per_cpu(smt_snooze_delay, cpu) = *val; } return 0; }
static void gather_partition_info(void) { struct device_node *rootdn; const char *ppartition_name; const unsigned int *p_number_ptr; /* Retrieve information about this partition */ rootdn = find_path_device("/"); if (!rootdn) { return; } ppartition_name = get_property(rootdn, "ibm,partition-name", NULL); if (ppartition_name) strncpy(partition_name, ppartition_name, sizeof(partition_name)); p_number_ptr = get_property(rootdn, "ibm,partition-no", NULL); if (p_number_ptr) partition_number = *p_number_ptr; }
/****************************************************************** * Find all PHBs in the system and initialize a set of data * structures to represent them. ******************************************************************/ unsigned long __init find_and_init_phbs(void) { struct device_node *Pci_Node; struct pci_controller *phb; unsigned int root_addr_size_words = 0, this_addr_size_words = 0; unsigned int this_addr_count = 0, range_stride; unsigned int *ui_ptr = NULL, *ranges; char *model; struct pci_range64 range; struct resource *res; unsigned int memno, rlen, i, index; unsigned int *opprop; int has_isa = 0; PPCDBG(PPCDBG_PHBINIT, "find_and_init_phbs\n"); read_pci_config = rtas_token("read-pci-config"); write_pci_config = rtas_token("write-pci-config"); ibm_read_pci_config = rtas_token("ibm,read-pci-config"); ibm_write_pci_config = rtas_token("ibm,write-pci-config"); if (naca->interrupt_controller == IC_OPEN_PIC) { opprop = (unsigned int *)get_property(find_path_device("/"), "platform-open-pic", NULL); } /* Get the root address word size. */ ui_ptr = (unsigned int *) get_property(find_path_device("/"), "#size-cells", NULL); if (ui_ptr) { root_addr_size_words = *ui_ptr; } else { PPCDBG(PPCDBG_PHBINIT, "\tget #size-cells failed.\n"); return(-1); } if (find_type_devices("isa")) { has_isa = 1; PPCDBG(PPCDBG_PHBINIT, "\tFound an ISA bus.\n"); } index = 0; /****************************************************************** * Find all PHB devices and create an object for them. ******************************************************************/ for (Pci_Node = find_devices("pci"); Pci_Node != NULL; Pci_Node = Pci_Node->next) { model = (char *) get_property(Pci_Node, "model", NULL); if (model != NULL) { phb = alloc_phb(Pci_Node, model, root_addr_size_words); if (phb == NULL) return(-1); } else { continue; } /* Get this node's address word size. */ ui_ptr = (unsigned int *) get_property(Pci_Node, "#size-cells", NULL); if (ui_ptr) this_addr_size_words = *ui_ptr; else this_addr_size_words = 1; /* Get this node's address word count. */ ui_ptr = (unsigned int *) get_property(Pci_Node, "#address-cells", NULL); if (ui_ptr) this_addr_count = *ui_ptr; else this_addr_count = 3; range_stride = this_addr_count + root_addr_size_words + this_addr_size_words; memno = 0; phb->io_base_phys = 0; ranges = (unsigned int *) get_property(Pci_Node, "ranges", &rlen); PPCDBG(PPCDBG_PHBINIT, "\trange_stride = 0x%lx, rlen = 0x%x\n", range_stride, rlen); for (i = 0; i < (rlen/sizeof(*ranges)); i+=range_stride) { /* Put the PCI addr part of the current element into a * '64' struct. */ range = *((struct pci_range64 *)(ranges + i)); /* If this is a '32' element, map into a 64 struct. */ if ((range_stride * sizeof(int)) == sizeof(struct pci_range32)) { range.parent_addr = (unsigned long)(*(ranges + i + 3)); range.size = (((unsigned long)(*(ranges + i + 4)))<<32) | (*(ranges + i + 5)); } else { range.parent_addr = (((unsigned long)(*(ranges + i + 3)))<<32) | (*(ranges + i + 4)); range.size = (((unsigned long)(*(ranges + i + 5)))<<32) | (*(ranges + i + 6)); } PPCDBG(PPCDBG_PHBINIT, "\trange.parent_addr = 0x%lx\n", range.parent_addr); PPCDBG(PPCDBG_PHBINIT, "\trange.child_addr.hi = 0x%lx\n", range.child_addr.a_hi); PPCDBG(PPCDBG_PHBINIT, "\trange.child_addr.mid = 0x%lx\n", range.child_addr.a_mid); PPCDBG(PPCDBG_PHBINIT, "\trange.child_addr.lo = 0x%lx\n", range.child_addr.a_lo); PPCDBG(PPCDBG_PHBINIT, "\trange.size = 0x%lx\n", range.size); res = NULL; switch ((range.child_addr.a_hi >> 24) & 0x3) { case 1: /* I/O space */ PPCDBG(PPCDBG_PHBINIT, "\tIO Space\n"); phb->io_base_phys = range.parent_addr; res = &phb->io_resource; res->name = Pci_Node->full_name; res->flags = IORESOURCE_IO; phb->io_base_virt = __ioremap(phb->io_base_phys, range.size, _PAGE_NO_CACHE); if (!pci_io_base) { pci_io_base = (unsigned long)phb->io_base_virt; if (has_isa) isa_io_base = pci_io_base; } res->start = ((((unsigned long) range.child_addr.a_mid) << 32) | (range.child_addr.a_lo)); res->start += (unsigned long)phb->io_base_virt - pci_io_base; res->end = res->start + range.size - 1; res->parent = NULL; res->sibling = NULL; res->child = NULL; phb->pci_io_offset = range.parent_addr - ((((unsigned long) range.child_addr.a_mid) << 32) | (range.child_addr.a_lo)); PPCDBG(PPCDBG_PHBINIT, "\tpci_io_offset = 0x%lx\n", phb->pci_io_offset); break; case 2: /* mem space */ PPCDBG(PPCDBG_PHBINIT, "\tMem Space\n"); phb->pci_mem_offset = range.parent_addr - ((((unsigned long) range.child_addr.a_mid) << 32) | (range.child_addr.a_lo)); PPCDBG(PPCDBG_PHBINIT, "\tpci_mem_offset = 0x%lx\n", phb->pci_mem_offset); if (memno < sizeof(phb->mem_resources)/sizeof(phb->mem_resources[0])) { res = &(phb->mem_resources[memno]); ++memno; res->name = Pci_Node->full_name; res->flags = IORESOURCE_MEM; res->start = range.parent_addr; res->end = range.parent_addr + range.size - 1; res->parent = NULL; res->sibling = NULL; res->child = NULL; } break; } } PPCDBG(PPCDBG_PHBINIT, "\tphb->io_base_phys = 0x%lx\n", phb->io_base_phys); PPCDBG(PPCDBG_PHBINIT, "\tphb->pci_mem_offset = 0x%lx\n", phb->pci_mem_offset); if (naca->interrupt_controller == IC_OPEN_PIC) { int addr = root_addr_size_words * (index + 2) - 1; openpic_setup_ISU(index, opprop[addr]); } index++; } pci_devs_phb_init(); return 0; /*Success */ }
void __init chrp_find_bridges(void) { struct device_node *dev; int *bus_range; int len, index = -1; struct pci_controller *hose; volatile unsigned char *cfg; unsigned int *dma; char *model, *machine; int is_longtrail = 0, is_mot = 0; struct device_node *root = find_path_device("/"); #ifdef CONFIG_POWER3 unsigned int *opprop = (unsigned int *) get_property(root, "platform-open-pic", NULL); int i; #endif /* * The PCI host bridge nodes on some machines don't have * properties to adequately identify them, so we have to * look at what sort of machine this is as well. */ machine = get_property(root, "model", NULL); if (machine != NULL) { is_longtrail = strncmp(machine, "IBM,LongTrail", 13) == 0; is_mot = strncmp(machine, "MOT", 3) == 0; } for (dev = root->child; dev != NULL; dev = dev->sibling) { if (dev->type == NULL || strcmp(dev->type, "pci") != 0) continue; ++index; /* The GG2 bridge on the LongTrail doesn't have an address */ if (dev->n_addrs < 1 && !is_longtrail) { printk(KERN_WARNING "Can't use %s: no address\n", dev->full_name); continue; } bus_range = (int *) get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { printk(KERN_WARNING "Can't get bus-range for %s\n", dev->full_name); continue; } if (bus_range[1] == bus_range[0]) printk(KERN_INFO "PCI bus %d", bus_range[0]); else printk(KERN_INFO "PCI buses %d..%d", bus_range[0], bus_range[1]); printk(" controlled by %s", dev->type); if (dev->n_addrs > 0) printk(" at %x", dev->addrs[0].address); printk("\n"); hose = pcibios_alloc_controller(); if (!hose) { printk("Can't allocate PCI controller structure for %s\n", dev->full_name); continue; } hose->arch_data = dev; hose->first_busno = bus_range[0]; hose->last_busno = bus_range[1]; model = get_property(dev, "model", NULL); if (model == NULL) model = "<none>"; if (device_is_compatible(dev, "IBM,python")) { hose->ops = &python_pci_ops; cfg = ioremap(dev->addrs[0].address + 0xf8000, 0x20); hose->cfg_addr = (volatile unsigned int *) cfg; hose->cfg_data = cfg + 0x10; } else if (is_mot || strncmp(model, "Motorola, Grackle", 17) == 0) { setup_grackle(hose); } else if (is_longtrail) { hose->ops = &gg2_pci_ops; gg2_pci_config_base = (unsigned long) ioremap(GG2_PCI_CONFIG_BASE, 0x80000); } else { printk("No methods for %s (model %s), using RTAS\n", dev->full_name, model); hose->ops = &rtas_pci_ops; } pci_process_bridge_OF_ranges(hose, dev, index == 0); #ifdef CONFIG_POWER3 if (opprop != NULL) { i = prom_n_addr_cells(root) * (index + 2) - 1; openpic_setup_ISU(index, opprop[i]); } #endif /* CONFIG_POWER3 */ /* check the first bridge for a property that we can use to set pci_dram_offset */ dma = (unsigned int *) get_property(dev, "ibm,dma-ranges", &len); if (index == 0 && dma != NULL && len >= 6 * sizeof(*dma)) { pci_dram_offset = dma[2] - dma[3]; printk("pci_dram_offset = %lx\n", pci_dram_offset); } } ppc_md.pcibios_fixup = chrp_pcibios_fixup; }
void __init chrp_find_bridges(void) { struct device_node *dev; int *bus_range; int len, index = -1; struct pci_controller *hose; unsigned int *dma; char *model, *machine; int is_longtrail = 0, is_mot = 0, is_pegasos = 0; struct device_node *root = find_path_device("/"); /* * The PCI host bridge nodes on some machines don't have * properties to adequately identify them, so we have to * look at what sort of machine this is as well. */ machine = get_property(root, "model", NULL); if (machine != NULL) { is_longtrail = strncmp(machine, "IBM,LongTrail", 13) == 0; is_mot = strncmp(machine, "MOT", 3) == 0; if (strncmp(machine, "Pegasos2", 8) == 0) is_pegasos = 2; else if (strncmp(machine, "Pegasos", 7) == 0) is_pegasos = 1; } for (dev = root->child; dev != NULL; dev = dev->sibling) { if (dev->type == NULL || strcmp(dev->type, "pci") != 0) continue; ++index; /* The GG2 bridge on the LongTrail doesn't have an address */ if (dev->n_addrs < 1 && !is_longtrail) { printk(KERN_WARNING "Can't use %s: no address\n", dev->full_name); continue; } bus_range = (int *) get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { printk(KERN_WARNING "Can't get bus-range for %s\n", dev->full_name); continue; } if (bus_range[1] == bus_range[0]) printk(KERN_INFO "PCI bus %d", bus_range[0]); else printk(KERN_INFO "PCI buses %d..%d", bus_range[0], bus_range[1]); printk(" controlled by %s", dev->type); if (dev->n_addrs > 0) printk(" at %lx", dev->addrs[0].address); printk("\n"); hose = pcibios_alloc_controller(); if (!hose) { printk("Can't allocate PCI controller structure for %s\n", dev->full_name); continue; } hose->arch_data = dev; hose->first_busno = bus_range[0]; hose->last_busno = bus_range[1]; model = get_property(dev, "model", NULL); if (model == NULL) model = "<none>"; if (device_is_compatible(dev, "IBM,python")) { setup_python(hose, dev); } else if (is_mot || strncmp(model, "Motorola, Grackle", 17) == 0) { setup_grackle(hose); } else if (is_longtrail) { void __iomem *p = ioremap(GG2_PCI_CONFIG_BASE, 0x80000); hose->ops = &gg2_pci_ops; hose->cfg_data = p; gg2_pci_config_base = p; } else if (is_pegasos == 1) { setup_indirect_pci(hose, 0xfec00cf8, 0xfee00cfc); } else if (is_pegasos == 2) { setup_peg2(hose, dev); } else { printk("No methods for %s (model %s), using RTAS\n", dev->full_name, model); hose->ops = &rtas_pci_ops; } pci_process_bridge_OF_ranges(hose, dev, index == 0); /* check the first bridge for a property that we can use to set pci_dram_offset */ dma = (unsigned int *) get_property(dev, "ibm,dma-ranges", &len); if (index == 0 && dma != NULL && len >= 6 * sizeof(*dma)) { pci_dram_offset = dma[2] - dma[3]; printk("pci_dram_offset = %lx\n", pci_dram_offset); } } /* Do not fixup interrupts from OF tree on pegasos */ if (is_pegasos == 0) ppc_md.pcibios_fixup = chrp_pcibios_fixup; }