xref: /openbmc/linux/drivers/fpga/dfl.c (revision a20eefae)
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/module.h>
14 
15 #include "dfl.h"
16 
17 static DEFINE_MUTEX(dfl_id_mutex);
18 
19 /*
20  * when adding a new feature dev support in DFL framework, it's required to
21  * add a new item in enum dfl_id_type and provide related information in below
22  * dfl_devs table which is indexed by dfl_id_type, e.g. name string used for
23  * platform device creation (define name strings in dfl.h, as they could be
24  * reused by platform device drivers).
25  *
26  * if the new feature dev needs chardev support, then it's required to add
27  * a new item in dfl_chardevs table and configure dfl_devs[i].devt_type as
28  * index to dfl_chardevs table. If no chardev support just set devt_type
29  * as one invalid index (DFL_FPGA_DEVT_MAX).
30  */
31 enum dfl_id_type {
32 	FME_ID,		/* fme id allocation and mapping */
33 	PORT_ID,	/* port id allocation and mapping */
34 	DFL_ID_MAX,
35 };
36 
37 enum dfl_fpga_devt_type {
38 	DFL_FPGA_DEVT_FME,
39 	DFL_FPGA_DEVT_PORT,
40 	DFL_FPGA_DEVT_MAX,
41 };
42 
43 static struct lock_class_key dfl_pdata_keys[DFL_ID_MAX];
44 
45 static const char *dfl_pdata_key_strings[DFL_ID_MAX] = {
46 	"dfl-fme-pdata",
47 	"dfl-port-pdata",
48 };
49 
50 /**
51  * dfl_dev_info - dfl feature device information.
52  * @name: name string of the feature platform device.
53  * @dfh_id: id value in Device Feature Header (DFH) register by DFL spec.
54  * @id: idr id of the feature dev.
55  * @devt_type: index to dfl_chrdevs[].
56  */
57 struct dfl_dev_info {
58 	const char *name;
59 	u32 dfh_id;
60 	struct idr id;
61 	enum dfl_fpga_devt_type devt_type;
62 };
63 
64 /* it is indexed by dfl_id_type */
65 static struct dfl_dev_info dfl_devs[] = {
66 	{.name = DFL_FPGA_FEATURE_DEV_FME, .dfh_id = DFH_ID_FIU_FME,
67 	 .devt_type = DFL_FPGA_DEVT_FME},
68 	{.name = DFL_FPGA_FEATURE_DEV_PORT, .dfh_id = DFH_ID_FIU_PORT,
69 	 .devt_type = DFL_FPGA_DEVT_PORT},
70 };
71 
72 /**
73  * dfl_chardev_info - chardev information of dfl feature device
74  * @name: nmae string of the char device.
75  * @devt: devt of the char device.
76  */
77 struct dfl_chardev_info {
78 	const char *name;
79 	dev_t devt;
80 };
81 
82 /* indexed by enum dfl_fpga_devt_type */
83 static struct dfl_chardev_info dfl_chrdevs[] = {
84 	{.name = DFL_FPGA_FEATURE_DEV_FME},
85 	{.name = DFL_FPGA_FEATURE_DEV_PORT},
86 };
87 
88 static void dfl_ids_init(void)
89 {
90 	int i;
91 
92 	for (i = 0; i < ARRAY_SIZE(dfl_devs); i++)
93 		idr_init(&dfl_devs[i].id);
94 }
95 
96 static void dfl_ids_destroy(void)
97 {
98 	int i;
99 
100 	for (i = 0; i < ARRAY_SIZE(dfl_devs); i++)
101 		idr_destroy(&dfl_devs[i].id);
102 }
103 
104 static int dfl_id_alloc(enum dfl_id_type type, struct device *dev)
105 {
106 	int id;
107 
108 	WARN_ON(type >= DFL_ID_MAX);
109 	mutex_lock(&dfl_id_mutex);
110 	id = idr_alloc(&dfl_devs[type].id, dev, 0, 0, GFP_KERNEL);
111 	mutex_unlock(&dfl_id_mutex);
112 
113 	return id;
114 }
115 
116 static void dfl_id_free(enum dfl_id_type type, int id)
117 {
118 	WARN_ON(type >= DFL_ID_MAX);
119 	mutex_lock(&dfl_id_mutex);
120 	idr_remove(&dfl_devs[type].id, id);
121 	mutex_unlock(&dfl_id_mutex);
122 }
123 
124 static enum dfl_id_type feature_dev_id_type(struct platform_device *pdev)
125 {
126 	int i;
127 
128 	for (i = 0; i < ARRAY_SIZE(dfl_devs); i++)
129 		if (!strcmp(dfl_devs[i].name, pdev->name))
130 			return i;
131 
132 	return DFL_ID_MAX;
133 }
134 
135 static enum dfl_id_type dfh_id_to_type(u32 id)
136 {
137 	int i;
138 
139 	for (i = 0; i < ARRAY_SIZE(dfl_devs); i++)
140 		if (dfl_devs[i].dfh_id == id)
141 			return i;
142 
143 	return DFL_ID_MAX;
144 }
145 
146 /*
147  * introduce a global port_ops list, it allows port drivers to register ops
148  * in such list, then other feature devices (e.g. FME), could use the port
149  * functions even related port platform device is hidden. Below is one example,
150  * in virtualization case of PCIe-based FPGA DFL device, when SRIOV is
151  * enabled, port (and it's AFU) is turned into VF and port platform device
152  * is hidden from system but it's still required to access port to finish FPGA
153  * reconfiguration function in FME.
154  */
155 
156 static DEFINE_MUTEX(dfl_port_ops_mutex);
157 static LIST_HEAD(dfl_port_ops_list);
158 
159 /**
160  * dfl_fpga_port_ops_get - get matched port ops from the global list
161  * @pdev: platform device to match with associated port ops.
162  * Return: matched port ops on success, NULL otherwise.
163  *
164  * Please note that must dfl_fpga_port_ops_put after use the port_ops.
165  */
166 struct dfl_fpga_port_ops *dfl_fpga_port_ops_get(struct platform_device *pdev)
167 {
168 	struct dfl_fpga_port_ops *ops = NULL;
169 
170 	mutex_lock(&dfl_port_ops_mutex);
171 	if (list_empty(&dfl_port_ops_list))
172 		goto done;
173 
174 	list_for_each_entry(ops, &dfl_port_ops_list, node) {
175 		/* match port_ops using the name of platform device */
176 		if (!strcmp(pdev->name, ops->name)) {
177 			if (!try_module_get(ops->owner))
178 				ops = NULL;
179 			goto done;
180 		}
181 	}
182 
183 	ops = NULL;
184 done:
185 	mutex_unlock(&dfl_port_ops_mutex);
186 	return ops;
187 }
188 EXPORT_SYMBOL_GPL(dfl_fpga_port_ops_get);
189 
190 /**
191  * dfl_fpga_port_ops_put - put port ops
192  * @ops: port ops.
193  */
194 void dfl_fpga_port_ops_put(struct dfl_fpga_port_ops *ops)
195 {
196 	if (ops && ops->owner)
197 		module_put(ops->owner);
198 }
199 EXPORT_SYMBOL_GPL(dfl_fpga_port_ops_put);
200 
201 /**
202  * dfl_fpga_port_ops_add - add port_ops to global list
203  * @ops: port ops to add.
204  */
205 void dfl_fpga_port_ops_add(struct dfl_fpga_port_ops *ops)
206 {
207 	mutex_lock(&dfl_port_ops_mutex);
208 	list_add_tail(&ops->node, &dfl_port_ops_list);
209 	mutex_unlock(&dfl_port_ops_mutex);
210 }
211 EXPORT_SYMBOL_GPL(dfl_fpga_port_ops_add);
212 
213 /**
214  * dfl_fpga_port_ops_del - remove port_ops from global list
215  * @ops: port ops to del.
216  */
217 void dfl_fpga_port_ops_del(struct dfl_fpga_port_ops *ops)
218 {
219 	mutex_lock(&dfl_port_ops_mutex);
220 	list_del(&ops->node);
221 	mutex_unlock(&dfl_port_ops_mutex);
222 }
223 EXPORT_SYMBOL_GPL(dfl_fpga_port_ops_del);
224 
225 /**
226  * dfl_fpga_check_port_id - check the port id
227  * @pdev: port platform device.
228  * @pport_id: port id to compare.
229  *
230  * Return: 1 if port device matches with given port id, otherwise 0.
231  */
232 int dfl_fpga_check_port_id(struct platform_device *pdev, void *pport_id)
233 {
234 	struct dfl_fpga_port_ops *port_ops = dfl_fpga_port_ops_get(pdev);
235 	int port_id;
236 
237 	if (!port_ops || !port_ops->get_id)
238 		return 0;
239 
240 	port_id = port_ops->get_id(pdev);
241 	dfl_fpga_port_ops_put(port_ops);
242 
243 	return port_id == *(int *)pport_id;
244 }
245 EXPORT_SYMBOL_GPL(dfl_fpga_check_port_id);
246 
247 /**
248  * dfl_fpga_dev_feature_uinit - uinit for sub features of dfl feature device
249  * @pdev: feature device.
250  */
251 void dfl_fpga_dev_feature_uinit(struct platform_device *pdev)
252 {
253 	struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
254 	struct dfl_feature *feature;
255 
256 	dfl_fpga_dev_for_each_feature(pdata, feature)
257 		if (feature->ops) {
258 			feature->ops->uinit(pdev, feature);
259 			feature->ops = NULL;
260 		}
261 }
262 EXPORT_SYMBOL_GPL(dfl_fpga_dev_feature_uinit);
263 
264 static int dfl_feature_instance_init(struct platform_device *pdev,
265 				     struct dfl_feature_platform_data *pdata,
266 				     struct dfl_feature *feature,
267 				     struct dfl_feature_driver *drv)
268 {
269 	int ret;
270 
271 	ret = drv->ops->init(pdev, feature);
272 	if (ret)
273 		return ret;
274 
275 	feature->ops = drv->ops;
276 
277 	return ret;
278 }
279 
280 /**
281  * dfl_fpga_dev_feature_init - init for sub features of dfl feature device
282  * @pdev: feature device.
283  * @feature_drvs: drvs for sub features.
284  *
285  * This function will match sub features with given feature drvs list and
286  * use matched drv to init related sub feature.
287  *
288  * Return: 0 on success, negative error code otherwise.
289  */
290 int dfl_fpga_dev_feature_init(struct platform_device *pdev,
291 			      struct dfl_feature_driver *feature_drvs)
292 {
293 	struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
294 	struct dfl_feature_driver *drv = feature_drvs;
295 	struct dfl_feature *feature;
296 	int ret;
297 
298 	while (drv->ops) {
299 		dfl_fpga_dev_for_each_feature(pdata, feature) {
300 			/* match feature and drv using id */
301 			if (feature->id == drv->id) {
302 				ret = dfl_feature_instance_init(pdev, pdata,
303 								feature, drv);
304 				if (ret)
305 					goto exit;
306 			}
307 		}
308 		drv++;
309 	}
310 
311 	return 0;
312 exit:
313 	dfl_fpga_dev_feature_uinit(pdev);
314 	return ret;
315 }
316 EXPORT_SYMBOL_GPL(dfl_fpga_dev_feature_init);
317 
318 static void dfl_chardev_uinit(void)
319 {
320 	int i;
321 
322 	for (i = 0; i < DFL_FPGA_DEVT_MAX; i++)
323 		if (MAJOR(dfl_chrdevs[i].devt)) {
324 			unregister_chrdev_region(dfl_chrdevs[i].devt,
325 						 MINORMASK + 1);
326 			dfl_chrdevs[i].devt = MKDEV(0, 0);
327 		}
328 }
329 
330 static int dfl_chardev_init(void)
331 {
332 	int i, ret;
333 
334 	for (i = 0; i < DFL_FPGA_DEVT_MAX; i++) {
335 		ret = alloc_chrdev_region(&dfl_chrdevs[i].devt, 0,
336 					  MINORMASK + 1, dfl_chrdevs[i].name);
337 		if (ret)
338 			goto exit;
339 	}
340 
341 	return 0;
342 
343 exit:
344 	dfl_chardev_uinit();
345 	return ret;
346 }
347 
348 static dev_t dfl_get_devt(enum dfl_fpga_devt_type type, int id)
349 {
350 	if (type >= DFL_FPGA_DEVT_MAX)
351 		return 0;
352 
353 	return MKDEV(MAJOR(dfl_chrdevs[type].devt), id);
354 }
355 
356 /**
357  * dfl_fpga_dev_ops_register - register cdev ops for feature dev
358  *
359  * @pdev: feature dev.
360  * @fops: file operations for feature dev's cdev.
361  * @owner: owning module/driver.
362  *
363  * Return: 0 on success, negative error code otherwise.
364  */
365 int dfl_fpga_dev_ops_register(struct platform_device *pdev,
366 			      const struct file_operations *fops,
367 			      struct module *owner)
368 {
369 	struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
370 
371 	cdev_init(&pdata->cdev, fops);
372 	pdata->cdev.owner = owner;
373 
374 	/*
375 	 * set parent to the feature device so that its refcount is
376 	 * decreased after the last refcount of cdev is gone, that
377 	 * makes sure the feature device is valid during device
378 	 * file's life-cycle.
379 	 */
380 	pdata->cdev.kobj.parent = &pdev->dev.kobj;
381 
382 	return cdev_add(&pdata->cdev, pdev->dev.devt, 1);
383 }
384 EXPORT_SYMBOL_GPL(dfl_fpga_dev_ops_register);
385 
386 /**
387  * dfl_fpga_dev_ops_unregister - unregister cdev ops for feature dev
388  * @pdev: feature dev.
389  */
390 void dfl_fpga_dev_ops_unregister(struct platform_device *pdev)
391 {
392 	struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
393 
394 	cdev_del(&pdata->cdev);
395 }
396 EXPORT_SYMBOL_GPL(dfl_fpga_dev_ops_unregister);
397 
398 /**
399  * struct build_feature_devs_info - info collected during feature dev build.
400  *
401  * @dev: device to enumerate.
402  * @cdev: the container device for all feature devices.
403  * @feature_dev: current feature device.
404  * @ioaddr: header register region address of feature device in enumeration.
405  * @sub_features: a sub features linked list for feature device in enumeration.
406  * @feature_num: number of sub features for feature device in enumeration.
407  */
408 struct build_feature_devs_info {
409 	struct device *dev;
410 	struct dfl_fpga_cdev *cdev;
411 	struct platform_device *feature_dev;
412 	void __iomem *ioaddr;
413 	struct list_head sub_features;
414 	int feature_num;
415 };
416 
417 /**
418  * struct dfl_feature_info - sub feature info collected during feature dev build
419  *
420  * @fid: id of this sub feature.
421  * @mmio_res: mmio resource of this sub feature.
422  * @ioaddr: mapped base address of mmio resource.
423  * @node: node in sub_features linked list.
424  */
425 struct dfl_feature_info {
426 	u64 fid;
427 	struct resource mmio_res;
428 	void __iomem *ioaddr;
429 	struct list_head node;
430 };
431 
432 static void dfl_fpga_cdev_add_port_dev(struct dfl_fpga_cdev *cdev,
433 				       struct platform_device *port)
434 {
435 	struct dfl_feature_platform_data *pdata = dev_get_platdata(&port->dev);
436 
437 	mutex_lock(&cdev->lock);
438 	list_add(&pdata->node, &cdev->port_dev_list);
439 	get_device(&pdata->dev->dev);
440 	mutex_unlock(&cdev->lock);
441 }
442 
443 /*
444  * register current feature device, it is called when we need to switch to
445  * another feature parsing or we have parsed all features on given device
446  * feature list.
447  */
448 static int build_info_commit_dev(struct build_feature_devs_info *binfo)
449 {
450 	struct platform_device *fdev = binfo->feature_dev;
451 	struct dfl_feature_platform_data *pdata;
452 	struct dfl_feature_info *finfo, *p;
453 	enum dfl_id_type type;
454 	int ret, index = 0;
455 
456 	if (!fdev)
457 		return 0;
458 
459 	type = feature_dev_id_type(fdev);
460 	if (WARN_ON_ONCE(type >= DFL_ID_MAX))
461 		return -EINVAL;
462 
463 	/*
464 	 * we do not need to care for the memory which is associated with
465 	 * the platform device. After calling platform_device_unregister(),
466 	 * it will be automatically freed by device's release() callback,
467 	 * platform_device_release().
468 	 */
469 	pdata = kzalloc(dfl_feature_platform_data_size(binfo->feature_num),
470 			GFP_KERNEL);
471 	if (!pdata)
472 		return -ENOMEM;
473 
474 	pdata->dev = fdev;
475 	pdata->num = binfo->feature_num;
476 	pdata->dfl_cdev = binfo->cdev;
477 	mutex_init(&pdata->lock);
478 	lockdep_set_class_and_name(&pdata->lock, &dfl_pdata_keys[type],
479 				   dfl_pdata_key_strings[type]);
480 
481 	/*
482 	 * the count should be initialized to 0 to make sure
483 	 *__fpga_port_enable() following __fpga_port_disable()
484 	 * works properly for port device.
485 	 * and it should always be 0 for fme device.
486 	 */
487 	WARN_ON(pdata->disable_count);
488 
489 	fdev->dev.platform_data = pdata;
490 
491 	/* each sub feature has one MMIO resource */
492 	fdev->num_resources = binfo->feature_num;
493 	fdev->resource = kcalloc(binfo->feature_num, sizeof(*fdev->resource),
494 				 GFP_KERNEL);
495 	if (!fdev->resource)
496 		return -ENOMEM;
497 
498 	/* fill features and resource information for feature dev */
499 	list_for_each_entry_safe(finfo, p, &binfo->sub_features, node) {
500 		struct dfl_feature *feature = &pdata->features[index];
501 
502 		/* save resource information for each feature */
503 		feature->id = finfo->fid;
504 		feature->resource_index = index;
505 		feature->ioaddr = finfo->ioaddr;
506 		fdev->resource[index++] = finfo->mmio_res;
507 
508 		list_del(&finfo->node);
509 		kfree(finfo);
510 	}
511 
512 	ret = platform_device_add(binfo->feature_dev);
513 	if (!ret) {
514 		if (type == PORT_ID)
515 			dfl_fpga_cdev_add_port_dev(binfo->cdev,
516 						   binfo->feature_dev);
517 		else
518 			binfo->cdev->fme_dev =
519 					get_device(&binfo->feature_dev->dev);
520 		/*
521 		 * reset it to avoid build_info_free() freeing their resource.
522 		 *
523 		 * The resource of successfully registered feature devices
524 		 * will be freed by platform_device_unregister(). See the
525 		 * comments in build_info_create_dev().
526 		 */
527 		binfo->feature_dev = NULL;
528 	}
529 
530 	return ret;
531 }
532 
533 static int
534 build_info_create_dev(struct build_feature_devs_info *binfo,
535 		      enum dfl_id_type type, void __iomem *ioaddr)
536 {
537 	struct platform_device *fdev;
538 	int ret;
539 
540 	if (type >= DFL_ID_MAX)
541 		return -EINVAL;
542 
543 	/* we will create a new device, commit current device first */
544 	ret = build_info_commit_dev(binfo);
545 	if (ret)
546 		return ret;
547 
548 	/*
549 	 * we use -ENODEV as the initialization indicator which indicates
550 	 * whether the id need to be reclaimed
551 	 */
552 	fdev = platform_device_alloc(dfl_devs[type].name, -ENODEV);
553 	if (!fdev)
554 		return -ENOMEM;
555 
556 	binfo->feature_dev = fdev;
557 	binfo->feature_num = 0;
558 	binfo->ioaddr = ioaddr;
559 	INIT_LIST_HEAD(&binfo->sub_features);
560 
561 	fdev->id = dfl_id_alloc(type, &fdev->dev);
562 	if (fdev->id < 0)
563 		return fdev->id;
564 
565 	fdev->dev.parent = &binfo->cdev->region->dev;
566 	fdev->dev.devt = dfl_get_devt(dfl_devs[type].devt_type, fdev->id);
567 
568 	return 0;
569 }
570 
571 static void build_info_free(struct build_feature_devs_info *binfo)
572 {
573 	struct dfl_feature_info *finfo, *p;
574 
575 	/*
576 	 * it is a valid id, free it. See comments in
577 	 * build_info_create_dev()
578 	 */
579 	if (binfo->feature_dev && binfo->feature_dev->id >= 0) {
580 		dfl_id_free(feature_dev_id_type(binfo->feature_dev),
581 			    binfo->feature_dev->id);
582 
583 		list_for_each_entry_safe(finfo, p, &binfo->sub_features, node) {
584 			list_del(&finfo->node);
585 			kfree(finfo);
586 		}
587 	}
588 
589 	platform_device_put(binfo->feature_dev);
590 
591 	devm_kfree(binfo->dev, binfo);
592 }
593 
594 static inline u32 feature_size(void __iomem *start)
595 {
596 	u64 v = readq(start + DFH);
597 	u32 ofst = FIELD_GET(DFH_NEXT_HDR_OFST, v);
598 	/* workaround for private features with invalid size, use 4K instead */
599 	return ofst ? ofst : 4096;
600 }
601 
602 static u64 feature_id(void __iomem *start)
603 {
604 	u64 v = readq(start + DFH);
605 	u16 id = FIELD_GET(DFH_ID, v);
606 	u8 type = FIELD_GET(DFH_TYPE, v);
607 
608 	if (type == DFH_TYPE_FIU)
609 		return FEATURE_ID_FIU_HEADER;
610 	else if (type == DFH_TYPE_PRIVATE)
611 		return id;
612 	else if (type == DFH_TYPE_AFU)
613 		return FEATURE_ID_AFU;
614 
615 	WARN_ON(1);
616 	return 0;
617 }
618 
619 /*
620  * when create sub feature instances, for private features, it doesn't need
621  * to provide resource size and feature id as they could be read from DFH
622  * register. For afu sub feature, its register region only contains user
623  * defined registers, so never trust any information from it, just use the
624  * resource size information provided by its parent FIU.
625  */
626 static int
627 create_feature_instance(struct build_feature_devs_info *binfo,
628 			struct dfl_fpga_enum_dfl *dfl, resource_size_t ofst,
629 			resource_size_t size, u64 fid)
630 {
631 	struct dfl_feature_info *finfo;
632 
633 	/* read feature size and id if inputs are invalid */
634 	size = size ? size : feature_size(dfl->ioaddr + ofst);
635 	fid = fid ? fid : feature_id(dfl->ioaddr + ofst);
636 
637 	if (dfl->len - ofst < size)
638 		return -EINVAL;
639 
640 	finfo = kzalloc(sizeof(*finfo), GFP_KERNEL);
641 	if (!finfo)
642 		return -ENOMEM;
643 
644 	finfo->fid = fid;
645 	finfo->mmio_res.start = dfl->start + ofst;
646 	finfo->mmio_res.end = finfo->mmio_res.start + size - 1;
647 	finfo->mmio_res.flags = IORESOURCE_MEM;
648 	finfo->ioaddr = dfl->ioaddr + ofst;
649 
650 	list_add_tail(&finfo->node, &binfo->sub_features);
651 	binfo->feature_num++;
652 
653 	return 0;
654 }
655 
656 static int parse_feature_port_afu(struct build_feature_devs_info *binfo,
657 				  struct dfl_fpga_enum_dfl *dfl,
658 				  resource_size_t ofst)
659 {
660 	u64 v = readq(binfo->ioaddr + PORT_HDR_CAP);
661 	u32 size = FIELD_GET(PORT_CAP_MMIO_SIZE, v) << 10;
662 
663 	WARN_ON(!size);
664 
665 	return create_feature_instance(binfo, dfl, ofst, size, FEATURE_ID_AFU);
666 }
667 
668 static int parse_feature_afu(struct build_feature_devs_info *binfo,
669 			     struct dfl_fpga_enum_dfl *dfl,
670 			     resource_size_t ofst)
671 {
672 	if (!binfo->feature_dev) {
673 		dev_err(binfo->dev, "this AFU does not belong to any FIU.\n");
674 		return -EINVAL;
675 	}
676 
677 	switch (feature_dev_id_type(binfo->feature_dev)) {
678 	case PORT_ID:
679 		return parse_feature_port_afu(binfo, dfl, ofst);
680 	default:
681 		dev_info(binfo->dev, "AFU belonging to FIU %s is not supported yet.\n",
682 			 binfo->feature_dev->name);
683 	}
684 
685 	return 0;
686 }
687 
688 static int parse_feature_fiu(struct build_feature_devs_info *binfo,
689 			     struct dfl_fpga_enum_dfl *dfl,
690 			     resource_size_t ofst)
691 {
692 	u32 id, offset;
693 	u64 v;
694 	int ret = 0;
695 
696 	v = readq(dfl->ioaddr + ofst + DFH);
697 	id = FIELD_GET(DFH_ID, v);
698 
699 	/* create platform device for dfl feature dev */
700 	ret = build_info_create_dev(binfo, dfh_id_to_type(id),
701 				    dfl->ioaddr + ofst);
702 	if (ret)
703 		return ret;
704 
705 	ret = create_feature_instance(binfo, dfl, ofst, 0, 0);
706 	if (ret)
707 		return ret;
708 	/*
709 	 * find and parse FIU's child AFU via its NEXT_AFU register.
710 	 * please note that only Port has valid NEXT_AFU pointer per spec.
711 	 */
712 	v = readq(dfl->ioaddr + ofst + NEXT_AFU);
713 
714 	offset = FIELD_GET(NEXT_AFU_NEXT_DFH_OFST, v);
715 	if (offset)
716 		return parse_feature_afu(binfo, dfl, ofst + offset);
717 
718 	dev_dbg(binfo->dev, "No AFUs detected on FIU %d\n", id);
719 
720 	return ret;
721 }
722 
723 static int parse_feature_private(struct build_feature_devs_info *binfo,
724 				 struct dfl_fpga_enum_dfl *dfl,
725 				 resource_size_t ofst)
726 {
727 	if (!binfo->feature_dev) {
728 		dev_err(binfo->dev, "the private feature %llx does not belong to any AFU.\n",
729 			(unsigned long long)feature_id(dfl->ioaddr + ofst));
730 		return -EINVAL;
731 	}
732 
733 	return create_feature_instance(binfo, dfl, ofst, 0, 0);
734 }
735 
736 /**
737  * parse_feature - parse a feature on given device feature list
738  *
739  * @binfo: build feature devices information.
740  * @dfl: device feature list to parse
741  * @ofst: offset to feature header on this device feature list
742  */
743 static int parse_feature(struct build_feature_devs_info *binfo,
744 			 struct dfl_fpga_enum_dfl *dfl, resource_size_t ofst)
745 {
746 	u64 v;
747 	u32 type;
748 
749 	v = readq(dfl->ioaddr + ofst + DFH);
750 	type = FIELD_GET(DFH_TYPE, v);
751 
752 	switch (type) {
753 	case DFH_TYPE_AFU:
754 		return parse_feature_afu(binfo, dfl, ofst);
755 	case DFH_TYPE_PRIVATE:
756 		return parse_feature_private(binfo, dfl, ofst);
757 	case DFH_TYPE_FIU:
758 		return parse_feature_fiu(binfo, dfl, ofst);
759 	default:
760 		dev_info(binfo->dev,
761 			 "Feature Type %x is not supported.\n", type);
762 	}
763 
764 	return 0;
765 }
766 
767 static int parse_feature_list(struct build_feature_devs_info *binfo,
768 			      struct dfl_fpga_enum_dfl *dfl)
769 {
770 	void __iomem *start = dfl->ioaddr;
771 	void __iomem *end = dfl->ioaddr + dfl->len;
772 	int ret = 0;
773 	u32 ofst = 0;
774 	u64 v;
775 
776 	/* walk through the device feature list via DFH's next DFH pointer. */
777 	for (; start < end; start += ofst) {
778 		if (end - start < DFH_SIZE) {
779 			dev_err(binfo->dev, "The region is too small to contain a feature.\n");
780 			return -EINVAL;
781 		}
782 
783 		ret = parse_feature(binfo, dfl, start - dfl->ioaddr);
784 		if (ret)
785 			return ret;
786 
787 		v = readq(start + DFH);
788 		ofst = FIELD_GET(DFH_NEXT_HDR_OFST, v);
789 
790 		/* stop parsing if EOL(End of List) is set or offset is 0 */
791 		if ((v & DFH_EOL) || !ofst)
792 			break;
793 	}
794 
795 	/* commit current feature device when reach the end of list */
796 	return build_info_commit_dev(binfo);
797 }
798 
799 struct dfl_fpga_enum_info *dfl_fpga_enum_info_alloc(struct device *dev)
800 {
801 	struct dfl_fpga_enum_info *info;
802 
803 	get_device(dev);
804 
805 	info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
806 	if (!info) {
807 		put_device(dev);
808 		return NULL;
809 	}
810 
811 	info->dev = dev;
812 	INIT_LIST_HEAD(&info->dfls);
813 
814 	return info;
815 }
816 EXPORT_SYMBOL_GPL(dfl_fpga_enum_info_alloc);
817 
818 void dfl_fpga_enum_info_free(struct dfl_fpga_enum_info *info)
819 {
820 	struct dfl_fpga_enum_dfl *tmp, *dfl;
821 	struct device *dev;
822 
823 	if (!info)
824 		return;
825 
826 	dev = info->dev;
827 
828 	/* remove all device feature lists in the list. */
829 	list_for_each_entry_safe(dfl, tmp, &info->dfls, node) {
830 		list_del(&dfl->node);
831 		devm_kfree(dev, dfl);
832 	}
833 
834 	devm_kfree(dev, info);
835 	put_device(dev);
836 }
837 EXPORT_SYMBOL_GPL(dfl_fpga_enum_info_free);
838 
839 /**
840  * dfl_fpga_enum_info_add_dfl - add info of a device feature list to enum info
841  *
842  * @info: ptr to dfl_fpga_enum_info
843  * @start: mmio resource address of the device feature list.
844  * @len: mmio resource length of the device feature list.
845  * @ioaddr: mapped mmio resource address of the device feature list.
846  *
847  * One FPGA device may have one or more Device Feature Lists (DFLs), use this
848  * function to add information of each DFL to common data structure for next
849  * step enumeration.
850  *
851  * Return: 0 on success, negative error code otherwise.
852  */
853 int dfl_fpga_enum_info_add_dfl(struct dfl_fpga_enum_info *info,
854 			       resource_size_t start, resource_size_t len,
855 			       void __iomem *ioaddr)
856 {
857 	struct dfl_fpga_enum_dfl *dfl;
858 
859 	dfl = devm_kzalloc(info->dev, sizeof(*dfl), GFP_KERNEL);
860 	if (!dfl)
861 		return -ENOMEM;
862 
863 	dfl->start = start;
864 	dfl->len = len;
865 	dfl->ioaddr = ioaddr;
866 
867 	list_add_tail(&dfl->node, &info->dfls);
868 
869 	return 0;
870 }
871 EXPORT_SYMBOL_GPL(dfl_fpga_enum_info_add_dfl);
872 
873 static int remove_feature_dev(struct device *dev, void *data)
874 {
875 	struct platform_device *pdev = to_platform_device(dev);
876 	enum dfl_id_type type = feature_dev_id_type(pdev);
877 	int id = pdev->id;
878 
879 	platform_device_unregister(pdev);
880 
881 	dfl_id_free(type, id);
882 
883 	return 0;
884 }
885 
886 static void remove_feature_devs(struct dfl_fpga_cdev *cdev)
887 {
888 	device_for_each_child(&cdev->region->dev, NULL, remove_feature_dev);
889 }
890 
891 /**
892  * dfl_fpga_feature_devs_enumerate - enumerate feature devices
893  * @info: information for enumeration.
894  *
895  * This function creates a container device (base FPGA region), enumerates
896  * feature devices based on the enumeration info and creates platform devices
897  * under the container device.
898  *
899  * Return: dfl_fpga_cdev struct on success, -errno on failure
900  */
901 struct dfl_fpga_cdev *
902 dfl_fpga_feature_devs_enumerate(struct dfl_fpga_enum_info *info)
903 {
904 	struct build_feature_devs_info *binfo;
905 	struct dfl_fpga_enum_dfl *dfl;
906 	struct dfl_fpga_cdev *cdev;
907 	int ret = 0;
908 
909 	if (!info->dev)
910 		return ERR_PTR(-ENODEV);
911 
912 	cdev = devm_kzalloc(info->dev, sizeof(*cdev), GFP_KERNEL);
913 	if (!cdev)
914 		return ERR_PTR(-ENOMEM);
915 
916 	cdev->region = devm_fpga_region_create(info->dev, NULL, NULL);
917 	if (!cdev->region) {
918 		ret = -ENOMEM;
919 		goto free_cdev_exit;
920 	}
921 
922 	cdev->parent = info->dev;
923 	mutex_init(&cdev->lock);
924 	INIT_LIST_HEAD(&cdev->port_dev_list);
925 
926 	ret = fpga_region_register(cdev->region);
927 	if (ret)
928 		goto free_cdev_exit;
929 
930 	/* create and init build info for enumeration */
931 	binfo = devm_kzalloc(info->dev, sizeof(*binfo), GFP_KERNEL);
932 	if (!binfo) {
933 		ret = -ENOMEM;
934 		goto unregister_region_exit;
935 	}
936 
937 	binfo->dev = info->dev;
938 	binfo->cdev = cdev;
939 
940 	/*
941 	 * start enumeration for all feature devices based on Device Feature
942 	 * Lists.
943 	 */
944 	list_for_each_entry(dfl, &info->dfls, node) {
945 		ret = parse_feature_list(binfo, dfl);
946 		if (ret) {
947 			remove_feature_devs(cdev);
948 			build_info_free(binfo);
949 			goto unregister_region_exit;
950 		}
951 	}
952 
953 	build_info_free(binfo);
954 
955 	return cdev;
956 
957 unregister_region_exit:
958 	fpga_region_unregister(cdev->region);
959 free_cdev_exit:
960 	devm_kfree(info->dev, cdev);
961 	return ERR_PTR(ret);
962 }
963 EXPORT_SYMBOL_GPL(dfl_fpga_feature_devs_enumerate);
964 
965 /**
966  * dfl_fpga_feature_devs_remove - remove all feature devices
967  * @cdev: fpga container device.
968  *
969  * Remove the container device and all feature devices under given container
970  * devices.
971  */
972 void dfl_fpga_feature_devs_remove(struct dfl_fpga_cdev *cdev)
973 {
974 	struct dfl_feature_platform_data *pdata, *ptmp;
975 
976 	remove_feature_devs(cdev);
977 
978 	mutex_lock(&cdev->lock);
979 	if (cdev->fme_dev) {
980 		/* the fme should be unregistered. */
981 		WARN_ON(device_is_registered(cdev->fme_dev));
982 		put_device(cdev->fme_dev);
983 	}
984 
985 	list_for_each_entry_safe(pdata, ptmp, &cdev->port_dev_list, node) {
986 		struct platform_device *port_dev = pdata->dev;
987 
988 		/* the port should be unregistered. */
989 		WARN_ON(device_is_registered(&port_dev->dev));
990 		list_del(&pdata->node);
991 		put_device(&port_dev->dev);
992 	}
993 	mutex_unlock(&cdev->lock);
994 
995 	fpga_region_unregister(cdev->region);
996 	devm_kfree(cdev->parent, cdev);
997 }
998 EXPORT_SYMBOL_GPL(dfl_fpga_feature_devs_remove);
999 
1000 /**
1001  * __dfl_fpga_cdev_find_port - find a port under given container device
1002  *
1003  * @cdev: container device
1004  * @data: data passed to match function
1005  * @match: match function used to find specific port from the port device list
1006  *
1007  * Find a port device under container device. This function needs to be
1008  * invoked with lock held.
1009  *
1010  * Return: pointer to port's platform device if successful, NULL otherwise.
1011  *
1012  * NOTE: you will need to drop the device reference with put_device() after use.
1013  */
1014 struct platform_device *
1015 __dfl_fpga_cdev_find_port(struct dfl_fpga_cdev *cdev, void *data,
1016 			  int (*match)(struct platform_device *, void *))
1017 {
1018 	struct dfl_feature_platform_data *pdata;
1019 	struct platform_device *port_dev;
1020 
1021 	list_for_each_entry(pdata, &cdev->port_dev_list, node) {
1022 		port_dev = pdata->dev;
1023 
1024 		if (match(port_dev, data) && get_device(&port_dev->dev))
1025 			return port_dev;
1026 	}
1027 
1028 	return NULL;
1029 }
1030 EXPORT_SYMBOL_GPL(__dfl_fpga_cdev_find_port);
1031 
1032 static int __init dfl_fpga_init(void)
1033 {
1034 	int ret;
1035 
1036 	dfl_ids_init();
1037 
1038 	ret = dfl_chardev_init();
1039 	if (ret)
1040 		dfl_ids_destroy();
1041 
1042 	return ret;
1043 }
1044 
1045 static void __exit dfl_fpga_exit(void)
1046 {
1047 	dfl_chardev_uinit();
1048 	dfl_ids_destroy();
1049 }
1050 
1051 module_init(dfl_fpga_init);
1052 module_exit(dfl_fpga_exit);
1053 
1054 MODULE_DESCRIPTION("FPGA Device Feature List (DFL) Support");
1055 MODULE_AUTHOR("Intel Corporation");
1056 MODULE_LICENSE("GPL v2");
1057