aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorViresh Kumar <viresh.kumar@linaro.org>2014-11-25 05:34:18 -0500
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>2014-11-29 17:53:20 -0500
commit38393409da345cd48d94a0e74c7bbc3402742882 (patch)
treeacaf242fb38292ed5c4c401beb375126c40bb033
parenta7470db6fec481b14afea117846fce383671ba59 (diff)
PM / OPP mark OPPs as 'static' or 'dynamic'
Static OPPs are the ones created from Device Tree entries and dynamic are the ones created at runtime by calling dev_pm_opp_add(). There is a need to distinguish them as we need to free static OPPs from cpufreq drivers when they are removed. So, add another field 'dynamic' in 'struct dev_pm_opp' to keep this 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/base/power/opp.c59
1 files changed, 34 insertions, 25 deletions
diff --git a/drivers/base/power/opp.c b/drivers/base/power/opp.c
index a333e2ef5cb2..b249b0127eff 100644
--- a/drivers/base/power/opp.c
+++ b/drivers/base/power/opp.c
@@ -49,6 +49,7 @@
49 * are protected by the dev_opp_list_lock for integrity. 49 * are protected by the dev_opp_list_lock for integrity.
50 * IMPORTANT: the opp nodes should be maintained in increasing 50 * IMPORTANT: the opp nodes should be maintained in increasing
51 * order. 51 * order.
52 * @dynamic: not-created from static DT entries.
52 * @available: true/false - marks if this OPP as available or not 53 * @available: true/false - marks if this OPP as available or not
53 * @rate: Frequency in hertz 54 * @rate: Frequency in hertz
54 * @u_volt: Nominal voltage in microvolts corresponding to this OPP 55 * @u_volt: Nominal voltage in microvolts corresponding to this OPP
@@ -61,6 +62,7 @@ struct dev_pm_opp {
61 struct list_head node; 62 struct list_head node;
62 63
63 bool available; 64 bool available;
65 bool dynamic;
64 unsigned long rate; 66 unsigned long rate;
65 unsigned long u_volt; 67 unsigned long u_volt;
66 68
@@ -378,30 +380,8 @@ struct dev_pm_opp *dev_pm_opp_find_freq_floor(struct device *dev,
378} 380}
379EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_floor); 381EXPORT_SYMBOL_GPL(dev_pm_opp_find_freq_floor);
380 382
381/** 383static int dev_pm_opp_add_dynamic(struct device *dev, unsigned long freq,
382 * dev_pm_opp_add() - Add an OPP table from a table definitions 384 unsigned long u_volt, bool dynamic)
383 * @dev: device for which we do this operation
384 * @freq: Frequency in Hz for this OPP
385 * @u_volt: Voltage in uVolts for this OPP
386 *
387 * This function adds an opp definition to the opp list and returns status.
388 * The opp is made available by default and it can be controlled using
389 * dev_pm_opp_enable/disable functions.
390 *
391 * Locking: The internal device_opp and opp structures are RCU protected.
392 * Hence this function internally uses RCU updater strategy with mutex locks
393 * to keep the integrity of the internal data structures. Callers should ensure
394 * that this function is *NOT* called under RCU protection or in contexts where
395 * mutex cannot be locked.
396 *
397 * Return:
398 * 0: On success OR
399 * Duplicate OPPs (both freq and volt are same) and opp->available
400 * -EEXIST: Freq are same and volt are different OR
401 * Duplicate OPPs (both freq and volt are same) and !opp->available
402 * -ENOMEM: Memory allocation failure
403 */
404int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt)
405{ 385{
406 struct device_opp *dev_opp = NULL; 386 struct device_opp *dev_opp = NULL;
407 struct dev_pm_opp *opp, *new_opp; 387 struct dev_pm_opp *opp, *new_opp;
@@ -422,6 +402,7 @@ int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt)
422 new_opp->rate = freq; 402 new_opp->rate = freq;
423 new_opp->u_volt = u_volt; 403 new_opp->u_volt = u_volt;
424 new_opp->available = true; 404 new_opp->available = true;
405 new_opp->dynamic = dynamic;
425 406
426 /* Check for existing list for 'dev' */ 407 /* Check for existing list for 'dev' */
427 dev_opp = find_device_opp(dev); 408 dev_opp = find_device_opp(dev);
@@ -487,6 +468,34 @@ list_add:
487 srcu_notifier_call_chain(&dev_opp->srcu_head, OPP_EVENT_ADD, new_opp); 468 srcu_notifier_call_chain(&dev_opp->srcu_head, OPP_EVENT_ADD, new_opp);
488 return 0; 469 return 0;
489} 470}
471
472/**
473 * dev_pm_opp_add() - Add an OPP table from a table definitions
474 * @dev: device for which we do this operation
475 * @freq: Frequency in Hz for this OPP
476 * @u_volt: Voltage in uVolts for this OPP
477 *
478 * This function adds an opp definition to the opp list and returns status.
479 * The opp is made available by default and it can be controlled using
480 * dev_pm_opp_enable/disable functions.
481 *
482 * Locking: The internal device_opp and opp structures are RCU protected.
483 * Hence this function internally uses RCU updater strategy with mutex locks
484 * to keep the integrity of the internal data structures. Callers should ensure
485 * that this function is *NOT* called under RCU protection or in contexts where
486 * mutex cannot be locked.
487 *
488 * Return:
489 * 0: On success OR
490 * Duplicate OPPs (both freq and volt are same) and opp->available
491 * -EEXIST: Freq are same and volt are different OR
492 * Duplicate OPPs (both freq and volt are same) and !opp->available
493 * -ENOMEM: Memory allocation failure
494 */
495int dev_pm_opp_add(struct device *dev, unsigned long freq, unsigned long u_volt)
496{
497 return dev_pm_opp_add_dynamic(dev, freq, u_volt, true);
498}
490EXPORT_SYMBOL_GPL(dev_pm_opp_add); 499EXPORT_SYMBOL_GPL(dev_pm_opp_add);
491 500
492/** 501/**
@@ -669,7 +678,7 @@ int of_init_opp_table(struct device *dev)
669 unsigned long freq = be32_to_cpup(val++) * 1000; 678 unsigned long freq = be32_to_cpup(val++) * 1000;
670 unsigned long volt = be32_to_cpup(val++); 679 unsigned long volt = be32_to_cpup(val++);
671 680
672 if (dev_pm_opp_add(dev, freq, volt)) 681 if (dev_pm_opp_add_dynamic(dev, freq, volt, false))
673 dev_warn(dev, "%s: Failed to add OPP %ld\n", 682 dev_warn(dev, "%s: Failed to add OPP %ld\n",
674 __func__, freq); 683 __func__, freq);
675 nr -= 2; 684 nr -= 2;