aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/fpga
diff options
context:
space:
mode:
authorAlan Tull <atull@kernel.org>2018-10-15 18:20:03 -0400
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-10-16 05:13:50 -0400
commitfea82b7f6670002ff36bf1bc77d0345b0b2f2d1c (patch)
treeeeed3d9f54d90d5f01ea84e1ebdd2d05b3553667 /drivers/fpga
parent213befe049c70cfcfcbb4f6010bd5276dbc1f7b9 (diff)
fpga: add devm_fpga_region_create
Add devm_fpga_region_create() which is the managed version of fpga_region_create(). Change current region drivers to use devm_fpga_region_create(). Signed-off-by: Alan Tull <atull@kernel.org> Suggested-by: Federico Vaga <federico.vaga@cern.ch> Acked-by: Moritz Fischer <mdf@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/fpga')
-rw-r--r--drivers/fpga/dfl-fme-region.c6
-rw-r--r--drivers/fpga/dfl.c6
-rw-r--r--drivers/fpga/fpga-region.c65
-rw-r--r--drivers/fpga/of-fpga-region.c6
4 files changed, 63 insertions, 20 deletions
diff --git a/drivers/fpga/dfl-fme-region.c b/drivers/fpga/dfl-fme-region.c
index 51a5ac2293a7..ec134ec93f08 100644
--- a/drivers/fpga/dfl-fme-region.c
+++ b/drivers/fpga/dfl-fme-region.c
@@ -39,7 +39,7 @@ static int fme_region_probe(struct platform_device *pdev)
39 if (IS_ERR(mgr)) 39 if (IS_ERR(mgr))
40 return -EPROBE_DEFER; 40 return -EPROBE_DEFER;
41 41
42 region = fpga_region_create(dev, mgr, fme_region_get_bridges); 42 region = devm_fpga_region_create(dev, mgr, fme_region_get_bridges);
43 if (!region) { 43 if (!region) {
44 ret = -ENOMEM; 44 ret = -ENOMEM;
45 goto eprobe_mgr_put; 45 goto eprobe_mgr_put;
@@ -51,14 +51,12 @@ static int fme_region_probe(struct platform_device *pdev)
51 51
52 ret = fpga_region_register(region); 52 ret = fpga_region_register(region);
53 if (ret) 53 if (ret)
54 goto region_free; 54 goto eprobe_mgr_put;
55 55
56 dev_dbg(dev, "DFL FME FPGA Region probed\n"); 56 dev_dbg(dev, "DFL FME FPGA Region probed\n");
57 57
58 return 0; 58 return 0;
59 59
60region_free:
61 fpga_region_free(region);
62eprobe_mgr_put: 60eprobe_mgr_put:
63 fpga_mgr_put(mgr); 61 fpga_mgr_put(mgr);
64 return ret; 62 return ret;
diff --git a/drivers/fpga/dfl.c b/drivers/fpga/dfl.c
index a9b521bccb06..2c09e502e721 100644
--- a/drivers/fpga/dfl.c
+++ b/drivers/fpga/dfl.c
@@ -899,7 +899,7 @@ dfl_fpga_feature_devs_enumerate(struct dfl_fpga_enum_info *info)
899 if (!cdev) 899 if (!cdev)
900 return ERR_PTR(-ENOMEM); 900 return ERR_PTR(-ENOMEM);
901 901
902 cdev->region = fpga_region_create(info->dev, NULL, NULL); 902 cdev->region = devm_fpga_region_create(info->dev, NULL, NULL);
903 if (!cdev->region) { 903 if (!cdev->region) {
904 ret = -ENOMEM; 904 ret = -ENOMEM;
905 goto free_cdev_exit; 905 goto free_cdev_exit;
@@ -911,7 +911,7 @@ dfl_fpga_feature_devs_enumerate(struct dfl_fpga_enum_info *info)
911 911
912 ret = fpga_region_register(cdev->region); 912 ret = fpga_region_register(cdev->region);
913 if (ret) 913 if (ret)
914 goto free_region_exit; 914 goto free_cdev_exit;
915 915
916 /* create and init build info for enumeration */ 916 /* create and init build info for enumeration */
917 binfo = devm_kzalloc(info->dev, sizeof(*binfo), GFP_KERNEL); 917 binfo = devm_kzalloc(info->dev, sizeof(*binfo), GFP_KERNEL);
@@ -942,8 +942,6 @@ dfl_fpga_feature_devs_enumerate(struct dfl_fpga_enum_info *info)
942 942
943unregister_region_exit: 943unregister_region_exit:
944 fpga_region_unregister(cdev->region); 944 fpga_region_unregister(cdev->region);
945free_region_exit:
946 fpga_region_free(cdev->region);
947free_cdev_exit: 945free_cdev_exit:
948 devm_kfree(info->dev, cdev); 946 devm_kfree(info->dev, cdev);
949 return ERR_PTR(ret); 947 return ERR_PTR(ret);
diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
index 0d65220d5ec5..bde5a9d460c5 100644
--- a/drivers/fpga/fpga-region.c
+++ b/drivers/fpga/fpga-region.c
@@ -185,6 +185,10 @@ ATTRIBUTE_GROUPS(fpga_region);
185 * @mgr: manager that programs this region 185 * @mgr: manager that programs this region
186 * @get_bridges: optional function to get bridges to a list 186 * @get_bridges: optional function to get bridges to a list
187 * 187 *
188 * The caller of this function is responsible for freeing the resulting region
189 * struct with fpga_region_free(). Using devm_fpga_region_create() instead is
190 * recommended.
191 *
188 * Return: struct fpga_region or NULL 192 * Return: struct fpga_region or NULL
189 */ 193 */
190struct fpga_region 194struct fpga_region
@@ -230,8 +234,8 @@ err_free:
230EXPORT_SYMBOL_GPL(fpga_region_create); 234EXPORT_SYMBOL_GPL(fpga_region_create);
231 235
232/** 236/**
233 * fpga_region_free - free a struct fpga_region 237 * fpga_region_free - free a FPGA region created by fpga_region_create()
234 * @region: FPGA region created by fpga_region_create 238 * @region: FPGA region
235 */ 239 */
236void fpga_region_free(struct fpga_region *region) 240void fpga_region_free(struct fpga_region *region)
237{ 241{
@@ -240,21 +244,69 @@ void fpga_region_free(struct fpga_region *region)
240} 244}
241EXPORT_SYMBOL_GPL(fpga_region_free); 245EXPORT_SYMBOL_GPL(fpga_region_free);
242 246
247static void devm_fpga_region_release(struct device *dev, void *res)
248{
249 struct fpga_region *region = *(struct fpga_region **)res;
250
251 fpga_region_free(region);
252}
253
254/**
255 * devm_fpga_region_create - create and initialize a managed FPGA region struct
256 * @dev: device parent
257 * @mgr: manager that programs this region
258 * @get_bridges: optional function to get bridges to a list
259 *
260 * This function is intended for use in a FPGA region driver's probe function.
261 * After the region driver creates the region struct with
262 * devm_fpga_region_create(), it should register it with fpga_region_register().
263 * The region driver's remove function should call fpga_region_unregister().
264 * The region struct allocated with this function will be freed automatically on
265 * driver detach. This includes the case of a probe function returning error
266 * before calling fpga_region_register(), the struct will still get cleaned up.
267 *
268 * Return: struct fpga_region or NULL
269 */
270struct fpga_region
271*devm_fpga_region_create(struct device *dev,
272 struct fpga_manager *mgr,
273 int (*get_bridges)(struct fpga_region *))
274{
275 struct fpga_region **ptr, *region;
276
277 ptr = devres_alloc(devm_fpga_region_release, sizeof(*ptr), GFP_KERNEL);
278 if (!ptr)
279 return NULL;
280
281 region = fpga_region_create(dev, mgr, get_bridges);
282 if (!region) {
283 devres_free(ptr);
284 } else {
285 *ptr = region;
286 devres_add(dev, ptr);
287 }
288
289 return region;
290}
291EXPORT_SYMBOL_GPL(devm_fpga_region_create);
292
243/** 293/**
244 * fpga_region_register - register a FPGA region 294 * fpga_region_register - register a FPGA region
245 * @region: FPGA region created by fpga_region_create 295 * @region: FPGA region
296 *
246 * Return: 0 or -errno 297 * Return: 0 or -errno
247 */ 298 */
248int fpga_region_register(struct fpga_region *region) 299int fpga_region_register(struct fpga_region *region)
249{ 300{
250 return device_add(&region->dev); 301 return device_add(&region->dev);
251
252} 302}
253EXPORT_SYMBOL_GPL(fpga_region_register); 303EXPORT_SYMBOL_GPL(fpga_region_register);
254 304
255/** 305/**
256 * fpga_region_unregister - unregister and free a FPGA region 306 * fpga_region_unregister - unregister a FPGA region
257 * @region: FPGA region 307 * @region: FPGA region
308 *
309 * This function is intended for use in a FPGA region driver's remove function.
258 */ 310 */
259void fpga_region_unregister(struct fpga_region *region) 311void fpga_region_unregister(struct fpga_region *region)
260{ 312{
@@ -264,9 +316,6 @@ EXPORT_SYMBOL_GPL(fpga_region_unregister);
264 316
265static void fpga_region_dev_release(struct device *dev) 317static void fpga_region_dev_release(struct device *dev)
266{ 318{
267 struct fpga_region *region = to_fpga_region(dev);
268
269 fpga_region_free(region);
270} 319}
271 320
272/** 321/**
diff --git a/drivers/fpga/of-fpga-region.c b/drivers/fpga/of-fpga-region.c
index 052a1342ab7e..122286fd255a 100644
--- a/drivers/fpga/of-fpga-region.c
+++ b/drivers/fpga/of-fpga-region.c
@@ -410,7 +410,7 @@ static int of_fpga_region_probe(struct platform_device *pdev)
410 if (IS_ERR(mgr)) 410 if (IS_ERR(mgr))
411 return -EPROBE_DEFER; 411 return -EPROBE_DEFER;
412 412
413 region = fpga_region_create(dev, mgr, of_fpga_region_get_bridges); 413 region = devm_fpga_region_create(dev, mgr, of_fpga_region_get_bridges);
414 if (!region) { 414 if (!region) {
415 ret = -ENOMEM; 415 ret = -ENOMEM;
416 goto eprobe_mgr_put; 416 goto eprobe_mgr_put;
@@ -418,7 +418,7 @@ static int of_fpga_region_probe(struct platform_device *pdev)
418 418
419 ret = fpga_region_register(region); 419 ret = fpga_region_register(region);
420 if (ret) 420 if (ret)
421 goto eprobe_free; 421 goto eprobe_mgr_put;
422 422
423 of_platform_populate(np, fpga_region_of_match, NULL, &region->dev); 423 of_platform_populate(np, fpga_region_of_match, NULL, &region->dev);
424 dev_set_drvdata(dev, region); 424 dev_set_drvdata(dev, region);
@@ -427,8 +427,6 @@ static int of_fpga_region_probe(struct platform_device *pdev)
427 427
428 return 0; 428 return 0;
429 429
430eprobe_free:
431 fpga_region_free(region);
432eprobe_mgr_put: 430eprobe_mgr_put:
433 fpga_mgr_put(mgr); 431 fpga_mgr_put(mgr);
434 return ret; 432 return ret;