diff options
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.patch | 235 |
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(®ion->mutex); + INIT_LIST_HEAD(®ion->bridge_list); ++ + device_initialize(®ion->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(®ion->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(®ion->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(®ion->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, ®ion->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 + |