diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-05 19:20:22 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2018-06-05 19:20:22 -0400 |
commit | abf7dba7c4f77d781f6df50fefb19a64c5dc331f (patch) | |
tree | 38648731b502d5aec508f3b33f6616190e598eb6 /drivers/fpga/fpga-mgr.c | |
parent | 07c4dd3435aa387d3b58f4e941dc516513f14507 (diff) | |
parent | b23220fe054e92f616b82450fae8cd3ab176cc60 (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/fpga-mgr.c')
-rw-r--r-- | drivers/fpga/fpga-mgr.c | 129 |
1 files changed, 82 insertions, 47 deletions
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 @@ | |||
32 | static DEFINE_IDA(fpga_mgr_ida); | 21 | static DEFINE_IDA(fpga_mgr_ida); |
33 | static struct class *fpga_mgr_class; | 22 | static 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 | */ | ||
35 | struct fpga_image_info *fpga_image_info_alloc(struct device *dev) | 30 | struct 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 | } |
51 | EXPORT_SYMBOL_GPL(fpga_image_info_alloc); | 46 | EXPORT_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 | */ | ||
53 | void fpga_image_info_free(struct fpga_image_info *info) | 52 | void 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 | */ | ||
346 | int fpga_mgr_load(struct fpga_manager *mgr, struct fpga_image_info *info) | 355 | int 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 | */ |
439 | struct fpga_manager *fpga_mgr_get(struct device *dev) | 446 | struct 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) | |||
505 | EXPORT_SYMBOL_GPL(fpga_mgr_lock); | 514 | EXPORT_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 | */ |
511 | void fpga_mgr_unlock(struct fpga_manager *mgr) | 520 | void fpga_mgr_unlock(struct fpga_manager *mgr) |
@@ -515,17 +524,17 @@ void fpga_mgr_unlock(struct fpga_manager *mgr) | |||
515 | EXPORT_SYMBOL_GPL(fpga_mgr_unlock); | 524 | EXPORT_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 | */ |
526 | int fpga_mgr_register(struct device *dev, const char *name, | 535 | struct 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 | |||
583 | error_device: | ||
584 | ida_simple_remove(&fpga_mgr_ida, id); | ||
585 | error_kfree: | ||
586 | kfree(mgr); | ||
587 | |||
588 | return NULL; | ||
589 | } | ||
590 | EXPORT_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 | */ | ||
596 | void fpga_mgr_free(struct fpga_manager *mgr) | ||
597 | { | ||
598 | ida_simple_remove(&fpga_mgr_ida, mgr->dev.id); | ||
599 | kfree(mgr); | ||
600 | } | ||
601 | EXPORT_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 | */ | ||
609 | int 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 | ||
588 | error_device: | 628 | error_device: |
589 | ida_simple_remove(&fpga_mgr_ida, id); | 629 | ida_simple_remove(&fpga_mgr_ida, mgr->dev.id); |
590 | error_kfree: | ||
591 | kfree(mgr); | ||
592 | 630 | ||
593 | return ret; | 631 | return ret; |
594 | } | 632 | } |
595 | EXPORT_SYMBOL_GPL(fpga_mgr_register); | 633 | EXPORT_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 | */ |
601 | void fpga_mgr_unregister(struct device *dev) | 639 | void 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 | ||
626 | static int __init fpga_mgr_class_init(void) | 661 | static int __init fpga_mgr_class_init(void) |