aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/fpga
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/fpga')
-rw-r--r--drivers/fpga/Kconfig103
-rw-r--r--drivers/fpga/Makefile1
-rw-r--r--drivers/fpga/fpga-bridge.c113
-rw-r--r--drivers/fpga/fpga-mgr.c123
-rw-r--r--drivers/fpga/fpga-region.c464
-rw-r--r--drivers/fpga/of-fpga-region.c504
-rw-r--r--drivers/fpga/socfpga-a10.c8
7 files changed, 795 insertions, 521 deletions
diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index ad5448f718b3..f47ef848bcd0 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -11,25 +11,30 @@ menuconfig FPGA
11 11
12if FPGA 12if FPGA
13 13
14config FPGA_REGION 14config FPGA_MGR_SOCFPGA
15 tristate "FPGA Region" 15 tristate "Altera SOCFPGA FPGA Manager"
16 depends on OF && FPGA_BRIDGE 16 depends on ARCH_SOCFPGA || COMPILE_TEST
17 help 17 help
18 FPGA Regions allow loading FPGA images under control of 18 FPGA manager driver support for Altera SOCFPGA.
19 the Device Tree.
20 19
21config FPGA_MGR_ICE40_SPI 20config FPGA_MGR_SOCFPGA_A10
22 tristate "Lattice iCE40 SPI" 21 tristate "Altera SoCFPGA Arria10"
23 depends on OF && SPI 22 depends on ARCH_SOCFPGA || COMPILE_TEST
23 select REGMAP_MMIO
24 help 24 help
25 FPGA manager driver support for Lattice iCE40 FPGAs over SPI. 25 FPGA manager driver support for Altera Arria10 SoCFPGA.
26 26
27config FPGA_MGR_ALTERA_CVP 27config ALTERA_PR_IP_CORE
28 tristate "Altera Arria-V/Cyclone-V/Stratix-V CvP FPGA Manager" 28 tristate "Altera Partial Reconfiguration IP Core"
29 depends on PCI 29 help
30 Core driver support for Altera Partial Reconfiguration IP component
31
32config ALTERA_PR_IP_CORE_PLAT
33 tristate "Platform support of Altera Partial Reconfiguration IP Core"
34 depends on ALTERA_PR_IP_CORE && OF && HAS_IOMEM
30 help 35 help
31 FPGA manager driver support for Arria-V, Cyclone-V, Stratix-V 36 Platform driver support for Altera Partial Reconfiguration IP
32 and Arria 10 Altera FPGAs using the CvP interface over PCIe. 37 component
33 38
34config FPGA_MGR_ALTERA_PS_SPI 39config FPGA_MGR_ALTERA_PS_SPI
35 tristate "Altera FPGA Passive Serial over SPI" 40 tristate "Altera FPGA Passive Serial over SPI"
@@ -38,25 +43,19 @@ config FPGA_MGR_ALTERA_PS_SPI
38 FPGA manager driver support for Altera Arria/Cyclone/Stratix 43 FPGA manager driver support for Altera Arria/Cyclone/Stratix
39 using the passive serial interface over SPI. 44 using the passive serial interface over SPI.
40 45
41config FPGA_MGR_SOCFPGA 46config FPGA_MGR_ALTERA_CVP
42 tristate "Altera SOCFPGA FPGA Manager" 47 tristate "Altera Arria-V/Cyclone-V/Stratix-V CvP FPGA Manager"
43 depends on ARCH_SOCFPGA || COMPILE_TEST 48 depends on PCI
44 help
45 FPGA manager driver support for Altera SOCFPGA.
46
47config FPGA_MGR_SOCFPGA_A10
48 tristate "Altera SoCFPGA Arria10"
49 depends on ARCH_SOCFPGA || COMPILE_TEST
50 select REGMAP_MMIO
51 help 49 help
52 FPGA manager driver support for Altera Arria10 SoCFPGA. 50 FPGA manager driver support for Arria-V, Cyclone-V, Stratix-V
51 and Arria 10 Altera FPGAs using the CvP interface over PCIe.
53 52
54config FPGA_MGR_TS73XX 53config FPGA_MGR_ZYNQ_FPGA
55 tristate "Technologic Systems TS-73xx SBC FPGA Manager" 54 tristate "Xilinx Zynq FPGA"
56 depends on ARCH_EP93XX && MACH_TS72XX 55 depends on ARCH_ZYNQ || COMPILE_TEST
56 depends on HAS_DMA
57 help 57 help
58 FPGA manager driver support for the Altera Cyclone II FPGA 58 FPGA manager driver support for Xilinx Zynq FPGAs.
59 present on the TS-73xx SBC boards.
60 59
61config FPGA_MGR_XILINX_SPI 60config FPGA_MGR_XILINX_SPI
62 tristate "Xilinx Configuration over Slave Serial (SPI)" 61 tristate "Xilinx Configuration over Slave Serial (SPI)"
@@ -65,16 +64,21 @@ config FPGA_MGR_XILINX_SPI
65 FPGA manager driver support for Xilinx FPGA configuration 64 FPGA manager driver support for Xilinx FPGA configuration
66 over slave serial interface. 65 over slave serial interface.
67 66
68config FPGA_MGR_ZYNQ_FPGA 67config FPGA_MGR_ICE40_SPI
69 tristate "Xilinx Zynq FPGA" 68 tristate "Lattice iCE40 SPI"
70 depends on ARCH_ZYNQ || COMPILE_TEST 69 depends on OF && SPI
71 depends on HAS_DMA
72 help 70 help
73 FPGA manager driver support for Xilinx Zynq FPGAs. 71 FPGA manager driver support for Lattice iCE40 FPGAs over SPI.
72
73config FPGA_MGR_TS73XX
74 tristate "Technologic Systems TS-73xx SBC FPGA Manager"
75 depends on ARCH_EP93XX && MACH_TS72XX
76 help
77 FPGA manager driver support for the Altera Cyclone II FPGA
78 present on the TS-73xx SBC boards.
74 79
75config FPGA_BRIDGE 80config FPGA_BRIDGE
76 tristate "FPGA Bridge Framework" 81 tristate "FPGA Bridge Framework"
77 depends on OF
78 help 82 help
79 Say Y here if you want to support bridges connected between host 83 Say Y here if you want to support bridges connected between host
80 processors and FPGAs or between FPGAs. 84 processors and FPGAs or between FPGAs.
@@ -95,18 +99,6 @@ config ALTERA_FREEZE_BRIDGE
95 isolate one region of the FPGA from the busses while that 99 isolate one region of the FPGA from the busses while that
96 region is being reprogrammed. 100 region is being reprogrammed.
97 101
98config ALTERA_PR_IP_CORE
99 tristate "Altera Partial Reconfiguration IP Core"
100 help
101 Core driver support for Altera Partial Reconfiguration IP component
102
103config ALTERA_PR_IP_CORE_PLAT
104 tristate "Platform support of Altera Partial Reconfiguration IP Core"
105 depends on ALTERA_PR_IP_CORE && OF && HAS_IOMEM
106 help
107 Platform driver support for Altera Partial Reconfiguration IP
108 component
109
110config XILINX_PR_DECOUPLER 102config XILINX_PR_DECOUPLER
111 tristate "Xilinx LogiCORE PR Decoupler" 103 tristate "Xilinx LogiCORE PR Decoupler"
112 depends on FPGA_BRIDGE 104 depends on FPGA_BRIDGE
@@ -117,4 +109,19 @@ config XILINX_PR_DECOUPLER
117 region of the FPGA from the busses while that region is 109 region of the FPGA from the busses while that region is
118 being reprogrammed during partial reconfig. 110 being reprogrammed during partial reconfig.
119 111
112config FPGA_REGION
113 tristate "FPGA Region"
114 depends on FPGA_BRIDGE
115 help
116 FPGA Region common code. A FPGA Region controls a FPGA Manager
117 and the FPGA Bridges associated with either a reconfigurable
118 region of an FPGA or a whole FPGA.
119
120config OF_FPGA_REGION
121 tristate "FPGA Region Device Tree Overlay Support"
122 depends on OF && FPGA_REGION
123 help
124 Support for loading FPGA images by applying a Device Tree
125 overlay.
126
120endif # FPGA 127endif # FPGA
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index f98dcf1d89e1..3cb276a0f88d 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -26,3 +26,4 @@ obj-$(CONFIG_XILINX_PR_DECOUPLER) += xilinx-pr-decoupler.o
26 26
27# High Level Interfaces 27# High Level Interfaces
28obj-$(CONFIG_FPGA_REGION) += fpga-region.o 28obj-$(CONFIG_FPGA_REGION) += fpga-region.o
29obj-$(CONFIG_OF_FPGA_REGION) += of-fpga-region.o
diff --git a/drivers/fpga/fpga-bridge.c b/drivers/fpga/fpga-bridge.c
index 9651aa56244a..31bd2c59c305 100644
--- a/drivers/fpga/fpga-bridge.c
+++ b/drivers/fpga/fpga-bridge.c
@@ -2,6 +2,7 @@
2 * FPGA Bridge Framework Driver 2 * FPGA Bridge Framework Driver
3 * 3 *
4 * Copyright (C) 2013-2016 Altera Corporation, All Rights Reserved. 4 * Copyright (C) 2013-2016 Altera Corporation, All Rights Reserved.
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,
@@ -70,32 +71,13 @@ int fpga_bridge_disable(struct fpga_bridge *bridge)
70} 71}
71EXPORT_SYMBOL_GPL(fpga_bridge_disable); 72EXPORT_SYMBOL_GPL(fpga_bridge_disable);
72 73
73/** 74static struct fpga_bridge *__fpga_bridge_get(struct device *dev,
74 * of_fpga_bridge_get - get an exclusive reference to a fpga bridge 75 struct fpga_image_info *info)
75 *
76 * @np: node pointer of a FPGA bridge
77 * @info: fpga image specific information
78 *
79 * Return fpga_bridge struct if successful.
80 * Return -EBUSY if someone already has a reference to the bridge.
81 * Return -ENODEV if @np is not a FPGA Bridge.
82 */
83struct fpga_bridge *of_fpga_bridge_get(struct device_node *np,
84 struct fpga_image_info *info)
85
86{ 76{
87 struct device *dev;
88 struct fpga_bridge *bridge; 77 struct fpga_bridge *bridge;
89 int ret = -ENODEV; 78 int ret = -ENODEV;
90 79
91 dev = class_find_device(fpga_bridge_class, NULL, np,
92 fpga_bridge_of_node_match);
93 if (!dev)
94 goto err_dev;
95
96 bridge = to_fpga_bridge(dev); 80 bridge = to_fpga_bridge(dev);
97 if (!bridge)
98 goto err_dev;
99 81
100 bridge->info = info; 82 bridge->info = info;
101 83
@@ -117,8 +99,58 @@ err_dev:
117 put_device(dev); 99 put_device(dev);
118 return ERR_PTR(ret); 100 return ERR_PTR(ret);
119} 101}
102
103/**
104 * of_fpga_bridge_get - get an exclusive reference to a fpga bridge
105 *
106 * @np: node pointer of a FPGA bridge
107 * @info: fpga image specific information
108 *
109 * Return fpga_bridge struct if successful.
110 * Return -EBUSY if someone already has a reference to the bridge.
111 * Return -ENODEV if @np is not a FPGA Bridge.
112 */
113struct fpga_bridge *of_fpga_bridge_get(struct device_node *np,
114 struct fpga_image_info *info)
115{
116 struct device *dev;
117
118 dev = class_find_device(fpga_bridge_class, NULL, np,
119 fpga_bridge_of_node_match);
120 if (!dev)
121 return ERR_PTR(-ENODEV);
122
123 return __fpga_bridge_get(dev, info);
124}
120EXPORT_SYMBOL_GPL(of_fpga_bridge_get); 125EXPORT_SYMBOL_GPL(of_fpga_bridge_get);
121 126
127static int fpga_bridge_dev_match(struct device *dev, const void *data)
128{
129 return dev->parent == data;
130}
131
132/**
133 * fpga_bridge_get - get an exclusive reference to a fpga bridge
134 * @dev: parent device that fpga bridge was registered with
135 *
136 * Given a device, get an exclusive reference to a fpga bridge.
137 *
138 * Return: fpga manager struct or IS_ERR() condition containing error code.
139 */
140struct fpga_bridge *fpga_bridge_get(struct device *dev,
141 struct fpga_image_info *info)
142{
143 struct device *bridge_dev;
144
145 bridge_dev = class_find_device(fpga_bridge_class, NULL, dev,
146 fpga_bridge_dev_match);
147 if (!bridge_dev)
148 return ERR_PTR(-ENODEV);
149
150 return __fpga_bridge_get(bridge_dev, info);
151}
152EXPORT_SYMBOL_GPL(fpga_bridge_get);
153
122/** 154/**
123 * fpga_bridge_put - release a reference to a bridge 155 * fpga_bridge_put - release a reference to a bridge
124 * 156 *
@@ -206,7 +238,7 @@ void fpga_bridges_put(struct list_head *bridge_list)
206EXPORT_SYMBOL_GPL(fpga_bridges_put); 238EXPORT_SYMBOL_GPL(fpga_bridges_put);
207 239
208/** 240/**
209 * fpga_bridges_get_to_list - get a bridge, add it to a list 241 * of_fpga_bridge_get_to_list - get a bridge, add it to a list
210 * 242 *
211 * @np: node pointer of a FPGA bridge 243 * @np: node pointer of a FPGA bridge
212 * @info: fpga image specific information 244 * @info: fpga image specific information
@@ -216,14 +248,44 @@ EXPORT_SYMBOL_GPL(fpga_bridges_put);
216 * 248 *
217 * Return 0 for success, error code from of_fpga_bridge_get() othewise. 249 * Return 0 for success, error code from of_fpga_bridge_get() othewise.
218 */ 250 */
219int fpga_bridge_get_to_list(struct device_node *np, 251int of_fpga_bridge_get_to_list(struct device_node *np,
252 struct fpga_image_info *info,
253 struct list_head *bridge_list)
254{
255 struct fpga_bridge *bridge;
256 unsigned long flags;
257
258 bridge = of_fpga_bridge_get(np, info);
259 if (IS_ERR(bridge))
260 return PTR_ERR(bridge);
261
262 spin_lock_irqsave(&bridge_list_lock, flags);
263 list_add(&bridge->node, bridge_list);
264 spin_unlock_irqrestore(&bridge_list_lock, flags);
265
266 return 0;
267}
268EXPORT_SYMBOL_GPL(of_fpga_bridge_get_to_list);
269
270/**
271 * fpga_bridge_get_to_list - given device, get a bridge, add it to a list
272 *
273 * @dev: FPGA bridge device
274 * @info: fpga image specific information
275 * @bridge_list: list of FPGA bridges
276 *
277 * Get an exclusive reference to the bridge and and it to the list.
278 *
279 * Return 0 for success, error code from fpga_bridge_get() othewise.
280 */
281int fpga_bridge_get_to_list(struct device *dev,
220 struct fpga_image_info *info, 282 struct fpga_image_info *info,
221 struct list_head *bridge_list) 283 struct list_head *bridge_list)
222{ 284{
223 struct fpga_bridge *bridge; 285 struct fpga_bridge *bridge;
224 unsigned long flags; 286 unsigned long flags;
225 287
226 bridge = of_fpga_bridge_get(np, info); 288 bridge = fpga_bridge_get(dev, info);
227 if (IS_ERR(bridge)) 289 if (IS_ERR(bridge))
228 return PTR_ERR(bridge); 290 return PTR_ERR(bridge);
229 291
@@ -303,6 +365,7 @@ int fpga_bridge_register(struct device *dev, const char *name,
303 bridge->priv = priv; 365 bridge->priv = priv;
304 366
305 device_initialize(&bridge->dev); 367 device_initialize(&bridge->dev);
368 bridge->dev.groups = br_ops->groups;
306 bridge->dev.class = fpga_bridge_class; 369 bridge->dev.class = fpga_bridge_class;
307 bridge->dev.parent = dev; 370 bridge->dev.parent = dev;
308 bridge->dev.of_node = dev->of_node; 371 bridge->dev.of_node = dev->of_node;
@@ -381,7 +444,7 @@ static void __exit fpga_bridge_dev_exit(void)
381} 444}
382 445
383MODULE_DESCRIPTION("FPGA Bridge Driver"); 446MODULE_DESCRIPTION("FPGA Bridge Driver");
384MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>"); 447MODULE_AUTHOR("Alan Tull <atull@kernel.org>");
385MODULE_LICENSE("GPL v2"); 448MODULE_LICENSE("GPL v2");
386 449
387subsys_initcall(fpga_bridge_dev_init); 450subsys_initcall(fpga_bridge_dev_init);
diff --git a/drivers/fpga/fpga-mgr.c b/drivers/fpga/fpga-mgr.c
index 188ffefa3cc3..9939d2cbc9a6 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",
@@ -364,28 +410,17 @@ ATTRIBUTE_GROUPS(fpga_mgr);
364static struct fpga_manager *__fpga_mgr_get(struct device *dev) 410static struct fpga_manager *__fpga_mgr_get(struct device *dev)
365{ 411{
366 struct fpga_manager *mgr; 412 struct fpga_manager *mgr;
367 int ret = -ENODEV;
368 413
369 mgr = to_fpga_manager(dev); 414 mgr = to_fpga_manager(dev);
370 if (!mgr)
371 goto err_dev;
372
373 /* Get exclusive use of fpga manager */
374 if (!mutex_trylock(&mgr->ref_mutex)) {
375 ret = -EBUSY;
376 goto err_dev;
377 }
378 415
379 if (!try_module_get(dev->parent->driver->owner)) 416 if (!try_module_get(dev->parent->driver->owner))
380 goto err_ll_mod; 417 goto err_dev;
381 418
382 return mgr; 419 return mgr;
383 420
384err_ll_mod:
385 mutex_unlock(&mgr->ref_mutex);
386err_dev: 421err_dev:
387 put_device(dev); 422 put_device(dev);
388 return ERR_PTR(ret); 423 return ERR_PTR(-ENODEV);
389} 424}
390 425
391static int fpga_mgr_dev_match(struct device *dev, const void *data) 426static int fpga_mgr_dev_match(struct device *dev, const void *data)
@@ -394,10 +429,10 @@ static int fpga_mgr_dev_match(struct device *dev, const void *data)
394} 429}
395 430
396/** 431/**
397 * fpga_mgr_get - get an exclusive reference to a fpga mgr 432 * fpga_mgr_get - get a reference to a fpga mgr
398 * @dev: parent device that fpga mgr was registered with 433 * @dev: parent device that fpga mgr was registered with
399 * 434 *
400 * Given a device, get an exclusive reference to a fpga mgr. 435 * Given a device, get a reference to a fpga mgr.
401 * 436 *
402 * Return: fpga manager struct or IS_ERR() condition containing error code. 437 * Return: fpga manager struct or IS_ERR() condition containing error code.
403 */ 438 */
@@ -418,10 +453,10 @@ static int fpga_mgr_of_node_match(struct device *dev, const void *data)
418} 453}
419 454
420/** 455/**
421 * of_fpga_mgr_get - get an exclusive reference to a fpga mgr 456 * of_fpga_mgr_get - get a reference to a fpga mgr
422 * @node: device node 457 * @node: device node
423 * 458 *
424 * Given a device node, get an exclusive reference to a fpga mgr. 459 * Given a device node, get a reference to a fpga mgr.
425 * 460 *
426 * Return: fpga manager struct or IS_ERR() condition containing error code. 461 * Return: fpga manager struct or IS_ERR() condition containing error code.
427 */ 462 */
@@ -445,12 +480,41 @@ EXPORT_SYMBOL_GPL(of_fpga_mgr_get);
445void fpga_mgr_put(struct fpga_manager *mgr) 480void fpga_mgr_put(struct fpga_manager *mgr)
446{ 481{
447 module_put(mgr->dev.parent->driver->owner); 482 module_put(mgr->dev.parent->driver->owner);
448 mutex_unlock(&mgr->ref_mutex);
449 put_device(&mgr->dev); 483 put_device(&mgr->dev);
450} 484}
451EXPORT_SYMBOL_GPL(fpga_mgr_put); 485EXPORT_SYMBOL_GPL(fpga_mgr_put);
452 486
453/** 487/**
488 * fpga_mgr_lock - Lock FPGA manager for exclusive use
489 * @mgr: fpga manager
490 *
491 * Given a pointer to FPGA Manager (from fpga_mgr_get() or
492 * of_fpga_mgr_put()) attempt to get the mutex.
493 *
494 * Return: 0 for success or -EBUSY
495 */
496int fpga_mgr_lock(struct fpga_manager *mgr)
497{
498 if (!mutex_trylock(&mgr->ref_mutex)) {
499 dev_err(&mgr->dev, "FPGA manager is in use.\n");
500 return -EBUSY;
501 }
502
503 return 0;
504}
505EXPORT_SYMBOL_GPL(fpga_mgr_lock);
506
507/**
508 * fpga_mgr_unlock - Unlock FPGA manager
509 * @mgr: fpga manager
510 */
511void fpga_mgr_unlock(struct fpga_manager *mgr)
512{
513 mutex_unlock(&mgr->ref_mutex);
514}
515EXPORT_SYMBOL_GPL(fpga_mgr_unlock);
516
517/**
454 * fpga_mgr_register - register a low level fpga manager driver 518 * fpga_mgr_register - register a low level fpga manager driver
455 * @dev: fpga manager device from pdev 519 * @dev: fpga manager device from pdev
456 * @name: fpga manager name 520 * @name: fpga manager name
@@ -503,6 +567,7 @@ int fpga_mgr_register(struct device *dev, const char *name,
503 567
504 device_initialize(&mgr->dev); 568 device_initialize(&mgr->dev);
505 mgr->dev.class = fpga_mgr_class; 569 mgr->dev.class = fpga_mgr_class;
570 mgr->dev.groups = mops->groups;
506 mgr->dev.parent = dev; 571 mgr->dev.parent = dev;
507 mgr->dev.of_node = dev->of_node; 572 mgr->dev.of_node = dev->of_node;
508 mgr->dev.id = id; 573 mgr->dev.id = id;
@@ -578,7 +643,7 @@ static void __exit fpga_mgr_class_exit(void)
578 ida_destroy(&fpga_mgr_ida); 643 ida_destroy(&fpga_mgr_ida);
579} 644}
580 645
581MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>"); 646MODULE_AUTHOR("Alan Tull <atull@kernel.org>");
582MODULE_DESCRIPTION("FPGA manager framework"); 647MODULE_DESCRIPTION("FPGA manager framework");
583MODULE_LICENSE("GPL v2"); 648MODULE_LICENSE("GPL v2");
584 649
diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
index d9ab7c75b14f..edab2a2e03ef 100644
--- a/drivers/fpga/fpga-region.c
+++ b/drivers/fpga/fpga-region.c
@@ -2,6 +2,7 @@
2 * FPGA Region - Device Tree support for FPGA programming under Linux 2 * FPGA Region - Device Tree support for FPGA programming under Linux
3 * 3 *
4 * Copyright (C) 2013-2016 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,
@@ -18,61 +19,30 @@
18 19
19#include <linux/fpga/fpga-bridge.h> 20#include <linux/fpga/fpga-bridge.h>
20#include <linux/fpga/fpga-mgr.h> 21#include <linux/fpga/fpga-mgr.h>
22#include <linux/fpga/fpga-region.h>
21#include <linux/idr.h> 23#include <linux/idr.h>
22#include <linux/kernel.h> 24#include <linux/kernel.h>
23#include <linux/list.h> 25#include <linux/list.h>
24#include <linux/module.h> 26#include <linux/module.h>
25#include <linux/of_platform.h>
26#include <linux/slab.h> 27#include <linux/slab.h>
27#include <linux/spinlock.h> 28#include <linux/spinlock.h>
28 29
29/**
30 * struct fpga_region - FPGA Region structure
31 * @dev: FPGA Region device
32 * @mutex: enforces exclusive reference to region
33 * @bridge_list: list of FPGA bridges specified in region
34 * @info: fpga image specific information
35 */
36struct fpga_region {
37 struct device dev;
38 struct mutex mutex; /* for exclusive reference to region */
39 struct list_head bridge_list;
40 struct fpga_image_info *info;
41};
42
43#define to_fpga_region(d) container_of(d, struct fpga_region, dev)
44
45static DEFINE_IDA(fpga_region_ida); 30static DEFINE_IDA(fpga_region_ida);
46static struct class *fpga_region_class; 31static struct class *fpga_region_class;
47 32
48static const struct of_device_id fpga_region_of_match[] = { 33struct fpga_region *fpga_region_class_find(
49 { .compatible = "fpga-region", }, 34 struct device *start, const void *data,
50 {}, 35 int (*match)(struct device *, const void *))
51};
52MODULE_DEVICE_TABLE(of, fpga_region_of_match);
53
54static int fpga_region_of_node_match(struct device *dev, const void *data)
55{
56 return dev->of_node == data;
57}
58
59/**
60 * fpga_region_find - find FPGA region
61 * @np: device node of FPGA Region
62 * Caller will need to put_device(&region->dev) when done.
63 * Returns FPGA Region struct or NULL
64 */
65static struct fpga_region *fpga_region_find(struct device_node *np)
66{ 36{
67 struct device *dev; 37 struct device *dev;
68 38
69 dev = class_find_device(fpga_region_class, NULL, np, 39 dev = class_find_device(fpga_region_class, start, data, match);
70 fpga_region_of_node_match);
71 if (!dev) 40 if (!dev)
72 return NULL; 41 return NULL;
73 42
74 return to_fpga_region(dev); 43 return to_fpga_region(dev);
75} 44}
45EXPORT_SYMBOL_GPL(fpga_region_class_find);
76 46
77/** 47/**
78 * fpga_region_get - get an exclusive reference to a fpga region 48 * fpga_region_get - get an exclusive reference to a fpga region
@@ -94,15 +64,13 @@ static struct fpga_region *fpga_region_get(struct fpga_region *region)
94 } 64 }
95 65
96 get_device(dev); 66 get_device(dev);
97 of_node_get(dev->of_node);
98 if (!try_module_get(dev->parent->driver->owner)) { 67 if (!try_module_get(dev->parent->driver->owner)) {
99 of_node_put(dev->of_node);
100 put_device(dev); 68 put_device(dev);
101 mutex_unlock(&region->mutex); 69 mutex_unlock(&region->mutex);
102 return ERR_PTR(-ENODEV); 70 return ERR_PTR(-ENODEV);
103 } 71 }
104 72
105 dev_dbg(&region->dev, "get\n"); 73 dev_dbg(dev, "get\n");
106 74
107 return region; 75 return region;
108} 76}
@@ -116,403 +84,99 @@ static void fpga_region_put(struct fpga_region *region)
116{ 84{
117 struct device *dev = &region->dev; 85 struct device *dev = &region->dev;
118 86
119 dev_dbg(&region->dev, "put\n"); 87 dev_dbg(dev, "put\n");
120 88
121 module_put(dev->parent->driver->owner); 89 module_put(dev->parent->driver->owner);
122 of_node_put(dev->of_node);
123 put_device(dev); 90 put_device(dev);
124 mutex_unlock(&region->mutex); 91 mutex_unlock(&region->mutex);
125} 92}
126 93
127/** 94/**
128 * fpga_region_get_manager - get exclusive reference for FPGA manager
129 * @region: FPGA region
130 *
131 * Get FPGA Manager from "fpga-mgr" property or from ancestor region.
132 *
133 * Caller should call fpga_mgr_put() when done with manager.
134 *
135 * Return: fpga manager struct or IS_ERR() condition containing error code.
136 */
137static struct fpga_manager *fpga_region_get_manager(struct fpga_region *region)
138{
139 struct device *dev = &region->dev;
140 struct device_node *np = dev->of_node;
141 struct device_node *mgr_node;
142 struct fpga_manager *mgr;
143
144 of_node_get(np);
145 while (np) {
146 if (of_device_is_compatible(np, "fpga-region")) {
147 mgr_node = of_parse_phandle(np, "fpga-mgr", 0);
148 if (mgr_node) {
149 mgr = of_fpga_mgr_get(mgr_node);
150 of_node_put(np);
151 return mgr;
152 }
153 }
154 np = of_get_next_parent(np);
155 }
156 of_node_put(np);
157
158 return ERR_PTR(-EINVAL);
159}
160
161/**
162 * fpga_region_get_bridges - create a list of bridges
163 * @region: FPGA region
164 * @overlay: device node of the overlay
165 *
166 * Create a list of bridges including the parent bridge and the bridges
167 * specified by "fpga-bridges" property. Note that the
168 * fpga_bridges_enable/disable/put functions are all fine with an empty list
169 * if that happens.
170 *
171 * Caller should call fpga_bridges_put(&region->bridge_list) when
172 * done with the bridges.
173 *
174 * Return 0 for success (even if there are no bridges specified)
175 * or -EBUSY if any of the bridges are in use.
176 */
177static int fpga_region_get_bridges(struct fpga_region *region,
178 struct device_node *overlay)
179{
180 struct device *dev = &region->dev;
181 struct device_node *region_np = dev->of_node;
182 struct device_node *br, *np, *parent_br = NULL;
183 int i, ret;
184
185 /* If parent is a bridge, add to list */
186 ret = fpga_bridge_get_to_list(region_np->parent, region->info,
187 &region->bridge_list);
188 if (ret == -EBUSY)
189 return ret;
190
191 if (!ret)
192 parent_br = region_np->parent;
193
194 /* If overlay has a list of bridges, use it. */
195 if (of_parse_phandle(overlay, "fpga-bridges", 0))
196 np = overlay;
197 else
198 np = region_np;
199
200 for (i = 0; ; i++) {
201 br = of_parse_phandle(np, "fpga-bridges", i);
202 if (!br)
203 break;
204
205 /* If parent bridge is in list, skip it. */
206 if (br == parent_br)
207 continue;
208
209 /* If node is a bridge, get it and add to list */
210 ret = fpga_bridge_get_to_list(br, region->info,
211 &region->bridge_list);
212
213 /* If any of the bridges are in use, give up */
214 if (ret == -EBUSY) {
215 fpga_bridges_put(&region->bridge_list);
216 return -EBUSY;
217 }
218 }
219
220 return 0;
221}
222
223/**
224 * fpga_region_program_fpga - program FPGA 95 * fpga_region_program_fpga - program FPGA
225 * @region: FPGA region 96 * @region: FPGA region
226 * @firmware_name: name of FPGA image firmware file 97 * Program an FPGA using fpga image info (region->info).
227 * @overlay: device node of the overlay
228 * Program an FPGA using information in the device tree.
229 * Function assumes that there is a firmware-name property.
230 * Return 0 for success or negative error code. 98 * Return 0 for success or negative error code.
231 */ 99 */
232static int fpga_region_program_fpga(struct fpga_region *region, 100int fpga_region_program_fpga(struct fpga_region *region)
233 const char *firmware_name,
234 struct device_node *overlay)
235{ 101{
236 struct fpga_manager *mgr; 102 struct device *dev = &region->dev;
103 struct fpga_image_info *info = region->info;
237 int ret; 104 int ret;
238 105
239 region = fpga_region_get(region); 106 region = fpga_region_get(region);
240 if (IS_ERR(region)) { 107 if (IS_ERR(region)) {
241 pr_err("failed to get fpga region\n"); 108 dev_err(dev, "failed to get FPGA region\n");
242 return PTR_ERR(region); 109 return PTR_ERR(region);
243 } 110 }
244 111
245 mgr = fpga_region_get_manager(region); 112 ret = fpga_mgr_lock(region->mgr);
246 if (IS_ERR(mgr)) { 113 if (ret) {
247 pr_err("failed to get fpga region manager\n"); 114 dev_err(dev, "FPGA manager is busy\n");
248 ret = PTR_ERR(mgr);
249 goto err_put_region; 115 goto err_put_region;
250 } 116 }
251 117
252 ret = fpga_region_get_bridges(region, overlay); 118 /*
253 if (ret) { 119 * In some cases, we already have a list of bridges in the
254 pr_err("failed to get fpga region bridges\n"); 120 * fpga region struct. Or we don't have any bridges.
255 goto err_put_mgr; 121 */
122 if (region->get_bridges) {
123 ret = region->get_bridges(region);
124 if (ret) {
125 dev_err(dev, "failed to get fpga region bridges\n");
126 goto err_unlock_mgr;
127 }
256 } 128 }
257 129
258 ret = fpga_bridges_disable(&region->bridge_list); 130 ret = fpga_bridges_disable(&region->bridge_list);
259 if (ret) { 131 if (ret) {
260 pr_err("failed to disable region bridges\n"); 132 dev_err(dev, "failed to disable bridges\n");
261 goto err_put_br; 133 goto err_put_br;
262 } 134 }
263 135
264 ret = fpga_mgr_firmware_load(mgr, region->info, firmware_name); 136 ret = fpga_mgr_load(region->mgr, info);
265 if (ret) { 137 if (ret) {
266 pr_err("failed to load fpga image\n"); 138 dev_err(dev, "failed to load FPGA image\n");
267 goto err_put_br; 139 goto err_put_br;
268 } 140 }
269 141
270 ret = fpga_bridges_enable(&region->bridge_list); 142 ret = fpga_bridges_enable(&region->bridge_list);
271 if (ret) { 143 if (ret) {
272 pr_err("failed to enable region bridges\n"); 144 dev_err(dev, "failed to enable region bridges\n");
273 goto err_put_br; 145 goto err_put_br;
274 } 146 }
275 147
276 fpga_mgr_put(mgr); 148 fpga_mgr_unlock(region->mgr);
277 fpga_region_put(region); 149 fpga_region_put(region);
278 150
279 return 0; 151 return 0;
280 152
281err_put_br: 153err_put_br:
282 fpga_bridges_put(&region->bridge_list); 154 if (region->get_bridges)
283err_put_mgr: 155 fpga_bridges_put(&region->bridge_list);
284 fpga_mgr_put(mgr); 156err_unlock_mgr:
157 fpga_mgr_unlock(region->mgr);
285err_put_region: 158err_put_region:
286 fpga_region_put(region); 159 fpga_region_put(region);
287 160
288 return ret; 161 return ret;
289} 162}
163EXPORT_SYMBOL_GPL(fpga_region_program_fpga);
290 164
291/** 165int fpga_region_register(struct device *dev, struct fpga_region *region)
292 * child_regions_with_firmware
293 * @overlay: device node of the overlay
294 *
295 * If the overlay adds child FPGA regions, they are not allowed to have
296 * firmware-name property.
297 *
298 * Return 0 for OK or -EINVAL if child FPGA region adds firmware-name.
299 */
300static int child_regions_with_firmware(struct device_node *overlay)
301{
302 struct device_node *child_region;
303 const char *child_firmware_name;
304 int ret = 0;
305
306 of_node_get(overlay);
307
308 child_region = of_find_matching_node(overlay, fpga_region_of_match);
309 while (child_region) {
310 if (!of_property_read_string(child_region, "firmware-name",
311 &child_firmware_name)) {
312 ret = -EINVAL;
313 break;
314 }
315 child_region = of_find_matching_node(child_region,
316 fpga_region_of_match);
317 }
318
319 of_node_put(child_region);
320
321 if (ret)
322 pr_err("firmware-name not allowed in child FPGA region: %pOF",
323 child_region);
324
325 return ret;
326}
327
328/**
329 * fpga_region_notify_pre_apply - pre-apply overlay notification
330 *
331 * @region: FPGA region that the overlay was applied to
332 * @nd: overlay notification data
333 *
334 * Called after when an overlay targeted to a FPGA Region is about to be
335 * applied. Function will check the properties that will be added to the FPGA
336 * region. If the checks pass, it will program the FPGA.
337 *
338 * The checks are:
339 * The overlay must add either firmware-name or external-fpga-config property
340 * to the FPGA Region.
341 *
342 * firmware-name : program the FPGA
343 * external-fpga-config : FPGA is already programmed
344 * encrypted-fpga-config : FPGA bitstream is encrypted
345 *
346 * The overlay can add other FPGA regions, but child FPGA regions cannot have a
347 * firmware-name property since those regions don't exist yet.
348 *
349 * If the overlay that breaks the rules, notifier returns an error and the
350 * overlay is rejected before it goes into the main tree.
351 *
352 * Returns 0 for success or negative error code for failure.
353 */
354static int fpga_region_notify_pre_apply(struct fpga_region *region,
355 struct of_overlay_notify_data *nd)
356{ 166{
357 const char *firmware_name = NULL;
358 struct fpga_image_info *info;
359 int ret;
360
361 info = devm_kzalloc(&region->dev, sizeof(*info), GFP_KERNEL);
362 if (!info)
363 return -ENOMEM;
364
365 region->info = info;
366
367 /* Reject overlay if child FPGA Regions have firmware-name property */
368 ret = child_regions_with_firmware(nd->overlay);
369 if (ret)
370 return ret;
371
372 /* Read FPGA region properties from the overlay */
373 if (of_property_read_bool(nd->overlay, "partial-fpga-config"))
374 info->flags |= FPGA_MGR_PARTIAL_RECONFIG;
375
376 if (of_property_read_bool(nd->overlay, "external-fpga-config"))
377 info->flags |= FPGA_MGR_EXTERNAL_CONFIG;
378
379 if (of_property_read_bool(nd->overlay, "encrypted-fpga-config"))
380 info->flags |= FPGA_MGR_ENCRYPTED_BITSTREAM;
381
382 of_property_read_string(nd->overlay, "firmware-name", &firmware_name);
383
384 of_property_read_u32(nd->overlay, "region-unfreeze-timeout-us",
385 &info->enable_timeout_us);
386
387 of_property_read_u32(nd->overlay, "region-freeze-timeout-us",
388 &info->disable_timeout_us);
389
390 of_property_read_u32(nd->overlay, "config-complete-timeout-us",
391 &info->config_complete_timeout_us);
392
393 /* If FPGA was externally programmed, don't specify firmware */
394 if ((info->flags & FPGA_MGR_EXTERNAL_CONFIG) && firmware_name) {
395 pr_err("error: specified firmware and external-fpga-config");
396 return -EINVAL;
397 }
398
399 /* FPGA is already configured externally. We're done. */
400 if (info->flags & FPGA_MGR_EXTERNAL_CONFIG)
401 return 0;
402
403 /* If we got this far, we should be programming the FPGA */
404 if (!firmware_name) {
405 pr_err("should specify firmware-name or external-fpga-config\n");
406 return -EINVAL;
407 }
408
409 return fpga_region_program_fpga(region, firmware_name, nd->overlay);
410}
411
412/**
413 * fpga_region_notify_post_remove - post-remove overlay notification
414 *
415 * @region: FPGA region that was targeted by the overlay that was removed
416 * @nd: overlay notification data
417 *
418 * Called after an overlay has been removed if the overlay's target was a
419 * FPGA region.
420 */
421static void fpga_region_notify_post_remove(struct fpga_region *region,
422 struct of_overlay_notify_data *nd)
423{
424 fpga_bridges_disable(&region->bridge_list);
425 fpga_bridges_put(&region->bridge_list);
426 devm_kfree(&region->dev, region->info);
427 region->info = NULL;
428}
429
430/**
431 * of_fpga_region_notify - reconfig notifier for dynamic DT changes
432 * @nb: notifier block
433 * @action: notifier action
434 * @arg: reconfig data
435 *
436 * This notifier handles programming a FPGA when a "firmware-name" property is
437 * added to a fpga-region.
438 *
439 * Returns NOTIFY_OK or error if FPGA programming fails.
440 */
441static int of_fpga_region_notify(struct notifier_block *nb,
442 unsigned long action, void *arg)
443{
444 struct of_overlay_notify_data *nd = arg;
445 struct fpga_region *region;
446 int ret;
447
448 switch (action) {
449 case OF_OVERLAY_PRE_APPLY:
450 pr_debug("%s OF_OVERLAY_PRE_APPLY\n", __func__);
451 break;
452 case OF_OVERLAY_POST_APPLY:
453 pr_debug("%s OF_OVERLAY_POST_APPLY\n", __func__);
454 return NOTIFY_OK; /* not for us */
455 case OF_OVERLAY_PRE_REMOVE:
456 pr_debug("%s OF_OVERLAY_PRE_REMOVE\n", __func__);
457 return NOTIFY_OK; /* not for us */
458 case OF_OVERLAY_POST_REMOVE:
459 pr_debug("%s OF_OVERLAY_POST_REMOVE\n", __func__);
460 break;
461 default: /* should not happen */
462 return NOTIFY_OK;
463 }
464
465 region = fpga_region_find(nd->target);
466 if (!region)
467 return NOTIFY_OK;
468
469 ret = 0;
470 switch (action) {
471 case OF_OVERLAY_PRE_APPLY:
472 ret = fpga_region_notify_pre_apply(region, nd);
473 break;
474
475 case OF_OVERLAY_POST_REMOVE:
476 fpga_region_notify_post_remove(region, nd);
477 break;
478 }
479
480 put_device(&region->dev);
481
482 if (ret)
483 return notifier_from_errno(ret);
484
485 return NOTIFY_OK;
486}
487
488static struct notifier_block fpga_region_of_nb = {
489 .notifier_call = of_fpga_region_notify,
490};
491
492static int fpga_region_probe(struct platform_device *pdev)
493{
494 struct device *dev = &pdev->dev;
495 struct device_node *np = dev->of_node;
496 struct fpga_region *region;
497 int id, ret = 0; 167 int id, ret = 0;
498 168
499 region = kzalloc(sizeof(*region), GFP_KERNEL);
500 if (!region)
501 return -ENOMEM;
502
503 id = ida_simple_get(&fpga_region_ida, 0, 0, GFP_KERNEL); 169 id = ida_simple_get(&fpga_region_ida, 0, 0, GFP_KERNEL);
504 if (id < 0) { 170 if (id < 0)
505 ret = id; 171 return id;
506 goto err_kfree;
507 }
508 172
509 mutex_init(&region->mutex); 173 mutex_init(&region->mutex);
510 INIT_LIST_HEAD(&region->bridge_list); 174 INIT_LIST_HEAD(&region->bridge_list);
511
512 device_initialize(&region->dev); 175 device_initialize(&region->dev);
176 region->dev.groups = region->groups;
513 region->dev.class = fpga_region_class; 177 region->dev.class = fpga_region_class;
514 region->dev.parent = dev; 178 region->dev.parent = dev;
515 region->dev.of_node = np; 179 region->dev.of_node = dev->of_node;
516 region->dev.id = id; 180 region->dev.id = id;
517 dev_set_drvdata(dev, region); 181 dev_set_drvdata(dev, region);
518 182
@@ -524,44 +188,27 @@ static int fpga_region_probe(struct platform_device *pdev)
524 if (ret) 188 if (ret)
525 goto err_remove; 189 goto err_remove;
526 190
527 of_platform_populate(np, fpga_region_of_match, NULL, &region->dev);
528
529 dev_info(dev, "FPGA Region probed\n");
530
531 return 0; 191 return 0;
532 192
533err_remove: 193err_remove:
534 ida_simple_remove(&fpga_region_ida, id); 194 ida_simple_remove(&fpga_region_ida, id);
535err_kfree:
536 kfree(region);
537
538 return ret; 195 return ret;
539} 196}
197EXPORT_SYMBOL_GPL(fpga_region_register);
540 198
541static int fpga_region_remove(struct platform_device *pdev) 199int fpga_region_unregister(struct fpga_region *region)
542{ 200{
543 struct fpga_region *region = platform_get_drvdata(pdev);
544
545 device_unregister(&region->dev); 201 device_unregister(&region->dev);
546 202
547 return 0; 203 return 0;
548} 204}
549 205EXPORT_SYMBOL_GPL(fpga_region_unregister);
550static struct platform_driver fpga_region_driver = {
551 .probe = fpga_region_probe,
552 .remove = fpga_region_remove,
553 .driver = {
554 .name = "fpga-region",
555 .of_match_table = of_match_ptr(fpga_region_of_match),
556 },
557};
558 206
559static void fpga_region_dev_release(struct device *dev) 207static void fpga_region_dev_release(struct device *dev)
560{ 208{
561 struct fpga_region *region = to_fpga_region(dev); 209 struct fpga_region *region = to_fpga_region(dev);
562 210
563 ida_simple_remove(&fpga_region_ida, region->dev.id); 211 ida_simple_remove(&fpga_region_ida, region->dev.id);
564 kfree(region);
565} 212}
566 213
567/** 214/**
@@ -570,36 +217,17 @@ static void fpga_region_dev_release(struct device *dev)
570 */ 217 */
571static int __init fpga_region_init(void) 218static int __init fpga_region_init(void)
572{ 219{
573 int ret;
574
575 fpga_region_class = class_create(THIS_MODULE, "fpga_region"); 220 fpga_region_class = class_create(THIS_MODULE, "fpga_region");
576 if (IS_ERR(fpga_region_class)) 221 if (IS_ERR(fpga_region_class))
577 return PTR_ERR(fpga_region_class); 222 return PTR_ERR(fpga_region_class);
578 223
579 fpga_region_class->dev_release = fpga_region_dev_release; 224 fpga_region_class->dev_release = fpga_region_dev_release;
580 225
581 ret = of_overlay_notifier_register(&fpga_region_of_nb);
582 if (ret)
583 goto err_class;
584
585 ret = platform_driver_register(&fpga_region_driver);
586 if (ret)
587 goto err_plat;
588
589 return 0; 226 return 0;
590
591err_plat:
592 of_overlay_notifier_unregister(&fpga_region_of_nb);
593err_class:
594 class_destroy(fpga_region_class);
595 ida_destroy(&fpga_region_ida);
596 return ret;
597} 227}
598 228
599static void __exit fpga_region_exit(void) 229static void __exit fpga_region_exit(void)
600{ 230{
601 platform_driver_unregister(&fpga_region_driver);
602 of_overlay_notifier_unregister(&fpga_region_of_nb);
603 class_destroy(fpga_region_class); 231 class_destroy(fpga_region_class);
604 ida_destroy(&fpga_region_ida); 232 ida_destroy(&fpga_region_ida);
605} 233}
@@ -608,5 +236,5 @@ subsys_initcall(fpga_region_init);
608module_exit(fpga_region_exit); 236module_exit(fpga_region_exit);
609 237
610MODULE_DESCRIPTION("FPGA Region"); 238MODULE_DESCRIPTION("FPGA Region");
611MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>"); 239MODULE_AUTHOR("Alan Tull <atull@kernel.org>");
612MODULE_LICENSE("GPL v2"); 240MODULE_LICENSE("GPL v2");
diff --git a/drivers/fpga/of-fpga-region.c b/drivers/fpga/of-fpga-region.c
new file mode 100644
index 000000000000..119ff75522f1
--- /dev/null
+++ b/drivers/fpga/of-fpga-region.c
@@ -0,0 +1,504 @@
1/*
2 * FPGA Region - Device Tree support for FPGA programming under Linux
3 *
4 * Copyright (C) 2013-2016 Altera Corporation
5 * Copyright (C) 2017 Intel Corporation
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms and conditions of the GNU General Public License,
9 * version 2, as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * more details.
15 *
16 * You should have received a copy of the GNU General Public License along with
17 * this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/fpga/fpga-bridge.h>
21#include <linux/fpga/fpga-mgr.h>
22#include <linux/fpga/fpga-region.h>
23#include <linux/idr.h>
24#include <linux/kernel.h>
25#include <linux/list.h>
26#include <linux/module.h>
27#include <linux/of_platform.h>
28#include <linux/slab.h>
29#include <linux/spinlock.h>
30
31static const struct of_device_id fpga_region_of_match[] = {
32 { .compatible = "fpga-region", },
33 {},
34};
35MODULE_DEVICE_TABLE(of, fpga_region_of_match);
36
37static int fpga_region_of_node_match(struct device *dev, const void *data)
38{
39 return dev->of_node == data;
40}
41
42/**
43 * of_fpga_region_find - find FPGA region
44 * @np: device node of FPGA Region
45 *
46 * Caller will need to put_device(&region->dev) when done.
47 *
48 * Returns FPGA Region struct or NULL
49 */
50static struct fpga_region *of_fpga_region_find(struct device_node *np)
51{
52 return fpga_region_class_find(NULL, np, fpga_region_of_node_match);
53}
54
55/**
56 * of_fpga_region_get_mgr - get reference for FPGA manager
57 * @np: device node of FPGA region
58 *
59 * Get FPGA Manager from "fpga-mgr" property or from ancestor region.
60 *
61 * Caller should call fpga_mgr_put() when done with manager.
62 *
63 * Return: fpga manager struct or IS_ERR() condition containing error code.
64 */
65static struct fpga_manager *of_fpga_region_get_mgr(struct device_node *np)
66{
67 struct device_node *mgr_node;
68 struct fpga_manager *mgr;
69
70 of_node_get(np);
71 while (np) {
72 if (of_device_is_compatible(np, "fpga-region")) {
73 mgr_node = of_parse_phandle(np, "fpga-mgr", 0);
74 if (mgr_node) {
75 mgr = of_fpga_mgr_get(mgr_node);
76 of_node_put(mgr_node);
77 of_node_put(np);
78 return mgr;
79 }
80 }
81 np = of_get_next_parent(np);
82 }
83 of_node_put(np);
84
85 return ERR_PTR(-EINVAL);
86}
87
88/**
89 * of_fpga_region_get_bridges - create a list of bridges
90 * @region: FPGA region
91 *
92 * Create a list of bridges including the parent bridge and the bridges
93 * specified by "fpga-bridges" property. Note that the
94 * fpga_bridges_enable/disable/put functions are all fine with an empty list
95 * if that happens.
96 *
97 * Caller should call fpga_bridges_put(&region->bridge_list) when
98 * done with the bridges.
99 *
100 * Return 0 for success (even if there are no bridges specified)
101 * or -EBUSY if any of the bridges are in use.
102 */
103static int of_fpga_region_get_bridges(struct fpga_region *region)
104{
105 struct device *dev = &region->dev;
106 struct device_node *region_np = dev->of_node;
107 struct fpga_image_info *info = region->info;
108 struct device_node *br, *np, *parent_br = NULL;
109 int i, ret;
110
111 /* If parent is a bridge, add to list */
112 ret = of_fpga_bridge_get_to_list(region_np->parent, info,
113 &region->bridge_list);
114
115 /* -EBUSY means parent is a bridge that is under use. Give up. */
116 if (ret == -EBUSY)
117 return ret;
118
119 /* Zero return code means parent was a bridge and was added to list. */
120 if (!ret)
121 parent_br = region_np->parent;
122
123 /* If overlay has a list of bridges, use it. */
124 br = of_parse_phandle(info->overlay, "fpga-bridges", 0);
125 if (br) {
126 of_node_put(br);
127 np = info->overlay;
128 } else {
129 np = region_np;
130 }
131
132 for (i = 0; ; i++) {
133 br = of_parse_phandle(np, "fpga-bridges", i);
134 if (!br)
135 break;
136
137 /* If parent bridge is in list, skip it. */
138 if (br == parent_br) {
139 of_node_put(br);
140 continue;
141 }
142
143 /* If node is a bridge, get it and add to list */
144 ret = of_fpga_bridge_get_to_list(br, info,
145 &region->bridge_list);
146 of_node_put(br);
147
148 /* If any of the bridges are in use, give up */
149 if (ret == -EBUSY) {
150 fpga_bridges_put(&region->bridge_list);
151 return -EBUSY;
152 }
153 }
154
155 return 0;
156}
157
158/**
159 * child_regions_with_firmware
160 * @overlay: device node of the overlay
161 *
162 * If the overlay adds child FPGA regions, they are not allowed to have
163 * firmware-name property.
164 *
165 * Return 0 for OK or -EINVAL if child FPGA region adds firmware-name.
166 */
167static int child_regions_with_firmware(struct device_node *overlay)
168{
169 struct device_node *child_region;
170 const char *child_firmware_name;
171 int ret = 0;
172
173 of_node_get(overlay);
174
175 child_region = of_find_matching_node(overlay, fpga_region_of_match);
176 while (child_region) {
177 if (!of_property_read_string(child_region, "firmware-name",
178 &child_firmware_name)) {
179 ret = -EINVAL;
180 break;
181 }
182 child_region = of_find_matching_node(child_region,
183 fpga_region_of_match);
184 }
185
186 of_node_put(child_region);
187
188 if (ret)
189 pr_err("firmware-name not allowed in child FPGA region: %pOF",
190 child_region);
191
192 return ret;
193}
194
195/**
196 * of_fpga_region_parse_ov - parse and check overlay applied to region
197 *
198 * @region: FPGA region
199 * @overlay: overlay applied to the FPGA region
200 *
201 * Given an overlay applied to a FPGA region, parse the FPGA image specific
202 * info in the overlay and do some checking.
203 *
204 * Returns:
205 * NULL if overlay doesn't direct us to program the FPGA.
206 * fpga_image_info struct if there is an image to program.
207 * error code for invalid overlay.
208 */
209static struct fpga_image_info *of_fpga_region_parse_ov(
210 struct fpga_region *region,
211 struct device_node *overlay)
212{
213 struct device *dev = &region->dev;
214 struct fpga_image_info *info;
215 const char *firmware_name;
216 int ret;
217
218 if (region->info) {
219 dev_err(dev, "Region already has overlay applied.\n");
220 return ERR_PTR(-EINVAL);
221 }
222
223 /*
224 * Reject overlay if child FPGA Regions added in the overlay have
225 * firmware-name property (would mean that an FPGA region that has
226 * not been added to the live tree yet is doing FPGA programming).
227 */
228 ret = child_regions_with_firmware(overlay);
229 if (ret)
230 return ERR_PTR(ret);
231
232 info = fpga_image_info_alloc(dev);
233 if (!info)
234 return ERR_PTR(-ENOMEM);
235
236 info->overlay = overlay;
237
238 /* Read FPGA region properties from the overlay */
239 if (of_property_read_bool(overlay, "partial-fpga-config"))
240 info->flags |= FPGA_MGR_PARTIAL_RECONFIG;
241
242 if (of_property_read_bool(overlay, "external-fpga-config"))
243 info->flags |= FPGA_MGR_EXTERNAL_CONFIG;
244
245 if (of_property_read_bool(overlay, "encrypted-fpga-config"))
246 info->flags |= FPGA_MGR_ENCRYPTED_BITSTREAM;
247
248 if (!of_property_read_string(overlay, "firmware-name",
249 &firmware_name)) {
250 info->firmware_name = devm_kstrdup(dev, firmware_name,
251 GFP_KERNEL);
252 if (!info->firmware_name)
253 return ERR_PTR(-ENOMEM);
254 }
255
256 of_property_read_u32(overlay, "region-unfreeze-timeout-us",
257 &info->enable_timeout_us);
258
259 of_property_read_u32(overlay, "region-freeze-timeout-us",
260 &info->disable_timeout_us);
261
262 of_property_read_u32(overlay, "config-complete-timeout-us",
263 &info->config_complete_timeout_us);
264
265 /* If overlay is not programming the FPGA, don't need FPGA image info */
266 if (!info->firmware_name) {
267 ret = 0;
268 goto ret_no_info;
269 }
270
271 /*
272 * If overlay informs us FPGA was externally programmed, specifying
273 * firmware here would be ambiguous.
274 */
275 if (info->flags & FPGA_MGR_EXTERNAL_CONFIG) {
276 dev_err(dev, "error: specified firmware and external-fpga-config");
277 ret = -EINVAL;
278 goto ret_no_info;
279 }
280
281 return info;
282ret_no_info:
283 fpga_image_info_free(info);
284 return ERR_PTR(ret);
285}
286
287/**
288 * of_fpga_region_notify_pre_apply - pre-apply overlay notification
289 *
290 * @region: FPGA region that the overlay was applied to
291 * @nd: overlay notification data
292 *
293 * Called when an overlay targeted to a FPGA Region is about to be applied.
294 * Parses the overlay for properties that influence how the FPGA will be
295 * programmed and does some checking. If the checks pass, programs the FPGA.
296 * If the checks fail, overlay is rejected and does not get added to the
297 * live tree.
298 *
299 * Returns 0 for success or negative error code for failure.
300 */
301static int of_fpga_region_notify_pre_apply(struct fpga_region *region,
302 struct of_overlay_notify_data *nd)
303{
304 struct device *dev = &region->dev;
305 struct fpga_image_info *info;
306 int ret;
307
308 info = of_fpga_region_parse_ov(region, nd->overlay);
309 if (IS_ERR(info))
310 return PTR_ERR(info);
311
312 /* If overlay doesn't program the FPGA, accept it anyway. */
313 if (!info)
314 return 0;
315
316 if (region->info) {
317 dev_err(dev, "Region already has overlay applied.\n");
318 return -EINVAL;
319 }
320
321 region->info = info;
322 ret = fpga_region_program_fpga(region);
323 if (ret) {
324 /* error; reject overlay */
325 fpga_image_info_free(info);
326 region->info = NULL;
327 }
328
329 return ret;
330}
331
332/**
333 * of_fpga_region_notify_post_remove - post-remove overlay notification
334 *
335 * @region: FPGA region that was targeted by the overlay that was removed
336 * @nd: overlay notification data
337 *
338 * Called after an overlay has been removed if the overlay's target was a
339 * FPGA region.
340 */
341static void of_fpga_region_notify_post_remove(struct fpga_region *region,
342 struct of_overlay_notify_data *nd)
343{
344 fpga_bridges_disable(&region->bridge_list);
345 fpga_bridges_put(&region->bridge_list);
346 fpga_image_info_free(region->info);
347 region->info = NULL;
348}
349
350/**
351 * of_fpga_region_notify - reconfig notifier for dynamic DT changes
352 * @nb: notifier block
353 * @action: notifier action
354 * @arg: reconfig data
355 *
356 * This notifier handles programming a FPGA when a "firmware-name" property is
357 * added to a fpga-region.
358 *
359 * Returns NOTIFY_OK or error if FPGA programming fails.
360 */
361static int of_fpga_region_notify(struct notifier_block *nb,
362 unsigned long action, void *arg)
363{
364 struct of_overlay_notify_data *nd = arg;
365 struct fpga_region *region;
366 int ret;
367
368 switch (action) {
369 case OF_OVERLAY_PRE_APPLY:
370 pr_debug("%s OF_OVERLAY_PRE_APPLY\n", __func__);
371 break;
372 case OF_OVERLAY_POST_APPLY:
373 pr_debug("%s OF_OVERLAY_POST_APPLY\n", __func__);
374 return NOTIFY_OK; /* not for us */
375 case OF_OVERLAY_PRE_REMOVE:
376 pr_debug("%s OF_OVERLAY_PRE_REMOVE\n", __func__);
377 return NOTIFY_OK; /* not for us */
378 case OF_OVERLAY_POST_REMOVE:
379 pr_debug("%s OF_OVERLAY_POST_REMOVE\n", __func__);
380 break;
381 default: /* should not happen */
382 return NOTIFY_OK;
383 }
384
385 region = of_fpga_region_find(nd->target);
386 if (!region)
387 return NOTIFY_OK;
388
389 ret = 0;
390 switch (action) {
391 case OF_OVERLAY_PRE_APPLY:
392 ret = of_fpga_region_notify_pre_apply(region, nd);
393 break;
394
395 case OF_OVERLAY_POST_REMOVE:
396 of_fpga_region_notify_post_remove(region, nd);
397 break;
398 }
399
400 put_device(&region->dev);
401
402 if (ret)
403 return notifier_from_errno(ret);
404
405 return NOTIFY_OK;
406}
407
408static struct notifier_block fpga_region_of_nb = {
409 .notifier_call = of_fpga_region_notify,
410};
411
412static int of_fpga_region_probe(struct platform_device *pdev)
413{
414 struct device *dev = &pdev->dev;
415 struct device_node *np = dev->of_node;
416 struct fpga_region *region;
417 struct fpga_manager *mgr;
418 int ret;
419
420 /* Find the FPGA mgr specified by region or parent region. */
421 mgr = of_fpga_region_get_mgr(np);
422 if (IS_ERR(mgr))
423 return -EPROBE_DEFER;
424
425 region = devm_kzalloc(dev, sizeof(*region), GFP_KERNEL);
426 if (!region) {
427 ret = -ENOMEM;
428 goto eprobe_mgr_put;
429 }
430
431 region->mgr = mgr;
432
433 /* Specify how to get bridges for this type of region. */
434 region->get_bridges = of_fpga_region_get_bridges;
435
436 ret = fpga_region_register(dev, region);
437 if (ret)
438 goto eprobe_mgr_put;
439
440 of_platform_populate(np, fpga_region_of_match, NULL, &region->dev);
441
442 dev_info(dev, "FPGA Region probed\n");
443
444 return 0;
445
446eprobe_mgr_put:
447 fpga_mgr_put(mgr);
448 return ret;
449}
450
451static int of_fpga_region_remove(struct platform_device *pdev)
452{
453 struct fpga_region *region = platform_get_drvdata(pdev);
454
455 fpga_region_unregister(region);
456 fpga_mgr_put(region->mgr);
457
458 return 0;
459}
460
461static struct platform_driver of_fpga_region_driver = {
462 .probe = of_fpga_region_probe,
463 .remove = of_fpga_region_remove,
464 .driver = {
465 .name = "of-fpga-region",
466 .of_match_table = of_match_ptr(fpga_region_of_match),
467 },
468};
469
470/**
471 * fpga_region_init - init function for fpga_region class
472 * Creates the fpga_region class and registers a reconfig notifier.
473 */
474static int __init of_fpga_region_init(void)
475{
476 int ret;
477
478 ret = of_overlay_notifier_register(&fpga_region_of_nb);
479 if (ret)
480 return ret;
481
482 ret = platform_driver_register(&of_fpga_region_driver);
483 if (ret)
484 goto err_plat;
485
486 return 0;
487
488err_plat:
489 of_overlay_notifier_unregister(&fpga_region_of_nb);
490 return ret;
491}
492
493static void __exit of_fpga_region_exit(void)
494{
495 platform_driver_unregister(&of_fpga_region_driver);
496 of_overlay_notifier_unregister(&fpga_region_of_nb);
497}
498
499subsys_initcall(of_fpga_region_init);
500module_exit(of_fpga_region_exit);
501
502MODULE_DESCRIPTION("FPGA Region");
503MODULE_AUTHOR("Alan Tull <atull@kernel.org>");
504MODULE_LICENSE("GPL v2");
diff --git a/drivers/fpga/socfpga-a10.c b/drivers/fpga/socfpga-a10.c
index f8770af0f6b5..a46e343a5b72 100644
--- a/drivers/fpga/socfpga-a10.c
+++ b/drivers/fpga/socfpga-a10.c
@@ -519,8 +519,14 @@ static int socfpga_a10_fpga_probe(struct platform_device *pdev)
519 return -EBUSY; 519 return -EBUSY;
520 } 520 }
521 521
522 return fpga_mgr_register(dev, "SoCFPGA Arria10 FPGA Manager", 522 ret = fpga_mgr_register(dev, "SoCFPGA Arria10 FPGA Manager",
523 &socfpga_a10_fpga_mgr_ops, priv); 523 &socfpga_a10_fpga_mgr_ops, priv);
524 if (ret) {
525 clk_disable_unprepare(priv->clk);
526 return ret;
527 }
528
529 return 0;
524} 530}
525 531
526static int socfpga_a10_fpga_remove(struct platform_device *pdev) 532static int socfpga_a10_fpga_remove(struct platform_device *pdev)