diff options
-rw-r--r-- | Documentation/fpga/fpga-mgr.txt | 119 | ||||
-rw-r--r-- | Documentation/fpga/fpga-region.txt | 95 | ||||
-rw-r--r-- | Documentation/fpga/overview.txt | 23 | ||||
-rw-r--r-- | drivers/fpga/fpga-mgr.c | 68 | ||||
-rw-r--r-- | drivers/fpga/fpga-region.c | 43 | ||||
-rw-r--r-- | include/linux/fpga/fpga-mgr.h | 30 |
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. | |||
11 | The FPGA image data itself is very manufacturer specific, but for our purposes | 11 | The FPGA image data itself is very manufacturer specific, but for our purposes |
12 | it's just binary data. The FPGA manager core won't parse it. | 12 | it's just binary data. The FPGA manager core won't parse it. |
13 | 13 | ||
14 | The FPGA image to be programmed can be in a scatter gather list, a single | ||
15 | contiguous buffer, or a firmware file. Because allocating contiguous kernel | ||
16 | memory for the buffer should be avoided, users are encouraged to use a scatter | ||
17 | gather list instead if possible. | ||
18 | |||
19 | The particulars for programming the image are presented in a structure (struct | ||
20 | fpga_image_info). This struct contains parameters such as pointers to the | ||
21 | FPGA image as well as image-specific particulars such as whether the image was | ||
22 | built for full or partial reconfiguration. | ||
14 | 23 | ||
15 | API Functions: | 24 | API Functions: |
16 | ============== | 25 | ============== |
17 | 26 | ||
18 | To program the FPGA from a file or from a buffer: | 27 | To 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 | |||
25 | Load the FPGA from an image which exists as a contiguous buffer in | ||
26 | memory. Allocating contiguous kernel memory for the buffer should be avoided, | ||
27 | users 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 | ||
33 | Load the FPGA from an image from non-contiguous in memory. Callers can | 30 | int fpga_mgr_load(struct fpga_manager *mgr, |
34 | construct 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, | 33 | Load 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 | |||
40 | Load the FPGA from an image which exists as a file. The image file must be on | ||
41 | the firmware search path (see the firmware class documentation). If successful, | ||
42 | the FPGA ends up in operating mode. Return 0 on success or a negative error | 34 | the FPGA ends up in operating mode. Return 0 on success or a negative error |
43 | code. | 35 | code. |
44 | 36 | ||
45 | A FPGA design contained in a FPGA image file will likely have particulars that | 37 | To allocate or free a struct fpga_image_info: |
46 | affect how the image is programmed to the FPGA. These are contained in struct | 38 | --------------------------------------------- |
47 | fpga_image_info. Currently the only such particular is a single flag bit | 39 | |
48 | indicating 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 | ||
50 | To get/put a reference to a FPGA manager: | 44 | To 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 | |||
56 | Given 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 | ||
60 | Release the reference. | 51 | Given a DT node or device, get an exclusive reference to a FPGA manager. |
52 | fpga_mgr_put releases the reference. | ||
61 | 53 | ||
62 | 54 | ||
63 | To register or unregister the low level FPGA-specific driver: | 55 | To 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 */ | 73 | struct fpga_manager *mgr; |
82 | struct device_node *mgr_node = ... | 74 | struct fpga_image_info *info; |
83 | 75 | int ret; | |
84 | /* FPGA image is in this buffer. count is size of the buffer. */ | ||
85 | char *buf = ... | ||
86 | int count = ... | ||
87 | 76 | ||
88 | /* struct with information about the FPGA image to program. */ | 77 | /* struct with information about the FPGA image to program. */ |
89 | struct fpga_image_info info; | 78 | info = 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 */ |
92 | info.flags = 0; | 81 | info->flags = FPGA_MGR_PARTIAL_RECONFIG; |
93 | |||
94 | int ret; | ||
95 | 82 | ||
96 | /* Get exclusive control of FPGA manager */ | 83 | /* |
97 | struct 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 | */ | ||
87 | if (image is in a scatter gather table) { | ||
98 | 88 | ||
99 | /* Load the buffer to the FPGA */ | 89 | info->sgt = [your scatter gather table] |
100 | ret = fpga_mgr_buf_load(mgr, &info, buf, count); | ||
101 | |||
102 | /* Release the FPGA manager */ | ||
103 | fpga_mgr_put(mgr); | ||
104 | 90 | ||
91 | } else if (image is in a buffer) { | ||
105 | 92 | ||
106 | How 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) { |
112 | struct 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); |
115 | const char *path = "fpga-image-9.rbf" | ||
116 | 99 | ||
117 | /* struct with information about the FPGA image to program. */ | 100 | } |
118 | struct fpga_image_info info; | ||
119 | |||
120 | /* flags indicates whether to do full or partial reconfiguration */ | ||
121 | info.flags = 0; | ||
122 | |||
123 | int ret; | ||
124 | 101 | ||
125 | /* Get exclusive control of FPGA manager */ | 102 | /* |
126 | struct 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 | */ | ||
107 | mgr = 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 */ |
129 | ret = fpga_mgr_firmware_load(mgr, &info, path); | 110 | ret = fpga_mgr_buf_load(mgr, &info, buf, count); |
130 | 111 | ||
131 | /* Release the FPGA manager */ | 112 | /* Release the FPGA manager */ |
132 | fpga_mgr_put(mgr); | 113 | fpga_mgr_put(mgr); |
133 | 114 | ||
115 | /* Deallocate the image info if you're done with it */ | ||
116 | fpga_image_info_free(info); | ||
134 | 117 | ||
135 | How to support a new FPGA device | 118 | How 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 @@ | |||
1 | FPGA Regions | ||
2 | |||
3 | Alan Tull 2017 | ||
4 | |||
5 | CONTENTS | ||
6 | - Introduction | ||
7 | - The FPGA region API | ||
8 | - Usage example | ||
9 | |||
10 | Introduction | ||
11 | ============ | ||
12 | |||
13 | This document is meant to be an brief overview of the FPGA region API usage. A | ||
14 | more conceptual look at regions can be found in [1]. | ||
15 | |||
16 | For the purposes of this API document, let's just say that a region associates | ||
17 | an FPGA Manager and a bridge (or bridges) with a reprogrammable region of an | ||
18 | FPGA or the whole FPGA. The API provides a way to register a region and to | ||
19 | program a region. | ||
20 | |||
21 | Currently the only layer above fpga-region.c in the kernel is the Device Tree | ||
22 | support (of-fpga-region.c) described in [1]. The DT support layer uses regions | ||
23 | to program the FPGA and then DT to handle enumeration. The common region code | ||
24 | is intended to be used by other schemes that have other ways of accomplishing | ||
25 | enumeration after programming. | ||
26 | |||
27 | An 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 | |||
31 | Additional info needed to program the FPGA image is passed in the struct | ||
32 | fpga_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 | =================== | ||
39 | The FPGA region API | ||
40 | =================== | ||
41 | |||
42 | To 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 | |||
49 | An example of usage can be seen in the probe function of [3] | ||
50 | |||
51 | To program an FPGA: | ||
52 | ------------------- | ||
53 | int fpga_region_program_fpga(struct fpga_region *region); | ||
54 | |||
55 | This function operates on info passed in the fpga_image_info | ||
56 | (region->info). | ||
57 | |||
58 | This 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 | ============= | ||
68 | Usage example | ||
69 | ============= | ||
70 | |||
71 | First, allocate the info struct: | ||
72 | |||
73 | info = fpga_image_info_alloc(dev); | ||
74 | if (!info) | ||
75 | return -ENOMEM; | ||
76 | |||
77 | Set flags as needed, i.e. | ||
78 | |||
79 | info->flags |= FPGA_MGR_PARTIAL_RECONFIG; | ||
80 | |||
81 | Point to your FPGA image, such as: | ||
82 | |||
83 | info->sgt = &sgt; | ||
84 | |||
85 | Add info to region and do the programming: | ||
86 | |||
87 | region->info = info; | ||
88 | ret = fpga_region_program_fpga(region); | ||
89 | |||
90 | Then 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 @@ | |||
1 | Linux kernel FPGA support | ||
2 | |||
3 | Alan Tull 2017 | ||
4 | |||
5 | The main point of this project has been to separate the out the upper layers | ||
6 | that know when to reprogram a FPGA from the lower layers that know how to | ||
7 | reprogram a specific FPGA device. The intention is to make this manufacturer | ||
8 | agnostic, understanding that of course the FPGA images are very device specific | ||
9 | themselves. | ||
10 | |||
11 | The 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 | |||
22 | I would encourage you the user to add code that creates FPGA regions rather | ||
23 | that 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 @@ | |||
31 | static DEFINE_IDA(fpga_mgr_ida); | 32 | static DEFINE_IDA(fpga_mgr_ida); |
32 | static struct class *fpga_mgr_class; | 33 | static struct class *fpga_mgr_class; |
33 | 34 | ||
35 | struct 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 | } | ||
51 | EXPORT_SYMBOL_GPL(fpga_image_info_alloc); | ||
52 | |||
53 | void 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 | } | ||
67 | EXPORT_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 | */ |
140 | int fpga_mgr_buf_load_sg(struct fpga_manager *mgr, struct fpga_image_info *info, | 175 | static 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 | } |
173 | EXPORT_SYMBOL_GPL(fpga_mgr_buf_load_sg); | ||
174 | 209 | ||
175 | static int fpga_mgr_buf_load_mapped(struct fpga_manager *mgr, | 210 | static 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 | */ |
213 | int fpga_mgr_buf_load(struct fpga_manager *mgr, struct fpga_image_info *info, | 248 | static 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 | } |
269 | EXPORT_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 | */ |
285 | int fpga_mgr_firmware_load(struct fpga_manager *mgr, | 320 | static 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 | } |
310 | EXPORT_SYMBOL_GPL(fpga_mgr_firmware_load); | 345 | |
346 | int 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 | } | ||
356 | EXPORT_SYMBOL_GPL(fpga_mgr_load); | ||
311 | 357 | ||
312 | static const char * const state_str[] = { | 358 | static 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 | ||
581 | MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>"); | 627 | MODULE_AUTHOR("Alan Tull <atull@kernel.org>"); |
582 | MODULE_DESCRIPTION("FPGA manager framework"); | 628 | MODULE_DESCRIPTION("FPGA manager framework"); |
583 | MODULE_LICENSE("GPL v2"); | 629 | MODULE_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 | */ |
235 | static int fpga_region_program_fpga(struct fpga_region *region, | 233 | static 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) | |||
357 | static int fpga_region_notify_pre_apply(struct fpga_region *region, | 354 | static 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 = ®ion->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(®ion->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(®ion->bridge_list); | 440 | fpga_bridges_disable(®ion->bridge_list); |
428 | fpga_bridges_put(®ion->bridge_list); | 441 | fpga_bridges_put(®ion->bridge_list); |
429 | devm_kfree(®ion->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 | |||
24 | struct fpga_manager; | 25 | struct fpga_manager; |
25 | struct sg_table; | 26 | struct 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 | */ |
87 | struct fpga_image_info { | 93 | struct 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 | ||
141 | int fpga_mgr_buf_load(struct fpga_manager *mgr, struct fpga_image_info *info, | 152 | struct fpga_image_info *fpga_image_info_alloc(struct device *dev); |
142 | const char *buf, size_t count); | 153 | |
143 | int fpga_mgr_buf_load_sg(struct fpga_manager *mgr, struct fpga_image_info *info, | 154 | void fpga_image_info_free(struct fpga_image_info *info); |
144 | struct sg_table *sgt); | ||
145 | 155 | ||
146 | int fpga_mgr_firmware_load(struct fpga_manager *mgr, | 156 | int 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 | ||
150 | struct fpga_manager *of_fpga_mgr_get(struct device_node *node); | 158 | struct fpga_manager *of_fpga_mgr_get(struct device_node *node); |
151 | 159 | ||