Skip to content

Commit 3466ea2

Browse files
windhlvireshk
authored andcommitted
OPP: Don't drop opp->np reference while it is still in use
The struct dev_pm_opp contains a reference of the DT node, opp->np, throughout its lifetime. We should increase the refcount for the same from _opp_add_static_v2(), and drop it while removing the OPP finally. Signed-off-by: Liang He <[email protected]> [ Viresh: Updated subject / commit log, create _of_clear_opp() and drop reference from it] Signed-off-by: Viresh Kumar <[email protected]>
1 parent ce736cf commit 3466ea2

File tree

3 files changed

+12
-8
lines changed

3 files changed

+12
-8
lines changed

drivers/opp/core.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1553,7 +1553,7 @@ static void _opp_kref_release(struct kref *kref)
15531553
* frequency/voltage list.
15541554
*/
15551555
blocking_notifier_call_chain(&opp_table->head, OPP_EVENT_REMOVE, opp);
1556-
_of_opp_free_required_opps(opp_table, opp);
1556+
_of_clear_opp(opp_table, opp);
15571557
opp_debug_remove_one(opp);
15581558
kfree(opp);
15591559
}

drivers/opp/of.c

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -254,8 +254,8 @@ void _of_clear_opp_table(struct opp_table *opp_table)
254254
* Release all resources previously acquired with a call to
255255
* _of_opp_alloc_required_opps().
256256
*/
257-
void _of_opp_free_required_opps(struct opp_table *opp_table,
258-
struct dev_pm_opp *opp)
257+
static void _of_opp_free_required_opps(struct opp_table *opp_table,
258+
struct dev_pm_opp *opp)
259259
{
260260
struct dev_pm_opp **required_opps = opp->required_opps;
261261
int i;
@@ -275,6 +275,12 @@ void _of_opp_free_required_opps(struct opp_table *opp_table,
275275
kfree(required_opps);
276276
}
277277

278+
void _of_clear_opp(struct opp_table *opp_table, struct dev_pm_opp *opp)
279+
{
280+
_of_opp_free_required_opps(opp_table, opp);
281+
of_node_put(opp->np);
282+
}
283+
278284
/* Populate all required OPPs which are part of "required-opps" list */
279285
static int _of_opp_alloc_required_opps(struct opp_table *opp_table,
280286
struct dev_pm_opp *opp)
@@ -938,7 +944,7 @@ static struct dev_pm_opp *_opp_add_static_v2(struct opp_table *opp_table,
938944

939945
new_opp->turbo = of_property_read_bool(np, "turbo-mode");
940946

941-
new_opp->np = np;
947+
new_opp->np = of_node_get(np);
942948
new_opp->dynamic = false;
943949
new_opp->available = true;
944950

drivers/opp/opp.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -267,14 +267,12 @@ static inline bool lazy_linking_pending(struct opp_table *opp_table)
267267
void _of_init_opp_table(struct opp_table *opp_table, struct device *dev, int index);
268268
void _of_clear_opp_table(struct opp_table *opp_table);
269269
struct opp_table *_managed_opp(struct device *dev, int index);
270-
void _of_opp_free_required_opps(struct opp_table *opp_table,
271-
struct dev_pm_opp *opp);
270+
void _of_clear_opp(struct opp_table *opp_table, struct dev_pm_opp *opp);
272271
#else
273272
static inline void _of_init_opp_table(struct opp_table *opp_table, struct device *dev, int index) {}
274273
static inline void _of_clear_opp_table(struct opp_table *opp_table) {}
275274
static inline struct opp_table *_managed_opp(struct device *dev, int index) { return NULL; }
276-
static inline void _of_opp_free_required_opps(struct opp_table *opp_table,
277-
struct dev_pm_opp *opp) {}
275+
static inline void _of_clear_opp(struct opp_table *opp_table, struct dev_pm_opp *opp) {}
278276
#endif
279277

280278
#ifdef CONFIG_DEBUG_FS

0 commit comments

Comments
 (0)