aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/fpga
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2018-06-05 19:20:22 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2018-06-05 19:20:22 -0400
commitabf7dba7c4f77d781f6df50fefb19a64c5dc331f (patch)
tree38648731b502d5aec508f3b33f6616190e598eb6 /drivers/fpga
parent07c4dd3435aa387d3b58f4e941dc516513f14507 (diff)
parentb23220fe054e92f616b82450fae8cd3ab176cc60 (diff)
Merge tag 'char-misc-4.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc
Pull char/misc driver updates from Greg KH: "Here is the "big" char and misc driver patches for 4.18-rc1. It's not a lot of stuff here, but there are some highlights: - coreboot driver updates - soundwire driver updates - android binder updates - fpga big sync, mostly documentation - lots of minor driver updates All of these have been in linux-next for a while with no reported issues" * tag 'char-misc-4.18-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/char-misc: (81 commits) vmw_balloon: fixing double free when batching mode is off MAINTAINERS: Add driver-api/fpga path fpga: clarify that unregister functions also free documentation: fpga: move fpga-region.txt to driver-api documentation: fpga: add bridge document to driver-api documentation: fpga: move fpga-mgr.txt to driver-api Documentation: fpga: move fpga overview to driver-api fpga: region: kernel-doc fixes fpga: bridge: kernel-doc fixes fpga: mgr: kernel-doc fixes fpga: use SPDX fpga: region: change api, add fpga_region_create/free fpga: bridge: change api, don't use drvdata fpga: manager: change api, don't use drvdata fpga: region: don't use drvdata in common fpga code Drivers: hv: vmbus: Removed an unnecessary cast from void * ver_linux: Drop redundant calls to system() to test if file is readable ver_linux: Move stderr redirection from function parameter to function body misc: IBM Virtual Management Channel Driver (VMC) rpmsg: Correct support for MODULE_DEVICE_TABLE() ...
Diffstat (limited to 'drivers/fpga')
-rw-r--r--drivers/fpga/Kconfig8
-rw-r--r--drivers/fpga/Makefile1
-rw-r--r--drivers/fpga/altera-cvp.c19
-rw-r--r--drivers/fpga/altera-fpga2sdram.c34
-rw-r--r--drivers/fpga/altera-freeze-bridge.c35
-rw-r--r--drivers/fpga/altera-hps2fpga.c37
-rw-r--r--drivers/fpga/altera-pr-ip-core-plat.c13
-rw-r--r--drivers/fpga/altera-pr-ip-core.c31
-rw-r--r--drivers/fpga/altera-ps-spi.c20
-rw-r--r--drivers/fpga/fpga-bridge.c86
-rw-r--r--drivers/fpga/fpga-mgr.c129
-rw-r--r--drivers/fpga/fpga-region.c91
-rw-r--r--drivers/fpga/ice40-spi.c21
-rw-r--r--drivers/fpga/machxo2-spi.c415
-rw-r--r--drivers/fpga/of-fpga-region.c28
-rw-r--r--drivers/fpga/socfpga-a10.c28
-rw-r--r--drivers/fpga/socfpga.c32
-rw-r--r--drivers/fpga/ts73xx-fpga.c20
-rw-r--r--drivers/fpga/xilinx-pr-decoupler.c22
-rw-r--r--drivers/fpga/xilinx-spi.c20
-rw-r--r--drivers/fpga/zynq-fpga.c14
21 files changed, 839 insertions, 265 deletions
diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index f47ef848bcd0..ee9c5420c47f 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -53,7 +53,6 @@ config FPGA_MGR_ALTERA_CVP
53config FPGA_MGR_ZYNQ_FPGA 53config FPGA_MGR_ZYNQ_FPGA
54 tristate "Xilinx Zynq FPGA" 54 tristate "Xilinx Zynq FPGA"
55 depends on ARCH_ZYNQ || COMPILE_TEST 55 depends on ARCH_ZYNQ || COMPILE_TEST
56 depends on HAS_DMA
57 help 56 help
58 FPGA manager driver support for Xilinx Zynq FPGAs. 57 FPGA manager driver support for Xilinx Zynq FPGAs.
59 58
@@ -70,6 +69,13 @@ config FPGA_MGR_ICE40_SPI
70 help 69 help
71 FPGA manager driver support for Lattice iCE40 FPGAs over SPI. 70 FPGA manager driver support for Lattice iCE40 FPGAs over SPI.
72 71
72config FPGA_MGR_MACHXO2_SPI
73 tristate "Lattice MachXO2 SPI"
74 depends on SPI
75 help
76 FPGA manager driver support for Lattice MachXO2 configuration
77 over slave SPI interface.
78
73config FPGA_MGR_TS73XX 79config FPGA_MGR_TS73XX
74 tristate "Technologic Systems TS-73xx SBC FPGA Manager" 80 tristate "Technologic Systems TS-73xx SBC FPGA Manager"
75 depends on ARCH_EP93XX && MACH_TS72XX 81 depends on ARCH_EP93XX && MACH_TS72XX
diff --git a/drivers/fpga/Makefile b/drivers/fpga/Makefile
index 3cb276a0f88d..f9803dad6919 100644
--- a/drivers/fpga/Makefile
+++ b/drivers/fpga/Makefile
@@ -10,6 +10,7 @@ obj-$(CONFIG_FPGA) += fpga-mgr.o
10obj-$(CONFIG_FPGA_MGR_ALTERA_CVP) += altera-cvp.o 10obj-$(CONFIG_FPGA_MGR_ALTERA_CVP) += altera-cvp.o
11obj-$(CONFIG_FPGA_MGR_ALTERA_PS_SPI) += altera-ps-spi.o 11obj-$(CONFIG_FPGA_MGR_ALTERA_PS_SPI) += altera-ps-spi.o
12obj-$(CONFIG_FPGA_MGR_ICE40_SPI) += ice40-spi.o 12obj-$(CONFIG_FPGA_MGR_ICE40_SPI) += ice40-spi.o
13obj-$(CONFIG_FPGA_MGR_MACHXO2_SPI) += machxo2-spi.o
13obj-$(CONFIG_FPGA_MGR_SOCFPGA) += socfpga.o 14obj-$(CONFIG_FPGA_MGR_SOCFPGA) += socfpga.o
14obj-$(CONFIG_FPGA_MGR_SOCFPGA_A10) += socfpga-a10.o 15obj-$(CONFIG_FPGA_MGR_SOCFPGA_A10) += socfpga-a10.o
15obj-$(CONFIG_FPGA_MGR_TS73XX) += ts73xx-fpga.o 16obj-$(CONFIG_FPGA_MGR_TS73XX) += ts73xx-fpga.o
diff --git a/drivers/fpga/altera-cvp.c b/drivers/fpga/altera-cvp.c
index 77b04e4b3254..dd4edd8f22ce 100644
--- a/drivers/fpga/altera-cvp.c
+++ b/drivers/fpga/altera-cvp.c
@@ -401,6 +401,7 @@ static int altera_cvp_probe(struct pci_dev *pdev,
401 const struct pci_device_id *dev_id) 401 const struct pci_device_id *dev_id)
402{ 402{
403 struct altera_cvp_conf *conf; 403 struct altera_cvp_conf *conf;
404 struct fpga_manager *mgr;
404 u16 cmd, val; 405 u16 cmd, val;
405 int ret; 406 int ret;
406 407
@@ -452,16 +453,24 @@ static int altera_cvp_probe(struct pci_dev *pdev,
452 snprintf(conf->mgr_name, sizeof(conf->mgr_name), "%s @%s", 453 snprintf(conf->mgr_name, sizeof(conf->mgr_name), "%s @%s",
453 ALTERA_CVP_MGR_NAME, pci_name(pdev)); 454 ALTERA_CVP_MGR_NAME, pci_name(pdev));
454 455
455 ret = fpga_mgr_register(&pdev->dev, conf->mgr_name, 456 mgr = fpga_mgr_create(&pdev->dev, conf->mgr_name,
456 &altera_cvp_ops, conf); 457 &altera_cvp_ops, conf);
457 if (ret) 458 if (!mgr)
459 return -ENOMEM;
460
461 pci_set_drvdata(pdev, mgr);
462
463 ret = fpga_mgr_register(mgr);
464 if (ret) {
465 fpga_mgr_free(mgr);
458 goto err_unmap; 466 goto err_unmap;
467 }
459 468
460 ret = driver_create_file(&altera_cvp_driver.driver, 469 ret = driver_create_file(&altera_cvp_driver.driver,
461 &driver_attr_chkcfg); 470 &driver_attr_chkcfg);
462 if (ret) { 471 if (ret) {
463 dev_err(&pdev->dev, "Can't create sysfs chkcfg file\n"); 472 dev_err(&pdev->dev, "Can't create sysfs chkcfg file\n");
464 fpga_mgr_unregister(&pdev->dev); 473 fpga_mgr_unregister(mgr);
465 goto err_unmap; 474 goto err_unmap;
466 } 475 }
467 476
@@ -483,7 +492,7 @@ static void altera_cvp_remove(struct pci_dev *pdev)
483 u16 cmd; 492 u16 cmd;
484 493
485 driver_remove_file(&altera_cvp_driver.driver, &driver_attr_chkcfg); 494 driver_remove_file(&altera_cvp_driver.driver, &driver_attr_chkcfg);
486 fpga_mgr_unregister(&pdev->dev); 495 fpga_mgr_unregister(mgr);
487 pci_iounmap(pdev, conf->map); 496 pci_iounmap(pdev, conf->map);
488 pci_release_region(pdev, CVP_BAR); 497 pci_release_region(pdev, CVP_BAR);
489 pci_read_config_word(pdev, PCI_COMMAND, &cmd); 498 pci_read_config_word(pdev, PCI_COMMAND, &cmd);
diff --git a/drivers/fpga/altera-fpga2sdram.c b/drivers/fpga/altera-fpga2sdram.c
index d4eeb74388da..23660ccd634b 100644
--- a/drivers/fpga/altera-fpga2sdram.c
+++ b/drivers/fpga/altera-fpga2sdram.c
@@ -1,19 +1,8 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * FPGA to SDRAM Bridge Driver for Altera SoCFPGA Devices 3 * FPGA to SDRAM Bridge Driver for Altera SoCFPGA Devices
3 * 4 *
4 * Copyright (C) 2013-2016 Altera Corporation, All Rights Reserved. 5 * Copyright (C) 2013-2016 Altera Corporation, All Rights Reserved.
5 *
6 * 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 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * 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 */ 6 */
18 7
19/* 8/*
@@ -106,6 +95,7 @@ static int alt_fpga_bridge_probe(struct platform_device *pdev)
106{ 95{
107 struct device *dev = &pdev->dev; 96 struct device *dev = &pdev->dev;
108 struct alt_fpga2sdram_data *priv; 97 struct alt_fpga2sdram_data *priv;
98 struct fpga_bridge *br;
109 u32 enable; 99 u32 enable;
110 struct regmap *sysmgr; 100 struct regmap *sysmgr;
111 int ret = 0; 101 int ret = 0;
@@ -131,10 +121,18 @@ static int alt_fpga_bridge_probe(struct platform_device *pdev)
131 /* Get f2s bridge configuration saved in handoff register */ 121 /* Get f2s bridge configuration saved in handoff register */
132 regmap_read(sysmgr, SYSMGR_ISWGRP_HANDOFF3, &priv->mask); 122 regmap_read(sysmgr, SYSMGR_ISWGRP_HANDOFF3, &priv->mask);
133 123
134 ret = fpga_bridge_register(dev, F2S_BRIDGE_NAME, 124 br = fpga_bridge_create(dev, F2S_BRIDGE_NAME,
135 &altera_fpga2sdram_br_ops, priv); 125 &altera_fpga2sdram_br_ops, priv);
136 if (ret) 126 if (!br)
127 return -ENOMEM;
128
129 platform_set_drvdata(pdev, br);
130
131 ret = fpga_bridge_register(br);
132 if (ret) {
133 fpga_bridge_free(br);
137 return ret; 134 return ret;
135 }
138 136
139 dev_info(dev, "driver initialized with handoff %08x\n", priv->mask); 137 dev_info(dev, "driver initialized with handoff %08x\n", priv->mask);
140 138
@@ -146,7 +144,7 @@ static int alt_fpga_bridge_probe(struct platform_device *pdev)
146 (enable ? "enabling" : "disabling")); 144 (enable ? "enabling" : "disabling"));
147 ret = _alt_fpga2sdram_enable_set(priv, enable); 145 ret = _alt_fpga2sdram_enable_set(priv, enable);
148 if (ret) { 146 if (ret) {
149 fpga_bridge_unregister(&pdev->dev); 147 fpga_bridge_unregister(br);
150 return ret; 148 return ret;
151 } 149 }
152 } 150 }
@@ -157,7 +155,9 @@ static int alt_fpga_bridge_probe(struct platform_device *pdev)
157 155
158static int alt_fpga_bridge_remove(struct platform_device *pdev) 156static int alt_fpga_bridge_remove(struct platform_device *pdev)
159{ 157{
160 fpga_bridge_unregister(&pdev->dev); 158 struct fpga_bridge *br = platform_get_drvdata(pdev);
159
160 fpga_bridge_unregister(br);
161 161
162 return 0; 162 return 0;
163} 163}
diff --git a/drivers/fpga/altera-freeze-bridge.c b/drivers/fpga/altera-freeze-bridge.c
index 6159cfcf78a2..ffd586c48ecf 100644
--- a/drivers/fpga/altera-freeze-bridge.c
+++ b/drivers/fpga/altera-freeze-bridge.c
@@ -1,19 +1,8 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * FPGA Freeze Bridge Controller 3 * FPGA Freeze Bridge Controller
3 * 4 *
4 * Copyright (C) 2016 Altera Corporation. All rights reserved. 5 * Copyright (C) 2016 Altera Corporation. All rights reserved.
5 *
6 * 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 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * 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 */ 6 */
18#include <linux/delay.h> 7#include <linux/delay.h>
19#include <linux/io.h> 8#include <linux/io.h>
@@ -221,8 +210,10 @@ static int altera_freeze_br_probe(struct platform_device *pdev)
221 struct device_node *np = pdev->dev.of_node; 210 struct device_node *np = pdev->dev.of_node;
222 void __iomem *base_addr; 211 void __iomem *base_addr;
223 struct altera_freeze_br_data *priv; 212 struct altera_freeze_br_data *priv;
213 struct fpga_bridge *br;
224 struct resource *res; 214 struct resource *res;
225 u32 status, revision; 215 u32 status, revision;
216 int ret;
226 217
227 if (!np) 218 if (!np)
228 return -ENODEV; 219 return -ENODEV;
@@ -254,13 +245,27 @@ static int altera_freeze_br_probe(struct platform_device *pdev)
254 245
255 priv->base_addr = base_addr; 246 priv->base_addr = base_addr;
256 247
257 return fpga_bridge_register(dev, FREEZE_BRIDGE_NAME, 248 br = fpga_bridge_create(dev, FREEZE_BRIDGE_NAME,
258 &altera_freeze_br_br_ops, priv); 249 &altera_freeze_br_br_ops, priv);
250 if (!br)
251 return -ENOMEM;
252
253 platform_set_drvdata(pdev, br);
254
255 ret = fpga_bridge_register(br);
256 if (ret) {
257 fpga_bridge_free(br);
258 return ret;
259 }
260
261 return 0;
259} 262}
260 263
261static int altera_freeze_br_remove(struct platform_device *pdev) 264static int altera_freeze_br_remove(struct platform_device *pdev)
262{ 265{
263 fpga_bridge_unregister(&pdev->dev); 266 struct fpga_bridge *br = platform_get_drvdata(pdev);
267
268 fpga_bridge_unregister(br);
264 269
265 return 0; 270 return 0;
266} 271}
diff --git a/drivers/fpga/altera-hps2fpga.c b/drivers/fpga/altera-hps2fpga.c
index 406d2f10741f..a974d3f60321 100644
--- a/drivers/fpga/altera-hps2fpga.c
+++ b/drivers/fpga/altera-hps2fpga.c
@@ -1,3 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * FPGA to/from HPS Bridge Driver for Altera SoCFPGA Devices 3 * FPGA to/from HPS Bridge Driver for Altera SoCFPGA Devices
3 * 4 *
@@ -6,18 +7,6 @@
6 * Includes this patch from the mailing list: 7 * Includes this patch from the mailing list:
7 * fpga: altera-hps2fpga: fix HPS2FPGA bridge visibility to L3 masters 8 * fpga: altera-hps2fpga: fix HPS2FPGA bridge visibility to L3 masters
8 * Signed-off-by: Anatolij Gustschin <agust@denx.de> 9 * Signed-off-by: Anatolij Gustschin <agust@denx.de>
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms and conditions of the GNU General Public License,
12 * version 2, as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * more details.
18 *
19 * You should have received a copy of the GNU General Public License along with
20 * this program. If not, see <http://www.gnu.org/licenses/>.
21 */ 10 */
22 11
23/* 12/*
@@ -139,6 +128,7 @@ static int alt_fpga_bridge_probe(struct platform_device *pdev)
139 struct device *dev = &pdev->dev; 128 struct device *dev = &pdev->dev;
140 struct altera_hps2fpga_data *priv; 129 struct altera_hps2fpga_data *priv;
141 const struct of_device_id *of_id; 130 const struct of_device_id *of_id;
131 struct fpga_bridge *br;
142 u32 enable; 132 u32 enable;
143 int ret; 133 int ret;
144 134
@@ -190,11 +180,24 @@ static int alt_fpga_bridge_probe(struct platform_device *pdev)
190 } 180 }
191 } 181 }
192 182
193 ret = fpga_bridge_register(dev, priv->name, &altera_hps2fpga_br_ops, 183 br = fpga_bridge_create(dev, priv->name, &altera_hps2fpga_br_ops, priv);
194 priv); 184 if (!br) {
195err: 185 ret = -ENOMEM;
186 goto err;
187 }
188
189 platform_set_drvdata(pdev, br);
190
191 ret = fpga_bridge_register(br);
196 if (ret) 192 if (ret)
197 clk_disable_unprepare(priv->clk); 193 goto err_free;
194
195 return 0;
196
197err_free:
198 fpga_bridge_free(br);
199err:
200 clk_disable_unprepare(priv->clk);
198 201
199 return ret; 202 return ret;
200} 203}
@@ -204,7 +207,7 @@ static int alt_fpga_bridge_remove(struct platform_device *pdev)
204 struct fpga_bridge *bridge = platform_get_drvdata(pdev); 207 struct fpga_bridge *bridge = platform_get_drvdata(pdev);
205 struct altera_hps2fpga_data *priv = bridge->priv; 208 struct altera_hps2fpga_data *priv = bridge->priv;
206 209
207 fpga_bridge_unregister(&pdev->dev); 210 fpga_bridge_unregister(bridge);
208 211
209 clk_disable_unprepare(priv->clk); 212 clk_disable_unprepare(priv->clk);
210 213
diff --git a/drivers/fpga/altera-pr-ip-core-plat.c b/drivers/fpga/altera-pr-ip-core-plat.c
index 8fb36b8b4648..b293d83143f1 100644
--- a/drivers/fpga/altera-pr-ip-core-plat.c
+++ b/drivers/fpga/altera-pr-ip-core-plat.c
@@ -1,3 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Driver for Altera Partial Reconfiguration IP Core 3 * Driver for Altera Partial Reconfiguration IP Core
3 * 4 *
@@ -5,18 +6,6 @@
5 * 6 *
6 * Based on socfpga-a10.c Copyright (C) 2015-2016 Altera Corporation 7 * Based on socfpga-a10.c Copyright (C) 2015-2016 Altera Corporation
7 * by Alan Tull <atull@opensource.altera.com> 8 * by Alan Tull <atull@opensource.altera.com>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms and conditions of the GNU General Public License,
11 * version 2, as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * this program. If not, see <http://www.gnu.org/licenses/>.
20 */ 9 */
21#include <linux/fpga/altera-pr-ip-core.h> 10#include <linux/fpga/altera-pr-ip-core.h>
22#include <linux/module.h> 11#include <linux/module.h>
diff --git a/drivers/fpga/altera-pr-ip-core.c b/drivers/fpga/altera-pr-ip-core.c
index a7b31f9797ce..65e0b6a2c031 100644
--- a/drivers/fpga/altera-pr-ip-core.c
+++ b/drivers/fpga/altera-pr-ip-core.c
@@ -1,3 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * Driver for Altera Partial Reconfiguration IP Core 3 * Driver for Altera Partial Reconfiguration IP Core
3 * 4 *
@@ -5,18 +6,6 @@
5 * 6 *
6 * Based on socfpga-a10.c Copyright (C) 2015-2016 Altera Corporation 7 * Based on socfpga-a10.c Copyright (C) 2015-2016 Altera Corporation
7 * by Alan Tull <atull@opensource.altera.com> 8 * by Alan Tull <atull@opensource.altera.com>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms and conditions of the GNU General Public License,
11 * version 2, as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 * You should have received a copy of the GNU General Public License along with
19 * this program. If not, see <http://www.gnu.org/licenses/>.
20 */ 9 */
21#include <linux/delay.h> 10#include <linux/delay.h>
22#include <linux/fpga/altera-pr-ip-core.h> 11#include <linux/fpga/altera-pr-ip-core.h>
@@ -187,6 +176,8 @@ static const struct fpga_manager_ops alt_pr_ops = {
187int alt_pr_register(struct device *dev, void __iomem *reg_base) 176int alt_pr_register(struct device *dev, void __iomem *reg_base)
188{ 177{
189 struct alt_pr_priv *priv; 178 struct alt_pr_priv *priv;
179 struct fpga_manager *mgr;
180 int ret;
190 u32 val; 181 u32 val;
191 182
192 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL); 183 priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -201,15 +192,27 @@ int alt_pr_register(struct device *dev, void __iomem *reg_base)
201 (val & ALT_PR_CSR_STATUS_MSK) >> ALT_PR_CSR_STATUS_SFT, 192 (val & ALT_PR_CSR_STATUS_MSK) >> ALT_PR_CSR_STATUS_SFT,
202 (int)(val & ALT_PR_CSR_PR_START)); 193 (int)(val & ALT_PR_CSR_PR_START));
203 194
204 return fpga_mgr_register(dev, dev_name(dev), &alt_pr_ops, priv); 195 mgr = fpga_mgr_create(dev, dev_name(dev), &alt_pr_ops, priv);
196 if (!mgr)
197 return -ENOMEM;
198
199 dev_set_drvdata(dev, mgr);
200
201 ret = fpga_mgr_register(mgr);
202 if (ret)
203 fpga_mgr_free(mgr);
204
205 return ret;
205} 206}
206EXPORT_SYMBOL_GPL(alt_pr_register); 207EXPORT_SYMBOL_GPL(alt_pr_register);
207 208
208int alt_pr_unregister(struct device *dev) 209int alt_pr_unregister(struct device *dev)
209{ 210{
211 struct fpga_manager *mgr = dev_get_drvdata(dev);
212
210 dev_dbg(dev, "%s\n", __func__); 213 dev_dbg(dev, "%s\n", __func__);
211 214
212 fpga_mgr_unregister(dev); 215 fpga_mgr_unregister(mgr);
213 216
214 return 0; 217 return 0;
215} 218}
diff --git a/drivers/fpga/altera-ps-spi.c b/drivers/fpga/altera-ps-spi.c
index 06d212a3d49d..24b25c626036 100644
--- a/drivers/fpga/altera-ps-spi.c
+++ b/drivers/fpga/altera-ps-spi.c
@@ -238,6 +238,8 @@ static int altera_ps_probe(struct spi_device *spi)
238{ 238{
239 struct altera_ps_conf *conf; 239 struct altera_ps_conf *conf;
240 const struct of_device_id *of_id; 240 const struct of_device_id *of_id;
241 struct fpga_manager *mgr;
242 int ret;
241 243
242 conf = devm_kzalloc(&spi->dev, sizeof(*conf), GFP_KERNEL); 244 conf = devm_kzalloc(&spi->dev, sizeof(*conf), GFP_KERNEL);
243 if (!conf) 245 if (!conf)
@@ -273,13 +275,25 @@ static int altera_ps_probe(struct spi_device *spi)
273 snprintf(conf->mgr_name, sizeof(conf->mgr_name), "%s %s", 275 snprintf(conf->mgr_name, sizeof(conf->mgr_name), "%s %s",
274 dev_driver_string(&spi->dev), dev_name(&spi->dev)); 276 dev_driver_string(&spi->dev), dev_name(&spi->dev));
275 277
276 return fpga_mgr_register(&spi->dev, conf->mgr_name, 278 mgr = fpga_mgr_create(&spi->dev, conf->mgr_name,
277 &altera_ps_ops, conf); 279 &altera_ps_ops, conf);
280 if (!mgr)
281 return -ENOMEM;
282
283 spi_set_drvdata(spi, mgr);
284
285 ret = fpga_mgr_register(mgr);
286 if (ret)
287 fpga_mgr_free(mgr);
288
289 return ret;
278} 290}
279 291
280static int altera_ps_remove(struct spi_device *spi) 292static int altera_ps_remove(struct spi_device *spi)
281{ 293{
282 fpga_mgr_unregister(&spi->dev); 294 struct fpga_manager *mgr = spi_get_drvdata(spi);
295
296 fpga_mgr_unregister(mgr);
283 297
284 return 0; 298 return 0;
285} 299}
diff --git a/drivers/fpga/fpga-bridge.c b/drivers/fpga/fpga-bridge.c
index 31bd2c59c305..24b8f98b73ec 100644
--- a/drivers/fpga/fpga-bridge.c
+++ b/drivers/fpga/fpga-bridge.c
@@ -1,20 +1,9 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * FPGA Bridge Framework Driver 3 * FPGA Bridge Framework Driver
3 * 4 *
4 * Copyright (C) 2013-2016 Altera Corporation, All Rights Reserved. 5 * Copyright (C) 2013-2016 Altera Corporation, All Rights Reserved.
5 * Copyright (C) 2017 Intel Corporation 6 * 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 */ 7 */
19#include <linux/fpga/fpga-bridge.h> 8#include <linux/fpga/fpga-bridge.h>
20#include <linux/idr.h> 9#include <linux/idr.h>
@@ -132,6 +121,7 @@ static int fpga_bridge_dev_match(struct device *dev, const void *data)
132/** 121/**
133 * fpga_bridge_get - get an exclusive reference to a fpga bridge 122 * fpga_bridge_get - get an exclusive reference to a fpga bridge
134 * @dev: parent device that fpga bridge was registered with 123 * @dev: parent device that fpga bridge was registered with
124 * @info: fpga manager info
135 * 125 *
136 * Given a device, get an exclusive reference to a fpga bridge. 126 * Given a device, get an exclusive reference to a fpga bridge.
137 * 127 *
@@ -328,28 +318,29 @@ static struct attribute *fpga_bridge_attrs[] = {
328ATTRIBUTE_GROUPS(fpga_bridge); 318ATTRIBUTE_GROUPS(fpga_bridge);
329 319
330/** 320/**
331 * fpga_bridge_register - register a fpga bridge driver 321 * fpga_bridge_create - create and initialize a struct fpga_bridge
332 * @dev: FPGA bridge device from pdev 322 * @dev: FPGA bridge device from pdev
333 * @name: FPGA bridge name 323 * @name: FPGA bridge name
334 * @br_ops: pointer to structure of fpga bridge ops 324 * @br_ops: pointer to structure of fpga bridge ops
335 * @priv: FPGA bridge private data 325 * @priv: FPGA bridge private data
336 * 326 *
337 * Return: 0 for success, error code otherwise. 327 * Return: struct fpga_bridge or NULL
338 */ 328 */
339int fpga_bridge_register(struct device *dev, const char *name, 329struct fpga_bridge *fpga_bridge_create(struct device *dev, const char *name,
340 const struct fpga_bridge_ops *br_ops, void *priv) 330 const struct fpga_bridge_ops *br_ops,
331 void *priv)
341{ 332{
342 struct fpga_bridge *bridge; 333 struct fpga_bridge *bridge;
343 int id, ret = 0; 334 int id, ret = 0;
344 335
345 if (!name || !strlen(name)) { 336 if (!name || !strlen(name)) {
346 dev_err(dev, "Attempt to register with no name!\n"); 337 dev_err(dev, "Attempt to register with no name!\n");
347 return -EINVAL; 338 return NULL;
348 } 339 }
349 340
350 bridge = kzalloc(sizeof(*bridge), GFP_KERNEL); 341 bridge = kzalloc(sizeof(*bridge), GFP_KERNEL);
351 if (!bridge) 342 if (!bridge)
352 return -ENOMEM; 343 return NULL;
353 344
354 id = ida_simple_get(&fpga_bridge_ida, 0, 0, GFP_KERNEL); 345 id = ida_simple_get(&fpga_bridge_ida, 0, 0, GFP_KERNEL);
355 if (id < 0) { 346 if (id < 0) {
@@ -370,40 +361,62 @@ int fpga_bridge_register(struct device *dev, const char *name,
370 bridge->dev.parent = dev; 361 bridge->dev.parent = dev;
371 bridge->dev.of_node = dev->of_node; 362 bridge->dev.of_node = dev->of_node;
372 bridge->dev.id = id; 363 bridge->dev.id = id;
373 dev_set_drvdata(dev, bridge);
374 364
375 ret = dev_set_name(&bridge->dev, "br%d", id); 365 ret = dev_set_name(&bridge->dev, "br%d", id);
376 if (ret) 366 if (ret)
377 goto error_device; 367 goto error_device;
378 368
379 ret = device_add(&bridge->dev); 369 return bridge;
380 if (ret)
381 goto error_device;
382
383 of_platform_populate(dev->of_node, NULL, NULL, dev);
384
385 dev_info(bridge->dev.parent, "fpga bridge [%s] registered\n",
386 bridge->name);
387
388 return 0;
389 370
390error_device: 371error_device:
391 ida_simple_remove(&fpga_bridge_ida, id); 372 ida_simple_remove(&fpga_bridge_ida, id);
392error_kfree: 373error_kfree:
393 kfree(bridge); 374 kfree(bridge);
394 375
395 return ret; 376 return NULL;
396} 377}
397EXPORT_SYMBOL_GPL(fpga_bridge_register); 378EXPORT_SYMBOL_GPL(fpga_bridge_create);
398 379
399/** 380/**
400 * fpga_bridge_unregister - unregister a fpga bridge driver 381 * fpga_bridge_free - free a fpga bridge and its id
401 * @dev: FPGA bridge device from pdev 382 * @bridge: FPGA bridge struct created by fpga_bridge_create
402 */ 383 */
403void fpga_bridge_unregister(struct device *dev) 384void fpga_bridge_free(struct fpga_bridge *bridge)
404{ 385{
405 struct fpga_bridge *bridge = dev_get_drvdata(dev); 386 ida_simple_remove(&fpga_bridge_ida, bridge->dev.id);
387 kfree(bridge);
388}
389EXPORT_SYMBOL_GPL(fpga_bridge_free);
406 390
391/**
392 * fpga_bridge_register - register a fpga bridge
393 * @bridge: FPGA bridge struct created by fpga_bridge_create
394 *
395 * Return: 0 for success, error code otherwise.
396 */
397int fpga_bridge_register(struct fpga_bridge *bridge)
398{
399 struct device *dev = &bridge->dev;
400 int ret;
401
402 ret = device_add(dev);
403 if (ret)
404 return ret;
405
406 of_platform_populate(dev->of_node, NULL, NULL, dev);
407
408 dev_info(dev->parent, "fpga bridge [%s] registered\n", bridge->name);
409
410 return 0;
411}
412EXPORT_SYMBOL_GPL(fpga_bridge_register);
413
414/**
415 * fpga_bridge_unregister - unregister and free a fpga bridge
416 * @bridge: FPGA bridge struct created by fpga_bridge_create
417 */
418void fpga_bridge_unregister(struct fpga_bridge *bridge)
419{
407 /* 420 /*
408 * If the low level driver provides a method for putting bridge into 421 * If the low level driver provides a method for putting bridge into
409 * a desired state upon unregister, do it. 422 * a desired state upon unregister, do it.
@@ -419,8 +432,7 @@ static void fpga_bridge_dev_release(struct device *dev)
419{ 432{
420 struct fpga_bridge *bridge = to_fpga_bridge(dev); 433 struct fpga_bridge *bridge = to_fpga_bridge(dev);
421 434
422 ida_simple_remove(&fpga_bridge_ida, bridge->dev.id); 435 fpga_bridge_free(bridge);
423 kfree(bridge);
424} 436}
425 437
426static int __init fpga_bridge_dev_init(void) 438static int __init fpga_bridge_dev_init(void)
diff --git a/drivers/fpga/fpga-mgr.c b/drivers/fpga/fpga-mgr.c
index 9939d2cbc9a6..c1564cf827fe 100644
--- a/drivers/fpga/fpga-mgr.c
+++ b/drivers/fpga/fpga-mgr.c
@@ -1,3 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * FPGA Manager Core 3 * FPGA Manager Core
3 * 4 *
@@ -6,18 +7,6 @@
6 * 7 *
7 * With code from the mailing list: 8 * With code from the mailing list:
8 * Copyright (C) 2013 Xilinx, Inc. 9 * Copyright (C) 2013 Xilinx, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms and conditions of the GNU General Public License,
12 * version 2, as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
17 * more details.
18 *
19 * You should have received a copy of the GNU General Public License along with
20 * this program. If not, see <http://www.gnu.org/licenses/>.
21 */ 10 */
22#include <linux/firmware.h> 11#include <linux/firmware.h>
23#include <linux/fpga/fpga-mgr.h> 12#include <linux/fpga/fpga-mgr.h>
@@ -32,6 +21,12 @@
32static DEFINE_IDA(fpga_mgr_ida); 21static DEFINE_IDA(fpga_mgr_ida);
33static struct class *fpga_mgr_class; 22static struct class *fpga_mgr_class;
34 23
24/**
25 * fpga_image_info_alloc - Allocate a FPGA image info struct
26 * @dev: owning device
27 *
28 * Return: struct fpga_image_info or NULL
29 */
35struct fpga_image_info *fpga_image_info_alloc(struct device *dev) 30struct fpga_image_info *fpga_image_info_alloc(struct device *dev)
36{ 31{
37 struct fpga_image_info *info; 32 struct fpga_image_info *info;
@@ -50,6 +45,10 @@ struct fpga_image_info *fpga_image_info_alloc(struct device *dev)
50} 45}
51EXPORT_SYMBOL_GPL(fpga_image_info_alloc); 46EXPORT_SYMBOL_GPL(fpga_image_info_alloc);
52 47
48/**
49 * fpga_image_info_free - Free a FPGA image info struct
50 * @info: FPGA image info struct to free
51 */
53void fpga_image_info_free(struct fpga_image_info *info) 52void fpga_image_info_free(struct fpga_image_info *info)
54{ 53{
55 struct device *dev; 54 struct device *dev;
@@ -234,7 +233,7 @@ static int fpga_mgr_buf_load_mapped(struct fpga_manager *mgr,
234/** 233/**
235 * fpga_mgr_buf_load - load fpga from image in buffer 234 * fpga_mgr_buf_load - load fpga from image in buffer
236 * @mgr: fpga manager 235 * @mgr: fpga manager
237 * @flags: flags setting fpga confuration modes 236 * @info: fpga image info
238 * @buf: buffer contain fpga image 237 * @buf: buffer contain fpga image
239 * @count: byte count of buf 238 * @count: byte count of buf
240 * 239 *
@@ -343,6 +342,16 @@ static int fpga_mgr_firmware_load(struct fpga_manager *mgr,
343 return ret; 342 return ret;
344} 343}
345 344
345/**
346 * fpga_mgr_load - load FPGA from scatter/gather table, buffer, or firmware
347 * @mgr: fpga manager
348 * @info: fpga image information.
349 *
350 * Load the FPGA from an image which is indicated in @info. If successful, the
351 * FPGA ends up in operating mode.
352 *
353 * Return: 0 on success, negative error code otherwise.
354 */
346int fpga_mgr_load(struct fpga_manager *mgr, struct fpga_image_info *info) 355int fpga_mgr_load(struct fpga_manager *mgr, struct fpga_image_info *info)
347{ 356{
348 if (info->sgt) 357 if (info->sgt)
@@ -429,11 +438,9 @@ static int fpga_mgr_dev_match(struct device *dev, const void *data)
429} 438}
430 439
431/** 440/**
432 * fpga_mgr_get - get a reference to a fpga mgr 441 * fpga_mgr_get - Given a device, get a reference to a fpga mgr.
433 * @dev: parent device that fpga mgr was registered with 442 * @dev: parent device that fpga mgr was registered with
434 * 443 *
435 * Given a device, get a reference to a fpga mgr.
436 *
437 * Return: fpga manager struct or IS_ERR() condition containing error code. 444 * Return: fpga manager struct or IS_ERR() condition containing error code.
438 */ 445 */
439struct fpga_manager *fpga_mgr_get(struct device *dev) 446struct fpga_manager *fpga_mgr_get(struct device *dev)
@@ -453,10 +460,9 @@ static int fpga_mgr_of_node_match(struct device *dev, const void *data)
453} 460}
454 461
455/** 462/**
456 * of_fpga_mgr_get - get a reference to a fpga mgr 463 * of_fpga_mgr_get - Given a device node, get a reference to a fpga mgr.
457 * @node: device node
458 * 464 *
459 * Given a device node, get a reference to a fpga mgr. 465 * @node: device node
460 * 466 *
461 * Return: fpga manager struct or IS_ERR() condition containing error code. 467 * Return: fpga manager struct or IS_ERR() condition containing error code.
462 */ 468 */
@@ -489,7 +495,10 @@ EXPORT_SYMBOL_GPL(fpga_mgr_put);
489 * @mgr: fpga manager 495 * @mgr: fpga manager
490 * 496 *
491 * Given a pointer to FPGA Manager (from fpga_mgr_get() or 497 * Given a pointer to FPGA Manager (from fpga_mgr_get() or
492 * of_fpga_mgr_put()) attempt to get the mutex. 498 * of_fpga_mgr_put()) attempt to get the mutex. The user should call
499 * fpga_mgr_lock() and verify that it returns 0 before attempting to
500 * program the FPGA. Likewise, the user should call fpga_mgr_unlock
501 * when done programming the FPGA.
493 * 502 *
494 * Return: 0 for success or -EBUSY 503 * Return: 0 for success or -EBUSY
495 */ 504 */
@@ -505,7 +514,7 @@ int fpga_mgr_lock(struct fpga_manager *mgr)
505EXPORT_SYMBOL_GPL(fpga_mgr_lock); 514EXPORT_SYMBOL_GPL(fpga_mgr_lock);
506 515
507/** 516/**
508 * fpga_mgr_unlock - Unlock FPGA manager 517 * fpga_mgr_unlock - Unlock FPGA manager after done programming
509 * @mgr: fpga manager 518 * @mgr: fpga manager
510 */ 519 */
511void fpga_mgr_unlock(struct fpga_manager *mgr) 520void fpga_mgr_unlock(struct fpga_manager *mgr)
@@ -515,17 +524,17 @@ void fpga_mgr_unlock(struct fpga_manager *mgr)
515EXPORT_SYMBOL_GPL(fpga_mgr_unlock); 524EXPORT_SYMBOL_GPL(fpga_mgr_unlock);
516 525
517/** 526/**
518 * fpga_mgr_register - register a low level fpga manager driver 527 * fpga_mgr_create - create and initialize a FPGA manager struct
519 * @dev: fpga manager device from pdev 528 * @dev: fpga manager device from pdev
520 * @name: fpga manager name 529 * @name: fpga manager name
521 * @mops: pointer to structure of fpga manager ops 530 * @mops: pointer to structure of fpga manager ops
522 * @priv: fpga manager private data 531 * @priv: fpga manager private data
523 * 532 *
524 * Return: 0 on success, negative error code otherwise. 533 * Return: pointer to struct fpga_manager or NULL
525 */ 534 */
526int fpga_mgr_register(struct device *dev, const char *name, 535struct fpga_manager *fpga_mgr_create(struct device *dev, const char *name,
527 const struct fpga_manager_ops *mops, 536 const struct fpga_manager_ops *mops,
528 void *priv) 537 void *priv)
529{ 538{
530 struct fpga_manager *mgr; 539 struct fpga_manager *mgr;
531 int id, ret; 540 int id, ret;
@@ -534,17 +543,17 @@ int fpga_mgr_register(struct device *dev, const char *name,
534 !mops->write_init || (!mops->write && !mops->write_sg) || 543 !mops->write_init || (!mops->write && !mops->write_sg) ||
535 (mops->write && mops->write_sg)) { 544 (mops->write && mops->write_sg)) {
536 dev_err(dev, "Attempt to register without fpga_manager_ops\n"); 545 dev_err(dev, "Attempt to register without fpga_manager_ops\n");
537 return -EINVAL; 546 return NULL;
538 } 547 }
539 548
540 if (!name || !strlen(name)) { 549 if (!name || !strlen(name)) {
541 dev_err(dev, "Attempt to register with no name!\n"); 550 dev_err(dev, "Attempt to register with no name!\n");
542 return -EINVAL; 551 return NULL;
543 } 552 }
544 553
545 mgr = kzalloc(sizeof(*mgr), GFP_KERNEL); 554 mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
546 if (!mgr) 555 if (!mgr)
547 return -ENOMEM; 556 return NULL;
548 557
549 id = ida_simple_get(&fpga_mgr_ida, 0, 0, GFP_KERNEL); 558 id = ida_simple_get(&fpga_mgr_ida, 0, 0, GFP_KERNEL);
550 if (id < 0) { 559 if (id < 0) {
@@ -558,25 +567,56 @@ int fpga_mgr_register(struct device *dev, const char *name,
558 mgr->mops = mops; 567 mgr->mops = mops;
559 mgr->priv = priv; 568 mgr->priv = priv;
560 569
561 /*
562 * Initialize framework state by requesting low level driver read state
563 * from device. FPGA may be in reset mode or may have been programmed
564 * by bootloader or EEPROM.
565 */
566 mgr->state = mgr->mops->state(mgr);
567
568 device_initialize(&mgr->dev); 570 device_initialize(&mgr->dev);
569 mgr->dev.class = fpga_mgr_class; 571 mgr->dev.class = fpga_mgr_class;
570 mgr->dev.groups = mops->groups; 572 mgr->dev.groups = mops->groups;
571 mgr->dev.parent = dev; 573 mgr->dev.parent = dev;
572 mgr->dev.of_node = dev->of_node; 574 mgr->dev.of_node = dev->of_node;
573 mgr->dev.id = id; 575 mgr->dev.id = id;
574 dev_set_drvdata(dev, mgr);
575 576
576 ret = dev_set_name(&mgr->dev, "fpga%d", id); 577 ret = dev_set_name(&mgr->dev, "fpga%d", id);
577 if (ret) 578 if (ret)
578 goto error_device; 579 goto error_device;
579 580
581 return mgr;
582
583error_device:
584 ida_simple_remove(&fpga_mgr_ida, id);
585error_kfree:
586 kfree(mgr);
587
588 return NULL;
589}
590EXPORT_SYMBOL_GPL(fpga_mgr_create);
591
592/**
593 * fpga_mgr_free - deallocate a FPGA manager
594 * @mgr: fpga manager struct created by fpga_mgr_create
595 */
596void fpga_mgr_free(struct fpga_manager *mgr)
597{
598 ida_simple_remove(&fpga_mgr_ida, mgr->dev.id);
599 kfree(mgr);
600}
601EXPORT_SYMBOL_GPL(fpga_mgr_free);
602
603/**
604 * fpga_mgr_register - register a FPGA manager
605 * @mgr: fpga manager struct created by fpga_mgr_create
606 *
607 * Return: 0 on success, negative error code otherwise.
608 */
609int fpga_mgr_register(struct fpga_manager *mgr)
610{
611 int ret;
612
613 /*
614 * Initialize framework state by requesting low level driver read state
615 * from device. FPGA may be in reset mode or may have been programmed
616 * by bootloader or EEPROM.
617 */
618 mgr->state = mgr->mops->state(mgr);
619
580 ret = device_add(&mgr->dev); 620 ret = device_add(&mgr->dev);
581 if (ret) 621 if (ret)
582 goto error_device; 622 goto error_device;
@@ -586,22 +626,18 @@ int fpga_mgr_register(struct device *dev, const char *name,
586 return 0; 626 return 0;
587 627
588error_device: 628error_device:
589 ida_simple_remove(&fpga_mgr_ida, id); 629 ida_simple_remove(&fpga_mgr_ida, mgr->dev.id);
590error_kfree:
591 kfree(mgr);
592 630
593 return ret; 631 return ret;
594} 632}
595EXPORT_SYMBOL_GPL(fpga_mgr_register); 633EXPORT_SYMBOL_GPL(fpga_mgr_register);
596 634
597/** 635/**
598 * fpga_mgr_unregister - unregister a low level fpga manager driver 636 * fpga_mgr_unregister - unregister and free a FPGA manager
599 * @dev: fpga manager device from pdev 637 * @mgr: fpga manager struct
600 */ 638 */
601void fpga_mgr_unregister(struct device *dev) 639void fpga_mgr_unregister(struct fpga_manager *mgr)
602{ 640{
603 struct fpga_manager *mgr = dev_get_drvdata(dev);
604
605 dev_info(&mgr->dev, "%s %s\n", __func__, mgr->name); 641 dev_info(&mgr->dev, "%s %s\n", __func__, mgr->name);
606 642
607 /* 643 /*
@@ -619,8 +655,7 @@ static void fpga_mgr_dev_release(struct device *dev)
619{ 655{
620 struct fpga_manager *mgr = to_fpga_manager(dev); 656 struct fpga_manager *mgr = to_fpga_manager(dev);
621 657
622 ida_simple_remove(&fpga_mgr_ida, mgr->dev.id); 658 fpga_mgr_free(mgr);
623 kfree(mgr);
624} 659}
625 660
626static int __init fpga_mgr_class_init(void) 661static int __init fpga_mgr_class_init(void)
diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
index edab2a2e03ef..6d214d75c7be 100644
--- a/drivers/fpga/fpga-region.c
+++ b/drivers/fpga/fpga-region.c
@@ -1,22 +1,10 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * FPGA Region - Device Tree support for FPGA programming under Linux 3 * FPGA Region - Device Tree support for FPGA programming under Linux
3 * 4 *
4 * Copyright (C) 2013-2016 Altera Corporation 5 * Copyright (C) 2013-2016 Altera Corporation
5 * Copyright (C) 2017 Intel Corporation 6 * 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 */ 7 */
19
20#include <linux/fpga/fpga-bridge.h> 8#include <linux/fpga/fpga-bridge.h>
21#include <linux/fpga/fpga-mgr.h> 9#include <linux/fpga/fpga-mgr.h>
22#include <linux/fpga/fpga-region.h> 10#include <linux/fpga/fpga-region.h>
@@ -93,8 +81,16 @@ static void fpga_region_put(struct fpga_region *region)
93 81
94/** 82/**
95 * fpga_region_program_fpga - program FPGA 83 * fpga_region_program_fpga - program FPGA
84 *
96 * @region: FPGA region 85 * @region: FPGA region
86 *
97 * Program an FPGA using fpga image info (region->info). 87 * Program an FPGA using fpga image info (region->info).
88 * If the region has a get_bridges function, the exclusive reference for the
89 * bridges will be held if programming succeeds. This is intended to prevent
90 * reprogramming the region until the caller considers it safe to do so.
91 * The caller will need to call fpga_bridges_put() before attempting to
92 * reprogram the region.
93 *
98 * Return 0 for success or negative error code. 94 * Return 0 for success or negative error code.
99 */ 95 */
100int fpga_region_program_fpga(struct fpga_region *region) 96int fpga_region_program_fpga(struct fpga_region *region)
@@ -162,45 +158,86 @@ err_put_region:
162} 158}
163EXPORT_SYMBOL_GPL(fpga_region_program_fpga); 159EXPORT_SYMBOL_GPL(fpga_region_program_fpga);
164 160
165int fpga_region_register(struct device *dev, struct fpga_region *region) 161/**
162 * fpga_region_create - alloc and init a struct fpga_region
163 * @dev: device parent
164 * @mgr: manager that programs this region
165 * @get_bridges: optional function to get bridges to a list
166 *
167 * Return: struct fpga_region or NULL
168 */
169struct fpga_region
170*fpga_region_create(struct device *dev,
171 struct fpga_manager *mgr,
172 int (*get_bridges)(struct fpga_region *))
166{ 173{
174 struct fpga_region *region;
167 int id, ret = 0; 175 int id, ret = 0;
168 176
177 region = kzalloc(sizeof(*region), GFP_KERNEL);
178 if (!region)
179 return NULL;
180
169 id = ida_simple_get(&fpga_region_ida, 0, 0, GFP_KERNEL); 181 id = ida_simple_get(&fpga_region_ida, 0, 0, GFP_KERNEL);
170 if (id < 0) 182 if (id < 0)
171 return id; 183 goto err_free;
172 184
185 region->mgr = mgr;
186 region->get_bridges = get_bridges;
173 mutex_init(&region->mutex); 187 mutex_init(&region->mutex);
174 INIT_LIST_HEAD(&region->bridge_list); 188 INIT_LIST_HEAD(&region->bridge_list);
189
175 device_initialize(&region->dev); 190 device_initialize(&region->dev);
176 region->dev.groups = region->groups;
177 region->dev.class = fpga_region_class; 191 region->dev.class = fpga_region_class;
178 region->dev.parent = dev; 192 region->dev.parent = dev;
179 region->dev.of_node = dev->of_node; 193 region->dev.of_node = dev->of_node;
180 region->dev.id = id; 194 region->dev.id = id;
181 dev_set_drvdata(dev, region);
182 195
183 ret = dev_set_name(&region->dev, "region%d", id); 196 ret = dev_set_name(&region->dev, "region%d", id);
184 if (ret) 197 if (ret)
185 goto err_remove; 198 goto err_remove;
186 199
187 ret = device_add(&region->dev); 200 return region;
188 if (ret)
189 goto err_remove;
190
191 return 0;
192 201
193err_remove: 202err_remove:
194 ida_simple_remove(&fpga_region_ida, id); 203 ida_simple_remove(&fpga_region_ida, id);
195 return ret; 204err_free:
205 kfree(region);
206
207 return NULL;
208}
209EXPORT_SYMBOL_GPL(fpga_region_create);
210
211/**
212 * fpga_region_free - free a struct fpga_region
213 * @region: FPGA region created by fpga_region_create
214 */
215void fpga_region_free(struct fpga_region *region)
216{
217 ida_simple_remove(&fpga_region_ida, region->dev.id);
218 kfree(region);
219}
220EXPORT_SYMBOL_GPL(fpga_region_free);
221
222/**
223 * fpga_region_register - register a FPGA region
224 * @region: FPGA region created by fpga_region_create
225 * Return: 0 or -errno
226 */
227int fpga_region_register(struct fpga_region *region)
228{
229 return device_add(&region->dev);
230
196} 231}
197EXPORT_SYMBOL_GPL(fpga_region_register); 232EXPORT_SYMBOL_GPL(fpga_region_register);
198 233
199int fpga_region_unregister(struct fpga_region *region) 234/**
235 * fpga_region_unregister - unregister and free a FPGA region
236 * @region: FPGA region
237 */
238void fpga_region_unregister(struct fpga_region *region)
200{ 239{
201 device_unregister(&region->dev); 240 device_unregister(&region->dev);
202
203 return 0;
204} 241}
205EXPORT_SYMBOL_GPL(fpga_region_unregister); 242EXPORT_SYMBOL_GPL(fpga_region_unregister);
206 243
@@ -208,7 +245,7 @@ static void fpga_region_dev_release(struct device *dev)
208{ 245{
209 struct fpga_region *region = to_fpga_region(dev); 246 struct fpga_region *region = to_fpga_region(dev);
210 247
211 ida_simple_remove(&fpga_region_ida, region->dev.id); 248 fpga_region_free(region);
212} 249}
213 250
214/** 251/**
diff --git a/drivers/fpga/ice40-spi.c b/drivers/fpga/ice40-spi.c
index 7fca82023062..5981c7ee7a7d 100644
--- a/drivers/fpga/ice40-spi.c
+++ b/drivers/fpga/ice40-spi.c
@@ -133,6 +133,7 @@ static int ice40_fpga_probe(struct spi_device *spi)
133{ 133{
134 struct device *dev = &spi->dev; 134 struct device *dev = &spi->dev;
135 struct ice40_fpga_priv *priv; 135 struct ice40_fpga_priv *priv;
136 struct fpga_manager *mgr;
136 int ret; 137 int ret;
137 138
138 priv = devm_kzalloc(&spi->dev, sizeof(*priv), GFP_KERNEL); 139 priv = devm_kzalloc(&spi->dev, sizeof(*priv), GFP_KERNEL);
@@ -174,14 +175,26 @@ static int ice40_fpga_probe(struct spi_device *spi)
174 return ret; 175 return ret;
175 } 176 }
176 177
177 /* Register with the FPGA manager */ 178 mgr = fpga_mgr_create(dev, "Lattice iCE40 FPGA Manager",
178 return fpga_mgr_register(dev, "Lattice iCE40 FPGA Manager", 179 &ice40_fpga_ops, priv);
179 &ice40_fpga_ops, priv); 180 if (!mgr)
181 return -ENOMEM;
182
183 spi_set_drvdata(spi, mgr);
184
185 ret = fpga_mgr_register(mgr);
186 if (ret)
187 fpga_mgr_free(mgr);
188
189 return ret;
180} 190}
181 191
182static int ice40_fpga_remove(struct spi_device *spi) 192static int ice40_fpga_remove(struct spi_device *spi)
183{ 193{
184 fpga_mgr_unregister(&spi->dev); 194 struct fpga_manager *mgr = spi_get_drvdata(spi);
195
196 fpga_mgr_unregister(mgr);
197
185 return 0; 198 return 0;
186} 199}
187 200
diff --git a/drivers/fpga/machxo2-spi.c b/drivers/fpga/machxo2-spi.c
new file mode 100644
index 000000000000..a582e0000c97
--- /dev/null
+++ b/drivers/fpga/machxo2-spi.c
@@ -0,0 +1,415 @@
1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Lattice MachXO2 Slave SPI Driver
4 *
5 * Manage Lattice FPGA firmware that is loaded over SPI using
6 * the slave serial configuration interface.
7 *
8 * Copyright (C) 2018 Paolo Pisati <p.pisati@gmail.com>
9 */
10
11#include <linux/delay.h>
12#include <linux/fpga/fpga-mgr.h>
13#include <linux/gpio/consumer.h>
14#include <linux/module.h>
15#include <linux/of.h>
16#include <linux/spi/spi.h>
17
18/* MachXO2 Programming Guide - sysCONFIG Programming Commands */
19#define IDCODE_PUB {0xe0, 0x00, 0x00, 0x00}
20#define ISC_ENABLE {0xc6, 0x08, 0x00, 0x00}
21#define ISC_ERASE {0x0e, 0x04, 0x00, 0x00}
22#define ISC_PROGRAMDONE {0x5e, 0x00, 0x00, 0x00}
23#define LSC_INITADDRESS {0x46, 0x00, 0x00, 0x00}
24#define LSC_PROGINCRNV {0x70, 0x00, 0x00, 0x01}
25#define LSC_READ_STATUS {0x3c, 0x00, 0x00, 0x00}
26#define LSC_REFRESH {0x79, 0x00, 0x00, 0x00}
27
28/*
29 * Max CCLK in Slave SPI mode according to 'MachXO2 Family Data
30 * Sheet' sysCONFIG Port Timing Specifications (3-36)
31 */
32#define MACHXO2_MAX_SPEED 66000000
33
34#define MACHXO2_LOW_DELAY_USEC 5
35#define MACHXO2_HIGH_DELAY_USEC 200
36#define MACHXO2_REFRESH_USEC 4800
37#define MACHXO2_MAX_BUSY_LOOP 128
38#define MACHXO2_MAX_REFRESH_LOOP 16
39
40#define MACHXO2_PAGE_SIZE 16
41#define MACHXO2_BUF_SIZE (MACHXO2_PAGE_SIZE + 4)
42
43/* Status register bits, errors and error mask */
44#define BUSY 12
45#define DONE 8
46#define DVER 27
47#define ENAB 9
48#define ERRBITS 23
49#define ERRMASK 7
50#define FAIL 13
51
52#define ENOERR 0 /* no error */
53#define EID 1
54#define ECMD 2
55#define ECRC 3
56#define EPREAM 4 /* preamble error */
57#define EABRT 5 /* abort error */
58#define EOVERFL 6 /* overflow error */
59#define ESDMEOF 7 /* SDM EOF */
60
61static inline u8 get_err(unsigned long *status)
62{
63 return (*status >> ERRBITS) & ERRMASK;
64}
65
66static int get_status(struct spi_device *spi, unsigned long *status)
67{
68 struct spi_message msg;
69 struct spi_transfer rx, tx;
70 static const u8 cmd[] = LSC_READ_STATUS;
71 int ret;
72
73 memset(&rx, 0, sizeof(rx));
74 memset(&tx, 0, sizeof(tx));
75 tx.tx_buf = cmd;
76 tx.len = sizeof(cmd);
77 rx.rx_buf = status;
78 rx.len = 4;
79 spi_message_init(&msg);
80 spi_message_add_tail(&tx, &msg);
81 spi_message_add_tail(&rx, &msg);
82 ret = spi_sync(spi, &msg);
83 if (ret)
84 return ret;
85
86 *status = be32_to_cpu(*status);
87
88 return 0;
89}
90
91#ifdef DEBUG
92static const char *get_err_string(u8 err)
93{
94 switch (err) {
95 case ENOERR: return "No Error";
96 case EID: return "ID ERR";
97 case ECMD: return "CMD ERR";
98 case ECRC: return "CRC ERR";
99 case EPREAM: return "Preamble ERR";
100 case EABRT: return "Abort ERR";
101 case EOVERFL: return "Overflow ERR";
102 case ESDMEOF: return "SDM EOF";
103 }
104
105 return "Default switch case";
106}
107#endif
108
109static void dump_status_reg(unsigned long *status)
110{
111#ifdef DEBUG
112 pr_debug("machxo2 status: 0x%08lX - done=%d, cfgena=%d, busy=%d, fail=%d, devver=%d, err=%s\n",
113 *status, test_bit(DONE, status), test_bit(ENAB, status),
114 test_bit(BUSY, status), test_bit(FAIL, status),
115 test_bit(DVER, status), get_err_string(get_err(status)));
116#endif
117}
118
119static int wait_until_not_busy(struct spi_device *spi)
120{
121 unsigned long status;
122 int ret, loop = 0;
123
124 do {
125 ret = get_status(spi, &status);
126 if (ret)
127 return ret;
128 if (++loop >= MACHXO2_MAX_BUSY_LOOP)
129 return -EBUSY;
130 } while (test_bit(BUSY, &status));
131
132 return 0;
133}
134
135static int machxo2_cleanup(struct fpga_manager *mgr)
136{
137 struct spi_device *spi = mgr->priv;
138 struct spi_message msg;
139 struct spi_transfer tx[2];
140 static const u8 erase[] = ISC_ERASE;
141 static const u8 refresh[] = LSC_REFRESH;
142 int ret;
143
144 memset(tx, 0, sizeof(tx));
145 spi_message_init(&msg);
146 tx[0].tx_buf = &erase;
147 tx[0].len = sizeof(erase);
148 spi_message_add_tail(&tx[0], &msg);
149 ret = spi_sync(spi, &msg);
150 if (ret)
151 goto fail;
152
153 ret = wait_until_not_busy(spi);
154 if (ret)
155 goto fail;
156
157 spi_message_init(&msg);
158 tx[1].tx_buf = &refresh;
159 tx[1].len = sizeof(refresh);
160 tx[1].delay_usecs = MACHXO2_REFRESH_USEC;
161 spi_message_add_tail(&tx[1], &msg);
162 ret = spi_sync(spi, &msg);
163 if (ret)
164 goto fail;
165
166 return 0;
167fail:
168 dev_err(&mgr->dev, "Cleanup failed\n");
169
170 return ret;
171}
172
173static enum fpga_mgr_states machxo2_spi_state(struct fpga_manager *mgr)
174{
175 struct spi_device *spi = mgr->priv;
176 unsigned long status;
177
178 get_status(spi, &status);
179 if (!test_bit(BUSY, &status) && test_bit(DONE, &status) &&
180 get_err(&status) == ENOERR)
181 return FPGA_MGR_STATE_OPERATING;
182
183 return FPGA_MGR_STATE_UNKNOWN;
184}
185
186static int machxo2_write_init(struct fpga_manager *mgr,
187 struct fpga_image_info *info,
188 const char *buf, size_t count)
189{
190 struct spi_device *spi = mgr->priv;
191 struct spi_message msg;
192 struct spi_transfer tx[3];
193 static const u8 enable[] = ISC_ENABLE;
194 static const u8 erase[] = ISC_ERASE;
195 static const u8 initaddr[] = LSC_INITADDRESS;
196 unsigned long status;
197 int ret;
198
199 if ((info->flags & FPGA_MGR_PARTIAL_RECONFIG)) {
200 dev_err(&mgr->dev,
201 "Partial reconfiguration is not supported\n");
202 return -ENOTSUPP;
203 }
204
205 get_status(spi, &status);
206 dump_status_reg(&status);
207 memset(tx, 0, sizeof(tx));
208 spi_message_init(&msg);
209 tx[0].tx_buf = &enable;
210 tx[0].len = sizeof(enable);
211 tx[0].delay_usecs = MACHXO2_LOW_DELAY_USEC;
212 spi_message_add_tail(&tx[0], &msg);
213
214 tx[1].tx_buf = &erase;
215 tx[1].len = sizeof(erase);
216 spi_message_add_tail(&tx[1], &msg);
217 ret = spi_sync(spi, &msg);
218 if (ret)
219 goto fail;
220
221 ret = wait_until_not_busy(spi);
222 if (ret)
223 goto fail;
224
225 get_status(spi, &status);
226 if (test_bit(FAIL, &status))
227 goto fail;
228 dump_status_reg(&status);
229
230 spi_message_init(&msg);
231 tx[2].tx_buf = &initaddr;
232 tx[2].len = sizeof(initaddr);
233 spi_message_add_tail(&tx[2], &msg);
234 ret = spi_sync(spi, &msg);
235 if (ret)
236 goto fail;
237
238 get_status(spi, &status);
239 dump_status_reg(&status);
240
241 return 0;
242fail:
243 dev_err(&mgr->dev, "Error during FPGA init.\n");
244
245 return ret;
246}
247
248static int machxo2_write(struct fpga_manager *mgr, const char *buf,
249 size_t count)
250{
251 struct spi_device *spi = mgr->priv;
252 struct spi_message msg;
253 struct spi_transfer tx;
254 static const u8 progincr[] = LSC_PROGINCRNV;
255 u8 payload[MACHXO2_BUF_SIZE];
256 unsigned long status;
257 int i, ret;
258
259 if (count % MACHXO2_PAGE_SIZE != 0) {
260 dev_err(&mgr->dev, "Malformed payload.\n");
261 return -EINVAL;
262 }
263 get_status(spi, &status);
264 dump_status_reg(&status);
265 memcpy(payload, &progincr, sizeof(progincr));
266 for (i = 0; i < count; i += MACHXO2_PAGE_SIZE) {
267 memcpy(&payload[sizeof(progincr)], &buf[i], MACHXO2_PAGE_SIZE);
268 memset(&tx, 0, sizeof(tx));
269 spi_message_init(&msg);
270 tx.tx_buf = payload;
271 tx.len = MACHXO2_BUF_SIZE;
272 tx.delay_usecs = MACHXO2_HIGH_DELAY_USEC;
273 spi_message_add_tail(&tx, &msg);
274 ret = spi_sync(spi, &msg);
275 if (ret) {
276 dev_err(&mgr->dev, "Error loading the bitstream.\n");
277 return ret;
278 }
279 }
280 get_status(spi, &status);
281 dump_status_reg(&status);
282
283 return 0;
284}
285
286static int machxo2_write_complete(struct fpga_manager *mgr,
287 struct fpga_image_info *info)
288{
289 struct spi_device *spi = mgr->priv;
290 struct spi_message msg;
291 struct spi_transfer tx[2];
292 static const u8 progdone[] = ISC_PROGRAMDONE;
293 static const u8 refresh[] = LSC_REFRESH;
294 unsigned long status;
295 int ret, refreshloop = 0;
296
297 memset(tx, 0, sizeof(tx));
298 spi_message_init(&msg);
299 tx[0].tx_buf = &progdone;
300 tx[0].len = sizeof(progdone);
301 spi_message_add_tail(&tx[0], &msg);
302 ret = spi_sync(spi, &msg);
303 if (ret)
304 goto fail;
305 ret = wait_until_not_busy(spi);
306 if (ret)
307 goto fail;
308
309 get_status(spi, &status);
310 dump_status_reg(&status);
311 if (!test_bit(DONE, &status)) {
312 machxo2_cleanup(mgr);
313 goto fail;
314 }
315
316 do {
317 spi_message_init(&msg);
318 tx[1].tx_buf = &refresh;
319 tx[1].len = sizeof(refresh);
320 tx[1].delay_usecs = MACHXO2_REFRESH_USEC;
321 spi_message_add_tail(&tx[1], &msg);
322 ret = spi_sync(spi, &msg);
323 if (ret)
324 goto fail;
325
326 /* check refresh status */
327 get_status(spi, &status);
328 dump_status_reg(&status);
329 if (!test_bit(BUSY, &status) && test_bit(DONE, &status) &&
330 get_err(&status) == ENOERR)
331 break;
332 if (++refreshloop == MACHXO2_MAX_REFRESH_LOOP) {
333 machxo2_cleanup(mgr);
334 goto fail;
335 }
336 } while (1);
337
338 get_status(spi, &status);
339 dump_status_reg(&status);
340
341 return 0;
342fail:
343 dev_err(&mgr->dev, "Refresh failed.\n");
344
345 return ret;
346}
347
348static const struct fpga_manager_ops machxo2_ops = {
349 .state = machxo2_spi_state,
350 .write_init = machxo2_write_init,
351 .write = machxo2_write,
352 .write_complete = machxo2_write_complete,
353};
354
355static int machxo2_spi_probe(struct spi_device *spi)
356{
357 struct device *dev = &spi->dev;
358 struct fpga_manager *mgr;
359 int ret;
360
361 if (spi->max_speed_hz > MACHXO2_MAX_SPEED) {
362 dev_err(dev, "Speed is too high\n");
363 return -EINVAL;
364 }
365
366 mgr = fpga_mgr_create(dev, "Lattice MachXO2 SPI FPGA Manager",
367 &machxo2_ops, spi);
368 if (!mgr)
369 return -ENOMEM;
370
371 spi_set_drvdata(spi, mgr);
372
373 ret = fpga_mgr_register(mgr);
374 if (ret)
375 fpga_mgr_free(mgr);
376
377 return ret;
378}
379
380static int machxo2_spi_remove(struct spi_device *spi)
381{
382 struct fpga_manager *mgr = spi_get_drvdata(spi);
383
384 fpga_mgr_unregister(mgr);
385
386 return 0;
387}
388
389static const struct of_device_id of_match[] = {
390 { .compatible = "lattice,machxo2-slave-spi", },
391 {}
392};
393MODULE_DEVICE_TABLE(of, of_match);
394
395static const struct spi_device_id lattice_ids[] = {
396 { "machxo2-slave-spi", 0 },
397 { },
398};
399MODULE_DEVICE_TABLE(spi, lattice_ids);
400
401static struct spi_driver machxo2_spi_driver = {
402 .driver = {
403 .name = "machxo2-slave-spi",
404 .of_match_table = of_match_ptr(of_match),
405 },
406 .probe = machxo2_spi_probe,
407 .remove = machxo2_spi_remove,
408 .id_table = lattice_ids,
409};
410
411module_spi_driver(machxo2_spi_driver)
412
413MODULE_AUTHOR("Paolo Pisati <p.pisati@gmail.com>");
414MODULE_DESCRIPTION("Load Lattice FPGA firmware over SPI");
415MODULE_LICENSE("GPL v2");
diff --git a/drivers/fpga/of-fpga-region.c b/drivers/fpga/of-fpga-region.c
index 119ff75522f1..35fabb8083fb 100644
--- a/drivers/fpga/of-fpga-region.c
+++ b/drivers/fpga/of-fpga-region.c
@@ -1,22 +1,10 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * FPGA Region - Device Tree support for FPGA programming under Linux 3 * FPGA Region - Device Tree support for FPGA programming under Linux
3 * 4 *
4 * Copyright (C) 2013-2016 Altera Corporation 5 * Copyright (C) 2013-2016 Altera Corporation
5 * Copyright (C) 2017 Intel Corporation 6 * 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 */ 7 */
19
20#include <linux/fpga/fpga-bridge.h> 8#include <linux/fpga/fpga-bridge.h>
21#include <linux/fpga/fpga-mgr.h> 9#include <linux/fpga/fpga-mgr.h>
22#include <linux/fpga/fpga-region.h> 10#include <linux/fpga/fpga-region.h>
@@ -422,27 +410,25 @@ static int of_fpga_region_probe(struct platform_device *pdev)
422 if (IS_ERR(mgr)) 410 if (IS_ERR(mgr))
423 return -EPROBE_DEFER; 411 return -EPROBE_DEFER;
424 412
425 region = devm_kzalloc(dev, sizeof(*region), GFP_KERNEL); 413 region = fpga_region_create(dev, mgr, of_fpga_region_get_bridges);
426 if (!region) { 414 if (!region) {
427 ret = -ENOMEM; 415 ret = -ENOMEM;
428 goto eprobe_mgr_put; 416 goto eprobe_mgr_put;
429 } 417 }
430 418
431 region->mgr = mgr; 419 ret = fpga_region_register(region);
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) 420 if (ret)
438 goto eprobe_mgr_put; 421 goto eprobe_free;
439 422
440 of_platform_populate(np, fpga_region_of_match, NULL, &region->dev); 423 of_platform_populate(np, fpga_region_of_match, NULL, &region->dev);
424 dev_set_drvdata(dev, region);
441 425
442 dev_info(dev, "FPGA Region probed\n"); 426 dev_info(dev, "FPGA Region probed\n");
443 427
444 return 0; 428 return 0;
445 429
430eprobe_free:
431 fpga_region_free(region);
446eprobe_mgr_put: 432eprobe_mgr_put:
447 fpga_mgr_put(mgr); 433 fpga_mgr_put(mgr);
448 return ret; 434 return ret;
diff --git a/drivers/fpga/socfpga-a10.c b/drivers/fpga/socfpga-a10.c
index a46e343a5b72..be30c48eb6e4 100644
--- a/drivers/fpga/socfpga-a10.c
+++ b/drivers/fpga/socfpga-a10.c
@@ -1,21 +1,9 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * FPGA Manager Driver for Altera Arria10 SoCFPGA 3 * FPGA Manager Driver for Altera Arria10 SoCFPGA
3 * 4 *
4 * Copyright (C) 2015-2016 Altera Corporation 5 * Copyright (C) 2015-2016 Altera Corporation
5 *
6 * 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 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * 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 */ 6 */
18
19#include <linux/clk.h> 7#include <linux/clk.h>
20#include <linux/device.h> 8#include <linux/device.h>
21#include <linux/delay.h> 9#include <linux/delay.h>
@@ -482,6 +470,7 @@ static int socfpga_a10_fpga_probe(struct platform_device *pdev)
482 struct device *dev = &pdev->dev; 470 struct device *dev = &pdev->dev;
483 struct a10_fpga_priv *priv; 471 struct a10_fpga_priv *priv;
484 void __iomem *reg_base; 472 void __iomem *reg_base;
473 struct fpga_manager *mgr;
485 struct resource *res; 474 struct resource *res;
486 int ret; 475 int ret;
487 476
@@ -519,9 +508,16 @@ static int socfpga_a10_fpga_probe(struct platform_device *pdev)
519 return -EBUSY; 508 return -EBUSY;
520 } 509 }
521 510
522 ret = fpga_mgr_register(dev, "SoCFPGA Arria10 FPGA Manager", 511 mgr = fpga_mgr_create(dev, "SoCFPGA Arria10 FPGA Manager",
523 &socfpga_a10_fpga_mgr_ops, priv); 512 &socfpga_a10_fpga_mgr_ops, priv);
513 if (!mgr)
514 return -ENOMEM;
515
516 platform_set_drvdata(pdev, mgr);
517
518 ret = fpga_mgr_register(mgr);
524 if (ret) { 519 if (ret) {
520 fpga_mgr_free(mgr);
525 clk_disable_unprepare(priv->clk); 521 clk_disable_unprepare(priv->clk);
526 return ret; 522 return ret;
527 } 523 }
@@ -534,7 +530,7 @@ static int socfpga_a10_fpga_remove(struct platform_device *pdev)
534 struct fpga_manager *mgr = platform_get_drvdata(pdev); 530 struct fpga_manager *mgr = platform_get_drvdata(pdev);
535 struct a10_fpga_priv *priv = mgr->priv; 531 struct a10_fpga_priv *priv = mgr->priv;
536 532
537 fpga_mgr_unregister(&pdev->dev); 533 fpga_mgr_unregister(mgr);
538 clk_disable_unprepare(priv->clk); 534 clk_disable_unprepare(priv->clk);
539 535
540 return 0; 536 return 0;
diff --git a/drivers/fpga/socfpga.c b/drivers/fpga/socfpga.c
index b6672e66cda6..959d71f26896 100644
--- a/drivers/fpga/socfpga.c
+++ b/drivers/fpga/socfpga.c
@@ -1,19 +1,8 @@
1// SPDX-License-Identifier: GPL-2.0
1/* 2/*
2 * FPGA Manager Driver for Altera SOCFPGA 3 * FPGA Manager Driver for Altera SOCFPGA
3 * 4 *
4 * Copyright (C) 2013-2015 Altera Corporation 5 * Copyright (C) 2013-2015 Altera Corporation
5 *
6 * 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 * version 2, as published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
14 *
15 * 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 */ 6 */
18#include <linux/completion.h> 7#include <linux/completion.h>
19#include <linux/delay.h> 8#include <linux/delay.h>
@@ -555,6 +544,7 @@ static int socfpga_fpga_probe(struct platform_device *pdev)
555{ 544{
556 struct device *dev = &pdev->dev; 545 struct device *dev = &pdev->dev;
557 struct socfpga_fpga_priv *priv; 546 struct socfpga_fpga_priv *priv;
547 struct fpga_manager *mgr;
558 struct resource *res; 548 struct resource *res;
559 int ret; 549 int ret;
560 550
@@ -581,13 +571,25 @@ static int socfpga_fpga_probe(struct platform_device *pdev)
581 if (ret) 571 if (ret)
582 return ret; 572 return ret;
583 573
584 return fpga_mgr_register(dev, "Altera SOCFPGA FPGA Manager", 574 mgr = fpga_mgr_create(dev, "Altera SOCFPGA FPGA Manager",
585 &socfpga_fpga_ops, priv); 575 &socfpga_fpga_ops, priv);
576 if (!mgr)
577 return -ENOMEM;
578
579 platform_set_drvdata(pdev, mgr);
580
581 ret = fpga_mgr_register(mgr);
582 if (ret)
583 fpga_mgr_free(mgr);
584
585 return ret;
586} 586}
587 587
588static int socfpga_fpga_remove(struct platform_device *pdev) 588static int socfpga_fpga_remove(struct platform_device *pdev)
589{ 589{
590 fpga_mgr_unregister(&pdev->dev); 590 struct fpga_manager *mgr = platform_get_drvdata(pdev);
591
592 fpga_mgr_unregister(mgr);
591 593
592 return 0; 594 return 0;
593} 595}
diff --git a/drivers/fpga/ts73xx-fpga.c b/drivers/fpga/ts73xx-fpga.c
index f6a96b42e2ca..08efd1895b1b 100644
--- a/drivers/fpga/ts73xx-fpga.c
+++ b/drivers/fpga/ts73xx-fpga.c
@@ -116,7 +116,9 @@ static int ts73xx_fpga_probe(struct platform_device *pdev)
116{ 116{
117 struct device *kdev = &pdev->dev; 117 struct device *kdev = &pdev->dev;
118 struct ts73xx_fpga_priv *priv; 118 struct ts73xx_fpga_priv *priv;
119 struct fpga_manager *mgr;
119 struct resource *res; 120 struct resource *res;
121 int ret;
120 122
121 priv = devm_kzalloc(kdev, sizeof(*priv), GFP_KERNEL); 123 priv = devm_kzalloc(kdev, sizeof(*priv), GFP_KERNEL);
122 if (!priv) 124 if (!priv)
@@ -131,13 +133,25 @@ static int ts73xx_fpga_probe(struct platform_device *pdev)
131 return PTR_ERR(priv->io_base); 133 return PTR_ERR(priv->io_base);
132 } 134 }
133 135
134 return fpga_mgr_register(kdev, "TS-73xx FPGA Manager", 136 mgr = fpga_mgr_create(kdev, "TS-73xx FPGA Manager",
135 &ts73xx_fpga_ops, priv); 137 &ts73xx_fpga_ops, priv);
138 if (!mgr)
139 return -ENOMEM;
140
141 platform_set_drvdata(pdev, mgr);
142
143 ret = fpga_mgr_register(mgr);
144 if (ret)
145 fpga_mgr_free(mgr);
146
147 return ret;
136} 148}
137 149
138static int ts73xx_fpga_remove(struct platform_device *pdev) 150static int ts73xx_fpga_remove(struct platform_device *pdev)
139{ 151{
140 fpga_mgr_unregister(&pdev->dev); 152 struct fpga_manager *mgr = platform_get_drvdata(pdev);
153
154 fpga_mgr_unregister(mgr);
141 155
142 return 0; 156 return 0;
143} 157}
diff --git a/drivers/fpga/xilinx-pr-decoupler.c b/drivers/fpga/xilinx-pr-decoupler.c
index 0d7743089414..07ba1539e82c 100644
--- a/drivers/fpga/xilinx-pr-decoupler.c
+++ b/drivers/fpga/xilinx-pr-decoupler.c
@@ -94,6 +94,7 @@ MODULE_DEVICE_TABLE(of, xlnx_pr_decoupler_of_match);
94static int xlnx_pr_decoupler_probe(struct platform_device *pdev) 94static int xlnx_pr_decoupler_probe(struct platform_device *pdev)
95{ 95{
96 struct xlnx_pr_decoupler_data *priv; 96 struct xlnx_pr_decoupler_data *priv;
97 struct fpga_bridge *br;
97 int err; 98 int err;
98 struct resource *res; 99 struct resource *res;
99 100
@@ -120,16 +121,27 @@ static int xlnx_pr_decoupler_probe(struct platform_device *pdev)
120 121
121 clk_disable(priv->clk); 122 clk_disable(priv->clk);
122 123
123 err = fpga_bridge_register(&pdev->dev, "Xilinx PR Decoupler", 124 br = fpga_bridge_create(&pdev->dev, "Xilinx PR Decoupler",
124 &xlnx_pr_decoupler_br_ops, priv); 125 &xlnx_pr_decoupler_br_ops, priv);
126 if (!br) {
127 err = -ENOMEM;
128 goto err_clk;
129 }
130
131 platform_set_drvdata(pdev, br);
125 132
133 err = fpga_bridge_register(br);
126 if (err) { 134 if (err) {
127 dev_err(&pdev->dev, "unable to register Xilinx PR Decoupler"); 135 dev_err(&pdev->dev, "unable to register Xilinx PR Decoupler");
128 clk_unprepare(priv->clk); 136 goto err_clk;
129 return err;
130 } 137 }
131 138
132 return 0; 139 return 0;
140
141err_clk:
142 clk_unprepare(priv->clk);
143
144 return err;
133} 145}
134 146
135static int xlnx_pr_decoupler_remove(struct platform_device *pdev) 147static int xlnx_pr_decoupler_remove(struct platform_device *pdev)
@@ -137,7 +149,7 @@ static int xlnx_pr_decoupler_remove(struct platform_device *pdev)
137 struct fpga_bridge *bridge = platform_get_drvdata(pdev); 149 struct fpga_bridge *bridge = platform_get_drvdata(pdev);
138 struct xlnx_pr_decoupler_data *p = bridge->priv; 150 struct xlnx_pr_decoupler_data *p = bridge->priv;
139 151
140 fpga_bridge_unregister(&pdev->dev); 152 fpga_bridge_unregister(bridge);
141 153
142 clk_unprepare(p->clk); 154 clk_unprepare(p->clk);
143 155
diff --git a/drivers/fpga/xilinx-spi.c b/drivers/fpga/xilinx-spi.c
index 9b62a4c2a3df..8d1945966533 100644
--- a/drivers/fpga/xilinx-spi.c
+++ b/drivers/fpga/xilinx-spi.c
@@ -143,6 +143,8 @@ static const struct fpga_manager_ops xilinx_spi_ops = {
143static int xilinx_spi_probe(struct spi_device *spi) 143static int xilinx_spi_probe(struct spi_device *spi)
144{ 144{
145 struct xilinx_spi_conf *conf; 145 struct xilinx_spi_conf *conf;
146 struct fpga_manager *mgr;
147 int ret;
146 148
147 conf = devm_kzalloc(&spi->dev, sizeof(*conf), GFP_KERNEL); 149 conf = devm_kzalloc(&spi->dev, sizeof(*conf), GFP_KERNEL);
148 if (!conf) 150 if (!conf)
@@ -165,13 +167,25 @@ static int xilinx_spi_probe(struct spi_device *spi)
165 return PTR_ERR(conf->done); 167 return PTR_ERR(conf->done);
166 } 168 }
167 169
168 return fpga_mgr_register(&spi->dev, "Xilinx Slave Serial FPGA Manager", 170 mgr = fpga_mgr_create(&spi->dev, "Xilinx Slave Serial FPGA Manager",
169 &xilinx_spi_ops, conf); 171 &xilinx_spi_ops, conf);
172 if (!mgr)
173 return -ENOMEM;
174
175 spi_set_drvdata(spi, mgr);
176
177 ret = fpga_mgr_register(mgr);
178 if (ret)
179 fpga_mgr_free(mgr);
180
181 return ret;
170} 182}
171 183
172static int xilinx_spi_remove(struct spi_device *spi) 184static int xilinx_spi_remove(struct spi_device *spi)
173{ 185{
174 fpga_mgr_unregister(&spi->dev); 186 struct fpga_manager *mgr = spi_get_drvdata(spi);
187
188 fpga_mgr_unregister(mgr);
175 189
176 return 0; 190 return 0;
177} 191}
diff --git a/drivers/fpga/zynq-fpga.c b/drivers/fpga/zynq-fpga.c
index 70b15b303471..3110e00121ca 100644
--- a/drivers/fpga/zynq-fpga.c
+++ b/drivers/fpga/zynq-fpga.c
@@ -558,6 +558,7 @@ static int zynq_fpga_probe(struct platform_device *pdev)
558{ 558{
559 struct device *dev = &pdev->dev; 559 struct device *dev = &pdev->dev;
560 struct zynq_fpga_priv *priv; 560 struct zynq_fpga_priv *priv;
561 struct fpga_manager *mgr;
561 struct resource *res; 562 struct resource *res;
562 int err; 563 int err;
563 564
@@ -613,10 +614,17 @@ static int zynq_fpga_probe(struct platform_device *pdev)
613 614
614 clk_disable(priv->clk); 615 clk_disable(priv->clk);
615 616
616 err = fpga_mgr_register(dev, "Xilinx Zynq FPGA Manager", 617 mgr = fpga_mgr_create(dev, "Xilinx Zynq FPGA Manager",
617 &zynq_fpga_ops, priv); 618 &zynq_fpga_ops, priv);
619 if (!mgr)
620 return -ENOMEM;
621
622 platform_set_drvdata(pdev, mgr);
623
624 err = fpga_mgr_register(mgr);
618 if (err) { 625 if (err) {
619 dev_err(dev, "unable to register FPGA manager\n"); 626 dev_err(dev, "unable to register FPGA manager\n");
627 fpga_mgr_free(mgr);
620 clk_unprepare(priv->clk); 628 clk_unprepare(priv->clk);
621 return err; 629 return err;
622 } 630 }
@@ -632,7 +640,7 @@ static int zynq_fpga_remove(struct platform_device *pdev)
632 mgr = platform_get_drvdata(pdev); 640 mgr = platform_get_drvdata(pdev);
633 priv = mgr->priv; 641 priv = mgr->priv;
634 642
635 fpga_mgr_unregister(&pdev->dev); 643 fpga_mgr_unregister(mgr);
636 644
637 clk_unprepare(priv->clk); 645 clk_unprepare(priv->clk);
638 646