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