From 40456168dbe8bf88d0ac19ed7ae1a1cbead74347 Mon Sep 17 00:00:00 2001 From: David Collins Date: Tue, 25 Aug 2015 10:52:38 -0700 Subject: regulator: core: put debugfs consumer handle when unregistering a regulator Ensure that regulator_put() is called on the core debugfs consumer pointer for a given regulator when the debugfs interface is no longer needed. This includes inside of the regulator_unregister() function as well as in the error return path of rdev_init_debugfs(). Change-Id: I10563ae1716f31bdc5840d22633fdbfe278330f1 Signed-off-by: David Collins --- drivers/regulator/core.c | 28 ++++++++++++++++++++-------- 1 file changed, 20 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c index 4de8b9c87f5f..044f2dc9fa0b 100644 --- a/drivers/regulator/core.c +++ b/drivers/regulator/core.c @@ -4183,6 +4183,14 @@ static const struct file_operations reg_consumers_fops = { .release = single_release, }; +static void rdev_deinit_debugfs(struct regulator_dev *rdev) +{ + if (!IS_ERR_OR_NULL(rdev)) { + debugfs_remove_recursive(rdev->debugfs); + regulator_put(rdev->debug_consumer); + } +} + static void rdev_init_debugfs(struct regulator_dev *rdev) { struct device *parent = rdev->dev.parent; @@ -4227,6 +4235,7 @@ static void rdev_init_debugfs(struct regulator_dev *rdev) pr_err("Error-Bad Function Input\n"); goto error; } + rdev->debug_consumer = reg; rdev->open_offset = 1; reg_ops = rdev->desc->ops; @@ -4237,7 +4246,6 @@ static void rdev_init_debugfs(struct regulator_dev *rdev) reg, ®_enable_fops); if (IS_ERR(err_ptr)) { pr_err("Error-Could not create enable file\n"); - debugfs_remove_recursive(rdev->debugfs); goto error; } @@ -4252,7 +4260,6 @@ static void rdev_init_debugfs(struct regulator_dev *rdev) ®_bypass_enable_fops); if (IS_ERR(err_ptr)) { pr_err("Error-Could not create bypass enable file\n"); - debugfs_remove_recursive(rdev->debugfs); goto error; } @@ -4267,7 +4274,6 @@ static void rdev_init_debugfs(struct regulator_dev *rdev) rdev->debugfs, reg, ®_fdisable_fops); if (IS_ERR(err_ptr)) { pr_err("Error-Could not create force_disable file\n"); - debugfs_remove_recursive(rdev->debugfs); goto error; } @@ -4282,7 +4288,6 @@ static void rdev_init_debugfs(struct regulator_dev *rdev) reg, ®_volt_fops); if (IS_ERR(err_ptr)) { pr_err("Error-Could not create voltage file\n"); - debugfs_remove_recursive(rdev->debugfs); goto error; } @@ -4297,7 +4302,6 @@ static void rdev_init_debugfs(struct regulator_dev *rdev) reg, ®_mode_fops); if (IS_ERR(err_ptr)) { pr_err("Error-Could not create mode file\n"); - debugfs_remove_recursive(rdev->debugfs); goto error; } @@ -4312,18 +4316,26 @@ static void rdev_init_debugfs(struct regulator_dev *rdev) rdev->debugfs, reg, ®_set_load_fops); if (IS_ERR(err_ptr)) { pr_err("Error-Could not create optimum_mode file\n"); - debugfs_remove_recursive(rdev->debugfs); goto error; } + return; + error: + rdev_deinit_debugfs(rdev); return; } + #else + +static inline void rdev_deinit_debugfs(struct regulator_dev *rdev) +{ +} + static inline void rdev_init_debugfs(struct regulator_dev *rdev) { - return; } + #endif /** @@ -4519,8 +4531,8 @@ void regulator_unregister(struct regulator_dev *rdev) regulator_put(rdev->supply); } regulator_proxy_consumer_unregister(rdev->proxy_consumer); + rdev_deinit_debugfs(rdev); mutex_lock(®ulator_list_mutex); - debugfs_remove_recursive(rdev->debugfs); flush_work(&rdev->disable_work.work); WARN_ON(rdev->open_count); unset_regulator_supplies(rdev); -- cgit v1.2.3