On Tue, Oct 17, 2017 at 04:20:23PM -0500, Alan Tull wrote:
> 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 <at...@kernel.org>
Acked-by: Moritz Fischer <m...@kernel.org>
> ---
> v2: split out from another patch
> v3: update comments
>     minor changes in flow
> v4: no change to this patch in this version of patchset
> v5: no change to this patch in this version of patchset
> ---
>  drivers/fpga/fpga-region.c | 122 
> +++++++++++++++++++++++++++------------------
>  1 file changed, 73 insertions(+), 49 deletions(-)
> 
> diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
> index eaacf50..2a8621d 100644
> --- a/drivers/fpga/fpga-region.c
> +++ b/drivers/fpga/fpga-region.c
> @@ -321,33 +321,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.
> - *
> - *   firmware-name         : program the FPGA
> - *   external-fpga-config  : FPGA is already programmed
> - *   encrypted-fpga-config : FPGA bitstream is encrypted
> + * of_fpga_region_parse_ov - parse and check overlay applied to region
>   *
> - * 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 = &region->dev;
>       struct fpga_image_info *info;
> @@ -356,7 +345,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);
>       }
>  
>       /*
> @@ -364,67 +353,102 @@ 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(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(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(info);
> +     return info;
> +ret_no_info:
> +     fpga_image_info_free(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 = &region->dev;
> +     struct fpga_image_info *info;
> +     int ret;
> +
> +     if (region->info) {
> +             dev_err(dev, "Region already has overlay applied.\n");
>               return -EINVAL;
>       }
>  
> -     region->info = info;
> +     info = of_fpga_region_parse_ov(region, nd->overlay);
> +     if (IS_ERR(info))
> +             return PTR_ERR(info);
> +
> +     if (!info)
> +             return 0;
>  
> +     region->info = info;
>       ret = fpga_region_program_fpga(region);
>       if (ret) {
> +             /* error; reject overlay */
>               fpga_image_info_free(info);
>               region->info = NULL;
>       }
> -- 
> 2.7.4
> 

Reply via email to