GNU Linux-libre 4.19.264-gnu1
[releases.git] / drivers / fpga / dfl.c
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);
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, MINORMASK,
336                                           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 = 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_region_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_region_exit:
960         fpga_region_free(cdev->region);
961 free_cdev_exit:
962         devm_kfree(info->dev, cdev);
963         return ERR_PTR(ret);
964 }
965 EXPORT_SYMBOL_GPL(dfl_fpga_feature_devs_enumerate);
966
967 /**
968  * dfl_fpga_feature_devs_remove - remove all feature devices
969  * @cdev: fpga container device.
970  *
971  * Remove the container device and all feature devices under given container
972  * devices.
973  */
974 void dfl_fpga_feature_devs_remove(struct dfl_fpga_cdev *cdev)
975 {
976         struct dfl_feature_platform_data *pdata, *ptmp;
977
978         remove_feature_devs(cdev);
979
980         mutex_lock(&cdev->lock);
981         if (cdev->fme_dev) {
982                 /* the fme should be unregistered. */
983                 WARN_ON(device_is_registered(cdev->fme_dev));
984                 put_device(cdev->fme_dev);
985         }
986
987         list_for_each_entry_safe(pdata, ptmp, &cdev->port_dev_list, node) {
988                 struct platform_device *port_dev = pdata->dev;
989
990                 /* the port should be unregistered. */
991                 WARN_ON(device_is_registered(&port_dev->dev));
992                 list_del(&pdata->node);
993                 put_device(&port_dev->dev);
994         }
995         mutex_unlock(&cdev->lock);
996
997         fpga_region_unregister(cdev->region);
998         devm_kfree(cdev->parent, cdev);
999 }
1000 EXPORT_SYMBOL_GPL(dfl_fpga_feature_devs_remove);
1001
1002 /**
1003  * __dfl_fpga_cdev_find_port - find a port under given container device
1004  *
1005  * @cdev: container device
1006  * @data: data passed to match function
1007  * @match: match function used to find specific port from the port device list
1008  *
1009  * Find a port device under container device. This function needs to be
1010  * invoked with lock held.
1011  *
1012  * Return: pointer to port's platform device if successful, NULL otherwise.
1013  *
1014  * NOTE: you will need to drop the device reference with put_device() after use.
1015  */
1016 struct platform_device *
1017 __dfl_fpga_cdev_find_port(struct dfl_fpga_cdev *cdev, void *data,
1018                           int (*match)(struct platform_device *, void *))
1019 {
1020         struct dfl_feature_platform_data *pdata;
1021         struct platform_device *port_dev;
1022
1023         list_for_each_entry(pdata, &cdev->port_dev_list, node) {
1024                 port_dev = pdata->dev;
1025
1026                 if (match(port_dev, data) && get_device(&port_dev->dev))
1027                         return port_dev;
1028         }
1029
1030         return NULL;
1031 }
1032 EXPORT_SYMBOL_GPL(__dfl_fpga_cdev_find_port);
1033
1034 static int __init dfl_fpga_init(void)
1035 {
1036         int ret;
1037
1038         dfl_ids_init();
1039
1040         ret = dfl_chardev_init();
1041         if (ret)
1042                 dfl_ids_destroy();
1043
1044         return ret;
1045 }
1046
1047 static void __exit dfl_fpga_exit(void)
1048 {
1049         dfl_chardev_uinit();
1050         dfl_ids_destroy();
1051 }
1052
1053 module_init(dfl_fpga_init);
1054 module_exit(dfl_fpga_exit);
1055
1056 MODULE_DESCRIPTION("FPGA Device Feature List (DFL) Support");
1057 MODULE_AUTHOR("Intel Corporation");
1058 MODULE_LICENSE("GPL v2");