Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1581425

[RFC 7/8] fpga-region: add sysfs interface

From Alan Tull <atull@kernel.org>
Newsgroups linux.kernel
Subject [RFC 7/8] fpga-region: add sysfs interface
Date 2017-02-15 17:20 +0100
Message-ID <tbatd-2fc-39@gated-at.bofh.it> (permalink)
References <tbatc-2fc-9@gated-at.bofh.it>
Organization linux.* mail to news gateway

Show all headers | View raw


Add a sysfs interface to control programming FPGA.

Each fpga-region will get the following files which set values
in the fpga_image_info struct for that region.  More files will
need to be added as fpga_image_info expands.

firmware_name
* writing a name of a FPGA image file to firmware_name causes the
  FPGA region to write the FPGA

partial_config
* 0 : full reconfiguration
* 1 : partial reconfiguration

unfreeze_timeout
* Timeout for waiting for a freeze bridge to enable traffic

freeze_timeout
* Timeout for waiting for a freeze bridge to disable traffic

Signed-off-by: Alan Tull <atull@kernel.org>
---
 drivers/fpga/Kconfig       |   8 ++
 drivers/fpga/fpga-region.c | 241 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 249 insertions(+)

diff --git a/drivers/fpga/Kconfig b/drivers/fpga/Kconfig
index be9c23d..6455e02 100644
--- a/drivers/fpga/Kconfig
+++ b/drivers/fpga/Kconfig
@@ -21,6 +21,14 @@ config FPGA_REGION
 	  and the FPGA Bridges associated with either a reconfigurable
 	  region of an FPGA or a whole FPGA.
 
+config FPGA_REGION_SYSFS
+       bool "FPGA Region Sysfs"
+	depends on FPGA_REGION
+	help
+	  FPGA Region sysfs interface.  This creates sysfs file for each
+	  FPGA Region under /sys/class/fpga_region/ to show status and
+	  control programming FPGA regions.
+
 config OF_FPGA_REGION
 	tristate "FPGA Region Device Tree Overlay Support"
 	depends on FPGA_REGION
diff --git a/drivers/fpga/fpga-region.c b/drivers/fpga/fpga-region.c
index 5690237..a63bc6c 100644
--- a/drivers/fpga/fpga-region.c
+++ b/drivers/fpga/fpga-region.c
@@ -105,6 +105,243 @@ EXPORT_SYMBOL_GPL(fpga_region_ovl_image_info);
 
 #endif /* CONFIG_OF_FPGA_REGION */
 
+#if IS_ENABLED(CONFIG_FPGA_REGION_SYSFS)
+
+struct fpga_image_info *image_info_from_region(struct fpga_region *region)
+{
+	struct fpga_image_info *image_info;
+
+	/* If region has an overlay, display image_info from overlay. */
+	image_info = fpga_region_ovl_image_info(region);
+	if (!image_info)
+		image_info = region->image_info;
+
+	return image_info;
+}
+
+/*
+ * Controlling a region both by sysfs and by device tree overlays is
+ * not supported.
+ */
+static ssize_t firmware_name_show(struct device *dev,
+				  struct device_attribute *attr, char *buf)
+{
+	struct fpga_region *region = to_fpga_region(dev);
+	struct fpga_image_info *image_info;
+
+	image_info = image_info_from_region(region);
+
+	if (image_info && image_info->firmware_name)
+		return sprintf(buf, "%s\n", image_info->firmware_name);
+
+	return 0;
+}
+
+static ssize_t firmware_name_store(struct device *dev,
+				   struct device_attribute *attr,
+				   const char *buf, size_t count)
+{
+	struct fpga_region *region = to_fpga_region(dev);
+	char *firmware_name;
+	size_t len;
+	int ret;
+
+	/*
+	 * Controlling a region both by sysfs and by device tree overlays is
+	 * not supported.
+	 */
+	if (fpga_region_ovl_image_info(region))
+		return -EINVAL;
+
+	if (!region->image_info) {
+		region->image_info = fpga_region_alloc_image_info(region);
+		if (!region->image_info)
+			return -ENOMEM;
+	}
+
+	firmware_name = devm_kzalloc(dev, count, GFP_KERNEL);
+	if (!firmware_name)
+		return -ENOMEM;
+	pr_err("count = %d\n", count);
+	/* lose terminating \n */
+	strcpy(firmware_name, buf);
+	len = strlen(firmware_name);
+	if (firmware_name[len - 1] == '\n')
+		firmware_name[len - 1] = 0;
+	if (firmware_name[0] == 0) {
+		devm_kfree(dev, firmware_name);
+		firmware_name = NULL;
+	}
+
+	/* Release previous firmware name (if any). Save current one. */
+	if (region->image_info->firmware_name)
+		devm_kfree(dev, region->image_info->firmware_name);
+	region->image_info->firmware_name = firmware_name;
+
+	if (firmware_name) {
+		ret = fpga_region_program_fpga(region, region->image_info);
+		if (ret)
+			dev_err(dev,
+				"FPGA programming failed with value %d\n", ret);
+	} else {
+		/*
+		 * Writing null string to firmware_name will disable and put
+		 * the bridges (if there were any bridges in the bridge list).
+		 */
+		fpga_bridges_disable(&region->bridge_list);
+		if (region->get_bridges)
+			fpga_bridges_put(&region->bridge_list);
+		fpga_region_free_image_info(region, region->image_info);
+		region->image_info = NULL;
+	}
+
+	return count;
+}
+
+static ssize_t partial_config_show(struct device *dev,
+				   struct device_attribute *attr, char *buf)
+{
+	struct fpga_region *region = to_fpga_region(dev);
+	struct fpga_image_info *image_info;
+	int partial;
+
+	image_info = image_info_from_region(region);
+	if (!image_info)
+		return 0;
+
+	partial = !!(image_info->flags & FPGA_MGR_PARTIAL_RECONFIG);
+
+	return sprintf(buf, "%d\n", partial);
+}
+
+static ssize_t partial_config_store(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf, size_t count)
+{
+	struct fpga_region *region = to_fpga_region(dev);
+	unsigned long val;
+	int ret;
+
+	if (fpga_region_ovl_image_info(region))
+		return -EINVAL;
+
+	if (!region->image_info) {
+		region->image_info = fpga_region_alloc_image_info(region);
+		if (!region->image_info)
+			return -ENOMEM;
+	}
+
+	ret = kstrtoul(buf, 0, &val);
+	if (ret)
+		return ret;
+
+	if (val == 1)
+		region->image_info->flags |= FPGA_MGR_PARTIAL_RECONFIG;
+	else if (val == 0)
+		region->image_info->flags &= ~FPGA_MGR_PARTIAL_RECONFIG;
+	else
+		return -EINVAL;
+
+	return count;
+}
+
+static ssize_t unfreeze_timeout_show(struct device *dev,
+				     struct device_attribute *attr,
+				     char *buf)
+{
+	struct fpga_region *region = to_fpga_region(dev);
+	struct fpga_image_info *image_info;
+
+	image_info = image_info_from_region(region);
+	if (!image_info)
+		return 0;
+
+	return sprintf(buf, "%d\n", image_info->enable_timeout_us);
+}
+
+static ssize_t unfreeze_timeout_store(struct device *dev,
+				      struct device_attribute *attr,
+				      const char *buf,
+				      size_t count)
+{
+	struct fpga_region *region = to_fpga_region(dev);
+	unsigned long val;
+	int ret;
+
+	if (fpga_region_ovl_image_info(region))
+		return -EINVAL;
+
+	if (!region->image_info) {
+		region->image_info = fpga_region_alloc_image_info(region);
+		if (!region->image_info)
+			return -ENOMEM;
+	}
+
+	ret = kstrtoul(buf, 0, &val);
+	if (ret)
+		return ret;
+
+	region->image_info->enable_timeout_us = val;
+
+	return count;
+}
+
+static ssize_t freeze_timeout_show(struct device *dev,
+				   struct device_attribute *attr, char *buf)
+{
+	struct fpga_region *region = to_fpga_region(dev);
+	struct fpga_image_info *image_info;
+
+	image_info = image_info_from_region(region);
+	if (!image_info)
+		return 0;
+
+	return sprintf(buf, "%d\n", image_info->disable_timeout_us);
+}
+
+static ssize_t freeze_timeout_store(struct device *dev,
+				    struct device_attribute *attr,
+				    const char *buf,
+				    size_t count)
+{
+	struct fpga_region *region = to_fpga_region(dev);
+	unsigned long val;
+	int ret;
+
+	if (fpga_region_ovl_image_info(region))
+		return -EINVAL;
+
+	if (!region->image_info) {
+		region->image_info = fpga_region_alloc_image_info(region);
+		if (!region->image_info)
+			return -ENOMEM;
+	}
+
+	ret = kstrtoul(buf, 0, &val);
+	if (ret)
+		return ret;
+
+	region->image_info->disable_timeout_us = val;
+
+	return count;
+}
+
+static DEVICE_ATTR_RW(firmware_name);
+static DEVICE_ATTR_RW(partial_config);
+static DEVICE_ATTR_RW(unfreeze_timeout);
+static DEVICE_ATTR_RW(freeze_timeout);
+
+static struct attribute *fpga_region_attrs[] = {
+	&dev_attr_firmware_name.attr,
+	&dev_attr_partial_config.attr,
+	&dev_attr_unfreeze_timeout.attr,
+	&dev_attr_freeze_timeout.attr,
+	NULL,
+};
+ATTRIBUTE_GROUPS(fpga_region);
+
+#endif /* CONFIG_FPGA_REGION_SYSFS */
+
 /**
  * fpga_region_get - get an exclusive reference to a fpga region
  * @region: FPGA Region struct
@@ -288,6 +525,10 @@ static int __init fpga_region_init(void)
 	if (IS_ERR(fpga_region_class))
 		return PTR_ERR(fpga_region_class);
 
+#if IS_ENABLED(CONFIG_FPGA_REGION_SYSFS)
+	fpga_region_class->dev_groups = fpga_region_groups;
+#endif /* CONFIG_FPGA_REGION_SYSFS */
+
 	fpga_region_class->dev_release = fpga_region_dev_release;
 
 	return 0;
-- 
2.7.4

Back to linux.kernel | Previous | NextNext in thread | Find similar | Unroll thread


Thread

[RFC 7/8] fpga-region: add sysfs interface Alan Tull <atull@kernel.org> - 2017-02-15 17:20 +0100
  Re: [RFC 7/8] fpga-region: add sysfs interface Jason Gunthorpe <jgunthorpe@obsidianresearch.com> - 2017-02-15 18:30 +0100
    Re: [RFC 7/8] fpga-region: add sysfs interface Alan Tull <delicious.quinoa@gmail.com> - 2017-02-15 18:50 +0100
      Re: [RFC 7/8] fpga-region: add sysfs interface Moritz Fischer <moritz.fischer@ettus.com> - 2017-02-15 19:00 +0100
      Re: [RFC 7/8] fpga-region: add sysfs interface Jason Gunthorpe <jgunthorpe@obsidianresearch.com> - 2017-02-15 19:10 +0100
        Re: [RFC 7/8] fpga-region: add sysfs interface Alan Tull <delicious.quinoa@gmail.com> - 2017-02-15 19:30 +0100
          Re: [RFC 7/8] fpga-region: add sysfs interface Moritz Fischer <moritz.fischer@ettus.com> - 2017-02-15 19:40 +0100
          Re: [RFC 7/8] fpga-region: add sysfs interface Jason Gunthorpe <jgunthorpe@obsidianresearch.com> - 2017-02-15 20:50 +0100
            Re: [RFC 7/8] fpga-region: add sysfs interface Alan Tull <delicious.quinoa@gmail.com> - 2017-02-16 00:00 +0100
              Re: [RFC 7/8] fpga-region: add sysfs interface Jason Gunthorpe <jgunthorpe@obsidianresearch.com> - 2017-02-16 00:10 +0100
          Re: [RFC 7/8] fpga-region: add sysfs interface matthew.gerlach@linux.intel.com - 2017-02-15 21:10 +0100
            Re: [RFC 7/8] fpga-region: add sysfs interface Jason Gunthorpe <jgunthorpe@obsidianresearch.com> - 2017-02-15 21:40 +0100
              Re: [RFC 7/8] fpga-region: add sysfs interface Moritz Fischer <moritz.fischer@ettus.com> - 2017-02-15 22:00 +0100
                Re: [RFC 7/8] fpga-region: add sysfs interface Jason Gunthorpe <jgunthorpe@obsidianresearch.com> - 2017-02-15 22:20 +0100
                Re: [RFC 7/8] fpga-region: add sysfs interface Moritz Fischer <moritz.fischer@ettus.com> - 2017-02-15 22:40 +0100
                Re: [RFC 7/8] fpga-region: add sysfs interface Alan Tull <delicious.quinoa@gmail.com> - 2017-02-15 23:50 +0100
                Re: [RFC 7/8] fpga-region: add sysfs interface Moritz Fischer <moritz.fischer@ettus.com> - 2017-02-16 01:20 +0100
                Re: [RFC 7/8] fpga-region: add sysfs interface Alan Tull <delicious.quinoa@gmail.com> - 2017-02-16 18:50 +0100
                Re: [RFC 7/8] fpga-region: add sysfs interface Jason Gunthorpe <jgunthorpe@obsidianresearch.com> - 2017-02-16 19:00 +0100
                Re: [RFC 7/8] fpga-region: add sysfs interface Moritz Fischer <moritz.fischer@ettus.com> - 2017-02-16 19:20 +0100
                Re: [RFC 7/8] fpga-region: add sysfs interface Yves Vandervennet <yves.vandervennet@linux.intel.com> - 2017-02-17 23:30 +0100
                Re: [RFC 7/8] fpga-region: add sysfs interface Moritz Fischer <moritz.fischer@ettus.com> - 2017-02-18 03:40 +0100
                RE: [RFC 7/8] fpga-region: add sysfs interface "Nadathur, Sundar" <sundar.nadathur@intel.com> - 2017-02-18 13:50 +0100
                Re: [RFC 7/8] fpga-region: add sysfs interface Alan Tull <delicious.quinoa@gmail.com> - 2017-02-18 21:20 +0100
                Re: [RFC 7/8] fpga-region: add sysfs interface Moritz Fischer <moritz.fischer@ettus.com> - 2017-02-18 22:00 +0100
                Re: [RFC 7/8] fpga-region: add sysfs interface Alan Tull <delicious.quinoa@gmail.com> - 2017-02-19 16:10 +0100
                Re: [RFC 7/8] fpga-region: add sysfs interface Alan Tull <delicious.quinoa@gmail.com> - 2017-02-20 00:20 +0100
                Re: [RFC 7/8] fpga-region: add sysfs interface Moritz Fischer <moritz.fischer@ettus.com> - 2017-02-21 01:00 +0100
                Re: [RFC 7/8] fpga-region: add sysfs interface Alan Tull <delicious.quinoa@gmail.com> - 2017-02-21 19:40 +0100
                RE: [RFC 7/8] fpga-region: add sysfs interface "Nadathur, Sundar" <sundar.nadathur@intel.com> - 2017-02-22 04:20 +0100
                Re: [RFC 7/8] fpga-region: add sysfs interface Moritz Fischer <moritz.fischer@ettus.com> - 2017-02-22 04:50 +0100
                Re: [RFC 7/8] fpga-region: add sysfs interface Jason Gunthorpe <jgunthorpe@obsidianresearch.com> - 2017-02-22 06:20 +0100
                Re: [RFC 7/8] fpga-region: add sysfs interface Moritz Fischer <moritz.fischer@ettus.com> - 2017-02-22 06:40 +0100
                RE: [RFC 7/8] fpga-region: add sysfs interface "Nadathur, Sundar" <sundar.nadathur@intel.com> - 2017-02-22 06:50 +0100
                Re: [RFC 7/8] fpga-region: add sysfs interface Moritz Fischer <moritz.fischer@ettus.com> - 2017-02-22 07:10 +0100
                Re: [RFC 7/8] fpga-region: add sysfs interface Jason Gunthorpe <jgunthorpe@obsidianresearch.com> - 2017-02-22 17:50 +0100
                Re: [RFC 7/8] fpga-region: add sysfs interface Moritz Fischer <moritz.fischer@ettus.com> - 2017-02-22 19:00 +0100
                Re: [RFC 7/8] fpga-region: add sysfs interface Jason Gunthorpe <jgunthorpe@obsidianresearch.com> - 2017-02-22 19:00 +0100
                Re: [RFC 7/8] fpga-region: add sysfs interface Moritz Fischer <moritz.fischer@ettus.com> - 2017-02-22 19:00 +0100
                Re: [RFC 7/8] fpga-region: add sysfs interface Alan Tull <delicious.quinoa@gmail.com> - 2017-02-22 17:40 +0100
                Re: [RFC 7/8] fpga-region: add sysfs interface Moritz Fischer <moritz.fischer@ettus.com> - 2017-02-22 17:50 +0100
                Re: [RFC 7/8] fpga-region: add sysfs interface Alan Tull <delicious.quinoa@gmail.com> - 2017-02-22 18:00 +0100
                Re: [RFC 7/8] fpga-region: add sysfs interface Moritz Fischer <moritz.fischer@ettus.com> - 2017-02-28 00:00 +0100
                Re: [RFC 7/8] fpga-region: add sysfs interface matthew.gerlach@linux.intel.com - 2017-02-28 07:30 +0100
                Re: [RFC 7/8] fpga-region: add sysfs interface Alan Tull <delicious.quinoa@gmail.com> - 2017-02-28 13:40 +0100
        Re: [RFC 7/8] fpga-region: add sysfs interface Anatolij Gustschin <agust@denx.de> - 2017-02-15 22:30 +0100

csiph-web