// SPDX-License-Identifier: GPL-2.0
/*
 * Driver for FPGA Device Feature List (DFL) Support
 *
 * Copyright (C) 2017-2018 Intel Corporation, Inc.
 *
 * Authors:
 *   Kang Luwei <luwei.kang@intel.com>
 *   Zhang Yi <yi.z.zhang@intel.com>
 *   Wu Hao <hao.wu@intel.com>
 *   Xiao Guangrong <guangrong.xiao@linux.intel.com>
 */
#include <linux/fpga-dfl.h>
#include <linux/module.h>
#include <linux/uaccess.h>

#include "dfl.h"

static DEFINE_MUTEX(dfl_id_mutex);

/*
 * when adding a new feature dev support in DFL framework, it's required to
 * add a new item in enum dfl_id_type and provide related information in below
 * dfl_devs table which is indexed by dfl_id_type, e.g. name string used for
 * platform device creation (define name strings in dfl.h, as they could be
 * reused by platform device drivers).
 *
 * if the new feature dev needs chardev support, then it's required to add
 * a new item in dfl_chardevs table and configure dfl_devs[i].devt_type as
 * index to dfl_chardevs table. If no chardev support just set devt_type
 * as one invalid index (DFL_FPGA_DEVT_MAX).
 */
enum dfl_fpga_devt_type {
	DFL_FPGA_DEVT_FME,
	DFL_FPGA_DEVT_PORT,
	DFL_FPGA_DEVT_MAX,
};

static struct lock_class_key dfl_pdata_keys[DFL_ID_MAX];

static const char *dfl_pdata_key_strings[DFL_ID_MAX] = {
	"dfl-fme-pdata",
	"dfl-port-pdata",
};

/**
 * dfl_dev_info - dfl feature device information.
 * @name: name string of the feature platform device.
 * @dfh_id: id value in Device Feature Header (DFH) register by DFL spec.
 * @id: idr id of the feature dev.
 * @devt_type: index to dfl_chrdevs[].
 */
struct dfl_dev_info {
	const char *name;
	u16 dfh_id;
	struct idr id;
	enum dfl_fpga_devt_type devt_type;
};

/* it is indexed by dfl_id_type */
static struct dfl_dev_info dfl_devs[] = {
	{.name = DFL_FPGA_FEATURE_DEV_FME, .dfh_id = DFH_ID_FIU_FME,
	 .devt_type = DFL_FPGA_DEVT_FME},
	{.name = DFL_FPGA_FEATURE_DEV_PORT, .dfh_id = DFH_ID_FIU_PORT,
	 .devt_type = DFL_FPGA_DEVT_PORT},
};

/**
 * dfl_chardev_info - chardev information of dfl feature device
 * @name: nmae string of the char device.
 * @devt: devt of the char device.
 */
struct dfl_chardev_info {
	const char *name;
	dev_t devt;
};

/* indexed by enum dfl_fpga_devt_type */
static struct dfl_chardev_info dfl_chrdevs[] = {
	{.name = DFL_FPGA_FEATURE_DEV_FME},
	{.name = DFL_FPGA_FEATURE_DEV_PORT},
};

static void dfl_ids_init(void)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(dfl_devs); i++)
		idr_init(&dfl_devs[i].id);
}

static void dfl_ids_destroy(void)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(dfl_devs); i++)
		idr_destroy(&dfl_devs[i].id);
}

static int dfl_id_alloc(enum dfl_id_type type, struct device *dev)
{
	int id;

	WARN_ON(type >= DFL_ID_MAX);
	mutex_lock(&dfl_id_mutex);
	id = idr_alloc(&dfl_devs[type].id, dev, 0, 0, GFP_KERNEL);
	mutex_unlock(&dfl_id_mutex);

	return id;
}

static void dfl_id_free(enum dfl_id_type type, int id)
{
	WARN_ON(type >= DFL_ID_MAX);
	mutex_lock(&dfl_id_mutex);
	idr_remove(&dfl_devs[type].id, id);
	mutex_unlock(&dfl_id_mutex);
}

static enum dfl_id_type feature_dev_id_type(struct platform_device *pdev)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(dfl_devs); i++)
		if (!strcmp(dfl_devs[i].name, pdev->name))
			return i;

	return DFL_ID_MAX;
}

static enum dfl_id_type dfh_id_to_type(u16 id)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(dfl_devs); i++)
		if (dfl_devs[i].dfh_id == id)
			return i;

	return DFL_ID_MAX;
}

/*
 * introduce a global port_ops list, it allows port drivers to register ops
 * in such list, then other feature devices (e.g. FME), could use the port
 * functions even related port platform device is hidden. Below is one example,
 * in virtualization case of PCIe-based FPGA DFL device, when SRIOV is
 * enabled, port (and it's AFU) is turned into VF and port platform device
 * is hidden from system but it's still required to access port to finish FPGA
 * reconfiguration function in FME.
 */

static DEFINE_MUTEX(dfl_port_ops_mutex);
static LIST_HEAD(dfl_port_ops_list);

/**
 * dfl_fpga_port_ops_get - get matched port ops from the global list
 * @pdev: platform device to match with associated port ops.
 * Return: matched port ops on success, NULL otherwise.
 *
 * Please note that must dfl_fpga_port_ops_put after use the port_ops.
 */
struct dfl_fpga_port_ops *dfl_fpga_port_ops_get(struct platform_device *pdev)
{
	struct dfl_fpga_port_ops *ops = NULL;

	mutex_lock(&dfl_port_ops_mutex);
	if (list_empty(&dfl_port_ops_list))
		goto done;

	list_for_each_entry(ops, &dfl_port_ops_list, node) {
		/* match port_ops using the name of platform device */
		if (!strcmp(pdev->name, ops->name)) {
			if (!try_module_get(ops->owner))
				ops = NULL;
			goto done;
		}
	}

	ops = NULL;
done:
	mutex_unlock(&dfl_port_ops_mutex);
	return ops;
}
EXPORT_SYMBOL_GPL(dfl_fpga_port_ops_get);

/**
 * dfl_fpga_port_ops_put - put port ops
 * @ops: port ops.
 */
void dfl_fpga_port_ops_put(struct dfl_fpga_port_ops *ops)
{
	if (ops && ops->owner)
		module_put(ops->owner);
}
EXPORT_SYMBOL_GPL(dfl_fpga_port_ops_put);

/**
 * dfl_fpga_port_ops_add - add port_ops to global list
 * @ops: port ops to add.
 */
void dfl_fpga_port_ops_add(struct dfl_fpga_port_ops *ops)
{
	mutex_lock(&dfl_port_ops_mutex);
	list_add_tail(&ops->node, &dfl_port_ops_list);
	mutex_unlock(&dfl_port_ops_mutex);
}
EXPORT_SYMBOL_GPL(dfl_fpga_port_ops_add);

/**
 * dfl_fpga_port_ops_del - remove port_ops from global list
 * @ops: port ops to del.
 */
void dfl_fpga_port_ops_del(struct dfl_fpga_port_ops *ops)
{
	mutex_lock(&dfl_port_ops_mutex);
	list_del(&ops->node);
	mutex_unlock(&dfl_port_ops_mutex);
}
EXPORT_SYMBOL_GPL(dfl_fpga_port_ops_del);

/**
 * dfl_fpga_check_port_id - check the port id
 * @pdev: port platform device.
 * @pport_id: port id to compare.
 *
 * Return: 1 if port device matches with given port id, otherwise 0.
 */
int dfl_fpga_check_port_id(struct platform_device *pdev, void *pport_id)
{
	struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
	struct dfl_fpga_port_ops *port_ops;

	if (pdata->id != FEATURE_DEV_ID_UNUSED)
		return pdata->id == *(int *)pport_id;

	port_ops = dfl_fpga_port_ops_get(pdev);
	if (!port_ops || !port_ops->get_id)
		return 0;

	pdata->id = port_ops->get_id(pdev);
	dfl_fpga_port_ops_put(port_ops);

	return pdata->id == *(int *)pport_id;
}
EXPORT_SYMBOL_GPL(dfl_fpga_check_port_id);

static DEFINE_IDA(dfl_device_ida);

static const struct dfl_device_id *
dfl_match_one_device(const struct dfl_device_id *id, struct dfl_device *ddev)
{
	if (id->type == ddev->type && id->feature_id == ddev->feature_id)
		return id;

	return NULL;
}

static int dfl_bus_match(struct device *dev, struct device_driver *drv)
{
	struct dfl_device *ddev = to_dfl_dev(dev);
	struct dfl_driver *ddrv = to_dfl_drv(drv);
	const struct dfl_device_id *id_entry;

	id_entry = ddrv->id_table;
	if (id_entry) {
		while (id_entry->feature_id) {
			if (dfl_match_one_device(id_entry, ddev)) {
				ddev->id_entry = id_entry;
				return 1;
			}
			id_entry++;
		}
	}

	return 0;
}

static int dfl_bus_probe(struct device *dev)
{
	struct dfl_driver *ddrv = to_dfl_drv(dev->driver);
	struct dfl_device *ddev = to_dfl_dev(dev);

	return ddrv->probe(ddev);
}

static int dfl_bus_remove(struct device *dev)
{
	struct dfl_driver *ddrv = to_dfl_drv(dev->driver);
	struct dfl_device *ddev = to_dfl_dev(dev);

	if (ddrv->remove)
		ddrv->remove(ddev);

	return 0;
}

static int dfl_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
{
	struct dfl_device *ddev = to_dfl_dev(dev);

	/* The type has 4 valid bits and feature_id has 12 valid bits */
	return add_uevent_var(env, "MODALIAS=dfl:t%01Xf%03X",
			      ddev->type, ddev->feature_id);
}

static ssize_t
type_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct dfl_device *ddev = to_dfl_dev(dev);

	return sprintf(buf, "0x%x\n", ddev->type);
}
static DEVICE_ATTR_RO(type);

static ssize_t
feature_id_show(struct device *dev, struct device_attribute *attr, char *buf)
{
	struct dfl_device *ddev = to_dfl_dev(dev);

	return sprintf(buf, "0x%x\n", ddev->feature_id);
}
static DEVICE_ATTR_RO(feature_id);

static struct attribute *dfl_dev_attrs[] = {
	&dev_attr_type.attr,
	&dev_attr_feature_id.attr,
	NULL,
};
ATTRIBUTE_GROUPS(dfl_dev);

static struct bus_type dfl_bus_type = {
	.name		= "dfl",
	.match		= dfl_bus_match,
	.probe		= dfl_bus_probe,
	.remove		= dfl_bus_remove,
	.uevent		= dfl_bus_uevent,
	.dev_groups	= dfl_dev_groups,
};

static void release_dfl_dev(struct device *dev)
{
	struct dfl_device *ddev = to_dfl_dev(dev);

	if (ddev->mmio_res.parent)
		release_resource(&ddev->mmio_res);

	ida_simple_remove(&dfl_device_ida, ddev->id);
	kfree(ddev->irqs);
	kfree(ddev);
}

static struct dfl_device *
dfl_dev_add(struct dfl_feature_platform_data *pdata,
	    struct dfl_feature *feature)
{
	struct platform_device *pdev = pdata->dev;
	struct resource *parent_res;
	struct dfl_device *ddev;
	int id, i, ret;

	ddev = kzalloc(sizeof(*ddev), GFP_KERNEL);
	if (!ddev)
		return ERR_PTR(-ENOMEM);

	id = ida_simple_get(&dfl_device_ida, 0, 0, GFP_KERNEL);
	if (id < 0) {
		dev_err(&pdev->dev, "unable to get id\n");
		kfree(ddev);
		return ERR_PTR(id);
	}

	/* freeing resources by put_device() after device_initialize() */
	device_initialize(&ddev->dev);
	ddev->dev.parent = &pdev->dev;
	ddev->dev.bus = &dfl_bus_type;
	ddev->dev.release = release_dfl_dev;
	ddev->id = id;
	ret = dev_set_name(&ddev->dev, "dfl_dev.%d", id);
	if (ret)
		goto put_dev;

	ddev->type = feature_dev_id_type(pdev);
	ddev->feature_id = feature->id;
	ddev->cdev = pdata->dfl_cdev;

	/* add mmio resource */
	parent_res = &pdev->resource[feature->resource_index];
	ddev->mmio_res.flags = IORESOURCE_MEM;
	ddev->mmio_res.start = parent_res->start;
	ddev->mmio_res.end = parent_res->end;
	ddev->mmio_res.name = dev_name(&ddev->dev);
	ret = insert_resource(parent_res, &ddev->mmio_res);
	if (ret) {
		dev_err(&pdev->dev, "%s failed to claim resource: %pR\n",
			dev_name(&ddev->dev), &ddev->mmio_res);
		goto put_dev;
	}

	/* then add irq resource */
	if (feature->nr_irqs) {
		ddev->irqs = kcalloc(feature->nr_irqs,
				     sizeof(*ddev->irqs), GFP_KERNEL);
		if (!ddev->irqs) {
			ret = -ENOMEM;
			goto put_dev;
		}

		for (i = 0; i < feature->nr_irqs; i++)
			ddev->irqs[i] = feature->irq_ctx[i].irq;

		ddev->num_irqs = feature->nr_irqs;
	}

	ret = device_add(&ddev->dev);
	if (ret)
		goto put_dev;

	dev_dbg(&pdev->dev, "add dfl_dev: %s\n", dev_name(&ddev->dev));
	return ddev;

put_dev:
	/* calls release_dfl_dev() which does the clean up  */
	put_device(&ddev->dev);
	return ERR_PTR(ret);
}

static void dfl_devs_remove(struct dfl_feature_platform_data *pdata)
{
	struct dfl_feature *feature;

	dfl_fpga_dev_for_each_feature(pdata, feature) {
		if (feature->ddev) {
			device_unregister(&feature->ddev->dev);
			feature->ddev = NULL;
		}
	}
}

static int dfl_devs_add(struct dfl_feature_platform_data *pdata)
{
	struct dfl_feature *feature;
	struct dfl_device *ddev;
	int ret;

	dfl_fpga_dev_for_each_feature(pdata, feature) {
		if (feature->ioaddr)
			continue;

		if (feature->ddev) {
			ret = -EEXIST;
			goto err;
		}

		ddev = dfl_dev_add(pdata, feature);
		if (IS_ERR(ddev)) {
			ret = PTR_ERR(ddev);
			goto err;
		}

		feature->ddev = ddev;
	}

	return 0;

err:
	dfl_devs_remove(pdata);
	return ret;
}

int __dfl_driver_register(struct dfl_driver *dfl_drv, struct module *owner)
{
	if (!dfl_drv || !dfl_drv->probe || !dfl_drv->id_table)
		return -EINVAL;

	dfl_drv->drv.owner = owner;
	dfl_drv->drv.bus = &dfl_bus_type;

	return driver_register(&dfl_drv->drv);
}
EXPORT_SYMBOL(__dfl_driver_register);

void dfl_driver_unregister(struct dfl_driver *dfl_drv)
{
	driver_unregister(&dfl_drv->drv);
}
EXPORT_SYMBOL(dfl_driver_unregister);

#define is_header_feature(feature) ((feature)->id == FEATURE_ID_FIU_HEADER)

/**
 * dfl_fpga_dev_feature_uinit - uinit for sub features of dfl feature device
 * @pdev: feature device.
 */
void dfl_fpga_dev_feature_uinit(struct platform_device *pdev)
{
	struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
	struct dfl_feature *feature;

	dfl_devs_remove(pdata);

	dfl_fpga_dev_for_each_feature(pdata, feature) {
		if (feature->ops) {
			if (feature->ops->uinit)
				feature->ops->uinit(pdev, feature);
			feature->ops = NULL;
		}
	}
}
EXPORT_SYMBOL_GPL(dfl_fpga_dev_feature_uinit);

static int dfl_feature_instance_init(struct platform_device *pdev,
				     struct dfl_feature_platform_data *pdata,
				     struct dfl_feature *feature,
				     struct dfl_feature_driver *drv)
{
	void __iomem *base;
	int ret = 0;

	if (!is_header_feature(feature)) {
		base = devm_platform_ioremap_resource(pdev,
						      feature->resource_index);
		if (IS_ERR(base)) {
			dev_err(&pdev->dev,
				"ioremap failed for feature 0x%x!\n",
				feature->id);
			return PTR_ERR(base);
		}

		feature->ioaddr = base;
	}

	if (drv->ops->init) {
		ret = drv->ops->init(pdev, feature);
		if (ret)
			return ret;
	}

	feature->ops = drv->ops;

	return ret;
}

static bool dfl_feature_drv_match(struct dfl_feature *feature,
				  struct dfl_feature_driver *driver)
{
	const struct dfl_feature_id *ids = driver->id_table;

	if (ids) {
		while (ids->id) {
			if (ids->id == feature->id)
				return true;
			ids++;
		}
	}
	return false;
}

/**
 * dfl_fpga_dev_feature_init - init for sub features of dfl feature device
 * @pdev: feature device.
 * @feature_drvs: drvs for sub features.
 *
 * This function will match sub features with given feature drvs list and
 * use matched drv to init related sub feature.
 *
 * Return: 0 on success, negative error code otherwise.
 */
int dfl_fpga_dev_feature_init(struct platform_device *pdev,
			      struct dfl_feature_driver *feature_drvs)
{
	struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
	struct dfl_feature_driver *drv = feature_drvs;
	struct dfl_feature *feature;
	int ret;

	while (drv->ops) {
		dfl_fpga_dev_for_each_feature(pdata, feature) {
			if (dfl_feature_drv_match(feature, drv)) {
				ret = dfl_feature_instance_init(pdev, pdata,
								feature, drv);
				if (ret)
					goto exit;
			}
		}
		drv++;
	}

	ret = dfl_devs_add(pdata);
	if (ret)
		goto exit;

	return 0;
exit:
	dfl_fpga_dev_feature_uinit(pdev);
	return ret;
}
EXPORT_SYMBOL_GPL(dfl_fpga_dev_feature_init);

static void dfl_chardev_uinit(void)
{
	int i;

	for (i = 0; i < DFL_FPGA_DEVT_MAX; i++)
		if (MAJOR(dfl_chrdevs[i].devt)) {
			unregister_chrdev_region(dfl_chrdevs[i].devt,
						 MINORMASK + 1);
			dfl_chrdevs[i].devt = MKDEV(0, 0);
		}
}

static int dfl_chardev_init(void)
{
	int i, ret;

	for (i = 0; i < DFL_FPGA_DEVT_MAX; i++) {
		ret = alloc_chrdev_region(&dfl_chrdevs[i].devt, 0,
					  MINORMASK + 1, dfl_chrdevs[i].name);
		if (ret)
			goto exit;
	}

	return 0;

exit:
	dfl_chardev_uinit();
	return ret;
}

static dev_t dfl_get_devt(enum dfl_fpga_devt_type type, int id)
{
	if (type >= DFL_FPGA_DEVT_MAX)
		return 0;

	return MKDEV(MAJOR(dfl_chrdevs[type].devt), id);
}

/**
 * dfl_fpga_dev_ops_register - register cdev ops for feature dev
 *
 * @pdev: feature dev.
 * @fops: file operations for feature dev's cdev.
 * @owner: owning module/driver.
 *
 * Return: 0 on success, negative error code otherwise.
 */
int dfl_fpga_dev_ops_register(struct platform_device *pdev,
			      const struct file_operations *fops,
			      struct module *owner)
{
	struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);

	cdev_init(&pdata->cdev, fops);
	pdata->cdev.owner = owner;

	/*
	 * set parent to the feature device so that its refcount is
	 * decreased after the last refcount of cdev is gone, that
	 * makes sure the feature device is valid during device
	 * file's life-cycle.
	 */
	pdata->cdev.kobj.parent = &pdev->dev.kobj;

	return cdev_add(&pdata->cdev, pdev->dev.devt, 1);
}
EXPORT_SYMBOL_GPL(dfl_fpga_dev_ops_register);

/**
 * dfl_fpga_dev_ops_unregister - unregister cdev ops for feature dev
 * @pdev: feature dev.
 */
void dfl_fpga_dev_ops_unregister(struct platform_device *pdev)
{
	struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);

	cdev_del(&pdata->cdev);
}
EXPORT_SYMBOL_GPL(dfl_fpga_dev_ops_unregister);

/**
 * struct build_feature_devs_info - info collected during feature dev build.
 *
 * @dev: device to enumerate.
 * @cdev: the container device for all feature devices.
 * @nr_irqs: number of irqs for all feature devices.
 * @irq_table: Linux IRQ numbers for all irqs, indexed by local irq index of
 *	       this device.
 * @feature_dev: current feature device.
 * @ioaddr: header register region address of current FIU in enumeration.
 * @start: register resource start of current FIU.
 * @len: max register resource length of current FIU.
 * @sub_features: a sub features linked list for feature device in enumeration.
 * @feature_num: number of sub features for feature device in enumeration.
 */
struct build_feature_devs_info {
	struct device *dev;
	struct dfl_fpga_cdev *cdev;
	unsigned int nr_irqs;
	int *irq_table;

	struct platform_device *feature_dev;
	void __iomem *ioaddr;
	resource_size_t start;
	resource_size_t len;
	struct list_head sub_features;
	int feature_num;
};

/**
 * struct dfl_feature_info - sub feature info collected during feature dev build
 *
 * @fid: id of this sub feature.
 * @mmio_res: mmio resource of this sub feature.
 * @ioaddr: mapped base address of mmio resource.
 * @node: node in sub_features linked list.
 * @irq_base: start of irq index in this sub feature.
 * @nr_irqs: number of irqs of this sub feature.
 */
struct dfl_feature_info {
	u16 fid;
	struct resource mmio_res;
	void __iomem *ioaddr;
	struct list_head node;
	unsigned int irq_base;
	unsigned int nr_irqs;
};

static void dfl_fpga_cdev_add_port_dev(struct dfl_fpga_cdev *cdev,
				       struct platform_device *port)
{
	struct dfl_feature_platform_data *pdata = dev_get_platdata(&port->dev);

	mutex_lock(&cdev->lock);
	list_add(&pdata->node, &cdev->port_dev_list);
	get_device(&pdata->dev->dev);
	mutex_unlock(&cdev->lock);
}

/*
 * register current feature device, it is called when we need to switch to
 * another feature parsing or we have parsed all features on given device
 * feature list.
 */
static int build_info_commit_dev(struct build_feature_devs_info *binfo)
{
	struct platform_device *fdev = binfo->feature_dev;
	struct dfl_feature_platform_data *pdata;
	struct dfl_feature_info *finfo, *p;
	enum dfl_id_type type;
	int ret, index = 0, res_idx = 0;

	type = feature_dev_id_type(fdev);
	if (WARN_ON_ONCE(type >= DFL_ID_MAX))
		return -EINVAL;

	/*
	 * we do not need to care for the memory which is associated with
	 * the platform device. After calling platform_device_unregister(),
	 * it will be automatically freed by device's release() callback,
	 * platform_device_release().
	 */
	pdata = kzalloc(struct_size(pdata, features, binfo->feature_num), GFP_KERNEL);
	if (!pdata)
		return -ENOMEM;

	pdata->dev = fdev;
	pdata->num = binfo->feature_num;
	pdata->dfl_cdev = binfo->cdev;
	pdata->id = FEATURE_DEV_ID_UNUSED;
	mutex_init(&pdata->lock);
	lockdep_set_class_and_name(&pdata->lock, &dfl_pdata_keys[type],
				   dfl_pdata_key_strings[type]);

	/*
	 * the count should be initialized to 0 to make sure
	 *__fpga_port_enable() following __fpga_port_disable()
	 * works properly for port device.
	 * and it should always be 0 for fme device.
	 */
	WARN_ON(pdata->disable_count);

	fdev->dev.platform_data = pdata;

	/* each sub feature has one MMIO resource */
	fdev->num_resources = binfo->feature_num;
	fdev->resource = kcalloc(binfo->feature_num, sizeof(*fdev->resource),
				 GFP_KERNEL);
	if (!fdev->resource)
		return -ENOMEM;

	/* fill features and resource information for feature dev */
	list_for_each_entry_safe(finfo, p, &binfo->sub_features, node) {
		struct dfl_feature *feature = &pdata->features[index++];
		struct dfl_feature_irq_ctx *ctx;
		unsigned int i;

		/* save resource information for each feature */
		feature->dev = fdev;
		feature->id = finfo->fid;

		/*
		 * the FIU header feature has some fundamental functions (sriov
		 * set, port enable/disable) needed for the dfl bus device and
		 * other sub features. So its mmio resource should be mapped by
		 * DFL bus device. And we should not assign it to feature
		 * devices (dfl-fme/afu) again.
		 */
		if (is_header_feature(feature)) {
			feature->resource_index = -1;
			feature->ioaddr =
				devm_ioremap_resource(binfo->dev,
						      &finfo->mmio_res);
			if (IS_ERR(feature->ioaddr))
				return PTR_ERR(feature->ioaddr);
		} else {
			feature->resource_index = res_idx;
			fdev->resource[res_idx++] = finfo->mmio_res;
		}

		if (finfo->nr_irqs) {
			ctx = devm_kcalloc(binfo->dev, finfo->nr_irqs,
					   sizeof(*ctx), GFP_KERNEL);
			if (!ctx)
				return -ENOMEM;

			for (i = 0; i < finfo->nr_irqs; i++)
				ctx[i].irq =
					binfo->irq_table[finfo->irq_base + i];

			feature->irq_ctx = ctx;
			feature->nr_irqs = finfo->nr_irqs;
		}

		list_del(&finfo->node);
		kfree(finfo);
	}

	ret = platform_device_add(binfo->feature_dev);
	if (!ret) {
		if (type == PORT_ID)
			dfl_fpga_cdev_add_port_dev(binfo->cdev,
						   binfo->feature_dev);
		else
			binfo->cdev->fme_dev =
					get_device(&binfo->feature_dev->dev);
		/*
		 * reset it to avoid build_info_free() freeing their resource.
		 *
		 * The resource of successfully registered feature devices
		 * will be freed by platform_device_unregister(). See the
		 * comments in build_info_create_dev().
		 */
		binfo->feature_dev = NULL;
	}

	return ret;
}

static int
build_info_create_dev(struct build_feature_devs_info *binfo,
		      enum dfl_id_type type)
{
	struct platform_device *fdev;

	if (type >= DFL_ID_MAX)
		return -EINVAL;

	/*
	 * we use -ENODEV as the initialization indicator which indicates
	 * whether the id need to be reclaimed
	 */
	fdev = platform_device_alloc(dfl_devs[type].name, -ENODEV);
	if (!fdev)
		return -ENOMEM;

	binfo->feature_dev = fdev;
	binfo->feature_num = 0;

	INIT_LIST_HEAD(&binfo->sub_features);

	fdev->id = dfl_id_alloc(type, &fdev->dev);
	if (fdev->id < 0)
		return fdev->id;

	fdev->dev.parent = &binfo->cdev->region->dev;
	fdev->dev.devt = dfl_get_devt(dfl_devs[type].devt_type, fdev->id);

	return 0;
}

static void build_info_free(struct build_feature_devs_info *binfo)
{
	struct dfl_feature_info *finfo, *p;

	/*
	 * it is a valid id, free it. See comments in
	 * build_info_create_dev()
	 */
	if (binfo->feature_dev && binfo->feature_dev->id >= 0) {
		dfl_id_free(feature_dev_id_type(binfo->feature_dev),
			    binfo->feature_dev->id);

		list_for_each_entry_safe(finfo, p, &binfo->sub_features, node) {
			list_del(&finfo->node);
			kfree(finfo);
		}
	}

	platform_device_put(binfo->feature_dev);

	devm_kfree(binfo->dev, binfo);
}

static inline u32 feature_size(void __iomem *start)
{
	u64 v = readq(start + DFH);
	u32 ofst = FIELD_GET(DFH_NEXT_HDR_OFST, v);
	/* workaround for private features with invalid size, use 4K instead */
	return ofst ? ofst : 4096;
}

static u16 feature_id(void __iomem *start)
{
	u64 v = readq(start + DFH);
	u16 id = FIELD_GET(DFH_ID, v);
	u8 type = FIELD_GET(DFH_TYPE, v);

	if (type == DFH_TYPE_FIU)
		return FEATURE_ID_FIU_HEADER;
	else if (type == DFH_TYPE_PRIVATE)
		return id;
	else if (type == DFH_TYPE_AFU)
		return FEATURE_ID_AFU;

	WARN_ON(1);
	return 0;
}

static int parse_feature_irqs(struct build_feature_devs_info *binfo,
			      resource_size_t ofst, u16 fid,
			      unsigned int *irq_base, unsigned int *nr_irqs)
{
	void __iomem *base = binfo->ioaddr + ofst;
	unsigned int i, ibase, inr = 0;
	int virq;
	u64 v;

	/*
	 * Ideally DFL framework should only read info from DFL header, but
	 * current version DFL only provides mmio resources information for
	 * each feature in DFL Header, no field for interrupt resources.
	 * Interrupt resource information is provided by specific mmio
	 * registers of each private feature which supports interrupt. So in
	 * order to parse and assign irq resources, DFL framework has to look
	 * into specific capability registers of these private features.
	 *
	 * Once future DFL version supports generic interrupt resource
	 * information in common DFL headers, the generic interrupt parsing
	 * code will be added. But in order to be compatible to old version
	 * DFL, the driver may still fall back to these quirks.
	 */
	switch (fid) {
	case PORT_FEATURE_ID_UINT:
		v = readq(base + PORT_UINT_CAP);
		ibase = FIELD_GET(PORT_UINT_CAP_FST_VECT, v);
		inr = FIELD_GET(PORT_UINT_CAP_INT_NUM, v);
		break;
	case PORT_FEATURE_ID_ERROR:
		v = readq(base + PORT_ERROR_CAP);
		ibase = FIELD_GET(PORT_ERROR_CAP_INT_VECT, v);
		inr = FIELD_GET(PORT_ERROR_CAP_SUPP_INT, v);
		break;
	case FME_FEATURE_ID_GLOBAL_ERR:
		v = readq(base + FME_ERROR_CAP);
		ibase = FIELD_GET(FME_ERROR_CAP_INT_VECT, v);
		inr = FIELD_GET(FME_ERROR_CAP_SUPP_INT, v);
		break;
	}

	if (!inr) {
		*irq_base = 0;
		*nr_irqs = 0;
		return 0;
	}

	dev_dbg(binfo->dev, "feature: 0x%x, irq_base: %u, nr_irqs: %u\n",
		fid, ibase, inr);

	if (ibase + inr > binfo->nr_irqs) {
		dev_err(binfo->dev,
			"Invalid interrupt number in feature 0x%x\n", fid);
		return -EINVAL;
	}

	for (i = 0; i < inr; i++) {
		virq = binfo->irq_table[ibase + i];
		if (virq < 0 || virq > NR_IRQS) {
			dev_err(binfo->dev,
				"Invalid irq table entry for feature 0x%x\n",
				fid);
			return -EINVAL;
		}
	}

	*irq_base = ibase;
	*nr_irqs = inr;

	return 0;
}

/*
 * when create sub feature instances, for private features, it doesn't need
 * to provide resource size and feature id as they could be read from DFH
 * register. For afu sub feature, its register region only contains user
 * defined registers, so never trust any information from it, just use the
 * resource size information provided by its parent FIU.
 */
static int
create_feature_instance(struct build_feature_devs_info *binfo,
			resource_size_t ofst, resource_size_t size, u16 fid)
{
	unsigned int irq_base, nr_irqs;
	struct dfl_feature_info *finfo;
	int ret;

	/* read feature size and id if inputs are invalid */
	size = size ? size : feature_size(binfo->ioaddr + ofst);
	fid = fid ? fid : feature_id(binfo->ioaddr + ofst);

	if (binfo->len - ofst < size)
		return -EINVAL;

	ret = parse_feature_irqs(binfo, ofst, fid, &irq_base, &nr_irqs);
	if (ret)
		return ret;

	finfo = kzalloc(sizeof(*finfo), GFP_KERNEL);
	if (!finfo)
		return -ENOMEM;

	finfo->fid = fid;
	finfo->mmio_res.start = binfo->start + ofst;
	finfo->mmio_res.end = finfo->mmio_res.start + size - 1;
	finfo->mmio_res.flags = IORESOURCE_MEM;
	finfo->irq_base = irq_base;
	finfo->nr_irqs = nr_irqs;

	list_add_tail(&finfo->node, &binfo->sub_features);
	binfo->feature_num++;

	return 0;
}

static int parse_feature_port_afu(struct build_feature_devs_info *binfo,
				  resource_size_t ofst)
{
	u64 v = readq(binfo->ioaddr + PORT_HDR_CAP);
	u32 size = FIELD_GET(PORT_CAP_MMIO_SIZE, v) << 10;

	WARN_ON(!size);

	return create_feature_instance(binfo, ofst, size, FEATURE_ID_AFU);
}

#define is_feature_dev_detected(binfo) (!!(binfo)->feature_dev)

static int parse_feature_afu(struct build_feature_devs_info *binfo,
			     resource_size_t ofst)
{
	if (!is_feature_dev_detected(binfo)) {
		dev_err(binfo->dev, "this AFU does not belong to any FIU.\n");
		return -EINVAL;
	}

	switch (feature_dev_id_type(binfo->feature_dev)) {
	case PORT_ID:
		return parse_feature_port_afu(binfo, ofst);
	default:
		dev_info(binfo->dev, "AFU belonging to FIU %s is not supported yet.\n",
			 binfo->feature_dev->name);
	}

	return 0;
}

static int build_info_prepare(struct build_feature_devs_info *binfo,
			      resource_size_t start, resource_size_t len)
{
	struct device *dev = binfo->dev;
	void __iomem *ioaddr;

	if (!devm_request_mem_region(dev, start, len, dev_name(dev))) {
		dev_err(dev, "request region fail, start:%pa, len:%pa\n",
			&start, &len);
		return -EBUSY;
	}

	ioaddr = devm_ioremap(dev, start, len);
	if (!ioaddr) {
		dev_err(dev, "ioremap region fail, start:%pa, len:%pa\n",
			&start, &len);
		return -ENOMEM;
	}

	binfo->start = start;
	binfo->len = len;
	binfo->ioaddr = ioaddr;

	return 0;
}

static void build_info_complete(struct build_feature_devs_info *binfo)
{
	devm_iounmap(binfo->dev, binfo->ioaddr);
	devm_release_mem_region(binfo->dev, binfo->start, binfo->len);
}

static int parse_feature_fiu(struct build_feature_devs_info *binfo,
			     resource_size_t ofst)
{
	int ret = 0;
	u32 offset;
	u16 id;
	u64 v;

	if (is_feature_dev_detected(binfo)) {
		build_info_complete(binfo);

		ret = build_info_commit_dev(binfo);
		if (ret)
			return ret;

		ret = build_info_prepare(binfo, binfo->start + ofst,
					 binfo->len - ofst);
		if (ret)
			return ret;
	}

	v = readq(binfo->ioaddr + DFH);
	id = FIELD_GET(DFH_ID, v);

	/* create platform device for dfl feature dev */
	ret = build_info_create_dev(binfo, dfh_id_to_type(id));
	if (ret)
		return ret;

	ret = create_feature_instance(binfo, 0, 0, 0);
	if (ret)
		return ret;
	/*
	 * find and parse FIU's child AFU via its NEXT_AFU register.
	 * please note that only Port has valid NEXT_AFU pointer per spec.
	 */
	v = readq(binfo->ioaddr + NEXT_AFU);

	offset = FIELD_GET(NEXT_AFU_NEXT_DFH_OFST, v);
	if (offset)
		return parse_feature_afu(binfo, offset);

	dev_dbg(binfo->dev, "No AFUs detected on FIU %d\n", id);

	return ret;
}

static int parse_feature_private(struct build_feature_devs_info *binfo,
				 resource_size_t ofst)
{
	if (!is_feature_dev_detected(binfo)) {
		dev_err(binfo->dev, "the private feature 0x%x does not belong to any AFU.\n",
			feature_id(binfo->ioaddr + ofst));
		return -EINVAL;
	}

	return create_feature_instance(binfo, ofst, 0, 0);
}

/**
 * parse_feature - parse a feature on given device feature list
 *
 * @binfo: build feature devices information.
 * @ofst: offset to current FIU header
 */
static int parse_feature(struct build_feature_devs_info *binfo,
			 resource_size_t ofst)
{
	u64 v;
	u32 type;

	v = readq(binfo->ioaddr + ofst + DFH);
	type = FIELD_GET(DFH_TYPE, v);

	switch (type) {
	case DFH_TYPE_AFU:
		return parse_feature_afu(binfo, ofst);
	case DFH_TYPE_PRIVATE:
		return parse_feature_private(binfo, ofst);
	case DFH_TYPE_FIU:
		return parse_feature_fiu(binfo, ofst);
	default:
		dev_info(binfo->dev,
			 "Feature Type %x is not supported.\n", type);
	}

	return 0;
}

static int parse_feature_list(struct build_feature_devs_info *binfo,
			      resource_size_t start, resource_size_t len)
{
	resource_size_t end = start + len;
	int ret = 0;
	u32 ofst = 0;
	u64 v;

	ret = build_info_prepare(binfo, start, len);
	if (ret)
		return ret;

	/* walk through the device feature list via DFH's next DFH pointer. */
	for (; start < end; start += ofst) {
		if (end - start < DFH_SIZE) {
			dev_err(binfo->dev, "The region is too small to contain a feature.\n");
			return -EINVAL;
		}

		ret = parse_feature(binfo, start - binfo->start);
		if (ret)
			return ret;

		v = readq(binfo->ioaddr + start - binfo->start + DFH);
		ofst = FIELD_GET(DFH_NEXT_HDR_OFST, v);

		/* stop parsing if EOL(End of List) is set or offset is 0 */
		if ((v & DFH_EOL) || !ofst)
			break;
	}

	/* commit current feature device when reach the end of list */
	build_info_complete(binfo);

	if (is_feature_dev_detected(binfo))
		ret = build_info_commit_dev(binfo);

	return ret;
}

struct dfl_fpga_enum_info *dfl_fpga_enum_info_alloc(struct device *dev)
{
	struct dfl_fpga_enum_info *info;

	get_device(dev);

	info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
	if (!info) {
		put_device(dev);
		return NULL;
	}

	info->dev = dev;
	INIT_LIST_HEAD(&info->dfls);

	return info;
}
EXPORT_SYMBOL_GPL(dfl_fpga_enum_info_alloc);

void dfl_fpga_enum_info_free(struct dfl_fpga_enum_info *info)
{
	struct dfl_fpga_enum_dfl *tmp, *dfl;
	struct device *dev;

	if (!info)
		return;

	dev = info->dev;

	/* remove all device feature lists in the list. */
	list_for_each_entry_safe(dfl, tmp, &info->dfls, node) {
		list_del(&dfl->node);
		devm_kfree(dev, dfl);
	}

	/* remove irq table */
	if (info->irq_table)
		devm_kfree(dev, info->irq_table);

	devm_kfree(dev, info);
	put_device(dev);
}
EXPORT_SYMBOL_GPL(dfl_fpga_enum_info_free);

/**
 * dfl_fpga_enum_info_add_dfl - add info of a device feature list to enum info
 *
 * @info: ptr to dfl_fpga_enum_info
 * @start: mmio resource address of the device feature list.
 * @len: mmio resource length of the device feature list.
 *
 * One FPGA device may have one or more Device Feature Lists (DFLs), use this
 * function to add information of each DFL to common data structure for next
 * step enumeration.
 *
 * Return: 0 on success, negative error code otherwise.
 */
int dfl_fpga_enum_info_add_dfl(struct dfl_fpga_enum_info *info,
			       resource_size_t start, resource_size_t len)
{
	struct dfl_fpga_enum_dfl *dfl;

	dfl = devm_kzalloc(info->dev, sizeof(*dfl), GFP_KERNEL);
	if (!dfl)
		return -ENOMEM;

	dfl->start = start;
	dfl->len = len;

	list_add_tail(&dfl->node, &info->dfls);

	return 0;
}
EXPORT_SYMBOL_GPL(dfl_fpga_enum_info_add_dfl);

/**
 * dfl_fpga_enum_info_add_irq - add irq table to enum info
 *
 * @info: ptr to dfl_fpga_enum_info
 * @nr_irqs: number of irqs of the DFL fpga device to be enumerated.
 * @irq_table: Linux IRQ numbers for all irqs, indexed by local irq index of
 *	       this device.
 *
 * One FPGA device may have several interrupts. This function adds irq
 * information of the DFL fpga device to enum info for next step enumeration.
 * This function should be called before dfl_fpga_feature_devs_enumerate().
 * As we only support one irq domain for all DFLs in the same enum info, adding
 * irq table a second time for the same enum info will return error.
 *
 * If we need to enumerate DFLs which belong to different irq domains, we
 * should fill more enum info and enumerate them one by one.
 *
 * Return: 0 on success, negative error code otherwise.
 */
int dfl_fpga_enum_info_add_irq(struct dfl_fpga_enum_info *info,
			       unsigned int nr_irqs, int *irq_table)
{
	if (!nr_irqs || !irq_table)
		return -EINVAL;

	if (info->irq_table)
		return -EEXIST;

	info->irq_table = devm_kmemdup(info->dev, irq_table,
				       sizeof(int) * nr_irqs, GFP_KERNEL);
	if (!info->irq_table)
		return -ENOMEM;

	info->nr_irqs = nr_irqs;

	return 0;
}
EXPORT_SYMBOL_GPL(dfl_fpga_enum_info_add_irq);

static int remove_feature_dev(struct device *dev, void *data)
{
	struct platform_device *pdev = to_platform_device(dev);
	enum dfl_id_type type = feature_dev_id_type(pdev);
	int id = pdev->id;

	platform_device_unregister(pdev);

	dfl_id_free(type, id);

	return 0;
}

static void remove_feature_devs(struct dfl_fpga_cdev *cdev)
{
	device_for_each_child(&cdev->region->dev, NULL, remove_feature_dev);
}

/**
 * dfl_fpga_feature_devs_enumerate - enumerate feature devices
 * @info: information for enumeration.
 *
 * This function creates a container device (base FPGA region), enumerates
 * feature devices based on the enumeration info and creates platform devices
 * under the container device.
 *
 * Return: dfl_fpga_cdev struct on success, -errno on failure
 */
struct dfl_fpga_cdev *
dfl_fpga_feature_devs_enumerate(struct dfl_fpga_enum_info *info)
{
	struct build_feature_devs_info *binfo;
	struct dfl_fpga_enum_dfl *dfl;
	struct dfl_fpga_cdev *cdev;
	int ret = 0;

	if (!info->dev)
		return ERR_PTR(-ENODEV);

	cdev = devm_kzalloc(info->dev, sizeof(*cdev), GFP_KERNEL);
	if (!cdev)
		return ERR_PTR(-ENOMEM);

	cdev->region = devm_fpga_region_create(info->dev, NULL, NULL);
	if (!cdev->region) {
		ret = -ENOMEM;
		goto free_cdev_exit;
	}

	cdev->parent = info->dev;
	mutex_init(&cdev->lock);
	INIT_LIST_HEAD(&cdev->port_dev_list);

	ret = fpga_region_register(cdev->region);
	if (ret)
		goto free_cdev_exit;

	/* create and init build info for enumeration */
	binfo = devm_kzalloc(info->dev, sizeof(*binfo), GFP_KERNEL);
	if (!binfo) {
		ret = -ENOMEM;
		goto unregister_region_exit;
	}

	binfo->dev = info->dev;
	binfo->cdev = cdev;

	binfo->nr_irqs = info->nr_irqs;
	if (info->nr_irqs)
		binfo->irq_table = info->irq_table;

	/*
	 * start enumeration for all feature devices based on Device Feature
	 * Lists.
	 */
	list_for_each_entry(dfl, &info->dfls, node) {
		ret = parse_feature_list(binfo, dfl->start, dfl->len);
		if (ret) {
			remove_feature_devs(cdev);
			build_info_free(binfo);
			goto unregister_region_exit;
		}
	}

	build_info_free(binfo);

	return cdev;

unregister_region_exit:
	fpga_region_unregister(cdev->region);
free_cdev_exit:
	devm_kfree(info->dev, cdev);
	return ERR_PTR(ret);
}
EXPORT_SYMBOL_GPL(dfl_fpga_feature_devs_enumerate);

/**
 * dfl_fpga_feature_devs_remove - remove all feature devices
 * @cdev: fpga container device.
 *
 * Remove the container device and all feature devices under given container
 * devices.
 */
void dfl_fpga_feature_devs_remove(struct dfl_fpga_cdev *cdev)
{
	struct dfl_feature_platform_data *pdata, *ptmp;

	mutex_lock(&cdev->lock);
	if (cdev->fme_dev)
		put_device(cdev->fme_dev);

	list_for_each_entry_safe(pdata, ptmp, &cdev->port_dev_list, node) {
		struct platform_device *port_dev = pdata->dev;

		/* remove released ports */
		if (!device_is_registered(&port_dev->dev)) {
			dfl_id_free(feature_dev_id_type(port_dev),
				    port_dev->id);
			platform_device_put(port_dev);
		}

		list_del(&pdata->node);
		put_device(&port_dev->dev);
	}
	mutex_unlock(&cdev->lock);

	remove_feature_devs(cdev);

	fpga_region_unregister(cdev->region);
	devm_kfree(cdev->parent, cdev);
}
EXPORT_SYMBOL_GPL(dfl_fpga_feature_devs_remove);

/**
 * __dfl_fpga_cdev_find_port - find a port under given container device
 *
 * @cdev: container device
 * @data: data passed to match function
 * @match: match function used to find specific port from the port device list
 *
 * Find a port device under container device. This function needs to be
 * invoked with lock held.
 *
 * Return: pointer to port's platform device if successful, NULL otherwise.
 *
 * NOTE: you will need to drop the device reference with put_device() after use.
 */
struct platform_device *
__dfl_fpga_cdev_find_port(struct dfl_fpga_cdev *cdev, void *data,
			  int (*match)(struct platform_device *, void *))
{
	struct dfl_feature_platform_data *pdata;
	struct platform_device *port_dev;

	list_for_each_entry(pdata, &cdev->port_dev_list, node) {
		port_dev = pdata->dev;

		if (match(port_dev, data) && get_device(&port_dev->dev))
			return port_dev;
	}

	return NULL;
}
EXPORT_SYMBOL_GPL(__dfl_fpga_cdev_find_port);

static int __init dfl_fpga_init(void)
{
	int ret;

	ret = bus_register(&dfl_bus_type);
	if (ret)
		return ret;

	dfl_ids_init();

	ret = dfl_chardev_init();
	if (ret) {
		dfl_ids_destroy();
		bus_unregister(&dfl_bus_type);
	}

	return ret;
}

/**
 * dfl_fpga_cdev_release_port - release a port platform device
 *
 * @cdev: parent container device.
 * @port_id: id of the port platform device.
 *
 * This function allows user to release a port platform device. This is a
 * mandatory step before turn a port from PF into VF for SRIOV support.
 *
 * Return: 0 on success, negative error code otherwise.
 */
int dfl_fpga_cdev_release_port(struct dfl_fpga_cdev *cdev, int port_id)
{
	struct dfl_feature_platform_data *pdata;
	struct platform_device *port_pdev;
	int ret = -ENODEV;

	mutex_lock(&cdev->lock);
	port_pdev = __dfl_fpga_cdev_find_port(cdev, &port_id,
					      dfl_fpga_check_port_id);
	if (!port_pdev)
		goto unlock_exit;

	if (!device_is_registered(&port_pdev->dev)) {
		ret = -EBUSY;
		goto put_dev_exit;
	}

	pdata = dev_get_platdata(&port_pdev->dev);

	mutex_lock(&pdata->lock);
	ret = dfl_feature_dev_use_begin(pdata, true);
	mutex_unlock(&pdata->lock);
	if (ret)
		goto put_dev_exit;

	platform_device_del(port_pdev);
	cdev->released_port_num++;
put_dev_exit:
	put_device(&port_pdev->dev);
unlock_exit:
	mutex_unlock(&cdev->lock);
	return ret;
}
EXPORT_SYMBOL_GPL(dfl_fpga_cdev_release_port);

/**
 * dfl_fpga_cdev_assign_port - assign a port platform device back
 *
 * @cdev: parent container device.
 * @port_id: id of the port platform device.
 *
 * This function allows user to assign a port platform device back. This is
 * a mandatory step after disable SRIOV support.
 *
 * Return: 0 on success, negative error code otherwise.
 */
int dfl_fpga_cdev_assign_port(struct dfl_fpga_cdev *cdev, int port_id)
{
	struct dfl_feature_platform_data *pdata;
	struct platform_device *port_pdev;
	int ret = -ENODEV;

	mutex_lock(&cdev->lock);
	port_pdev = __dfl_fpga_cdev_find_port(cdev, &port_id,
					      dfl_fpga_check_port_id);
	if (!port_pdev)
		goto unlock_exit;

	if (device_is_registered(&port_pdev->dev)) {
		ret = -EBUSY;
		goto put_dev_exit;
	}

	ret = platform_device_add(port_pdev);
	if (ret)
		goto put_dev_exit;

	pdata = dev_get_platdata(&port_pdev->dev);

	mutex_lock(&pdata->lock);
	dfl_feature_dev_use_end(pdata);
	mutex_unlock(&pdata->lock);

	cdev->released_port_num--;
put_dev_exit:
	put_device(&port_pdev->dev);
unlock_exit:
	mutex_unlock(&cdev->lock);
	return ret;
}
EXPORT_SYMBOL_GPL(dfl_fpga_cdev_assign_port);

static void config_port_access_mode(struct device *fme_dev, int port_id,
				    bool is_vf)
{
	void __iomem *base;
	u64 v;

	base = dfl_get_feature_ioaddr_by_id(fme_dev, FME_FEATURE_ID_HEADER);

	v = readq(base + FME_HDR_PORT_OFST(port_id));

	v &= ~FME_PORT_OFST_ACC_CTRL;
	v |= FIELD_PREP(FME_PORT_OFST_ACC_CTRL,
			is_vf ? FME_PORT_OFST_ACC_VF : FME_PORT_OFST_ACC_PF);

	writeq(v, base + FME_HDR_PORT_OFST(port_id));
}

#define config_port_vf_mode(dev, id) config_port_access_mode(dev, id, true)
#define config_port_pf_mode(dev, id) config_port_access_mode(dev, id, false)

/**
 * dfl_fpga_cdev_config_ports_pf - configure ports to PF access mode
 *
 * @cdev: parent container device.
 *
 * This function is needed in sriov configuration routine. It could be used to
 * configure the all released ports from VF access mode to PF.
 */
void dfl_fpga_cdev_config_ports_pf(struct dfl_fpga_cdev *cdev)
{
	struct dfl_feature_platform_data *pdata;

	mutex_lock(&cdev->lock);
	list_for_each_entry(pdata, &cdev->port_dev_list, node) {
		if (device_is_registered(&pdata->dev->dev))
			continue;

		config_port_pf_mode(cdev->fme_dev, pdata->id);
	}
	mutex_unlock(&cdev->lock);
}
EXPORT_SYMBOL_GPL(dfl_fpga_cdev_config_ports_pf);

/**
 * dfl_fpga_cdev_config_ports_vf - configure ports to VF access mode
 *
 * @cdev: parent container device.
 * @num_vfs: VF device number.
 *
 * This function is needed in sriov configuration routine. It could be used to
 * configure the released ports from PF access mode to VF.
 *
 * Return: 0 on success, negative error code otherwise.
 */
int dfl_fpga_cdev_config_ports_vf(struct dfl_fpga_cdev *cdev, int num_vfs)
{
	struct dfl_feature_platform_data *pdata;
	int ret = 0;

	mutex_lock(&cdev->lock);
	/*
	 * can't turn multiple ports into 1 VF device, only 1 port for 1 VF
	 * device, so if released port number doesn't match VF device number,
	 * then reject the request with -EINVAL error code.
	 */
	if (cdev->released_port_num != num_vfs) {
		ret = -EINVAL;
		goto done;
	}

	list_for_each_entry(pdata, &cdev->port_dev_list, node) {
		if (device_is_registered(&pdata->dev->dev))
			continue;

		config_port_vf_mode(cdev->fme_dev, pdata->id);
	}
done:
	mutex_unlock(&cdev->lock);
	return ret;
}
EXPORT_SYMBOL_GPL(dfl_fpga_cdev_config_ports_vf);

static irqreturn_t dfl_irq_handler(int irq, void *arg)
{
	struct eventfd_ctx *trigger = arg;

	eventfd_signal(trigger, 1);
	return IRQ_HANDLED;
}

static int do_set_irq_trigger(struct dfl_feature *feature, unsigned int idx,
			      int fd)
{
	struct platform_device *pdev = feature->dev;
	struct eventfd_ctx *trigger;
	int irq, ret;

	irq = feature->irq_ctx[idx].irq;

	if (feature->irq_ctx[idx].trigger) {
		free_irq(irq, feature->irq_ctx[idx].trigger);
		kfree(feature->irq_ctx[idx].name);
		eventfd_ctx_put(feature->irq_ctx[idx].trigger);
		feature->irq_ctx[idx].trigger = NULL;
	}

	if (fd < 0)
		return 0;

	feature->irq_ctx[idx].name =
		kasprintf(GFP_KERNEL, "fpga-irq[%u](%s-%x)", idx,
			  dev_name(&pdev->dev), feature->id);
	if (!feature->irq_ctx[idx].name)
		return -ENOMEM;

	trigger = eventfd_ctx_fdget(fd);
	if (IS_ERR(trigger)) {
		ret = PTR_ERR(trigger);
		goto free_name;
	}

	ret = request_irq(irq, dfl_irq_handler, 0,
			  feature->irq_ctx[idx].name, trigger);
	if (!ret) {
		feature->irq_ctx[idx].trigger = trigger;
		return ret;
	}

	eventfd_ctx_put(trigger);
free_name:
	kfree(feature->irq_ctx[idx].name);

	return ret;
}

/**
 * dfl_fpga_set_irq_triggers - set eventfd triggers for dfl feature interrupts
 *
 * @feature: dfl sub feature.
 * @start: start of irq index in this dfl sub feature.
 * @count: number of irqs.
 * @fds: eventfds to bind with irqs. unbind related irq if fds[n] is negative.
 *	 unbind "count" specified number of irqs if fds ptr is NULL.
 *
 * Bind given eventfds with irqs in this dfl sub feature. Unbind related irq if
 * fds[n] is negative. Unbind "count" specified number of irqs if fds ptr is
 * NULL.
 *
 * Return: 0 on success, negative error code otherwise.
 */
int dfl_fpga_set_irq_triggers(struct dfl_feature *feature, unsigned int start,
			      unsigned int count, int32_t *fds)
{
	unsigned int i;
	int ret = 0;

	/* overflow */
	if (unlikely(start + count < start))
		return -EINVAL;

	/* exceeds nr_irqs */
	if (start + count > feature->nr_irqs)
		return -EINVAL;

	for (i = 0; i < count; i++) {
		int fd = fds ? fds[i] : -1;

		ret = do_set_irq_trigger(feature, start + i, fd);
		if (ret) {
			while (i--)
				do_set_irq_trigger(feature, start + i, -1);
			break;
		}
	}

	return ret;
}
EXPORT_SYMBOL_GPL(dfl_fpga_set_irq_triggers);

/**
 * dfl_feature_ioctl_get_num_irqs - dfl feature _GET_IRQ_NUM ioctl interface.
 * @pdev: the feature device which has the sub feature
 * @feature: the dfl sub feature
 * @arg: ioctl argument
 *
 * Return: 0 on success, negative error code otherwise.
 */
long dfl_feature_ioctl_get_num_irqs(struct platform_device *pdev,
				    struct dfl_feature *feature,
				    unsigned long arg)
{
	return put_user(feature->nr_irqs, (__u32 __user *)arg);
}
EXPORT_SYMBOL_GPL(dfl_feature_ioctl_get_num_irqs);

/**
 * dfl_feature_ioctl_set_irq - dfl feature _SET_IRQ ioctl interface.
 * @pdev: the feature device which has the sub feature
 * @feature: the dfl sub feature
 * @arg: ioctl argument
 *
 * Return: 0 on success, negative error code otherwise.
 */
long dfl_feature_ioctl_set_irq(struct platform_device *pdev,
			       struct dfl_feature *feature,
			       unsigned long arg)
{
	struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
	struct dfl_fpga_irq_set hdr;
	s32 *fds;
	long ret;

	if (!feature->nr_irqs)
		return -ENOENT;

	if (copy_from_user(&hdr, (void __user *)arg, sizeof(hdr)))
		return -EFAULT;

	if (!hdr.count || (hdr.start + hdr.count > feature->nr_irqs) ||
	    (hdr.start + hdr.count < hdr.start))
		return -EINVAL;

	fds = memdup_user((void __user *)(arg + sizeof(hdr)),
			  hdr.count * sizeof(s32));
	if (IS_ERR(fds))
		return PTR_ERR(fds);

	mutex_lock(&pdata->lock);
	ret = dfl_fpga_set_irq_triggers(feature, hdr.start, hdr.count, fds);
	mutex_unlock(&pdata->lock);

	kfree(fds);
	return ret;
}
EXPORT_SYMBOL_GPL(dfl_feature_ioctl_set_irq);

static void __exit dfl_fpga_exit(void)
{
	dfl_chardev_uinit();
	dfl_ids_destroy();
	bus_unregister(&dfl_bus_type);
}

module_init(dfl_fpga_init);
module_exit(dfl_fpga_exit);

MODULE_DESCRIPTION("FPGA Device Feature List (DFL) Support");
MODULE_AUTHOR("Intel Corporation");
MODULE_LICENSE("GPL v2");
