Loading drivers/opp/core.c +25 −23 Original line number Diff line number Diff line Loading @@ -1492,7 +1492,11 @@ static struct dev_pm_opp *_opp_get_next(struct opp_table *opp_table, mutex_lock(&opp_table->lock); list_for_each_entry(temp, &opp_table->opp_list, node) { if (dynamic == temp->dynamic) { /* * Refcount must be dropped only once for each OPP by OPP core, * do that with help of "removed" flag. */ if (!temp->removed && dynamic == temp->dynamic) { opp = temp; break; } Loading @@ -1502,10 +1506,27 @@ static struct dev_pm_opp *_opp_get_next(struct opp_table *opp_table, return opp; } bool _opp_remove_all_static(struct opp_table *opp_table) /* * Can't call dev_pm_opp_put() from under the lock as debugfs removal needs to * happen lock less to avoid circular dependency issues. This routine must be * called without the opp_table->lock held. */ static void _opp_remove_all(struct opp_table *opp_table, bool dynamic) { struct dev_pm_opp *opp; while ((opp = _opp_get_next(opp_table, dynamic))) { opp->removed = true; dev_pm_opp_put(opp); /* Drop the references taken by dev_pm_opp_add() */ if (dynamic) dev_pm_opp_put_opp_table(opp_table); } } bool _opp_remove_all_static(struct opp_table *opp_table) { mutex_lock(&opp_table->lock); if (!opp_table->parsed_static_opps) { Loading @@ -1520,13 +1541,7 @@ bool _opp_remove_all_static(struct opp_table *opp_table) mutex_unlock(&opp_table->lock); /* * Can't remove the OPP from under the lock, debugfs removal needs to * happen lock less to avoid circular dependency issues. */ while ((opp = _opp_get_next(opp_table, false))) dev_pm_opp_put(opp); _opp_remove_all(opp_table, false); return true; } Loading @@ -1539,25 +1554,12 @@ bool _opp_remove_all_static(struct opp_table *opp_table) void dev_pm_opp_remove_all_dynamic(struct device *dev) { struct opp_table *opp_table; struct dev_pm_opp *opp; int count = 0; opp_table = _find_opp_table(dev); if (IS_ERR(opp_table)) return; /* * Can't remove the OPP from under the lock, debugfs removal needs to * happen lock less to avoid circular dependency issues. */ while ((opp = _opp_get_next(opp_table, true))) { dev_pm_opp_put(opp); count++; } /* Drop the references taken by dev_pm_opp_add() */ while (count--) dev_pm_opp_put_opp_table(opp_table); _opp_remove_all(opp_table, true); /* Drop the reference taken by _find_opp_table() */ dev_pm_opp_put_opp_table(opp_table); Loading drivers/opp/opp.h +2 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ extern struct list_head opp_tables, lazy_opp_tables; * @dynamic: not-created from static DT entries. * @turbo: true if turbo (boost) OPP * @suspend: true if suspend OPP * @removed: flag indicating that OPP's reference is dropped by OPP core. * @pstate: Device's power domain's performance state. * @rate: Frequency in hertz * @level: Performance level Loading @@ -78,6 +79,7 @@ struct dev_pm_opp { bool dynamic; bool turbo; bool suspend; bool removed; unsigned int pstate; unsigned long rate; unsigned int level; Loading Loading
drivers/opp/core.c +25 −23 Original line number Diff line number Diff line Loading @@ -1492,7 +1492,11 @@ static struct dev_pm_opp *_opp_get_next(struct opp_table *opp_table, mutex_lock(&opp_table->lock); list_for_each_entry(temp, &opp_table->opp_list, node) { if (dynamic == temp->dynamic) { /* * Refcount must be dropped only once for each OPP by OPP core, * do that with help of "removed" flag. */ if (!temp->removed && dynamic == temp->dynamic) { opp = temp; break; } Loading @@ -1502,10 +1506,27 @@ static struct dev_pm_opp *_opp_get_next(struct opp_table *opp_table, return opp; } bool _opp_remove_all_static(struct opp_table *opp_table) /* * Can't call dev_pm_opp_put() from under the lock as debugfs removal needs to * happen lock less to avoid circular dependency issues. This routine must be * called without the opp_table->lock held. */ static void _opp_remove_all(struct opp_table *opp_table, bool dynamic) { struct dev_pm_opp *opp; while ((opp = _opp_get_next(opp_table, dynamic))) { opp->removed = true; dev_pm_opp_put(opp); /* Drop the references taken by dev_pm_opp_add() */ if (dynamic) dev_pm_opp_put_opp_table(opp_table); } } bool _opp_remove_all_static(struct opp_table *opp_table) { mutex_lock(&opp_table->lock); if (!opp_table->parsed_static_opps) { Loading @@ -1520,13 +1541,7 @@ bool _opp_remove_all_static(struct opp_table *opp_table) mutex_unlock(&opp_table->lock); /* * Can't remove the OPP from under the lock, debugfs removal needs to * happen lock less to avoid circular dependency issues. */ while ((opp = _opp_get_next(opp_table, false))) dev_pm_opp_put(opp); _opp_remove_all(opp_table, false); return true; } Loading @@ -1539,25 +1554,12 @@ bool _opp_remove_all_static(struct opp_table *opp_table) void dev_pm_opp_remove_all_dynamic(struct device *dev) { struct opp_table *opp_table; struct dev_pm_opp *opp; int count = 0; opp_table = _find_opp_table(dev); if (IS_ERR(opp_table)) return; /* * Can't remove the OPP from under the lock, debugfs removal needs to * happen lock less to avoid circular dependency issues. */ while ((opp = _opp_get_next(opp_table, true))) { dev_pm_opp_put(opp); count++; } /* Drop the references taken by dev_pm_opp_add() */ while (count--) dev_pm_opp_put_opp_table(opp_table); _opp_remove_all(opp_table, true); /* Drop the reference taken by _find_opp_table() */ dev_pm_opp_put_opp_table(opp_table); Loading
drivers/opp/opp.h +2 −0 Original line number Diff line number Diff line Loading @@ -56,6 +56,7 @@ extern struct list_head opp_tables, lazy_opp_tables; * @dynamic: not-created from static DT entries. * @turbo: true if turbo (boost) OPP * @suspend: true if suspend OPP * @removed: flag indicating that OPP's reference is dropped by OPP core. * @pstate: Device's power domain's performance state. * @rate: Frequency in hertz * @level: Performance level Loading @@ -78,6 +79,7 @@ struct dev_pm_opp { bool dynamic; bool turbo; bool suspend; bool removed; unsigned int pstate; unsigned long rate; unsigned int level; Loading