aboutsummaryrefslogtreecommitdiff
path: root/drivers/fpga/dfl-fme-main.c
diff options
context:
space:
mode:
authorKang Luwei <luwei.kang@intel.com>2018-06-30 08:53:24 +0800
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-07-15 13:55:46 +0200
commit29de76240e861d52b75405166337e94184f1875d (patch)
tree6332ab2f0ff81745d13f4fc818e6d4c49fc07af0 /drivers/fpga/dfl-fme-main.c
parent620e1902f6fe57ddacdabd9e33fadbd290be9652 (diff)
fpga: dfl: fme: add partial reconfiguration sub feature support
Partial Reconfiguration (PR) is the most important function for FME. It allows reconfiguration for given Port/Accelerated Function Unit (AFU). It creates platform devices for fpga-mgr, fpga-regions and fpga-bridges, and invokes fpga-region's interface (fpga_region_program_fpga) for PR operation once PR request received via ioctl. Below user space interface is exposed by this sub feature. Ioctl interface: * DFL_FPGA_FME_PORT_PR Do partial reconfiguration per information from userspace, including target port(AFU), buffer size and address info. It returns error code to userspace if failed. For detailed PR error information, user needs to read fpga-mgr's status sysfs interface. Signed-off-by: Tim Whisonant <tim.whisonant@intel.com> Signed-off-by: Enno Luebbers <enno.luebbers@intel.com> Signed-off-by: Shiva Rao <shiva.rao@intel.com> Signed-off-by: Christopher Rauer <christopher.rauer@intel.com> Signed-off-by: Kang Luwei <luwei.kang@intel.com> Signed-off-by: Xiao Guangrong <guangrong.xiao@linux.intel.com> Signed-off-by: Wu Hao <hao.wu@intel.com> Acked-by: Alan Tull <atull@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/fpga/dfl-fme-main.c')
-rw-r--r--drivers/fpga/dfl-fme-main.c43
1 files changed, 42 insertions, 1 deletions
diff --git a/drivers/fpga/dfl-fme-main.c b/drivers/fpga/dfl-fme-main.c
index c83ff88e3bbb..086ad2420ade 100644
--- a/drivers/fpga/dfl-fme-main.c
+++ b/drivers/fpga/dfl-fme-main.c
@@ -19,6 +19,7 @@
#include <linux/fpga-dfl.h>
#include "dfl.h"
+#include "dfl-fme.h"
static ssize_t ports_num_show(struct device *dev,
struct device_attribute *attr, char *buf)
@@ -113,6 +114,10 @@ static struct dfl_feature_driver fme_feature_drvs[] = {
.ops = &fme_hdr_ops,
},
{
+ .id = FME_FEATURE_ID_PR_MGMT,
+ .ops = &pr_mgmt_ops,
+ },
+ {
.ops = NULL,
},
};
@@ -187,6 +192,35 @@ static long fme_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
return -EINVAL;
}
+static int fme_dev_init(struct platform_device *pdev)
+{
+ struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
+ struct dfl_fme *fme;
+
+ fme = devm_kzalloc(&pdev->dev, sizeof(*fme), GFP_KERNEL);
+ if (!fme)
+ return -ENOMEM;
+
+ fme->pdata = pdata;
+
+ mutex_lock(&pdata->lock);
+ dfl_fpga_pdata_set_private(pdata, fme);
+ mutex_unlock(&pdata->lock);
+
+ return 0;
+}
+
+static void fme_dev_destroy(struct platform_device *pdev)
+{
+ struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev);
+ struct dfl_fme *fme;
+
+ mutex_lock(&pdata->lock);
+ fme = dfl_fpga_pdata_get_private(pdata);
+ dfl_fpga_pdata_set_private(pdata, NULL);
+ mutex_unlock(&pdata->lock);
+}
+
static const struct file_operations fme_fops = {
.owner = THIS_MODULE,
.open = fme_open,
@@ -198,10 +232,14 @@ static int fme_probe(struct platform_device *pdev)
{
int ret;
- ret = dfl_fpga_dev_feature_init(pdev, fme_feature_drvs);
+ ret = fme_dev_init(pdev);
if (ret)
goto exit;
+ ret = dfl_fpga_dev_feature_init(pdev, fme_feature_drvs);
+ if (ret)
+ goto dev_destroy;
+
ret = dfl_fpga_dev_ops_register(pdev, &fme_fops, THIS_MODULE);
if (ret)
goto feature_uinit;
@@ -210,6 +248,8 @@ static int fme_probe(struct platform_device *pdev)
feature_uinit:
dfl_fpga_dev_feature_uinit(pdev);
+dev_destroy:
+ fme_dev_destroy(pdev);
exit:
return ret;
}
@@ -218,6 +258,7 @@ static int fme_remove(struct platform_device *pdev)
{
dfl_fpga_dev_ops_unregister(pdev);
dfl_fpga_dev_feature_uinit(pdev);
+ fme_dev_destroy(pdev);
return 0;
}