Beispiel #1
0
static int __init l4vpci_x86_init(void)
{
	struct pci_dev *dev = NULL;
	struct pci_bus *bus;
	struct pci_sysdata *sd = kzalloc(sizeof(*sd), GFP_KERNEL);
	if (!sd)
		return -ENOMEM;

	bus = pci_scan_bus(0, &l4vpci_ops, sd);
	if (!bus) {
		pr_err("Failed to scan PCI bus\n");
		return -ENODEV;
	}

	pci_bus_add_devices(bus);

	pr_info("l4vPCI: Using L4-IO for IRQ routing\n");

	for_each_pci_dev(dev)
		l4vpci_irq_enable(dev);

	pcibios_resource_survey();

	return 0;
}
Beispiel #2
0
int  vpci_bus_init(void)
{
	struct pci_dev *pcidev = NULL;
	sysdata = kzalloc(sizeof(void *), GFP_KERNEL);
		vbus = pci_scan_bus_parented(NULL, 2, & vpci_ops, sysdata);
		//vbus = pci_create_root_bus(NULL,i,& vpci_ops, sysdata,NULL);
		//if (vbus != NULL)
			//break;
		memset(sysdata, 0, sizeof(void *));
	if (vbus == NULL) {
		kfree(sysdata);
		return -EINVAL;
	}
	if (pci_register_driver(& vpci_vdev_driver) < 0) {
		pci_remove_bus(vbus);
		vbus = NULL;
		return -EINVAL;
	}
	pcidev = pci_scan_single_device(vbus, 0);

        if (pcidev == NULL)
                return 0;
        else
                pci_dev_get(pcidev);
	
	pci_bus_add_devices(vbus);
	
	return 0;
}
Beispiel #3
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;
}
unsigned int __devinit pci_do_scan_bus(struct pci_bus *bus)
{
	unsigned int max;

	max = pci_scan_child_bus(bus);

	pci_bus_add_devices(bus);

	return max;
}
Beispiel #5
0
int pci_host_common_probe(struct platform_device *pdev,
			  struct pci_ecam_ops *ops)
{
	const char *type;
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	struct pci_bus *bus, *child;
	struct pci_config_window *cfg;
	struct list_head resources;

	type = of_get_property(np, "device_type", NULL);
	if (!type || strcmp(type, "pci")) {
		dev_err(dev, "invalid \"device_type\" %s\n", type);
		return -EINVAL;
	}

	of_pci_check_probe_only();

	/* Parse and map our Configuration Space windows */
	INIT_LIST_HEAD(&resources);
	cfg = gen_pci_init(dev, &resources, ops);
	if (IS_ERR(cfg))
		return PTR_ERR(cfg);

	/* Do not reassign resources if probe only */
	if (!pci_has_flag(PCI_PROBE_ONLY))
		pci_add_flags(PCI_REASSIGN_ALL_RSRC | PCI_REASSIGN_ALL_BUS);

	bus = pci_scan_root_bus(dev, cfg->busr.start, &ops->pci_ops, cfg,
				&resources);
	if (!bus) {
		dev_err(dev, "Scanning rootbus failed");
		return -ENODEV;
	}

	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);

	/*
	 * We insert PCI resources into the iomem_resource and
	 * ioport_resource trees in either pci_bus_claim_resources()
	 * or pci_bus_assign_resources().
	 */
	if (pci_has_flag(PCI_PROBE_ONLY)) {
		pci_bus_claim_resources(bus);
	} else {
		pci_bus_size_bridges(bus);
		pci_bus_assign_resources(bus);

		list_for_each_entry(child, &bus->children, node)
			pcie_bus_configure_settings(child);
	}

	pci_bus_add_devices(bus);
	return 0;
}
int __ref cpci_configure_slot(struct slot *slot)
{
	struct pci_bus *parent;
	int fn;

	dbg("%s - enter", __func__);

	if (slot->dev == NULL) {
		dbg("pci_dev null, finding %02x:%02x:%x",
		    slot->bus->number, PCI_SLOT(slot->devfn), PCI_FUNC(slot->devfn));
		slot->dev = pci_get_slot(slot->bus, slot->devfn);
	}

	/* Still NULL? Well then scan for it! */
	if (slot->dev == NULL) {
		int n;
		dbg("pci_dev still null");

		/*
		 * This will generate pci_dev structures for all functions, but
		 * we will only call this case when lookup fails.
		 */
		n = pci_scan_slot(slot->bus, slot->devfn);
		dbg("%s: pci_scan_slot returned %d", __func__, n);
		slot->dev = pci_get_slot(slot->bus, slot->devfn);
		if (slot->dev == NULL) {
			err("Could not find PCI device for slot %02x", slot->number);
			return -ENODEV;
		}
	}
	parent = slot->dev->bus;

	for (fn = 0; fn < 8; fn++) {
		struct pci_dev *dev;

		dev = pci_get_slot(parent,
				   PCI_DEVFN(PCI_SLOT(slot->devfn), fn));
		if (!dev)
			continue;
		if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
		    (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS))
			pci_hp_add_bridge(dev);
		pci_dev_put(dev);
	}

	pci_assign_unassigned_bridge_resources(parent->self);

	pci_bus_add_devices(parent);

	dbg("%s - exit", __func__);
	return 0;
}
Beispiel #7
0
struct pci_bus * __init l4vpci_scan_bus(int nr, struct pci_sys_data *sys)
{
	struct pci_bus *b;
	struct pci_dev *dev = NULL;
	b = pci_scan_root_bus(NULL, sys->busnr, &l4vpci_ops, sys,
	                      &sys->resources);
	for_each_pci_dev(dev)
		l4vpci_irq_enable(dev);

	pci_bus_add_devices(b);

	return b;
}
Beispiel #8
0
unsigned int __devinit pci_do_scan_bus(struct pci_bus *bus)
{
	unsigned int max;

	max = pci_scan_child_bus(bus);

	/*
	 * Make the discovered devices available.
	 */
	pci_bus_add_devices(bus);

	return max;
}
Beispiel #9
0
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;
}
Beispiel #10
0
/*
 * test_bus_add_devices
 *	make call to pci_bus_add_devices,
 *	which will check the device pointer
 *	that is passed in for more devices
 *	that it can add
 */
static int test_bus_add_devices(void)
{
	struct pci_bus *bus = ltp_pci.bus;

	prk_info("add bus device");

	pci_bus_add_devices(bus);

	if (bus) {
		prk_info("called bus_add_device");
		return TPASS;
	}

	prk_err("bus_add_device failed");
	return TFAIL;
}
Beispiel #11
0
static int __init pci_legacy_init(void)
{
    if (!raw_pci_ops) {
        printk("PCI: System does not support PCI\n");
        return 0;
    }

    if (pcibios_scanned++)
        return 0;

    printk("PCI: Probing PCI hardware\n");
    pci_root_bus = pcibios_scan_root(0);
    if (pci_root_bus)
        pci_bus_add_devices(pci_root_bus);

    pcibios_fixup_peer_bridges();

    return 0;
}
Beispiel #12
0
/*
 * Initialization. Try all known PCI access methods. Note that we support
 * using both PCI BIOS and direct access: in such cases, we use I/O ports
 * to access config space, but we still keep BIOS order of cards to be
 * compatible with 2.0.X. This should go away some day.
 */
static int __init pcibios_init(void)
{
	resource_size_t io_offset, mem_offset;
	LIST_HEAD(resources);
	struct pci_bus *bus;

	ioport_resource.start	= 0xA0000000;
	ioport_resource.end	= 0xDFFFFFFF;
	iomem_resource.start	= 0xA0000000;
	iomem_resource.end	= 0xDFFFFFFF;

	if (insert_resource(&iomem_resource, &pci_iomem_resource) < 0)
		panic("Unable to insert PCI IOMEM resource\n");
	if (insert_resource(&ioport_resource, &pci_ioport_resource) < 0)
		panic("Unable to insert PCI IOPORT resource\n");

	if (!pci_probe)
		return 0;

	if (pci_check_direct() < 0) {
		printk(KERN_WARNING "PCI: No PCI bus detected\n");
		return 0;
	}

	printk(KERN_INFO "PCI: Probing PCI hardware [mempage %08x]\n",
	       MEM_PAGING_REG);

	io_offset = pci_ioport_resource.start -
	    (pci_ioport_resource.start & 0x00ffffff);
	mem_offset = pci_iomem_resource.start -
	    ((pci_iomem_resource.start & 0x03ffffff) | MEM_PAGING_REG);

	pci_add_resource_offset(&resources, &pci_ioport_resource, io_offset);
	pci_add_resource_offset(&resources, &pci_iomem_resource, mem_offset);
	bus = pci_scan_root_bus(NULL, 0, &pci_direct_ampci, NULL, &resources);
	if (!bus)
		return 0;
	pcibios_resource_survey();
	pci_bus_add_devices(bus);
	return 0;
}
Beispiel #13
0
void pcibios_scan_root(int busnum)
{
	struct pci_bus *bus;
	struct pci_sysdata *sd;
	LIST_HEAD(resources);

	sd = kzalloc(sizeof(*sd), GFP_KERNEL);
	if (!sd) {
		printk(KERN_ERR "PCI: OOM, skipping PCI bus %02x\n", busnum);
		return;
	}
	sd->node = x86_pci_root_bus_node(busnum);
	x86_pci_root_bus_resources(busnum, &resources);
	printk(KERN_DEBUG "PCI: Probing PCI hardware (bus %02x)\n", busnum);
	bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, sd, &resources);
	if (!bus) {
		pci_free_resource_list(&resources);
		kfree(sd);
		return;
	}
	pci_bus_add_devices(bus);
}
Beispiel #14
0
static int versatile_pci_probe(struct platform_device *pdev)
{
	struct resource *res;
	int ret, i, myslot = -1;
	u32 val;
	void __iomem *local_pci_cfg_base;
	struct pci_bus *bus;
	LIST_HEAD(pci_res);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
	versatile_pci_base = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(versatile_pci_base))
		return PTR_ERR(versatile_pci_base);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	versatile_cfg_base[0] = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(versatile_cfg_base[0]))
		return PTR_ERR(versatile_cfg_base[0]);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
	versatile_cfg_base[1] = devm_ioremap_resource(&pdev->dev, res);
	if (IS_ERR(versatile_cfg_base[1]))
		return PTR_ERR(versatile_cfg_base[1]);

	ret = versatile_pci_parse_request_of_pci_ranges(&pdev->dev, &pci_res);
	if (ret)
		return ret;

	/*
	 * We need to discover the PCI core first to configure itself
	 * before the main PCI probing is performed
	 */
	for (i = 0; i < 32; i++) {
		if ((readl(versatile_cfg_base[0] + (i << 11) + PCI_VENDOR_ID) == VP_PCI_DEVICE_ID) &&
		    (readl(versatile_cfg_base[0] + (i << 11) + PCI_CLASS_REVISION) == VP_PCI_CLASS_ID)) {
			myslot = i;
			break;
		}
	}
	if (myslot == -1) {
		dev_err(&pdev->dev, "Cannot find PCI core!\n");
		return -EIO;
	}
	/*
	 * Do not to map Versatile FPGA PCI device into memory space
	 */
	pci_slot_ignore |= (1 << myslot);

	dev_info(&pdev->dev, "PCI core found (slot %d)\n", myslot);

	writel(myslot, PCI_SELFID);
	local_pci_cfg_base = versatile_cfg_base[1] + (myslot << 11);

	val = readl(local_pci_cfg_base + PCI_COMMAND);
	val |= PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER | PCI_COMMAND_INVALIDATE;
	writel(val, local_pci_cfg_base + PCI_COMMAND);

	/*
	 * Configure the PCI inbound memory windows to be 1:1 mapped to SDRAM
	 */
	writel(PHYS_OFFSET, local_pci_cfg_base + PCI_BASE_ADDRESS_0);
	writel(PHYS_OFFSET, local_pci_cfg_base + PCI_BASE_ADDRESS_1);
	writel(PHYS_OFFSET, local_pci_cfg_base + PCI_BASE_ADDRESS_2);

	/*
	 * For many years the kernel and QEMU were symbiotically buggy
	 * in that they both assumed the same broken IRQ mapping.
	 * QEMU therefore attempts to auto-detect old broken kernels
	 * so that they still work on newer QEMU as they did on old
	 * QEMU. Since we now use the correct (ie matching-hardware)
	 * IRQ mapping we write a definitely different value to a
	 * PCI_INTERRUPT_LINE register to tell QEMU that we expect
	 * real hardware behaviour and it need not be backwards
	 * compatible for us. This write is harmless on real hardware.
	 */
	writel(0, versatile_cfg_base[0] + PCI_INTERRUPT_LINE);

	pci_add_flags(PCI_ENABLE_PROC_DOMAINS);
	pci_add_flags(PCI_REASSIGN_ALL_BUS | PCI_REASSIGN_ALL_RSRC);

	bus = pci_scan_root_bus(&pdev->dev, 0, &pci_versatile_ops, NULL, &pci_res);
	if (!bus)
		return -ENOMEM;

	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
	pci_assign_unassigned_bus_resources(bus);
	pci_bus_add_devices(bus);

	return 0;
}
Beispiel #15
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;
}
Beispiel #16
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 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;
}
Beispiel #18
0
int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
{
	struct device *dev;
	int ret;
	void *sysdata;
	struct pci_bus *bus;

	dev = pcie->dev;
	ret = devm_request_pci_bus_resources(dev, res);
	if (ret)
		return ret;

	ret = phy_init(pcie->phy);
	if (ret) {
		dev_err(dev, "unable to initialize PCIe PHY\n");
		return ret;
	}

	ret = phy_power_on(pcie->phy);
	if (ret) {
		dev_err(dev, "unable to power on PCIe PHY\n");
		goto err_exit_phy;
	}

	switch (pcie->type) {
	case IPROC_PCIE_PAXB:
		pcie->reg_offsets = iproc_pcie_reg_paxb;
		break;
	case IPROC_PCIE_PAXC:
		pcie->reg_offsets = iproc_pcie_reg_paxc;
		break;
	default:
		dev_err(dev, "incompatible iProc PCIe interface\n");
		ret = -EINVAL;
		goto err_power_off_phy;
	}

	iproc_pcie_reset(pcie);

	if (pcie->need_ob_cfg) {
		ret = iproc_pcie_map_ranges(pcie, res);
		if (ret) {
			dev_err(dev, "map failed\n");
			goto err_power_off_phy;
		}
	}

#ifdef CONFIG_ARM
	pcie->sysdata.private_data = pcie;
	sysdata = &pcie->sysdata;
#else
	sysdata = pcie;
#endif

	bus = pci_create_root_bus(dev, 0, &iproc_pcie_ops, sysdata, res);
	if (!bus) {
		dev_err(dev, "unable to create PCI root bus\n");
		ret = -ENOMEM;
		goto err_power_off_phy;
	}
	pcie->root_bus = bus;

	ret = iproc_pcie_check_link(pcie, bus);
	if (ret) {
		dev_err(dev, "no PCIe EP device detected\n");
		goto err_rm_root_bus;
	}

	iproc_pcie_enable(pcie);

	if (IS_ENABLED(CONFIG_PCI_MSI))
		if (iproc_pcie_msi_enable(pcie))
			dev_info(dev, "not using iProc MSI\n");

	pci_scan_child_bus(bus);
	pci_assign_unassigned_bus_resources(bus);
	pci_fixup_irqs(pci_common_swizzle, pcie->map_irq);
	pci_bus_add_devices(bus);

	return 0;

err_rm_root_bus:
	pci_stop_root_bus(bus);
	pci_remove_root_bus(bus);

err_power_off_phy:
	phy_power_off(pcie->phy);
err_exit_phy:
	phy_exit(pcie->phy);
	return ret;
}
Beispiel #19
0
int __ref cpci_configure_slot(struct slot *slot)
{
    struct pci_bus *parent;
    int fn;

    dbg("%s - enter", __func__);

    if (slot->dev == NULL) {
        dbg("pci_dev null, finding %02x:%02x:%x",
            slot->bus->number, PCI_SLOT(slot->devfn), PCI_FUNC(slot->devfn));
        slot->dev = pci_get_slot(slot->bus, slot->devfn);
    }

    /* Still NULL? Well then scan for it! */
    if (slot->dev == NULL) {
        int n;
        dbg("pci_dev still null");

        /*
         * This will generate pci_dev structures for all functions, but
         * we will only call this case when lookup fails.
         */
        n = pci_scan_slot(slot->bus, slot->devfn);
        dbg("%s: pci_scan_slot returned %d", __func__, n);
        slot->dev = pci_get_slot(slot->bus, slot->devfn);
        if (slot->dev == NULL) {
            err("Could not find PCI device for slot %02x", slot->number);
            return -ENODEV;
        }
    }
    parent = slot->dev->bus;

    for (fn = 0; fn < 8; fn++) {
        struct pci_dev *dev;

        dev = pci_get_slot(parent, PCI_DEVFN(PCI_SLOT(slot->devfn), fn));
        if (!dev)
            continue;
        if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
            (dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) {
            /* Find an unused bus number for the new bridge */
            struct pci_bus *child;
            unsigned char busnr, start = parent->secondary;
            unsigned char end = parent->subordinate;

            for (busnr = start; busnr <= end; busnr++) {
                if (!pci_find_bus(pci_domain_nr(parent),
                          busnr))
                    break;
            }
            if (busnr >= end) {
                err("No free bus for hot-added bridge\n");
                pci_dev_put(dev);
                continue;
            }
            child = pci_add_new_bus(parent, dev, busnr);
            if (!child) {
                err("Cannot add new bus for %s\n",
                    pci_name(dev));
                pci_dev_put(dev);
                continue;
            }
            child->subordinate = pci_do_scan_bus(child);
            pci_bus_size_bridges(child);
        }
        pci_dev_put(dev);
    }

    pci_bus_assign_resources(parent);
    pci_bus_add_devices(parent);
    pci_enable_bridges(parent);

    dbg("%s - exit", __func__);
    return 0;
}
Beispiel #20
0
int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
{
	int ret;
	void *sysdata;
	struct pci_bus *bus;

	if (!pcie || !pcie->dev || !pcie->base)
		return -EINVAL;

	ret = phy_init(pcie->phy);
	if (ret) {
		dev_err(pcie->dev, "unable to initialize PCIe PHY\n");
		return ret;
	}

	ret = phy_power_on(pcie->phy);
	if (ret) {
		dev_err(pcie->dev, "unable to power on PCIe PHY\n");
		goto err_exit_phy;
	}

	iproc_pcie_reset(pcie);

#ifdef CONFIG_ARM
	pcie->sysdata.private_data = pcie;
	sysdata = &pcie->sysdata;
#else
	sysdata = pcie;
#endif

	bus = pci_create_root_bus(pcie->dev, 0, &iproc_pcie_ops, sysdata, res);
	if (!bus) {
		dev_err(pcie->dev, "unable to create PCI root bus\n");
		ret = -ENOMEM;
		goto err_power_off_phy;
	}
	pcie->root_bus = bus;

	ret = iproc_pcie_check_link(pcie, bus);
	if (ret) {
		dev_err(pcie->dev, "no PCIe EP device detected\n");
		goto err_rm_root_bus;
	}

	iproc_pcie_enable(pcie);

	pci_scan_child_bus(bus);
	pci_assign_unassigned_bus_resources(bus);
#ifdef CONFIG_ARM
	pci_fixup_irqs(pci_common_swizzle, pcie->map_irq);
#endif
	pci_bus_add_devices(bus);

	return 0;

err_rm_root_bus:
	pci_stop_root_bus(bus);
	pci_remove_root_bus(bus);

err_power_off_phy:
	phy_power_off(pcie->phy);
err_exit_phy:
	phy_exit(pcie->phy);
	return ret;
}
Beispiel #21
0
int __ref shpchp_configure_device(struct slot *p_slot)
{
	struct pci_dev *dev;
	struct pci_bus *parent = p_slot->ctrl->pci_dev->subordinate;
	int num, fn;
	struct controller *ctrl = p_slot->ctrl;

	dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, 0));
	if (dev) {
		ctrl_err(ctrl, "Device %s already exists "
			 "at %04x:%02x:%02x, cannot hot-add\n", pci_name(dev),
			 pci_domain_nr(parent), p_slot->bus, p_slot->device);
		pci_dev_put(dev);
		return -EINVAL;
	}

	num = pci_scan_slot(parent, PCI_DEVFN(p_slot->device, 0));
	if (num == 0) {
		ctrl_err(ctrl, "No new device found\n");
		return -ENODEV;
	}

	for (fn = 0; fn < 8; fn++) {
		dev = pci_get_slot(parent, PCI_DEVFN(p_slot->device, fn));
		if (!dev)
			continue;
		if ((dev->hdr_type == PCI_HEADER_TYPE_BRIDGE) ||
				(dev->hdr_type == PCI_HEADER_TYPE_CARDBUS)) {
			/* Find an unused bus number for the new bridge */
			struct pci_bus *child;
			unsigned char busnr, start = parent->secondary;
			unsigned char end = parent->subordinate;
			for (busnr = start; busnr <= end; busnr++) {
				if (!pci_find_bus(pci_domain_nr(parent),
							busnr))
					break;
			}
			if (busnr > end) {
				ctrl_err(ctrl,
					 "No free bus for hot-added bridge\n");
				pci_dev_put(dev);
				continue;
			}
			child = pci_add_new_bus(parent, dev, busnr);
			if (!child) {
				ctrl_err(ctrl, "Cannot add new bus for %s\n",
					 pci_name(dev));
				pci_dev_put(dev);
				continue;
			}
			child->subordinate = pci_do_scan_bus(child);
			pci_bus_size_bridges(child);
		}
		pci_configure_slot(dev);
		pci_dev_put(dev);
	}

	pci_bus_assign_resources(parent);
	pci_bus_add_devices(parent);
	pci_enable_bridges(parent);
	return 0;
}
static int __init mcf_pci_init(void)
{
	pr_info("ColdFire: PCI bus initialization...\n");

	/* Reset the external PCI bus */
	__raw_writel(PCIGSCR_RESET, PCIGSCR);
	__raw_writel(0, PCITCR);

	request_resource(&iomem_resource, &mcf_pci_mem);
	request_resource(&iomem_resource, &mcf_pci_io);

	/* Configure PCI arbiter */
	__raw_writel(PACR_INTMPRI | PACR_INTMINTE | PACR_EXTMPRI(0x1f) |
		PACR_EXTMINTE(0x1f), PACR);

	/* Set required multi-function pins for PCI bus use */
	__raw_writew(0x3ff, MCFGPIO_PAR_PCIBG);
	__raw_writew(0x3ff, MCFGPIO_PAR_PCIBR);

	/* Set up config space for local host bus controller */
	__raw_writel(PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER |
		PCI_COMMAND_INVALIDATE, PCISCR);
	__raw_writel(PCICR1_LT(32) | PCICR1_CL(8), PCICR1);
	__raw_writel(0, PCICR2);

	/*
	 * Set up the initiator windows for memory and IO mapping.
	 * These give the CPU bus access onto the PCI bus. One for each of
	 * PCI memory and IO address spaces.
	 */
	__raw_writel(WXBTAR(PCI_MEM_PA, PCI_MEM_BA, PCI_MEM_SIZE),
		PCIIW0BTAR);
	__raw_writel(WXBTAR(PCI_IO_PA, PCI_IO_BA, PCI_IO_SIZE),
		PCIIW1BTAR);
	__raw_writel(PCIIWCR_W0_MEM /*| PCIIWCR_W0_MRDL*/ | PCIIWCR_W0_E |
		PCIIWCR_W1_IO | PCIIWCR_W1_E, PCIIWCR);

	/*
	 * Set up the target windows for access from the PCI bus back to the
	 * CPU bus. All we need is access to system RAM (for mastering).
	 */
	__raw_writel(CONFIG_RAMBASE, PCIBAR1);
	__raw_writel(CONFIG_RAMBASE | PCITBATR1_E, PCITBATR1);

	/* Keep a virtual mapping to IO/config space active */
	iospace = (unsigned long) ioremap(PCI_IO_PA, PCI_IO_SIZE);
	if (iospace == 0)
		return -ENODEV;
	pr_info("Coldfire: PCI IO/config window mapped to 0x%x\n",
		(u32) iospace);

	/* Turn of PCI reset, and wait for devices to settle */
	__raw_writel(0, PCIGSCR);
	set_current_state(TASK_UNINTERRUPTIBLE);
	schedule_timeout(msecs_to_jiffies(200));

	rootbus = pci_scan_bus(0, &mcf_pci_ops, NULL);
	if (!rootbus)
		return -ENODEV;

	rootbus->resource[0] = &mcf_pci_io;
	rootbus->resource[1] = &mcf_pci_mem;

	pci_fixup_irqs(pci_common_swizzle, mcf_pci_map_irq);
	pci_bus_size_bridges(rootbus);
	pci_bus_assign_resources(rootbus);
	pci_bus_add_devices(rootbus);
	return 0;
}