diff options
author | Jonathan Corbet <corbet@lwn.net> | 2016-12-27 14:53:44 -0500 |
---|---|---|
committer | Jonathan Corbet <corbet@lwn.net> | 2016-12-27 14:53:44 -0500 |
commit | 54ab6db0909061ab7ee07233d3cab86d29f86e6c (patch) | |
tree | a7650ab5c0fa3a6a3841de8e8693041b3e009054 /drivers/fpga/fpga-mgr.c | |
parent | 217e2bfab22e740227df09f22165e834cddd8a3b (diff) | |
parent | 7ce7d89f48834cefece7804d38fc5d85382edf77 (diff) |
Merge tag 'v4.10-rc1' into docs-next
Linux 4.10-rc1
Diffstat (limited to 'drivers/fpga/fpga-mgr.c')
-rw-r--r-- | drivers/fpga/fpga-mgr.c | 97 |
1 files changed, 66 insertions, 31 deletions
diff --git a/drivers/fpga/fpga-mgr.c b/drivers/fpga/fpga-mgr.c index 953dc9195937..f0a69d3e60a5 100644 --- a/drivers/fpga/fpga-mgr.c +++ b/drivers/fpga/fpga-mgr.c | |||
@@ -32,19 +32,20 @@ static struct class *fpga_mgr_class; | |||
32 | /** | 32 | /** |
33 | * fpga_mgr_buf_load - load fpga from image in buffer | 33 | * fpga_mgr_buf_load - load fpga from image in buffer |
34 | * @mgr: fpga manager | 34 | * @mgr: fpga manager |
35 | * @flags: flags setting fpga confuration modes | 35 | * @info: fpga image specific information |
36 | * @buf: buffer contain fpga image | 36 | * @buf: buffer contain fpga image |
37 | * @count: byte count of buf | 37 | * @count: byte count of buf |
38 | * | 38 | * |
39 | * Step the low level fpga manager through the device-specific steps of getting | 39 | * Step the low level fpga manager through the device-specific steps of getting |
40 | * an FPGA ready to be configured, writing the image to it, then doing whatever | 40 | * an FPGA ready to be configured, writing the image to it, then doing whatever |
41 | * post-configuration steps necessary. This code assumes the caller got the | 41 | * post-configuration steps necessary. This code assumes the caller got the |
42 | * mgr pointer from of_fpga_mgr_get() and checked that it is not an error code. | 42 | * mgr pointer from of_fpga_mgr_get() or fpga_mgr_get() and checked that it is |
43 | * not an error code. | ||
43 | * | 44 | * |
44 | * Return: 0 on success, negative error code otherwise. | 45 | * Return: 0 on success, negative error code otherwise. |
45 | */ | 46 | */ |
46 | int fpga_mgr_buf_load(struct fpga_manager *mgr, u32 flags, const char *buf, | 47 | int fpga_mgr_buf_load(struct fpga_manager *mgr, struct fpga_image_info *info, |
47 | size_t count) | 48 | const char *buf, size_t count) |
48 | { | 49 | { |
49 | struct device *dev = &mgr->dev; | 50 | struct device *dev = &mgr->dev; |
50 | int ret; | 51 | int ret; |
@@ -52,10 +53,12 @@ int fpga_mgr_buf_load(struct fpga_manager *mgr, u32 flags, const char *buf, | |||
52 | /* | 53 | /* |
53 | * Call the low level driver's write_init function. This will do the | 54 | * Call the low level driver's write_init function. This will do the |
54 | * device-specific things to get the FPGA into the state where it is | 55 | * device-specific things to get the FPGA into the state where it is |
55 | * ready to receive an FPGA image. | 56 | * ready to receive an FPGA image. The low level driver only gets to |
57 | * see the first initial_header_size bytes in the buffer. | ||
56 | */ | 58 | */ |
57 | mgr->state = FPGA_MGR_STATE_WRITE_INIT; | 59 | mgr->state = FPGA_MGR_STATE_WRITE_INIT; |
58 | ret = mgr->mops->write_init(mgr, flags, buf, count); | 60 | ret = mgr->mops->write_init(mgr, info, buf, |
61 | min(mgr->mops->initial_header_size, count)); | ||
59 | if (ret) { | 62 | if (ret) { |
60 | dev_err(dev, "Error preparing FPGA for writing\n"); | 63 | dev_err(dev, "Error preparing FPGA for writing\n"); |
61 | mgr->state = FPGA_MGR_STATE_WRITE_INIT_ERR; | 64 | mgr->state = FPGA_MGR_STATE_WRITE_INIT_ERR; |
@@ -78,7 +81,7 @@ int fpga_mgr_buf_load(struct fpga_manager *mgr, u32 flags, const char *buf, | |||
78 | * steps to finish and set the FPGA into operating mode. | 81 | * steps to finish and set the FPGA into operating mode. |
79 | */ | 82 | */ |
80 | mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE; | 83 | mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE; |
81 | ret = mgr->mops->write_complete(mgr, flags); | 84 | ret = mgr->mops->write_complete(mgr, info); |
82 | if (ret) { | 85 | if (ret) { |
83 | dev_err(dev, "Error after writing image data to FPGA\n"); | 86 | dev_err(dev, "Error after writing image data to FPGA\n"); |
84 | mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE_ERR; | 87 | mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE_ERR; |
@@ -93,17 +96,19 @@ EXPORT_SYMBOL_GPL(fpga_mgr_buf_load); | |||
93 | /** | 96 | /** |
94 | * fpga_mgr_firmware_load - request firmware and load to fpga | 97 | * fpga_mgr_firmware_load - request firmware and load to fpga |
95 | * @mgr: fpga manager | 98 | * @mgr: fpga manager |
96 | * @flags: flags setting fpga confuration modes | 99 | * @info: fpga image specific information |
97 | * @image_name: name of image file on the firmware search path | 100 | * @image_name: name of image file on the firmware search path |
98 | * | 101 | * |
99 | * Request an FPGA image using the firmware class, then write out to the FPGA. | 102 | * Request an FPGA image using the firmware class, then write out to the FPGA. |
100 | * Update the state before each step to provide info on what step failed if | 103 | * Update the state before each step to provide info on what step failed if |
101 | * there is a failure. This code assumes the caller got the mgr pointer | 104 | * there is a failure. This code assumes the caller got the mgr pointer |
102 | * from of_fpga_mgr_get() and checked that it is not an error code. | 105 | * from of_fpga_mgr_get() or fpga_mgr_get() and checked that it is not an error |
106 | * code. | ||
103 | * | 107 | * |
104 | * Return: 0 on success, negative error code otherwise. | 108 | * Return: 0 on success, negative error code otherwise. |
105 | */ | 109 | */ |
106 | int fpga_mgr_firmware_load(struct fpga_manager *mgr, u32 flags, | 110 | int fpga_mgr_firmware_load(struct fpga_manager *mgr, |
111 | struct fpga_image_info *info, | ||
107 | const char *image_name) | 112 | const char *image_name) |
108 | { | 113 | { |
109 | struct device *dev = &mgr->dev; | 114 | struct device *dev = &mgr->dev; |
@@ -121,7 +126,7 @@ int fpga_mgr_firmware_load(struct fpga_manager *mgr, u32 flags, | |||
121 | return ret; | 126 | return ret; |
122 | } | 127 | } |
123 | 128 | ||
124 | ret = fpga_mgr_buf_load(mgr, flags, fw->data, fw->size); | 129 | ret = fpga_mgr_buf_load(mgr, info, fw->data, fw->size); |
125 | 130 | ||
126 | release_firmware(fw); | 131 | release_firmware(fw); |
127 | 132 | ||
@@ -181,30 +186,11 @@ static struct attribute *fpga_mgr_attrs[] = { | |||
181 | }; | 186 | }; |
182 | ATTRIBUTE_GROUPS(fpga_mgr); | 187 | ATTRIBUTE_GROUPS(fpga_mgr); |
183 | 188 | ||
184 | static int fpga_mgr_of_node_match(struct device *dev, const void *data) | 189 | struct fpga_manager *__fpga_mgr_get(struct device *dev) |
185 | { | ||
186 | return dev->of_node == data; | ||
187 | } | ||
188 | |||
189 | /** | ||
190 | * of_fpga_mgr_get - get an exclusive reference to a fpga mgr | ||
191 | * @node: device node | ||
192 | * | ||
193 | * Given a device node, get an exclusive reference to a fpga mgr. | ||
194 | * | ||
195 | * Return: fpga manager struct or IS_ERR() condition containing error code. | ||
196 | */ | ||
197 | struct fpga_manager *of_fpga_mgr_get(struct device_node *node) | ||
198 | { | 190 | { |
199 | struct fpga_manager *mgr; | 191 | struct fpga_manager *mgr; |
200 | struct device *dev; | ||
201 | int ret = -ENODEV; | 192 | int ret = -ENODEV; |
202 | 193 | ||
203 | dev = class_find_device(fpga_mgr_class, NULL, node, | ||
204 | fpga_mgr_of_node_match); | ||
205 | if (!dev) | ||
206 | return ERR_PTR(-ENODEV); | ||
207 | |||
208 | mgr = to_fpga_manager(dev); | 194 | mgr = to_fpga_manager(dev); |
209 | if (!mgr) | 195 | if (!mgr) |
210 | goto err_dev; | 196 | goto err_dev; |
@@ -226,6 +212,55 @@ err_dev: | |||
226 | put_device(dev); | 212 | put_device(dev); |
227 | return ERR_PTR(ret); | 213 | return ERR_PTR(ret); |
228 | } | 214 | } |
215 | |||
216 | static int fpga_mgr_dev_match(struct device *dev, const void *data) | ||
217 | { | ||
218 | return dev->parent == data; | ||
219 | } | ||
220 | |||
221 | /** | ||
222 | * fpga_mgr_get - get an exclusive reference to a fpga mgr | ||
223 | * @dev: parent device that fpga mgr was registered with | ||
224 | * | ||
225 | * Given a device, get an exclusive reference to a fpga mgr. | ||
226 | * | ||
227 | * Return: fpga manager struct or IS_ERR() condition containing error code. | ||
228 | */ | ||
229 | struct fpga_manager *fpga_mgr_get(struct device *dev) | ||
230 | { | ||
231 | struct device *mgr_dev = class_find_device(fpga_mgr_class, NULL, dev, | ||
232 | fpga_mgr_dev_match); | ||
233 | if (!mgr_dev) | ||
234 | return ERR_PTR(-ENODEV); | ||
235 | |||
236 | return __fpga_mgr_get(mgr_dev); | ||
237 | } | ||
238 | EXPORT_SYMBOL_GPL(fpga_mgr_get); | ||
239 | |||
240 | static int fpga_mgr_of_node_match(struct device *dev, const void *data) | ||
241 | { | ||
242 | return dev->of_node == data; | ||
243 | } | ||
244 | |||
245 | /** | ||
246 | * of_fpga_mgr_get - get an exclusive reference to a fpga mgr | ||
247 | * @node: device node | ||
248 | * | ||
249 | * Given a device node, get an exclusive reference to a fpga mgr. | ||
250 | * | ||
251 | * Return: fpga manager struct or IS_ERR() condition containing error code. | ||
252 | */ | ||
253 | struct fpga_manager *of_fpga_mgr_get(struct device_node *node) | ||
254 | { | ||
255 | struct device *dev; | ||
256 | |||
257 | dev = class_find_device(fpga_mgr_class, NULL, node, | ||
258 | fpga_mgr_of_node_match); | ||
259 | if (!dev) | ||
260 | return ERR_PTR(-ENODEV); | ||
261 | |||
262 | return __fpga_mgr_get(dev); | ||
263 | } | ||
229 | EXPORT_SYMBOL_GPL(of_fpga_mgr_get); | 264 | EXPORT_SYMBOL_GPL(of_fpga_mgr_get); |
230 | 265 | ||
231 | /** | 266 | /** |