diff options
author | Alan Tull <atull@kernel.org> | 2018-10-15 18:20:03 -0400 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2018-10-16 05:13:50 -0400 |
commit | fea82b7f6670002ff36bf1bc77d0345b0b2f2d1c (patch) | |
tree | eeed3d9f54d90d5f01ea84e1ebdd2d05b3553667 /drivers/fpga | |
parent | 213befe049c70cfcfcbb4f6010bd5276dbc1f7b9 (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.c | 6 | ||||
-rw-r--r-- | drivers/fpga/dfl.c | 6 | ||||
-rw-r--r-- | drivers/fpga/fpga-region.c | 65 | ||||
-rw-r--r-- | drivers/fpga/of-fpga-region.c | 6 |
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 | ||
60 | region_free: | ||
61 | fpga_region_free(region); | ||
62 | eprobe_mgr_put: | 60 | eprobe_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 | ||
943 | unregister_region_exit: | 943 | unregister_region_exit: |
944 | fpga_region_unregister(cdev->region); | 944 | fpga_region_unregister(cdev->region); |
945 | free_region_exit: | ||
946 | fpga_region_free(cdev->region); | ||
947 | free_cdev_exit: | 945 | free_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 | */ |
190 | struct fpga_region | 194 | struct fpga_region |
@@ -230,8 +234,8 @@ err_free: | |||
230 | EXPORT_SYMBOL_GPL(fpga_region_create); | 234 | EXPORT_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 | */ |
236 | void fpga_region_free(struct fpga_region *region) | 240 | void fpga_region_free(struct fpga_region *region) |
237 | { | 241 | { |
@@ -240,21 +244,69 @@ void fpga_region_free(struct fpga_region *region) | |||
240 | } | 244 | } |
241 | EXPORT_SYMBOL_GPL(fpga_region_free); | 245 | EXPORT_SYMBOL_GPL(fpga_region_free); |
242 | 246 | ||
247 | static 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 | */ | ||
270 | struct 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 | } | ||
291 | EXPORT_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 | */ |
248 | int fpga_region_register(struct fpga_region *region) | 299 | int fpga_region_register(struct fpga_region *region) |
249 | { | 300 | { |
250 | return device_add(®ion->dev); | 301 | return device_add(®ion->dev); |
251 | |||
252 | } | 302 | } |
253 | EXPORT_SYMBOL_GPL(fpga_region_register); | 303 | EXPORT_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 | */ |
259 | void fpga_region_unregister(struct fpga_region *region) | 311 | void fpga_region_unregister(struct fpga_region *region) |
260 | { | 312 | { |
@@ -264,9 +316,6 @@ EXPORT_SYMBOL_GPL(fpga_region_unregister); | |||
264 | 316 | ||
265 | static void fpga_region_dev_release(struct device *dev) | 317 | static 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, ®ion->dev); | 423 | of_platform_populate(np, fpga_region_of_match, NULL, ®ion->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 | ||
430 | eprobe_free: | ||
431 | fpga_region_free(region); | ||
432 | eprobe_mgr_put: | 430 | eprobe_mgr_put: |
433 | fpga_mgr_put(mgr); | 431 | fpga_mgr_put(mgr); |
434 | return ret; | 432 | return ret; |