@@ -87,10 +87,40 @@ struct opp_table *_find_opp_table(struct device *dev)
mutex_unlock(&opp_table_lock);
return opp_table;
}
+/**
+ * _find_opp_table() - find device struct using opp_table pointer
+ *
+ * OPP table must be exclusive: not be shared between devices.
+ */
+struct device *dev_pm_opp_table_get_device(struct opp_table *opp_table)
+{
+ struct opp_device *opp_dev;
+ struct device *dev = ERR_PTR(-EINVAL);
+ int opp_dev_cnt = 0;
+
+ mutex_lock(&opp_table->lock);
+
+ /* OPP table must not be shared: only one device */
+ if (opp_table->shared_opp != OPP_TABLE_ACCESS_EXCLUSIVE)
+ goto out;
+ list_for_each_entry(opp_dev, &opp_table->dev_list, node)
+ opp_dev_cnt++;
+ if (opp_dev_cnt != 1)
+ goto out;
+
+ opp_dev = list_first_entry(&opp_table->dev_list, struct opp_device, node);
+ dev = opp_dev->dev;
+
+out:
+ mutex_unlock(&opp_table->lock);
+ return dev;
+}
+EXPORT_SYMBOL_GPL(dev_pm_opp_table_get_device);
+
/**
* dev_pm_opp_get_voltage() - Gets the voltage corresponding to an opp
* @opp: opp for which voltage has to be returned for
*
* Return: voltage in micro volt corresponding to the opp, else
@@ -76,10 +76,11 @@ struct dev_pm_set_opp_data {
#if defined(CONFIG_PM_OPP)
struct opp_table *dev_pm_opp_get_opp_table(struct device *dev);
struct opp_table *dev_pm_opp_get_opp_table_indexed(struct device *dev, int index);
void dev_pm_opp_put_opp_table(struct opp_table *opp_table);
+struct device *dev_pm_opp_table_get_device(struct opp_table *opp_table);
unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp);
unsigned long dev_pm_opp_get_freq(struct dev_pm_opp *opp);
@@ -149,10 +150,15 @@ static inline struct opp_table *dev_pm_opp_get_opp_table_indexed(struct device *
return ERR_PTR(-ENOTSUPP);
}
static inline void dev_pm_opp_put_opp_table(struct opp_table *opp_table) {}
+struct struct device *dev_pm_opp_table_get_device(struct opp_table *opp_table)
+{
+ return ERR_PTR(-ENOTSUPP);
+}
+
static inline unsigned long dev_pm_opp_get_voltage(struct dev_pm_opp *opp)
{
return 0;
}
This API is the opposite of dev_pm_opp_get_opp_table. OPP tables can be shared between devices but this ambiguity can be handled by returning an error if opp table is not exclusive. This can used for fetching the device pointed to by "required-opps". Signed-off-by: Leonard Crestez <leonard.crestez@nxp.com> --- drivers/opp/core.c | 30 ++++++++++++++++++++++++++++++ include/linux/pm_opp.h | 6 ++++++ 2 files changed, 36 insertions(+)