]> asedeno.scripts.mit.edu Git - linux.git/blob - drivers/fpga/dfl-afu-main.c
fpga: dfl: afu: add userclock sysfs interfaces.
[linux.git] / drivers / fpga / dfl-afu-main.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Driver for FPGA Accelerated Function Unit (AFU)
4  *
5  * Copyright (C) 2017-2018 Intel Corporation, Inc.
6  *
7  * Authors:
8  *   Wu Hao <hao.wu@intel.com>
9  *   Xiao Guangrong <guangrong.xiao@linux.intel.com>
10  *   Joseph Grecco <joe.grecco@intel.com>
11  *   Enno Luebbers <enno.luebbers@intel.com>
12  *   Tim Whisonant <tim.whisonant@intel.com>
13  *   Ananda Ravuri <ananda.ravuri@intel.com>
14  *   Henry Mitchel <henry.mitchel@intel.com>
15  */
16
17 #include <linux/kernel.h>
18 #include <linux/module.h>
19 #include <linux/uaccess.h>
20 #include <linux/fpga-dfl.h>
21
22 #include "dfl-afu.h"
23
24 /**
25  * port_enable - enable a port
26  * @pdev: port platform device.
27  *
28  * Enable Port by clear the port soft reset bit, which is set by default.
29  * The AFU is unable to respond to any MMIO access while in reset.
30  * port_enable function should only be used after port_disable function.
31  */
32 static void port_enable(struct platform_device *pdev)
33 {
34         struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
35         void __iomem *base;
36         u64 v;
37
38         WARN_ON(!pdata->disable_count);
39
40         if (--pdata->disable_count != 0)
41                 return;
42
43         base = dfl_get_feature_ioaddr_by_id(&pdev->dev, PORT_FEATURE_ID_HEADER);
44
45         /* Clear port soft reset */
46         v = readq(base + PORT_HDR_CTRL);
47         v &= ~PORT_CTRL_SFTRST;
48         writeq(v, base + PORT_HDR_CTRL);
49 }
50
51 #define RST_POLL_INVL 10 /* us */
52 #define RST_POLL_TIMEOUT 1000 /* us */
53
54 /**
55  * port_disable - disable a port
56  * @pdev: port platform device.
57  *
58  * Disable Port by setting the port soft reset bit, it puts the port into
59  * reset.
60  */
61 static int port_disable(struct platform_device *pdev)
62 {
63         struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
64         void __iomem *base;
65         u64 v;
66
67         if (pdata->disable_count++ != 0)
68                 return 0;
69
70         base = dfl_get_feature_ioaddr_by_id(&pdev->dev, PORT_FEATURE_ID_HEADER);
71
72         /* Set port soft reset */
73         v = readq(base + PORT_HDR_CTRL);
74         v |= PORT_CTRL_SFTRST;
75         writeq(v, base + PORT_HDR_CTRL);
76
77         /*
78          * HW sets ack bit to 1 when all outstanding requests have been drained
79          * on this port and minimum soft reset pulse width has elapsed.
80          * Driver polls port_soft_reset_ack to determine if reset done by HW.
81          */
82         if (readq_poll_timeout(base + PORT_HDR_CTRL, v, v & PORT_CTRL_SFTRST,
83                                RST_POLL_INVL, RST_POLL_TIMEOUT)) {
84                 dev_err(&pdev->dev, "timeout, fail to reset device\n");
85                 return -ETIMEDOUT;
86         }
87
88         return 0;
89 }
90
91 /*
92  * This function resets the FPGA Port and its accelerator (AFU) by function
93  * __port_disable and __port_enable (set port soft reset bit and then clear
94  * it). Userspace can do Port reset at any time, e.g. during DMA or Partial
95  * Reconfiguration. But it should never cause any system level issue, only
96  * functional failure (e.g. DMA or PR operation failure) and be recoverable
97  * from the failure.
98  *
99  * Note: the accelerator (AFU) is not accessible when its port is in reset
100  * (disabled). Any attempts on MMIO access to AFU while in reset, will
101  * result errors reported via port error reporting sub feature (if present).
102  */
103 static int __port_reset(struct platform_device *pdev)
104 {
105         int ret;
106
107         ret = port_disable(pdev);
108         if (!ret)
109                 port_enable(pdev);
110
111         return ret;
112 }
113
114 static int port_reset(struct platform_device *pdev)
115 {
116         struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
117         int ret;
118
119         mutex_lock(&pdata->lock);
120         ret = __port_reset(pdev);
121         mutex_unlock(&pdata->lock);
122
123         return ret;
124 }
125
126 static int port_get_id(struct platform_device *pdev)
127 {
128         void __iomem *base;
129
130         base = dfl_get_feature_ioaddr_by_id(&pdev->dev, PORT_FEATURE_ID_HEADER);
131
132         return FIELD_GET(PORT_CAP_PORT_NUM, readq(base + PORT_HDR_CAP));
133 }
134
135 static ssize_t
136 id_show(struct device *dev, struct device_attribute *attr, char *buf)
137 {
138         int id = port_get_id(to_platform_device(dev));
139
140         return scnprintf(buf, PAGE_SIZE, "%d\n", id);
141 }
142 static DEVICE_ATTR_RO(id);
143
144 static ssize_t
145 ltr_show(struct device *dev, struct device_attribute *attr, char *buf)
146 {
147         struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
148         void __iomem *base;
149         u64 v;
150
151         base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER);
152
153         mutex_lock(&pdata->lock);
154         v = readq(base + PORT_HDR_CTRL);
155         mutex_unlock(&pdata->lock);
156
157         return sprintf(buf, "%x\n", (u8)FIELD_GET(PORT_CTRL_LATENCY, v));
158 }
159
160 static ssize_t
161 ltr_store(struct device *dev, struct device_attribute *attr,
162           const char *buf, size_t count)
163 {
164         struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
165         void __iomem *base;
166         bool ltr;
167         u64 v;
168
169         if (kstrtobool(buf, &ltr))
170                 return -EINVAL;
171
172         base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER);
173
174         mutex_lock(&pdata->lock);
175         v = readq(base + PORT_HDR_CTRL);
176         v &= ~PORT_CTRL_LATENCY;
177         v |= FIELD_PREP(PORT_CTRL_LATENCY, ltr ? 1 : 0);
178         writeq(v, base + PORT_HDR_CTRL);
179         mutex_unlock(&pdata->lock);
180
181         return count;
182 }
183 static DEVICE_ATTR_RW(ltr);
184
185 static ssize_t
186 ap1_event_show(struct device *dev, struct device_attribute *attr, char *buf)
187 {
188         struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
189         void __iomem *base;
190         u64 v;
191
192         base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER);
193
194         mutex_lock(&pdata->lock);
195         v = readq(base + PORT_HDR_STS);
196         mutex_unlock(&pdata->lock);
197
198         return sprintf(buf, "%x\n", (u8)FIELD_GET(PORT_STS_AP1_EVT, v));
199 }
200
201 static ssize_t
202 ap1_event_store(struct device *dev, struct device_attribute *attr,
203                 const char *buf, size_t count)
204 {
205         struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
206         void __iomem *base;
207         bool clear;
208
209         if (kstrtobool(buf, &clear) || !clear)
210                 return -EINVAL;
211
212         base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER);
213
214         mutex_lock(&pdata->lock);
215         writeq(PORT_STS_AP1_EVT, base + PORT_HDR_STS);
216         mutex_unlock(&pdata->lock);
217
218         return count;
219 }
220 static DEVICE_ATTR_RW(ap1_event);
221
222 static ssize_t
223 ap2_event_show(struct device *dev, struct device_attribute *attr,
224                char *buf)
225 {
226         struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
227         void __iomem *base;
228         u64 v;
229
230         base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER);
231
232         mutex_lock(&pdata->lock);
233         v = readq(base + PORT_HDR_STS);
234         mutex_unlock(&pdata->lock);
235
236         return sprintf(buf, "%x\n", (u8)FIELD_GET(PORT_STS_AP2_EVT, v));
237 }
238
239 static ssize_t
240 ap2_event_store(struct device *dev, struct device_attribute *attr,
241                 const char *buf, size_t count)
242 {
243         struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
244         void __iomem *base;
245         bool clear;
246
247         if (kstrtobool(buf, &clear) || !clear)
248                 return -EINVAL;
249
250         base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER);
251
252         mutex_lock(&pdata->lock);
253         writeq(PORT_STS_AP2_EVT, base + PORT_HDR_STS);
254         mutex_unlock(&pdata->lock);
255
256         return count;
257 }
258 static DEVICE_ATTR_RW(ap2_event);
259
260 static ssize_t
261 power_state_show(struct device *dev, struct device_attribute *attr, char *buf)
262 {
263         struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
264         void __iomem *base;
265         u64 v;
266
267         base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER);
268
269         mutex_lock(&pdata->lock);
270         v = readq(base + PORT_HDR_STS);
271         mutex_unlock(&pdata->lock);
272
273         return sprintf(buf, "0x%x\n", (u8)FIELD_GET(PORT_STS_PWR_STATE, v));
274 }
275 static DEVICE_ATTR_RO(power_state);
276
277 static ssize_t
278 userclk_freqcmd_store(struct device *dev, struct device_attribute *attr,
279                       const char *buf, size_t count)
280 {
281         struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
282         u64 userclk_freq_cmd;
283         void __iomem *base;
284
285         if (kstrtou64(buf, 0, &userclk_freq_cmd))
286                 return -EINVAL;
287
288         base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER);
289
290         mutex_lock(&pdata->lock);
291         writeq(userclk_freq_cmd, base + PORT_HDR_USRCLK_CMD0);
292         mutex_unlock(&pdata->lock);
293
294         return count;
295 }
296 static DEVICE_ATTR_WO(userclk_freqcmd);
297
298 static ssize_t
299 userclk_freqcntrcmd_store(struct device *dev, struct device_attribute *attr,
300                           const char *buf, size_t count)
301 {
302         struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
303         u64 userclk_freqcntr_cmd;
304         void __iomem *base;
305
306         if (kstrtou64(buf, 0, &userclk_freqcntr_cmd))
307                 return -EINVAL;
308
309         base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER);
310
311         mutex_lock(&pdata->lock);
312         writeq(userclk_freqcntr_cmd, base + PORT_HDR_USRCLK_CMD1);
313         mutex_unlock(&pdata->lock);
314
315         return count;
316 }
317 static DEVICE_ATTR_WO(userclk_freqcntrcmd);
318
319 static ssize_t
320 userclk_freqsts_show(struct device *dev, struct device_attribute *attr,
321                      char *buf)
322 {
323         struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
324         u64 userclk_freqsts;
325         void __iomem *base;
326
327         base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER);
328
329         mutex_lock(&pdata->lock);
330         userclk_freqsts = readq(base + PORT_HDR_USRCLK_STS0);
331         mutex_unlock(&pdata->lock);
332
333         return sprintf(buf, "0x%llx\n", (unsigned long long)userclk_freqsts);
334 }
335 static DEVICE_ATTR_RO(userclk_freqsts);
336
337 static ssize_t
338 userclk_freqcntrsts_show(struct device *dev, struct device_attribute *attr,
339                          char *buf)
340 {
341         struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
342         u64 userclk_freqcntrsts;
343         void __iomem *base;
344
345         base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER);
346
347         mutex_lock(&pdata->lock);
348         userclk_freqcntrsts = readq(base + PORT_HDR_USRCLK_STS1);
349         mutex_unlock(&pdata->lock);
350
351         return sprintf(buf, "0x%llx\n",
352                        (unsigned long long)userclk_freqcntrsts);
353 }
354 static DEVICE_ATTR_RO(userclk_freqcntrsts);
355
356 static struct attribute *port_hdr_attrs[] = {
357         &dev_attr_id.attr,
358         &dev_attr_ltr.attr,
359         &dev_attr_ap1_event.attr,
360         &dev_attr_ap2_event.attr,
361         &dev_attr_power_state.attr,
362         &dev_attr_userclk_freqcmd.attr,
363         &dev_attr_userclk_freqcntrcmd.attr,
364         &dev_attr_userclk_freqsts.attr,
365         &dev_attr_userclk_freqcntrsts.attr,
366         NULL,
367 };
368
369 static umode_t port_hdr_attrs_visible(struct kobject *kobj,
370                                       struct attribute *attr, int n)
371 {
372         struct device *dev = kobj_to_dev(kobj);
373         umode_t mode = attr->mode;
374         void __iomem *base;
375
376         base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_HEADER);
377
378         if (dfl_feature_revision(base) > 0) {
379                 /*
380                  * userclk sysfs interfaces are only visible in case port
381                  * revision is 0, as hardware with revision >0 doesn't
382                  * support this.
383                  */
384                 if (attr == &dev_attr_userclk_freqcmd.attr ||
385                     attr == &dev_attr_userclk_freqcntrcmd.attr ||
386                     attr == &dev_attr_userclk_freqsts.attr ||
387                     attr == &dev_attr_userclk_freqcntrsts.attr)
388                         mode = 0;
389         }
390
391         return mode;
392 }
393
394 static const struct attribute_group port_hdr_group = {
395         .attrs      = port_hdr_attrs,
396         .is_visible = port_hdr_attrs_visible,
397 };
398
399 static int port_hdr_init(struct platform_device *pdev,
400                          struct dfl_feature *feature)
401 {
402         port_reset(pdev);
403
404         return 0;
405 }
406
407 static long
408 port_hdr_ioctl(struct platform_device *pdev, struct dfl_feature *feature,
409                unsigned int cmd, unsigned long arg)
410 {
411         long ret;
412
413         switch (cmd) {
414         case DFL_FPGA_PORT_RESET:
415                 if (!arg)
416                         ret = port_reset(pdev);
417                 else
418                         ret = -EINVAL;
419                 break;
420         default:
421                 dev_dbg(&pdev->dev, "%x cmd not handled", cmd);
422                 ret = -ENODEV;
423         }
424
425         return ret;
426 }
427
428 static const struct dfl_feature_id port_hdr_id_table[] = {
429         {.id = PORT_FEATURE_ID_HEADER,},
430         {0,}
431 };
432
433 static const struct dfl_feature_ops port_hdr_ops = {
434         .init = port_hdr_init,
435         .ioctl = port_hdr_ioctl,
436 };
437
438 static ssize_t
439 afu_id_show(struct device *dev, struct device_attribute *attr, char *buf)
440 {
441         struct dfl_feature_platform_data *pdata = dev_get_platdata(dev);
442         void __iomem *base;
443         u64 guidl, guidh;
444
445         base = dfl_get_feature_ioaddr_by_id(dev, PORT_FEATURE_ID_AFU);
446
447         mutex_lock(&pdata->lock);
448         if (pdata->disable_count) {
449                 mutex_unlock(&pdata->lock);
450                 return -EBUSY;
451         }
452
453         guidl = readq(base + GUID_L);
454         guidh = readq(base + GUID_H);
455         mutex_unlock(&pdata->lock);
456
457         return scnprintf(buf, PAGE_SIZE, "%016llx%016llx\n", guidh, guidl);
458 }
459 static DEVICE_ATTR_RO(afu_id);
460
461 static struct attribute *port_afu_attrs[] = {
462         &dev_attr_afu_id.attr,
463         NULL
464 };
465
466 static umode_t port_afu_attrs_visible(struct kobject *kobj,
467                                       struct attribute *attr, int n)
468 {
469         struct device *dev = kobj_to_dev(kobj);
470
471         /*
472          * sysfs entries are visible only if related private feature is
473          * enumerated.
474          */
475         if (!dfl_get_feature_by_id(dev, PORT_FEATURE_ID_AFU))
476                 return 0;
477
478         return attr->mode;
479 }
480
481 static const struct attribute_group port_afu_group = {
482         .attrs      = port_afu_attrs,
483         .is_visible = port_afu_attrs_visible,
484 };
485
486 static int port_afu_init(struct platform_device *pdev,
487                          struct dfl_feature *feature)
488 {
489         struct resource *res = &pdev->resource[feature->resource_index];
490
491         return afu_mmio_region_add(dev_get_platdata(&pdev->dev),
492                                    DFL_PORT_REGION_INDEX_AFU,
493                                    resource_size(res), res->start,
494                                    DFL_PORT_REGION_MMAP | DFL_PORT_REGION_READ |
495                                    DFL_PORT_REGION_WRITE);
496 }
497
498 static const struct dfl_feature_id port_afu_id_table[] = {
499         {.id = PORT_FEATURE_ID_AFU,},
500         {0,}
501 };
502
503 static const struct dfl_feature_ops port_afu_ops = {
504         .init = port_afu_init,
505 };
506
507 static struct dfl_feature_driver port_feature_drvs[] = {
508         {
509                 .id_table = port_hdr_id_table,
510                 .ops = &port_hdr_ops,
511         },
512         {
513                 .id_table = port_afu_id_table,
514                 .ops = &port_afu_ops,
515         },
516         {
517                 .ops = NULL,
518         }
519 };
520
521 static int afu_open(struct inode *inode, struct file *filp)
522 {
523         struct platform_device *fdev = dfl_fpga_inode_to_feature_dev(inode);
524         struct dfl_feature_platform_data *pdata;
525         int ret;
526
527         pdata = dev_get_platdata(&fdev->dev);
528         if (WARN_ON(!pdata))
529                 return -ENODEV;
530
531         ret = dfl_feature_dev_use_begin(pdata);
532         if (ret)
533                 return ret;
534
535         dev_dbg(&fdev->dev, "Device File Open\n");
536         filp->private_data = fdev;
537
538         return 0;
539 }
540
541 static int afu_release(struct inode *inode, struct file *filp)
542 {
543         struct platform_device *pdev = filp->private_data;
544         struct dfl_feature_platform_data *pdata;
545
546         dev_dbg(&pdev->dev, "Device File Release\n");
547
548         pdata = dev_get_platdata(&pdev->dev);
549
550         mutex_lock(&pdata->lock);
551         __port_reset(pdev);
552         afu_dma_region_destroy(pdata);
553         mutex_unlock(&pdata->lock);
554
555         dfl_feature_dev_use_end(pdata);
556
557         return 0;
558 }
559
560 static long afu_ioctl_check_extension(struct dfl_feature_platform_data *pdata,
561                                       unsigned long arg)
562 {
563         /* No extension support for now */
564         return 0;
565 }
566
567 static long
568 afu_ioctl_get_info(struct dfl_feature_platform_data *pdata, void __user *arg)
569 {
570         struct dfl_fpga_port_info info;
571         struct dfl_afu *afu;
572         unsigned long minsz;
573
574         minsz = offsetofend(struct dfl_fpga_port_info, num_umsgs);
575
576         if (copy_from_user(&info, arg, minsz))
577                 return -EFAULT;
578
579         if (info.argsz < minsz)
580                 return -EINVAL;
581
582         mutex_lock(&pdata->lock);
583         afu = dfl_fpga_pdata_get_private(pdata);
584         info.flags = 0;
585         info.num_regions = afu->num_regions;
586         info.num_umsgs = afu->num_umsgs;
587         mutex_unlock(&pdata->lock);
588
589         if (copy_to_user(arg, &info, sizeof(info)))
590                 return -EFAULT;
591
592         return 0;
593 }
594
595 static long afu_ioctl_get_region_info(struct dfl_feature_platform_data *pdata,
596                                       void __user *arg)
597 {
598         struct dfl_fpga_port_region_info rinfo;
599         struct dfl_afu_mmio_region region;
600         unsigned long minsz;
601         long ret;
602
603         minsz = offsetofend(struct dfl_fpga_port_region_info, offset);
604
605         if (copy_from_user(&rinfo, arg, minsz))
606                 return -EFAULT;
607
608         if (rinfo.argsz < minsz || rinfo.padding)
609                 return -EINVAL;
610
611         ret = afu_mmio_region_get_by_index(pdata, rinfo.index, &region);
612         if (ret)
613                 return ret;
614
615         rinfo.flags = region.flags;
616         rinfo.size = region.size;
617         rinfo.offset = region.offset;
618
619         if (copy_to_user(arg, &rinfo, sizeof(rinfo)))
620                 return -EFAULT;
621
622         return 0;
623 }
624
625 static long
626 afu_ioctl_dma_map(struct dfl_feature_platform_data *pdata, void __user *arg)
627 {
628         struct dfl_fpga_port_dma_map map;
629         unsigned long minsz;
630         long ret;
631
632         minsz = offsetofend(struct dfl_fpga_port_dma_map, iova);
633
634         if (copy_from_user(&map, arg, minsz))
635                 return -EFAULT;
636
637         if (map.argsz < minsz || map.flags)
638                 return -EINVAL;
639
640         ret = afu_dma_map_region(pdata, map.user_addr, map.length, &map.iova);
641         if (ret)
642                 return ret;
643
644         if (copy_to_user(arg, &map, sizeof(map))) {
645                 afu_dma_unmap_region(pdata, map.iova);
646                 return -EFAULT;
647         }
648
649         dev_dbg(&pdata->dev->dev, "dma map: ua=%llx, len=%llx, iova=%llx\n",
650                 (unsigned long long)map.user_addr,
651                 (unsigned long long)map.length,
652                 (unsigned long long)map.iova);
653
654         return 0;
655 }
656
657 static long
658 afu_ioctl_dma_unmap(struct dfl_feature_platform_data *pdata, void __user *arg)
659 {
660         struct dfl_fpga_port_dma_unmap unmap;
661         unsigned long minsz;
662
663         minsz = offsetofend(struct dfl_fpga_port_dma_unmap, iova);
664
665         if (copy_from_user(&unmap, arg, minsz))
666                 return -EFAULT;
667
668         if (unmap.argsz < minsz || unmap.flags)
669                 return -EINVAL;
670
671         return afu_dma_unmap_region(pdata, unmap.iova);
672 }
673
674 static long afu_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
675 {
676         struct platform_device *pdev = filp->private_data;
677         struct dfl_feature_platform_data *pdata;
678         struct dfl_feature *f;
679         long ret;
680
681         dev_dbg(&pdev->dev, "%s cmd 0x%x\n", __func__, cmd);
682
683         pdata = dev_get_platdata(&pdev->dev);
684
685         switch (cmd) {
686         case DFL_FPGA_GET_API_VERSION:
687                 return DFL_FPGA_API_VERSION;
688         case DFL_FPGA_CHECK_EXTENSION:
689                 return afu_ioctl_check_extension(pdata, arg);
690         case DFL_FPGA_PORT_GET_INFO:
691                 return afu_ioctl_get_info(pdata, (void __user *)arg);
692         case DFL_FPGA_PORT_GET_REGION_INFO:
693                 return afu_ioctl_get_region_info(pdata, (void __user *)arg);
694         case DFL_FPGA_PORT_DMA_MAP:
695                 return afu_ioctl_dma_map(pdata, (void __user *)arg);
696         case DFL_FPGA_PORT_DMA_UNMAP:
697                 return afu_ioctl_dma_unmap(pdata, (void __user *)arg);
698         default:
699                 /*
700                  * Let sub-feature's ioctl function to handle the cmd
701                  * Sub-feature's ioctl returns -ENODEV when cmd is not
702                  * handled in this sub feature, and returns 0 and other
703                  * error code if cmd is handled.
704                  */
705                 dfl_fpga_dev_for_each_feature(pdata, f)
706                         if (f->ops && f->ops->ioctl) {
707                                 ret = f->ops->ioctl(pdev, f, cmd, arg);
708                                 if (ret != -ENODEV)
709                                         return ret;
710                         }
711         }
712
713         return -EINVAL;
714 }
715
716 static int afu_mmap(struct file *filp, struct vm_area_struct *vma)
717 {
718         struct platform_device *pdev = filp->private_data;
719         struct dfl_feature_platform_data *pdata;
720         u64 size = vma->vm_end - vma->vm_start;
721         struct dfl_afu_mmio_region region;
722         u64 offset;
723         int ret;
724
725         if (!(vma->vm_flags & VM_SHARED))
726                 return -EINVAL;
727
728         pdata = dev_get_platdata(&pdev->dev);
729
730         offset = vma->vm_pgoff << PAGE_SHIFT;
731         ret = afu_mmio_region_get_by_offset(pdata, offset, size, &region);
732         if (ret)
733                 return ret;
734
735         if (!(region.flags & DFL_PORT_REGION_MMAP))
736                 return -EINVAL;
737
738         if ((vma->vm_flags & VM_READ) && !(region.flags & DFL_PORT_REGION_READ))
739                 return -EPERM;
740
741         if ((vma->vm_flags & VM_WRITE) &&
742             !(region.flags & DFL_PORT_REGION_WRITE))
743                 return -EPERM;
744
745         vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
746
747         return remap_pfn_range(vma, vma->vm_start,
748                         (region.phys + (offset - region.offset)) >> PAGE_SHIFT,
749                         size, vma->vm_page_prot);
750 }
751
752 static const struct file_operations afu_fops = {
753         .owner = THIS_MODULE,
754         .open = afu_open,
755         .release = afu_release,
756         .unlocked_ioctl = afu_ioctl,
757         .mmap = afu_mmap,
758 };
759
760 static int afu_dev_init(struct platform_device *pdev)
761 {
762         struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
763         struct dfl_afu *afu;
764
765         afu = devm_kzalloc(&pdev->dev, sizeof(*afu), GFP_KERNEL);
766         if (!afu)
767                 return -ENOMEM;
768
769         afu->pdata = pdata;
770
771         mutex_lock(&pdata->lock);
772         dfl_fpga_pdata_set_private(pdata, afu);
773         afu_mmio_region_init(pdata);
774         afu_dma_region_init(pdata);
775         mutex_unlock(&pdata->lock);
776
777         return 0;
778 }
779
780 static int afu_dev_destroy(struct platform_device *pdev)
781 {
782         struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
783         struct dfl_afu *afu;
784
785         mutex_lock(&pdata->lock);
786         afu = dfl_fpga_pdata_get_private(pdata);
787         afu_mmio_region_destroy(pdata);
788         afu_dma_region_destroy(pdata);
789         dfl_fpga_pdata_set_private(pdata, NULL);
790         mutex_unlock(&pdata->lock);
791
792         return 0;
793 }
794
795 static int port_enable_set(struct platform_device *pdev, bool enable)
796 {
797         struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
798         int ret = 0;
799
800         mutex_lock(&pdata->lock);
801         if (enable)
802                 port_enable(pdev);
803         else
804                 ret = port_disable(pdev);
805         mutex_unlock(&pdata->lock);
806
807         return ret;
808 }
809
810 static struct dfl_fpga_port_ops afu_port_ops = {
811         .name = DFL_FPGA_FEATURE_DEV_PORT,
812         .owner = THIS_MODULE,
813         .get_id = port_get_id,
814         .enable_set = port_enable_set,
815 };
816
817 static int afu_probe(struct platform_device *pdev)
818 {
819         int ret;
820
821         dev_dbg(&pdev->dev, "%s\n", __func__);
822
823         ret = afu_dev_init(pdev);
824         if (ret)
825                 goto exit;
826
827         ret = dfl_fpga_dev_feature_init(pdev, port_feature_drvs);
828         if (ret)
829                 goto dev_destroy;
830
831         ret = dfl_fpga_dev_ops_register(pdev, &afu_fops, THIS_MODULE);
832         if (ret) {
833                 dfl_fpga_dev_feature_uinit(pdev);
834                 goto dev_destroy;
835         }
836
837         return 0;
838
839 dev_destroy:
840         afu_dev_destroy(pdev);
841 exit:
842         return ret;
843 }
844
845 static int afu_remove(struct platform_device *pdev)
846 {
847         dev_dbg(&pdev->dev, "%s\n", __func__);
848
849         dfl_fpga_dev_ops_unregister(pdev);
850         dfl_fpga_dev_feature_uinit(pdev);
851         afu_dev_destroy(pdev);
852
853         return 0;
854 }
855
856 static const struct attribute_group *afu_dev_groups[] = {
857         &port_hdr_group,
858         &port_afu_group,
859         NULL
860 };
861
862 static struct platform_driver afu_driver = {
863         .driver = {
864                 .name       = DFL_FPGA_FEATURE_DEV_PORT,
865                 .dev_groups = afu_dev_groups,
866         },
867         .probe   = afu_probe,
868         .remove  = afu_remove,
869 };
870
871 static int __init afu_init(void)
872 {
873         int ret;
874
875         dfl_fpga_port_ops_add(&afu_port_ops);
876
877         ret = platform_driver_register(&afu_driver);
878         if (ret)
879                 dfl_fpga_port_ops_del(&afu_port_ops);
880
881         return ret;
882 }
883
884 static void __exit afu_exit(void)
885 {
886         platform_driver_unregister(&afu_driver);
887
888         dfl_fpga_port_ops_del(&afu_port_ops);
889 }
890
891 module_init(afu_init);
892 module_exit(afu_exit);
893
894 MODULE_DESCRIPTION("FPGA Accelerated Function Unit driver");
895 MODULE_AUTHOR("Intel Corporation");
896 MODULE_LICENSE("GPL v2");
897 MODULE_ALIAS("platform:dfl-port");