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; }
void __init nautilus_init_pci(void) { struct pci_controller *hose = hose_head; struct pci_bus *bus; struct pci_dev *irongate; unsigned long bus_align, bus_size, pci_mem; unsigned long memtop = max_low_pfn << PAGE_SHIFT; /* Scan our single hose. */ bus = pci_scan_bus(0, alpha_mv.pci_ops, hose); if (!bus) return; hose->bus = bus; pcibios_claim_one_bus(bus); irongate = pci_get_bus_and_slot(0, 0); bus->self = irongate; bus->resource[0] = &irongate_io; bus->resource[1] = &irongate_mem; pci_bus_size_bridges(bus); /* IO port range. */ bus->resource[0]->start = 0; bus->resource[0]->end = 0xffff; /* Set up PCI memory range - limit is hardwired to 0xffffffff, base must be at aligned to 16Mb. */ bus_align = bus->resource[1]->start; bus_size = bus->resource[1]->end + 1 - bus_align; if (bus_align < 0x1000000UL) bus_align = 0x1000000UL; pci_mem = (0x100000000UL - bus_size) & -bus_align; bus->resource[1]->start = pci_mem; bus->resource[1]->end = 0xffffffffUL; if (request_resource(&iomem_resource, bus->resource[1]) < 0) printk(KERN_ERR "Failed to request MEM on hose 0\n"); if (pci_mem < memtop) memtop = pci_mem; if (memtop > alpha_mv.min_mem_address) { free_reserved_area(__va(alpha_mv.min_mem_address), __va(memtop), -1, NULL); printk("nautilus_init_pci: %ldk freed\n", (memtop - alpha_mv.min_mem_address) >> 10); }
int cxl_pci_vphb_add(struct cxl_afu *afu) { struct pci_dev *phys_dev; struct pci_controller *phb, *phys_phb; struct device_node *vphb_dn; struct device *parent; if (cpu_has_feature(CPU_FTR_HVMODE)) { phys_dev = to_pci_dev(afu->adapter->dev.parent); phys_phb = pci_bus_to_host(phys_dev->bus); vphb_dn = phys_phb->dn; parent = &phys_dev->dev; } else { vphb_dn = afu->adapter->dev.parent->of_node; parent = afu->adapter->dev.parent; } /* Alloc and setup PHB data structure */ phb = pcibios_alloc_controller(vphb_dn); if (!phb) return -ENODEV; /* Setup parent in sysfs */ phb->parent = parent; /* Setup the PHB using arch provided callback */ phb->ops = &cxl_pcie_pci_ops; phb->cfg_addr = NULL; phb->cfg_data = 0; phb->private_data = afu; phb->controller_ops = cxl_pci_controller_ops; /* 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); /* Add probed PCI devices to the device model */ pci_bus_add_devices(phb->bus); afu->phb = phb; return 0; }
void __init nautilus_init_pci(void) { struct pci_controller *hose = hose_head; struct pci_bus *bus; struct pci_dev *irongate; unsigned long bus_align, bus_size, pci_mem; unsigned long memtop = max_low_pfn << PAGE_SHIFT; /* */ bus = pci_scan_bus(0, alpha_mv.pci_ops, hose); hose->bus = bus; pcibios_claim_one_bus(bus); irongate = pci_get_bus_and_slot(0, 0); bus->self = irongate; bus->resource[1] = &irongate_mem; pci_bus_size_bridges(bus); /* */ bus->resource[0]->start = 0; bus->resource[0]->end = 0xffff; /* */ bus_align = bus->resource[1]->start; bus_size = bus->resource[1]->end + 1 - bus_align; if (bus_align < 0x1000000UL) bus_align = 0x1000000UL; pci_mem = (0x100000000UL - bus_size) & -bus_align; bus->resource[1]->start = pci_mem; bus->resource[1]->end = 0xffffffffUL; if (request_resource(&iomem_resource, bus->resource[1]) < 0) printk(KERN_ERR "Failed to request MEM on hose 0\n"); if (pci_mem < memtop) memtop = pci_mem; if (memtop > alpha_mv.min_mem_address) { free_reserved_mem(__va(alpha_mv.min_mem_address), __va(memtop)); printk("nautilus_init_pci: %ldk freed\n", (memtop - alpha_mv.min_mem_address) >> 10); }
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 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; }
int cxl_pci_vphb_add(struct cxl_afu *afu) { struct pci_controller *phb; struct device_node *vphb_dn; struct device *parent; /* * If there are no AFU configuration records we won't have anything to * expose under the vPHB, so skip creating one, returning success since * this is still a valid case. This will also opt us out of EEH * handling since we won't have anything special to do if there are no * kernel drivers attached to the vPHB, and EEH handling is not yet * supported in the peer model. */ if (!afu->crs_num) return 0; /* The parent device is the adapter. Reuse the device node of * the adapter. * We don't seem to care what device node is used for the vPHB, * but tools such as lsvpd walk up the device parents looking * for a valid location code, so we might as well show devices * attached to the adapter as being located on that adapter. */ parent = afu->adapter->dev.parent; vphb_dn = parent->of_node; /* Alloc and setup PHB data structure */ phb = pcibios_alloc_controller(vphb_dn); if (!phb) return -ENODEV; /* Setup parent in sysfs */ phb->parent = parent; /* Setup the PHB using arch provided callback */ phb->ops = &cxl_pcie_pci_ops; phb->cfg_addr = NULL; phb->cfg_data = NULL; phb->private_data = afu; phb->controller_ops = cxl_pci_controller_ops; /* Scan the bus */ pcibios_scan_phb(phb); if (phb->bus == NULL) return -ENXIO; /* Set release hook on root bus */ pci_set_host_bridge_release(to_pci_host_bridge(phb->bus->bridge), pcibios_free_controller_deferred, (void *) phb); /* 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); /* Add probed PCI devices to the device model */ pci_bus_add_devices(phb->bus); afu->phb = phb; return 0; }