diff options
author | Viresh Kumar <viresh.kumar@linaro.org> | 2020-10-22 08:42:27 +0200 |
---|---|---|
committer | Viresh Kumar <viresh.kumar@linaro.org> | 2020-11-02 06:15:37 +0100 |
commit | ef43f01ac06976b2aa2b17266d307bb1a4f7e6f9 (patch) | |
tree | a95507529f3d026af183fcf5aa708e29a4873078 /drivers/opp | |
parent | opp: Reduce the size of critical section in _opp_table_kref_release() (diff) | |
download | linux-ef43f01ac06976b2aa2b17266d307bb1a4f7e6f9.tar.xz linux-ef43f01ac06976b2aa2b17266d307bb1a4f7e6f9.zip |
opp: Always add entries in dev_list with opp_table->lock held
The readers of dev_list expect the updates to it to take place from
within the opp_table->lock and this is missing in the case where the
dev_list is updated for already managed OPPs.
Fix that by calling _add_opp_dev() from there and remove the now unused
_add_opp_dev_unlocked() callback. While at it, also reduce the length of
the critical section in _add_opp_dev().
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Diffstat (limited to 'drivers/opp')
-rw-r--r-- | drivers/opp/core.c | 20 |
1 files changed, 5 insertions, 15 deletions
diff --git a/drivers/opp/core.c b/drivers/opp/core.c index 0e0a5269dc82..84035ab8bb31 100644 --- a/drivers/opp/core.c +++ b/drivers/opp/core.c @@ -1036,8 +1036,8 @@ static void _remove_opp_dev(struct opp_device *opp_dev, kfree(opp_dev); } -static struct opp_device *_add_opp_dev_unlocked(const struct device *dev, - struct opp_table *opp_table) +struct opp_device *_add_opp_dev(const struct device *dev, + struct opp_table *opp_table) { struct opp_device *opp_dev; @@ -1048,7 +1048,9 @@ static struct opp_device *_add_opp_dev_unlocked(const struct device *dev, /* Initialize opp-dev */ opp_dev->dev = dev; + mutex_lock(&opp_table->lock); list_add(&opp_dev->node, &opp_table->dev_list); + mutex_unlock(&opp_table->lock); /* Create debugfs entries for the opp_table */ opp_debug_register(opp_dev, opp_table); @@ -1056,18 +1058,6 @@ static struct opp_device *_add_opp_dev_unlocked(const struct device *dev, return opp_dev; } -struct opp_device *_add_opp_dev(const struct device *dev, - struct opp_table *opp_table) -{ - struct opp_device *opp_dev; - - mutex_lock(&opp_table->lock); - opp_dev = _add_opp_dev_unlocked(dev, opp_table); - mutex_unlock(&opp_table->lock); - - return opp_dev; -} - static struct opp_table *_allocate_opp_table(struct device *dev, int index) { struct opp_table *opp_table; @@ -1148,7 +1138,7 @@ static struct opp_table *_opp_get_opp_table(struct device *dev, int index) opp_table = _managed_opp(dev, index); if (opp_table) { - if (!_add_opp_dev_unlocked(dev, opp_table)) { + if (!_add_opp_dev(dev, opp_table)) { dev_pm_opp_put_opp_table(opp_table); opp_table = ERR_PTR(-ENOMEM); } |