Ejemplo n.º 1
0
void zpci_event_availability(void *data)
{
    struct zpci_ccdf_avail *ccdf = data;
    struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid);
    struct pci_dev *pdev = zdev ? zdev->pdev : NULL;
    int ret;

    pr_info("%s: Event 0x%x reconfigured PCI function 0x%x\n",
            pdev ? pci_name(pdev) : "n/a", ccdf->pec, ccdf->fid);
    zpci_err("avail CCDF:\n");
    zpci_err_hex(ccdf, sizeof(*ccdf));

    switch (ccdf->pec) {
    case 0x0301: /* Standby -> Configured */
        if (!zdev || zdev->state == ZPCI_FN_STATE_CONFIGURED)
            break;
        zdev->state = ZPCI_FN_STATE_CONFIGURED;
        ret = zpci_enable_device(zdev);
        if (ret)
            break;
        pci_rescan_bus(zdev->bus);
        break;
    case 0x0302: /* Reserved -> Standby */
        clp_add_pci_device(ccdf->fid, ccdf->fh, 0);
        break;
    case 0x0303: /* Deconfiguration requested */
        if (pdev)
            pci_stop_and_remove_bus_device(pdev);

        ret = zpci_disable_device(zdev);
        if (ret)
            break;

        ret = sclp_pci_deconfigure(zdev->fid);
        zpci_dbg(3, "deconf fid:%x, rc:%d\n", zdev->fid, ret);
        if (!ret)
            zdev->state = ZPCI_FN_STATE_STANDBY;

        break;
    case 0x0304: /* Configured -> Standby */
        if (pdev)
            pci_stop_and_remove_bus_device(pdev);

        zpci_disable_device(zdev);
        zdev->state = ZPCI_FN_STATE_STANDBY;
        break;
    case 0x0306: /* 0x308 or 0x302 for multiple devices */
        clp_rescan_pci_devices();
        break;
    case 0x0308: /* Standby -> Reserved */
        pci_stop_root_bus(zdev->bus);
        pci_remove_root_bus(zdev->bus);
        break;
    default:
        break;
    }
}
Ejemplo n.º 2
0
int iproc_pcie_remove(struct iproc_pcie *pcie)
{
	pci_stop_root_bus(pcie->root_bus);
	pci_remove_root_bus(pcie->root_bus);

	phy_power_off(pcie->phy);
	phy_exit(pcie->phy);

	return 0;
}
Ejemplo n.º 3
0
Archivo: vphb.c Proyecto: 020gzh/linux
void cxl_pci_vphb_remove(struct cxl_afu *afu)
{
	struct pci_controller *phb;

	/* If there is no configuration record we won't have one of these */
	if (!afu || !afu->phb)
		return;

	phb = afu->phb;
	afu->phb = NULL;

	pci_remove_root_bus(phb->bus);
	pcibios_free_controller(phb);
}
Ejemplo n.º 4
0
void cxl_pci_vphb_remove(struct cxl_afu *afu)
{
	struct pci_controller *phb;

	/* If there is no configuration record we won't have one of these */
	if (!afu || !afu->phb)
		return;

	phb = afu->phb;
	afu->phb = NULL;

	pci_remove_root_bus(phb->bus);
	/*
	 * We don't free phb here - that's handled by
	 * pcibios_free_controller_deferred()
	 */
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
0
static void __zpci_event_availability(struct zpci_ccdf_avail *ccdf)
{
	struct zpci_dev *zdev = get_zdev_by_fid(ccdf->fid);
	struct pci_dev *pdev = NULL;
	int ret;

	if (zdev)
		pdev = pci_get_slot(zdev->bus, ZPCI_DEVFN);

	pr_info("%s: Event 0x%x reconfigured PCI function 0x%x\n",
		pdev ? pci_name(pdev) : "n/a", ccdf->pec, ccdf->fid);
	zpci_err("avail CCDF:\n");
	zpci_err_hex(ccdf, sizeof(*ccdf));

	switch (ccdf->pec) {
	case 0x0301: /* Reserved|Standby -> Configured */
		if (!zdev) {
			ret = clp_add_pci_device(ccdf->fid, ccdf->fh, 0);
			if (ret)
				break;
			zdev = get_zdev_by_fid(ccdf->fid);
		}
		if (!zdev || zdev->state != ZPCI_FN_STATE_STANDBY)
			break;
		zdev->state = ZPCI_FN_STATE_CONFIGURED;
		zdev->fh = ccdf->fh;
		ret = zpci_enable_device(zdev);
		if (ret)
			break;
		pci_lock_rescan_remove();
		pci_rescan_bus(zdev->bus);
		pci_unlock_rescan_remove();
		break;
	case 0x0302: /* Reserved -> Standby */
		if (!zdev)
			clp_add_pci_device(ccdf->fid, ccdf->fh, 0);
		break;
	case 0x0303: /* Deconfiguration requested */
		if (pdev)
			pci_stop_and_remove_bus_device_locked(pdev);

		ret = zpci_disable_device(zdev);
		if (ret)
			break;

		ret = sclp_pci_deconfigure(zdev->fid);
		zpci_dbg(3, "deconf fid:%x, rc:%d\n", zdev->fid, ret);
		if (!ret)
			zdev->state = ZPCI_FN_STATE_STANDBY;

		break;
	case 0x0304: /* Configured -> Standby */
		if (pdev) {
			/* Give the driver a hint that the function is
			 * already unusable. */
			pdev->error_state = pci_channel_io_perm_failure;
			pci_stop_and_remove_bus_device_locked(pdev);
		}

		zdev->fh = ccdf->fh;
		zpci_disable_device(zdev);
		zdev->state = ZPCI_FN_STATE_STANDBY;
		break;
	case 0x0306: /* 0x308 or 0x302 for multiple devices */
		clp_rescan_pci_devices();
		break;
	case 0x0308: /* Standby -> Reserved */
		if (!zdev)
			break;
		pci_stop_root_bus(zdev->bus);
		pci_remove_root_bus(zdev->bus);
		break;
	default:
		break;
	}
	if (pdev)
		pci_dev_put(pdev);
}
Ejemplo n.º 7
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;
}