aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/fpga/fpga-mgr.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/fpga/fpga-mgr.c')
-rw-r--r--drivers/fpga/fpga-mgr.c157
1 files changed, 110 insertions, 47 deletions
diff --git a/drivers/fpga/fpga-mgr.c b/drivers/fpga/fpga-mgr.c
index 9939d2cbc9a6..a41b07e37884 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)
@@ -397,12 +406,40 @@ static ssize_t state_show(struct device *dev,
397 return sprintf(buf, "%s\n", state_str[mgr->state]); 406 return sprintf(buf, "%s\n", state_str[mgr->state]);
398} 407}
399 408
409static ssize_t status_show(struct device *dev,
410 struct device_attribute *attr, char *buf)
411{
412 struct fpga_manager *mgr = to_fpga_manager(dev);
413 u64 status;
414 int len = 0;
415
416 if (!mgr->mops->status)
417 return -ENOENT;
418
419 status = mgr->mops->status(mgr);
420
421 if (status & FPGA_MGR_STATUS_OPERATION_ERR)
422 len += sprintf(buf + len, "reconfig operation error\n");
423 if (status & FPGA_MGR_STATUS_CRC_ERR)
424 len += sprintf(buf + len, "reconfig CRC error\n");
425 if (status & FPGA_MGR_STATUS_INCOMPATIBLE_IMAGE_ERR)
426 len += sprintf(buf + len, "reconfig incompatible image\n");
427 if (status & FPGA_MGR_STATUS_IP_PROTOCOL_ERR)
428 len += sprintf(buf + len, "reconfig IP protocol error\n");
429 if (status & FPGA_MGR_STATUS_FIFO_OVERFLOW_ERR)
430 len += sprintf(buf + len, "reconfig fifo overflow error\n");
431
432 return len;
433}
434
400static DEVICE_ATTR_RO(name); 435static DEVICE_ATTR_RO(name);
401static DEVICE_ATTR_RO(state); 436static DEVICE_ATTR_RO(state);
437static DEVICE_ATTR_RO(status);
402 438
403static struct attribute *fpga_mgr_attrs[] = { 439static struct attribute *fpga_mgr_attrs[] = {
404 &dev_attr_name.attr, 440 &dev_attr_name.attr,
405 &dev_attr_state.attr, 441 &dev_attr_state.attr,
442 &dev_attr_status.attr,
406 NULL, 443 NULL,
407}; 444};
408ATTRIBUTE_GROUPS(fpga_mgr); 445ATTRIBUTE_GROUPS(fpga_mgr);
@@ -429,11 +466,9 @@ static int fpga_mgr_dev_match(struct device *dev, const void *data)
429} 466}
430 467
431/** 468/**
432 * fpga_mgr_get - get a reference to a fpga mgr 469 * fpga_mgr_get - Given a device, get a reference to a fpga mgr.
433 * @dev: parent device that fpga mgr was registered with 470 * @dev: parent device that fpga mgr was registered with
434 * 471 *
435 * Given a device, get a reference to a fpga mgr.
436 *
437 * Return: fpga manager struct or IS_ERR() condition containing error code. 472 * Return: fpga manager struct or IS_ERR() condition containing error code.
438 */ 473 */
439struct fpga_manager *fpga_mgr_get(struct device *dev) 474struct fpga_manager *fpga_mgr_get(struct device *dev)
@@ -453,10 +488,9 @@ static int fpga_mgr_of_node_match(struct device *dev, const void *data)
453} 488}
454 489
455/** 490/**
456 * of_fpga_mgr_get - get a reference to a fpga mgr 491 * of_fpga_mgr_get - Given a device node, get a reference to a fpga mgr.
457 * @node: device node
458 * 492 *
459 * Given a device node, get a reference to a fpga mgr. 493 * @node: device node
460 * 494 *
461 * Return: fpga manager struct or IS_ERR() condition containing error code. 495 * Return: fpga manager struct or IS_ERR() condition containing error code.
462 */ 496 */
@@ -489,7 +523,10 @@ EXPORT_SYMBOL_GPL(fpga_mgr_put);
489 * @mgr: fpga manager 523 * @mgr: fpga manager
490 * 524 *
491 * Given a pointer to FPGA Manager (from fpga_mgr_get() or 525 * Given a pointer to FPGA Manager (from fpga_mgr_get() or
492 * of_fpga_mgr_put()) attempt to get the mutex. 526 * of_fpga_mgr_put()) attempt to get the mutex. The user should call
527 * fpga_mgr_lock() and verify that it returns 0 before attempting to
528 * program the FPGA. Likewise, the user should call fpga_mgr_unlock
529 * when done programming the FPGA.
493 * 530 *
494 * Return: 0 for success or -EBUSY 531 * Return: 0 for success or -EBUSY
495 */ 532 */
@@ -505,7 +542,7 @@ int fpga_mgr_lock(struct fpga_manager *mgr)
505EXPORT_SYMBOL_GPL(fpga_mgr_lock); 542EXPORT_SYMBOL_GPL(fpga_mgr_lock);
506 543
507/** 544/**
508 * fpga_mgr_unlock - Unlock FPGA manager 545 * fpga_mgr_unlock - Unlock FPGA manager after done programming
509 * @mgr: fpga manager 546 * @mgr: fpga manager
510 */ 547 */
511void fpga_mgr_unlock(struct fpga_manager *mgr) 548void fpga_mgr_unlock(struct fpga_manager *mgr)
@@ -515,17 +552,17 @@ void fpga_mgr_unlock(struct fpga_manager *mgr)
515EXPORT_SYMBOL_GPL(fpga_mgr_unlock); 552EXPORT_SYMBOL_GPL(fpga_mgr_unlock);
516 553
517/** 554/**
518 * fpga_mgr_register - register a low level fpga manager driver 555 * fpga_mgr_create - create and initialize a FPGA manager struct
519 * @dev: fpga manager device from pdev 556 * @dev: fpga manager device from pdev
520 * @name: fpga manager name 557 * @name: fpga manager name
521 * @mops: pointer to structure of fpga manager ops 558 * @mops: pointer to structure of fpga manager ops
522 * @priv: fpga manager private data 559 * @priv: fpga manager private data
523 * 560 *
524 * Return: 0 on success, negative error code otherwise. 561 * Return: pointer to struct fpga_manager or NULL
525 */ 562 */
526int fpga_mgr_register(struct device *dev, const char *name, 563struct fpga_manager *fpga_mgr_create(struct device *dev, const char *name,
527 const struct fpga_manager_ops *mops, 564 const struct fpga_manager_ops *mops,
528 void *priv) 565 void *priv)
529{ 566{
530 struct fpga_manager *mgr; 567 struct fpga_manager *mgr;
531 int id, ret; 568 int id, ret;
@@ -534,17 +571,17 @@ int fpga_mgr_register(struct device *dev, const char *name,
534 !mops->write_init || (!mops->write && !mops->write_sg) || 571 !mops->write_init || (!mops->write && !mops->write_sg) ||
535 (mops->write && mops->write_sg)) { 572 (mops->write && mops->write_sg)) {
536 dev_err(dev, "Attempt to register without fpga_manager_ops\n"); 573 dev_err(dev, "Attempt to register without fpga_manager_ops\n");
537 return -EINVAL; 574 return NULL;
538 } 575 }
539 576
540 if (!name || !strlen(name)) { 577 if (!name || !strlen(name)) {
541 dev_err(dev, "Attempt to register with no name!\n"); 578 dev_err(dev, "Attempt to register with no name!\n");
542 return -EINVAL; 579 return NULL;
543 } 580 }
544 581
545 mgr = kzalloc(sizeof(*mgr), GFP_KERNEL); 582 mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
546 if (!mgr) 583 if (!mgr)
547 return -ENOMEM; 584 return NULL;
548 585
549 id = ida_simple_get(&fpga_mgr_ida, 0, 0, GFP_KERNEL); 586 id = ida_simple_get(&fpga_mgr_ida, 0, 0, GFP_KERNEL);
550 if (id < 0) { 587 if (id < 0) {
@@ -558,25 +595,56 @@ int fpga_mgr_register(struct device *dev, const char *name,
558 mgr->mops = mops; 595 mgr->mops = mops;
559 mgr->priv = priv; 596 mgr->priv = priv;
560 597
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); 598 device_initialize(&mgr->dev);
569 mgr->dev.class = fpga_mgr_class; 599 mgr->dev.class = fpga_mgr_class;
570 mgr->dev.groups = mops->groups; 600 mgr->dev.groups = mops->groups;
571 mgr->dev.parent = dev; 601 mgr->dev.parent = dev;
572 mgr->dev.of_node = dev->of_node; 602 mgr->dev.of_node = dev->of_node;
573 mgr->dev.id = id; 603 mgr->dev.id = id;
574 dev_set_drvdata(dev, mgr);
575 604
576 ret = dev_set_name(&mgr->dev, "fpga%d", id); 605 ret = dev_set_name(&mgr->dev, "fpga%d", id);
577 if (ret) 606 if (ret)
578 goto error_device; 607 goto error_device;
579 608
609 return mgr;
610
611error_device:
612 ida_simple_remove(&fpga_mgr_ida, id);
613error_kfree:
614 kfree(mgr);
615
616 return NULL;
617}
618EXPORT_SYMBOL_GPL(fpga_mgr_create);
619
620/**
621 * fpga_mgr_free - deallocate a FPGA manager
622 * @mgr: fpga manager struct created by fpga_mgr_create
623 */
624void fpga_mgr_free(struct fpga_manager *mgr)
625{
626 ida_simple_remove(&fpga_mgr_ida, mgr->dev.id);
627 kfree(mgr);
628}
629EXPORT_SYMBOL_GPL(fpga_mgr_free);
630
631/**
632 * fpga_mgr_register - register a FPGA manager
633 * @mgr: fpga manager struct created by fpga_mgr_create
634 *
635 * Return: 0 on success, negative error code otherwise.
636 */
637int fpga_mgr_register(struct fpga_manager *mgr)
638{
639 int ret;
640
641 /*
642 * Initialize framework state by requesting low level driver read state
643 * from device. FPGA may be in reset mode or may have been programmed
644 * by bootloader or EEPROM.
645 */
646 mgr->state = mgr->mops->state(mgr);
647
580 ret = device_add(&mgr->dev); 648 ret = device_add(&mgr->dev);
581 if (ret) 649 if (ret)
582 goto error_device; 650 goto error_device;
@@ -586,22 +654,18 @@ int fpga_mgr_register(struct device *dev, const char *name,
586 return 0; 654 return 0;
587 655
588error_device: 656error_device:
589 ida_simple_remove(&fpga_mgr_ida, id); 657 ida_simple_remove(&fpga_mgr_ida, mgr->dev.id);
590error_kfree:
591 kfree(mgr);
592 658
593 return ret; 659 return ret;
594} 660}
595EXPORT_SYMBOL_GPL(fpga_mgr_register); 661EXPORT_SYMBOL_GPL(fpga_mgr_register);
596 662
597/** 663/**
598 * fpga_mgr_unregister - unregister a low level fpga manager driver 664 * fpga_mgr_unregister - unregister and free a FPGA manager
599 * @dev: fpga manager device from pdev 665 * @mgr: fpga manager struct
600 */ 666 */
601void fpga_mgr_unregister(struct device *dev) 667void fpga_mgr_unregister(struct fpga_manager *mgr)
602{ 668{
603 struct fpga_manager *mgr = dev_get_drvdata(dev);
604
605 dev_info(&mgr->dev, "%s %s\n", __func__, mgr->name); 669 dev_info(&mgr->dev, "%s %s\n", __func__, mgr->name);
606 670
607 /* 671 /*
@@ -619,8 +683,7 @@ static void fpga_mgr_dev_release(struct device *dev)
619{ 683{
620 struct fpga_manager *mgr = to_fpga_manager(dev); 684 struct fpga_manager *mgr = to_fpga_manager(dev);
621 685
622 ida_simple_remove(&fpga_mgr_ida, mgr->dev.id); 686 fpga_mgr_free(mgr);
623 kfree(mgr);
624} 687}
625 688
626static int __init fpga_mgr_class_init(void) 689static int __init fpga_mgr_class_init(void)