summaryrefslogtreecommitdiffstats
path: root/drivers/fpga/dfl-afu-main.c
diff options
context:
space:
mode:
authorXu Yilun <yilun.xu@intel.com>2019-11-18 13:20:41 +0800
committerMoritz Fischer <mdf@kernel.org>2020-04-29 20:37:07 -0700
commitb6862193ca12e4bce6a18f31bb36eaa6d801b377 (patch)
tree6ecae23ae25f89edce3ec7b6d620e7027635f67c /drivers/fpga/dfl-afu-main.c
parent8f3d9f354286745c751374f5f1fcafee6b3f3136 (diff)
fpga: dfl: support multiple opens on feature device node.
Each DFL functional block, e.g. AFU (Accelerated Function Unit) and FME (FPGA Management Engine), could implement more than one function within its region, but current driver only allows one user application to access it by exclusive open on device node. So this is not convenient and flexible for userspace applications, as they have to combine lots of different functions into one single application. This patch removes the limitation here to allow multiple opens to each feature device node for AFU and FME from userspace applications. If user still needs exclusive access to these device node, O_EXCL flag must be issued together with open. Signed-off-by: Wu Hao <hao.wu@intel.com> Signed-off-by: Xu Yilun <yilun.xu@intel.com> Signed-off-by: Moritz Fischer <mdf@kernel.org>
Diffstat (limited to 'drivers/fpga/dfl-afu-main.c')
-rw-r--r--drivers/fpga/dfl-afu-main.c26
1 files changed, 15 insertions, 11 deletions
diff --git a/drivers/fpga/dfl-afu-main.c b/drivers/fpga/dfl-afu-main.c
index 65437b6a6842..435bde40f361 100644
--- a/drivers/fpga/dfl-afu-main.c
+++ b/drivers/fpga/dfl-afu-main.c
@@ -561,14 +561,16 @@ static int afu_open(struct inode *inode, struct file *filp)
if (WARN_ON(!pdata))
return -ENODEV;
- ret = dfl_feature_dev_use_begin(pdata);
- if (ret)
- return ret;
-
- dev_dbg(&fdev->dev, "Device File Open\n");
- filp->private_data = fdev;
+ mutex_lock(&pdata->lock);
+ ret = dfl_feature_dev_use_begin(pdata, filp->f_flags & O_EXCL);
+ if (!ret) {
+ dev_dbg(&fdev->dev, "Device File Opened %d Times\n",
+ dfl_feature_dev_use_count(pdata));
+ filp->private_data = fdev;
+ }
+ mutex_unlock(&pdata->lock);
- return 0;
+ return ret;
}
static int afu_release(struct inode *inode, struct file *filp)
@@ -581,12 +583,14 @@ static int afu_release(struct inode *inode, struct file *filp)
pdata = dev_get_platdata(&pdev->dev);
mutex_lock(&pdata->lock);
- __port_reset(pdev);
- afu_dma_region_destroy(pdata);
- mutex_unlock(&pdata->lock);
-
dfl_feature_dev_use_end(pdata);
+ if (!dfl_feature_dev_use_count(pdata)) {
+ __port_reset(pdev);
+ afu_dma_region_destroy(pdata);
+ }
+ mutex_unlock(&pdata->lock);
+
return 0;
}