@@ -47,7 +47,6 @@ API to add a new FPGA region
* struct fpga_region — The FPGA region struct
* struct fpga_region_ops — Low level FPGA region driver ops
-* devm_fpga_region_create() — Allocate and init a region struct
* fpga_region_register() — Register an FPGA region
* fpga_region_unregister() — Unregister an FPGA region
@@ -79,9 +78,6 @@ following APIs to handle building or tearing down that list.
.. kernel-doc:: include/linux/fpga/fpga-region.h
:functions: fpga_region_ops
-.. kernel-doc:: drivers/fpga/fpga-region.c
- :functions: devm_fpga_region_create
-
.. kernel-doc:: drivers/fpga/fpga-region.c
:functions: fpga_region_register
@@ -57,19 +57,14 @@ static int fme_region_probe(struct platform_device *pdev)
if (IS_ERR(mgr))
return -EPROBE_DEFER;
- region = devm_fpga_region_create(dev, mgr, &fme_fpga_region_ops);
+ region = fpga_region_register(dev, mgr, &fme_fpga_region_ops, pdata);
if (!region) {
ret = -ENOMEM;
goto eprobe_mgr_put;
}
- region->priv = pdata;
platform_set_drvdata(pdev, region);
- ret = fpga_region_register(region);
- if (ret)
- goto eprobe_mgr_put;
-
dev_dbg(dev, "DFL FME FPGA Region probed\n");
return 0;
@@ -1400,19 +1400,15 @@ dfl_fpga_feature_devs_enumerate(struct dfl_fpga_enum_info *info)
if (!cdev)
return ERR_PTR(-ENOMEM);
- cdev->region = devm_fpga_region_create(info->dev, NULL, NULL);
- if (!cdev->region) {
- ret = -ENOMEM;
- goto free_cdev_exit;
- }
-
cdev->parent = info->dev;
mutex_init(&cdev->lock);
INIT_LIST_HEAD(&cdev->port_dev_list);
- ret = fpga_region_register(cdev->region);
- if (ret)
+ cdev->region = fpga_region_register(info->dev, NULL, NULL, NULL);
+ if (IS_ERR(cdev->region)) {
+ ret = PTR_ERR(cdev->region);
goto free_cdev_exit;
+ }
/* create and init build info for enumeration */
binfo = devm_kzalloc(info->dev, sizeof(*binfo), GFP_KERNEL);
@@ -184,39 +184,44 @@ static struct attribute *fpga_region_attrs[] = {
ATTRIBUTE_GROUPS(fpga_region);
/**
- * fpga_region_create - alloc and init a struct fpga_region
+ * fpga_region_register - create and register an FPGA Region device
* @parent: device parent
* @mgr: manager that programs this region
- * @rops: optional pointer to struct for fpga region ops
+ * @rops: optional pointer to struct for fpga region ops
+ * @priv: fpga region private data
*
* The caller of this function is responsible for freeing the resulting region
- * struct with fpga_region_free(). Using devm_fpga_region_create() instead is
+ * struct with fpga_region_unregiser(). Using devm_fpga_region_create() instead is
* recommended.
*
- * Return: struct fpga_region or NULL
+ * Return: struct fpga_region or ERR_PTR()
*/
-struct fpga_region
-*fpga_region_create(struct device *parent,
- struct fpga_manager *mgr,
- const struct fpga_region_ops *rops)
+struct fpga_region *
+fpga_region_register(struct device *parent,
+ struct fpga_manager *mgr,
+ const struct fpga_region_ops *rops,
+ void *priv)
{
struct fpga_region *region;
int id, ret = 0;
region = kzalloc(sizeof(*region), GFP_KERNEL);
if (!region)
- return NULL;
+ return ERR_PTR(-ENOMEM);
id = ida_simple_get(&fpga_region_ida, 0, 0, GFP_KERNEL);
- if (id < 0)
+ if (id < 0) {
+ ret = id;
goto err_free;
+ }
region->mgr = mgr;
region->rops = rops;
+ region->priv = priv;
+
mutex_init(®ion->mutex);
INIT_LIST_HEAD(®ion->bridge_list);
- device_initialize(®ion->dev);
region->dev.class = fpga_region_class;
region->dev.parent = parent;
region->dev.of_node = parent->of_node;
@@ -226,6 +231,12 @@ struct fpga_region
if (ret)
goto err_remove;
+ ret = device_register(®ion->dev);
+ if (ret) {
+ put_device(®ion->dev);
+ return ERR_PTR(ret);
+ }
+
return region;
err_remove:
@@ -233,76 +244,7 @@ struct fpga_region
err_free:
kfree(region);
- return NULL;
-}
-EXPORT_SYMBOL_GPL(fpga_region_create);
-
-/**
- * fpga_region_free - free an FPGA region created by fpga_region_create()
- * @region: FPGA region
- */
-void fpga_region_free(struct fpga_region *region)
-{
- ida_simple_remove(&fpga_region_ida, region->dev.id);
- kfree(region);
-}
-EXPORT_SYMBOL_GPL(fpga_region_free);
-
-static void devm_fpga_region_release(struct device *dev, void *res)
-{
- struct fpga_region *region = *(struct fpga_region **)res;
-
- fpga_region_free(region);
-}
-
-/**
- * devm_fpga_region_create - create and initialize a managed FPGA region struct
- * @parent: device parent
- * @mgr: manager that programs this region
- * @rops: optional pointer to struct for fpga region ops
- *
- * This function is intended for use in an FPGA region driver's probe function.
- * After the region driver creates the region struct with
- * devm_fpga_region_create(), it should register it with fpga_region_register().
- * The region driver's remove function should call fpga_region_unregister().
- * The region struct allocated with this function will be freed automatically on
- * driver detach. This includes the case of a probe function returning error
- * before calling fpga_region_register(), the struct will still get cleaned up.
- *
- * Return: struct fpga_region or NULL
- */
-struct fpga_region
-*devm_fpga_region_create(struct device *parent,
- struct fpga_manager *mgr,
- const struct fpga_region_ops *rops)
-{
- struct fpga_region **ptr, *region;
-
- ptr = devres_alloc(devm_fpga_region_release, sizeof(*ptr), GFP_KERNEL);
- if (!ptr)
- return NULL;
-
- region = fpga_region_create(parent, mgr, rops);
- if (!region) {
- devres_free(ptr);
- } else {
- *ptr = region;
- devres_add(parent, ptr);
- }
-
- return region;
-}
-EXPORT_SYMBOL_GPL(devm_fpga_region_create);
-
-/**
- * fpga_region_register - register an FPGA region
- * @region: FPGA region
- *
- * Return: 0 or -errno
- */
-int fpga_region_register(struct fpga_region *region)
-{
- return device_add(®ion->dev);
+ return ERR_PTR(ret);
}
EXPORT_SYMBOL_GPL(fpga_region_register);
@@ -320,6 +262,10 @@ EXPORT_SYMBOL_GPL(fpga_region_unregister);
static void fpga_region_dev_release(struct device *dev)
{
+ struct fpga_region *region = to_fpga_region(dev);
+
+ ida_simple_remove(&fpga_region_ida, region->dev.id);
+ kfree(region);
}
/**
@@ -409,16 +409,12 @@ static int of_fpga_region_probe(struct platform_device *pdev)
if (IS_ERR(mgr))
return -EPROBE_DEFER;
- region = devm_fpga_region_create(dev, mgr, &of_fpga_region_ops);
- if (!region) {
- ret = -ENOMEM;
+ region = fpga_region_register(dev, mgr, &of_fpga_region_ops, NULL);
+ if (IS_ERR(region)) {
+ ret = PTR_ERR(region);
goto eprobe_mgr_put;
}
- ret = fpga_region_register(region);
- if (ret)
- goto eprobe_mgr_put;
-
of_platform_populate(np, fpga_region_of_match, NULL, ®ion->dev);
platform_set_drvdata(pdev, region);
@@ -51,15 +51,9 @@ struct fpga_region *fpga_region_class_find(
int fpga_region_program_fpga(struct fpga_region *region);
-struct fpga_region
-*fpga_region_create(struct device *dev, struct fpga_manager *mgr,
- const struct fpga_region_ops *rops);
-void fpga_region_free(struct fpga_region *region);
-int fpga_region_register(struct fpga_region *region);
+struct fpga_region *
+fpga_region_register(struct device *parent, struct fpga_manager *mgr,
+ const struct fpga_region_ops *rops, void *priv);
void fpga_region_unregister(struct fpga_region *region);
-struct fpga_region
-*devm_fpga_region_create(struct device *dev, struct fpga_manager *mgr,
- const struct fpga_region_ops *rops);
-
#endif /* _FPGA_REGION_H */