diff options
Diffstat (limited to 'drivers/fpga/fpga-mgr.c')
| -rw-r--r-- | drivers/fpga/fpga-mgr.c | 82 | 
1 files changed, 49 insertions, 33 deletions
| diff --git a/drivers/fpga/fpga-mgr.c b/drivers/fpga/fpga-mgr.c index 06651389c592..0f4035b089a2 100644 --- a/drivers/fpga/fpga-mgr.c +++ b/drivers/fpga/fpga-mgr.c @@ -664,20 +664,16 @@ static struct attribute *fpga_mgr_attrs[] = {  };  ATTRIBUTE_GROUPS(fpga_mgr); -static struct fpga_manager *__fpga_mgr_get(struct device *dev) +static struct fpga_manager *__fpga_mgr_get(struct device *mgr_dev)  {  	struct fpga_manager *mgr; -	mgr = to_fpga_manager(dev); +	mgr = to_fpga_manager(mgr_dev); -	if (!try_module_get(dev->parent->driver->owner)) -		goto err_dev; +	if (!try_module_get(mgr->mops_owner)) +		mgr = ERR_PTR(-ENODEV);  	return mgr; - -err_dev: -	put_device(dev); -	return ERR_PTR(-ENODEV);  }  static int fpga_mgr_dev_match(struct device *dev, const void *data) @@ -693,12 +689,18 @@ static int fpga_mgr_dev_match(struct device *dev, const void *data)   */  struct fpga_manager *fpga_mgr_get(struct device *dev)  { -	struct device *mgr_dev = class_find_device(&fpga_mgr_class, NULL, dev, -						   fpga_mgr_dev_match); +	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); -	return __fpga_mgr_get(mgr_dev); +	mgr = __fpga_mgr_get(mgr_dev); +	if (IS_ERR(mgr)) +		put_device(mgr_dev); + +	return mgr;  }  EXPORT_SYMBOL_GPL(fpga_mgr_get); @@ -711,13 +713,18 @@ EXPORT_SYMBOL_GPL(fpga_mgr_get);   */  struct fpga_manager *of_fpga_mgr_get(struct device_node *node)  { -	struct device *dev; +	struct fpga_manager *mgr; +	struct device *mgr_dev; -	dev = class_find_device_by_of_node(&fpga_mgr_class, node); -	if (!dev) +	mgr_dev = class_find_device_by_of_node(&fpga_mgr_class, node); +	if (!mgr_dev)  		return ERR_PTR(-ENODEV); -	return __fpga_mgr_get(dev); +	mgr = __fpga_mgr_get(mgr_dev); +	if (IS_ERR(mgr)) +		put_device(mgr_dev); + +	return mgr;  }  EXPORT_SYMBOL_GPL(of_fpga_mgr_get); @@ -727,7 +734,7 @@ EXPORT_SYMBOL_GPL(of_fpga_mgr_get);   */  void fpga_mgr_put(struct fpga_manager *mgr)  { -	module_put(mgr->dev.parent->driver->owner); +	module_put(mgr->mops_owner);  	put_device(&mgr->dev);  }  EXPORT_SYMBOL_GPL(fpga_mgr_put); @@ -766,9 +773,10 @@ void fpga_mgr_unlock(struct fpga_manager *mgr)  EXPORT_SYMBOL_GPL(fpga_mgr_unlock);  /** - * fpga_mgr_register_full - create and register an FPGA Manager device + * __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. @@ -776,7 +784,8 @@ EXPORT_SYMBOL_GPL(fpga_mgr_unlock);   * 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) +__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; @@ -804,6 +813,8 @@ fpga_mgr_register_full(struct device *parent, const struct fpga_manager_info *in  	mutex_init(&mgr->ref_mutex); +	mgr->mops_owner = owner; +  	mgr->name = info->name;  	mgr->mops = info->mops;  	mgr->priv = info->priv; @@ -841,14 +852,15 @@ error_kfree:  	return ERR_PTR(ret);  } -EXPORT_SYMBOL_GPL(fpga_mgr_register_full); +EXPORT_SYMBOL_GPL(__fpga_mgr_register_full);  /** - * fpga_mgr_register - create and register an FPGA Manager device + * __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 @@ -859,8 +871,8 @@ EXPORT_SYMBOL_GPL(fpga_mgr_register_full);   * 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) +__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 }; @@ -868,9 +880,9 @@ fpga_mgr_register(struct device *parent, const char *name,  	info.mops = mops;  	info.priv = priv; -	return fpga_mgr_register_full(parent, &info); +	return __fpga_mgr_register_full(parent, &info, owner);  } -EXPORT_SYMBOL_GPL(fpga_mgr_register); +EXPORT_SYMBOL_GPL(__fpga_mgr_register);  /**   * fpga_mgr_unregister - unregister an FPGA manager @@ -900,9 +912,10 @@ static void devm_fpga_mgr_unregister(struct device *dev, void *res)  }  /** - * devm_fpga_mgr_register_full - resource managed variant of fpga_mgr_register() + * __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.   * @@ -910,7 +923,8 @@ static void devm_fpga_mgr_unregister(struct device *dev, void *res)   * 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) +__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; @@ -919,7 +933,7 @@ devm_fpga_mgr_register_full(struct device *parent, const struct fpga_manager_inf  	if (!dr)  		return ERR_PTR(-ENOMEM); -	mgr = fpga_mgr_register_full(parent, info); +	mgr = __fpga_mgr_register_full(parent, info, owner);  	if (IS_ERR(mgr)) {  		devres_free(dr);  		return mgr; @@ -930,14 +944,15 @@ devm_fpga_mgr_register_full(struct device *parent, const struct fpga_manager_inf  	return mgr;  } -EXPORT_SYMBOL_GPL(devm_fpga_mgr_register_full); +EXPORT_SYMBOL_GPL(__devm_fpga_mgr_register_full);  /** - * devm_fpga_mgr_register - resource managed variant of fpga_mgr_register() + * __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.   * @@ -946,8 +961,9 @@ EXPORT_SYMBOL_GPL(devm_fpga_mgr_register_full);   * device is detached.   */  struct fpga_manager * -devm_fpga_mgr_register(struct device *parent, const char *name, -		       const struct fpga_manager_ops *mops, void *priv) +__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 }; @@ -955,9 +971,9 @@ devm_fpga_mgr_register(struct device *parent, const char *name,  	info.mops = mops;  	info.priv = priv; -	return devm_fpga_mgr_register_full(parent, &info); +	return __devm_fpga_mgr_register_full(parent, &info, owner);  } -EXPORT_SYMBOL_GPL(devm_fpga_mgr_register); +EXPORT_SYMBOL_GPL(__devm_fpga_mgr_register);  static void fpga_mgr_dev_release(struct device *dev)  { | 
