cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dfl.c (47533B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Driver for FPGA Device Feature List (DFL) Support
      4 *
      5 * Copyright (C) 2017-2018 Intel Corporation, Inc.
      6 *
      7 * Authors:
      8 *   Kang Luwei <luwei.kang@intel.com>
      9 *   Zhang Yi <yi.z.zhang@intel.com>
     10 *   Wu Hao <hao.wu@intel.com>
     11 *   Xiao Guangrong <guangrong.xiao@linux.intel.com>
     12 */
     13#include <linux/dfl.h>
     14#include <linux/fpga-dfl.h>
     15#include <linux/module.h>
     16#include <linux/uaccess.h>
     17
     18#include "dfl.h"
     19
     20static DEFINE_MUTEX(dfl_id_mutex);
     21
     22/*
     23 * when adding a new feature dev support in DFL framework, it's required to
     24 * add a new item in enum dfl_id_type and provide related information in below
     25 * dfl_devs table which is indexed by dfl_id_type, e.g. name string used for
     26 * platform device creation (define name strings in dfl.h, as they could be
     27 * reused by platform device drivers).
     28 *
     29 * if the new feature dev needs chardev support, then it's required to add
     30 * a new item in dfl_chardevs table and configure dfl_devs[i].devt_type as
     31 * index to dfl_chardevs table. If no chardev support just set devt_type
     32 * as one invalid index (DFL_FPGA_DEVT_MAX).
     33 */
     34enum dfl_fpga_devt_type {
     35	DFL_FPGA_DEVT_FME,
     36	DFL_FPGA_DEVT_PORT,
     37	DFL_FPGA_DEVT_MAX,
     38};
     39
     40static struct lock_class_key dfl_pdata_keys[DFL_ID_MAX];
     41
     42static const char *dfl_pdata_key_strings[DFL_ID_MAX] = {
     43	"dfl-fme-pdata",
     44	"dfl-port-pdata",
     45};
     46
     47/**
     48 * dfl_dev_info - dfl feature device information.
     49 * @name: name string of the feature platform device.
     50 * @dfh_id: id value in Device Feature Header (DFH) register by DFL spec.
     51 * @id: idr id of the feature dev.
     52 * @devt_type: index to dfl_chrdevs[].
     53 */
     54struct dfl_dev_info {
     55	const char *name;
     56	u16 dfh_id;
     57	struct idr id;
     58	enum dfl_fpga_devt_type devt_type;
     59};
     60
     61/* it is indexed by dfl_id_type */
     62static struct dfl_dev_info dfl_devs[] = {
     63	{.name = DFL_FPGA_FEATURE_DEV_FME, .dfh_id = DFH_ID_FIU_FME,
     64	 .devt_type = DFL_FPGA_DEVT_FME},
     65	{.name = DFL_FPGA_FEATURE_DEV_PORT, .dfh_id = DFH_ID_FIU_PORT,
     66	 .devt_type = DFL_FPGA_DEVT_PORT},
     67};
     68
     69/**
     70 * dfl_chardev_info - chardev information of dfl feature device
     71 * @name: nmae string of the char device.
     72 * @devt: devt of the char device.
     73 */
     74struct dfl_chardev_info {
     75	const char *name;
     76	dev_t devt;
     77};
     78
     79/* indexed by enum dfl_fpga_devt_type */
     80static struct dfl_chardev_info dfl_chrdevs[] = {
     81	{.name = DFL_FPGA_FEATURE_DEV_FME},
     82	{.name = DFL_FPGA_FEATURE_DEV_PORT},
     83};
     84
     85static void dfl_ids_init(void)
     86{
     87	int i;
     88
     89	for (i = 0; i < ARRAY_SIZE(dfl_devs); i++)
     90		idr_init(&dfl_devs[i].id);
     91}
     92
     93static void dfl_ids_destroy(void)
     94{
     95	int i;
     96
     97	for (i = 0; i < ARRAY_SIZE(dfl_devs); i++)
     98		idr_destroy(&dfl_devs[i].id);
     99}
    100
    101static int dfl_id_alloc(enum dfl_id_type type, struct device *dev)
    102{
    103	int id;
    104
    105	WARN_ON(type >= DFL_ID_MAX);
    106	mutex_lock(&dfl_id_mutex);
    107	id = idr_alloc(&dfl_devs[type].id, dev, 0, 0, GFP_KERNEL);
    108	mutex_unlock(&dfl_id_mutex);
    109
    110	return id;
    111}
    112
    113static void dfl_id_free(enum dfl_id_type type, int id)
    114{
    115	WARN_ON(type >= DFL_ID_MAX);
    116	mutex_lock(&dfl_id_mutex);
    117	idr_remove(&dfl_devs[type].id, id);
    118	mutex_unlock(&dfl_id_mutex);
    119}
    120
    121static enum dfl_id_type feature_dev_id_type(struct platform_device *pdev)
    122{
    123	int i;
    124
    125	for (i = 0; i < ARRAY_SIZE(dfl_devs); i++)
    126		if (!strcmp(dfl_devs[i].name, pdev->name))
    127			return i;
    128
    129	return DFL_ID_MAX;
    130}
    131
    132static enum dfl_id_type dfh_id_to_type(u16 id)
    133{
    134	int i;
    135
    136	for (i = 0; i < ARRAY_SIZE(dfl_devs); i++)
    137		if (dfl_devs[i].dfh_id == id)
    138			return i;
    139
    140	return DFL_ID_MAX;
    141}
    142
    143/*
    144 * introduce a global port_ops list, it allows port drivers to register ops
    145 * in such list, then other feature devices (e.g. FME), could use the port
    146 * functions even related port platform device is hidden. Below is one example,
    147 * in virtualization case of PCIe-based FPGA DFL device, when SRIOV is
    148 * enabled, port (and it's AFU) is turned into VF and port platform device
    149 * is hidden from system but it's still required to access port to finish FPGA
    150 * reconfiguration function in FME.
    151 */
    152
    153static DEFINE_MUTEX(dfl_port_ops_mutex);
    154static LIST_HEAD(dfl_port_ops_list);
    155
    156/**
    157 * dfl_fpga_port_ops_get - get matched port ops from the global list
    158 * @pdev: platform device to match with associated port ops.
    159 * Return: matched port ops on success, NULL otherwise.
    160 *
    161 * Please note that must dfl_fpga_port_ops_put after use the port_ops.
    162 */
    163struct dfl_fpga_port_ops *dfl_fpga_port_ops_get(struct platform_device *pdev)
    164{
    165	struct dfl_fpga_port_ops *ops = NULL;
    166
    167	mutex_lock(&dfl_port_ops_mutex);
    168	if (list_empty(&dfl_port_ops_list))
    169		goto done;
    170
    171	list_for_each_entry(ops, &dfl_port_ops_list, node) {
    172		/* match port_ops using the name of platform device */
    173		if (!strcmp(pdev->name, ops->name)) {
    174			if (!try_module_get(ops->owner))
    175				ops = NULL;
    176			goto done;
    177		}
    178	}
    179
    180	ops = NULL;
    181done:
    182	mutex_unlock(&dfl_port_ops_mutex);
    183	return ops;
    184}
    185EXPORT_SYMBOL_GPL(dfl_fpga_port_ops_get);
    186
    187/**
    188 * dfl_fpga_port_ops_put - put port ops
    189 * @ops: port ops.
    190 */
    191void dfl_fpga_port_ops_put(struct dfl_fpga_port_ops *ops)
    192{
    193	if (ops && ops->owner)
    194		module_put(ops->owner);
    195}
    196EXPORT_SYMBOL_GPL(dfl_fpga_port_ops_put);
    197
    198/**
    199 * dfl_fpga_port_ops_add - add port_ops to global list
    200 * @ops: port ops to add.
    201 */
    202void dfl_fpga_port_ops_add(struct dfl_fpga_port_ops *ops)
    203{
    204	mutex_lock(&dfl_port_ops_mutex);
    205	list_add_tail(&ops->node, &dfl_port_ops_list);
    206	mutex_unlock(&dfl_port_ops_mutex);
    207}
    208EXPORT_SYMBOL_GPL(dfl_fpga_port_ops_add);
    209
    210/**
    211 * dfl_fpga_port_ops_del - remove port_ops from global list
    212 * @ops: port ops to del.
    213 */
    214void dfl_fpga_port_ops_del(struct dfl_fpga_port_ops *ops)
    215{
    216	mutex_lock(&dfl_port_ops_mutex);
    217	list_del(&ops->node);
    218	mutex_unlock(&dfl_port_ops_mutex);
    219}
    220EXPORT_SYMBOL_GPL(dfl_fpga_port_ops_del);
    221
    222/**
    223 * dfl_fpga_check_port_id - check the port id
    224 * @pdev: port platform device.
    225 * @pport_id: port id to compare.
    226 *
    227 * Return: 1 if port device matches with given port id, otherwise 0.
    228 */
    229int dfl_fpga_check_port_id(struct platform_device *pdev, void *pport_id)
    230{
    231	struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
    232	struct dfl_fpga_port_ops *port_ops;
    233
    234	if (pdata->id != FEATURE_DEV_ID_UNUSED)
    235		return pdata->id == *(int *)pport_id;
    236
    237	port_ops = dfl_fpga_port_ops_get(pdev);
    238	if (!port_ops || !port_ops->get_id)
    239		return 0;
    240
    241	pdata->id = port_ops->get_id(pdev);
    242	dfl_fpga_port_ops_put(port_ops);
    243
    244	return pdata->id == *(int *)pport_id;
    245}
    246EXPORT_SYMBOL_GPL(dfl_fpga_check_port_id);
    247
    248static DEFINE_IDA(dfl_device_ida);
    249
    250static const struct dfl_device_id *
    251dfl_match_one_device(const struct dfl_device_id *id, struct dfl_device *ddev)
    252{
    253	if (id->type == ddev->type && id->feature_id == ddev->feature_id)
    254		return id;
    255
    256	return NULL;
    257}
    258
    259static int dfl_bus_match(struct device *dev, struct device_driver *drv)
    260{
    261	struct dfl_device *ddev = to_dfl_dev(dev);
    262	struct dfl_driver *ddrv = to_dfl_drv(drv);
    263	const struct dfl_device_id *id_entry;
    264
    265	id_entry = ddrv->id_table;
    266	if (id_entry) {
    267		while (id_entry->feature_id) {
    268			if (dfl_match_one_device(id_entry, ddev)) {
    269				ddev->id_entry = id_entry;
    270				return 1;
    271			}
    272			id_entry++;
    273		}
    274	}
    275
    276	return 0;
    277}
    278
    279static int dfl_bus_probe(struct device *dev)
    280{
    281	struct dfl_driver *ddrv = to_dfl_drv(dev->driver);
    282	struct dfl_device *ddev = to_dfl_dev(dev);
    283
    284	return ddrv->probe(ddev);
    285}
    286
    287static void dfl_bus_remove(struct device *dev)
    288{
    289	struct dfl_driver *ddrv = to_dfl_drv(dev->driver);
    290	struct dfl_device *ddev = to_dfl_dev(dev);
    291
    292	if (ddrv->remove)
    293		ddrv->remove(ddev);
    294}
    295
    296static int dfl_bus_uevent(struct device *dev, struct kobj_uevent_env *env)
    297{
    298	struct dfl_device *ddev = to_dfl_dev(dev);
    299
    300	return add_uevent_var(env, "MODALIAS=dfl:t%04Xf%04X",
    301			      ddev->type, ddev->feature_id);
    302}
    303
    304static ssize_t
    305type_show(struct device *dev, struct device_attribute *attr, char *buf)
    306{
    307	struct dfl_device *ddev = to_dfl_dev(dev);
    308
    309	return sprintf(buf, "0x%x\n", ddev->type);
    310}
    311static DEVICE_ATTR_RO(type);
    312
    313static ssize_t
    314feature_id_show(struct device *dev, struct device_attribute *attr, char *buf)
    315{
    316	struct dfl_device *ddev = to_dfl_dev(dev);
    317
    318	return sprintf(buf, "0x%x\n", ddev->feature_id);
    319}
    320static DEVICE_ATTR_RO(feature_id);
    321
    322static struct attribute *dfl_dev_attrs[] = {
    323	&dev_attr_type.attr,
    324	&dev_attr_feature_id.attr,
    325	NULL,
    326};
    327ATTRIBUTE_GROUPS(dfl_dev);
    328
    329static struct bus_type dfl_bus_type = {
    330	.name		= "dfl",
    331	.match		= dfl_bus_match,
    332	.probe		= dfl_bus_probe,
    333	.remove		= dfl_bus_remove,
    334	.uevent		= dfl_bus_uevent,
    335	.dev_groups	= dfl_dev_groups,
    336};
    337
    338static void release_dfl_dev(struct device *dev)
    339{
    340	struct dfl_device *ddev = to_dfl_dev(dev);
    341
    342	if (ddev->mmio_res.parent)
    343		release_resource(&ddev->mmio_res);
    344
    345	ida_simple_remove(&dfl_device_ida, ddev->id);
    346	kfree(ddev->irqs);
    347	kfree(ddev);
    348}
    349
    350static struct dfl_device *
    351dfl_dev_add(struct dfl_feature_platform_data *pdata,
    352	    struct dfl_feature *feature)
    353{
    354	struct platform_device *pdev = pdata->dev;
    355	struct resource *parent_res;
    356	struct dfl_device *ddev;
    357	int id, i, ret;
    358
    359	ddev = kzalloc(sizeof(*ddev), GFP_KERNEL);
    360	if (!ddev)
    361		return ERR_PTR(-ENOMEM);
    362
    363	id = ida_simple_get(&dfl_device_ida, 0, 0, GFP_KERNEL);
    364	if (id < 0) {
    365		dev_err(&pdev->dev, "unable to get id\n");
    366		kfree(ddev);
    367		return ERR_PTR(id);
    368	}
    369
    370	/* freeing resources by put_device() after device_initialize() */
    371	device_initialize(&ddev->dev);
    372	ddev->dev.parent = &pdev->dev;
    373	ddev->dev.bus = &dfl_bus_type;
    374	ddev->dev.release = release_dfl_dev;
    375	ddev->id = id;
    376	ret = dev_set_name(&ddev->dev, "dfl_dev.%d", id);
    377	if (ret)
    378		goto put_dev;
    379
    380	ddev->type = feature_dev_id_type(pdev);
    381	ddev->feature_id = feature->id;
    382	ddev->revision = feature->revision;
    383	ddev->cdev = pdata->dfl_cdev;
    384
    385	/* add mmio resource */
    386	parent_res = &pdev->resource[feature->resource_index];
    387	ddev->mmio_res.flags = IORESOURCE_MEM;
    388	ddev->mmio_res.start = parent_res->start;
    389	ddev->mmio_res.end = parent_res->end;
    390	ddev->mmio_res.name = dev_name(&ddev->dev);
    391	ret = insert_resource(parent_res, &ddev->mmio_res);
    392	if (ret) {
    393		dev_err(&pdev->dev, "%s failed to claim resource: %pR\n",
    394			dev_name(&ddev->dev), &ddev->mmio_res);
    395		goto put_dev;
    396	}
    397
    398	/* then add irq resource */
    399	if (feature->nr_irqs) {
    400		ddev->irqs = kcalloc(feature->nr_irqs,
    401				     sizeof(*ddev->irqs), GFP_KERNEL);
    402		if (!ddev->irqs) {
    403			ret = -ENOMEM;
    404			goto put_dev;
    405		}
    406
    407		for (i = 0; i < feature->nr_irqs; i++)
    408			ddev->irqs[i] = feature->irq_ctx[i].irq;
    409
    410		ddev->num_irqs = feature->nr_irqs;
    411	}
    412
    413	ret = device_add(&ddev->dev);
    414	if (ret)
    415		goto put_dev;
    416
    417	dev_dbg(&pdev->dev, "add dfl_dev: %s\n", dev_name(&ddev->dev));
    418	return ddev;
    419
    420put_dev:
    421	/* calls release_dfl_dev() which does the clean up  */
    422	put_device(&ddev->dev);
    423	return ERR_PTR(ret);
    424}
    425
    426static void dfl_devs_remove(struct dfl_feature_platform_data *pdata)
    427{
    428	struct dfl_feature *feature;
    429
    430	dfl_fpga_dev_for_each_feature(pdata, feature) {
    431		if (feature->ddev) {
    432			device_unregister(&feature->ddev->dev);
    433			feature->ddev = NULL;
    434		}
    435	}
    436}
    437
    438static int dfl_devs_add(struct dfl_feature_platform_data *pdata)
    439{
    440	struct dfl_feature *feature;
    441	struct dfl_device *ddev;
    442	int ret;
    443
    444	dfl_fpga_dev_for_each_feature(pdata, feature) {
    445		if (feature->ioaddr)
    446			continue;
    447
    448		if (feature->ddev) {
    449			ret = -EEXIST;
    450			goto err;
    451		}
    452
    453		ddev = dfl_dev_add(pdata, feature);
    454		if (IS_ERR(ddev)) {
    455			ret = PTR_ERR(ddev);
    456			goto err;
    457		}
    458
    459		feature->ddev = ddev;
    460	}
    461
    462	return 0;
    463
    464err:
    465	dfl_devs_remove(pdata);
    466	return ret;
    467}
    468
    469int __dfl_driver_register(struct dfl_driver *dfl_drv, struct module *owner)
    470{
    471	if (!dfl_drv || !dfl_drv->probe || !dfl_drv->id_table)
    472		return -EINVAL;
    473
    474	dfl_drv->drv.owner = owner;
    475	dfl_drv->drv.bus = &dfl_bus_type;
    476
    477	return driver_register(&dfl_drv->drv);
    478}
    479EXPORT_SYMBOL(__dfl_driver_register);
    480
    481void dfl_driver_unregister(struct dfl_driver *dfl_drv)
    482{
    483	driver_unregister(&dfl_drv->drv);
    484}
    485EXPORT_SYMBOL(dfl_driver_unregister);
    486
    487#define is_header_feature(feature) ((feature)->id == FEATURE_ID_FIU_HEADER)
    488
    489/**
    490 * dfl_fpga_dev_feature_uinit - uinit for sub features of dfl feature device
    491 * @pdev: feature device.
    492 */
    493void dfl_fpga_dev_feature_uinit(struct platform_device *pdev)
    494{
    495	struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
    496	struct dfl_feature *feature;
    497
    498	dfl_devs_remove(pdata);
    499
    500	dfl_fpga_dev_for_each_feature(pdata, feature) {
    501		if (feature->ops) {
    502			if (feature->ops->uinit)
    503				feature->ops->uinit(pdev, feature);
    504			feature->ops = NULL;
    505		}
    506	}
    507}
    508EXPORT_SYMBOL_GPL(dfl_fpga_dev_feature_uinit);
    509
    510static int dfl_feature_instance_init(struct platform_device *pdev,
    511				     struct dfl_feature_platform_data *pdata,
    512				     struct dfl_feature *feature,
    513				     struct dfl_feature_driver *drv)
    514{
    515	void __iomem *base;
    516	int ret = 0;
    517
    518	if (!is_header_feature(feature)) {
    519		base = devm_platform_ioremap_resource(pdev,
    520						      feature->resource_index);
    521		if (IS_ERR(base)) {
    522			dev_err(&pdev->dev,
    523				"ioremap failed for feature 0x%x!\n",
    524				feature->id);
    525			return PTR_ERR(base);
    526		}
    527
    528		feature->ioaddr = base;
    529	}
    530
    531	if (drv->ops->init) {
    532		ret = drv->ops->init(pdev, feature);
    533		if (ret)
    534			return ret;
    535	}
    536
    537	feature->ops = drv->ops;
    538
    539	return ret;
    540}
    541
    542static bool dfl_feature_drv_match(struct dfl_feature *feature,
    543				  struct dfl_feature_driver *driver)
    544{
    545	const struct dfl_feature_id *ids = driver->id_table;
    546
    547	if (ids) {
    548		while (ids->id) {
    549			if (ids->id == feature->id)
    550				return true;
    551			ids++;
    552		}
    553	}
    554	return false;
    555}
    556
    557/**
    558 * dfl_fpga_dev_feature_init - init for sub features of dfl feature device
    559 * @pdev: feature device.
    560 * @feature_drvs: drvs for sub features.
    561 *
    562 * This function will match sub features with given feature drvs list and
    563 * use matched drv to init related sub feature.
    564 *
    565 * Return: 0 on success, negative error code otherwise.
    566 */
    567int dfl_fpga_dev_feature_init(struct platform_device *pdev,
    568			      struct dfl_feature_driver *feature_drvs)
    569{
    570	struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
    571	struct dfl_feature_driver *drv = feature_drvs;
    572	struct dfl_feature *feature;
    573	int ret;
    574
    575	while (drv->ops) {
    576		dfl_fpga_dev_for_each_feature(pdata, feature) {
    577			if (dfl_feature_drv_match(feature, drv)) {
    578				ret = dfl_feature_instance_init(pdev, pdata,
    579								feature, drv);
    580				if (ret)
    581					goto exit;
    582			}
    583		}
    584		drv++;
    585	}
    586
    587	ret = dfl_devs_add(pdata);
    588	if (ret)
    589		goto exit;
    590
    591	return 0;
    592exit:
    593	dfl_fpga_dev_feature_uinit(pdev);
    594	return ret;
    595}
    596EXPORT_SYMBOL_GPL(dfl_fpga_dev_feature_init);
    597
    598static void dfl_chardev_uinit(void)
    599{
    600	int i;
    601
    602	for (i = 0; i < DFL_FPGA_DEVT_MAX; i++)
    603		if (MAJOR(dfl_chrdevs[i].devt)) {
    604			unregister_chrdev_region(dfl_chrdevs[i].devt,
    605						 MINORMASK + 1);
    606			dfl_chrdevs[i].devt = MKDEV(0, 0);
    607		}
    608}
    609
    610static int dfl_chardev_init(void)
    611{
    612	int i, ret;
    613
    614	for (i = 0; i < DFL_FPGA_DEVT_MAX; i++) {
    615		ret = alloc_chrdev_region(&dfl_chrdevs[i].devt, 0,
    616					  MINORMASK + 1, dfl_chrdevs[i].name);
    617		if (ret)
    618			goto exit;
    619	}
    620
    621	return 0;
    622
    623exit:
    624	dfl_chardev_uinit();
    625	return ret;
    626}
    627
    628static dev_t dfl_get_devt(enum dfl_fpga_devt_type type, int id)
    629{
    630	if (type >= DFL_FPGA_DEVT_MAX)
    631		return 0;
    632
    633	return MKDEV(MAJOR(dfl_chrdevs[type].devt), id);
    634}
    635
    636/**
    637 * dfl_fpga_dev_ops_register - register cdev ops for feature dev
    638 *
    639 * @pdev: feature dev.
    640 * @fops: file operations for feature dev's cdev.
    641 * @owner: owning module/driver.
    642 *
    643 * Return: 0 on success, negative error code otherwise.
    644 */
    645int dfl_fpga_dev_ops_register(struct platform_device *pdev,
    646			      const struct file_operations *fops,
    647			      struct module *owner)
    648{
    649	struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
    650
    651	cdev_init(&pdata->cdev, fops);
    652	pdata->cdev.owner = owner;
    653
    654	/*
    655	 * set parent to the feature device so that its refcount is
    656	 * decreased after the last refcount of cdev is gone, that
    657	 * makes sure the feature device is valid during device
    658	 * file's life-cycle.
    659	 */
    660	pdata->cdev.kobj.parent = &pdev->dev.kobj;
    661
    662	return cdev_add(&pdata->cdev, pdev->dev.devt, 1);
    663}
    664EXPORT_SYMBOL_GPL(dfl_fpga_dev_ops_register);
    665
    666/**
    667 * dfl_fpga_dev_ops_unregister - unregister cdev ops for feature dev
    668 * @pdev: feature dev.
    669 */
    670void dfl_fpga_dev_ops_unregister(struct platform_device *pdev)
    671{
    672	struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
    673
    674	cdev_del(&pdata->cdev);
    675}
    676EXPORT_SYMBOL_GPL(dfl_fpga_dev_ops_unregister);
    677
    678/**
    679 * struct build_feature_devs_info - info collected during feature dev build.
    680 *
    681 * @dev: device to enumerate.
    682 * @cdev: the container device for all feature devices.
    683 * @nr_irqs: number of irqs for all feature devices.
    684 * @irq_table: Linux IRQ numbers for all irqs, indexed by local irq index of
    685 *	       this device.
    686 * @feature_dev: current feature device.
    687 * @ioaddr: header register region address of current FIU in enumeration.
    688 * @start: register resource start of current FIU.
    689 * @len: max register resource length of current FIU.
    690 * @sub_features: a sub features linked list for feature device in enumeration.
    691 * @feature_num: number of sub features for feature device in enumeration.
    692 */
    693struct build_feature_devs_info {
    694	struct device *dev;
    695	struct dfl_fpga_cdev *cdev;
    696	unsigned int nr_irqs;
    697	int *irq_table;
    698
    699	struct platform_device *feature_dev;
    700	void __iomem *ioaddr;
    701	resource_size_t start;
    702	resource_size_t len;
    703	struct list_head sub_features;
    704	int feature_num;
    705};
    706
    707/**
    708 * struct dfl_feature_info - sub feature info collected during feature dev build
    709 *
    710 * @fid: id of this sub feature.
    711 * @mmio_res: mmio resource of this sub feature.
    712 * @ioaddr: mapped base address of mmio resource.
    713 * @node: node in sub_features linked list.
    714 * @irq_base: start of irq index in this sub feature.
    715 * @nr_irqs: number of irqs of this sub feature.
    716 */
    717struct dfl_feature_info {
    718	u16 fid;
    719	u8 revision;
    720	struct resource mmio_res;
    721	void __iomem *ioaddr;
    722	struct list_head node;
    723	unsigned int irq_base;
    724	unsigned int nr_irqs;
    725};
    726
    727static void dfl_fpga_cdev_add_port_dev(struct dfl_fpga_cdev *cdev,
    728				       struct platform_device *port)
    729{
    730	struct dfl_feature_platform_data *pdata = dev_get_platdata(&port->dev);
    731
    732	mutex_lock(&cdev->lock);
    733	list_add(&pdata->node, &cdev->port_dev_list);
    734	get_device(&pdata->dev->dev);
    735	mutex_unlock(&cdev->lock);
    736}
    737
    738/*
    739 * register current feature device, it is called when we need to switch to
    740 * another feature parsing or we have parsed all features on given device
    741 * feature list.
    742 */
    743static int build_info_commit_dev(struct build_feature_devs_info *binfo)
    744{
    745	struct platform_device *fdev = binfo->feature_dev;
    746	struct dfl_feature_platform_data *pdata;
    747	struct dfl_feature_info *finfo, *p;
    748	enum dfl_id_type type;
    749	int ret, index = 0, res_idx = 0;
    750
    751	type = feature_dev_id_type(fdev);
    752	if (WARN_ON_ONCE(type >= DFL_ID_MAX))
    753		return -EINVAL;
    754
    755	/*
    756	 * we do not need to care for the memory which is associated with
    757	 * the platform device. After calling platform_device_unregister(),
    758	 * it will be automatically freed by device's release() callback,
    759	 * platform_device_release().
    760	 */
    761	pdata = kzalloc(struct_size(pdata, features, binfo->feature_num), GFP_KERNEL);
    762	if (!pdata)
    763		return -ENOMEM;
    764
    765	pdata->dev = fdev;
    766	pdata->num = binfo->feature_num;
    767	pdata->dfl_cdev = binfo->cdev;
    768	pdata->id = FEATURE_DEV_ID_UNUSED;
    769	mutex_init(&pdata->lock);
    770	lockdep_set_class_and_name(&pdata->lock, &dfl_pdata_keys[type],
    771				   dfl_pdata_key_strings[type]);
    772
    773	/*
    774	 * the count should be initialized to 0 to make sure
    775	 *__fpga_port_enable() following __fpga_port_disable()
    776	 * works properly for port device.
    777	 * and it should always be 0 for fme device.
    778	 */
    779	WARN_ON(pdata->disable_count);
    780
    781	fdev->dev.platform_data = pdata;
    782
    783	/* each sub feature has one MMIO resource */
    784	fdev->num_resources = binfo->feature_num;
    785	fdev->resource = kcalloc(binfo->feature_num, sizeof(*fdev->resource),
    786				 GFP_KERNEL);
    787	if (!fdev->resource)
    788		return -ENOMEM;
    789
    790	/* fill features and resource information for feature dev */
    791	list_for_each_entry_safe(finfo, p, &binfo->sub_features, node) {
    792		struct dfl_feature *feature = &pdata->features[index++];
    793		struct dfl_feature_irq_ctx *ctx;
    794		unsigned int i;
    795
    796		/* save resource information for each feature */
    797		feature->dev = fdev;
    798		feature->id = finfo->fid;
    799		feature->revision = finfo->revision;
    800
    801		/*
    802		 * the FIU header feature has some fundamental functions (sriov
    803		 * set, port enable/disable) needed for the dfl bus device and
    804		 * other sub features. So its mmio resource should be mapped by
    805		 * DFL bus device. And we should not assign it to feature
    806		 * devices (dfl-fme/afu) again.
    807		 */
    808		if (is_header_feature(feature)) {
    809			feature->resource_index = -1;
    810			feature->ioaddr =
    811				devm_ioremap_resource(binfo->dev,
    812						      &finfo->mmio_res);
    813			if (IS_ERR(feature->ioaddr))
    814				return PTR_ERR(feature->ioaddr);
    815		} else {
    816			feature->resource_index = res_idx;
    817			fdev->resource[res_idx++] = finfo->mmio_res;
    818		}
    819
    820		if (finfo->nr_irqs) {
    821			ctx = devm_kcalloc(binfo->dev, finfo->nr_irqs,
    822					   sizeof(*ctx), GFP_KERNEL);
    823			if (!ctx)
    824				return -ENOMEM;
    825
    826			for (i = 0; i < finfo->nr_irqs; i++)
    827				ctx[i].irq =
    828					binfo->irq_table[finfo->irq_base + i];
    829
    830			feature->irq_ctx = ctx;
    831			feature->nr_irqs = finfo->nr_irqs;
    832		}
    833
    834		list_del(&finfo->node);
    835		kfree(finfo);
    836	}
    837
    838	ret = platform_device_add(binfo->feature_dev);
    839	if (!ret) {
    840		if (type == PORT_ID)
    841			dfl_fpga_cdev_add_port_dev(binfo->cdev,
    842						   binfo->feature_dev);
    843		else
    844			binfo->cdev->fme_dev =
    845					get_device(&binfo->feature_dev->dev);
    846		/*
    847		 * reset it to avoid build_info_free() freeing their resource.
    848		 *
    849		 * The resource of successfully registered feature devices
    850		 * will be freed by platform_device_unregister(). See the
    851		 * comments in build_info_create_dev().
    852		 */
    853		binfo->feature_dev = NULL;
    854	}
    855
    856	return ret;
    857}
    858
    859static int
    860build_info_create_dev(struct build_feature_devs_info *binfo,
    861		      enum dfl_id_type type)
    862{
    863	struct platform_device *fdev;
    864
    865	if (type >= DFL_ID_MAX)
    866		return -EINVAL;
    867
    868	/*
    869	 * we use -ENODEV as the initialization indicator which indicates
    870	 * whether the id need to be reclaimed
    871	 */
    872	fdev = platform_device_alloc(dfl_devs[type].name, -ENODEV);
    873	if (!fdev)
    874		return -ENOMEM;
    875
    876	binfo->feature_dev = fdev;
    877	binfo->feature_num = 0;
    878
    879	INIT_LIST_HEAD(&binfo->sub_features);
    880
    881	fdev->id = dfl_id_alloc(type, &fdev->dev);
    882	if (fdev->id < 0)
    883		return fdev->id;
    884
    885	fdev->dev.parent = &binfo->cdev->region->dev;
    886	fdev->dev.devt = dfl_get_devt(dfl_devs[type].devt_type, fdev->id);
    887
    888	return 0;
    889}
    890
    891static void build_info_free(struct build_feature_devs_info *binfo)
    892{
    893	struct dfl_feature_info *finfo, *p;
    894
    895	/*
    896	 * it is a valid id, free it. See comments in
    897	 * build_info_create_dev()
    898	 */
    899	if (binfo->feature_dev && binfo->feature_dev->id >= 0) {
    900		dfl_id_free(feature_dev_id_type(binfo->feature_dev),
    901			    binfo->feature_dev->id);
    902
    903		list_for_each_entry_safe(finfo, p, &binfo->sub_features, node) {
    904			list_del(&finfo->node);
    905			kfree(finfo);
    906		}
    907	}
    908
    909	platform_device_put(binfo->feature_dev);
    910
    911	devm_kfree(binfo->dev, binfo);
    912}
    913
    914static inline u32 feature_size(u64 value)
    915{
    916	u32 ofst = FIELD_GET(DFH_NEXT_HDR_OFST, value);
    917	/* workaround for private features with invalid size, use 4K instead */
    918	return ofst ? ofst : 4096;
    919}
    920
    921static u16 feature_id(u64 value)
    922{
    923	u16 id = FIELD_GET(DFH_ID, value);
    924	u8 type = FIELD_GET(DFH_TYPE, value);
    925
    926	if (type == DFH_TYPE_FIU)
    927		return FEATURE_ID_FIU_HEADER;
    928	else if (type == DFH_TYPE_PRIVATE)
    929		return id;
    930	else if (type == DFH_TYPE_AFU)
    931		return FEATURE_ID_AFU;
    932
    933	WARN_ON(1);
    934	return 0;
    935}
    936
    937static int parse_feature_irqs(struct build_feature_devs_info *binfo,
    938			      resource_size_t ofst, u16 fid,
    939			      unsigned int *irq_base, unsigned int *nr_irqs)
    940{
    941	void __iomem *base = binfo->ioaddr + ofst;
    942	unsigned int i, ibase, inr = 0;
    943	enum dfl_id_type type;
    944	int virq;
    945	u64 v;
    946
    947	type = feature_dev_id_type(binfo->feature_dev);
    948
    949	/*
    950	 * Ideally DFL framework should only read info from DFL header, but
    951	 * current version DFL only provides mmio resources information for
    952	 * each feature in DFL Header, no field for interrupt resources.
    953	 * Interrupt resource information is provided by specific mmio
    954	 * registers of each private feature which supports interrupt. So in
    955	 * order to parse and assign irq resources, DFL framework has to look
    956	 * into specific capability registers of these private features.
    957	 *
    958	 * Once future DFL version supports generic interrupt resource
    959	 * information in common DFL headers, the generic interrupt parsing
    960	 * code will be added. But in order to be compatible to old version
    961	 * DFL, the driver may still fall back to these quirks.
    962	 */
    963	if (type == PORT_ID) {
    964		switch (fid) {
    965		case PORT_FEATURE_ID_UINT:
    966			v = readq(base + PORT_UINT_CAP);
    967			ibase = FIELD_GET(PORT_UINT_CAP_FST_VECT, v);
    968			inr = FIELD_GET(PORT_UINT_CAP_INT_NUM, v);
    969			break;
    970		case PORT_FEATURE_ID_ERROR:
    971			v = readq(base + PORT_ERROR_CAP);
    972			ibase = FIELD_GET(PORT_ERROR_CAP_INT_VECT, v);
    973			inr = FIELD_GET(PORT_ERROR_CAP_SUPP_INT, v);
    974			break;
    975		}
    976	} else if (type == FME_ID) {
    977		if (fid == FME_FEATURE_ID_GLOBAL_ERR) {
    978			v = readq(base + FME_ERROR_CAP);
    979			ibase = FIELD_GET(FME_ERROR_CAP_INT_VECT, v);
    980			inr = FIELD_GET(FME_ERROR_CAP_SUPP_INT, v);
    981		}
    982	}
    983
    984	if (!inr) {
    985		*irq_base = 0;
    986		*nr_irqs = 0;
    987		return 0;
    988	}
    989
    990	dev_dbg(binfo->dev, "feature: 0x%x, irq_base: %u, nr_irqs: %u\n",
    991		fid, ibase, inr);
    992
    993	if (ibase + inr > binfo->nr_irqs) {
    994		dev_err(binfo->dev,
    995			"Invalid interrupt number in feature 0x%x\n", fid);
    996		return -EINVAL;
    997	}
    998
    999	for (i = 0; i < inr; i++) {
   1000		virq = binfo->irq_table[ibase + i];
   1001		if (virq < 0 || virq > NR_IRQS) {
   1002			dev_err(binfo->dev,
   1003				"Invalid irq table entry for feature 0x%x\n",
   1004				fid);
   1005			return -EINVAL;
   1006		}
   1007	}
   1008
   1009	*irq_base = ibase;
   1010	*nr_irqs = inr;
   1011
   1012	return 0;
   1013}
   1014
   1015/*
   1016 * when create sub feature instances, for private features, it doesn't need
   1017 * to provide resource size and feature id as they could be read from DFH
   1018 * register. For afu sub feature, its register region only contains user
   1019 * defined registers, so never trust any information from it, just use the
   1020 * resource size information provided by its parent FIU.
   1021 */
   1022static int
   1023create_feature_instance(struct build_feature_devs_info *binfo,
   1024			resource_size_t ofst, resource_size_t size, u16 fid)
   1025{
   1026	unsigned int irq_base, nr_irqs;
   1027	struct dfl_feature_info *finfo;
   1028	u8 revision = 0;
   1029	int ret;
   1030	u64 v;
   1031
   1032	if (fid != FEATURE_ID_AFU) {
   1033		v = readq(binfo->ioaddr + ofst);
   1034		revision = FIELD_GET(DFH_REVISION, v);
   1035
   1036		/* read feature size and id if inputs are invalid */
   1037		size = size ? size : feature_size(v);
   1038		fid = fid ? fid : feature_id(v);
   1039	}
   1040
   1041	if (binfo->len - ofst < size)
   1042		return -EINVAL;
   1043
   1044	ret = parse_feature_irqs(binfo, ofst, fid, &irq_base, &nr_irqs);
   1045	if (ret)
   1046		return ret;
   1047
   1048	finfo = kzalloc(sizeof(*finfo), GFP_KERNEL);
   1049	if (!finfo)
   1050		return -ENOMEM;
   1051
   1052	finfo->fid = fid;
   1053	finfo->revision = revision;
   1054	finfo->mmio_res.start = binfo->start + ofst;
   1055	finfo->mmio_res.end = finfo->mmio_res.start + size - 1;
   1056	finfo->mmio_res.flags = IORESOURCE_MEM;
   1057	finfo->irq_base = irq_base;
   1058	finfo->nr_irqs = nr_irqs;
   1059
   1060	list_add_tail(&finfo->node, &binfo->sub_features);
   1061	binfo->feature_num++;
   1062
   1063	return 0;
   1064}
   1065
   1066static int parse_feature_port_afu(struct build_feature_devs_info *binfo,
   1067				  resource_size_t ofst)
   1068{
   1069	u64 v = readq(binfo->ioaddr + PORT_HDR_CAP);
   1070	u32 size = FIELD_GET(PORT_CAP_MMIO_SIZE, v) << 10;
   1071
   1072	WARN_ON(!size);
   1073
   1074	return create_feature_instance(binfo, ofst, size, FEATURE_ID_AFU);
   1075}
   1076
   1077#define is_feature_dev_detected(binfo) (!!(binfo)->feature_dev)
   1078
   1079static int parse_feature_afu(struct build_feature_devs_info *binfo,
   1080			     resource_size_t ofst)
   1081{
   1082	if (!is_feature_dev_detected(binfo)) {
   1083		dev_err(binfo->dev, "this AFU does not belong to any FIU.\n");
   1084		return -EINVAL;
   1085	}
   1086
   1087	switch (feature_dev_id_type(binfo->feature_dev)) {
   1088	case PORT_ID:
   1089		return parse_feature_port_afu(binfo, ofst);
   1090	default:
   1091		dev_info(binfo->dev, "AFU belonging to FIU %s is not supported yet.\n",
   1092			 binfo->feature_dev->name);
   1093	}
   1094
   1095	return 0;
   1096}
   1097
   1098static int build_info_prepare(struct build_feature_devs_info *binfo,
   1099			      resource_size_t start, resource_size_t len)
   1100{
   1101	struct device *dev = binfo->dev;
   1102	void __iomem *ioaddr;
   1103
   1104	if (!devm_request_mem_region(dev, start, len, dev_name(dev))) {
   1105		dev_err(dev, "request region fail, start:%pa, len:%pa\n",
   1106			&start, &len);
   1107		return -EBUSY;
   1108	}
   1109
   1110	ioaddr = devm_ioremap(dev, start, len);
   1111	if (!ioaddr) {
   1112		dev_err(dev, "ioremap region fail, start:%pa, len:%pa\n",
   1113			&start, &len);
   1114		return -ENOMEM;
   1115	}
   1116
   1117	binfo->start = start;
   1118	binfo->len = len;
   1119	binfo->ioaddr = ioaddr;
   1120
   1121	return 0;
   1122}
   1123
   1124static void build_info_complete(struct build_feature_devs_info *binfo)
   1125{
   1126	devm_iounmap(binfo->dev, binfo->ioaddr);
   1127	devm_release_mem_region(binfo->dev, binfo->start, binfo->len);
   1128}
   1129
   1130static int parse_feature_fiu(struct build_feature_devs_info *binfo,
   1131			     resource_size_t ofst)
   1132{
   1133	int ret = 0;
   1134	u32 offset;
   1135	u16 id;
   1136	u64 v;
   1137
   1138	if (is_feature_dev_detected(binfo)) {
   1139		build_info_complete(binfo);
   1140
   1141		ret = build_info_commit_dev(binfo);
   1142		if (ret)
   1143			return ret;
   1144
   1145		ret = build_info_prepare(binfo, binfo->start + ofst,
   1146					 binfo->len - ofst);
   1147		if (ret)
   1148			return ret;
   1149	}
   1150
   1151	v = readq(binfo->ioaddr + DFH);
   1152	id = FIELD_GET(DFH_ID, v);
   1153
   1154	/* create platform device for dfl feature dev */
   1155	ret = build_info_create_dev(binfo, dfh_id_to_type(id));
   1156	if (ret)
   1157		return ret;
   1158
   1159	ret = create_feature_instance(binfo, 0, 0, 0);
   1160	if (ret)
   1161		return ret;
   1162	/*
   1163	 * find and parse FIU's child AFU via its NEXT_AFU register.
   1164	 * please note that only Port has valid NEXT_AFU pointer per spec.
   1165	 */
   1166	v = readq(binfo->ioaddr + NEXT_AFU);
   1167
   1168	offset = FIELD_GET(NEXT_AFU_NEXT_DFH_OFST, v);
   1169	if (offset)
   1170		return parse_feature_afu(binfo, offset);
   1171
   1172	dev_dbg(binfo->dev, "No AFUs detected on FIU %d\n", id);
   1173
   1174	return ret;
   1175}
   1176
   1177static int parse_feature_private(struct build_feature_devs_info *binfo,
   1178				 resource_size_t ofst)
   1179{
   1180	if (!is_feature_dev_detected(binfo)) {
   1181		dev_err(binfo->dev, "the private feature 0x%x does not belong to any AFU.\n",
   1182			feature_id(readq(binfo->ioaddr + ofst)));
   1183		return -EINVAL;
   1184	}
   1185
   1186	return create_feature_instance(binfo, ofst, 0, 0);
   1187}
   1188
   1189/**
   1190 * parse_feature - parse a feature on given device feature list
   1191 *
   1192 * @binfo: build feature devices information.
   1193 * @ofst: offset to current FIU header
   1194 */
   1195static int parse_feature(struct build_feature_devs_info *binfo,
   1196			 resource_size_t ofst)
   1197{
   1198	u64 v;
   1199	u32 type;
   1200
   1201	v = readq(binfo->ioaddr + ofst + DFH);
   1202	type = FIELD_GET(DFH_TYPE, v);
   1203
   1204	switch (type) {
   1205	case DFH_TYPE_AFU:
   1206		return parse_feature_afu(binfo, ofst);
   1207	case DFH_TYPE_PRIVATE:
   1208		return parse_feature_private(binfo, ofst);
   1209	case DFH_TYPE_FIU:
   1210		return parse_feature_fiu(binfo, ofst);
   1211	default:
   1212		dev_info(binfo->dev,
   1213			 "Feature Type %x is not supported.\n", type);
   1214	}
   1215
   1216	return 0;
   1217}
   1218
   1219static int parse_feature_list(struct build_feature_devs_info *binfo,
   1220			      resource_size_t start, resource_size_t len)
   1221{
   1222	resource_size_t end = start + len;
   1223	int ret = 0;
   1224	u32 ofst = 0;
   1225	u64 v;
   1226
   1227	ret = build_info_prepare(binfo, start, len);
   1228	if (ret)
   1229		return ret;
   1230
   1231	/* walk through the device feature list via DFH's next DFH pointer. */
   1232	for (; start < end; start += ofst) {
   1233		if (end - start < DFH_SIZE) {
   1234			dev_err(binfo->dev, "The region is too small to contain a feature.\n");
   1235			return -EINVAL;
   1236		}
   1237
   1238		ret = parse_feature(binfo, start - binfo->start);
   1239		if (ret)
   1240			return ret;
   1241
   1242		v = readq(binfo->ioaddr + start - binfo->start + DFH);
   1243		ofst = FIELD_GET(DFH_NEXT_HDR_OFST, v);
   1244
   1245		/* stop parsing if EOL(End of List) is set or offset is 0 */
   1246		if ((v & DFH_EOL) || !ofst)
   1247			break;
   1248	}
   1249
   1250	/* commit current feature device when reach the end of list */
   1251	build_info_complete(binfo);
   1252
   1253	if (is_feature_dev_detected(binfo))
   1254		ret = build_info_commit_dev(binfo);
   1255
   1256	return ret;
   1257}
   1258
   1259struct dfl_fpga_enum_info *dfl_fpga_enum_info_alloc(struct device *dev)
   1260{
   1261	struct dfl_fpga_enum_info *info;
   1262
   1263	get_device(dev);
   1264
   1265	info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
   1266	if (!info) {
   1267		put_device(dev);
   1268		return NULL;
   1269	}
   1270
   1271	info->dev = dev;
   1272	INIT_LIST_HEAD(&info->dfls);
   1273
   1274	return info;
   1275}
   1276EXPORT_SYMBOL_GPL(dfl_fpga_enum_info_alloc);
   1277
   1278void dfl_fpga_enum_info_free(struct dfl_fpga_enum_info *info)
   1279{
   1280	struct dfl_fpga_enum_dfl *tmp, *dfl;
   1281	struct device *dev;
   1282
   1283	if (!info)
   1284		return;
   1285
   1286	dev = info->dev;
   1287
   1288	/* remove all device feature lists in the list. */
   1289	list_for_each_entry_safe(dfl, tmp, &info->dfls, node) {
   1290		list_del(&dfl->node);
   1291		devm_kfree(dev, dfl);
   1292	}
   1293
   1294	/* remove irq table */
   1295	if (info->irq_table)
   1296		devm_kfree(dev, info->irq_table);
   1297
   1298	devm_kfree(dev, info);
   1299	put_device(dev);
   1300}
   1301EXPORT_SYMBOL_GPL(dfl_fpga_enum_info_free);
   1302
   1303/**
   1304 * dfl_fpga_enum_info_add_dfl - add info of a device feature list to enum info
   1305 *
   1306 * @info: ptr to dfl_fpga_enum_info
   1307 * @start: mmio resource address of the device feature list.
   1308 * @len: mmio resource length of the device feature list.
   1309 *
   1310 * One FPGA device may have one or more Device Feature Lists (DFLs), use this
   1311 * function to add information of each DFL to common data structure for next
   1312 * step enumeration.
   1313 *
   1314 * Return: 0 on success, negative error code otherwise.
   1315 */
   1316int dfl_fpga_enum_info_add_dfl(struct dfl_fpga_enum_info *info,
   1317			       resource_size_t start, resource_size_t len)
   1318{
   1319	struct dfl_fpga_enum_dfl *dfl;
   1320
   1321	dfl = devm_kzalloc(info->dev, sizeof(*dfl), GFP_KERNEL);
   1322	if (!dfl)
   1323		return -ENOMEM;
   1324
   1325	dfl->start = start;
   1326	dfl->len = len;
   1327
   1328	list_add_tail(&dfl->node, &info->dfls);
   1329
   1330	return 0;
   1331}
   1332EXPORT_SYMBOL_GPL(dfl_fpga_enum_info_add_dfl);
   1333
   1334/**
   1335 * dfl_fpga_enum_info_add_irq - add irq table to enum info
   1336 *
   1337 * @info: ptr to dfl_fpga_enum_info
   1338 * @nr_irqs: number of irqs of the DFL fpga device to be enumerated.
   1339 * @irq_table: Linux IRQ numbers for all irqs, indexed by local irq index of
   1340 *	       this device.
   1341 *
   1342 * One FPGA device may have several interrupts. This function adds irq
   1343 * information of the DFL fpga device to enum info for next step enumeration.
   1344 * This function should be called before dfl_fpga_feature_devs_enumerate().
   1345 * As we only support one irq domain for all DFLs in the same enum info, adding
   1346 * irq table a second time for the same enum info will return error.
   1347 *
   1348 * If we need to enumerate DFLs which belong to different irq domains, we
   1349 * should fill more enum info and enumerate them one by one.
   1350 *
   1351 * Return: 0 on success, negative error code otherwise.
   1352 */
   1353int dfl_fpga_enum_info_add_irq(struct dfl_fpga_enum_info *info,
   1354			       unsigned int nr_irqs, int *irq_table)
   1355{
   1356	if (!nr_irqs || !irq_table)
   1357		return -EINVAL;
   1358
   1359	if (info->irq_table)
   1360		return -EEXIST;
   1361
   1362	info->irq_table = devm_kmemdup(info->dev, irq_table,
   1363				       sizeof(int) * nr_irqs, GFP_KERNEL);
   1364	if (!info->irq_table)
   1365		return -ENOMEM;
   1366
   1367	info->nr_irqs = nr_irqs;
   1368
   1369	return 0;
   1370}
   1371EXPORT_SYMBOL_GPL(dfl_fpga_enum_info_add_irq);
   1372
   1373static int remove_feature_dev(struct device *dev, void *data)
   1374{
   1375	struct platform_device *pdev = to_platform_device(dev);
   1376	enum dfl_id_type type = feature_dev_id_type(pdev);
   1377	int id = pdev->id;
   1378
   1379	platform_device_unregister(pdev);
   1380
   1381	dfl_id_free(type, id);
   1382
   1383	return 0;
   1384}
   1385
   1386static void remove_feature_devs(struct dfl_fpga_cdev *cdev)
   1387{
   1388	device_for_each_child(&cdev->region->dev, NULL, remove_feature_dev);
   1389}
   1390
   1391/**
   1392 * dfl_fpga_feature_devs_enumerate - enumerate feature devices
   1393 * @info: information for enumeration.
   1394 *
   1395 * This function creates a container device (base FPGA region), enumerates
   1396 * feature devices based on the enumeration info and creates platform devices
   1397 * under the container device.
   1398 *
   1399 * Return: dfl_fpga_cdev struct on success, -errno on failure
   1400 */
   1401struct dfl_fpga_cdev *
   1402dfl_fpga_feature_devs_enumerate(struct dfl_fpga_enum_info *info)
   1403{
   1404	struct build_feature_devs_info *binfo;
   1405	struct dfl_fpga_enum_dfl *dfl;
   1406	struct dfl_fpga_cdev *cdev;
   1407	int ret = 0;
   1408
   1409	if (!info->dev)
   1410		return ERR_PTR(-ENODEV);
   1411
   1412	cdev = devm_kzalloc(info->dev, sizeof(*cdev), GFP_KERNEL);
   1413	if (!cdev)
   1414		return ERR_PTR(-ENOMEM);
   1415
   1416	cdev->parent = info->dev;
   1417	mutex_init(&cdev->lock);
   1418	INIT_LIST_HEAD(&cdev->port_dev_list);
   1419
   1420	cdev->region = fpga_region_register(info->dev, NULL, NULL);
   1421	if (IS_ERR(cdev->region)) {
   1422		ret = PTR_ERR(cdev->region);
   1423		goto free_cdev_exit;
   1424	}
   1425
   1426	/* create and init build info for enumeration */
   1427	binfo = devm_kzalloc(info->dev, sizeof(*binfo), GFP_KERNEL);
   1428	if (!binfo) {
   1429		ret = -ENOMEM;
   1430		goto unregister_region_exit;
   1431	}
   1432
   1433	binfo->dev = info->dev;
   1434	binfo->cdev = cdev;
   1435
   1436	binfo->nr_irqs = info->nr_irqs;
   1437	if (info->nr_irqs)
   1438		binfo->irq_table = info->irq_table;
   1439
   1440	/*
   1441	 * start enumeration for all feature devices based on Device Feature
   1442	 * Lists.
   1443	 */
   1444	list_for_each_entry(dfl, &info->dfls, node) {
   1445		ret = parse_feature_list(binfo, dfl->start, dfl->len);
   1446		if (ret) {
   1447			remove_feature_devs(cdev);
   1448			build_info_free(binfo);
   1449			goto unregister_region_exit;
   1450		}
   1451	}
   1452
   1453	build_info_free(binfo);
   1454
   1455	return cdev;
   1456
   1457unregister_region_exit:
   1458	fpga_region_unregister(cdev->region);
   1459free_cdev_exit:
   1460	devm_kfree(info->dev, cdev);
   1461	return ERR_PTR(ret);
   1462}
   1463EXPORT_SYMBOL_GPL(dfl_fpga_feature_devs_enumerate);
   1464
   1465/**
   1466 * dfl_fpga_feature_devs_remove - remove all feature devices
   1467 * @cdev: fpga container device.
   1468 *
   1469 * Remove the container device and all feature devices under given container
   1470 * devices.
   1471 */
   1472void dfl_fpga_feature_devs_remove(struct dfl_fpga_cdev *cdev)
   1473{
   1474	struct dfl_feature_platform_data *pdata, *ptmp;
   1475
   1476	mutex_lock(&cdev->lock);
   1477	if (cdev->fme_dev)
   1478		put_device(cdev->fme_dev);
   1479
   1480	list_for_each_entry_safe(pdata, ptmp, &cdev->port_dev_list, node) {
   1481		struct platform_device *port_dev = pdata->dev;
   1482
   1483		/* remove released ports */
   1484		if (!device_is_registered(&port_dev->dev)) {
   1485			dfl_id_free(feature_dev_id_type(port_dev),
   1486				    port_dev->id);
   1487			platform_device_put(port_dev);
   1488		}
   1489
   1490		list_del(&pdata->node);
   1491		put_device(&port_dev->dev);
   1492	}
   1493	mutex_unlock(&cdev->lock);
   1494
   1495	remove_feature_devs(cdev);
   1496
   1497	fpga_region_unregister(cdev->region);
   1498	devm_kfree(cdev->parent, cdev);
   1499}
   1500EXPORT_SYMBOL_GPL(dfl_fpga_feature_devs_remove);
   1501
   1502/**
   1503 * __dfl_fpga_cdev_find_port - find a port under given container device
   1504 *
   1505 * @cdev: container device
   1506 * @data: data passed to match function
   1507 * @match: match function used to find specific port from the port device list
   1508 *
   1509 * Find a port device under container device. This function needs to be
   1510 * invoked with lock held.
   1511 *
   1512 * Return: pointer to port's platform device if successful, NULL otherwise.
   1513 *
   1514 * NOTE: you will need to drop the device reference with put_device() after use.
   1515 */
   1516struct platform_device *
   1517__dfl_fpga_cdev_find_port(struct dfl_fpga_cdev *cdev, void *data,
   1518			  int (*match)(struct platform_device *, void *))
   1519{
   1520	struct dfl_feature_platform_data *pdata;
   1521	struct platform_device *port_dev;
   1522
   1523	list_for_each_entry(pdata, &cdev->port_dev_list, node) {
   1524		port_dev = pdata->dev;
   1525
   1526		if (match(port_dev, data) && get_device(&port_dev->dev))
   1527			return port_dev;
   1528	}
   1529
   1530	return NULL;
   1531}
   1532EXPORT_SYMBOL_GPL(__dfl_fpga_cdev_find_port);
   1533
   1534static int __init dfl_fpga_init(void)
   1535{
   1536	int ret;
   1537
   1538	ret = bus_register(&dfl_bus_type);
   1539	if (ret)
   1540		return ret;
   1541
   1542	dfl_ids_init();
   1543
   1544	ret = dfl_chardev_init();
   1545	if (ret) {
   1546		dfl_ids_destroy();
   1547		bus_unregister(&dfl_bus_type);
   1548	}
   1549
   1550	return ret;
   1551}
   1552
   1553/**
   1554 * dfl_fpga_cdev_release_port - release a port platform device
   1555 *
   1556 * @cdev: parent container device.
   1557 * @port_id: id of the port platform device.
   1558 *
   1559 * This function allows user to release a port platform device. This is a
   1560 * mandatory step before turn a port from PF into VF for SRIOV support.
   1561 *
   1562 * Return: 0 on success, negative error code otherwise.
   1563 */
   1564int dfl_fpga_cdev_release_port(struct dfl_fpga_cdev *cdev, int port_id)
   1565{
   1566	struct dfl_feature_platform_data *pdata;
   1567	struct platform_device *port_pdev;
   1568	int ret = -ENODEV;
   1569
   1570	mutex_lock(&cdev->lock);
   1571	port_pdev = __dfl_fpga_cdev_find_port(cdev, &port_id,
   1572					      dfl_fpga_check_port_id);
   1573	if (!port_pdev)
   1574		goto unlock_exit;
   1575
   1576	if (!device_is_registered(&port_pdev->dev)) {
   1577		ret = -EBUSY;
   1578		goto put_dev_exit;
   1579	}
   1580
   1581	pdata = dev_get_platdata(&port_pdev->dev);
   1582
   1583	mutex_lock(&pdata->lock);
   1584	ret = dfl_feature_dev_use_begin(pdata, true);
   1585	mutex_unlock(&pdata->lock);
   1586	if (ret)
   1587		goto put_dev_exit;
   1588
   1589	platform_device_del(port_pdev);
   1590	cdev->released_port_num++;
   1591put_dev_exit:
   1592	put_device(&port_pdev->dev);
   1593unlock_exit:
   1594	mutex_unlock(&cdev->lock);
   1595	return ret;
   1596}
   1597EXPORT_SYMBOL_GPL(dfl_fpga_cdev_release_port);
   1598
   1599/**
   1600 * dfl_fpga_cdev_assign_port - assign a port platform device back
   1601 *
   1602 * @cdev: parent container device.
   1603 * @port_id: id of the port platform device.
   1604 *
   1605 * This function allows user to assign a port platform device back. This is
   1606 * a mandatory step after disable SRIOV support.
   1607 *
   1608 * Return: 0 on success, negative error code otherwise.
   1609 */
   1610int dfl_fpga_cdev_assign_port(struct dfl_fpga_cdev *cdev, int port_id)
   1611{
   1612	struct dfl_feature_platform_data *pdata;
   1613	struct platform_device *port_pdev;
   1614	int ret = -ENODEV;
   1615
   1616	mutex_lock(&cdev->lock);
   1617	port_pdev = __dfl_fpga_cdev_find_port(cdev, &port_id,
   1618					      dfl_fpga_check_port_id);
   1619	if (!port_pdev)
   1620		goto unlock_exit;
   1621
   1622	if (device_is_registered(&port_pdev->dev)) {
   1623		ret = -EBUSY;
   1624		goto put_dev_exit;
   1625	}
   1626
   1627	ret = platform_device_add(port_pdev);
   1628	if (ret)
   1629		goto put_dev_exit;
   1630
   1631	pdata = dev_get_platdata(&port_pdev->dev);
   1632
   1633	mutex_lock(&pdata->lock);
   1634	dfl_feature_dev_use_end(pdata);
   1635	mutex_unlock(&pdata->lock);
   1636
   1637	cdev->released_port_num--;
   1638put_dev_exit:
   1639	put_device(&port_pdev->dev);
   1640unlock_exit:
   1641	mutex_unlock(&cdev->lock);
   1642	return ret;
   1643}
   1644EXPORT_SYMBOL_GPL(dfl_fpga_cdev_assign_port);
   1645
   1646static void config_port_access_mode(struct device *fme_dev, int port_id,
   1647				    bool is_vf)
   1648{
   1649	void __iomem *base;
   1650	u64 v;
   1651
   1652	base = dfl_get_feature_ioaddr_by_id(fme_dev, FME_FEATURE_ID_HEADER);
   1653
   1654	v = readq(base + FME_HDR_PORT_OFST(port_id));
   1655
   1656	v &= ~FME_PORT_OFST_ACC_CTRL;
   1657	v |= FIELD_PREP(FME_PORT_OFST_ACC_CTRL,
   1658			is_vf ? FME_PORT_OFST_ACC_VF : FME_PORT_OFST_ACC_PF);
   1659
   1660	writeq(v, base + FME_HDR_PORT_OFST(port_id));
   1661}
   1662
   1663#define config_port_vf_mode(dev, id) config_port_access_mode(dev, id, true)
   1664#define config_port_pf_mode(dev, id) config_port_access_mode(dev, id, false)
   1665
   1666/**
   1667 * dfl_fpga_cdev_config_ports_pf - configure ports to PF access mode
   1668 *
   1669 * @cdev: parent container device.
   1670 *
   1671 * This function is needed in sriov configuration routine. It could be used to
   1672 * configure the all released ports from VF access mode to PF.
   1673 */
   1674void dfl_fpga_cdev_config_ports_pf(struct dfl_fpga_cdev *cdev)
   1675{
   1676	struct dfl_feature_platform_data *pdata;
   1677
   1678	mutex_lock(&cdev->lock);
   1679	list_for_each_entry(pdata, &cdev->port_dev_list, node) {
   1680		if (device_is_registered(&pdata->dev->dev))
   1681			continue;
   1682
   1683		config_port_pf_mode(cdev->fme_dev, pdata->id);
   1684	}
   1685	mutex_unlock(&cdev->lock);
   1686}
   1687EXPORT_SYMBOL_GPL(dfl_fpga_cdev_config_ports_pf);
   1688
   1689/**
   1690 * dfl_fpga_cdev_config_ports_vf - configure ports to VF access mode
   1691 *
   1692 * @cdev: parent container device.
   1693 * @num_vfs: VF device number.
   1694 *
   1695 * This function is needed in sriov configuration routine. It could be used to
   1696 * configure the released ports from PF access mode to VF.
   1697 *
   1698 * Return: 0 on success, negative error code otherwise.
   1699 */
   1700int dfl_fpga_cdev_config_ports_vf(struct dfl_fpga_cdev *cdev, int num_vfs)
   1701{
   1702	struct dfl_feature_platform_data *pdata;
   1703	int ret = 0;
   1704
   1705	mutex_lock(&cdev->lock);
   1706	/*
   1707	 * can't turn multiple ports into 1 VF device, only 1 port for 1 VF
   1708	 * device, so if released port number doesn't match VF device number,
   1709	 * then reject the request with -EINVAL error code.
   1710	 */
   1711	if (cdev->released_port_num != num_vfs) {
   1712		ret = -EINVAL;
   1713		goto done;
   1714	}
   1715
   1716	list_for_each_entry(pdata, &cdev->port_dev_list, node) {
   1717		if (device_is_registered(&pdata->dev->dev))
   1718			continue;
   1719
   1720		config_port_vf_mode(cdev->fme_dev, pdata->id);
   1721	}
   1722done:
   1723	mutex_unlock(&cdev->lock);
   1724	return ret;
   1725}
   1726EXPORT_SYMBOL_GPL(dfl_fpga_cdev_config_ports_vf);
   1727
   1728static irqreturn_t dfl_irq_handler(int irq, void *arg)
   1729{
   1730	struct eventfd_ctx *trigger = arg;
   1731
   1732	eventfd_signal(trigger, 1);
   1733	return IRQ_HANDLED;
   1734}
   1735
   1736static int do_set_irq_trigger(struct dfl_feature *feature, unsigned int idx,
   1737			      int fd)
   1738{
   1739	struct platform_device *pdev = feature->dev;
   1740	struct eventfd_ctx *trigger;
   1741	int irq, ret;
   1742
   1743	irq = feature->irq_ctx[idx].irq;
   1744
   1745	if (feature->irq_ctx[idx].trigger) {
   1746		free_irq(irq, feature->irq_ctx[idx].trigger);
   1747		kfree(feature->irq_ctx[idx].name);
   1748		eventfd_ctx_put(feature->irq_ctx[idx].trigger);
   1749		feature->irq_ctx[idx].trigger = NULL;
   1750	}
   1751
   1752	if (fd < 0)
   1753		return 0;
   1754
   1755	feature->irq_ctx[idx].name =
   1756		kasprintf(GFP_KERNEL, "fpga-irq[%u](%s-%x)", idx,
   1757			  dev_name(&pdev->dev), feature->id);
   1758	if (!feature->irq_ctx[idx].name)
   1759		return -ENOMEM;
   1760
   1761	trigger = eventfd_ctx_fdget(fd);
   1762	if (IS_ERR(trigger)) {
   1763		ret = PTR_ERR(trigger);
   1764		goto free_name;
   1765	}
   1766
   1767	ret = request_irq(irq, dfl_irq_handler, 0,
   1768			  feature->irq_ctx[idx].name, trigger);
   1769	if (!ret) {
   1770		feature->irq_ctx[idx].trigger = trigger;
   1771		return ret;
   1772	}
   1773
   1774	eventfd_ctx_put(trigger);
   1775free_name:
   1776	kfree(feature->irq_ctx[idx].name);
   1777
   1778	return ret;
   1779}
   1780
   1781/**
   1782 * dfl_fpga_set_irq_triggers - set eventfd triggers for dfl feature interrupts
   1783 *
   1784 * @feature: dfl sub feature.
   1785 * @start: start of irq index in this dfl sub feature.
   1786 * @count: number of irqs.
   1787 * @fds: eventfds to bind with irqs. unbind related irq if fds[n] is negative.
   1788 *	 unbind "count" specified number of irqs if fds ptr is NULL.
   1789 *
   1790 * Bind given eventfds with irqs in this dfl sub feature. Unbind related irq if
   1791 * fds[n] is negative. Unbind "count" specified number of irqs if fds ptr is
   1792 * NULL.
   1793 *
   1794 * Return: 0 on success, negative error code otherwise.
   1795 */
   1796int dfl_fpga_set_irq_triggers(struct dfl_feature *feature, unsigned int start,
   1797			      unsigned int count, int32_t *fds)
   1798{
   1799	unsigned int i;
   1800	int ret = 0;
   1801
   1802	/* overflow */
   1803	if (unlikely(start + count < start))
   1804		return -EINVAL;
   1805
   1806	/* exceeds nr_irqs */
   1807	if (start + count > feature->nr_irqs)
   1808		return -EINVAL;
   1809
   1810	for (i = 0; i < count; i++) {
   1811		int fd = fds ? fds[i] : -1;
   1812
   1813		ret = do_set_irq_trigger(feature, start + i, fd);
   1814		if (ret) {
   1815			while (i--)
   1816				do_set_irq_trigger(feature, start + i, -1);
   1817			break;
   1818		}
   1819	}
   1820
   1821	return ret;
   1822}
   1823EXPORT_SYMBOL_GPL(dfl_fpga_set_irq_triggers);
   1824
   1825/**
   1826 * dfl_feature_ioctl_get_num_irqs - dfl feature _GET_IRQ_NUM ioctl interface.
   1827 * @pdev: the feature device which has the sub feature
   1828 * @feature: the dfl sub feature
   1829 * @arg: ioctl argument
   1830 *
   1831 * Return: 0 on success, negative error code otherwise.
   1832 */
   1833long dfl_feature_ioctl_get_num_irqs(struct platform_device *pdev,
   1834				    struct dfl_feature *feature,
   1835				    unsigned long arg)
   1836{
   1837	return put_user(feature->nr_irqs, (__u32 __user *)arg);
   1838}
   1839EXPORT_SYMBOL_GPL(dfl_feature_ioctl_get_num_irqs);
   1840
   1841/**
   1842 * dfl_feature_ioctl_set_irq - dfl feature _SET_IRQ ioctl interface.
   1843 * @pdev: the feature device which has the sub feature
   1844 * @feature: the dfl sub feature
   1845 * @arg: ioctl argument
   1846 *
   1847 * Return: 0 on success, negative error code otherwise.
   1848 */
   1849long dfl_feature_ioctl_set_irq(struct platform_device *pdev,
   1850			       struct dfl_feature *feature,
   1851			       unsigned long arg)
   1852{
   1853	struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
   1854	struct dfl_fpga_irq_set hdr;
   1855	s32 *fds;
   1856	long ret;
   1857
   1858	if (!feature->nr_irqs)
   1859		return -ENOENT;
   1860
   1861	if (copy_from_user(&hdr, (void __user *)arg, sizeof(hdr)))
   1862		return -EFAULT;
   1863
   1864	if (!hdr.count || (hdr.start + hdr.count > feature->nr_irqs) ||
   1865	    (hdr.start + hdr.count < hdr.start))
   1866		return -EINVAL;
   1867
   1868	fds = memdup_user((void __user *)(arg + sizeof(hdr)),
   1869			  hdr.count * sizeof(s32));
   1870	if (IS_ERR(fds))
   1871		return PTR_ERR(fds);
   1872
   1873	mutex_lock(&pdata->lock);
   1874	ret = dfl_fpga_set_irq_triggers(feature, hdr.start, hdr.count, fds);
   1875	mutex_unlock(&pdata->lock);
   1876
   1877	kfree(fds);
   1878	return ret;
   1879}
   1880EXPORT_SYMBOL_GPL(dfl_feature_ioctl_set_irq);
   1881
   1882static void __exit dfl_fpga_exit(void)
   1883{
   1884	dfl_chardev_uinit();
   1885	dfl_ids_destroy();
   1886	bus_unregister(&dfl_bus_type);
   1887}
   1888
   1889module_init(dfl_fpga_init);
   1890module_exit(dfl_fpga_exit);
   1891
   1892MODULE_DESCRIPTION("FPGA Device Feature List (DFL) Support");
   1893MODULE_AUTHOR("Intel Corporation");
   1894MODULE_LICENSE("GPL v2");