aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@linaro.org>2017-10-11 03:24:15 -0400
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2017-10-13 18:54:41 -0400
commitb6aa98364f842f943495408895627702ad7ad44b (patch)
treef453c5d9b6483239e3f411c2e210914c0a3e8089
parent009acd196fc860045bf7b2c3f5812f0f5efb2782 (diff)
PM / OPP: Add dev_pm_opp_{un}register_get_pstate_helper()
This adds the dev_pm_opp_{un}register_get_pstate_helper() helper routines which will be used to set the get_pstate() callback for a device. This callback will be later called internally by the OPP core to get performance state corresponding to an OPP. This is required temporarily until the time we have proper DT bindings to include the performance state information. Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
-rw-r--r--drivers/opp/core.c78
-rw-r--r--drivers/opp/opp.h2
-rw-r--r--include/linux/pm_opp.h10
3 files changed, 90 insertions, 0 deletions
diff --git a/drivers/opp/core.c b/drivers/opp/core.c
index 0ce8069d6843..92fa94a6dcc1 100644
--- a/drivers/opp/core.c
+++ b/drivers/opp/core.c
@@ -1036,6 +1036,9 @@ int _opp_add(struct device *dev, struct dev_pm_opp *new_opp,
1036 return ret; 1036 return ret;
1037 } 1037 }
1038 1038
1039 if (opp_table->get_pstate)
1040 new_opp->pstate = opp_table->get_pstate(dev, new_opp->rate);
1041
1039 list_add(&new_opp->node, head); 1042 list_add(&new_opp->node, head);
1040 mutex_unlock(&opp_table->lock); 1043 mutex_unlock(&opp_table->lock);
1041 1044
@@ -1548,6 +1551,81 @@ void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table)
1548EXPORT_SYMBOL_GPL(dev_pm_opp_unregister_set_opp_helper); 1551EXPORT_SYMBOL_GPL(dev_pm_opp_unregister_set_opp_helper);
1549 1552
1550/** 1553/**
1554 * dev_pm_opp_register_get_pstate_helper() - Register get_pstate() helper.
1555 * @dev: Device for which the helper is getting registered.
1556 * @get_pstate: Helper.
1557 *
1558 * TODO: Remove this callback after the same information is available via Device
1559 * Tree.
1560 *
1561 * This allows a platform to initialize the performance states of individual
1562 * OPPs for its devices, until we get similar information directly from DT.
1563 *
1564 * This must be called before the OPPs are initialized for the device.
1565 */
1566struct opp_table *dev_pm_opp_register_get_pstate_helper(struct device *dev,
1567 int (*get_pstate)(struct device *dev, unsigned long rate))
1568{
1569 struct opp_table *opp_table;
1570 int ret;
1571
1572 if (!get_pstate)
1573 return ERR_PTR(-EINVAL);
1574
1575 opp_table = dev_pm_opp_get_opp_table(dev);
1576 if (!opp_table)
1577 return ERR_PTR(-ENOMEM);
1578
1579 /* This should be called before OPPs are initialized */
1580 if (WARN_ON(!list_empty(&opp_table->opp_list))) {
1581 ret = -EBUSY;
1582 goto err;
1583 }
1584
1585 /* Already have genpd_performance_state set */
1586 if (WARN_ON(opp_table->genpd_performance_state)) {
1587 ret = -EBUSY;
1588 goto err;
1589 }
1590
1591 opp_table->genpd_performance_state = true;
1592 opp_table->get_pstate = get_pstate;
1593
1594 return opp_table;
1595
1596err:
1597 dev_pm_opp_put_opp_table(opp_table);
1598
1599 return ERR_PTR(ret);
1600}
1601EXPORT_SYMBOL_GPL(dev_pm_opp_register_get_pstate_helper);
1602
1603/**
1604 * dev_pm_opp_unregister_get_pstate_helper() - Releases resources blocked for
1605 * get_pstate() helper
1606 * @opp_table: OPP table returned from dev_pm_opp_register_get_pstate_helper().
1607 *
1608 * Release resources blocked for platform specific get_pstate() helper.
1609 */
1610void dev_pm_opp_unregister_get_pstate_helper(struct opp_table *opp_table)
1611{
1612 if (!opp_table->genpd_performance_state) {
1613 pr_err("%s: Doesn't have performance states set\n",
1614 __func__);
1615 return;
1616 }
1617
1618 /* Make sure there are no concurrent readers while updating opp_table */
1619 WARN_ON(!list_empty(&opp_table->opp_list));
1620
1621 opp_table->genpd_performance_state = false;
1622 opp_table->get_pstate = NULL;
1623
1624 dev_pm_opp_put_opp_table(opp_table);
1625}
1626EXPORT_SYMBOL_GPL(dev_pm_opp_unregister_get_pstate_helper);
1627
1628/**
1551 * dev_pm_opp_add() - Add an OPP table from a table definitions 1629 * dev_pm_opp_add() - Add an OPP table from a table definitions
1552 * @dev: device for which we do this operation 1630 * @dev: device for which we do this operation
1553 * @freq: Frequency in Hz for this OPP 1631 * @freq: Frequency in Hz for this OPP
diff --git a/drivers/opp/opp.h b/drivers/opp/opp.h
index e8f767ab5814..4d00061648a3 100644
--- a/drivers/opp/opp.h
+++ b/drivers/opp/opp.h
@@ -140,6 +140,7 @@ enum opp_table_access {
140 * @genpd_performance_state: Device's power domain support performance state. 140 * @genpd_performance_state: Device's power domain support performance state.
141 * @set_opp: Platform specific set_opp callback 141 * @set_opp: Platform specific set_opp callback
142 * @set_opp_data: Data to be passed to set_opp callback 142 * @set_opp_data: Data to be passed to set_opp callback
143 * @get_pstate: Platform specific get_pstate callback
143 * @dentry: debugfs dentry pointer of the real device directory (not links). 144 * @dentry: debugfs dentry pointer of the real device directory (not links).
144 * @dentry_name: Name of the real dentry. 145 * @dentry_name: Name of the real dentry.
145 * 146 *
@@ -177,6 +178,7 @@ struct opp_table {
177 178
178 int (*set_opp)(struct dev_pm_set_opp_data *data); 179 int (*set_opp)(struct dev_pm_set_opp_data *data);
179 struct dev_pm_set_opp_data *set_opp_data; 180 struct dev_pm_set_opp_data *set_opp_data;
181 int (*get_pstate)(struct device *dev, unsigned long rate);
180 182
181#ifdef CONFIG_DEBUG_FS 183#ifdef CONFIG_DEBUG_FS
182 struct dentry *dentry; 184 struct dentry *dentry;
diff --git a/include/linux/pm_opp.h b/include/linux/pm_opp.h
index 849d21dc4ca7..6c2d2e88f066 100644
--- a/include/linux/pm_opp.h
+++ b/include/linux/pm_opp.h
@@ -125,6 +125,8 @@ struct opp_table *dev_pm_opp_set_clkname(struct device *dev, const char * name);
125void dev_pm_opp_put_clkname(struct opp_table *opp_table); 125void dev_pm_opp_put_clkname(struct opp_table *opp_table);
126struct opp_table *dev_pm_opp_register_set_opp_helper(struct device *dev, int (*set_opp)(struct dev_pm_set_opp_data *data)); 126struct opp_table *dev_pm_opp_register_set_opp_helper(struct device *dev, int (*set_opp)(struct dev_pm_set_opp_data *data));
127void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table); 127void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table);
128struct opp_table *dev_pm_opp_register_get_pstate_helper(struct device *dev, int (*get_pstate)(struct device *dev, unsigned long rate));
129void dev_pm_opp_unregister_get_pstate_helper(struct opp_table *opp_table);
128int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq); 130int dev_pm_opp_set_rate(struct device *dev, unsigned long target_freq);
129int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const struct cpumask *cpumask); 131int dev_pm_opp_set_sharing_cpus(struct device *cpu_dev, const struct cpumask *cpumask);
130int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask); 132int dev_pm_opp_get_sharing_cpus(struct device *cpu_dev, struct cpumask *cpumask);
@@ -245,6 +247,14 @@ static inline struct opp_table *dev_pm_opp_register_set_opp_helper(struct device
245 247
246static inline void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table) {} 248static inline void dev_pm_opp_unregister_set_opp_helper(struct opp_table *opp_table) {}
247 249
250static inline struct opp_table *dev_pm_opp_register_get_pstate_helper(struct device *dev,
251 int (*get_pstate)(struct device *dev, unsigned long rate))
252{
253 return ERR_PTR(-ENOTSUPP);
254}
255
256static inline void dev_pm_opp_unregister_get_pstate_helper(struct opp_table *opp_table) {}
257
248static inline struct opp_table *dev_pm_opp_set_prop_name(struct device *dev, const char *name) 258static inline struct opp_table *dev_pm_opp_set_prop_name(struct device *dev, const char *name)
249{ 259{
250 return ERR_PTR(-ENOTSUPP); 260 return ERR_PTR(-ENOTSUPP);