From 5b57d02a2f94bb04c6b36932412f7f3b1bb38518 Mon Sep 17 00:00:00 2001 From: Xiao Guangrong Date: Sat, 30 Jun 2018 08:53:16 +0800 Subject: fpga: dfl: add feature device infrastructure This patch abstracts the common operations of the sub features and defines the feature_ops data structure, including init, uinit and ioctl function pointers. And this patch adds some common helper functions for FME and AFU drivers, e.g. dfl_feature_dev_use_begin/end which are used to ensure exclusive usage of the feature device file. Signed-off-by: Tim Whisonant Signed-off-by: Enno Luebbers Signed-off-by: Shiva Rao Signed-off-by: Christopher Rauer Signed-off-by: Kang Luwei Signed-off-by: Zhang Yi Signed-off-by: Xiao Guangrong Signed-off-by: Wu Hao Acked-by: Alan Tull Signed-off-by: Greg Kroah-Hartman --- drivers/fpga/dfl.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 71 insertions(+) (limited to 'drivers/fpga/dfl.c') diff --git a/drivers/fpga/dfl.c b/drivers/fpga/dfl.c index 68e0b45617b2..e2c72c5dd9e6 100644 --- a/drivers/fpga/dfl.c +++ b/drivers/fpga/dfl.c @@ -136,6 +136,77 @@ static enum dfl_id_type dfh_id_to_type(u32 id) return DFL_ID_MAX; } +/** + * dfl_fpga_dev_feature_uinit - uinit for sub features of dfl feature device + * @pdev: feature device. + */ +void dfl_fpga_dev_feature_uinit(struct platform_device *pdev) +{ + struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev); + struct dfl_feature *feature; + + dfl_fpga_dev_for_each_feature(pdata, feature) + if (feature->ops) { + feature->ops->uinit(pdev, feature); + feature->ops = NULL; + } +} +EXPORT_SYMBOL_GPL(dfl_fpga_dev_feature_uinit); + +static int dfl_feature_instance_init(struct platform_device *pdev, + struct dfl_feature_platform_data *pdata, + struct dfl_feature *feature, + struct dfl_feature_driver *drv) +{ + int ret; + + ret = drv->ops->init(pdev, feature); + if (ret) + return ret; + + feature->ops = drv->ops; + + return ret; +} + +/** + * dfl_fpga_dev_feature_init - init for sub features of dfl feature device + * @pdev: feature device. + * @feature_drvs: drvs for sub features. + * + * This function will match sub features with given feature drvs list and + * use matched drv to init related sub feature. + * + * Return: 0 on success, negative error code otherwise. + */ +int dfl_fpga_dev_feature_init(struct platform_device *pdev, + struct dfl_feature_driver *feature_drvs) +{ + struct dfl_feature_platform_data *pdata = dev_get_platdata(&pdev->dev); + struct dfl_feature_driver *drv = feature_drvs; + struct dfl_feature *feature; + int ret; + + while (drv->ops) { + dfl_fpga_dev_for_each_feature(pdata, feature) { + /* match feature and drv using id */ + if (feature->id == drv->id) { + ret = dfl_feature_instance_init(pdev, pdata, + feature, drv); + if (ret) + goto exit; + } + } + drv++; + } + + return 0; +exit: + dfl_fpga_dev_feature_uinit(pdev); + return ret; +} +EXPORT_SYMBOL_GPL(dfl_fpga_dev_feature_init); + static void dfl_chardev_uinit(void) { int i; -- cgit v1.2.3