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>
This commit is contained in:
Alan Tull
2017-11-15 14:20:13 -06:00
committed by Greg Kroah-Hartman
parent 5cf0c7f650
commit ebf877a51a
4 changed files with 77 additions and 27 deletions

View File

@@ -125,7 +125,7 @@ static void fpga_region_put(struct fpga_region *region)
}
/**
* fpga_region_get_manager - get exclusive reference for FPGA manager
* fpga_region_get_manager - get reference for FPGA manager
* @region: FPGA region
*
* 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,
static int fpga_region_program_fpga(struct fpga_region *region,
struct device_node *overlay)
{
struct device *dev = &region->dev;
struct fpga_manager *mgr;
int ret;
@@ -249,10 +250,16 @@ static int fpga_region_program_fpga(struct fpga_region *region,
goto err_put_region;
}
ret = fpga_mgr_lock(mgr);
if (ret) {
dev_err(dev, "FPGA manager is busy\n");
goto err_put_mgr;
}
ret = fpga_region_get_bridges(region, overlay);
if (ret) {
pr_err("failed to get fpga region bridges\n");
goto err_put_mgr;
goto err_unlock_mgr;
}
ret = fpga_bridges_disable(&region->bridge_list);
@@ -273,6 +280,7 @@ static int fpga_region_program_fpga(struct fpga_region *region,
goto err_put_br;
}
fpga_mgr_unlock(mgr);
fpga_mgr_put(mgr);
fpga_region_put(region);
@@ -280,6 +288,8 @@ static int fpga_region_program_fpga(struct fpga_region *region,
err_put_br:
fpga_bridges_put(&region->bridge_list);
err_unlock_mgr:
fpga_mgr_unlock(mgr);
err_put_mgr:
fpga_mgr_put(mgr);
err_put_region: