brintos

brintos / linux-shallow public Read only

0
0
Text · 25.7 KiB · 0f4035b Raw
1011 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * FPGA Manager Core4 *5 *  Copyright (C) 2013-2015 Altera Corporation6 *  Copyright (C) 2017 Intel Corporation7 *8 * With code from the mailing list:9 * Copyright (C) 2013 Xilinx, Inc.10 */11#include <linux/firmware.h>12#include <linux/fpga/fpga-mgr.h>13#include <linux/idr.h>14#include <linux/module.h>15#include <linux/of.h>16#include <linux/mutex.h>17#include <linux/slab.h>18#include <linux/scatterlist.h>19#include <linux/highmem.h>20 21static DEFINE_IDA(fpga_mgr_ida);22static const struct class fpga_mgr_class;23 24struct fpga_mgr_devres {25	struct fpga_manager *mgr;26};27 28static inline void fpga_mgr_fpga_remove(struct fpga_manager *mgr)29{30	if (mgr->mops->fpga_remove)31		mgr->mops->fpga_remove(mgr);32}33 34static inline enum fpga_mgr_states fpga_mgr_state(struct fpga_manager *mgr)35{36	if (mgr->mops->state)37		return  mgr->mops->state(mgr);38	return FPGA_MGR_STATE_UNKNOWN;39}40 41static inline u64 fpga_mgr_status(struct fpga_manager *mgr)42{43	if (mgr->mops->status)44		return mgr->mops->status(mgr);45	return 0;46}47 48static inline int fpga_mgr_write(struct fpga_manager *mgr, const char *buf, size_t count)49{50	if (mgr->mops->write)51		return  mgr->mops->write(mgr, buf, count);52	return -EOPNOTSUPP;53}54 55/*56 * After all the FPGA image has been written, do the device specific steps to57 * finish and set the FPGA into operating mode.58 */59static inline int fpga_mgr_write_complete(struct fpga_manager *mgr,60					  struct fpga_image_info *info)61{62	int ret = 0;63 64	mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE;65	if (mgr->mops->write_complete)66		ret = mgr->mops->write_complete(mgr, info);67	if (ret) {68		dev_err(&mgr->dev, "Error after writing image data to FPGA\n");69		mgr->state = FPGA_MGR_STATE_WRITE_COMPLETE_ERR;70		return ret;71	}72	mgr->state = FPGA_MGR_STATE_OPERATING;73 74	return 0;75}76 77static inline int fpga_mgr_parse_header(struct fpga_manager *mgr,78					struct fpga_image_info *info,79					const char *buf, size_t count)80{81	if (mgr->mops->parse_header)82		return mgr->mops->parse_header(mgr, info, buf, count);83	return 0;84}85 86static inline int fpga_mgr_write_init(struct fpga_manager *mgr,87				      struct fpga_image_info *info,88				      const char *buf, size_t count)89{90	if (mgr->mops->write_init)91		return  mgr->mops->write_init(mgr, info, buf, count);92	return 0;93}94 95static inline int fpga_mgr_write_sg(struct fpga_manager *mgr,96				    struct sg_table *sgt)97{98	if (mgr->mops->write_sg)99		return  mgr->mops->write_sg(mgr, sgt);100	return -EOPNOTSUPP;101}102 103/**104 * fpga_image_info_alloc - Allocate an FPGA image info struct105 * @dev: owning device106 *107 * Return: struct fpga_image_info or NULL108 */109struct fpga_image_info *fpga_image_info_alloc(struct device *dev)110{111	struct fpga_image_info *info;112 113	get_device(dev);114 115	info = devm_kzalloc(dev, sizeof(*info), GFP_KERNEL);116	if (!info) {117		put_device(dev);118		return NULL;119	}120 121	info->dev = dev;122 123	return info;124}125EXPORT_SYMBOL_GPL(fpga_image_info_alloc);126 127/**128 * fpga_image_info_free - Free an FPGA image info struct129 * @info: FPGA image info struct to free130 */131void fpga_image_info_free(struct fpga_image_info *info)132{133	struct device *dev;134 135	if (!info)136		return;137 138	dev = info->dev;139	if (info->firmware_name)140		devm_kfree(dev, info->firmware_name);141 142	devm_kfree(dev, info);143	put_device(dev);144}145EXPORT_SYMBOL_GPL(fpga_image_info_free);146 147/*148 * Call the low level driver's parse_header function with entire FPGA image149 * buffer on the input. This will set info->header_size and info->data_size.150 */151static int fpga_mgr_parse_header_mapped(struct fpga_manager *mgr,152					struct fpga_image_info *info,153					const char *buf, size_t count)154{155	int ret;156 157	mgr->state = FPGA_MGR_STATE_PARSE_HEADER;158	ret = fpga_mgr_parse_header(mgr, info, buf, count);159 160	if (info->header_size + info->data_size > count) {161		dev_err(&mgr->dev, "Bitstream data outruns FPGA image\n");162		ret = -EINVAL;163	}164 165	if (ret) {166		dev_err(&mgr->dev, "Error while parsing FPGA image header\n");167		mgr->state = FPGA_MGR_STATE_PARSE_HEADER_ERR;168	}169 170	return ret;171}172 173/*174 * Call the low level driver's parse_header function with first fragment of175 * scattered FPGA image on the input. If header fits first fragment,176 * parse_header will set info->header_size and info->data_size. If it is not,177 * parse_header will set desired size to info->header_size and -EAGAIN will be178 * returned.179 */180static int fpga_mgr_parse_header_sg_first(struct fpga_manager *mgr,181					  struct fpga_image_info *info,182					  struct sg_table *sgt)183{184	struct sg_mapping_iter miter;185	int ret;186 187	mgr->state = FPGA_MGR_STATE_PARSE_HEADER;188 189	sg_miter_start(&miter, sgt->sgl, sgt->nents, SG_MITER_FROM_SG);190	if (sg_miter_next(&miter) &&191	    miter.length >= info->header_size)192		ret = fpga_mgr_parse_header(mgr, info, miter.addr, miter.length);193	else194		ret = -EAGAIN;195	sg_miter_stop(&miter);196 197	if (ret && ret != -EAGAIN) {198		dev_err(&mgr->dev, "Error while parsing FPGA image header\n");199		mgr->state = FPGA_MGR_STATE_PARSE_HEADER_ERR;200	}201 202	return ret;203}204 205/*206 * Copy scattered FPGA image fragments to temporary buffer and call the207 * low level driver's parse_header function. This should be called after208 * fpga_mgr_parse_header_sg_first() returned -EAGAIN. In case of success,209 * pointer to the newly allocated image header copy will be returned and210 * its size will be set into *ret_size. Returned buffer needs to be freed.211 */212static void *fpga_mgr_parse_header_sg(struct fpga_manager *mgr,213				      struct fpga_image_info *info,214				      struct sg_table *sgt, size_t *ret_size)215{216	size_t len, new_header_size, header_size = 0;217	char *new_buf, *buf = NULL;218	int ret;219 220	do {221		new_header_size = info->header_size;222		if (new_header_size <= header_size) {223			dev_err(&mgr->dev, "Requested invalid header size\n");224			ret = -EFAULT;225			break;226		}227 228		new_buf = krealloc(buf, new_header_size, GFP_KERNEL);229		if (!new_buf) {230			ret = -ENOMEM;231			break;232		}233 234		buf = new_buf;235 236		len = sg_pcopy_to_buffer(sgt->sgl, sgt->nents,237					 buf + header_size,238					 new_header_size - header_size,239					 header_size);240		if (len != new_header_size - header_size) {241			ret = -EFAULT;242			break;243		}244 245		header_size = new_header_size;246		ret = fpga_mgr_parse_header(mgr, info, buf, header_size);247	} while (ret == -EAGAIN);248 249	if (ret) {250		dev_err(&mgr->dev, "Error while parsing FPGA image header\n");251		mgr->state = FPGA_MGR_STATE_PARSE_HEADER_ERR;252		kfree(buf);253		buf = ERR_PTR(ret);254	}255 256	*ret_size = header_size;257 258	return buf;259}260 261/*262 * Call the low level driver's write_init function. This will do the263 * device-specific things to get the FPGA into the state where it is ready to264 * receive an FPGA image. The low level driver gets to see at least first265 * info->header_size bytes in the buffer. If info->header_size is 0,266 * write_init will not get any bytes of image buffer.267 */268static int fpga_mgr_write_init_buf(struct fpga_manager *mgr,269				   struct fpga_image_info *info,270				   const char *buf, size_t count)271{272	size_t header_size = info->header_size;273	int ret;274 275	mgr->state = FPGA_MGR_STATE_WRITE_INIT;276 277	if (header_size > count)278		ret = -EINVAL;279	else if (!header_size)280		ret = fpga_mgr_write_init(mgr, info, NULL, 0);281	else282		ret = fpga_mgr_write_init(mgr, info, buf, count);283 284	if (ret) {285		dev_err(&mgr->dev, "Error preparing FPGA for writing\n");286		mgr->state = FPGA_MGR_STATE_WRITE_INIT_ERR;287		return ret;288	}289 290	return 0;291}292 293static int fpga_mgr_prepare_sg(struct fpga_manager *mgr,294			       struct fpga_image_info *info,295			       struct sg_table *sgt)296{297	struct sg_mapping_iter miter;298	size_t len;299	char *buf;300	int ret;301 302	/* Short path. Low level driver don't care about image header. */303	if (!mgr->mops->initial_header_size && !mgr->mops->parse_header)304		return fpga_mgr_write_init_buf(mgr, info, NULL, 0);305 306	/*307	 * First try to use miter to map the first fragment to access the308	 * header, this is the typical path.309	 */310	ret = fpga_mgr_parse_header_sg_first(mgr, info, sgt);311	/* If 0, header fits first fragment, call write_init on it */312	if (!ret) {313		sg_miter_start(&miter, sgt->sgl, sgt->nents, SG_MITER_FROM_SG);314		if (sg_miter_next(&miter)) {315			ret = fpga_mgr_write_init_buf(mgr, info, miter.addr,316						      miter.length);317			sg_miter_stop(&miter);318			return ret;319		}320		sg_miter_stop(&miter);321	/*322	 * If -EAGAIN, more sg buffer is needed,323	 * otherwise an error has occurred.324	 */325	} else if (ret != -EAGAIN) {326		return ret;327	}328 329	/*330	 * Copy the fragments into temporary memory.331	 * Copying is done inside fpga_mgr_parse_header_sg().332	 */333	buf = fpga_mgr_parse_header_sg(mgr, info, sgt, &len);334	if (IS_ERR(buf))335		return PTR_ERR(buf);336 337	ret = fpga_mgr_write_init_buf(mgr, info, buf, len);338 339	kfree(buf);340 341	return ret;342}343 344/**345 * fpga_mgr_buf_load_sg - load fpga from image in buffer from a scatter list346 * @mgr:	fpga manager347 * @info:	fpga image specific information348 * @sgt:	scatterlist table349 *350 * Step the low level fpga manager through the device-specific steps of getting351 * an FPGA ready to be configured, writing the image to it, then doing whatever352 * post-configuration steps necessary.  This code assumes the caller got the353 * mgr pointer from of_fpga_mgr_get() or fpga_mgr_get() and checked that it is354 * not an error code.355 *356 * This is the preferred entry point for FPGA programming, it does not require357 * any contiguous kernel memory.358 *359 * Return: 0 on success, negative error code otherwise.360 */361static int fpga_mgr_buf_load_sg(struct fpga_manager *mgr,362				struct fpga_image_info *info,363				struct sg_table *sgt)364{365	int ret;366 367	ret = fpga_mgr_prepare_sg(mgr, info, sgt);368	if (ret)369		return ret;370 371	/* Write the FPGA image to the FPGA. */372	mgr->state = FPGA_MGR_STATE_WRITE;373	if (mgr->mops->write_sg) {374		ret = fpga_mgr_write_sg(mgr, sgt);375	} else {376		size_t length, count = 0, data_size = info->data_size;377		struct sg_mapping_iter miter;378 379		sg_miter_start(&miter, sgt->sgl, sgt->nents, SG_MITER_FROM_SG);380 381		if (mgr->mops->skip_header &&382		    !sg_miter_skip(&miter, info->header_size)) {383			ret = -EINVAL;384			goto out;385		}386 387		while (sg_miter_next(&miter)) {388			if (data_size)389				length = min(miter.length, data_size - count);390			else391				length = miter.length;392 393			ret = fpga_mgr_write(mgr, miter.addr, length);394			if (ret)395				break;396 397			count += length;398			if (data_size && count >= data_size)399				break;400		}401		sg_miter_stop(&miter);402	}403 404out:405	if (ret) {406		dev_err(&mgr->dev, "Error while writing image data to FPGA\n");407		mgr->state = FPGA_MGR_STATE_WRITE_ERR;408		return ret;409	}410 411	return fpga_mgr_write_complete(mgr, info);412}413 414static int fpga_mgr_buf_load_mapped(struct fpga_manager *mgr,415				    struct fpga_image_info *info,416				    const char *buf, size_t count)417{418	int ret;419 420	ret = fpga_mgr_parse_header_mapped(mgr, info, buf, count);421	if (ret)422		return ret;423 424	ret = fpga_mgr_write_init_buf(mgr, info, buf, count);425	if (ret)426		return ret;427 428	if (mgr->mops->skip_header) {429		buf += info->header_size;430		count -= info->header_size;431	}432 433	if (info->data_size)434		count = info->data_size;435 436	/*437	 * Write the FPGA image to the FPGA.438	 */439	mgr->state = FPGA_MGR_STATE_WRITE;440	ret = fpga_mgr_write(mgr, buf, count);441	if (ret) {442		dev_err(&mgr->dev, "Error while writing image data to FPGA\n");443		mgr->state = FPGA_MGR_STATE_WRITE_ERR;444		return ret;445	}446 447	return fpga_mgr_write_complete(mgr, info);448}449 450/**451 * fpga_mgr_buf_load - load fpga from image in buffer452 * @mgr:	fpga manager453 * @info:	fpga image info454 * @buf:	buffer contain fpga image455 * @count:	byte count of buf456 *457 * Step the low level fpga manager through the device-specific steps of getting458 * an FPGA ready to be configured, writing the image to it, then doing whatever459 * post-configuration steps necessary.  This code assumes the caller got the460 * mgr pointer from of_fpga_mgr_get() and checked that it is not an error code.461 *462 * Return: 0 on success, negative error code otherwise.463 */464static int fpga_mgr_buf_load(struct fpga_manager *mgr,465			     struct fpga_image_info *info,466			     const char *buf, size_t count)467{468	struct page **pages;469	struct sg_table sgt;470	const void *p;471	int nr_pages;472	int index;473	int rc;474 475	/*476	 * This is just a fast path if the caller has already created a477	 * contiguous kernel buffer and the driver doesn't require SG, non-SG478	 * drivers will still work on the slow path.479	 */480	if (mgr->mops->write)481		return fpga_mgr_buf_load_mapped(mgr, info, buf, count);482 483	/*484	 * Convert the linear kernel pointer into a sg_table of pages for use485	 * by the driver.486	 */487	nr_pages = DIV_ROUND_UP((unsigned long)buf + count, PAGE_SIZE) -488		   (unsigned long)buf / PAGE_SIZE;489	pages = kmalloc_array(nr_pages, sizeof(struct page *), GFP_KERNEL);490	if (!pages)491		return -ENOMEM;492 493	p = buf - offset_in_page(buf);494	for (index = 0; index < nr_pages; index++) {495		if (is_vmalloc_addr(p))496			pages[index] = vmalloc_to_page(p);497		else498			pages[index] = kmap_to_page((void *)p);499		if (!pages[index]) {500			kfree(pages);501			return -EFAULT;502		}503		p += PAGE_SIZE;504	}505 506	/*507	 * The temporary pages list is used to code share the merging algorithm508	 * in sg_alloc_table_from_pages509	 */510	rc = sg_alloc_table_from_pages(&sgt, pages, index, offset_in_page(buf),511				       count, GFP_KERNEL);512	kfree(pages);513	if (rc)514		return rc;515 516	rc = fpga_mgr_buf_load_sg(mgr, info, &sgt);517	sg_free_table(&sgt);518 519	return rc;520}521 522/**523 * fpga_mgr_firmware_load - request firmware and load to fpga524 * @mgr:	fpga manager525 * @info:	fpga image specific information526 * @image_name:	name of image file on the firmware search path527 *528 * Request an FPGA image using the firmware class, then write out to the FPGA.529 * Update the state before each step to provide info on what step failed if530 * there is a failure.  This code assumes the caller got the mgr pointer531 * from of_fpga_mgr_get() or fpga_mgr_get() and checked that it is not an error532 * code.533 *534 * Return: 0 on success, negative error code otherwise.535 */536static int fpga_mgr_firmware_load(struct fpga_manager *mgr,537				  struct fpga_image_info *info,538				  const char *image_name)539{540	struct device *dev = &mgr->dev;541	const struct firmware *fw;542	int ret;543 544	dev_info(dev, "writing %s to %s\n", image_name, mgr->name);545 546	mgr->state = FPGA_MGR_STATE_FIRMWARE_REQ;547 548	ret = request_firmware(&fw, image_name, dev);549	if (ret) {550		mgr->state = FPGA_MGR_STATE_FIRMWARE_REQ_ERR;551		dev_err(dev, "Error requesting firmware %s\n", image_name);552		return ret;553	}554 555	ret = fpga_mgr_buf_load(mgr, info, fw->data, fw->size);556 557	release_firmware(fw);558 559	return ret;560}561 562/**563 * fpga_mgr_load - load FPGA from scatter/gather table, buffer, or firmware564 * @mgr:	fpga manager565 * @info:	fpga image information.566 *567 * Load the FPGA from an image which is indicated in @info.  If successful, the568 * FPGA ends up in operating mode.569 *570 * Return: 0 on success, negative error code otherwise.571 */572int fpga_mgr_load(struct fpga_manager *mgr, struct fpga_image_info *info)573{574	info->header_size = mgr->mops->initial_header_size;575 576	if (info->sgt)577		return fpga_mgr_buf_load_sg(mgr, info, info->sgt);578	if (info->buf && info->count)579		return fpga_mgr_buf_load(mgr, info, info->buf, info->count);580	if (info->firmware_name)581		return fpga_mgr_firmware_load(mgr, info, info->firmware_name);582	return -EINVAL;583}584EXPORT_SYMBOL_GPL(fpga_mgr_load);585 586static const char * const state_str[] = {587	[FPGA_MGR_STATE_UNKNOWN] =		"unknown",588	[FPGA_MGR_STATE_POWER_OFF] =		"power off",589	[FPGA_MGR_STATE_POWER_UP] =		"power up",590	[FPGA_MGR_STATE_RESET] =		"reset",591 592	/* requesting FPGA image from firmware */593	[FPGA_MGR_STATE_FIRMWARE_REQ] =		"firmware request",594	[FPGA_MGR_STATE_FIRMWARE_REQ_ERR] =	"firmware request error",595 596	/* Parse FPGA image header */597	[FPGA_MGR_STATE_PARSE_HEADER] =		"parse header",598	[FPGA_MGR_STATE_PARSE_HEADER_ERR] =	"parse header error",599 600	/* Preparing FPGA to receive image */601	[FPGA_MGR_STATE_WRITE_INIT] =		"write init",602	[FPGA_MGR_STATE_WRITE_INIT_ERR] =	"write init error",603 604	/* Writing image to FPGA */605	[FPGA_MGR_STATE_WRITE] =		"write",606	[FPGA_MGR_STATE_WRITE_ERR] =		"write error",607 608	/* Finishing configuration after image has been written */609	[FPGA_MGR_STATE_WRITE_COMPLETE] =	"write complete",610	[FPGA_MGR_STATE_WRITE_COMPLETE_ERR] =	"write complete error",611 612	/* FPGA reports to be in normal operating mode */613	[FPGA_MGR_STATE_OPERATING] =		"operating",614};615 616static ssize_t name_show(struct device *dev,617			 struct device_attribute *attr, char *buf)618{619	struct fpga_manager *mgr = to_fpga_manager(dev);620 621	return sprintf(buf, "%s\n", mgr->name);622}623 624static ssize_t state_show(struct device *dev,625			  struct device_attribute *attr, char *buf)626{627	struct fpga_manager *mgr = to_fpga_manager(dev);628 629	return sprintf(buf, "%s\n", state_str[mgr->state]);630}631 632static ssize_t status_show(struct device *dev,633			   struct device_attribute *attr, char *buf)634{635	struct fpga_manager *mgr = to_fpga_manager(dev);636	u64 status;637	int len = 0;638 639	status = fpga_mgr_status(mgr);640 641	if (status & FPGA_MGR_STATUS_OPERATION_ERR)642		len += sprintf(buf + len, "reconfig operation error\n");643	if (status & FPGA_MGR_STATUS_CRC_ERR)644		len += sprintf(buf + len, "reconfig CRC error\n");645	if (status & FPGA_MGR_STATUS_INCOMPATIBLE_IMAGE_ERR)646		len += sprintf(buf + len, "reconfig incompatible image\n");647	if (status & FPGA_MGR_STATUS_IP_PROTOCOL_ERR)648		len += sprintf(buf + len, "reconfig IP protocol error\n");649	if (status & FPGA_MGR_STATUS_FIFO_OVERFLOW_ERR)650		len += sprintf(buf + len, "reconfig fifo overflow error\n");651 652	return len;653}654 655static DEVICE_ATTR_RO(name);656static DEVICE_ATTR_RO(state);657static DEVICE_ATTR_RO(status);658 659static struct attribute *fpga_mgr_attrs[] = {660	&dev_attr_name.attr,661	&dev_attr_state.attr,662	&dev_attr_status.attr,663	NULL,664};665ATTRIBUTE_GROUPS(fpga_mgr);666 667static struct fpga_manager *__fpga_mgr_get(struct device *mgr_dev)668{669	struct fpga_manager *mgr;670 671	mgr = to_fpga_manager(mgr_dev);672 673	if (!try_module_get(mgr->mops_owner))674		mgr = ERR_PTR(-ENODEV);675 676	return mgr;677}678 679static int fpga_mgr_dev_match(struct device *dev, const void *data)680{681	return dev->parent == data;682}683 684/**685 * fpga_mgr_get - Given a device, get a reference to an fpga mgr.686 * @dev:	parent device that fpga mgr was registered with687 *688 * Return: fpga manager struct or IS_ERR() condition containing error code.689 */690struct fpga_manager *fpga_mgr_get(struct device *dev)691{692	struct fpga_manager *mgr;693	struct device *mgr_dev;694 695	mgr_dev = class_find_device(&fpga_mgr_class, NULL, dev, fpga_mgr_dev_match);696	if (!mgr_dev)697		return ERR_PTR(-ENODEV);698 699	mgr = __fpga_mgr_get(mgr_dev);700	if (IS_ERR(mgr))701		put_device(mgr_dev);702 703	return mgr;704}705EXPORT_SYMBOL_GPL(fpga_mgr_get);706 707/**708 * of_fpga_mgr_get - Given a device node, get a reference to an fpga mgr.709 *710 * @node:	device node711 *712 * Return: fpga manager struct or IS_ERR() condition containing error code.713 */714struct fpga_manager *of_fpga_mgr_get(struct device_node *node)715{716	struct fpga_manager *mgr;717	struct device *mgr_dev;718 719	mgr_dev = class_find_device_by_of_node(&fpga_mgr_class, node);720	if (!mgr_dev)721		return ERR_PTR(-ENODEV);722 723	mgr = __fpga_mgr_get(mgr_dev);724	if (IS_ERR(mgr))725		put_device(mgr_dev);726 727	return mgr;728}729EXPORT_SYMBOL_GPL(of_fpga_mgr_get);730 731/**732 * fpga_mgr_put - release a reference to an fpga manager733 * @mgr:	fpga manager structure734 */735void fpga_mgr_put(struct fpga_manager *mgr)736{737	module_put(mgr->mops_owner);738	put_device(&mgr->dev);739}740EXPORT_SYMBOL_GPL(fpga_mgr_put);741 742/**743 * fpga_mgr_lock - Lock FPGA manager for exclusive use744 * @mgr:	fpga manager745 *746 * Given a pointer to FPGA Manager (from fpga_mgr_get() or747 * of_fpga_mgr_put()) attempt to get the mutex. The user should call748 * fpga_mgr_lock() and verify that it returns 0 before attempting to749 * program the FPGA.  Likewise, the user should call fpga_mgr_unlock750 * when done programming the FPGA.751 *752 * Return: 0 for success or -EBUSY753 */754int fpga_mgr_lock(struct fpga_manager *mgr)755{756	if (!mutex_trylock(&mgr->ref_mutex)) {757		dev_err(&mgr->dev, "FPGA manager is in use.\n");758		return -EBUSY;759	}760 761	return 0;762}763EXPORT_SYMBOL_GPL(fpga_mgr_lock);764 765/**766 * fpga_mgr_unlock - Unlock FPGA manager after done programming767 * @mgr:	fpga manager768 */769void fpga_mgr_unlock(struct fpga_manager *mgr)770{771	mutex_unlock(&mgr->ref_mutex);772}773EXPORT_SYMBOL_GPL(fpga_mgr_unlock);774 775/**776 * __fpga_mgr_register_full - create and register an FPGA Manager device777 * @parent:	fpga manager device from pdev778 * @info:	parameters for fpga manager779 * @owner:	owner module containing the ops780 *781 * The caller of this function is responsible for calling fpga_mgr_unregister().782 * Using devm_fpga_mgr_register_full() instead is recommended.783 *784 * Return: pointer to struct fpga_manager pointer or ERR_PTR()785 */786struct fpga_manager *787__fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info,788			 struct module *owner)789{790	const struct fpga_manager_ops *mops = info->mops;791	struct fpga_manager *mgr;792	int id, ret;793 794	if (!mops) {795		dev_err(parent, "Attempt to register without fpga_manager_ops\n");796		return ERR_PTR(-EINVAL);797	}798 799	if (!info->name || !strlen(info->name)) {800		dev_err(parent, "Attempt to register with no name!\n");801		return ERR_PTR(-EINVAL);802	}803 804	mgr = kzalloc(sizeof(*mgr), GFP_KERNEL);805	if (!mgr)806		return ERR_PTR(-ENOMEM);807 808	id = ida_alloc(&fpga_mgr_ida, GFP_KERNEL);809	if (id < 0) {810		ret = id;811		goto error_kfree;812	}813 814	mutex_init(&mgr->ref_mutex);815 816	mgr->mops_owner = owner;817 818	mgr->name = info->name;819	mgr->mops = info->mops;820	mgr->priv = info->priv;821	mgr->compat_id = info->compat_id;822 823	mgr->dev.class = &fpga_mgr_class;824	mgr->dev.groups = mops->groups;825	mgr->dev.parent = parent;826	mgr->dev.of_node = parent->of_node;827	mgr->dev.id = id;828 829	ret = dev_set_name(&mgr->dev, "fpga%d", id);830	if (ret)831		goto error_device;832 833	/*834	 * Initialize framework state by requesting low level driver read state835	 * from device.  FPGA may be in reset mode or may have been programmed836	 * by bootloader or EEPROM.837	 */838	mgr->state = fpga_mgr_state(mgr);839 840	ret = device_register(&mgr->dev);841	if (ret) {842		put_device(&mgr->dev);843		return ERR_PTR(ret);844	}845 846	return mgr;847 848error_device:849	ida_free(&fpga_mgr_ida, id);850error_kfree:851	kfree(mgr);852 853	return ERR_PTR(ret);854}855EXPORT_SYMBOL_GPL(__fpga_mgr_register_full);856 857/**858 * __fpga_mgr_register - create and register an FPGA Manager device859 * @parent:	fpga manager device from pdev860 * @name:	fpga manager name861 * @mops:	pointer to structure of fpga manager ops862 * @priv:	fpga manager private data863 * @owner:	owner module containing the ops864 *865 * The caller of this function is responsible for calling fpga_mgr_unregister().866 * Using devm_fpga_mgr_register() instead is recommended. This simple867 * version of the register function should be sufficient for most users. The868 * fpga_mgr_register_full() function is available for users that need to pass869 * additional, optional parameters.870 *871 * Return: pointer to struct fpga_manager pointer or ERR_PTR()872 */873struct fpga_manager *874__fpga_mgr_register(struct device *parent, const char *name,875		    const struct fpga_manager_ops *mops, void *priv, struct module *owner)876{877	struct fpga_manager_info info = { 0 };878 879	info.name = name;880	info.mops = mops;881	info.priv = priv;882 883	return __fpga_mgr_register_full(parent, &info, owner);884}885EXPORT_SYMBOL_GPL(__fpga_mgr_register);886 887/**888 * fpga_mgr_unregister - unregister an FPGA manager889 * @mgr: fpga manager struct890 *891 * This function is intended for use in an FPGA manager driver's remove function.892 */893void fpga_mgr_unregister(struct fpga_manager *mgr)894{895	dev_info(&mgr->dev, "%s %s\n", __func__, mgr->name);896 897	/*898	 * If the low level driver provides a method for putting fpga into899	 * a desired state upon unregister, do it.900	 */901	fpga_mgr_fpga_remove(mgr);902 903	device_unregister(&mgr->dev);904}905EXPORT_SYMBOL_GPL(fpga_mgr_unregister);906 907static void devm_fpga_mgr_unregister(struct device *dev, void *res)908{909	struct fpga_mgr_devres *dr = res;910 911	fpga_mgr_unregister(dr->mgr);912}913 914/**915 * __devm_fpga_mgr_register_full - resource managed variant of fpga_mgr_register()916 * @parent:	fpga manager device from pdev917 * @info:	parameters for fpga manager918 * @owner:	owner module containing the ops919 *920 * Return:  fpga manager pointer on success, negative error code otherwise.921 *922 * This is the devres variant of fpga_mgr_register_full() for which the unregister923 * function will be called automatically when the managing device is detached.924 */925struct fpga_manager *926__devm_fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *info,927			      struct module *owner)928{929	struct fpga_mgr_devres *dr;930	struct fpga_manager *mgr;931 932	dr = devres_alloc(devm_fpga_mgr_unregister, sizeof(*dr), GFP_KERNEL);933	if (!dr)934		return ERR_PTR(-ENOMEM);935 936	mgr = __fpga_mgr_register_full(parent, info, owner);937	if (IS_ERR(mgr)) {938		devres_free(dr);939		return mgr;940	}941 942	dr->mgr = mgr;943	devres_add(parent, dr);944 945	return mgr;946}947EXPORT_SYMBOL_GPL(__devm_fpga_mgr_register_full);948 949/**950 * __devm_fpga_mgr_register - resource managed variant of fpga_mgr_register()951 * @parent:	fpga manager device from pdev952 * @name:	fpga manager name953 * @mops:	pointer to structure of fpga manager ops954 * @priv:	fpga manager private data955 * @owner:	owner module containing the ops956 *957 * Return:  fpga manager pointer on success, negative error code otherwise.958 *959 * This is the devres variant of fpga_mgr_register() for which the960 * unregister function will be called automatically when the managing961 * device is detached.962 */963struct fpga_manager *964__devm_fpga_mgr_register(struct device *parent, const char *name,965			 const struct fpga_manager_ops *mops, void *priv,966			 struct module *owner)967{968	struct fpga_manager_info info = { 0 };969 970	info.name = name;971	info.mops = mops;972	info.priv = priv;973 974	return __devm_fpga_mgr_register_full(parent, &info, owner);975}976EXPORT_SYMBOL_GPL(__devm_fpga_mgr_register);977 978static void fpga_mgr_dev_release(struct device *dev)979{980	struct fpga_manager *mgr = to_fpga_manager(dev);981 982	ida_free(&fpga_mgr_ida, mgr->dev.id);983	kfree(mgr);984}985 986static const struct class fpga_mgr_class = {987	.name = "fpga_manager",988	.dev_groups = fpga_mgr_groups,989	.dev_release = fpga_mgr_dev_release,990};991 992static int __init fpga_mgr_class_init(void)993{994	pr_info("FPGA manager framework\n");995 996	return class_register(&fpga_mgr_class);997}998 999static void __exit fpga_mgr_class_exit(void)1000{1001	class_unregister(&fpga_mgr_class);1002	ida_destroy(&fpga_mgr_ida);1003}1004 1005MODULE_AUTHOR("Alan Tull <atull@kernel.org>");1006MODULE_DESCRIPTION("FPGA manager framework");1007MODULE_LICENSE("GPL v2");1008 1009subsys_initcall(fpga_mgr_class_init);1010module_exit(fpga_mgr_class_exit);1011