| From 2004199987c92dad3cd238b78b214ac33689373e Mon Sep 17 00:00:00 2001 |
| From: Alan Tull <atull@kernel.org> |
| Date: Wed, 15 Nov 2017 14:20:16 -0600 |
| Subject: [PATCH 1665/1795] 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> |
| (cherry picked from commit 1df2dd7f587107ebf3c8e3733410627cf5c3b3ec) |
| Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be> |
| --- |
| drivers/fpga/fpga-region.c | 45 +++++++++++++++++++------------------- |
| 1 file changed, 23 insertions(+), 22 deletions(-) |
| |
| diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c |
| index 5741ad6af1d2..8c0d7bc572ed 100644 |
| --- a/drivers/fpga/fpga-region.c |
| +++ b/drivers/fpga/fpga-region.c |
| @@ -31,12 +31,14 @@ |
| * @dev: FPGA Region device |
| * @mutex: enforces exclusive reference to region |
| * @bridge_list: list of FPGA bridges specified in region |
| + * @mgr: FPGA manager |
| * @info: fpga image specific information |
| */ |
| struct fpga_region { |
| struct device dev; |
| struct mutex mutex; /* for exclusive reference to region */ |
| struct list_head bridge_list; |
| + struct fpga_manager *mgr; |
| struct fpga_image_info *info; |
| }; |
| |
| @@ -123,7 +125,7 @@ static void fpga_region_put(struct fpga_region *region) |
| |
| /** |
| * fpga_region_get_manager - get reference for FPGA manager |
| - * @region: FPGA region |
| + * @np: device node of FPGA region |
| * |
| * Get FPGA Manager from "fpga-mgr" property or from ancestor region. |
| * |
| @@ -131,10 +133,8 @@ static void fpga_region_put(struct fpga_region *region) |
| * |
| * Return: fpga manager struct or IS_ERR() condition containing error code. |
| */ |
| -static struct fpga_manager *fpga_region_get_manager(struct fpga_region *region) |
| +static struct fpga_manager *fpga_region_get_manager(struct device_node *np) |
| { |
| - struct device *dev = ®ion->dev; |
| - struct device_node *np = dev->of_node; |
| struct device_node *mgr_node; |
| struct fpga_manager *mgr; |
| |
| @@ -238,7 +238,6 @@ static int fpga_region_program_fpga(struct fpga_region *region, |
| struct device_node *overlay) |
| { |
| struct device *dev = ®ion->dev; |
| - struct fpga_manager *mgr; |
| int ret; |
| |
| region = fpga_region_get(region); |
| @@ -247,17 +246,10 @@ static int fpga_region_program_fpga(struct fpga_region *region, |
| return PTR_ERR(region); |
| } |
| |
| - mgr = fpga_region_get_manager(region); |
| - if (IS_ERR(mgr)) { |
| - dev_err(dev, "failed to get FPGA manager\n"); |
| - ret = PTR_ERR(mgr); |
| - goto err_put_region; |
| - } |
| - |
| - ret = fpga_mgr_lock(mgr); |
| + ret = fpga_mgr_lock(region->mgr); |
| if (ret) { |
| dev_err(dev, "FPGA manager is busy\n"); |
| - goto err_put_mgr; |
| + goto err_put_region; |
| } |
| |
| ret = fpga_region_get_bridges(region, overlay); |
| @@ -272,7 +264,7 @@ static int fpga_region_program_fpga(struct fpga_region *region, |
| goto err_put_br; |
| } |
| |
| - ret = fpga_mgr_load(mgr, region->info); |
| + ret = fpga_mgr_load(region->mgr, region->info); |
| if (ret) { |
| dev_err(dev, "failed to load FPGA image\n"); |
| goto err_put_br; |
| @@ -284,8 +276,7 @@ static int fpga_region_program_fpga(struct fpga_region *region, |
| goto err_put_br; |
| } |
| |
| - fpga_mgr_unlock(mgr); |
| - fpga_mgr_put(mgr); |
| + fpga_mgr_unlock(region->mgr); |
| fpga_region_put(region); |
| |
| return 0; |
| @@ -293,9 +284,7 @@ static int fpga_region_program_fpga(struct fpga_region *region, |
| err_put_br: |
| fpga_bridges_put(®ion->bridge_list); |
| err_unlock_mgr: |
| - fpga_mgr_unlock(mgr); |
| -err_put_mgr: |
| - fpga_mgr_put(mgr); |
| + fpga_mgr_unlock(region->mgr); |
| err_put_region: |
| fpga_region_put(region); |
| |
| @@ -524,11 +513,20 @@ static int fpga_region_probe(struct platform_device *pdev) |
| struct device *dev = &pdev->dev; |
| struct device_node *np = dev->of_node; |
| struct fpga_region *region; |
| + struct fpga_manager *mgr; |
| int id, ret = 0; |
| |
| + mgr = fpga_region_get_manager(np); |
| + if (IS_ERR(mgr)) |
| + return -EPROBE_DEFER; |
| + |
| region = kzalloc(sizeof(*region), GFP_KERNEL); |
| - if (!region) |
| - return -ENOMEM; |
| + if (!region) { |
| + ret = -ENOMEM; |
| + goto err_put_mgr; |
| + } |
| + |
| + region->mgr = mgr; |
| |
| id = ida_simple_get(&fpga_region_ida, 0, 0, GFP_KERNEL); |
| if (id < 0) { |
| @@ -564,6 +562,8 @@ static int fpga_region_probe(struct platform_device *pdev) |
| ida_simple_remove(&fpga_region_ida, id); |
| err_kfree: |
| kfree(region); |
| +err_put_mgr: |
| + fpga_mgr_put(mgr); |
| |
| return ret; |
| } |
| @@ -573,6 +573,7 @@ static int fpga_region_remove(struct platform_device *pdev) |
| struct fpga_region *region = platform_get_drvdata(pdev); |
| |
| device_unregister(®ion->dev); |
| + fpga_mgr_put(region->mgr); |
| |
| return 0; |
| } |
| -- |
| 2.19.0 |
| |