Загрузка данных


#include <linux/fs.h>
#include <linux/firmware.h>
#include <linux/fpga/fpga-mgr.h>

/* ... ваши существующие функции I2C-транспорта (sysconfig_i2c_...) ... */

/*
 * Sysfs callback handler for writing the firmware.
 * This function is triggered when you execute: echo file.bit > /sys/bus/i2c/devices/.../load_fpga
 */
static ssize_t load_fpga_store(struct device *dev, struct device_attribute *attr,
				const char *buf, size_t count)
{
	struct fpga_csi_bridge_priv *priv = dev_get_drvdata(dev);
	struct fpga_image_info *info;
	char fw_name[64];
	int ret;

	if (count == 0 || count >= sizeof(fw_name))
		return -EINVAL;

	/* Copy the filename and strip the trailing newline character */
	strscpy(fw_name, buf, count);
	strim(fw_name);

	dev_info(dev, "Loading FPGA bitstream file: %s ...\n", fw_name);

	/* Allocate image info structure required by modern FPGA Manager API */
	info = fpga_image_info_alloc(dev);
	if (!info)
		return -ENOMEM;

	info->firmware_name = fw_name;

	/*
	 * In modern kernels (6.x+), fpga_mgr_load uses fpga_priv.mgr pointer.
	 * If sysconfig_probe registers it, we find the registered manager.
	 */
	struct fpga_manager *mgr = __fpga_mgr_get(dev);
	if (IS_ERR_OR_NULL(mgr)) {
		dev_err(dev, "Could not find registered FPGA Manager instance\n");
		fpga_image_info_free(info);
		return -ENODEV;
	}

	/* Trigger the generic architecture-agnostic load sequence */
	ret = fpga_mgr_load(mgr, info);
	
	fpga_image_info_free(info);

	if (ret) {
		dev_err(dev, "FPGA programming failed with error code: %d\n", ret);
		return ret;
	}

	dev_info(dev, "FPGA successfully programmed!\n");
	return count;
}

/* Define the custom sysfs attribute named "load_fpga" with write-only permissions */
static DEVICE_ATTR_WO(load_fpga);