From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1032243AbdDTOKw (ORCPT ); Thu, 20 Apr 2017 10:10:52 -0400 Received: from mail.kernel.org ([198.145.29.136]:60116 "EHLO mail.kernel.org" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1032189AbdDTOKp (ORCPT ); Thu, 20 Apr 2017 10:10:45 -0400 From: Alan Tull To: Moritz Fischer Cc: Alan Tull , linux-kernel@vger.kernel.org, linux-fpga@vger.kernel.org Subject: [PATCH v2 11/16] fpga: region: separate out code that parses the overlay Date: Thu, 20 Apr 2017 09:09:56 -0500 Message-Id: <1492697401-11211-12-git-send-email-atull@kernel.org> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1492697401-11211-1-git-send-email-atull@kernel.org> References: <1492697401-11211-1-git-send-email-atull@kernel.org> Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org New function of_fpga_region_parse_ov added, moving code from fpga_region_notify_pre_apply. This function gets the FPGA image info from the overlay and is able to simplify some of the logic involved. This is a baby step in refactoring the FPGA region code to separate out common code from Device Tree overlay support. Signed-off-by: Alan Tull --- v2: split out from another patch --- drivers/fpga/fpga-region.c | 129 +++++++++++++++++++++++++++------------------ 1 file changed, 77 insertions(+), 52 deletions(-) diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c index 1892126..3fd4674a 100644 --- a/drivers/fpga/fpga-region.c +++ b/drivers/fpga/fpga-region.c @@ -329,33 +329,22 @@ static int child_regions_with_firmware(struct device_node *overlay) } /** - * fpga_region_notify_pre_apply - pre-apply overlay notification - * - * @region: FPGA region that the overlay was applied to - * @nd: overlay notification data - * - * Called after when an overlay targeted to a FPGA Region is about to be - * applied. Function will check the properties that will be added to the FPGA - * region. If the checks pass, it will program the FPGA. - * - * The checks are: - * The overlay must add either firmware-name or external-fpga-config property - * to the FPGA Region. + * of_fpga_region_parse_ov - parse and check overlay applied to region * - * firmware-name : program the FPGA - * external-fpga-config : FPGA is already programmed - * encrypted-fpga-config : FPGA bitstream is encrypted - * - * The overlay can add other FPGA regions, but child FPGA regions cannot have a - * firmware-name property since those regions don't exist yet. + * @region: FPGA region + * @overlay: overlay applied to the FPGA region * - * If the overlay that breaks the rules, notifier returns an error and the - * overlay is rejected before it goes into the main tree. + * Given an overlay applied to a FPGA region, parse the FPGA image specific + * info in the overlay and do some checking. * - * Returns 0 for success or negative error code for failure. + * Returns: + * NULL if overlay doesn't direct us to program the FPGA. + * fpga_image_info struct if there is an image to program. + * error code for invalid overlay. */ -static int fpga_region_notify_pre_apply(struct fpga_region *region, - struct of_overlay_notify_data *nd) +static struct fpga_image_info *of_fpga_region_parse_ov( + struct fpga_region *region, + struct device_node *overlay) { struct device *dev = ®ion->dev; struct fpga_image_info *info; @@ -364,7 +353,7 @@ static int fpga_region_notify_pre_apply(struct fpga_region *region, if (region->info) { dev_err(dev, "Region already has overlay applied.\n"); - return -EINVAL; + return ERR_PTR(-EINVAL); } /* @@ -372,68 +361,104 @@ static int fpga_region_notify_pre_apply(struct fpga_region *region, * firmware-name property (would mean that an FPGA region that has * not been added to the live tree yet is doing FPGA programming). */ - ret = child_regions_with_firmware(nd->overlay); + ret = child_regions_with_firmware(overlay); if (ret) - return ret; + return ERR_PTR(ret); info = fpga_image_info_alloc(dev); if (!info) - return -ENOMEM; + return ERR_PTR(-ENOMEM); - info->overlay = nd->overlay; + info->overlay = overlay; /* Read FPGA region properties from the overlay */ - if (of_property_read_bool(nd->overlay, "partial-fpga-config")) + if (of_property_read_bool(overlay, "partial-fpga-config")) info->flags |= FPGA_MGR_PARTIAL_RECONFIG; - if (of_property_read_bool(nd->overlay, "external-fpga-config")) + if (of_property_read_bool(overlay, "external-fpga-config")) info->flags |= FPGA_MGR_EXTERNAL_CONFIG; - if (of_property_read_bool(nd->overlay, "encrypted-fpga-config")) + if (of_property_read_bool(overlay, "encrypted-fpga-config")) info->flags |= FPGA_MGR_ENCRYPTED_BITSTREAM; - if (!of_property_read_string(nd->overlay, "firmware-name", + if (!of_property_read_string(overlay, "firmware-name", &firmware_name)) { info->firmware_name = devm_kstrdup(dev, firmware_name, GFP_KERNEL); if (!info->firmware_name) - return -ENOMEM; + return ERR_PTR(-ENOMEM); } - of_property_read_u32(nd->overlay, "region-unfreeze-timeout-us", + of_property_read_u32(overlay, "region-unfreeze-timeout-us", &info->enable_timeout_us); - of_property_read_u32(nd->overlay, "region-freeze-timeout-us", + of_property_read_u32(overlay, "region-freeze-timeout-us", &info->disable_timeout_us); - of_property_read_u32(nd->overlay, "config-complete-timeout-us", + of_property_read_u32(overlay, "config-complete-timeout-us", &info->config_complete_timeout_us); - /* If FPGA was externally programmed, don't specify firmware */ - if ((info->flags & FPGA_MGR_EXTERNAL_CONFIG) && info->firmware_name) { - dev_err(dev, "error: specified firmware and external-fpga-config"); - fpga_image_info_free(dev, info); - return -EINVAL; + /* If overlay is not programming the FPGA, don't need FPGA image info */ + if (!info->firmware_name) { + ret = 0; + goto ret_no_info; } - /* FPGA is already configured externally. We're done. */ + /* + * If overlay informs us FPGA was externally programmed, specifying + * firmware here would be ambiguous. + */ if (info->flags & FPGA_MGR_EXTERNAL_CONFIG) { - fpga_image_info_free(®ion->dev, info); - return 0; + dev_err(dev, "error: specified firmware and external-fpga-config"); + ret = -EINVAL; + goto ret_no_info; } - /* If we got this far, we should be programming the FPGA */ - if (!info->firmware_name) { - dev_err(dev, "should specify firmware-name or external-fpga-config\n"); - fpga_image_info_free(dev, info); + return info; +ret_no_info: + fpga_image_info_free(dev, info); + return ERR_PTR(ret); +} + +/** + * fpga_region_notify_pre_apply - pre-apply overlay notification + * + * @region: FPGA region that the overlay was applied to + * @nd: overlay notification data + * + * Called when an overlay targeted to a FPGA Region is about to be applied. + * Parses the overlay for properties that influence how the FPGA will be + * programmed and does some checking. If the checks pass, programs the FPGA. + * If the checks fail, overlay is rejected and does not get added to the + * live tree. + * + * Returns 0 for success or negative error code for failure. + */ +static int fpga_region_notify_pre_apply(struct fpga_region *region, + struct of_overlay_notify_data *nd) +{ + struct device *dev = ®ion->dev; + struct fpga_image_info *info; + int ret; + + if (region->info) { + dev_err(dev, "Region already has overlay applied.\n"); return -EINVAL; } - ret = fpga_region_program_fpga(region, info); - if (ret) - fpga_image_info_free(®ion->dev, info); + info = of_fpga_region_parse_ov(region, nd->overlay); + if (IS_ERR(info)) + return PTR_ERR(info); - return ret; + if (info) { + ret = fpga_region_program_fpga(region, info); + if (ret) { + fpga_image_info_free(dev, info); + return ret; + } + } + + return 0; } /** -- 2.7.4