diff options
author | Alan Tull <atull@kernel.org> | 2017-11-15 15:20:13 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2017-11-28 10:30:37 -0500 |
commit | ebf877a51ad7b65e4ab024f021b60a4f7928864a (patch) | |
tree | cca7dfc760c45f32bdbd9e6f69106dd24651d468 /drivers/fpga/fpga-region.c | |
parent | 5cf0c7f6502f26332b46fa87914553a4d6ae75ac (diff) |
fpga: mgr: separate getting/locking FPGA manager
Previously when the user gets a FPGA manager, it was locked
and nobody else could use it for programming.
This commit makes it straightforward to save a reference to an
FPGA manager and only lock it when programming the FPGA.
Add functions that get an FPGA manager's mutex for exclusive use:
* fpga_mgr_lock
* fpga_mgr_unlock
The following functions no longer lock an FPGA manager's mutex:
* of_fpga_mgr_get
* fpga_mgr_get
* fpga_mgr_put
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 | 14 |
1 files changed, 12 insertions, 2 deletions
diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c index 120c496eb7bd..1e1640a29306 100644 --- a/drivers/fpga/fpga-region.c +++ b/drivers/fpga/fpga-region.c | |||
@@ -125,7 +125,7 @@ static void fpga_region_put(struct fpga_region *region) | |||
125 | } | 125 | } |
126 | 126 | ||
127 | /** | 127 | /** |
128 | * fpga_region_get_manager - get exclusive reference for FPGA manager | 128 | * fpga_region_get_manager - get reference for FPGA manager |
129 | * @region: FPGA region | 129 | * @region: FPGA region |
130 | * | 130 | * |
131 | * Get FPGA Manager from "fpga-mgr" property or from ancestor region. | 131 | * Get FPGA Manager from "fpga-mgr" property or from ancestor region. |
@@ -233,6 +233,7 @@ static int fpga_region_get_bridges(struct fpga_region *region, | |||
233 | static int fpga_region_program_fpga(struct fpga_region *region, | 233 | static int fpga_region_program_fpga(struct fpga_region *region, |
234 | struct device_node *overlay) | 234 | struct device_node *overlay) |
235 | { | 235 | { |
236 | struct device *dev = ®ion->dev; | ||
236 | struct fpga_manager *mgr; | 237 | struct fpga_manager *mgr; |
237 | int ret; | 238 | int ret; |
238 | 239 | ||
@@ -249,10 +250,16 @@ static int fpga_region_program_fpga(struct fpga_region *region, | |||
249 | goto err_put_region; | 250 | goto err_put_region; |
250 | } | 251 | } |
251 | 252 | ||
253 | ret = fpga_mgr_lock(mgr); | ||
254 | if (ret) { | ||
255 | dev_err(dev, "FPGA manager is busy\n"); | ||
256 | goto err_put_mgr; | ||
257 | } | ||
258 | |||
252 | ret = fpga_region_get_bridges(region, overlay); | 259 | ret = fpga_region_get_bridges(region, overlay); |
253 | if (ret) { | 260 | if (ret) { |
254 | pr_err("failed to get fpga region bridges\n"); | 261 | pr_err("failed to get fpga region bridges\n"); |
255 | goto err_put_mgr; | 262 | goto err_unlock_mgr; |
256 | } | 263 | } |
257 | 264 | ||
258 | ret = fpga_bridges_disable(®ion->bridge_list); | 265 | ret = fpga_bridges_disable(®ion->bridge_list); |
@@ -273,6 +280,7 @@ static int fpga_region_program_fpga(struct fpga_region *region, | |||
273 | goto err_put_br; | 280 | goto err_put_br; |
274 | } | 281 | } |
275 | 282 | ||
283 | fpga_mgr_unlock(mgr); | ||
276 | fpga_mgr_put(mgr); | 284 | fpga_mgr_put(mgr); |
277 | fpga_region_put(region); | 285 | fpga_region_put(region); |
278 | 286 | ||
@@ -280,6 +288,8 @@ static int fpga_region_program_fpga(struct fpga_region *region, | |||
280 | 288 | ||
281 | err_put_br: | 289 | err_put_br: |
282 | fpga_bridges_put(®ion->bridge_list); | 290 | fpga_bridges_put(®ion->bridge_list); |
291 | err_unlock_mgr: | ||
292 | fpga_mgr_unlock(mgr); | ||
283 | err_put_mgr: | 293 | err_put_mgr: |
284 | fpga_mgr_put(mgr); | 294 | fpga_mgr_put(mgr); |
285 | err_put_region: | 295 | err_put_region: |