diff options
author | Alan Tull <atull@opensource.altera.com> | 2015-10-22 20:38:37 +0300 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2015-10-24 02:49:44 +0300 |
commit | 654ba4cc0f3ed7c0f08bfb39f66059d8c42943ee (patch) | |
tree | 0afa1399bea345e12cf72ffac476190f27562275 /drivers | |
parent | 4d10eaff5bfc69997a769f9c83b749f0a8c542fa (diff) | |
download | linux-654ba4cc0f3ed7c0f08bfb39f66059d8c42943ee.tar.xz |
fpga manager: ensure lifetime with of_fpga_mgr_get
Ensure device and driver lifetime from of_fpga_mgr_get() to
fpga_mgr_put().
* Don't put_device() in of_fpga_mgr_get, do it in fpga_mgr_put().
(still do put_device if there is an error).
* Do module_get on the low level driver.
* Don't need to module_get(THIS_MODULE) since we won't be allowed
to unload the fpga manager core without unloading low level
driver first.
* Remove unnedessary null check for node pointer.
Signed-off-by: Alan Tull <atull@opensource.altera.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/fpga/fpga-mgr.c | 32 |
1 files changed, 17 insertions, 15 deletions
diff --git a/drivers/fpga/fpga-mgr.c b/drivers/fpga/fpga-mgr.c index 25261636687c..68d7b41159cb 100644 --- a/drivers/fpga/fpga-mgr.c +++ b/drivers/fpga/fpga-mgr.c @@ -204,9 +204,7 @@ struct fpga_manager *of_fpga_mgr_get(struct device_node *node) { struct fpga_manager *mgr; struct device *dev; - - if (!node) - return ERR_PTR(-EINVAL); + int ret = -ENODEV; dev = class_find_device(fpga_mgr_class, NULL, node, fpga_mgr_of_node_match); @@ -214,20 +212,25 @@ struct fpga_manager *of_fpga_mgr_get(struct device_node *node) return ERR_PTR(-ENODEV); mgr = to_fpga_manager(dev); - put_device(dev); if (!mgr) - return ERR_PTR(-ENODEV); + goto err_dev; /* Get exclusive use of fpga manager */ - if (!mutex_trylock(&mgr->ref_mutex)) - return ERR_PTR(-EBUSY); - - if (!try_module_get(THIS_MODULE)) { - mutex_unlock(&mgr->ref_mutex); - return ERR_PTR(-ENODEV); + if (!mutex_trylock(&mgr->ref_mutex)) { + ret = -EBUSY; + goto err_dev; } + if (!try_module_get(dev->parent->driver->owner)) + goto err_ll_mod; + return mgr; + +err_ll_mod: + mutex_unlock(&mgr->ref_mutex); +err_dev: + put_device(dev); + return ERR_PTR(ret); } EXPORT_SYMBOL_GPL(of_fpga_mgr_get); @@ -237,10 +240,9 @@ EXPORT_SYMBOL_GPL(of_fpga_mgr_get); */ void fpga_mgr_put(struct fpga_manager *mgr) { - if (mgr) { - module_put(THIS_MODULE); - mutex_unlock(&mgr->ref_mutex); - } + module_put(mgr->dev.parent->driver->owner); + mutex_unlock(&mgr->ref_mutex); + put_device(&mgr->dev); } EXPORT_SYMBOL_GPL(fpga_mgr_put); |