@@ -16,6 +16,7 @@
#include <linux/err.h>
#include <linux/cpufreq.h>
+#include <linux/clk.h>
#include <plat/common.h>
@@ -38,21 +39,45 @@
*/
struct omap_opp_def {
char *hwmod_name;
+ char *vdd_name;
unsigned long freq;
unsigned long u_volt;
+ int (*set_rate)(struct device *dev, unsigned long rate);
+ unsigned long (*get_rate) (struct device *dev);
+
bool enabled;
};
+struct device_opp {
+ struct list_head node;
+ char *vdd_name;
+
+ struct omap_hwmod *oh;
+ struct device *dev;
+ struct omap_volt_domain *volt_domain;
+
+ struct list_head opp_list;
+ u32 opp_count;
+ u32 enabled_opp_count;
+
+ int (*set_rate)(struct device *dev, unsigned long rate);
+ unsigned long (*get_rate) (struct device *dev);
+};
+
/*
* Initialization wrapper used to define an OPP.
* To point at the end of a terminator of a list of OPPs,
* use OMAP_OPP_DEF(0, 0, 0)
*/
-#define OMAP_OPP_DEF(_hwmod_name, _enabled, _freq, _uv) \
+#define OMAP_OPP_DEF(_hwmod_name, _vdd_name, _set_rate, _get_rate, \
+ _enabled, _freq, _uv) \
{ \
.hwmod_name = _hwmod_name, \
+ .vdd_name = _vdd_name, \
+ .set_rate = _set_rate, \
+ .get_rate = _get_rate, \
.enabled = _enabled, \
.freq = _freq, \
.u_volt = _uv, \
@@ -77,6 +102,8 @@ struct omap_opp *opp_find_freq_ceil(struct device *dev, unsigned long *freq);
struct omap_opp *opp_find_voltage(struct device *dev, unsigned long volt);
+struct device_opp *opp_find_dev_opp(struct device *dev);
+
int opp_add(const struct omap_opp_def *opp_def);
int opp_enable(struct omap_opp *opp);
@@ -89,6 +116,9 @@ u8 __deprecated opp_get_opp_id(struct omap_opp *opp);
void opp_init_cpufreq_table(struct device *dev,
struct cpufreq_frequency_table **table);
+
+struct device **opp_init_voltage_params(struct omap_volt_domain *volt_domain,
+ int *dev_count);
#else
static inline unsigned long opp_get_voltage(const struct omap_opp *opp)
{
@@ -124,6 +154,11 @@ static inline struct omap_opp *opp_find_freq_ceil(struct omap_opp *oppl,
return ERR_PTR(-EINVAL);
}
+static inline struct device_opp *opp_find_dev_opp(struct device *dev)
+{
+ return ERR_PTR(-EINVAL);
+}
+
static inline struct omap_opp *opp_add(struct omap_opp *oppl,
const struct omap_opp_def *opp_def)
{
@@ -22,6 +22,7 @@
#include <plat/opp_twl_tps.h>
#include <plat/opp.h>
#include <plat/omap_device.h>
+#include <plat/voltage.h>
/**
* struct omap_opp - OMAP OPP description structure
@@ -43,17 +44,6 @@ struct omap_opp {
struct device_opp *dev_opp; /* containing device_opp struct */
};
-struct device_opp {
- struct list_head node;
-
- struct omap_hwmod *oh;
- struct device *dev;
-
- struct list_head opp_list;
- u32 opp_count;
- u32 enabled_opp_count;
-};
-
static LIST_HEAD(dev_opp_list);
/**
@@ -330,6 +320,11 @@ struct omap_opp *opp_find_voltage(struct device *dev, unsigned long volt)
return opp;
}
+struct device_opp *opp_find_dev_opp(struct device *dev)
+{
+ return find_device_opp(dev);
+}
+
/* wrapper to reuse converting opp_def to opp struct */
static void omap_opp_populate(struct omap_opp *opp,
const struct omap_opp_def *opp_def)
@@ -385,6 +380,11 @@ int opp_add(const struct omap_opp_def *opp_def)
dev_opp->oh = oh;
dev_opp->dev = &oh->od->pdev.dev;
+ dev_opp->vdd_name = kzalloc(strlen(opp_def->vdd_name) + 1,
+ GFP_KERNEL);
+ strcpy(dev_opp->vdd_name, opp_def->vdd_name);
+ dev_opp->set_rate = opp_def->set_rate;
+ dev_opp->get_rate = opp_def->get_rate;
INIT_LIST_HEAD(&dev_opp->opp_list);
list_add(&dev_opp->node, &dev_opp_list);
@@ -511,3 +511,28 @@ void opp_init_cpufreq_table(struct device *dev,
*table = &freq_table[0];
}
+
+struct device **opp_init_voltage_params(struct omap_volt_domain *volt_domain,
+ int *dev_count)
+{
+ struct device_opp *dev_opp;
+ struct device **dev_list;
+ int count = 0, i = 0;
+
+ list_for_each_entry(dev_opp, &dev_opp_list, node) {
+ if (!strcmp(dev_opp->vdd_name, volt_domain->name)) {
+ dev_opp->volt_domain = volt_domain;
+ count++;
+ }
+ }
+
+ dev_list = kzalloc(sizeof(struct device *) * count, GFP_KERNEL);
+
+ list_for_each_entry(dev_opp, &dev_opp_list, node) {
+ if (dev_opp->volt_domain == volt_domain)
+ dev_list[i++] = dev_opp->dev;
+ }
+
+ *dev_count = count;
+ return dev_list;
+}