xref: /openbmc/linux/drivers/fpga/socfpga-a10.c (revision 5d0e4d78)
1 /*
2  * FPGA Manager Driver for Altera Arria10 SoCFPGA
3  *
4  * 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  */
18 
19 #include <linux/clk.h>
20 #include <linux/device.h>
21 #include <linux/delay.h>
22 #include <linux/fpga/fpga-mgr.h>
23 #include <linux/io.h>
24 #include <linux/module.h>
25 #include <linux/of_address.h>
26 #include <linux/regmap.h>
27 
28 #define A10_FPGAMGR_DCLKCNT_OFST				0x08
29 #define A10_FPGAMGR_DCLKSTAT_OFST				0x0c
30 #define A10_FPGAMGR_IMGCFG_CTL_00_OFST				0x70
31 #define A10_FPGAMGR_IMGCFG_CTL_01_OFST				0x74
32 #define A10_FPGAMGR_IMGCFG_CTL_02_OFST				0x78
33 #define A10_FPGAMGR_IMGCFG_STAT_OFST				0x80
34 
35 #define A10_FPGAMGR_DCLKSTAT_DCLKDONE				BIT(0)
36 
37 #define A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NCONFIG		BIT(0)
38 #define A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NSTATUS		BIT(1)
39 #define A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_CONDONE		BIT(2)
40 #define A10_FPGAMGR_IMGCFG_CTL_00_S2F_NCONFIG			BIT(8)
41 #define A10_FPGAMGR_IMGCFG_CTL_00_S2F_NSTATUS_OE		BIT(16)
42 #define A10_FPGAMGR_IMGCFG_CTL_00_S2F_CONDONE_OE		BIT(24)
43 
44 #define A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG		BIT(0)
45 #define A10_FPGAMGR_IMGCFG_CTL_01_S2F_PR_REQUEST		BIT(16)
46 #define A10_FPGAMGR_IMGCFG_CTL_01_S2F_NCE			BIT(24)
47 
48 #define A10_FPGAMGR_IMGCFG_CTL_02_EN_CFG_CTRL			BIT(0)
49 #define A10_FPGAMGR_IMGCFG_CTL_02_CDRATIO_MASK		(BIT(16) | BIT(17))
50 #define A10_FPGAMGR_IMGCFG_CTL_02_CDRATIO_SHIFT			16
51 #define A10_FPGAMGR_IMGCFG_CTL_02_CFGWIDTH			BIT(24)
52 #define A10_FPGAMGR_IMGCFG_CTL_02_CFGWIDTH_SHIFT		24
53 
54 #define A10_FPGAMGR_IMGCFG_STAT_F2S_CRC_ERROR			BIT(0)
55 #define A10_FPGAMGR_IMGCFG_STAT_F2S_EARLY_USERMODE		BIT(1)
56 #define A10_FPGAMGR_IMGCFG_STAT_F2S_USERMODE			BIT(2)
57 #define A10_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN			BIT(4)
58 #define A10_FPGAMGR_IMGCFG_STAT_F2S_CONDONE_PIN			BIT(6)
59 #define A10_FPGAMGR_IMGCFG_STAT_F2S_PR_READY			BIT(9)
60 #define A10_FPGAMGR_IMGCFG_STAT_F2S_PR_DONE			BIT(10)
61 #define A10_FPGAMGR_IMGCFG_STAT_F2S_PR_ERROR			BIT(11)
62 #define A10_FPGAMGR_IMGCFG_STAT_F2S_NCONFIG_PIN			BIT(12)
63 #define A10_FPGAMGR_IMGCFG_STAT_F2S_MSEL_MASK	(BIT(16) | BIT(17) | BIT(18))
64 #define A10_FPGAMGR_IMGCFG_STAT_F2S_MSEL_SHIFT		        16
65 
66 /* FPGA CD Ratio Value */
67 #define CDRATIO_x1						0x0
68 #define CDRATIO_x2						0x1
69 #define CDRATIO_x4						0x2
70 #define CDRATIO_x8						0x3
71 
72 /* Configuration width 16/32 bit */
73 #define CFGWDTH_32						1
74 #define CFGWDTH_16						0
75 
76 /*
77  * struct a10_fpga_priv - private data for fpga manager
78  * @regmap: regmap for register access
79  * @fpga_data_addr: iomap for single address data register to FPGA
80  * @clk: clock
81  */
82 struct a10_fpga_priv {
83 	struct regmap *regmap;
84 	void __iomem *fpga_data_addr;
85 	struct clk *clk;
86 };
87 
88 static bool socfpga_a10_fpga_writeable_reg(struct device *dev, unsigned int reg)
89 {
90 	switch (reg) {
91 	case A10_FPGAMGR_DCLKCNT_OFST:
92 	case A10_FPGAMGR_DCLKSTAT_OFST:
93 	case A10_FPGAMGR_IMGCFG_CTL_00_OFST:
94 	case A10_FPGAMGR_IMGCFG_CTL_01_OFST:
95 	case A10_FPGAMGR_IMGCFG_CTL_02_OFST:
96 		return true;
97 	}
98 	return false;
99 }
100 
101 static bool socfpga_a10_fpga_readable_reg(struct device *dev, unsigned int reg)
102 {
103 	switch (reg) {
104 	case A10_FPGAMGR_DCLKCNT_OFST:
105 	case A10_FPGAMGR_DCLKSTAT_OFST:
106 	case A10_FPGAMGR_IMGCFG_CTL_00_OFST:
107 	case A10_FPGAMGR_IMGCFG_CTL_01_OFST:
108 	case A10_FPGAMGR_IMGCFG_CTL_02_OFST:
109 	case A10_FPGAMGR_IMGCFG_STAT_OFST:
110 		return true;
111 	}
112 	return false;
113 }
114 
115 static const struct regmap_config socfpga_a10_fpga_regmap_config = {
116 	.reg_bits = 32,
117 	.reg_stride = 4,
118 	.val_bits = 32,
119 	.writeable_reg = socfpga_a10_fpga_writeable_reg,
120 	.readable_reg = socfpga_a10_fpga_readable_reg,
121 	.max_register = A10_FPGAMGR_IMGCFG_STAT_OFST,
122 	.cache_type = REGCACHE_NONE,
123 };
124 
125 /*
126  * from the register map description of cdratio in imgcfg_ctrl_02:
127  *  Normal Configuration    : 32bit Passive Parallel
128  *  Partial Reconfiguration : 16bit Passive Parallel
129  */
130 static void socfpga_a10_fpga_set_cfg_width(struct a10_fpga_priv *priv,
131 					   int width)
132 {
133 	width <<= A10_FPGAMGR_IMGCFG_CTL_02_CFGWIDTH_SHIFT;
134 
135 	regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_02_OFST,
136 			   A10_FPGAMGR_IMGCFG_CTL_02_CFGWIDTH, width);
137 }
138 
139 static void socfpga_a10_fpga_generate_dclks(struct a10_fpga_priv *priv,
140 					    u32 count)
141 {
142 	u32 val;
143 
144 	/* Clear any existing DONE status. */
145 	regmap_write(priv->regmap, A10_FPGAMGR_DCLKSTAT_OFST,
146 		     A10_FPGAMGR_DCLKSTAT_DCLKDONE);
147 
148 	/* Issue the DCLK regmap. */
149 	regmap_write(priv->regmap, A10_FPGAMGR_DCLKCNT_OFST, count);
150 
151 	/* wait till the dclkcnt done */
152 	regmap_read_poll_timeout(priv->regmap, A10_FPGAMGR_DCLKSTAT_OFST, val,
153 				 val, 1, 100);
154 
155 	/* Clear DONE status. */
156 	regmap_write(priv->regmap, A10_FPGAMGR_DCLKSTAT_OFST,
157 		     A10_FPGAMGR_DCLKSTAT_DCLKDONE);
158 }
159 
160 #define RBF_ENCRYPTION_MODE_OFFSET		69
161 #define RBF_DECOMPRESS_OFFSET			229
162 
163 static int socfpga_a10_fpga_encrypted(u32 *buf32, size_t buf32_size)
164 {
165 	if (buf32_size < RBF_ENCRYPTION_MODE_OFFSET + 1)
166 		return -EINVAL;
167 
168 	/* Is the bitstream encrypted? */
169 	return ((buf32[RBF_ENCRYPTION_MODE_OFFSET] >> 2) & 3) != 0;
170 }
171 
172 static int socfpga_a10_fpga_compressed(u32 *buf32, size_t buf32_size)
173 {
174 	if (buf32_size < RBF_DECOMPRESS_OFFSET + 1)
175 		return -EINVAL;
176 
177 	/* Is the bitstream compressed? */
178 	return !((buf32[RBF_DECOMPRESS_OFFSET] >> 1) & 1);
179 }
180 
181 static unsigned int socfpga_a10_fpga_get_cd_ratio(unsigned int cfg_width,
182 						  bool encrypt, bool compress)
183 {
184 	unsigned int cd_ratio;
185 
186 	/*
187 	 * cd ratio is dependent on cfg width and whether the bitstream
188 	 * is encrypted and/or compressed.
189 	 *
190 	 * | width | encr. | compr. | cd ratio |
191 	 * |  16   |   0   |   0    |     1    |
192 	 * |  16   |   0   |   1    |     4    |
193 	 * |  16   |   1   |   0    |     2    |
194 	 * |  16   |   1   |   1    |     4    |
195 	 * |  32   |   0   |   0    |     1    |
196 	 * |  32   |   0   |   1    |     8    |
197 	 * |  32   |   1   |   0    |     4    |
198 	 * |  32   |   1   |   1    |     8    |
199 	 */
200 	if (!compress && !encrypt)
201 		return CDRATIO_x1;
202 
203 	if (compress)
204 		cd_ratio = CDRATIO_x4;
205 	else
206 		cd_ratio = CDRATIO_x2;
207 
208 	/* If 32 bit, double the cd ratio by incrementing the field  */
209 	if (cfg_width == CFGWDTH_32)
210 		cd_ratio += 1;
211 
212 	return cd_ratio;
213 }
214 
215 static int socfpga_a10_fpga_set_cdratio(struct fpga_manager *mgr,
216 					unsigned int cfg_width,
217 					const char *buf, size_t count)
218 {
219 	struct a10_fpga_priv *priv = mgr->priv;
220 	unsigned int cd_ratio;
221 	int encrypt, compress;
222 
223 	encrypt = socfpga_a10_fpga_encrypted((u32 *)buf, count / 4);
224 	if (encrypt < 0)
225 		return -EINVAL;
226 
227 	compress = socfpga_a10_fpga_compressed((u32 *)buf, count / 4);
228 	if (compress < 0)
229 		return -EINVAL;
230 
231 	cd_ratio = socfpga_a10_fpga_get_cd_ratio(cfg_width, encrypt, compress);
232 
233 	regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_02_OFST,
234 			   A10_FPGAMGR_IMGCFG_CTL_02_CDRATIO_MASK,
235 			   cd_ratio << A10_FPGAMGR_IMGCFG_CTL_02_CDRATIO_SHIFT);
236 
237 	return 0;
238 }
239 
240 static u32 socfpga_a10_fpga_read_stat(struct a10_fpga_priv *priv)
241 {
242 	u32 val;
243 
244 	regmap_read(priv->regmap, A10_FPGAMGR_IMGCFG_STAT_OFST, &val);
245 
246 	return val;
247 }
248 
249 static int socfpga_a10_fpga_wait_for_pr_ready(struct a10_fpga_priv *priv)
250 {
251 	u32 reg, i;
252 
253 	for (i = 0; i < 10 ; i++) {
254 		reg = socfpga_a10_fpga_read_stat(priv);
255 
256 		if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_PR_ERROR)
257 			return -EINVAL;
258 
259 		if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_PR_READY)
260 			return 0;
261 	}
262 
263 	return -ETIMEDOUT;
264 }
265 
266 static int socfpga_a10_fpga_wait_for_pr_done(struct a10_fpga_priv *priv)
267 {
268 	u32 reg, i;
269 
270 	for (i = 0; i < 10 ; i++) {
271 		reg = socfpga_a10_fpga_read_stat(priv);
272 
273 		if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_PR_ERROR)
274 			return -EINVAL;
275 
276 		if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_PR_DONE)
277 			return 0;
278 	}
279 
280 	return -ETIMEDOUT;
281 }
282 
283 /* Start the FPGA programming by initialize the FPGA Manager */
284 static int socfpga_a10_fpga_write_init(struct fpga_manager *mgr,
285 				       struct fpga_image_info *info,
286 				       const char *buf, size_t count)
287 {
288 	struct a10_fpga_priv *priv = mgr->priv;
289 	unsigned int cfg_width;
290 	u32 msel, stat, mask;
291 	int ret;
292 
293 	if (info->flags & FPGA_MGR_PARTIAL_RECONFIG)
294 		cfg_width = CFGWDTH_16;
295 	else
296 		return -EINVAL;
297 
298 	/* Check for passive parallel (msel == 000 or 001) */
299 	msel = socfpga_a10_fpga_read_stat(priv);
300 	msel &= A10_FPGAMGR_IMGCFG_STAT_F2S_MSEL_MASK;
301 	msel >>= A10_FPGAMGR_IMGCFG_STAT_F2S_MSEL_SHIFT;
302 	if ((msel != 0) && (msel != 1)) {
303 		dev_dbg(&mgr->dev, "Fail: invalid msel=%d\n", msel);
304 		return -EINVAL;
305 	}
306 
307 	/* Make sure no external devices are interfering */
308 	stat = socfpga_a10_fpga_read_stat(priv);
309 	mask = A10_FPGAMGR_IMGCFG_STAT_F2S_NCONFIG_PIN |
310 	       A10_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN;
311 	if ((stat & mask) != mask)
312 		return -EINVAL;
313 
314 	/* Set cfg width */
315 	socfpga_a10_fpga_set_cfg_width(priv, cfg_width);
316 
317 	/* Determine cd ratio from bitstream header and set cd ratio */
318 	ret = socfpga_a10_fpga_set_cdratio(mgr, cfg_width, buf, count);
319 	if (ret)
320 		return ret;
321 
322 	/*
323 	 * Clear s2f_nce to enable chip select.  Leave pr_request
324 	 * unasserted and override disabled.
325 	 */
326 	regmap_write(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST,
327 		     A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG);
328 
329 	/* Set cfg_ctrl to enable s2f dclk and data */
330 	regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_02_OFST,
331 			   A10_FPGAMGR_IMGCFG_CTL_02_EN_CFG_CTRL,
332 			   A10_FPGAMGR_IMGCFG_CTL_02_EN_CFG_CTRL);
333 
334 	/*
335 	 * Disable overrides not needed for pr.
336 	 * s2f_config==1 leaves reset deasseted.
337 	 */
338 	regmap_write(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_00_OFST,
339 		     A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NCONFIG |
340 		     A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_NSTATUS |
341 		     A10_FPGAMGR_IMGCFG_CTL_00_S2F_NENABLE_CONDONE |
342 		     A10_FPGAMGR_IMGCFG_CTL_00_S2F_NCONFIG);
343 
344 	/* Enable override for data, dclk, nce, and pr_request to CSS */
345 	regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST,
346 			   A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG, 0);
347 
348 	/* Send some clocks to clear out any errors */
349 	socfpga_a10_fpga_generate_dclks(priv, 256);
350 
351 	/* Assert pr_request */
352 	regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST,
353 			   A10_FPGAMGR_IMGCFG_CTL_01_S2F_PR_REQUEST,
354 			   A10_FPGAMGR_IMGCFG_CTL_01_S2F_PR_REQUEST);
355 
356 	/* Provide 2048 DCLKs before starting the config data streaming. */
357 	socfpga_a10_fpga_generate_dclks(priv, 0x7ff);
358 
359 	/* Wait for pr_ready */
360 	return socfpga_a10_fpga_wait_for_pr_ready(priv);
361 }
362 
363 /*
364  * write data to the FPGA data register
365  */
366 static int socfpga_a10_fpga_write(struct fpga_manager *mgr, const char *buf,
367 				  size_t count)
368 {
369 	struct a10_fpga_priv *priv = mgr->priv;
370 	u32 *buffer_32 = (u32 *)buf;
371 	size_t i = 0;
372 
373 	if (count <= 0)
374 		return -EINVAL;
375 
376 	/* Write out the complete 32-bit chunks */
377 	while (count >= sizeof(u32)) {
378 		writel(buffer_32[i++], priv->fpga_data_addr);
379 		count -= sizeof(u32);
380 	}
381 
382 	/* Write out remaining non 32-bit chunks */
383 	switch (count) {
384 	case 3:
385 		writel(buffer_32[i++] & 0x00ffffff, priv->fpga_data_addr);
386 		break;
387 	case 2:
388 		writel(buffer_32[i++] & 0x0000ffff, priv->fpga_data_addr);
389 		break;
390 	case 1:
391 		writel(buffer_32[i++] & 0x000000ff, priv->fpga_data_addr);
392 		break;
393 	case 0:
394 		break;
395 	default:
396 		/* This will never happen */
397 		return -EFAULT;
398 	}
399 
400 	return 0;
401 }
402 
403 static int socfpga_a10_fpga_write_complete(struct fpga_manager *mgr,
404 					   struct fpga_image_info *info)
405 {
406 	struct a10_fpga_priv *priv = mgr->priv;
407 	u32 reg;
408 	int ret;
409 
410 	/* Wait for pr_done */
411 	ret = socfpga_a10_fpga_wait_for_pr_done(priv);
412 
413 	/* Clear pr_request */
414 	regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST,
415 			   A10_FPGAMGR_IMGCFG_CTL_01_S2F_PR_REQUEST, 0);
416 
417 	/* Send some clocks to clear out any errors */
418 	socfpga_a10_fpga_generate_dclks(priv, 256);
419 
420 	/* Disable s2f dclk and data */
421 	regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_02_OFST,
422 			   A10_FPGAMGR_IMGCFG_CTL_02_EN_CFG_CTRL, 0);
423 
424 	/* Deassert chip select */
425 	regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST,
426 			   A10_FPGAMGR_IMGCFG_CTL_01_S2F_NCE,
427 			   A10_FPGAMGR_IMGCFG_CTL_01_S2F_NCE);
428 
429 	/* Disable data, dclk, nce, and pr_request override to CSS */
430 	regmap_update_bits(priv->regmap, A10_FPGAMGR_IMGCFG_CTL_01_OFST,
431 			   A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG,
432 			   A10_FPGAMGR_IMGCFG_CTL_01_S2F_NENABLE_CONFIG);
433 
434 	/* Return any errors regarding pr_done or pr_error */
435 	if (ret)
436 		return ret;
437 
438 	/* Final check */
439 	reg = socfpga_a10_fpga_read_stat(priv);
440 
441 	if (((reg & A10_FPGAMGR_IMGCFG_STAT_F2S_USERMODE) == 0) ||
442 	    ((reg & A10_FPGAMGR_IMGCFG_STAT_F2S_CONDONE_PIN) == 0) ||
443 	    ((reg & A10_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN) == 0)) {
444 		dev_dbg(&mgr->dev,
445 			"Timeout in final check. Status=%08xf\n", reg);
446 		return -ETIMEDOUT;
447 	}
448 
449 	return 0;
450 }
451 
452 static enum fpga_mgr_states socfpga_a10_fpga_state(struct fpga_manager *mgr)
453 {
454 	struct a10_fpga_priv *priv = mgr->priv;
455 	u32 reg = socfpga_a10_fpga_read_stat(priv);
456 
457 	if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_USERMODE)
458 		return FPGA_MGR_STATE_OPERATING;
459 
460 	if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_PR_READY)
461 		return FPGA_MGR_STATE_WRITE;
462 
463 	if (reg & A10_FPGAMGR_IMGCFG_STAT_F2S_CRC_ERROR)
464 		return FPGA_MGR_STATE_WRITE_COMPLETE_ERR;
465 
466 	if ((reg & A10_FPGAMGR_IMGCFG_STAT_F2S_NSTATUS_PIN) == 0)
467 		return FPGA_MGR_STATE_RESET;
468 
469 	return FPGA_MGR_STATE_UNKNOWN;
470 }
471 
472 static const struct fpga_manager_ops socfpga_a10_fpga_mgr_ops = {
473 	.initial_header_size = (RBF_DECOMPRESS_OFFSET + 1) * 4,
474 	.state = socfpga_a10_fpga_state,
475 	.write_init = socfpga_a10_fpga_write_init,
476 	.write = socfpga_a10_fpga_write,
477 	.write_complete = socfpga_a10_fpga_write_complete,
478 };
479 
480 static int socfpga_a10_fpga_probe(struct platform_device *pdev)
481 {
482 	struct device *dev = &pdev->dev;
483 	struct a10_fpga_priv *priv;
484 	void __iomem *reg_base;
485 	struct resource *res;
486 	int ret;
487 
488 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
489 	if (!priv)
490 		return -ENOMEM;
491 
492 	/* First mmio base is for register access */
493 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
494 	reg_base = devm_ioremap_resource(dev, res);
495 	if (IS_ERR(reg_base))
496 		return PTR_ERR(reg_base);
497 
498 	/* Second mmio base is for writing FPGA image data */
499 	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
500 	priv->fpga_data_addr = devm_ioremap_resource(dev, res);
501 	if (IS_ERR(priv->fpga_data_addr))
502 		return PTR_ERR(priv->fpga_data_addr);
503 
504 	/* regmap for register access */
505 	priv->regmap = devm_regmap_init_mmio(dev, reg_base,
506 					     &socfpga_a10_fpga_regmap_config);
507 	if (IS_ERR(priv->regmap))
508 		return -ENODEV;
509 
510 	priv->clk = devm_clk_get(dev, NULL);
511 	if (IS_ERR(priv->clk)) {
512 		dev_err(dev, "no clock specified\n");
513 		return PTR_ERR(priv->clk);
514 	}
515 
516 	ret = clk_prepare_enable(priv->clk);
517 	if (ret) {
518 		dev_err(dev, "could not enable clock\n");
519 		return -EBUSY;
520 	}
521 
522 	return fpga_mgr_register(dev, "SoCFPGA Arria10 FPGA Manager",
523 				 &socfpga_a10_fpga_mgr_ops, priv);
524 }
525 
526 static int socfpga_a10_fpga_remove(struct platform_device *pdev)
527 {
528 	struct fpga_manager *mgr = platform_get_drvdata(pdev);
529 	struct a10_fpga_priv *priv = mgr->priv;
530 
531 	fpga_mgr_unregister(&pdev->dev);
532 	clk_disable_unprepare(priv->clk);
533 
534 	return 0;
535 }
536 
537 static const struct of_device_id socfpga_a10_fpga_of_match[] = {
538 	{ .compatible = "altr,socfpga-a10-fpga-mgr", },
539 	{},
540 };
541 
542 MODULE_DEVICE_TABLE(of, socfpga_a10_fpga_of_match);
543 
544 static struct platform_driver socfpga_a10_fpga_driver = {
545 	.probe = socfpga_a10_fpga_probe,
546 	.remove = socfpga_a10_fpga_remove,
547 	.driver = {
548 		.name	= "socfpga_a10_fpga_manager",
549 		.of_match_table = socfpga_a10_fpga_of_match,
550 	},
551 };
552 
553 module_platform_driver(socfpga_a10_fpga_driver);
554 
555 MODULE_AUTHOR("Alan Tull <atull@opensource.altera.com>");
556 MODULE_DESCRIPTION("SoCFPGA Arria10 FPGA Manager");
557 MODULE_LICENSE("GPL v2");
558