// SPDX-License-Identifier: GPL-2.0
/*
 * FPGA Manager Core
 *
 *  Copyright (C) 2013-2015 Altera Corporation
 *  Copyright (C) 2017 Intel Corporation
 *
 * With code from the mailing list:
 * Copyright (C) 2013 Xilinx, Inc.
 */
#include <linux/firmware.h>
#include <linux/fpga/fpga-mgr.h>
#include <linux/idr.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/mutex.h>
#include <linux/slab.h>
#include <linux/scatterlist.h>
#include <linux/highmem.h>

static DEFINE_IDA(fpga_mgr_ida);
static struct class *fpga_mgr_class;

struct fpga_mgr_devres {
	struct fpga_manager *mgr;
};

static inline void fpga_mgr_fpga_remove(struct fpga_manager *mgr)
{
	if (mgr->mops->fpga_remove)
		mgr->mops->fpga_remove(mgr);
}

static inline enum fpga_mgr_states fpga_mgr_state(struct fpga_manager *mgr)
{
	if (mgr->mops->state)
		return  mgr->mops->state(mgr);
	return FPGA_MGR_STATE_UNKNOWN;
}

static inline u64 fpga_mgr_status(struct fpga_manager *mgr)
{
	if (mgr->mops->status)
		return mgr->mops->status(mgr);
	return 0;
}

static inline int fpga_mgr_write(struct fpga_manager *mgr, const char *buf, size_t count)
{
	if (mgr->mops->write)
		return  mgr->mops->write(mgr, buf, count);
	return -EOPNOTSUPP;
}

/*
 * After all the FPGA image has been written, do the device specific steps to
 * finish and set the FPGA into operating mode.
 */
static inline int fpga_mgr_write_complete(struct fpga_manager *mgr,
					  struct fpga_image_info *info)
{
	int ret = 0;

	mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE;
	if (mgr->mops->write_complete)
		ret = mgr->mops->write_complete(mgr, info);
	if (ret) {
		dev_err(&mgr->dev, "Error after writing image data to FPGA\n");
		mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE_ERR;
		return ret;
	}
	mgr->state = FPGA_MGR_STATE_OPERATING;

	return 0;
}

static inline int fpga_mgr_parse_header(struct fpga_manager *mgr,
					struct fpga_image_info *info,
					const char *buf, size_t count)
{
	if (mgr->mops->parse_header)
		return mgr->mops->parse_header(mgr, info, buf, count);
	return 0;
}

static inline int fpga_mgr_write_init(struct fpga_manager *mgr,
				      struct fpga_image_info *info,
				      const char *buf, size_t count)
{
	if (mgr->mops->write_init)
		return  mgr->mops->write_init(mgr, info, buf, count);
	return 0;
}

static inline int fpga_mgr_write_sg(struct fpga_manager *mgr,
				    struct sg_table *sgt)
{
	if (mgr->mops->write_sg)
		return  mgr->mops->write_sg(mgr, sgt);
	return -EOPNOTSUPP;
}

/**
 * fpga_image_info_alloc - Allocate an FPGA image info struct
 * @dev: owning device
 *
 * Return: struct fpga_image_info or NULL
 */
struct fpga_image_info *fpga_image_info_alloc(struct device *dev)
{
	struct fpga_image_info *info;

	get_device(dev);

	info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);
	if (!info) {
		put_device(dev);
		return NULL;
	}

	info->dev = dev;

	return info;
}
EXPORT_SYMBOL_GPL(fpga_image_info_alloc);

/**
 * fpga_image_info_free - Free an FPGA image info struct
 * @info: FPGA image info struct to free
 */
void fpga_image_info_free(struct fpga_image_info *info)
{
	struct device *dev;

	if (!info)
		return;

	dev = info->dev;
	if (info->firmware_name)
		devm_kfree(dev, info->firmware_name);

	devm_kfree(dev, info);
	put_device(dev);
}
EXPORT_SYMBOL_GPL(fpga_image_info_free);

/*
 * Call the low level driver's parse_header function with entire FPGA image
 * buffer on the input. This will set info->header_size and info->data_size.
 */
static int fpga_mgr_parse_header_mapped(struct fpga_manager *mgr,
					struct fpga_image_info *info,
					const char *buf, size_t count)
{
	int ret;

	mgr->state = FPGA_MGR_STATE_PARSE_HEADER;
	ret = fpga_mgr_parse_header(mgr, info, buf, count);

	if (info->header_size + info->data_size > count) {
		dev_err(&mgr->dev, "Bitstream data outruns FPGA image\n");
		ret = -EINVAL;
	}

	if (ret) {
		dev_err(&mgr->dev, "Error while parsing FPGA image header\n");
		mgr->state = FPGA_MGR_STATE_PARSE_HEADER_ERR;
	}

	return ret;
}

/*
 * Call the low level driver's parse_header function with first fragment of
 * scattered FPGA image on the input. If header fits first fragment,
 * parse_header will set info->header_size and info->data_size. If it is not,
 * parse_header will set desired size to info->header_size and -EAGAIN will be
 * returned.
 */
static int fpga_mgr_parse_header_sg_first(struct fpga_manager *mgr,
					  struct fpga_image_info *info,
					  struct sg_table *sgt)
{
	struct sg_mapping_iter miter;
	int ret;

	mgr->state = FPGA_MGR_STATE_PARSE_HEADER;

	sg_miter_start(&miter, sgt->sgl, sgt->nents, SG_MITER_FROM_SG);
	if (sg_miter_next(&miter) &&
	    miter.length >= info->header_size)
		ret = fpga_mgr_parse_header(mgr, info, miter.addr, miter.length);
	else
		ret = -EAGAIN;
	sg_miter_stop(&miter);

	if (ret && ret != -EAGAIN) {
		dev_err(&mgr->dev, "Error while parsing FPGA image header\n");
		mgr->state = FPGA_MGR_STATE_PARSE_HEADER_ERR;
	}

	return ret;
}

/*
 * Copy scattered FPGA image fragments to temporary buffer and call the
 * low level driver's parse_header function. This should be called after
 * fpga_mgr_parse_header_sg_first() returned -EAGAIN. In case of success,
 * pointer to the newly allocated image header copy will be returned and
 * its size will be set into *ret_size. Returned buffer needs to be freed.
 */
static void *fpga_mgr_parse_header_sg(struct fpga_manager *mgr,
				      struct fpga_image_info *info,
				      struct sg_table *sgt, size_t *ret_size)
{
	size_t len, new_header_size, header_size = 0;
	char *new_buf, *buf = NULL;
	int ret;

	do {
		new_header_size = info->header_size;
		if (new_header_size <= header_size) {
			dev_err(&mgr->dev, "Requested invalid header size\n");
			ret = -EFAULT;
			break;
		}

		new_buf = krealloc(buf, new_header_size, GFP_KERNEL);
		if (!new_buf) {
			ret = -ENOMEM;
			break;
		}

		buf = new_buf;

		len = sg_pcopy_to_buffer(sgt->sgl, sgt->nents,
					 buf + header_size,
					 new_header_size - header_size,
					 header_size);
		if (len != new_header_size - header_size) {
			ret = -EFAULT;
			break;
		}

		header_size = new_header_size;
		ret = fpga_mgr_parse_header(mgr, info, buf, header_size);
	} while (ret == -EAGAIN);

	if (ret) {
		dev_err(&mgr->dev, "Error while parsing FPGA image header\n");
		mgr->state = FPGA_MGR_STATE_PARSE_HEADER_ERR;
		kfree(buf);
		buf = ERR_PTR(ret);
	}

	*ret_size = header_size;

	return buf;
}

/*
 * Call the low level driver's write_init function. This will do the
 * device-specific things to get the FPGA into the state where it is ready to
 * receive an FPGA image. The low level driver gets to see at least first
 * info->header_size bytes in the buffer. If info->header_size is 0,
 * write_init will not get any bytes of image buffer.
 */
static int fpga_mgr_write_init_buf(struct fpga_manager *mgr,
				   struct fpga_image_info *info,
				   const char *buf, size_t count)
{
	size_t header_size = info->header_size;
	int ret;

	mgr->state = FPGA_MGR_STATE_WRITE_INIT;

	if (header_size > count)
		ret = -EINVAL;
	else if (!header_size)
		ret = fpga_mgr_write_init(mgr, info, NULL, 0);
	else
		ret = fpga_mgr_write_init(mgr, info, buf, count);

	if (ret) {
		dev_err(&mgr->dev, "Error preparing FPGA for writing\n");
		mgr->state = FPGA_MGR_STATE_WRITE_INIT_ERR;
		return ret;
	}

	return 0;
}

static int fpga_mgr_prepare_sg(struct fpga_manager *mgr,
			       struct fpga_image_info *info,
			       struct sg_table *sgt)
{
	struct sg_mapping_iter miter;
	size_t len;
	char *buf;
	int ret;

	/* Short path. Low level driver don't care about image header. */
	if (!mgr->mops->initial_header_size && !mgr->mops->parse_header)
		return fpga_mgr_write_init_buf(mgr, info, NULL, 0);

	/*
	 * First try to use miter to map the first fragment to access the
	 * header, this is the typical path.
	 */
	ret = fpga_mgr_parse_header_sg_first(mgr, info, sgt);
	/* If 0, header fits first fragment, call write_init on it */
	if (!ret) {
		sg_miter_start(&miter, sgt->sgl, sgt->nents, SG_MITER_FROM_SG);
		if (sg_miter_next(&miter)) {
			ret = fpga_mgr_write_init_buf(mgr, info, miter.addr,
						      miter.length);
			sg_miter_stop(&miter);
			return ret;
		}
		sg_miter_stop(&miter);
	/*
	 * If -EAGAIN, more sg buffer is needed,
	 * otherwise an error has occurred.
	 */
	} else if (ret != -EAGAIN) {
		return ret;
	}

	/*
	 * Copy the fragments into temporary memory.
	 * Copying is done inside fpga_mgr_parse_header_sg().
	 */
	buf = fpga_mgr_parse_header_sg(mgr, info, sgt, &len);
	if (IS_ERR(buf))
		return PTR_ERR(buf);

	ret = fpga_mgr_write_init_buf(mgr, info, buf, len);

	kfree(buf);

	return ret;
}

/**
 * fpga_mgr_buf_load_sg - load fpga from image in buffer from a scatter list
 * @mgr:	fpga manager
 * @info:	fpga image specific information
 * @sgt:	scatterlist table
 *
 * Step the low level fpga manager through the device-specific steps of getting
 * an FPGA ready to be configured, writing the image to it, then doing whatever
 * post-configuration steps necessary.  This code assumes the caller got the
 * mgr pointer from of_fpga_mgr_get() or fpga_mgr_get() and checked that it is
 * not an error code.
 *
 * This is the preferred entry point for FPGA programming, it does not require
 * any contiguous kernel memory.
 *
 * Return: 0 on success, negative error code otherwise.
 */
static int fpga_mgr_buf_load_sg(struct fpga_manager *mgr,
				struct fpga_image_info *info,
				struct sg_table *sgt)
{
	int ret;

	ret = fpga_mgr_prepare_sg(mgr, info, sgt);
	if (ret)
		return ret;

	/* Write the FPGA image to the FPGA. */
	mgr->state = FPGA_MGR_STATE_WRITE;
	if (mgr->mops->write_sg) {
		ret = fpga_mgr_write_sg(mgr, sgt);
	} else {
		size_t length, count = 0, data_size = info->data_size;
		struct sg_mapping_iter miter;

		sg_miter_start(&miter, sgt->sgl, sgt->nents, SG_MITER_FROM_SG);

		if (mgr->mops->skip_header &&
		    !sg_miter_skip(&miter, info->header_size)) {
			ret = -EINVAL;
			goto out;
		}

		while (sg_miter_next(&miter)) {
			if (data_size)
				length = min(miter.length, data_size - count);
			else
				length = miter.length;

			ret = fpga_mgr_write(mgr, miter.addr, length);
			if (ret)
				break;

			count += length;
			if (data_size && count >= data_size)
				break;
		}
		sg_miter_stop(&miter);
	}

out:
	if (ret) {
		dev_err(&mgr->dev, "Error while writing image data to FPGA\n");
		mgr->state = FPGA_MGR_STATE_WRITE_ERR;
		return ret;
	}

	return fpga_mgr_write_complete(mgr, info);
}

static int fpga_mgr_buf_load_mapped(struct fpga_manager *mgr,
				    struct fpga_image_info *info,
				    const char *buf, size_t count)
{
	int ret;

	ret = fpga_mgr_parse_header_mapped(mgr, info, buf, count);
	if (ret)
		return ret;

	ret = fpga_mgr_write_init_buf(mgr, info, buf, count);
	if (ret)
		return ret;

	if (mgr->mops->skip_header) {
		buf += info->header_size;
		count -= info->header_size;
	}

	if (info->data_size)
		count = info->data_size;

	/*
	 * Write the FPGA image to the FPGA.
	 */
	mgr->state = FPGA_MGR_STATE_WRITE;
	ret = fpga_mgr_write(mgr, buf, count);
	if (ret) {
		dev_err(&mgr->dev, "Error while writing image data to FPGA\n");
		mgr->state = FPGA_MGR_STATE_WRITE_ERR;
		return ret;
	}

	return fpga_mgr_write_complete(mgr, info);
}

/**
 * fpga_mgr_buf_load - load fpga from image in buffer
 * @mgr:	fpga manager
 * @info:	fpga image info
 * @buf:	buffer contain fpga image
 * @count:	byte count of buf
 *
 * Step the low level fpga manager through the device-specific steps of getting
 * an FPGA ready to be configured, writing the image to it, then doing whatever
 * post-configuration steps necessary.  This code assumes the caller got the
 * mgr pointer from of_fpga_mgr_get() and checked that it is not an error code.
 *
 * Return: 0 on success, negative error code otherwise.
 */
static int fpga_mgr_buf_load(struct fpga_manager *mgr,
			     struct fpga_image_info *info,
			     const char *buf, size_t count)
{
	struct page **pages;
	struct sg_table sgt;
	const void *p;
	int nr_pages;
	int index;
	int rc;

	/*
	 * This is just a fast path if the caller has already created a
	 * contiguous kernel buffer and the driver doesn't require SG, non-SG
	 * drivers will still work on the slow path.
	 */
	if (mgr->mops->write)
		return fpga_mgr_buf_load_mapped(mgr, info, buf, count);

	/*
	 * Convert the linear kernel pointer into a sg_table of pages for use
	 * by the driver.
	 */
	nr_pages = DIV_ROUND_UP((unsigned long)buf + count, PAGE_SIZE) -
		   (unsigned long)buf / PAGE_SIZE;
	pages = kmalloc_array(nr_pages, sizeof(struct page *), GFP_KERNEL);
	if (!pages)
		return -ENOMEM;

	p = buf - offset_in_page(buf);
	for (index = 0; index < nr_pages; index++) {
		if (is_vmalloc_addr(p))
			pages[index] = vmalloc_to_page(p);
		else
			pages[index] = kmap_to_page((void *)p);
		if (!pages[index]) {
			kfree(pages);
			return -EFAULT;
		}
		p += PAGE_SIZE;
	}

	/*
	 * The temporary pages list is used to code share the merging algorithm
	 * in sg_alloc_table_from_pages
	 */
	rc = sg_alloc_table_from_pages(&sgt, pages, index, offset_in_page(buf),
				       count, GFP_KERNEL);
	kfree(pages);
	if (rc)
		return rc;

	rc = fpga_mgr_buf_load_sg(mgr, info, &sgt);
	sg_free_table(&sgt);

	return rc;
}

/**
 * fpga_mgr_firmware_load - request firmware and load to fpga
 * @mgr:	fpga manager
 * @info:	fpga image specific information
 * @image_name:	name of image file on the firmware search path
 *
 * Request an FPGA image using the firmware class, then write out to the FPGA.
 * Update the state before each step to provide info on what step failed if
 * there is a failure.  This code assumes the caller got the mgr pointer
 * from of_fpga_mgr_get() or fpga_mgr_get() and checked that it is not an error
 * code.
 *
 * Return: 0 on success, negative error code otherwise.
 */
static int fpga_mgr_firmware_load(struct fpga_manager *mgr,
				  struct fpga_image_info *info,
				  const char *image_name)
{
	struct device *dev = &mgr->dev;
	const struct firmware *fw;
	int ret;

	dev_info(dev, "writing %s to %s\n", image_name, mgr->name);

	mgr->state = FPGA_MGR_STATE_FIRMWARE_REQ;

	ret = request_firmware(&fw, image_name, dev);
	if (ret) {
		mgr->state = FPGA_MGR_STATE_FIRMWARE_REQ_ERR;
		dev_err(dev, "Error requesting firmware %s\n", image_name);
		return ret;
	}

	ret = fpga_mgr_buf_load(mgr, info, fw->data, fw->size);

	release_firmware(fw);

	return ret;
}

/**
 * fpga_mgr_load - load FPGA from scatter/gather table, buffer, or firmware
 * @mgr:	fpga manager
 * @info:	fpga image information.
 *
 * Load the FPGA from an image which is indicated in @info.  If successful, the
 * FPGA ends up in operating mode.
 *
 * Return: 0 on success, negative error code otherwise.
 */
int fpga_mgr_load(struct fpga_manager *mgr, struct fpga_image_info *info)
{
	info->header_size = mgr->mops->initial_header_size;

	if (info->sgt)
		return fpga_mgr_buf_load_sg(mgr, info, info->sgt);
	if (info->buf && info->count)
		return fpga_mgr_buf_load(mgr, info, info->buf, info->count);
	if (info->firmware_name)
		return fpga_mgr_firmware_load(mgr, info, info->firmware_name);
	return -EINVAL;
}
EXPORT_SYMBOL_GPL(fpga_mgr_load);

static const char * const state_str[] = {
	[FPGA_MGR_STATE_UNKNOWN] =		"unknown",
	[FPGA_MGR_STATE_POWER_OFF] =		"power off",
	[FPGA_MGR_STATE_POWER_UP] =		"power up",
	[FPGA_MGR_STATE_RESET] =		"reset",

	/* requesting FPGA image from firmware */
	[FPGA_MGR_STATE_FIRMWARE_REQ] =		"firmware request",
	[FPGA_MGR_STATE_FIRMWARE_REQ_ERR] =	"firmware request error",

	/* Parse FPGA image header */
	[FPGA_MGR_STATE_PARSE_HEADER] =		"parse header",
	[FPGA_MGR_STATE_PARSE_HEADER_ERR] =	"parse header error",

	/* Preparing FPGA to receive image */
	[FPGA_MGR_STATE_WRITE_INIT] =		"write init",
	[FPGA_MGR_STATE_WRITE_INIT_ERR] =	"write init error",

	/* Writing image to FPGA */
	[FPGA_MGR_STATE_WRITE] =		"write",
	[FPGA_MGR_STATE_WRITE_ERR] =		"write error",

	/* Finishing configuration after image has been written */
	[FPGA_MGR_STATE_WRITE_COMPLETE] =	"write complete",
	[FPGA_MGR_STATE_WRITE_COMPLETE_ERR] =	"write complete error",

	/* FPGA reports to be in normal operating mode */
	[FPGA_MGR_STATE_OPERATING] =		"operating",
};

static ssize_t name_show(struct device *dev,
			 struct device_attribute *attr, char *buf)
{
	struct fpga_manager *mgr = to_fpga_manager(dev);

	return sprintf(buf, "%s\n", mgr->name);
}

static ssize_t state_show(struct device *dev,
			  struct device_attribute *attr, char *buf)
{
	struct fpga_manager *mgr = to_fpga_manager(dev);

	return sprintf(buf, "%s\n", state_str[mgr->state]);
}

static ssize_t status_show(struct device *dev,
			   struct device_attribute *attr, char *buf)
{
	struct fpga_manager *mgr = to_fpga_manager(dev);
	u64 status;
	int len = 0;

	status = fpga_mgr_status(mgr);

	if (status & FPGA_MGR_STATUS_OPERATION_ERR)
		len += sprintf(buf + len, "reconfig operation error\n");
	if (status & FPGA_MGR_STATUS_CRC_ERR)
		len += sprintf(buf + len, "reconfig CRC error\n");
	if (status & FPGA_MGR_STATUS_INCOMPATIBLE_IMAGE_ERR)
		len += sprintf(buf + len, "reconfig incompatible image\n");
	if (status & FPGA_MGR_STATUS_IP_PROTOCOL_ERR)
		len += sprintf(buf + len, "reconfig IP protocol error\n");
	if (status & FPGA_MGR_STATUS_FIFO_OVERFLOW_ERR)
		len += sprintf(buf + len, "reconfig fifo overflow error\n");

	return len;
}

static DEVICE_ATTR_RO(name);
static DEVICE_ATTR_RO(state);
static DEVICE_ATTR_RO(status);

static struct attribute *fpga_mgr_attrs[] = {
	&dev_attr_name.attr,
	&dev_attr_state.attr,
	&dev_attr_status.attr,
	NULL,
};
ATTRIBUTE_GROUPS(fpga_mgr);

static struct fpga_manager *__fpga_mgr_get(struct device *mgr_dev)
{
	struct fpga_manager *mgr;

	mgr = to_fpga_manager(mgr_dev);

	if (!try_module_get(mgr->mops_owner))
		mgr = ERR_PTR(-ENODEV);

	return mgr;
}

static int fpga_mgr_dev_match(struct device *dev, const void *data)
{
	return dev->parent == data;
}

/**
 * fpga_mgr_get - Given a device, get a reference to an fpga mgr.
 * @dev:	parent device that fpga mgr was registered with
 *
 * Return: fpga manager struct or IS_ERR() condition containing error code.
 */
struct fpga_manager *fpga_mgr_get(struct device *dev)
{
	struct fpga_manager *mgr;
	struct device *mgr_dev;

	mgr_dev = class_find_device(fpga_mgr_class, NULL, dev, fpga_mgr_dev_match);
	if (!mgr_dev)
		return ERR_PTR(-ENODEV);

	mgr = __fpga_mgr_get(mgr_dev);
	if (IS_ERR(mgr))
		put_device(mgr_dev);

	return mgr;
}
EXPORT_SYMBOL_GPL(fpga_mgr_get);

/**
 * of_fpga_mgr_get - Given a device node, get a reference to an fpga mgr.
 *
 * @node:	device node
 *
 * Return: fpga manager struct or IS_ERR() condition containing error code.
 */
struct fpga_manager *of_fpga_mgr_get(struct device_node *node)
{
	struct fpga_manager *mgr;
	struct device *mgr_dev;

	mgr_dev = class_find_device_by_of_node(fpga_mgr_class, node);
	if (!mgr_dev)
		return ERR_PTR(-ENODEV);

	mgr = __fpga_mgr_get(mgr_dev);
	if (IS_ERR(mgr))
		put_device(mgr_dev);

	return mgr;
}
EXPORT_SYMBOL_GPL(of_fpga_mgr_get);

/**
 * fpga_mgr_put - release a reference to an fpga manager
 * @mgr:	fpga manager structure
 */
void fpga_mgr_put(struct fpga_manager *mgr)
{
	module_put(mgr->mops_owner);
	put_device(&mgr->dev);
}
EXPORT_SYMBOL_GPL(fpga_mgr_put);

/**
 * fpga_mgr_lock - Lock FPGA manager for exclusive use
 * @mgr:	fpga manager
 *
 * Given a pointer to FPGA Manager (from fpga_mgr_get() or
 * of_fpga_mgr_put()) attempt to get the mutex. The user should call
 * fpga_mgr_lock() and verify that it returns 0 before attempting to
 * program the FPGA.  Likewise, the user should call fpga_mgr_unlock
 * when done programming the FPGA.
 *
 * Return: 0 for success or -EBUSY
 */
int fpga_mgr_lock(struct fpga_manager *mgr)
{
	if (!mutex_trylock(&mgr->ref_mutex)) {
		dev_err(&mgr->dev, "FPGA manager is in use.\n");
		return -EBUSY;
	}

	return 0;
}
EXPORT_SYMBOL_GPL(fpga_mgr_lock);

/**
 * fpga_mgr_unlock - Unlock FPGA manager after done programming
 * @mgr:	fpga manager
 */
void fpga_mgr_unlock(struct fpga_manager *mgr)
{
	mutex_unlock(&mgr->ref_mutex);
}
EXPORT_SYMBOL_GPL(fpga_mgr_unlock);

/**
 * __fpga_mgr_register_full - create and register an FPGA Manager device
 * @parent:	fpga manager device from pdev
 * @info:	parameters for fpga manager
 * @owner:	owner module containing the ops
 *
 * The caller of this function is responsible for calling fpga_mgr_unregister().
 * Using devm_fpga_mgr_register_full() instead is recommended.
 *
 * Return: pointer to struct fpga_manager pointer or ERR_PTR()
 */
struct fpga_manager *
__fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info,
			 struct module *owner)
{
	const struct fpga_manager_ops *mops = info->mops;
	struct fpga_manager *mgr;
	int id, ret;

	if (!mops) {
		dev_err(parent, "Attempt to register without fpga_manager_ops\n");
		return ERR_PTR(-EINVAL);
	}

	if (!info->name || !strlen(info->name)) {
		dev_err(parent, "Attempt to register with no name!\n");
		return ERR_PTR(-EINVAL);
	}

	mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);
	if (!mgr)
		return ERR_PTR(-ENOMEM);

	id = ida_alloc(&fpga_mgr_ida, GFP_KERNEL);
	if (id < 0) {
		ret = id;
		goto error_kfree;
	}

	mutex_init(&mgr->ref_mutex);

	mgr->mops_owner = owner;

	mgr->name = info->name;
	mgr->mops = info->mops;
	mgr->priv = info->priv;
	mgr->compat_id = info->compat_id;

	mgr->dev.class = fpga_mgr_class;
	mgr->dev.groups = mops->groups;
	mgr->dev.parent = parent;
	mgr->dev.of_node = parent->of_node;
	mgr->dev.id = id;

	ret = dev_set_name(&mgr->dev, "fpga%d", id);
	if (ret)
		goto error_device;

	/*
	 * Initialize framework state by requesting low level driver read state
	 * from device.  FPGA may be in reset mode or may have been programmed
	 * by bootloader or EEPROM.
	 */
	mgr->state = fpga_mgr_state(mgr);

	ret = device_register(&mgr->dev);
	if (ret) {
		put_device(&mgr->dev);
		return ERR_PTR(ret);
	}

	return mgr;

error_device:
	ida_free(&fpga_mgr_ida, id);
error_kfree:
	kfree(mgr);

	return ERR_PTR(ret);
}
EXPORT_SYMBOL_GPL(__fpga_mgr_register_full);

/**
 * __fpga_mgr_register - create and register an FPGA Manager device
 * @parent:	fpga manager device from pdev
 * @name:	fpga manager name
 * @mops:	pointer to structure of fpga manager ops
 * @priv:	fpga manager private data
 * @owner:	owner module containing the ops
 *
 * The caller of this function is responsible for calling fpga_mgr_unregister().
 * Using devm_fpga_mgr_register() instead is recommended. This simple
 * version of the register function should be sufficient for most users. The
 * fpga_mgr_register_full() function is available for users that need to pass
 * additional, optional parameters.
 *
 * Return: pointer to struct fpga_manager pointer or ERR_PTR()
 */
struct fpga_manager *
__fpga_mgr_register(struct device *parent, const char *name,
		    const struct fpga_manager_ops *mops, void *priv, struct module *owner)
{
	struct fpga_manager_info info = { 0 };

	info.name = name;
	info.mops = mops;
	info.priv = priv;

	return __fpga_mgr_register_full(parent, &info, owner);
}
EXPORT_SYMBOL_GPL(__fpga_mgr_register);

/**
 * fpga_mgr_unregister - unregister an FPGA manager
 * @mgr: fpga manager struct
 *
 * This function is intended for use in an FPGA manager driver's remove function.
 */
void fpga_mgr_unregister(struct fpga_manager *mgr)
{
	dev_info(&mgr->dev, "%s %s\n", __func__, mgr->name);

	/*
	 * If the low level driver provides a method for putting fpga into
	 * a desired state upon unregister, do it.
	 */
	fpga_mgr_fpga_remove(mgr);

	device_unregister(&mgr->dev);
}
EXPORT_SYMBOL_GPL(fpga_mgr_unregister);

static void devm_fpga_mgr_unregister(struct device *dev, void *res)
{
	struct fpga_mgr_devres *dr = res;

	fpga_mgr_unregister(dr->mgr);
}

/**
 * __devm_fpga_mgr_register_full - resource managed variant of fpga_mgr_register()
 * @parent:	fpga manager device from pdev
 * @info:	parameters for fpga manager
 * @owner:	owner module containing the ops
 *
 * Return:  fpga manager pointer on success, negative error code otherwise.
 *
 * This is the devres variant of fpga_mgr_register_full() for which the unregister
 * function will be called automatically when the managing device is detached.
 */
struct fpga_manager *
__devm_fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info,
			      struct module *owner)
{
	struct fpga_mgr_devres *dr;
	struct fpga_manager *mgr;

	dr = devres_alloc(devm_fpga_mgr_unregister, sizeof(*dr), GFP_KERNEL);
	if (!dr)
		return ERR_PTR(-ENOMEM);

	mgr = __fpga_mgr_register_full(parent, info, owner);
	if (IS_ERR(mgr)) {
		devres_free(dr);
		return mgr;
	}

	dr->mgr = mgr;
	devres_add(parent, dr);

	return mgr;
}
EXPORT_SYMBOL_GPL(__devm_fpga_mgr_register_full);

/**
 * __devm_fpga_mgr_register - resource managed variant of fpga_mgr_register()
 * @parent:	fpga manager device from pdev
 * @name:	fpga manager name
 * @mops:	pointer to structure of fpga manager ops
 * @priv:	fpga manager private data
 * @owner:	owner module containing the ops
 *
 * Return:  fpga manager pointer on success, negative error code otherwise.
 *
 * This is the devres variant of fpga_mgr_register() for which the
 * unregister function will be called automatically when the managing
 * device is detached.
 */
struct fpga_manager *
__devm_fpga_mgr_register(struct device *parent, const char *name,
			 const struct fpga_manager_ops *mops, void *priv,
			 struct module *owner)
{
	struct fpga_manager_info info = { 0 };

	info.name = name;
	info.mops = mops;
	info.priv = priv;

	return __devm_fpga_mgr_register_full(parent, &info, owner);
}
EXPORT_SYMBOL_GPL(__devm_fpga_mgr_register);

static void fpga_mgr_dev_release(struct device *dev)
{
	struct fpga_manager *mgr = to_fpga_manager(dev);

	ida_free(&fpga_mgr_ida, mgr->dev.id);
	kfree(mgr);
}

static int __init fpga_mgr_class_init(void)
{
	pr_info("FPGA manager framework\n");

	fpga_mgr_class = class_create(THIS_MODULE, "fpga_manager");
	if (IS_ERR(fpga_mgr_class))
		return PTR_ERR(fpga_mgr_class);

	fpga_mgr_class->dev_groups = fpga_mgr_groups;
	fpga_mgr_class->dev_release = fpga_mgr_dev_release;

	return 0;
}

static void __exit fpga_mgr_class_exit(void)
{
	class_destroy(fpga_mgr_class);
	ida_destroy(&fpga_mgr_ida);
}

MODULE_AUTHOR("Alan Tull <atull@kernel.org>");
MODULE_DESCRIPTION("FPGA manager framework");
MODULE_LICENSE("GPL v2");

subsys_initcall(fpga_mgr_class_init);
module_exit(fpga_mgr_class_exit);
