aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/fpga/fpga-region.c
diff options
context:
space:
mode:
authorAlan Tull <atull@kernel.org>2017-11-15 15:20:20 -0500
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2017-11-28 10:30:37 -0500
commitc8898eda81e0b949ca214e1a45ce1b56677eb849 (patch)
tree448d586adecd41d97ba4d2a2f1163f7979f781fe /drivers/fpga/fpga-region.c
parent61c32102391ff38dfd4aba835dd0f99db6b46908 (diff)
fpga: region: separate out code that parses the overlay
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 <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.c122
1 files changed, 73 insertions, 49 deletions
diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
index eaacf5049381..2a8621db5f5b 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)
321} 321}
322 322
323/** 323/**
324 * fpga_region_notify_pre_apply - pre-apply overlay notification 324 * of_fpga_region_parse_ov - parse and check overlay applied to region
325 *
326 * @region: FPGA region that the overlay was applied to
327 * @nd: overlay notification data
328 *
329 * Called after when an overlay targeted to a FPGA Region is about to be
330 * applied. Function will check the properties that will be added to the FPGA
331 * region. If the checks pass, it will program the FPGA.
332 *
333 * The checks are:
334 * The overlay must add either firmware-name or external-fpga-config property
335 * to the FPGA Region.
336 *
337 * firmware-name : program the FPGA
338 * external-fpga-config : FPGA is already programmed
339 * encrypted-fpga-config : FPGA bitstream is encrypted
340 * 325 *
341 * The overlay can add other FPGA regions, but child FPGA regions cannot have a 326 * @region: FPGA region
342 * firmware-name property since those regions don't exist yet. 327 * @overlay: overlay applied to the FPGA region
343 * 328 *
344 * If the overlay that breaks the rules, notifier returns an error and the 329 * Given an overlay applied to a FPGA region, parse the FPGA image specific
345 * overlay is rejected before it goes into the main tree. 330 * info in the overlay and do some checking.
346 * 331 *
347 * Returns 0 for success or negative error code for failure. 332 * Returns:
333 * NULL if overlay doesn't direct us to program the FPGA.
334 * fpga_image_info struct if there is an image to program.
335 * error code for invalid overlay.
348 */ 336 */
349static int fpga_region_notify_pre_apply(struct fpga_region *region, 337static struct fpga_image_info *of_fpga_region_parse_ov(
350 struct of_overlay_notify_data *nd) 338 struct fpga_region *region,
339 struct device_node *overlay)
351{ 340{
352 struct device *dev = &region->dev; 341 struct device *dev = &region->dev;
353 struct fpga_image_info *info; 342 struct fpga_image_info *info;
@@ -356,7 +345,7 @@ static int fpga_region_notify_pre_apply(struct fpga_region *region,
356 345
357 if (region->info) { 346 if (region->info) {
358 dev_err(dev, "Region already has overlay applied.\n"); 347 dev_err(dev, "Region already has overlay applied.\n");
359 return -EINVAL; 348 return ERR_PTR(-EINVAL);
360 } 349 }
361 350
362 /* 351 /*
@@ -364,67 +353,102 @@ static int fpga_region_notify_pre_apply(struct fpga_region *region,
364 * firmware-name property (would mean that an FPGA region that has 353 * firmware-name property (would mean that an FPGA region that has
365 * not been added to the live tree yet is doing FPGA programming). 354 * not been added to the live tree yet is doing FPGA programming).
366 */ 355 */
367 ret = child_regions_with_firmware(nd->overlay); 356 ret = child_regions_with_firmware(overlay);
368 if (ret) 357 if (ret)
369 return ret; 358 return ERR_PTR(ret);
370 359
371 info = fpga_image_info_alloc(dev); 360 info = fpga_image_info_alloc(dev);
372 if (!info) 361 if (!info)
373 return -ENOMEM; 362 return ERR_PTR(-ENOMEM);
374 363
375 info->overlay = nd->overlay; 364 info->overlay = overlay;
376 365
377 /* Read FPGA region properties from the overlay */ 366 /* Read FPGA region properties from the overlay */
378 if (of_property_read_bool(nd->overlay, "partial-fpga-config")) 367 if (of_property_read_bool(overlay, "partial-fpga-config"))
379 info->flags |= FPGA_MGR_PARTIAL_RECONFIG; 368 info->flags |= FPGA_MGR_PARTIAL_RECONFIG;
380 369
381 if (of_property_read_bool(nd->overlay, "external-fpga-config")) 370 if (of_property_read_bool(overlay, "external-fpga-config"))
382 info->flags |= FPGA_MGR_EXTERNAL_CONFIG; 371 info->flags |= FPGA_MGR_EXTERNAL_CONFIG;
383 372
384 if (of_property_read_bool(nd->overlay, "encrypted-fpga-config")) 373 if (of_property_read_bool(overlay, "encrypted-fpga-config"))
385 info->flags |= FPGA_MGR_ENCRYPTED_BITSTREAM; 374 info->flags |= FPGA_MGR_ENCRYPTED_BITSTREAM;
386 375
387 if (!of_property_read_string(nd->overlay, "firmware-name", 376 if (!of_property_read_string(overlay, "firmware-name",
388 &firmware_name)) { 377 &firmware_name)) {
389 info->firmware_name = devm_kstrdup(dev, firmware_name, 378 info->firmware_name = devm_kstrdup(dev, firmware_name,
390 GFP_KERNEL); 379 GFP_KERNEL);
391 if (!info->firmware_name) 380 if (!info->firmware_name)
392 return -ENOMEM; 381 return ERR_PTR(-ENOMEM);
393 } 382 }
394 383
395 of_property_read_u32(nd->overlay, "region-unfreeze-timeout-us", 384 of_property_read_u32(overlay, "region-unfreeze-timeout-us",
396 &info->enable_timeout_us); 385 &info->enable_timeout_us);
397 386
398 of_property_read_u32(nd->overlay, "region-freeze-timeout-us", 387 of_property_read_u32(overlay, "region-freeze-timeout-us",
399 &info->disable_timeout_us); 388 &info->disable_timeout_us);
400 389
401 of_property_read_u32(nd->overlay, "config-complete-timeout-us", 390 of_property_read_u32(overlay, "config-complete-timeout-us",
402 &info->config_complete_timeout_us); 391 &info->config_complete_timeout_us);
403 392
404 /* If FPGA was externally programmed, don't specify firmware */ 393 /* If overlay is not programming the FPGA, don't need FPGA image info */
405 if ((info->flags & FPGA_MGR_EXTERNAL_CONFIG) && info->firmware_name) { 394 if (!info->firmware_name) {
406 dev_err(dev, "error: specified firmware and external-fpga-config"); 395 ret = 0;
407 fpga_image_info_free(info); 396 goto ret_no_info;
408 return -EINVAL;
409 } 397 }
410 398
411 /* FPGA is already configured externally. We're done. */ 399 /*
400 * If overlay informs us FPGA was externally programmed, specifying
401 * firmware here would be ambiguous.
402 */
412 if (info->flags & FPGA_MGR_EXTERNAL_CONFIG) { 403 if (info->flags & FPGA_MGR_EXTERNAL_CONFIG) {
413 fpga_image_info_free(info); 404 dev_err(dev, "error: specified firmware and external-fpga-config");
414 return 0; 405 ret = -EINVAL;
406 goto ret_no_info;
415 } 407 }
416 408
417 /* If we got this far, we should be programming the FPGA */ 409 return info;
418 if (!info->firmware_name) { 410ret_no_info:
419 dev_err(dev, "should specify firmware-name or external-fpga-config\n"); 411 fpga_image_info_free(info);
420 fpga_image_info_free(info); 412 return ERR_PTR(ret);
413}
414
415/**
416 * fpga_region_notify_pre_apply - pre-apply overlay notification
417 *
418 * @region: FPGA region that the overlay was applied to
419 * @nd: overlay notification data
420 *
421 * Called when an overlay targeted to a FPGA Region is about to be applied.
422 * Parses the overlay for properties that influence how the FPGA will be
423 * programmed and does some checking. If the checks pass, programs the FPGA.
424 * If the checks fail, overlay is rejected and does not get added to the
425 * live tree.
426 *
427 * Returns 0 for success or negative error code for failure.
428 */
429static int fpga_region_notify_pre_apply(struct fpga_region *region,
430 struct of_overlay_notify_data *nd)
431{
432 struct device *dev = &region->dev;
433 struct fpga_image_info *info;
434 int ret;
435
436 if (region->info) {
437 dev_err(dev, "Region already has overlay applied.\n");
421 return -EINVAL; 438 return -EINVAL;
422 } 439 }
423 440
424 region->info = info; 441 info = of_fpga_region_parse_ov(region, nd->overlay);
442 if (IS_ERR(info))
443 return PTR_ERR(info);
444
445 if (!info)
446 return 0;
425 447
448 region->info = info;
426 ret = fpga_region_program_fpga(region); 449 ret = fpga_region_program_fpga(region);
427 if (ret) { 450 if (ret) {
451 /* error; reject overlay */
428 fpga_image_info_free(info); 452 fpga_image_info_free(info);
429 region->info = NULL; 453 region->info = NULL;
430 } 454 }