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; |
