static int pr_mgmt_init()

in dfl-fme-pr.c [369:437]


static int pr_mgmt_init(struct platform_device *pdev,
			struct dfl_feature *feature)
{
	struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
	struct dfl_fme_region *fme_region;
	struct dfl_fme_bridge *fme_br;
	struct platform_device *mgr;
	struct dfl_fme *priv;
	void __iomem *fme_hdr;
	int ret = -ENODEV, i = 0;
	u64 fme_cap, port_offset;

	fme_hdr = dfl_get_feature_ioaddr_by_id(&pdev->dev,
					       FME_FEATURE_ID_HEADER);

	mutex_lock(&pdata->lock);
	priv = dfl_fpga_pdata_get_private(pdata);

	/* Initialize the region and bridge sub device list */
	INIT_LIST_HEAD(&priv->region_list);
	INIT_LIST_HEAD(&priv->bridge_list);

	/* Create fpga mgr platform device */
	mgr = dfl_fme_create_mgr(pdata, feature);
	if (IS_ERR(mgr)) {
		dev_err(&pdev->dev, "fail to create fpga mgr pdev\n");
		goto unlock;
	}

	priv->mgr = mgr;

	/* Read capability register to check number of regions and bridges */
	fme_cap = readq(fme_hdr + FME_HDR_CAP);
	for (; i < FIELD_GET(FME_CAP_NUM_PORTS, fme_cap); i++) {
		port_offset = readq(fme_hdr + FME_HDR_PORT_OFST(i));
		if (!(port_offset & FME_PORT_OFST_IMP))
			continue;

		/* Create bridge for each port */
		fme_br = dfl_fme_create_bridge(pdata, i);
		if (IS_ERR(fme_br)) {
			ret = PTR_ERR(fme_br);
			goto destroy_region;
		}

		list_add(&fme_br->node, &priv->bridge_list);

		/* Create region for each port */
		fme_region = dfl_fme_create_region(pdata, mgr,
						   fme_br->br, i);
		if (IS_ERR(fme_region)) {
			ret = PTR_ERR(fme_region);
			goto destroy_region;
		}

		list_add(&fme_region->node, &priv->region_list);
	}
	mutex_unlock(&pdata->lock);

	return 0;

destroy_region:
	dfl_fme_destroy_regions(pdata);
	dfl_fme_destroy_bridges(pdata);
	dfl_fme_destroy_mgr(pdata);
unlock:
	mutex_unlock(&pdata->lock);
	return ret;
}