diff options
author | Alan Tull <atull@kernel.org> | 2017-11-15 15:20:16 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-11-28 10:30:37 -0500 |
commit | 1df2dd7f587107ebf3c8e3733410627cf5c3b3ec (patch) | |
tree | 75fa57d1b934d39307df37f48a7405f65b98f01b /drivers/fpga/fpga-region.c | |
parent | 08bcb4b1a7615762e1e2c87a5c8cc5d9709b60f6 (diff) |
fpga: region: get mgr early on
Get the FPGA manager during region creation.
This is a baby step in refactoring the FPGA region code to
separate out common FPGA region code from FPGA region
Device Tree overlay support.
Signed-off-by: Alan Tull <atull@kernel.org>
Acked-by: Moritz Fischer <mdf@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers/fpga/fpga-region.c')
-rw-r--r-- | drivers/fpga/fpga-region.c | 45 |
1 files changed, 23 insertions, 22 deletions
diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c index 352661fc6b14..d78f444c1350 100644 --- a/drivers/fpga/fpga-region.c +++ b/drivers/fpga/fpga-region.c | |||
@@ -31,12 +31,14 @@ | |||
31 | * @dev: FPGA Region device | 31 | * @dev: FPGA Region device |
32 | * @mutex: enforces exclusive reference to region | 32 | * @mutex: enforces exclusive reference to region |
33 | * @bridge_list: list of FPGA bridges specified in region | 33 | * @bridge_list: list of FPGA bridges specified in region |
34 | * @mgr: FPGA manager | ||
34 | * @info: fpga image specific information | 35 | * @info: fpga image specific information |
35 | */ | 36 | */ |
36 | struct fpga_region { | 37 | struct fpga_region { |
37 | struct device dev; | 38 | struct device dev; |
38 | struct mutex mutex; /* for exclusive reference to region */ | 39 | struct mutex mutex; /* for exclusive reference to region */ |
39 | struct list_head bridge_list; | 40 | struct list_head bridge_list; |
41 | struct fpga_manager *mgr; | ||
40 | struct fpga_image_info *info; | 42 | struct fpga_image_info *info; |
41 | }; | 43 | }; |
42 | 44 | ||
@@ -123,7 +125,7 @@ static void fpga_region_put(struct fpga_region *region) | |||
123 | 125 | ||
124 | /** | 126 | /** |
125 | * fpga_region_get_manager - get reference for FPGA manager | 127 | * fpga_region_get_manager - get reference for FPGA manager |
126 | * @region: FPGA region | 128 | * @np: device node of FPGA region |
127 | * | 129 | * |
128 | * Get FPGA Manager from "fpga-mgr" property or from ancestor region. | 130 | * Get FPGA Manager from "fpga-mgr" property or from ancestor region. |
129 | * | 131 | * |
@@ -131,10 +133,8 @@ static void fpga_region_put(struct fpga_region *region) | |||
131 | * | 133 | * |
132 | * Return: fpga manager struct or IS_ERR() condition containing error code. | 134 | * Return: fpga manager struct or IS_ERR() condition containing error code. |
133 | */ | 135 | */ |
134 | static struct fpga_manager *fpga_region_get_manager(struct fpga_region *region) | 136 | static struct fpga_manager *fpga_region_get_manager(struct device_node *np) |
135 | { | 137 | { |
136 | struct device *dev = ®ion->dev; | ||
137 | struct device_node *np = dev->of_node; | ||
138 | struct device_node *mgr_node; | 138 | struct device_node *mgr_node; |
139 | struct fpga_manager *mgr; | 139 | struct fpga_manager *mgr; |
140 | 140 | ||
@@ -231,7 +231,6 @@ static int fpga_region_program_fpga(struct fpga_region *region, | |||
231 | struct device_node *overlay) | 231 | struct device_node *overlay) |
232 | { | 232 | { |
233 | struct device *dev = ®ion->dev; | 233 | struct device *dev = ®ion->dev; |
234 | struct fpga_manager *mgr; | ||
235 | int ret; | 234 | int ret; |
236 | 235 | ||
237 | region = fpga_region_get(region); | 236 | region = fpga_region_get(region); |
@@ -240,17 +239,10 @@ static int fpga_region_program_fpga(struct fpga_region *region, | |||
240 | return PTR_ERR(region); | 239 | return PTR_ERR(region); |
241 | } | 240 | } |
242 | 241 | ||
243 | mgr = fpga_region_get_manager(region); | 242 | ret = fpga_mgr_lock(region->mgr); |
244 | if (IS_ERR(mgr)) { | ||
245 | dev_err(dev, "failed to get FPGA manager\n"); | ||
246 | ret = PTR_ERR(mgr); | ||
247 | goto err_put_region; | ||
248 | } | ||
249 | |||
250 | ret = fpga_mgr_lock(mgr); | ||
251 | if (ret) { | 243 | if (ret) { |
252 | dev_err(dev, "FPGA manager is busy\n"); | 244 | dev_err(dev, "FPGA manager is busy\n"); |
253 | goto err_put_mgr; | 245 | goto err_put_region; |
254 | } | 246 | } |
255 | 247 | ||
256 | ret = fpga_region_get_bridges(region, overlay); | 248 | ret = fpga_region_get_bridges(region, overlay); |
@@ -265,7 +257,7 @@ static int fpga_region_program_fpga(struct fpga_region *region, | |||
265 | goto err_put_br; | 257 | goto err_put_br; |
266 | } | 258 | } |
267 | 259 | ||
268 | ret = fpga_mgr_load(mgr, region->info); | 260 | ret = fpga_mgr_load(region->mgr, region->info); |
269 | if (ret) { | 261 | if (ret) { |
270 | dev_err(dev, "failed to load FPGA image\n"); | 262 | dev_err(dev, "failed to load FPGA image\n"); |
271 | goto err_put_br; | 263 | goto err_put_br; |
@@ -277,8 +269,7 @@ static int fpga_region_program_fpga(struct fpga_region *region, | |||
277 | goto err_put_br; | 269 | goto err_put_br; |
278 | } | 270 | } |
279 | 271 | ||
280 | fpga_mgr_unlock(mgr); | 272 | fpga_mgr_unlock(region->mgr); |
281 | fpga_mgr_put(mgr); | ||
282 | fpga_region_put(region); | 273 | fpga_region_put(region); |
283 | 274 | ||
284 | return 0; | 275 | return 0; |
@@ -286,9 +277,7 @@ static int fpga_region_program_fpga(struct fpga_region *region, | |||
286 | err_put_br: | 277 | err_put_br: |
287 | fpga_bridges_put(®ion->bridge_list); | 278 | fpga_bridges_put(®ion->bridge_list); |
288 | err_unlock_mgr: | 279 | err_unlock_mgr: |
289 | fpga_mgr_unlock(mgr); | 280 | fpga_mgr_unlock(region->mgr); |
290 | err_put_mgr: | ||
291 | fpga_mgr_put(mgr); | ||
292 | err_put_region: | 281 | err_put_region: |
293 | fpga_region_put(region); | 282 | fpga_region_put(region); |
294 | 283 | ||
@@ -517,11 +506,20 @@ static int fpga_region_probe(struct platform_device *pdev) | |||
517 | struct device *dev = &pdev->dev; | 506 | struct device *dev = &pdev->dev; |
518 | struct device_node *np = dev->of_node; | 507 | struct device_node *np = dev->of_node; |
519 | struct fpga_region *region; | 508 | struct fpga_region *region; |
509 | struct fpga_manager *mgr; | ||
520 | int id, ret = 0; | 510 | int id, ret = 0; |
521 | 511 | ||
512 | mgr = fpga_region_get_manager(np); | ||
513 | if (IS_ERR(mgr)) | ||
514 | return -EPROBE_DEFER; | ||
515 | |||
522 | region = kzalloc(sizeof(*region), GFP_KERNEL); | 516 | region = kzalloc(sizeof(*region), GFP_KERNEL); |
523 | if (!region) | 517 | if (!region) { |
524 | return -ENOMEM; | 518 | ret = -ENOMEM; |
519 | goto err_put_mgr; | ||
520 | } | ||
521 | |||
522 | region->mgr = mgr; | ||
525 | 523 | ||
526 | id = ida_simple_get(&fpga_region_ida, 0, 0, GFP_KERNEL); | 524 | id = ida_simple_get(&fpga_region_ida, 0, 0, GFP_KERNEL); |
527 | if (id < 0) { | 525 | if (id < 0) { |
@@ -557,6 +555,8 @@ err_remove: | |||
557 | ida_simple_remove(&fpga_region_ida, id); | 555 | ida_simple_remove(&fpga_region_ida, id); |
558 | err_kfree: | 556 | err_kfree: |
559 | kfree(region); | 557 | kfree(region); |
558 | err_put_mgr: | ||
559 | fpga_mgr_put(mgr); | ||
560 | 560 | ||
561 | return ret; | 561 | return ret; |
562 | } | 562 | } |
@@ -566,6 +566,7 @@ static int fpga_region_remove(struct platform_device *pdev) | |||
566 | struct fpga_region *region = platform_get_drvdata(pdev); | 566 | struct fpga_region *region = platform_get_drvdata(pdev); |
567 | 567 | ||
568 | device_unregister(®ion->dev); | 568 | device_unregister(®ion->dev); |
569 | fpga_mgr_put(region->mgr); | ||
569 | 570 | ||
570 | return 0; | 571 | return 0; |
571 | } | 572 | } |