aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/fpga/fpga-mgr.c
diff options
context:
space:
mode:
authorThomas Gleixner <tglx@linutronix.de>2018-02-16 09:47:26 -0500
committerThomas Gleixner <tglx@linutronix.de>2018-02-16 09:47:26 -0500
commit6dee6ae9d62642e81def4d461d71f13a6496ab59 (patch)
tree6c75d416c427a59f190e197ad83fe59b7bebf656 /drivers/fpga/fpga-mgr.c
parent1beaeacdc88b537703d04d5536235d0bbb36db93 (diff)
parent0b24a0bbe2147815d982d9335c41bb10c04f40bc (diff)
Merge tag 'irqchip-4.16-2' of git://git.kernel.org/pub/scm/linux/kernel/git/maz/arm-platforms into irq/urgent
Pull irqchip updates for 4.16-rc2 from Marc Zyngier - A MIPS GIC fix for spurious, masked interrupts - A fix for a subtle IPI bug in GICv3 - Do not probe GICv3 ITSs that are marked as disabled - Multi-MSI support for GICv2m - Various cleanups
Diffstat (limited to 'drivers/fpga/fpga-mgr.c')
-rw-r--r--drivers/fpga/fpga-mgr.c123
1 files changed, 94 insertions, 29 deletions
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