aboutsummaryrefslogtreecommitdiffstats
path: root/patches/1689-fpga-region-change-api-add-fpga_region_create-free.patch
diff options
context:
space:
mode:
Diffstat (limited to 'patches/1689-fpga-region-change-api-add-fpga_region_create-free.patch')
-rw-r--r--patches/1689-fpga-region-change-api-add-fpga_region_create-free.patch235
1 files changed, 235 insertions, 0 deletions
diff --git a/patches/1689-fpga-region-change-api-add-fpga_region_create-free.patch b/patches/1689-fpga-region-change-api-add-fpga_region_create-free.patch
new file mode 100644
index 00000000000000..8f0cb6a15fef6b
--- /dev/null
+++ b/patches/1689-fpga-region-change-api-add-fpga_region_create-free.patch
@@ -0,0 +1,235 @@
+From 4405f8a50fd15b0022c920fee635ddb47c1664ec Mon Sep 17 00:00:00 2001
+From: Alan Tull <atull@kernel.org>
+Date: Wed, 16 May 2018 18:49:57 -0500
+Subject: [PATCH 1689/1795] fpga: region: change api, add
+ fpga_region_create/free
+
+Add fpga_region_create/free API functions.
+
+Change fpga_region_register to take FPGA region struct as the only
+parameter. Change fpga_region_unregister to return void.
+
+ struct fpga_region *fpga_region_create(struct device *dev,
+ struct fpga_manager *mgr,
+ int (*get_bridges)(struct fpga_region *));
+ void fpga_region_free(struct fpga_region *region);
+ int fpga_region_register(struct fpga_region *region);
+ void fpga_region_unregister(struct fpga_region *region);
+
+Remove groups storage from struct fpga_region, it's not
+needed. Callers can just "region->dev.groups = groups;"
+after calling fpga_region_create.
+
+Update the drivers that call fpga_region_register with the new API.
+
+Signed-off-by: Alan Tull <atull@kernel.org>
+Signed-off-by: Moritz Fischer <mdf@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+(cherry picked from commit 9f368977b4589e2fe0b9d3a4cbaf11ff6a58ecf5)
+Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
+---
+ Documentation/fpga/fpga-region.txt | 3 +-
+ drivers/fpga/fpga-region.c | 68 ++++++++++++++++++++++++------
+ drivers/fpga/of-fpga-region.c | 13 +++---
+ include/linux/fpga/fpga-region.h | 11 +++--
+ 4 files changed, 68 insertions(+), 27 deletions(-)
+
+diff --git a/Documentation/fpga/fpga-region.txt b/Documentation/fpga/fpga-region.txt
+index 139a02ba1ff6..d38fa3b4154a 100644
+--- a/Documentation/fpga/fpga-region.txt
++++ b/Documentation/fpga/fpga-region.txt
+@@ -42,8 +42,7 @@ The FPGA region API
+ To register or unregister a region:
+ -----------------------------------
+
+- int fpga_region_register(struct device *dev,
+- struct fpga_region *region);
++ int fpga_region_register(struct fpga_region *region);
+ int fpga_region_unregister(struct fpga_region *region);
+
+ An example of usage can be seen in the probe function of [3]
+diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
+index f634a8ed5e2c..b3ba3e40c44b 100644
+--- a/drivers/fpga/fpga-region.c
++++ b/drivers/fpga/fpga-region.c
+@@ -167,18 +167,36 @@ int fpga_region_program_fpga(struct fpga_region *region)
+ }
+ EXPORT_SYMBOL_GPL(fpga_region_program_fpga);
+
+-int fpga_region_register(struct device *dev, struct fpga_region *region)
++/**
++ * fpga_region_create - alloc and init a struct fpga_region
++ * @dev: device parent
++ * @mgr: manager that programs this region
++ * @get_bridges: optional function to get bridges to a list
++ *
++ * Return: struct fpga_region or NULL
++ */
++struct fpga_region
++*fpga_region_create(struct device *dev,
++ struct fpga_manager *mgr,
++ int (*get_bridges)(struct fpga_region *))
+ {
++ struct fpga_region *region;
+ int id, ret = 0;
+
++ region = kzalloc(sizeof(*region), GFP_KERNEL);
++ if (!region)
++ return NULL;
++
+ id = ida_simple_get(&fpga_region_ida, 0, 0, GFP_KERNEL);
+ if (id < 0)
+- return id;
++ goto err_free;
+
++ region->mgr = mgr;
++ region->get_bridges = get_bridges;
+ mutex_init(&region->mutex);
+ INIT_LIST_HEAD(&region->bridge_list);
++
+ device_initialize(&region->dev);
+- region->dev.groups = region->groups;
+ region->dev.class = fpga_region_class;
+ region->dev.parent = dev;
+ region->dev.of_node = dev->of_node;
+@@ -188,23 +206,47 @@ int fpga_region_register(struct device *dev, struct fpga_region *region)
+ if (ret)
+ goto err_remove;
+
+- ret = device_add(&region->dev);
+- if (ret)
+- goto err_remove;
+-
+- return 0;
++ return region;
+
+ err_remove:
+ ida_simple_remove(&fpga_region_ida, id);
+- return ret;
++err_free:
++ kfree(region);
++
++ return NULL;
++}
++EXPORT_SYMBOL_GPL(fpga_region_create);
++
++/**
++ * fpga_region_free - free a struct fpga_region
++ * @region: FPGA region created by fpga_region_create
++ */
++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);
++
++/*
++ * fpga_region_register - register a FPGA region
++ * @region: FPGA region created by fpga_region_create
++ * Return: 0 or -errno
++ */
++int fpga_region_register(struct fpga_region *region)
++{
++ return device_add(&region->dev);
++
+ }
+ EXPORT_SYMBOL_GPL(fpga_region_register);
+
+-int fpga_region_unregister(struct fpga_region *region)
++/*
++ * fpga_region_unregister - unregister a FPGA region
++ * @region: FPGA region
++ */
++void fpga_region_unregister(struct fpga_region *region)
+ {
+ device_unregister(&region->dev);
+-
+- return 0;
+ }
+ EXPORT_SYMBOL_GPL(fpga_region_unregister);
+
+@@ -212,7 +254,7 @@ 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);
++ fpga_region_free(region);
+ }
+
+ /**
+diff --git a/drivers/fpga/of-fpga-region.c b/drivers/fpga/of-fpga-region.c
+index 35e7e8c4a0cb..9d681a1c5738 100644
+--- a/drivers/fpga/of-fpga-region.c
++++ b/drivers/fpga/of-fpga-region.c
+@@ -422,20 +422,15 @@ static int of_fpga_region_probe(struct platform_device *pdev)
+ if (IS_ERR(mgr))
+ return -EPROBE_DEFER;
+
+- region = devm_kzalloc(dev, sizeof(*region), GFP_KERNEL);
++ region = fpga_region_create(dev, mgr, of_fpga_region_get_bridges);
+ if (!region) {
+ ret = -ENOMEM;
+ goto eprobe_mgr_put;
+ }
+
+- region->mgr = mgr;
+-
+- /* Specify how to get bridges for this type of region. */
+- region->get_bridges = of_fpga_region_get_bridges;
+-
+- ret = fpga_region_register(dev, region);
++ ret = fpga_region_register(region);
+ if (ret)
+- goto eprobe_mgr_put;
++ goto eprobe_free;
+
+ of_platform_populate(np, fpga_region_of_match, NULL, &region->dev);
+ dev_set_drvdata(dev, region);
+@@ -444,6 +439,8 @@ static int of_fpga_region_probe(struct platform_device *pdev)
+
+ return 0;
+
++eprobe_free:
++ fpga_region_free(region);
+ eprobe_mgr_put:
+ fpga_mgr_put(mgr);
+ return ret;
+diff --git a/include/linux/fpga/fpga-region.h b/include/linux/fpga/fpga-region.h
+index b6520318ab9c..f2e215bd1330 100644
+--- a/include/linux/fpga/fpga-region.h
++++ b/include/linux/fpga/fpga-region.h
+@@ -14,7 +14,6 @@
+ * @info: FPGA image info
+ * @priv: private data
+ * @get_bridges: optional function to get bridges to a list
+- * @groups: optional attribute groups.
+ */
+ struct fpga_region {
+ struct device dev;
+@@ -24,7 +23,6 @@ struct fpga_region {
+ struct fpga_image_info *info;
+ void *priv;
+ int (*get_bridges)(struct fpga_region *region);
+- const struct attribute_group **groups;
+ };
+
+ #define to_fpga_region(d) container_of(d, struct fpga_region, dev)
+@@ -34,7 +32,12 @@ struct fpga_region *fpga_region_class_find(
+ int (*match)(struct device *, const void *));
+
+ int fpga_region_program_fpga(struct fpga_region *region);
+-int fpga_region_register(struct device *dev, struct fpga_region *region);
+-int fpga_region_unregister(struct fpga_region *region);
++
++struct fpga_region
++*fpga_region_create(struct device *dev, struct fpga_manager *mgr,
++ int (*get_bridges)(struct fpga_region *));
++void fpga_region_free(struct fpga_region *region);
++int fpga_region_register(struct fpga_region *region);
++void fpga_region_unregister(struct fpga_region *region);
+
+ #endif /* _FPGA_REGION_H */
+--
+2.19.0
+