diff options
Diffstat (limited to 'drivers/fpga/fpga-mgr.c')
-rw-r--r-- | drivers/fpga/fpga-mgr.c | 153 |
1 files changed, 96 insertions, 57 deletions
diff --git a/drivers/fpga/fpga-mgr.c b/drivers/fpga/fpga-mgr.c index b85bc47c91a9..aa30889e2320 100644 --- a/drivers/fpga/fpga-mgr.c +++ b/drivers/fpga/fpga-mgr.c @@ -25,8 +25,74 @@ 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_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 a FPGA image info struct + * fpga_image_info_alloc - Allocate an FPGA image info struct * @dev: owning device * * Return: struct fpga_image_info or NULL @@ -50,7 +116,7 @@ struct fpga_image_info *fpga_image_info_alloc(struct device *dev) EXPORT_SYMBOL_GPL(fpga_image_info_alloc); /** - * fpga_image_info_free - Free a FPGA image info struct + * 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) @@ -83,9 +149,9 @@ static int fpga_mgr_write_init_buf(struct fpga_manager *mgr, mgr->state = FPGA_MGR_STATE_WRITE_INIT; if (!mgr->mops->initial_header_size) - ret = mgr->mops->write_init(mgr, info, NULL, 0); + ret = fpga_mgr_write_init(mgr, info, NULL, 0); else - ret = mgr->mops->write_init( + ret = fpga_mgr_write_init( mgr, info, buf, min(mgr->mops->initial_header_size, count)); if (ret) { @@ -137,27 +203,6 @@ static int fpga_mgr_write_init_sg(struct fpga_manager *mgr, return ret; } -/* - * After all the FPGA image has been written, do the device specific steps to - * finish and set the FPGA into operating mode. - */ -static int fpga_mgr_write_complete(struct fpga_manager *mgr, - struct fpga_image_info *info) -{ - int ret; - - mgr->state = FPGA_MGR_STATE_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; -} - /** * fpga_mgr_buf_load_sg - load fpga from image in buffer from a scatter list * @mgr: fpga manager @@ -188,13 +233,13 @@ static int fpga_mgr_buf_load_sg(struct fpga_manager *mgr, /* Write the FPGA image to the FPGA. */ mgr->state = FPGA_MGR_STATE_WRITE; if (mgr->mops->write_sg) { - ret = mgr->mops->write_sg(mgr, sgt); + ret = fpga_mgr_write_sg(mgr, sgt); } else { struct sg_mapping_iter miter; sg_miter_start(&miter, sgt->sgl, sgt->nents, SG_MITER_FROM_SG); while (sg_miter_next(&miter)) { - ret = mgr->mops->write(mgr, miter.addr, miter.length); + ret = fpga_mgr_write(mgr, miter.addr, miter.length); if (ret) break; } @@ -224,7 +269,7 @@ static int fpga_mgr_buf_load_mapped(struct fpga_manager *mgr, * Write the FPGA image to the FPGA. */ mgr->state = FPGA_MGR_STATE_WRITE; - ret = mgr->mops->write(mgr, buf, count); + 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; @@ -417,10 +462,7 @@ static ssize_t status_show(struct device *dev, u64 status; int len = 0; - if (!mgr->mops->status) - return -ENOENT; - - status = mgr->mops->status(mgr); + status = fpga_mgr_status(mgr); if (status & FPGA_MGR_STATUS_OPERATION_ERR) len += sprintf(buf + len, "reconfig operation error\n"); @@ -470,7 +512,7 @@ static int fpga_mgr_dev_match(struct device *dev, const void *data) } /** - * fpga_mgr_get - Given a device, get a reference to a fpga mgr. + * 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. @@ -487,7 +529,7 @@ struct fpga_manager *fpga_mgr_get(struct device *dev) EXPORT_SYMBOL_GPL(fpga_mgr_get); /** - * of_fpga_mgr_get - Given a device node, get a reference to a fpga mgr. + * of_fpga_mgr_get - Given a device node, get a reference to an fpga mgr. * * @node: device node * @@ -506,7 +548,7 @@ struct fpga_manager *of_fpga_mgr_get(struct device_node *node) EXPORT_SYMBOL_GPL(of_fpga_mgr_get); /** - * fpga_mgr_put - release a reference to a fpga manager + * fpga_mgr_put - release a reference to an fpga manager * @mgr: fpga manager structure */ void fpga_mgr_put(struct fpga_manager *mgr) @@ -550,8 +592,8 @@ void fpga_mgr_unlock(struct fpga_manager *mgr) EXPORT_SYMBOL_GPL(fpga_mgr_unlock); /** - * fpga_mgr_create - create and initialize a FPGA manager struct - * @dev: fpga manager device from pdev + * fpga_mgr_create - create and initialize an FPGA manager struct + * @parent: fpga manager device from pdev * @name: fpga manager name * @mops: pointer to structure of fpga manager ops * @priv: fpga manager private data @@ -561,22 +603,20 @@ EXPORT_SYMBOL_GPL(fpga_mgr_unlock); * * Return: pointer to struct fpga_manager or NULL */ -struct fpga_manager *fpga_mgr_create(struct device *dev, const char *name, +struct fpga_manager *fpga_mgr_create(struct device *parent, const char *name, const struct fpga_manager_ops *mops, void *priv) { struct fpga_manager *mgr; int id, ret; - if (!mops || !mops->write_complete || !mops->state || - !mops->write_init || (!mops->write && !mops->write_sg) || - (mops->write && mops->write_sg)) { - dev_err(dev, "Attempt to register without fpga_manager_ops\n"); + if (!mops) { + dev_err(parent, "Attempt to register without fpga_manager_ops\n"); return NULL; } if (!name || !strlen(name)) { - dev_err(dev, "Attempt to register with no name!\n"); + dev_err(parent, "Attempt to register with no name!\n"); return NULL; } @@ -597,8 +637,8 @@ struct fpga_manager *fpga_mgr_create(struct device *dev, const char *name, device_initialize(&mgr->dev); mgr->dev.class = fpga_mgr_class; mgr->dev.groups = mops->groups; - mgr->dev.parent = dev; - mgr->dev.of_node = dev->of_node; + mgr->dev.parent = parent; + mgr->dev.of_node = parent->of_node; mgr->dev.id = id; ret = dev_set_name(&mgr->dev, "fpga%d", id); @@ -617,7 +657,7 @@ error_kfree: EXPORT_SYMBOL_GPL(fpga_mgr_create); /** - * fpga_mgr_free - free a FPGA manager created with fpga_mgr_create() + * fpga_mgr_free - free an FPGA manager created with fpga_mgr_create() * @mgr: fpga manager struct */ void fpga_mgr_free(struct fpga_manager *mgr) @@ -636,12 +676,12 @@ static void devm_fpga_mgr_release(struct device *dev, void *res) /** * devm_fpga_mgr_create - create and initialize a managed FPGA manager struct - * @dev: fpga manager device from pdev + * @parent: fpga manager device from pdev * @name: fpga manager name * @mops: pointer to structure of fpga manager ops * @priv: fpga manager private data * - * This function is intended for use in a FPGA manager driver's probe function. + * This function is intended for use in an FPGA manager driver's probe function. * After the manager driver creates the manager struct with * devm_fpga_mgr_create(), it should register it with fpga_mgr_register(). The * manager driver's remove function should call fpga_mgr_unregister(). The @@ -651,7 +691,7 @@ static void devm_fpga_mgr_release(struct device *dev, void *res) * * Return: pointer to struct fpga_manager or NULL */ -struct fpga_manager *devm_fpga_mgr_create(struct device *dev, const char *name, +struct fpga_manager *devm_fpga_mgr_create(struct device *parent, const char *name, const struct fpga_manager_ops *mops, void *priv) { @@ -661,20 +701,20 @@ struct fpga_manager *devm_fpga_mgr_create(struct device *dev, const char *name, if (!dr) return NULL; - dr->mgr = fpga_mgr_create(dev, name, mops, priv); + dr->mgr = fpga_mgr_create(parent, name, mops, priv); if (!dr->mgr) { devres_free(dr); return NULL; } - devres_add(dev, dr); + devres_add(parent, dr); return dr->mgr; } EXPORT_SYMBOL_GPL(devm_fpga_mgr_create); /** - * fpga_mgr_register - register a FPGA manager + * fpga_mgr_register - register an FPGA manager * @mgr: fpga manager struct * * Return: 0 on success, negative error code otherwise. @@ -688,7 +728,7 @@ int fpga_mgr_register(struct fpga_manager *mgr) * from device. FPGA may be in reset mode or may have been programmed * by bootloader or EEPROM. */ - mgr->state = mgr->mops->state(mgr); + mgr->state = fpga_mgr_state(mgr); ret = device_add(&mgr->dev); if (ret) @@ -706,10 +746,10 @@ error_device: EXPORT_SYMBOL_GPL(fpga_mgr_register); /** - * fpga_mgr_unregister - unregister a FPGA manager + * fpga_mgr_unregister - unregister an FPGA manager * @mgr: fpga manager struct * - * This function is intended for use in a FPGA manager driver's remove function. + * This function is intended for use in an FPGA manager driver's remove function. */ void fpga_mgr_unregister(struct fpga_manager *mgr) { @@ -719,8 +759,7 @@ void fpga_mgr_unregister(struct fpga_manager *mgr) * If the low level driver provides a method for putting fpga into * a desired state upon unregister, do it. */ - if (mgr->mops->fpga_remove) - mgr->mops->fpga_remove(mgr); + fpga_mgr_fpga_remove(mgr); device_unregister(&mgr->dev); } |