diff options
Diffstat (limited to 'drivers/fpga/fpga-bridge.c')
| -rw-r--r-- | drivers/fpga/fpga-bridge.c | 68 | 
1 files changed, 59 insertions, 9 deletions
| diff --git a/drivers/fpga/fpga-bridge.c b/drivers/fpga/fpga-bridge.c index c983dac97501..80bd8f1b2aa6 100644 --- a/drivers/fpga/fpga-bridge.c +++ b/drivers/fpga/fpga-bridge.c @@ -324,6 +324,9 @@ ATTRIBUTE_GROUPS(fpga_bridge);   * @br_ops:	pointer to structure of fpga bridge ops   * @priv:	FPGA bridge private data   * + * The caller of this function is responsible for freeing the bridge with + * fpga_bridge_free().  Using devm_fpga_bridge_create() instead is recommended. + *   * Return: struct fpga_bridge or NULL   */  struct fpga_bridge *fpga_bridge_create(struct device *dev, const char *name, @@ -378,8 +381,8 @@ error_kfree:  EXPORT_SYMBOL_GPL(fpga_bridge_create);  /** - * fpga_bridge_free - free a fpga bridge and its id - * @bridge:	FPGA bridge struct created by fpga_bridge_create + * fpga_bridge_free - free a fpga bridge created by fpga_bridge_create() + * @bridge:	FPGA bridge struct   */  void fpga_bridge_free(struct fpga_bridge *bridge)  { @@ -388,9 +391,56 @@ void fpga_bridge_free(struct fpga_bridge *bridge)  }  EXPORT_SYMBOL_GPL(fpga_bridge_free); +static void devm_fpga_bridge_release(struct device *dev, void *res) +{ +	struct fpga_bridge *bridge = *(struct fpga_bridge **)res; + +	fpga_bridge_free(bridge); +} +  /** - * fpga_bridge_register - register a fpga bridge - * @bridge:	FPGA bridge struct created by fpga_bridge_create + * devm_fpga_bridge_create - create and init a managed struct fpga_bridge + * @dev:	FPGA bridge device from pdev + * @name:	FPGA bridge name + * @br_ops:	pointer to structure of fpga bridge ops + * @priv:	FPGA bridge private data + * + * This function is intended for use in a FPGA bridge driver's probe function. + * After the bridge driver creates the struct with devm_fpga_bridge_create(), it + * should register the bridge with fpga_bridge_register().  The bridge driver's + * remove function should call fpga_bridge_unregister().  The bridge struct + * allocated with this function will be freed automatically on driver detach. + * This includes the case of a probe function returning error before calling + * fpga_bridge_register(), the struct will still get cleaned up. + * + *  Return: struct fpga_bridge or NULL + */ +struct fpga_bridge +*devm_fpga_bridge_create(struct device *dev, const char *name, +			 const struct fpga_bridge_ops *br_ops, void *priv) +{ +	struct fpga_bridge **ptr, *bridge; + +	ptr = devres_alloc(devm_fpga_bridge_release, sizeof(*ptr), GFP_KERNEL); +	if (!ptr) +		return NULL; + +	bridge = fpga_bridge_create(dev, name, br_ops, priv); +	if (!bridge) { +		devres_free(ptr); +	} else { +		*ptr = bridge; +		devres_add(dev, ptr); +	} + +	return bridge; +} +EXPORT_SYMBOL_GPL(devm_fpga_bridge_create); + +/** + * fpga_bridge_register - register a FPGA bridge + * + * @bridge: FPGA bridge struct   *   * Return: 0 for success, error code otherwise.   */ @@ -412,8 +462,11 @@ int fpga_bridge_register(struct fpga_bridge *bridge)  EXPORT_SYMBOL_GPL(fpga_bridge_register);  /** - * fpga_bridge_unregister - unregister and free a fpga bridge - * @bridge:	FPGA bridge struct created by fpga_bridge_create + * fpga_bridge_unregister - unregister a FPGA bridge + * + * @bridge: FPGA bridge struct + * + * This function is intended for use in a FPGA bridge driver's remove function.   */  void fpga_bridge_unregister(struct fpga_bridge *bridge)  { @@ -430,9 +483,6 @@ EXPORT_SYMBOL_GPL(fpga_bridge_unregister);  static void fpga_bridge_dev_release(struct device *dev)  { -	struct fpga_bridge *bridge = to_fpga_bridge(dev); - -	fpga_bridge_free(bridge);  }  static int __init fpga_bridge_dev_init(void) | 
