Commit 411466c5 authored by Sudeep Holla's avatar Sudeep Holla Committed by Rafael J. Wysocki

PM / OPP: add non-OF versions of dev_pm_opp_{cpumask_, }remove_table

Functions dev_pm_opp_of_{cpumask_,}remove_table removes/frees all the
static OPP entries associated with the device and/or all cpus(in case
of cpumask) that are created from DT.

However the OPP entries are populated reading from the firmware or some
different method using dev_pm_opp_add are marked dynamic and can't be
removed using above functions.

This patch adds non DT/OF versions of dev_pm_opp_{cpumask_,}remove_table
to support the above mentioned usecase.

This is in preparation to make use of the same in scpi-cpufreq.c
Signed-off-by: default avatarSudeep Holla <sudeep.holla@arm.com>
Acked-by: default avatarViresh Kumar <viresh.kumar@linaro.org>
Reviewed-by: default avatarStephen Boyd <sboyd@codeaurora.org>
Signed-off-by: default avatarRafael J. Wysocki <rafael.j.wysocki@intel.com>
parent ddbb74bc
...@@ -1845,21 +1845,11 @@ struct srcu_notifier_head *dev_pm_opp_get_notifier(struct device *dev) ...@@ -1845,21 +1845,11 @@ struct srcu_notifier_head *dev_pm_opp_get_notifier(struct device *dev)
} }
EXPORT_SYMBOL_GPL(dev_pm_opp_get_notifier); EXPORT_SYMBOL_GPL(dev_pm_opp_get_notifier);
#ifdef CONFIG_OF /*
/** * Free OPPs either created using static entries present in DT or even the
* dev_pm_opp_of_remove_table() - Free OPP table entries created from static DT * dynamically added entries based on remove_all param.
* entries
* @dev: device pointer used to lookup OPP table.
*
* Free OPPs created using static entries present in DT.
*
* Locking: The internal opp_table and opp structures are RCU protected.
* Hence this function indirectly uses RCU updater strategy with mutex locks
* to keep the integrity of the internal data structures. Callers should ensure
* that this function is *NOT* called under RCU protection or in contexts where
* mutex cannot be locked.
*/ */
void dev_pm_opp_of_remove_table(struct device *dev) static void _dev_pm_opp_remove_table(struct device *dev, bool remove_all)
{ {
struct opp_table *opp_table; struct opp_table *opp_table;
struct dev_pm_opp *opp, *tmp; struct dev_pm_opp *opp, *tmp;
...@@ -1884,7 +1874,7 @@ void dev_pm_opp_of_remove_table(struct device *dev) ...@@ -1884,7 +1874,7 @@ void dev_pm_opp_of_remove_table(struct device *dev)
if (list_is_singular(&opp_table->dev_list)) { if (list_is_singular(&opp_table->dev_list)) {
/* Free static OPPs */ /* Free static OPPs */
list_for_each_entry_safe(opp, tmp, &opp_table->opp_list, node) { list_for_each_entry_safe(opp, tmp, &opp_table->opp_list, node) {
if (!opp->dynamic) if (remove_all || !opp->dynamic)
_opp_remove(opp_table, opp, true); _opp_remove(opp_table, opp, true);
} }
} else { } else {
...@@ -1894,6 +1884,44 @@ void dev_pm_opp_of_remove_table(struct device *dev) ...@@ -1894,6 +1884,44 @@ void dev_pm_opp_of_remove_table(struct device *dev)
unlock: unlock:
mutex_unlock(&opp_table_lock); mutex_unlock(&opp_table_lock);
} }
/**
* dev_pm_opp_remove_table() - Free all OPPs associated with the device
* @dev: device pointer used to lookup OPP table.
*
* Free both OPPs created using static entries present in DT and the
* dynamically added entries.
*
* Locking: The internal opp_table and opp structures are RCU protected.
* Hence this function indirectly uses RCU updater strategy with mutex locks
* to keep the integrity of the internal data structures. Callers should ensure
* that this function is *NOT* called under RCU protection or in contexts where
* mutex cannot be locked.
*/
void dev_pm_opp_remove_table(struct device *dev)
{
_dev_pm_opp_remove_table(dev, true);
}
EXPORT_SYMBOL_GPL(dev_pm_opp_remove_table);
#ifdef CONFIG_OF
/**
* dev_pm_opp_of_remove_table() - Free OPP table entries created from static DT
* entries
* @dev: device pointer used to lookup OPP table.
*
* Free OPPs created using static entries present in DT.
*
* Locking: The internal opp_table and opp structures are RCU protected.
* Hence this function indirectly uses RCU updater strategy with mutex locks
* to keep the integrity of the internal data structures. Callers should ensure
* that this function is *NOT* called under RCU protection or in contexts where
* mutex cannot be locked.
*/
void dev_pm_opp_of_remove_table(struct device *dev)
{
_dev_pm_opp_remove_table(dev, false);
}
EXPORT_SYMBOL_GPL(dev_pm_opp_of_remove_table); EXPORT_SYMBOL_GPL(dev_pm_opp_of_remove_table);
/* Returns opp descriptor node for a device, caller must do of_node_put() */ /* Returns opp descriptor node for a device, caller must do of_node_put() */
......
...@@ -119,20 +119,8 @@ void dev_pm_opp_free_cpufreq_table(struct device *dev, ...@@ -119,20 +119,8 @@ void dev_pm_opp_free_cpufreq_table(struct device *dev,
EXPORT_SYMBOL_GPL(dev_pm_opp_free_cpufreq_table); EXPORT_SYMBOL_GPL(dev_pm_opp_free_cpufreq_table);
#endif /* CONFIG_CPU_FREQ */ #endif /* CONFIG_CPU_FREQ */
#ifdef CONFIG_OF static void
/** _dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask, bool of)
* dev_pm_opp_of_cpumask_remove_table() - Removes OPP table for @cpumask
* @cpumask: cpumask for which OPP table needs to be removed
*
* This removes the OPP tables for CPUs present in the @cpumask.
*
* Locking: The internal opp_table and opp structures are RCU protected.
* Hence this function internally uses RCU updater strategy with mutex locks
* to keep the integrity of the internal data structures. Callers should ensure
* that this function is *NOT* called under RCU protection or in contexts where
* mutex cannot be locked.
*/
void dev_pm_opp_of_cpumask_remove_table(const struct cpumask *cpumask)
{ {
struct device *cpu_dev; struct device *cpu_dev;
int cpu; int cpu;
...@@ -147,9 +135,51 @@ void dev_pm_opp_of_cpumask_remove_table(const struct cpumask *cpumask) ...@@ -147,9 +135,51 @@ void dev_pm_opp_of_cpumask_remove_table(const struct cpumask *cpumask)
continue; continue;
} }
if (of)
dev_pm_opp_of_remove_table(cpu_dev); dev_pm_opp_of_remove_table(cpu_dev);
else
dev_pm_opp_remove_table(cpu_dev);
} }
} }
/**
* dev_pm_opp_cpumask_remove_table() - Removes OPP table for @cpumask
* @cpumask: cpumask for which OPP table needs to be removed
*
* This removes the OPP tables for CPUs present in the @cpumask.
* This should be used to remove all the OPPs entries associated with
* the cpus in @cpumask.
*
* Locking: The internal opp_table and opp structures are RCU protected.
* Hence this function internally uses RCU updater strategy with mutex locks
* to keep the integrity of the internal data structures. Callers should ensure
* that this function is *NOT* called under RCU protection or in contexts where
* mutex cannot be locked.
*/
void dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask)
{
_dev_pm_opp_cpumask_remove_table(cpumask, false);
}
EXPORT_SYMBOL_GPL(dev_pm_opp_cpumask_remove_table);
#ifdef CONFIG_OF
/**
* dev_pm_opp_of_cpumask_remove_table() - Removes OPP table for @cpumask
* @cpumask: cpumask for which OPP table needs to be removed
*
* This removes the OPP tables for CPUs present in the @cpumask.
* This should be used only to remove static entries created from DT.
*
* Locking: The internal opp_table and opp structures are RCU protected.
* Hence this function internally uses RCU updater strategy with mutex locks
* to keep the integrity of the internal data structures. Callers should ensure
* that this function is *NOT* called under RCU protection or in contexts where
* mutex cannot be locked.
*/
void dev_pm_opp_of_cpumask_remove_table(const struct cpumask *cpumask)
{
_dev_pm_opp_cpumask_remove_table(cpumask, true);
}
EXPORT_SYMBOL_GPL(dev_pm_opp_of_cpumask_remove_table); EXPORT_SYMBOL_GPL(dev_pm_opp_of_cpumask_remove_table);
/** /**
......
...@@ -67,6 +67,8 @@ void dev_pm_opp_put_regulator(struct device *dev); ...@@ -67,6 +67,8 @@ void dev_pm_opp_put_regulator(struct device *dev);
int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq); int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq);
int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const struct cpumask *cpumask); int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const struct cpumask *cpumask);
int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask); int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask);
void dev_pm_opp_remove_table(struct device *dev);
void dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask);
#else #else
static inline unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp) static inline unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp)
{ {
...@@ -190,6 +192,14 @@ static inline int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpu ...@@ -190,6 +192,14 @@ static inline int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpu
return -EINVAL; return -EINVAL;
} }
static inline void dev_pm_opp_remove_table(struct device *dev)
{
}
static inline void dev_pm_opp_cpumask_remove_table(const struct cpumask *cpumask)
{
}
#endif /* CONFIG_PM_OPP */ #endif /* CONFIG_PM_OPP */
#if defined(CONFIG_PM_OPP) && defined(CONFIG_OF) #if defined(CONFIG_PM_OPP) && defined(CONFIG_OF)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment