diff options
author | Xu Yilun <yilun.xu@intel.com> | 2019-11-18 08:20:41 +0300 |
---|---|---|
committer | Moritz Fischer <mdf@kernel.org> | 2020-04-30 06:37:07 +0300 |
commit | b6862193ca12e4bce6a18f31bb36eaa6d801b377 (patch) | |
tree | 6ecae23ae25f89edce3ec7b6d620e7027635f67c /drivers/fpga/dfl.c | |
parent | 8f3d9f354286745c751374f5f1fcafee6b3f3136 (diff) | |
download | linux-b6862193ca12e4bce6a18f31bb36eaa6d801b377.tar.xz |
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.c')
-rw-r--r-- | drivers/fpga/dfl.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/drivers/fpga/dfl.c b/drivers/fpga/dfl.c index 96a2b8274a33..990994874bf1 100644 --- a/drivers/fpga/dfl.c +++ b/drivers/fpga/dfl.c @@ -1079,6 +1079,7 @@ static int __init dfl_fpga_init(void) */ int dfl_fpga_cdev_release_port(struct dfl_fpga_cdev *cdev, int port_id) { + struct dfl_feature_platform_data *pdata; struct platform_device *port_pdev; int ret = -ENODEV; @@ -1093,7 +1094,11 @@ int dfl_fpga_cdev_release_port(struct dfl_fpga_cdev *cdev, int port_id) goto put_dev_exit; } - ret = dfl_feature_dev_use_begin(dev_get_platdata(&port_pdev->dev)); + pdata = dev_get_platdata(&port_pdev->dev); + + mutex_lock(&pdata->lock); + ret = dfl_feature_dev_use_begin(pdata, true); + mutex_unlock(&pdata->lock); if (ret) goto put_dev_exit; @@ -1120,6 +1125,7 @@ EXPORT_SYMBOL_GPL(dfl_fpga_cdev_release_port); */ int dfl_fpga_cdev_assign_port(struct dfl_fpga_cdev *cdev, int port_id) { + struct dfl_feature_platform_data *pdata; struct platform_device *port_pdev; int ret = -ENODEV; @@ -1138,7 +1144,12 @@ int dfl_fpga_cdev_assign_port(struct dfl_fpga_cdev *cdev, int port_id) if (ret) goto put_dev_exit; - dfl_feature_dev_use_end(dev_get_platdata(&port_pdev->dev)); + pdata = dev_get_platdata(&port_pdev->dev); + + mutex_lock(&pdata->lock); + dfl_feature_dev_use_end(pdata); + mutex_unlock(&pdata->lock); + cdev->released_port_num--; put_dev_exit: put_device(&port_pdev->dev); |