void __init efika_pcisetup(void) { const int *bus_range; int len; struct pci_controller *hose; struct device_node *root; struct device_node *pcictrl; root = of_find_node_by_path("/"); if (root == NULL) { printk(KERN_WARNING EFIKA_PLATFORM_NAME ": Unable to find the root node\n"); return; } for (pcictrl = NULL;;) { pcictrl = of_get_next_child(root, pcictrl); if ((pcictrl == NULL) || (strcmp(pcictrl->name, "pci") == 0)) break; } of_node_put(root); if (pcictrl == NULL) { printk(KERN_WARNING EFIKA_PLATFORM_NAME ": Unable to find the PCI bridge node\n"); return; } bus_range = of_get_property(pcictrl, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { printk(KERN_WARNING EFIKA_PLATFORM_NAME ": Can't get bus-range for %s\n", pcictrl->full_name); return; } if (bus_range[1] == bus_range[0]) printk(KERN_INFO EFIKA_PLATFORM_NAME ": PCI bus %d", bus_range[0]); else printk(KERN_INFO EFIKA_PLATFORM_NAME ": PCI buses %d..%d", bus_range[0], bus_range[1]); printk(" controlled by %s\n", pcictrl->full_name); printk("\n"); hose = pcibios_alloc_controller(); if (!hose) { printk(KERN_WARNING EFIKA_PLATFORM_NAME ": Can't allocate PCI controller structure for %s\n", pcictrl->full_name); return; } hose->arch_data = of_node_get(pcictrl); hose->first_busno = bus_range[0]; hose->last_busno = bus_range[1]; hose->ops = &rtas_pci_ops; pci_process_bridge_OF_ranges(hose, pcictrl, 0); }
static int __init linkstation_add_bridge(struct device_node *dev) { #ifdef CONFIG_PCI int len; struct pci_controller *hose; const int *bus_range; printk("Adding PCI host bridge %s\n", dev->full_name); bus_range = of_get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) printk(KERN_WARNING "Can't get bus-range for %s, assume" " bus 0\n", dev->full_name); hose = pcibios_alloc_controller(dev); if (hose == NULL) return -ENOMEM; hose->first_busno = bus_range ? bus_range[0] : 0; hose->last_busno = bus_range ? bus_range[1] : 0xff; setup_indirect_pci(hose, 0xfec00000, 0xfee00000, 0); /* Interpret the "ranges" property */ /* This also maps the I/O region and sets isa_io/mem_base */ pci_process_bridge_OF_ranges(hose, dev, 1); #endif return 0; }
static int __init amigaone_add_bridge(struct device_node *dev) { const u32 *cfg_addr, *cfg_data; int len; const int *bus_range; struct pci_controller *hose; printk(KERN_INFO "Adding PCI host bridge %s\n", dev->full_name); cfg_addr = of_get_address(dev, 0, NULL, NULL); cfg_data = of_get_address(dev, 1, NULL, NULL); if ((cfg_addr == NULL) || (cfg_data == NULL)) return -ENODEV; bus_range = of_get_property(dev, "bus-range", &len); if ((bus_range == NULL) || (len < 2 * sizeof(int))) printk(KERN_WARNING "Can't get bus-range for %s, assume" " bus 0\n", dev->full_name); hose = pcibios_alloc_controller(dev); if (hose == NULL) return -ENOMEM; hose->first_busno = bus_range ? bus_range[0] : 0; hose->last_busno = bus_range ? bus_range[1] : 0xff; setup_indirect_pci(hose, cfg_addr[0], cfg_data[0], 0); /* Interpret the "ranges" property */ /* This also maps the I/O region and sets isa_io/mem_base */ pci_process_bridge_OF_ranges(hose, dev, 1); return 0; }
static int __init storcenter_add_bridge(struct device_node *dev) { #ifdef CONFIG_PCI int len; struct pci_controller *hose; const int *bus_range; printk("Adding PCI host bridge %s\n", dev->full_name); hose = pcibios_alloc_controller(dev); if (hose == NULL) return -ENOMEM; bus_range = of_get_property(dev, "bus-range", &len); hose->first_busno = bus_range ? bus_range[0] : 0; hose->last_busno = bus_range ? bus_range[1] : 0xff; setup_indirect_pci(hose, MPC10X_MAPB_CNFG_ADDR, MPC10X_MAPB_CNFG_DATA, 0); /* Interpret the "ranges" property */ /* This also maps the I/O region and sets isa_io/mem_base */ pci_process_bridge_OF_ranges(hose, dev, 1); #endif return 0; }
static int of_pci_phb_probe(struct platform_device *dev) { struct pci_controller *phb; /* Check if we can do that ... */ if (ppc_md.pci_setup_phb == NULL) return -ENODEV; pr_info("Setting up PCI bus %s\n", dev->dev.of_node->full_name); /* Alloc and setup PHB data structure */ phb = pcibios_alloc_controller(dev->dev.of_node); if (!phb) return -ENODEV; /* Setup parent in sysfs */ phb->parent = &dev->dev; /* Setup the PHB using arch provided callback */ if (ppc_md.pci_setup_phb(phb)) { pcibios_free_controller(phb); return -ENODEV; } /* Process "ranges" property */ pci_process_bridge_OF_ranges(phb, dev->dev.of_node, 0); /* Init pci_dn data structures */ pci_devs_phb_init_dynamic(phb); /* Create EEH devices for the PHB */ eeh_dev_phb_init_dynamic(phb); /* Register devices with EEH */ if (dev->dev.of_node->child) eeh_add_device_tree_early(dev->dev.of_node); /* Scan the bus */ pcibios_scan_phb(phb); if (phb->bus == NULL) return -ENXIO; /* Claim resources. This might need some rework as well depending * whether we are doing probe-only or not, like assigning unassigned * resources etc... */ pcibios_claim_one_bus(phb->bus); /* Finish EEH setup */ eeh_add_device_tree_late(phb->bus); /* Add probed PCI devices to the device model */ pci_bus_add_devices(phb->bus); /* sysfs files should only be added after devices are added */ eeh_add_sysfs_files(phb->bus); return 0; }
int __init add_bridge(struct device_node *dev) { int len; struct pci_controller *hose; struct resource rsrc; const int *bus_range; int primary = 1, has_address = 0; phys_addr_t immr = get_immrbase(); DBG("Adding PCI host bridge %s\n", dev->full_name); /* Fetch host bridge registers address */ has_address = (of_address_to_resource(dev, 0, &rsrc) == 0); /* Get bus range if any */ bus_range = get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { printk(KERN_WARNING "Can't get bus-range for %s, assume" " bus 0\n", dev->full_name); } hose = pcibios_alloc_controller(); if (!hose) return -ENOMEM; hose->arch_data = dev; hose->set_cfg_type = 1; hose->first_busno = bus_range ? bus_range[0] : 0; hose->last_busno = bus_range ? bus_range[1] : 0xff; /* MPC83xx supports up to two host controllers one at 0x8500 from immrbar * the other at 0x8600, we consider the 0x8500 the primary controller */ /* PCI 1 */ if ((rsrc.start & 0xfffff) == 0x8500) { setup_indirect_pci(hose, immr + 0x8300, immr + 0x8304); } /* PCI 2 */ if ((rsrc.start & 0xfffff) == 0x8600) { setup_indirect_pci(hose, immr + 0x8380, immr + 0x8384); primary = 0; hose->bus_offset = hose->first_busno; mpc83xx_pci2_busno = hose->first_busno; } printk(KERN_INFO "Found MPC83xx PCI host bridge at 0x%016llx. " "Firmware bus number: %d->%d\n", (unsigned long long)rsrc.start, hose->first_busno, hose->last_busno); DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", hose, hose->cfg_addr, hose->cfg_data); /* Interpret the "ranges" property */ /* This also maps the I/O region and sets isa_io/mem_base */ pci_process_bridge_OF_ranges(hose, dev, primary); return 0; }
/** * xilinx_pci_init - Find and register a Xilinx PCI host bridge */ void __init xilinx_pci_init(void) { struct pci_controller *hose; struct resource r; void __iomem *pci_reg; struct device_node *pci_node; pci_node = of_find_matching_node(NULL, xilinx_pci_match); if(!pci_node) return; if (of_address_to_resource(pci_node, 0, &r)) { pr_err("xilinx-pci: cannot resolve base address\n"); return; } hose = pcibios_alloc_controller(pci_node); if (!hose) { pr_err("xilinx-pci: pcibios_alloc_controller() failed\n"); return; } /* Setup config space */ setup_indirect_pci(hose, r.start + XPLB_PCI_ADDR, r.start + XPLB_PCI_DATA, PPC_INDIRECT_TYPE_SET_CFG_TYPE); /* According to the xilinx plbv46_pci documentation the soft-core starts * a self-init when the bus master enable bit is set. Without this bit * set the pci bus can't be scanned. */ early_write_config_word(hose, 0, 0, PCI_COMMAND, PCI_HOST_ENABLE_CMD); /* Set the max latency timer to 255 */ early_write_config_byte(hose, 0, 0, PCI_LATENCY_TIMER, 0xff); /* Set the max bus number to 255 */ pci_reg = of_iomap(pci_node, 0); out_8(pci_reg + XPLB_PCI_BUS, 0xff); iounmap(pci_reg); /* Nothing past the root bridge is working right now. By default * exclude config access to anything except bus 0 */ if (!ppc_md.pci_exclude_device) ppc_md.pci_exclude_device = xilinx_pci_exclude_device; /* Register the host bridge with the linux kernel! */ pci_process_bridge_OF_ranges(hose, pci_node, 1); pr_info("xilinx-pci: Registered PCI host bridge\n"); }
static void __init cell_add_phb(struct device_node *node, int index) { struct pci_controller *phb; struct resource r; phb = pcibios_alloc_controller(node); if (!phb) return; setup_phb(node, phb); if (of_address_to_resource(node, 0, &r) == 0) phb->buid = r.start; pci_process_bridge_OF_ranges(phb, node, 0); pci_setup_phb_io(phb, index == 0); }
void __init find_and_init_phbs(void) { struct device_node *node; struct pci_controller *phb; struct device_node *root = of_find_node_by_path("/"); for_each_child_of_node(root, node) { if (node->type == NULL || (strcmp(node->type, "pci") != 0 && strcmp(node->type, "pciex") != 0)) continue; phb = pcibios_alloc_controller(node); if (!phb) continue; rtas_setup_phb(phb); pci_process_bridge_OF_ranges(phb, node, 0); isa_bridge_find_early(phb); } of_node_put(root); pci_devs_phb_init(); /* Create EEH devices for all PHBs */ eeh_dev_phb_init(); /* * PCI_PROBE_ONLY and PCI_REASSIGN_ALL_BUS can be set via properties * in chosen. */ if (of_chosen) { const int *prop; prop = of_get_property(of_chosen, "linux,pci-probe-only", NULL); if (prop) { if (*prop) pci_add_flags(PCI_PROBE_ONLY); else pci_clear_flags(PCI_PROBE_ONLY); } #ifdef CONFIG_PPC32 /* Will be made generic soon */ prop = of_get_property(of_chosen, "linux,pci-assign-all-buses", NULL); if (prop && *prop) pci_add_flags(PCI_REASSIGN_ALL_BUS); #endif /* CONFIG_PPC32 */ } }
unsigned long __init find_and_init_phbs(void) { struct device_node *node; struct pci_controller *phb; unsigned int index; struct device_node *root = of_find_node_by_path("/"); index = 0; for (node = of_get_next_child(root, NULL); node != NULL; node = of_get_next_child(root, node)) { if (node->type == NULL || (strcmp(node->type, "pci") != 0 && strcmp(node->type, "pciex") != 0)) continue; phb = pcibios_alloc_controller(node); if (!phb) continue; rtas_setup_phb(phb); pci_process_bridge_OF_ranges(phb, node, 0); pci_setup_phb_io(phb, index == 0); index++; } of_node_put(root); pci_devs_phb_init(); /* * pci_probe_only and pci_assign_all_buses can be set via properties * in chosen. */ if (of_chosen) { const int *prop; prop = get_property(of_chosen, "linux,pci-probe-only", NULL); if (prop) pci_probe_only = *prop; prop = get_property(of_chosen, "linux,pci-assign-all-buses", NULL); if (prop) pci_assign_all_buses = *prop; } return 0; }
void __init add_bridge(struct device_node *np) { int len; struct pci_controller *hose; struct resource r; const int *bus_range; const uint *ptr; memset(&r, 0, sizeof(r)); if (of_address_to_resource(np, 0, &r)) { printk(KERN_INFO "No PCI reg property in device tree\n"); return; } if (!(ptr = of_get_property(np, "clock-frequency", NULL))) { printk(KERN_INFO "No clock-frequency property in PCI node"); return; } pci_clk_frq = *ptr; of_node_put(np); bus_range = of_get_property(np, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { printk(KERN_WARNING "Can't get bus-range for %s, assume" " bus 0\n", np->full_name); } pci_assign_all_buses = 1; hose = pcibios_alloc_controller(); if (!hose) return; hose->arch_data = np; hose->set_cfg_type = 1; hose->first_busno = bus_range ? bus_range[0] : 0; hose->last_busno = bus_range ? bus_range[1] : 0xff; hose->bus_offset = 0; hose->set_cfg_type = 1; setup_indirect_pci(hose, r.start + offsetof(pci_cpm2_t, pci_cfg_addr), r.start + offsetof(pci_cpm2_t, pci_cfg_data)); pci_process_bridge_OF_ranges(hose, np, 1); }
int __init tsi108_setup_pci(struct device_node *dev) { int len; struct pci_controller *hose; struct resource rsrc; const int *bus_range; int primary = 0, has_address = 0; /* PCI Config mapping */ tsi108_pci_cfg_base = (u32)ioremap(TSI108_PCI_CFG_BASE_PHYS, TSI108_PCI_CFG_SIZE); DBG("TSI_PCI: %s tsi108_pci_cfg_base=0x%x\n", __FUNCTION__, tsi108_pci_cfg_base); /* Fetch host bridge registers address */ has_address = (of_address_to_resource(dev, 0, &rsrc) == 0); /* Get bus range if any */ bus_range = get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { printk(KERN_WARNING "Can't get bus-range for %s, assume" " bus 0\n", dev->full_name); } hose = pcibios_alloc_controller(); if (!hose) { printk("PCI Host bridge init failed\n"); return -ENOMEM; } hose->arch_data = dev; hose->set_cfg_type = 1; hose->first_busno = bus_range ? bus_range[0] : 0; hose->last_busno = bus_range ? bus_range[1] : 0xff; (hose)->ops = &tsi108_direct_pci_ops; printk(KERN_INFO "Found tsi108 PCI host bridge at 0x%08x. " "Firmware bus number: %d->%d\n", rsrc.start, hose->first_busno, hose->last_busno); /* Interpret the "ranges" property */ /* This also maps the I/O region and sets isa_io/mem_base */ pci_process_bridge_OF_ranges(hose, dev, primary); return 0; }
static int __init mv64x60_add_bridge(struct device_node *dev) { int len; struct pci_controller *hose; struct resource rsrc; const int *bus_range; int primary; memset(&rsrc, 0, sizeof(rsrc)); /* Fetch host bridge registers address */ if (of_address_to_resource(dev, 0, &rsrc)) { printk(KERN_ERR "No PCI reg property in device tree\n"); return -ENODEV; } /* Get bus range if any */ bus_range = of_get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) printk(KERN_WARNING "Can't get bus-range for %s, assume" " bus 0\n", dev->full_name); hose = pcibios_alloc_controller(dev); if (!hose) return -ENOMEM; hose->set_cfg_type = 1; hose->first_busno = bus_range ? bus_range[0] : 0; hose->last_busno = bus_range ? bus_range[1] : 0xff; setup_indirect_pci(hose, rsrc.start, rsrc.start + 4, 0); hose->bus_offset = hose->first_busno; printk(KERN_INFO "Found MV64x60 PCI host bridge at 0x%016llx. " "Firmware bus number: %d->%d\n", (unsigned long long)rsrc.start, hose->first_busno, hose->last_busno); /* Interpret the "ranges" property */ /* This also maps the I/O region and sets isa_io/mem_base */ primary = (hose->first_busno == 0); pci_process_bridge_OF_ranges(hose, dev, primary); return 0; }
int __init tsi108_setup_pci(struct device_node *dev, u32 cfg_phys, int primary) { int len; struct pci_controller *hose; struct resource rsrc; const int *bus_range; int has_address = 0; tsi108_pci_cfg_base = (u32)ioremap(cfg_phys, TSI108_PCI_CFG_SIZE); tsi108_pci_cfg_phys = cfg_phys; DBG("TSI_PCI: %s tsi108_pci_cfg_base=0x%x\n", __func__, tsi108_pci_cfg_base); has_address = (of_address_to_resource(dev, 0, &rsrc) == 0); bus_range = of_get_property(dev, "bus-range", &len); if (bus_range == NULL || len < 2 * sizeof(int)) { printk(KERN_WARNING "Can't get bus-range for %s, assume" " bus 0\n", dev->full_name); } hose = pcibios_alloc_controller(dev); if (!hose) { printk("PCI Host bridge init failed\n"); return -ENOMEM; } hose->first_busno = bus_range ? bus_range[0] : 0; hose->last_busno = bus_range ? bus_range[1] : 0xff; (hose)->ops = &tsi108_direct_pci_ops; printk(KERN_INFO "Found tsi108 PCI host bridge at 0x%08x. " "Firmware bus number: %d->%d\n", rsrc.start, hose->first_busno, hose->last_busno); pci_process_bridge_OF_ranges(hose, dev, primary); return 0; }
void __init find_and_init_phbs(void) { struct device_node *node; struct pci_controller *phb; struct device_node *root = of_find_node_by_path("/"); for (node = of_get_next_child(root, NULL); node != NULL; node = of_get_next_child(root, node)) { if (node->type == NULL || (strcmp(node->type, "pci") != 0 && strcmp(node->type, "pciex") != 0)) continue; phb = pcibios_alloc_controller(node); if (!phb) continue; rtas_setup_phb(phb); pci_process_bridge_OF_ranges(phb, node, 0); isa_bridge_find_early(phb); } of_node_put(root); pci_devs_phb_init(); /* * pci_probe_only and pci_assign_all_buses can be set via properties * in chosen. */ if (of_chosen) { const int *prop; prop = of_get_property(of_chosen, "linux,pci-probe-only", NULL); if (prop) pci_probe_only = *prop; #ifdef CONFIG_PPC32 /* Will be made generic soon */ prop = of_get_property(of_chosen, "linux,pci-assign-all-buses", NULL); if (prop && *prop) ppc_pci_flags |= PPC_PCI_REASSIGN_ALL_BUS; #endif /* CONFIG_PPC32 */ } }
static int __init mvme5100_add_bridge(struct device_node *dev) { const int *bus_range; int len; struct pci_controller *hose; unsigned short devid; pr_info("Adding PCI host bridge %s\n", dev->full_name); bus_range = of_get_property(dev, "bus-range", &len); hose = pcibios_alloc_controller(dev); if (hose == NULL) return -ENOMEM; hose->first_busno = bus_range ? bus_range[0] : 0; hose->last_busno = bus_range ? bus_range[1] : 0xff; setup_indirect_pci(hose, 0xfe000cf8, 0xfe000cfc, 0); pci_process_bridge_OF_ranges(hose, dev, 1); early_read_config_word(hose, 0, 0, PCI_DEVICE_ID, &devid); if (devid != PCI_DEVICE_ID_MOTOROLA_HAWK) { pr_err("HAWK PHB not present?\n"); return 0; } early_read_config_dword(hose, 0, 0, PCI_BASE_ADDRESS_1, &pci_membase); if (pci_membase == 0) { pr_err("HAWK PHB mibar not correctly set?\n"); return 0; } pr_info("mvme5100_pic_init: pci_membase: %x\n", pci_membase); return 0; }
static void __init pq2_pci_add_bridge(struct device_node *np) { struct pci_controller *hose; struct resource r; if (of_address_to_resource(np, 0, &r) || r.end - r.start < 0x10b) goto err; pci_add_flags(PCI_REASSIGN_ALL_BUS); hose = pcibios_alloc_controller(np); if (!hose) return; hose->dn = np; setup_indirect_pci(hose, r.start + 0x100, r.start + 0x104, 0); pci_process_bridge_OF_ranges(hose, np, 1); return; err: printk(KERN_ERR "No valid PCI reg property in device tree\n"); }
struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn) { struct device_node *root = of_find_node_by_path("/"); unsigned int root_size_cells = 0; struct pci_controller *phb; int primary; root_size_cells = prom_n_size_cells(root); primary = list_empty(&hose_list); phb = pcibios_alloc_controller(dn); if (!phb) return NULL; setup_phb(dn, phb, root_size_cells); pci_process_bridge_OF_ranges(phb, dn, primary); pci_setup_phb_io_dynamic(phb, primary); of_node_put(root); pci_devs_phb_init_dynamic(phb); scan_phb(phb); return phb; }
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; }
static int __devinit of_pci_phb_probe(struct of_device *dev, const struct of_device_id *match) { struct pci_controller *phb; /* Check if we can do that ... */ if (ppc_md.pci_setup_phb == NULL) return -ENODEV; printk(KERN_INFO "Setting up PCI bus %s\n", dev->node->full_name); /* Alloc and setup PHB data structure */ phb = pcibios_alloc_controller(dev->node); if (!phb) return -ENODEV; /* Setup parent in sysfs */ phb->parent = &dev->dev; /* Setup the PHB using arch provided callback */ if (ppc_md.pci_setup_phb(phb)) { pcibios_free_controller(phb); return -ENODEV; } /* Process "ranges" property */ pci_process_bridge_OF_ranges(phb, dev->node, 0); /* Setup IO space. * This will not work properly for ISA IOs, something needs to be done * about it if we ever generalize that way of probing PCI brigdes */ pci_setup_phb_io_dynamic(phb, 0); /* Init pci_dn data structures */ pci_devs_phb_init_dynamic(phb); /* Register devices with EEH */ #ifdef CONFIG_EEH if (dev->node->child) eeh_add_device_tree_early(dev->node); #endif /* CONFIG_EEH */ /* Scan the bus */ scan_phb(phb); /* Claim resources. This might need some rework as well depending * wether we are doing probe-only or not, like assigning unassigned * resources etc... */ pcibios_claim_one_bus(phb->bus); /* Finish EEH setup */ #ifdef CONFIG_EEH eeh_add_device_tree_late(phb->bus); #endif /* Add probed PCI devices to the device model */ pci_bus_add_devices(phb->bus); return 0; }
static int __devinit of_pci_phb_probe(struct of_device *dev, const struct of_device_id *match) { struct pci_controller *phb; /* Check if we can do that ... */ if (ppc_md.pci_setup_phb == NULL) return -ENODEV; printk(KERN_INFO "Setting up PCI bus %s\n", dev->node->full_name); /* Alloc and setup PHB data structure */ phb = pcibios_alloc_controller(dev->node); if (!phb) return -ENODEV; /* Setup parent in sysfs */ phb->parent = &dev->dev; /* Setup the PHB using arch provided callback */ if (ppc_md.pci_setup_phb(phb)) { pcibios_free_controller(phb); return -ENODEV; } /* Process "ranges" property */ pci_process_bridge_OF_ranges(phb, dev->node, 0); /* Setup IO space. We use the non-dynamic version of that code here, * which doesn't quite support unplugging. Next kernel release will * have a better fix for this. * Note also that we don't do ISA, this will also be fixed with a * more massive rework. */ pci_setup_phb_io(phb, pci_io_base == 0); /* Init pci_dn data structures */ pci_devs_phb_init_dynamic(phb); /* Register devices with EEH */ #ifdef CONFIG_EEH if (dev->node->child) eeh_add_device_tree_early(dev->node); #endif /* CONFIG_EEH */ /* Scan the bus */ scan_phb(phb); /* Claim resources. This might need some rework as well depending * wether we are doing probe-only or not, like assigning unassigned * resources etc... */ pcibios_claim_one_bus(phb->bus); /* Finish EEH setup */ #ifdef CONFIG_EEH eeh_add_device_tree_late(phb->bus); #endif /* Add probed PCI devices to the device model */ pci_bus_add_devices(phb->bus); return 0; }
static void __init pnv_pci_init_p5ioc2_phb(struct device_node *np, u64 hub_id, void *tce_mem, u64 tce_size) { struct pnv_phb *phb; const __be64 *prop64; u64 phb_id; int64_t rc; static int primary = 1; pr_info(" Initializing p5ioc2 PHB %s\n", np->full_name); prop64 = of_get_property(np, "ibm,opal-phbid", NULL); if (!prop64) { pr_err(" Missing \"ibm,opal-phbid\" property !\n"); return; } phb_id = be64_to_cpup(prop64); pr_devel(" PHB-ID : 0x%016llx\n", phb_id); pr_devel(" TCE AT : 0x%016lx\n", __pa(tce_mem)); pr_devel(" TCE SZ : 0x%016llx\n", tce_size); rc = opal_pci_set_phb_tce_memory(phb_id, __pa(tce_mem), tce_size); if (rc != OPAL_SUCCESS) { pr_err(" Failed to set TCE memory, OPAL error %lld\n", rc); return; } phb = alloc_bootmem(sizeof(struct pnv_phb)); if (phb) { memset(phb, 0, sizeof(struct pnv_phb)); phb->hose = pcibios_alloc_controller(np); } if (!phb || !phb->hose) { pr_err(" Failed to allocate PCI controller\n"); return; } spin_lock_init(&phb->lock); phb->hose->first_busno = 0; phb->hose->last_busno = 0xff; phb->hose->private_data = phb; phb->hub_id = hub_id; phb->opal_id = phb_id; phb->type = PNV_PHB_P5IOC2; phb->model = PNV_PHB_MODEL_P5IOC2; phb->regs = of_iomap(np, 0); if (phb->regs == NULL) pr_err(" Failed to map registers !\n"); else { pr_devel(" P_BUID = 0x%08x\n", in_be32(phb->regs + 0x100)); pr_devel(" P_IOSZ = 0x%08x\n", in_be32(phb->regs + 0x1b0)); pr_devel(" P_IO_ST = 0x%08x\n", in_be32(phb->regs + 0x1e0)); pr_devel(" P_MEM1_H = 0x%08x\n", in_be32(phb->regs + 0x1a0)); pr_devel(" P_MEM1_L = 0x%08x\n", in_be32(phb->regs + 0x190)); pr_devel(" P_MSZ1_L = 0x%08x\n", in_be32(phb->regs + 0x1c0)); pr_devel(" P_MEM_ST = 0x%08x\n", in_be32(phb->regs + 0x1d0)); pr_devel(" P_MEM2_H = 0x%08x\n", in_be32(phb->regs + 0x2c0)); pr_devel(" P_MEM2_L = 0x%08x\n", in_be32(phb->regs + 0x2b0)); pr_devel(" P_MSZ2_H = 0x%08x\n", in_be32(phb->regs + 0x2d0)); pr_devel(" P_MSZ2_L = 0x%08x\n", in_be32(phb->regs + 0x2e0)); } /* Interpret the "ranges" property */ /* This also maps the I/O region and sets isa_io/mem_base */ pci_process_bridge_OF_ranges(phb->hose, np, primary); primary = 0; phb->hose->ops = &pnv_pci_ops; /* Setup MSI support */ pnv_pci_init_p5ioc2_msis(phb); /* Setup TCEs */ phb->dma_dev_setup = pnv_pci_p5ioc2_dma_dev_setup; pnv_pci_setup_iommu_table(&phb->p5ioc2.iommu_table, tce_mem, tce_size, 0); }
static void __init ppc4xx_pciex_port_setup_hose(struct ppc4xx_pciex_port *port) { struct resource dma_window; struct pci_controller *hose = NULL; const int *bus_range; int primary = 0, busses; void __iomem *mbase = NULL, *cfg_data = NULL; const u32 *pval; u32 val; /* Check if primary bridge */ if (of_get_property(port->node, "primary", NULL)) primary = 1; /* Get bus range if any */ bus_range = of_get_property(port->node, "bus-range", NULL); /* Allocate the host controller data structure */ hose = pcibios_alloc_controller(port->node); if (!hose) goto fail; /* We stick the port number in "indirect_type" so the config space * ops can retrieve the port data structure easily */ hose->indirect_type = port->index; /* Get bus range */ hose->first_busno = bus_range ? bus_range[0] : 0x0; hose->last_busno = bus_range ? bus_range[1] : 0xff; /* Because of how big mapping the config space is (1M per bus), we * limit how many busses we support. In the long run, we could replace * that with something akin to kmap_atomic instead. We set aside 1 bus * for the host itself too. */ busses = hose->last_busno - hose->first_busno; /* This is off by 1 */ if (busses > MAX_PCIE_BUS_MAPPED) { busses = MAX_PCIE_BUS_MAPPED; hose->last_busno = hose->first_busno + busses; } if (!port->endpoint) { /* Only map the external config space in cfg_data for * PCIe root-complexes. External space is 1M per bus */ cfg_data = ioremap(port->cfg_space.start + (hose->first_busno + 1) * 0x100000, busses * 0x100000); if (cfg_data == NULL) { printk(KERN_ERR "%s: Can't map external config space !", port->node->full_name); goto fail; } hose->cfg_data = cfg_data; } /* Always map the host config space in cfg_addr. * Internal space is 4K */ mbase = ioremap(port->cfg_space.start + 0x10000000, 0x1000); if (mbase == NULL) { printk(KERN_ERR "%s: Can't map internal config space !", port->node->full_name); goto fail; } hose->cfg_addr = mbase; pr_debug("PCIE %s, bus %d..%d\n", port->node->full_name, hose->first_busno, hose->last_busno); pr_debug(" config space mapped at: root @0x%p, other @0x%p\n", hose->cfg_addr, hose->cfg_data); /* Setup config space */ hose->ops = &ppc4xx_pciex_pci_ops; port->hose = hose; mbase = (void __iomem *)hose->cfg_addr; if (!port->endpoint) { /* * Set bus numbers on our root port */ out_8(mbase + PCI_PRIMARY_BUS, hose->first_busno); out_8(mbase + PCI_SECONDARY_BUS, hose->first_busno + 1); out_8(mbase + PCI_SUBORDINATE_BUS, hose->last_busno); } /* * OMRs are already reset, also disable PIMs */ out_le32(mbase + PECFG_PIMEN, 0); /* Parse outbound mapping resources */ pci_process_bridge_OF_ranges(hose, port->node, primary); /* Parse inbound mapping resources */ if (ppc4xx_parse_dma_ranges(hose, mbase, &dma_window) != 0) goto fail; /* Configure outbound ranges POMs */ ppc4xx_configure_pciex_POMs(port, hose, mbase); /* Configure inbound ranges PIMs */ ppc4xx_configure_pciex_PIMs(port, hose, mbase, &dma_window); /* The root complex doesn't show up if we don't set some vendor * and device IDs into it. The defaults below are the same bogus * one that the initial code in arch/ppc had. This can be * overwritten by setting the "vendor-id/device-id" properties * in the pciex node. */ /* Get the (optional) vendor-/device-id from the device-tree */ pval = of_get_property(port->node, "vendor-id", NULL); if (pval) { val = *pval; } else { if (!port->endpoint) val = 0xaaa0 + port->index; else val = 0xeee0 + port->index; } out_le16(mbase + 0x200, val); pval = of_get_property(port->node, "device-id", NULL); if (pval) { val = *pval; } else { if (!port->endpoint) val = 0xbed0 + port->index; else val = 0xfed0 + port->index; } out_le16(mbase + 0x202, val); if (!port->endpoint) { /* Set Class Code to PCI-PCI bridge and Revision Id to 1 */ out_le32(mbase + 0x208, 0x06040001); printk(KERN_INFO "PCIE%d: successfully set as root-complex\n", port->index); } else { /* Set Class Code to Processor/PPC */ out_le32(mbase + 0x208, 0x0b200001); printk(KERN_INFO "PCIE%d: successfully set as endpoint\n", port->index); } return; fail: if (hose) pcibios_free_controller(hose); if (cfg_data) iounmap(cfg_data); if (mbase) iounmap(mbase); }
static void __init ppc4xx_probe_pcix_bridge(struct device_node *np) { struct resource rsrc_cfg; struct resource rsrc_reg; struct resource dma_window; struct pci_controller *hose = NULL; void __iomem *reg = NULL; const int *bus_range; int big_pim = 0, msi = 0, primary = 0; /* Fetch config space registers address */ if (of_address_to_resource(np, 0, &rsrc_cfg)) { printk(KERN_ERR "%s:Can't get PCI-X config register base !", np->full_name); return; } /* Fetch host bridge internal registers address */ if (of_address_to_resource(np, 3, &rsrc_reg)) { printk(KERN_ERR "%s: Can't get PCI-X internal register base !", np->full_name); return; } /* Check if it supports large PIMs (440GX) */ if (of_get_property(np, "large-inbound-windows", NULL)) big_pim = 1; /* Check if we should enable MSIs inbound hole */ if (of_get_property(np, "enable-msi-hole", NULL)) msi = 1; /* Check if primary bridge */ if (of_get_property(np, "primary", NULL)) primary = 1; /* Get bus range if any */ bus_range = of_get_property(np, "bus-range", NULL); /* Map registers */ reg = ioremap(rsrc_reg.start, rsrc_reg.end + 1 - rsrc_reg.start); if (reg == NULL) { printk(KERN_ERR "%s: Can't map registers !", np->full_name); goto fail; } /* Allocate the host controller data structure */ hose = pcibios_alloc_controller(np); if (!hose) goto fail; hose->first_busno = bus_range ? bus_range[0] : 0x0; hose->last_busno = bus_range ? bus_range[1] : 0xff; /* Setup config space */ setup_indirect_pci(hose, rsrc_cfg.start, rsrc_cfg.start + 0x4, PPC_INDIRECT_TYPE_SET_CFG_TYPE); /* Disable all windows */ writel(0, reg + PCIX0_POM0SA); writel(0, reg + PCIX0_POM1SA); writel(0, reg + PCIX0_POM2SA); writel(0, reg + PCIX0_PIM0SA); writel(0, reg + PCIX0_PIM1SA); writel(0, reg + PCIX0_PIM2SA); if (big_pim) { writel(0, reg + PCIX0_PIM0SAH); writel(0, reg + PCIX0_PIM2SAH); } /* Parse outbound mapping resources */ pci_process_bridge_OF_ranges(hose, np, primary); /* Parse inbound mapping resources */ if (ppc4xx_parse_dma_ranges(hose, reg, &dma_window) != 0) goto fail; /* Configure outbound ranges POMs */ ppc4xx_configure_pcix_POMs(hose, reg); /* Configure inbound ranges PIMs */ ppc4xx_configure_pcix_PIMs(hose, reg, &dma_window, big_pim, msi); /* We don't need the registers anymore */ iounmap(reg); return; fail: if (hose) pcibios_free_controller(hose); if (reg) iounmap(reg); }
static void __init ppc4xx_probe_pci_bridge(struct device_node *np) { /* NYI */ struct resource rsrc_cfg; struct resource rsrc_reg; struct resource dma_window; struct pci_controller *hose = NULL; void __iomem *reg = NULL; const int *bus_range; int primary = 0; /* Check if device is enabled */ if (!of_device_is_available(np)) { printk(KERN_INFO "%s: Port disabled via device-tree\n", np->full_name); return; } /* Fetch config space registers address */ if (of_address_to_resource(np, 0, &rsrc_cfg)) { printk(KERN_ERR "%s: Can't get PCI config register base !", np->full_name); return; } /* Fetch host bridge internal registers address */ if (of_address_to_resource(np, 3, &rsrc_reg)) { printk(KERN_ERR "%s: Can't get PCI internal register base !", np->full_name); return; } /* Check if primary bridge */ if (of_get_property(np, "primary", NULL)) primary = 1; /* Get bus range if any */ bus_range = of_get_property(np, "bus-range", NULL); /* Map registers */ reg = ioremap(rsrc_reg.start, rsrc_reg.end + 1 - rsrc_reg.start); if (reg == NULL) { printk(KERN_ERR "%s: Can't map registers !", np->full_name); goto fail; } /* Allocate the host controller data structure */ hose = pcibios_alloc_controller(np); if (!hose) goto fail; hose->first_busno = bus_range ? bus_range[0] : 0x0; hose->last_busno = bus_range ? bus_range[1] : 0xff; /* Setup config space */ setup_indirect_pci(hose, rsrc_cfg.start, rsrc_cfg.start + 0x4, 0); /* Disable all windows */ writel(0, reg + PCIL0_PMM0MA); writel(0, reg + PCIL0_PMM1MA); writel(0, reg + PCIL0_PMM2MA); writel(0, reg + PCIL0_PTM1MS); writel(0, reg + PCIL0_PTM2MS); /* Parse outbound mapping resources */ pci_process_bridge_OF_ranges(hose, np, primary); /* Parse inbound mapping resources */ if (ppc4xx_parse_dma_ranges(hose, reg, &dma_window) != 0) goto fail; /* Configure outbound ranges POMs */ ppc4xx_configure_pci_PMMs(hose, reg); /* Configure inbound ranges PIMs */ ppc4xx_configure_pci_PTMs(hose, reg, &dma_window); /* We don't need the registers anymore */ iounmap(reg); return; fail: if (hose) pcibios_free_controller(hose); if (reg) iounmap(reg); }
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; }
static void __init pnv_pci_init_p5ioc2_phb(struct device_node *np, u64 hub_id, void *tce_mem, u64 tce_size) { struct pnv_phb *phb; const __be64 *prop64; u64 phb_id; int64_t rc; static int primary = 1; struct iommu_table_group *table_group; struct iommu_table *tbl; pr_info(" Initializing p5ioc2 PHB %s\n", np->full_name); prop64 = of_get_property(np, "ibm,opal-phbid", NULL); if (!prop64) { pr_err(" Missing \"ibm,opal-phbid\" property !\n"); return; } phb_id = be64_to_cpup(prop64); pr_devel(" PHB-ID : 0x%016llx\n", phb_id); pr_devel(" TCE AT : 0x%016lx\n", __pa(tce_mem)); pr_devel(" TCE SZ : 0x%016llx\n", tce_size); rc = opal_pci_set_phb_tce_memory(phb_id, __pa(tce_mem), tce_size); if (rc != OPAL_SUCCESS) { pr_err(" Failed to set TCE memory, OPAL error %lld\n", rc); return; } phb = memblock_virt_alloc(sizeof(struct pnv_phb), 0); phb->hose = pcibios_alloc_controller(np); if (!phb->hose) { pr_err(" Failed to allocate PCI controller\n"); return; } spin_lock_init(&phb->lock); phb->hose->first_busno = 0; phb->hose->last_busno = 0xff; phb->hose->private_data = phb; phb->hose->controller_ops = pnv_pci_p5ioc2_controller_ops; phb->hub_id = hub_id; phb->opal_id = phb_id; phb->type = PNV_PHB_P5IOC2; phb->model = PNV_PHB_MODEL_P5IOC2; phb->regs = of_iomap(np, 0); if (phb->regs == NULL) pr_err(" Failed to map registers !\n"); else { pr_devel(" P_BUID = 0x%08x\n", in_be32(phb->regs + 0x100)); pr_devel(" P_IOSZ = 0x%08x\n", in_be32(phb->regs + 0x1b0)); pr_devel(" P_IO_ST = 0x%08x\n", in_be32(phb->regs + 0x1e0)); pr_devel(" P_MEM1_H = 0x%08x\n", in_be32(phb->regs + 0x1a0)); pr_devel(" P_MEM1_L = 0x%08x\n", in_be32(phb->regs + 0x190)); pr_devel(" P_MSZ1_L = 0x%08x\n", in_be32(phb->regs + 0x1c0)); pr_devel(" P_MEM_ST = 0x%08x\n", in_be32(phb->regs + 0x1d0)); pr_devel(" P_MEM2_H = 0x%08x\n", in_be32(phb->regs + 0x2c0)); pr_devel(" P_MEM2_L = 0x%08x\n", in_be32(phb->regs + 0x2b0)); pr_devel(" P_MSZ2_H = 0x%08x\n", in_be32(phb->regs + 0x2d0)); pr_devel(" P_MSZ2_L = 0x%08x\n", in_be32(phb->regs + 0x2e0)); } /* Interpret the "ranges" property */ /* This also maps the I/O region and sets isa_io/mem_base */ pci_process_bridge_OF_ranges(phb->hose, np, primary); primary = 0; phb->hose->ops = &pnv_pci_ops; /* Setup MSI support */ pnv_pci_init_p5ioc2_msis(phb); /* Setup TCEs */ phb->dma_dev_setup = pnv_pci_p5ioc2_dma_dev_setup; pnv_pci_setup_iommu_table(&phb->p5ioc2.iommu_table, tce_mem, tce_size, 0, IOMMU_PAGE_SHIFT_4K); /* * We do not allocate iommu_table as we do not support * hotplug or SRIOV on P5IOC2 and therefore iommu_free_table() * should not be called for phb->p5ioc2.table_group.tables[0] ever. */ tbl = phb->p5ioc2.table_group.tables[0] = &phb->p5ioc2.iommu_table; table_group = &phb->p5ioc2.table_group; table_group->tce32_start = tbl->it_offset << tbl->it_page_shift; table_group->tce32_size = tbl->it_size << tbl->it_page_shift; }
unsigned long __init find_and_init_phbs(void) { struct device_node *node; struct pci_controller *phb; unsigned int root_size_cells = 0; unsigned int index; unsigned int *opprop = NULL; struct device_node *root = of_find_node_by_path("/"); if (ppc64_interrupt_controller == IC_OPEN_PIC) { opprop = (unsigned int *)get_property(root, "platform-open-pic", NULL); } root_size_cells = prom_n_size_cells(root); index = 0; for (node = of_get_next_child(root, NULL); node != NULL; node = of_get_next_child(root, node)) { if (node->type == NULL || strcmp(node->type, "pci") != 0) continue; phb = pcibios_alloc_controller(node); if (!phb) continue; setup_phb(node, phb, root_size_cells); pci_process_bridge_OF_ranges(phb, node, 0); pci_setup_phb_io(phb, index == 0); #ifdef CONFIG_PPC_PSERIES if (ppc64_interrupt_controller == IC_OPEN_PIC && pSeries_mpic) { int addr = root_size_cells * (index + 2) - 1; mpic_assign_isu(pSeries_mpic, index, opprop[addr]); } #endif index++; } of_node_put(root); pci_devs_phb_init(); /* * pci_probe_only and pci_assign_all_buses can be set via properties * in chosen. */ if (of_chosen) { int *prop; prop = (int *)get_property(of_chosen, "linux,pci-probe-only", NULL); if (prop) pci_probe_only = *prop; prop = (int *)get_property(of_chosen, "linux,pci-assign-all-buses", NULL); if (prop) pci_assign_all_buses = *prop; } return 0; }