Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 328721
b: refs/heads/master
c: b496dfb
h: refs/heads/master
i:
  328719: 4731c16
v: v3
  • Loading branch information
Shawn Guo authored and Rafael J. Wysocki committed Sep 9, 2012
1 parent 78e6c27 commit 5a691a4
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: ec971ea5f2426a0bf9d5cca9a103743918c12978
refs/heads/master: b496dfbc94ab86f970ef0167eaabe51f930aa5fb
25 changes: 25 additions & 0 deletions trunk/Documentation/devicetree/bindings/power/opp.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
* Generic OPP Interface

SoCs have a standard set of tuples consisting of frequency and
voltage pairs that the device will support per voltage domain. These
are called Operating Performance Points or OPPs.

Properties:
- operating-points: An array of 2-tuples items, and each item consists
of frequency and voltage like <freq-kHz vol-uV>.
freq: clock frequency in kHz
vol: voltage in microvolt

Examples:

cpu@0 {
compatible = "arm,cortex-a9";
reg = <0>;
next-level-cache = <&L2>;
operating-points = <
/* kHz uV */
792000 1100000
396000 950000
198000 850000
>;
};
47 changes: 47 additions & 0 deletions trunk/drivers/base/power/opp.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <linux/rculist.h>
#include <linux/rcupdate.h>
#include <linux/opp.h>
#include <linux/of.h>

/*
* Internal data structure organization with the OPP layer library is as
Expand Down Expand Up @@ -674,3 +675,49 @@ struct srcu_notifier_head *opp_get_notifier(struct device *dev)

return &dev_opp->head;
}

#ifdef CONFIG_OF
/**
* of_init_opp_table() - Initialize opp table from device tree
* @dev: device pointer used to lookup device OPPs.
*
* Register the initial OPP table with the OPP library for given device.
*/
int of_init_opp_table(struct device *dev)
{
const struct property *prop;
const __be32 *val;
int nr;

prop = of_find_property(dev->of_node, "operating-points", NULL);
if (!prop)
return -ENODEV;
if (!prop->value)
return -ENODATA;

/*
* Each OPP is a set of tuples consisting of frequency and
* voltage like <freq-kHz vol-uV>.
*/
nr = prop->length / sizeof(u32);
if (nr % 2) {
dev_err(dev, "%s: Invalid OPP list\n", __func__);
return -EINVAL;
}

val = prop->value;
while (nr) {
unsigned long freq = be32_to_cpup(val++) * 1000;
unsigned long volt = be32_to_cpup(val++);

if (opp_add(dev, freq, volt)) {
dev_warn(dev, "%s: Failed to add OPP %ld\n",
__func__, freq);
continue;
}
nr -= 2;
}

return 0;
}
#endif
8 changes: 8 additions & 0 deletions trunk/include/linux/opp.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,14 @@ int opp_disable(struct device *dev, unsigned long freq);

struct srcu_notifier_head *opp_get_notifier(struct device *dev);

#ifdef CONFIG_OF
int of_init_opp_table(struct device *dev);
#else
static inline int of_init_opp_table(struct device *dev)
{
return -EINVAL;
}
#endif /* CONFIG_OF */
#else
static inline unsigned long opp_get_voltage(struct opp *opp)
{
Expand Down

0 comments on commit 5a691a4

Please sign in to comment.