summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/fpga/fpga-mgr.txt119
-rw-r--r--Documentation/fpga/fpga-region.txt95
-rw-r--r--Documentation/fpga/overview.txt23
-rw-r--r--drivers/fpga/fpga-mgr.c68
-rw-r--r--drivers/fpga/fpga-region.c43
-rw-r--r--include/linux/fpga/fpga-mgr.h30
6 files changed, 273 insertions, 105 deletions
diff --git a/Documentation/fpga/fpga-mgr.txt b/Documentation/fpga/fpga-mgr.txt
index 78f197fadfd1..6ebc714f4b03 100644
--- a/Documentation/fpga/fpga-mgr.txt
+++ b/Documentation/fpga/fpga-mgr.txt
@@ -11,61 +11,53 @@ hidden away in a low level driver which registers a set of ops with the core.
11The FPGA image data itself is very manufacturer specific, but for our purposes 11The FPGA image data itself is very manufacturer specific, but for our purposes
12it's just binary data. The FPGA manager core won't parse it. 12it's just binary data. The FPGA manager core won't parse it.
13 13
14The FPGA image to be programmed can be in a scatter gather list, a single
15contiguous buffer, or a firmware file. Because allocating contiguous kernel
16memory for the buffer should be avoided, users are encouraged to use a scatter
17gather list instead if possible.
18
19The particulars for programming the image are presented in a structure (struct
20fpga_image_info). This struct contains parameters such as pointers to the
21FPGA image as well as image-specific particulars such as whether the image was
22built for full or partial reconfiguration.
14 23
15API Functions: 24API Functions:
16============== 25==============
17 26
18To program the FPGA from a file or from a buffer: 27To program the FPGA:
19------------------------------------------------- 28--------------------
20
21 int fpga_mgr_buf_load(struct fpga_manager *mgr,
22 struct fpga_image_info *info,
23 const char *buf, size_t count);
24
25Load the FPGA from an image which exists as a contiguous buffer in
26memory. Allocating contiguous kernel memory for the buffer should be avoided,
27users are encouraged to use the _sg interface instead of this.
28
29 int fpga_mgr_buf_load_sg(struct fpga_manager *mgr,
30 struct fpga_image_info *info,
31 struct sg_table *sgt);
32 29
33Load the FPGA from an image from non-contiguous in memory. Callers can 30 int fpga_mgr_load(struct fpga_manager *mgr,
34construct a sg_table using alloc_page backed memory. 31 struct fpga_image_info *info);
35 32
36 int fpga_mgr_firmware_load(struct fpga_manager *mgr, 33Load the FPGA from an image which is indicated in the info. If successful,
37 struct fpga_image_info *info,
38 const char *image_name);
39
40Load the FPGA from an image which exists as a file. The image file must be on
41the firmware search path (see the firmware class documentation). If successful,
42the FPGA ends up in operating mode. Return 0 on success or a negative error 34the FPGA ends up in operating mode. Return 0 on success or a negative error
43code. 35code.
44 36
45A FPGA design contained in a FPGA image file will likely have particulars that 37To allocate or free a struct fpga_image_info:
46affect how the image is programmed to the FPGA. These are contained in struct 38---------------------------------------------
47fpga_image_info. Currently the only such particular is a single flag bit 39
48indicating whether the image is for full or partial reconfiguration. 40 struct fpga_image_info *fpga_image_info_alloc(struct device *dev);
41
42 void fpga_image_info_free(struct fpga_image_info *info);
49 43
50To get/put a reference to a FPGA manager: 44To get/put a reference to a FPGA manager:
51----------------------------------------- 45-----------------------------------------
52 46
53 struct fpga_manager *of_fpga_mgr_get(struct device_node *node); 47 struct fpga_manager *of_fpga_mgr_get(struct device_node *node);
54 struct fpga_manager *fpga_mgr_get(struct device *dev); 48 struct fpga_manager *fpga_mgr_get(struct device *dev);
55
56Given a DT node or device, get an exclusive reference to a FPGA manager.
57
58 void fpga_mgr_put(struct fpga_manager *mgr); 49 void fpga_mgr_put(struct fpga_manager *mgr);
59 50
60Release the reference. 51Given a DT node or device, get an exclusive reference to a FPGA manager.
52fpga_mgr_put releases the reference.
61 53
62 54
63To register or unregister the low level FPGA-specific driver: 55To register or unregister the low level FPGA-specific driver:
64------------------------------------------------------------- 56-------------------------------------------------------------
65 57
66 int fpga_mgr_register(struct device *dev, const char *name, 58 int fpga_mgr_register(struct device *dev, const char *name,
67 const struct fpga_manager_ops *mops, 59 const struct fpga_manager_ops *mops,
68 void *priv); 60 void *priv);
69 61
70 void fpga_mgr_unregister(struct device *dev); 62 void fpga_mgr_unregister(struct device *dev);
71 63
@@ -78,59 +70,50 @@ How to write an image buffer to a supported FPGA
78/* Include to get the API */ 70/* Include to get the API */
79#include <linux/fpga/fpga-mgr.h> 71#include <linux/fpga/fpga-mgr.h>
80 72
81/* device node that specifies the FPGA manager to use */ 73struct fpga_manager *mgr;
82struct device_node *mgr_node = ... 74struct fpga_image_info *info;
83 75int ret;
84/* FPGA image is in this buffer. count is size of the buffer. */
85char *buf = ...
86int count = ...
87 76
88/* struct with information about the FPGA image to program. */ 77/* struct with information about the FPGA image to program. */
89struct fpga_image_info info; 78info = fpga_image_info_alloc(dev);
90 79
91/* flags indicates whether to do full or partial reconfiguration */ 80/* flags indicates whether to do full or partial reconfiguration */
92info.flags = 0; 81info->flags = FPGA_MGR_PARTIAL_RECONFIG;
93
94int ret;
95 82
96/* Get exclusive control of FPGA manager */ 83/*
97struct fpga_manager *mgr = of_fpga_mgr_get(mgr_node); 84 * At this point, indicate where the image is. This is pseudo-code; you're
85 * going to use one of these three.
86 */
87if (image is in a scatter gather table) {
98 88
99/* Load the buffer to the FPGA */ 89 info->sgt = [your scatter gather table]
100ret = fpga_mgr_buf_load(mgr, &info, buf, count);
101
102/* Release the FPGA manager */
103fpga_mgr_put(mgr);
104 90
91} else if (image is in a buffer) {
105 92
106How to write an image file to a supported FPGA 93 info->buf = [your image buffer]
107============================================== 94 info->count = [image buffer size]
108/* Include to get the API */
109#include <linux/fpga/fpga-mgr.h>
110 95
111/* device node that specifies the FPGA manager to use */ 96} else if (image is in a firmware file) {
112struct device_node *mgr_node = ...
113 97
114/* FPGA image is in this file which is in the firmware search path */ 98 info->firmware_name = devm_kstrdup(dev, firmware_name, GFP_KERNEL);
115const char *path = "fpga-image-9.rbf"
116 99
117/* struct with information about the FPGA image to program. */ 100}
118struct fpga_image_info info;
119
120/* flags indicates whether to do full or partial reconfiguration */
121info.flags = 0;
122
123int ret;
124 101
125/* Get exclusive control of FPGA manager */ 102/*
126struct fpga_manager *mgr = of_fpga_mgr_get(mgr_node); 103 * Get a reference to FPGA manager. This example uses the device node of the
104 * manager. You could use fpga_mgr_get() instead if you have the device instead
105 * of the device node.
106 */
107mgr = of_fpga_mgr_get(mgr_node);
127 108
128/* Get the firmware image (path) and load it to the FPGA */ 109/* Load the buffer to the FPGA */
129ret = fpga_mgr_firmware_load(mgr, &info, path); 110ret = fpga_mgr_buf_load(mgr, &info, buf, count);
130 111
131/* Release the FPGA manager */ 112/* Release the FPGA manager */
132fpga_mgr_put(mgr); 113fpga_mgr_put(mgr);
133 114
115/* Deallocate the image info if you're done with it */
116fpga_image_info_free(info);
134 117
135How to support a new FPGA device 118How to support a new FPGA device
136================================ 119================================
diff --git a/Documentation/fpga/fpga-region.txt b/Documentation/fpga/fpga-region.txt
new file mode 100644
index 000000000000..139a02ba1ff6
--- /dev/null
+++ b/Documentation/fpga/fpga-region.txt
@@ -0,0 +1,95 @@
1FPGA Regions
2
3Alan Tull 2017
4
5CONTENTS
6 - Introduction
7 - The FPGA region API
8 - Usage example
9
10Introduction
11============
12
13This document is meant to be an brief overview of the FPGA region API usage. A
14more conceptual look at regions can be found in [1].
15
16For the purposes of this API document, let's just say that a region associates
17an FPGA Manager and a bridge (or bridges) with a reprogrammable region of an
18FPGA or the whole FPGA. The API provides a way to register a region and to
19program a region.
20
21Currently the only layer above fpga-region.c in the kernel is the Device Tree
22support (of-fpga-region.c) described in [1]. The DT support layer uses regions
23to program the FPGA and then DT to handle enumeration. The common region code
24is intended to be used by other schemes that have other ways of accomplishing
25enumeration after programming.
26
27An fpga-region can be set up to know the following things:
28* which FPGA manager to use to do the programming
29* which bridges to disable before programming and enable afterwards.
30
31Additional info needed to program the FPGA image is passed in the struct
32fpga_image_info [2] including:
33* pointers to the image as either a scatter-gather buffer, a contiguous
34 buffer, or the name of firmware file
35* flags indicating specifics such as whether the image if for partial
36 reconfiguration.
37
38===================
39The FPGA region API
40===================
41
42To register or unregister a region:
43-----------------------------------
44
45 int fpga_region_register(struct device *dev,
46 struct fpga_region *region);
47 int fpga_region_unregister(struct fpga_region *region);
48
49An example of usage can be seen in the probe function of [3]
50
51To program an FPGA:
52-------------------
53 int fpga_region_program_fpga(struct fpga_region *region);
54
55This function operates on info passed in the fpga_image_info
56(region->info).
57
58This function will attempt to:
59 * lock the region's mutex
60 * lock the region's FPGA manager
61 * build a list of FPGA bridges if a method has been specified to do so
62 * disable the bridges
63 * program the FPGA
64 * re-enable the bridges
65 * release the locks
66
67=============
68Usage example
69=============
70
71First, allocate the info struct:
72
73 info = fpga_image_info_alloc(dev);
74 if (!info)
75 return -ENOMEM;
76
77Set flags as needed, i.e.
78
79 info->flags |= FPGA_MGR_PARTIAL_RECONFIG;
80
81Point to your FPGA image, such as:
82
83 info->sgt = &sgt;
84
85Add info to region and do the programming:
86
87 region->info = info;
88 ret = fpga_region_program_fpga(region);
89
90Then enumerate whatever hardware has appeared in the FPGA.
91
92--
93[1] ../devicetree/bindings/fpga/fpga-region.txt
94[2] ./fpga-mgr.txt
95[3] ../../drivers/fpga/of-fpga-region.c
diff --git a/Documentation/fpga/overview.txt b/Documentation/fpga/overview.txt
new file mode 100644
index 000000000000..0f1236e7e675
--- /dev/null
+++ b/Documentation/fpga/overview.txt
@@ -0,0 +1,23 @@
1Linux kernel FPGA support
2
3Alan Tull 2017
4
5The main point of this project has been to separate the out the upper layers
6that know when to reprogram a FPGA from the lower layers that know how to
7reprogram a specific FPGA device. The intention is to make this manufacturer
8agnostic, understanding that of course the FPGA images are very device specific
9themselves.
10
11The framework in the kernel includes:
12* low level FPGA manager drivers that know how to program a specific device
13* the fpga-mgr framework they are registered with
14* low level FPGA bridge drivers for hard/soft bridges which are intended to
15 be disable during FPGA programming
16* the fpga-bridge framework they are registered with
17* the fpga-region framework which associates and controls managers and bridges
18 as reconfigurable regions
19* the of-fpga-region support for reprogramming FPGAs when device tree overlays
20 are applied.
21
22I would encourage you the user to add code that creates FPGA regions rather
23that trying to control managers and bridges separately.
diff --git a/drivers/fpga/fpga-mgr.c b/drivers/fpga/fpga-mgr.c
index 188ffefa3cc3..a8dd54945470 100644
--- a/drivers/fpga/fpga-mgr.c
+++ b/drivers/fpga/fpga-mgr.c
@@ -2,6 +2,7 @@
2 * FPGA Manager Core 2 * FPGA Manager Core
3 * 3 *
4 * Copyright (C) 2013-2015 Altera Corporation 4 * Copyright (C) 2013-2015 Altera Corporation
5 * Copyright (C) 2017 Intel Corporation
5 * 6 *
6 * With code from the mailing list: 7 * With code from the mailing list:
7 * Copyright (C) 2013 Xilinx, Inc. 8 * Copyright (C) 2013 Xilinx, Inc.
@@ -31,6 +32,40 @@
31static DEFINE_IDA(fpga_mgr_ida); 32static DEFINE_IDA(fpga_mgr_ida);
32static struct class *fpga_mgr_class; 33static struct class *fpga_mgr_class;
33 34
35struct fpga_image_info *fpga_image_info_alloc(struct device *dev)
36{
37 struct fpga_image_info *info;
38
39 get_device(dev);
40
41 info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
42 if (!info) {
43 put_device(dev);
44 return NULL;
45 }
46
47 info->dev = dev;
48
49 return info;
50}
51EXPORT_SYMBOL_GPL(fpga_image_info_alloc);
52
53void fpga_image_info_free(struct fpga_image_info *info)
54{
55 struct device *dev;
56
57 if (!info)
58 return;
59
60 dev = info->dev;
61 if (info->firmware_name)
62 devm_kfree(dev, info->firmware_name);
63
64 devm_kfree(dev, info);
65 put_device(dev);
66}
67EXPORT_SYMBOL_GPL(fpga_image_info_free);
68
34/* 69/*
35 * Call the low level driver's write_init function. This will do the 70 * Call the low level driver's write_init function. This will do the
36 * device-specific things to get the FPGA into the state where it is ready to 71 * device-specific things to get the FPGA into the state where it is ready to
@@ -137,8 +172,9 @@ static int fpga_mgr_write_complete(struct fpga_manager *mgr,
137 * 172 *
138 * Return: 0 on success, negative error code otherwise. 173 * Return: 0 on success, negative error code otherwise.
139 */ 174 */
140int fpga_mgr_buf_load_sg(struct fpga_manager *mgr, struct fpga_image_info *info, 175static int fpga_mgr_buf_load_sg(struct fpga_manager *mgr,
141 struct sg_table *sgt) 176 struct fpga_image_info *info,
177 struct sg_table *sgt)
142{ 178{
143 int ret; 179 int ret;
144 180
@@ -170,7 +206,6 @@ int fpga_mgr_buf_load_sg(struct fpga_manager *mgr, struct fpga_image_info *info,
170 206
171 return fpga_mgr_write_complete(mgr, info); 207 return fpga_mgr_write_complete(mgr, info);
172} 208}
173EXPORT_SYMBOL_GPL(fpga_mgr_buf_load_sg);
174 209
175static int fpga_mgr_buf_load_mapped(struct fpga_manager *mgr, 210static int fpga_mgr_buf_load_mapped(struct fpga_manager *mgr,
176 struct fpga_image_info *info, 211 struct fpga_image_info *info,
@@ -210,8 +245,9 @@ static int fpga_mgr_buf_load_mapped(struct fpga_manager *mgr,
210 * 245 *
211 * Return: 0 on success, negative error code otherwise. 246 * Return: 0 on success, negative error code otherwise.
212 */ 247 */
213int fpga_mgr_buf_load(struct fpga_manager *mgr, struct fpga_image_info *info, 248static int fpga_mgr_buf_load(struct fpga_manager *mgr,
214 const char *buf, size_t count) 249 struct fpga_image_info *info,
250 const char *buf, size_t count)
215{ 251{
216 struct page **pages; 252 struct page **pages;
217 struct sg_table sgt; 253 struct sg_table sgt;
@@ -266,7 +302,6 @@ int fpga_mgr_buf_load(struct fpga_manager *mgr, struct fpga_image_info *info,
266 302
267 return rc; 303 return rc;
268} 304}
269EXPORT_SYMBOL_GPL(fpga_mgr_buf_load);
270 305
271/** 306/**
272 * fpga_mgr_firmware_load - request firmware and load to fpga 307 * fpga_mgr_firmware_load - request firmware and load to fpga
@@ -282,9 +317,9 @@ EXPORT_SYMBOL_GPL(fpga_mgr_buf_load);
282 * 317 *
283 * Return: 0 on success, negative error code otherwise. 318 * Return: 0 on success, negative error code otherwise.
284 */ 319 */
285int fpga_mgr_firmware_load(struct fpga_manager *mgr, 320static int fpga_mgr_firmware_load(struct fpga_manager *mgr,
286 struct fpga_image_info *info, 321 struct fpga_image_info *info,
287 const char *image_name) 322 const char *image_name)
288{ 323{
289 struct device *dev = &mgr->dev; 324 struct device *dev = &mgr->dev;
290 const struct firmware *fw; 325 const struct firmware *fw;
@@ -307,7 +342,18 @@ int fpga_mgr_firmware_load(struct fpga_manager *mgr,
307 342
308 return ret; 343 return ret;
309} 344}
310EXPORT_SYMBOL_GPL(fpga_mgr_firmware_load); 345
346int fpga_mgr_load(struct fpga_manager *mgr, struct fpga_image_info *info)
347{
348 if (info->sgt)
349 return fpga_mgr_buf_load_sg(mgr, info, info->sgt);
350 if (info->buf && info->count)
351 return fpga_mgr_buf_load(mgr, info, info->buf, info->count);
352 if (info->firmware_name)
353 return fpga_mgr_firmware_load(mgr, info, info->firmware_name);
354 return -EINVAL;
355}
356EXPORT_SYMBOL_GPL(fpga_mgr_load);
311 357
312static const char * const state_str[] = { 358static const char * const state_str[] = {
313 [FPGA_MGR_STATE_UNKNOWN] = "unknown", 359 [FPGA_MGR_STATE_UNKNOWN] = "unknown",
@@ -578,7 +624,7 @@ static void __exit fpga_mgr_class_exit(void)
578 ida_destroy(&fpga_mgr_ida); 624 ida_destroy(&fpga_mgr_ida);
579} 625}
580 626
581MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>"); 627MODULE_AUTHOR("Alan Tull <atull@kernel.org>");
582MODULE_DESCRIPTION("FPGA manager framework"); 628MODULE_DESCRIPTION("FPGA manager framework");
583MODULE_LICENSE("GPL v2"); 629MODULE_LICENSE("GPL v2");
584 630
diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
index 9175556215b1..120c496eb7bd 100644
--- a/drivers/fpga/fpga-region.c
+++ b/drivers/fpga/fpga-region.c
@@ -226,14 +226,11 @@ static int fpga_region_get_bridges(struct fpga_region *region,
226/** 226/**
227 * fpga_region_program_fpga - program FPGA 227 * fpga_region_program_fpga - program FPGA
228 * @region: FPGA region 228 * @region: FPGA region
229 * @firmware_name: name of FPGA image firmware file
230 * @overlay: device node of the overlay 229 * @overlay: device node of the overlay
231 * Program an FPGA using information in the device tree. 230 * Program an FPGA using information in the region's fpga image info.
232 * Function assumes that there is a firmware-name property.
233 * Return 0 for success or negative error code. 231 * Return 0 for success or negative error code.
234 */ 232 */
235static int fpga_region_program_fpga(struct fpga_region *region, 233static int fpga_region_program_fpga(struct fpga_region *region,
236 const char *firmware_name,
237 struct device_node *overlay) 234 struct device_node *overlay)
238{ 235{
239 struct fpga_manager *mgr; 236 struct fpga_manager *mgr;
@@ -264,7 +261,7 @@ static int fpga_region_program_fpga(struct fpga_region *region,
264 goto err_put_br; 261 goto err_put_br;
265 } 262 }
266 263
267 ret = fpga_mgr_firmware_load(mgr, region->info, firmware_name); 264 ret = fpga_mgr_load(mgr, region->info);
268 if (ret) { 265 if (ret) {
269 pr_err("failed to load fpga image\n"); 266 pr_err("failed to load fpga image\n");
270 goto err_put_br; 267 goto err_put_br;
@@ -357,16 +354,15 @@ static int child_regions_with_firmware(struct device_node *overlay)
357static int fpga_region_notify_pre_apply(struct fpga_region *region, 354static int fpga_region_notify_pre_apply(struct fpga_region *region,
358 struct of_overlay_notify_data *nd) 355 struct of_overlay_notify_data *nd)
359{ 356{
360 const char *firmware_name = NULL; 357 struct device *dev = &region->dev;
361 struct fpga_image_info *info; 358 struct fpga_image_info *info;
359 const char *firmware_name;
362 int ret; 360 int ret;
363 361
364 info = devm_kzalloc(&region->dev, sizeof(*info), GFP_KERNEL); 362 info = fpga_image_info_alloc(dev);
365 if (!info) 363 if (!info)
366 return -ENOMEM; 364 return -ENOMEM;
367 365
368 region->info = info;
369
370 /* Reject overlay if child FPGA Regions have firmware-name property */ 366 /* Reject overlay if child FPGA Regions have firmware-name property */
371 ret = child_regions_with_firmware(nd->overlay); 367 ret = child_regions_with_firmware(nd->overlay);
372 if (ret) 368 if (ret)
@@ -382,7 +378,13 @@ static int fpga_region_notify_pre_apply(struct fpga_region *region,
382 if (of_property_read_bool(nd->overlay, "encrypted-fpga-config")) 378 if (of_property_read_bool(nd->overlay, "encrypted-fpga-config"))
383 info->flags |= FPGA_MGR_ENCRYPTED_BITSTREAM; 379 info->flags |= FPGA_MGR_ENCRYPTED_BITSTREAM;
384 380
385 of_property_read_string(nd->overlay, "firmware-name", &firmware_name); 381 if (!of_property_read_string(nd->overlay, "firmware-name",
382 &firmware_name)) {
383 info->firmware_name = devm_kstrdup(dev, firmware_name,
384 GFP_KERNEL);
385 if (!info->firmware_name)
386 return -ENOMEM;
387 }
386 388
387 of_property_read_u32(nd->overlay, "region-unfreeze-timeout-us", 389 of_property_read_u32(nd->overlay, "region-unfreeze-timeout-us",
388 &info->enable_timeout_us); 390 &info->enable_timeout_us);
@@ -394,22 +396,33 @@ static int fpga_region_notify_pre_apply(struct fpga_region *region,
394 &info->config_complete_timeout_us); 396 &info->config_complete_timeout_us);
395 397
396 /* If FPGA was externally programmed, don't specify firmware */ 398 /* If FPGA was externally programmed, don't specify firmware */
397 if ((info->flags & FPGA_MGR_EXTERNAL_CONFIG) && firmware_name) { 399 if ((info->flags & FPGA_MGR_EXTERNAL_CONFIG) && info->firmware_name) {
398 pr_err("error: specified firmware and external-fpga-config"); 400 pr_err("error: specified firmware and external-fpga-config");
401 fpga_image_info_free(info);
399 return -EINVAL; 402 return -EINVAL;
400 } 403 }
401 404
402 /* FPGA is already configured externally. We're done. */ 405 /* FPGA is already configured externally. We're done. */
403 if (info->flags & FPGA_MGR_EXTERNAL_CONFIG) 406 if (info->flags & FPGA_MGR_EXTERNAL_CONFIG) {
407 fpga_image_info_free(info);
404 return 0; 408 return 0;
409 }
405 410
406 /* If we got this far, we should be programming the FPGA */ 411 /* If we got this far, we should be programming the FPGA */
407 if (!firmware_name) { 412 if (!info->firmware_name) {
408 pr_err("should specify firmware-name or external-fpga-config\n"); 413 pr_err("should specify firmware-name or external-fpga-config\n");
414 fpga_image_info_free(info);
409 return -EINVAL; 415 return -EINVAL;
410 } 416 }
411 417
412 return fpga_region_program_fpga(region, firmware_name, nd->overlay); 418 region->info = info;
419 ret = fpga_region_program_fpga(region, nd->overlay);
420 if (ret) {
421 fpga_image_info_free(info);
422 region->info = NULL;
423 }
424
425 return ret;
413} 426}
414 427
415/** 428/**
@@ -426,7 +439,7 @@ static void fpga_region_notify_post_remove(struct fpga_region *region,
426{ 439{
427 fpga_bridges_disable(&region->bridge_list); 440 fpga_bridges_disable(&region->bridge_list);
428 fpga_bridges_put(&region->bridge_list); 441 fpga_bridges_put(&region->bridge_list);
429 devm_kfree(&region->dev, region->info); 442 fpga_image_info_free(region->info);
430 region->info = NULL; 443 region->info = NULL;
431} 444}
432 445
diff --git a/include/linux/fpga/fpga-mgr.h b/include/linux/fpga/fpga-mgr.h
index bfa14bc023fb..6b791348023b 100644
--- a/include/linux/fpga/fpga-mgr.h
+++ b/include/linux/fpga/fpga-mgr.h
@@ -1,7 +1,8 @@
1/* 1/*
2 * FPGA Framework 2 * FPGA Framework
3 * 3 *
4 * Copyright (C) 2013-2015 Altera Corporation 4 * Copyright (C) 2013-2016 Altera Corporation
5 * Copyright (C) 2017 Intel Corporation
5 * 6 *
6 * This program is free software; you can redistribute it and/or modify it 7 * This program is free software; you can redistribute it and/or modify it
7 * under the terms and conditions of the GNU General Public License, 8 * under the terms and conditions of the GNU General Public License,
@@ -15,12 +16,12 @@
15 * You should have received a copy of the GNU General Public License along with 16 * You should have received a copy of the GNU General Public License along with
16 * this program. If not, see <http://www.gnu.org/licenses/>. 17 * this program. If not, see <http://www.gnu.org/licenses/>.
17 */ 18 */
18#include <linux/mutex.h>
19#include <linux/platform_device.h>
20
21#ifndef _LINUX_FPGA_MGR_H 19#ifndef _LINUX_FPGA_MGR_H
22#define _LINUX_FPGA_MGR_H 20#define _LINUX_FPGA_MGR_H
23 21
22#include <linux/mutex.h>
23#include <linux/platform_device.h>
24
24struct fpga_manager; 25struct fpga_manager;
25struct sg_table; 26struct sg_table;
26 27
@@ -83,12 +84,22 @@ enum fpga_mgr_states {
83 * @disable_timeout_us: maximum time to disable traffic through bridge (uSec) 84 * @disable_timeout_us: maximum time to disable traffic through bridge (uSec)
84 * @config_complete_timeout_us: maximum time for FPGA to switch to operating 85 * @config_complete_timeout_us: maximum time for FPGA to switch to operating
85 * status in the write_complete op. 86 * status in the write_complete op.
87 * @firmware_name: name of FPGA image firmware file
88 * @sgt: scatter/gather table containing FPGA image
89 * @buf: contiguous buffer containing FPGA image
90 * @count: size of buf
91 * @dev: device that owns this
86 */ 92 */
87struct fpga_image_info { 93struct fpga_image_info {
88 u32 flags; 94 u32 flags;
89 u32 enable_timeout_us; 95 u32 enable_timeout_us;
90 u32 disable_timeout_us; 96 u32 disable_timeout_us;
91 u32 config_complete_timeout_us; 97 u32 config_complete_timeout_us;
98 char *firmware_name;
99 struct sg_table *sgt;
100 const char *buf;
101 size_t count;
102 struct device *dev;
92}; 103};
93 104
94/** 105/**
@@ -138,14 +149,11 @@ struct fpga_manager {
138 149
139#define to_fpga_manager(d) container_of(d, struct fpga_manager, dev) 150#define to_fpga_manager(d) container_of(d, struct fpga_manager, dev)
140 151
141int fpga_mgr_buf_load(struct fpga_manager *mgr, struct fpga_image_info *info, 152struct fpga_image_info *fpga_image_info_alloc(struct device *dev);
142 const char *buf, size_t count); 153
143int fpga_mgr_buf_load_sg(struct fpga_manager *mgr, struct fpga_image_info *info, 154void fpga_image_info_free(struct fpga_image_info *info);
144 struct sg_table *sgt);
145 155
146int fpga_mgr_firmware_load(struct fpga_manager *mgr, 156int fpga_mgr_load(struct fpga_manager *mgr, struct fpga_image_info *info);
147 struct fpga_image_info *info,
148 const char *image_name);
149 157
150struct fpga_manager *of_fpga_mgr_get(struct device_node *node); 158struct fpga_manager *of_fpga_mgr_get(struct device_node *node);
151 159