Re: [RFC 3/7] OMAP: Introduce voltage domain pointer and device specific set rate and get rate in device opp structures.

2010-08-04 Thread Kevin Hilman
Gopinath, Thara th...@ti.com writes:

 @@ -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);

Since this is user-defined data/string, should probably have a max
strlen and use strncpy.

 I did not get this. What is the problem with the strlen here ?

It's more of a paranoia issue than a technical issue.  I don't like
blindly using strlen on strings that are user-configurable.  I guess,
since they're coming from the OPP table, they're not terribly
configurable, so it's probably not a big deal.

However, since opp_add() is already doing one kzalloc, I think it's
probably cleaner to just to make this field a fixed lenght and
then use strncpy():

#define VDD_NAME_LEN 8

struct device_opp {
   ...
   char vdd_name[VDD_NAME_LEN];
   ...
}

Kevin
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [RFC 3/7] OMAP: Introduce voltage domain pointer and device specific set rate and get rate in device opp structures.

2010-08-04 Thread Gopinath, Thara


-Original Message-
From: Kevin Hilman [mailto:khil...@deeprootsystems.com]
Sent: Thursday, August 05, 2010 2:36 AM
To: Gopinath, Thara
Cc: linux-omap@vger.kernel.org; p...@pwsan.com; Cousson, Benoit; Sripathy, 
Vishwanath; Sawant, Anand;
Basak, Partha
Subject: Re: [RFC 3/7] OMAP: Introduce voltage domain pointer and device 
specific set rate and get
rate in device opp structures.

Gopinath, Thara th...@ti.com writes:

 @@ -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);

Since this is user-defined data/string, should probably have a max
strlen and use strncpy.

 I did not get this. What is the problem with the strlen here ?

It's more of a paranoia issue than a technical issue.  I don't like
blindly using strlen on strings that are user-configurable.  I guess,
since they're coming from the OPP table, they're not terribly
configurable, so it's probably not a big deal.

However, since opp_add() is already doing one kzalloc, I think it's
probably cleaner to just to make this field a fixed lenght and
then use strncpy():

#define VDD_NAME_LEN 8

struct device_opp {
   ...
   char vdd_name[VDD_NAME_LEN];
   ...
}

Gotcha! Will incorporate in V2.

Regards
Thara
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC 3/7] OMAP: Introduce voltage domain pointer and device specific set rate and get rate in device opp structures.

2010-08-03 Thread Kevin Hilman
Thara Gopinath th...@ti.com writes:

 This patch extends the device opp structure to contain
 info about the voltage domain to which the device belongs to
 and to contain pointers to scale the operating rate of the
 device. This patch also adds an API in the opp layer that
 can be used by the voltage layer to get a list of all the
 scalable devices belonging to a particular voltage domain.
 This API is to be typically called only once by the voltage
 layer per voltage domain instance and the device list should
 be stored. This approach makes it easy during dvfs to scale
 all the devices associated with a voltage domain and then
 scale the voltage domain.

 Signed-off-by: Thara Gopinath th...@ti.com
 ---
  arch/arm/plat-omap/include/plat/opp.h |   37 +-
  arch/arm/plat-omap/opp.c  |   47 +---
  2 files changed, 72 insertions(+), 12 deletions(-)

 diff --git a/arch/arm/plat-omap/include/plat/opp.h 
 b/arch/arm/plat-omap/include/plat/opp.h
 index 893731f..15e1e70 100644
 --- a/arch/arm/plat-omap/include/plat/opp.h
 +++ b/arch/arm/plat-omap/include/plat/opp.h
 @@ -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);
 +};

I don't like moving the definition of this struct out.  This exposes the
implmentation details of the OPP layer that are subject to change.

A quick glance shows you need to access the volt_domain field and the
new function pointers.

The voltage domain should be part of the hwmod as suggested by Benoit,
and an API created to get the voltage domain from the hwmod.

For the get/set rate functions, maybe new OPP layer API should be
created access those functions.  opp_[get|set]_rate()?


  /*
   * 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)
  {
 diff --git a/arch/arm/plat-omap/opp.c b/arch/arm/plat-omap/opp.c
 index 070ff5b..9bc53e8 100644
 --- a/arch/arm/plat-omap/opp.c
 +++ b/arch/arm/plat-omap/opp.c
 @@ -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;
 -};
 -
  

RE: [RFC 3/7] OMAP: Introduce voltage domain pointer and device specific set rate and get rate in device opp structures.

2010-08-03 Thread Gopinath, Thara


-Original Message-
From: Cousson, Benoit
Sent: Monday, August 02, 2010 5:41 PM
To: Gopinath, Thara
Cc: linux-omap@vger.kernel.org; khil...@deeprootsystems.com; p...@pwsan.com; 
Sripathy, Vishwanath;
Sawant, Anand; Basak, Partha
Subject: Re: [RFC 3/7] OMAP: Introduce voltage domain pointer and device 
specific set rate and get
rate in device opp structures.

Hi Thara,

On 7/2/2010 12:18 PM, Gopinath, Thara wrote:
 This patch extends the device opp structure to contain
 info about the voltage domain to which the device belongs to
 and to contain pointers to scale the operating rate of the
 device. This patch also adds an API in the opp layer that
 can be used by the voltage layer to get a list of all the
 scalable devices belonging to a particular voltage domain.
 This API is to be typically called only once by the voltage
 layer per voltage domain instance and the device list should
 be stored. This approach makes it easy during dvfs to scale
 all the devices associated with a voltage domain and then
 scale the voltage domain.

 Signed-off-by: Thara Gopinathth...@ti.com
 ---
   arch/arm/plat-omap/include/plat/opp.h |   37 +-
   arch/arm/plat-omap/opp.c  |   47 
 +---
   2 files changed, 72 insertions(+), 12 deletions(-)

 diff --git a/arch/arm/plat-omap/include/plat/opp.h 
 b/arch/arm/plat-omap/include/plat/opp.h
 index 893731f..15e1e70 100644
 --- a/arch/arm/plat-omap/include/plat/opp.h
 +++ b/arch/arm/plat-omap/include/plat/opp.h
 @@ -16,6 +16,7 @@

   #includelinux/err.h
   #includelinux/cpufreq.h
 +#includelinux/clk.h

   #includeplat/common.h

 @@ -38,21 +39,45 @@
*/
   struct omap_opp_def {
 char *hwmod_name;
 +   char *vdd_name;

vdd should be an attribute of hwmod. For one hwmod in a soc we will
always have the same vdd.
That will avoid to duplicate information and to have to populate that in
each OPP entry (cf patch 6).
I also do not like the duplication of info in the opp tables. I was not sure
about introducing this in the hwmod layer. I could surely do this for the
vdd name and voltage domain pointer.


 unsigned long freq;
 unsigned long u_volt;

 +   int (*set_rate)(struct device *dev, unsigned long rate);
 +   unsigned long (*get_rate) (struct device *dev);

We might already discussed that, but why should we store that per OPP?
Cannot we store that per device?

Paul had concerns regarding this. These are not h/w or h/w interface related 
info
in any manner. One good point is that even though these pointers are duplicated 
in
the init opp tables, during init the device opp tables are built and only one 
copy
is maintained. But I agree this does not look too very good.

Regards
Thara
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


RE: [RFC 3/7] OMAP: Introduce voltage domain pointer and device specific set rate and get rate in device opp structures.

2010-08-03 Thread Gopinath, Thara


-Original Message-
From: Kevin Hilman [mailto:khil...@deeprootsystems.com]
Sent: Wednesday, August 04, 2010 6:03 AM
To: Gopinath, Thara
Cc: linux-omap@vger.kernel.org; p...@pwsan.com; Cousson, Benoit; Sripathy, 
Vishwanath; Sawant, Anand;
Basak, Partha
Subject: Re: [RFC 3/7] OMAP: Introduce voltage domain pointer and device 
specific set rate and get
rate in device opp structures.

Thara Gopinath th...@ti.com writes:

 This patch extends the device opp structure to contain
 info about the voltage domain to which the device belongs to
 and to contain pointers to scale the operating rate of the
 device. This patch also adds an API in the opp layer that
 can be used by the voltage layer to get a list of all the
 scalable devices belonging to a particular voltage domain.
 This API is to be typically called only once by the voltage
 layer per voltage domain instance and the device list should
 be stored. This approach makes it easy during dvfs to scale
 all the devices associated with a voltage domain and then
 scale the voltage domain.

 Signed-off-by: Thara Gopinath th...@ti.com
 ---
  arch/arm/plat-omap/include/plat/opp.h |   37 +-
  arch/arm/plat-omap/opp.c  |   47 
 +---
  2 files changed, 72 insertions(+), 12 deletions(-)

 diff --git a/arch/arm/plat-omap/include/plat/opp.h 
 b/arch/arm/plat-omap/include/plat/opp.h
 index 893731f..15e1e70 100644
 --- a/arch/arm/plat-omap/include/plat/opp.h
 +++ b/arch/arm/plat-omap/include/plat/opp.h
 @@ -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);
 +};

I don't like moving the definition of this struct out.  This exposes the
implmentation details of the OPP layer that are subject to change.

A quick glance shows you need to access the volt_domain field and the
new function pointers.

The voltage domain should be part of the hwmod as suggested by Benoit,
and an API created to get the voltage domain from the hwmod.

For the get/set rate functions, maybe new OPP layer API should be
created access those functions.  opp_[get|set]_rate()?

Yes I could do this.



  /*
   * 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)
  {
 diff --git a/arch/arm/plat-omap/opp.c b/arch/arm/plat-omap/opp.c
 index 070ff5b..9bc53e8 100644
 --- a/arch/arm/plat-omap/opp.c
 +++ b/arch/arm/plat-omap/opp.c
 @@ -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 

Re: [RFC 3/7] OMAP: Introduce voltage domain pointer and device specific set rate and get rate in device opp structures.

2010-08-02 Thread Cousson, Benoit

Hi Thara,

On 7/2/2010 12:18 PM, Gopinath, Thara wrote:

This patch extends the device opp structure to contain
info about the voltage domain to which the device belongs to
and to contain pointers to scale the operating rate of the
device. This patch also adds an API in the opp layer that
can be used by the voltage layer to get a list of all the
scalable devices belonging to a particular voltage domain.
This API is to be typically called only once by the voltage
layer per voltage domain instance and the device list should
be stored. This approach makes it easy during dvfs to scale
all the devices associated with a voltage domain and then
scale the voltage domain.

Signed-off-by: Thara Gopinathth...@ti.com
---
  arch/arm/plat-omap/include/plat/opp.h |   37 +-
  arch/arm/plat-omap/opp.c  |   47 +---
  2 files changed, 72 insertions(+), 12 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/opp.h 
b/arch/arm/plat-omap/include/plat/opp.h
index 893731f..15e1e70 100644
--- a/arch/arm/plat-omap/include/plat/opp.h
+++ b/arch/arm/plat-omap/include/plat/opp.h
@@ -16,6 +16,7 @@

  #includelinux/err.h
  #includelinux/cpufreq.h
+#includelinux/clk.h

  #includeplat/common.h

@@ -38,21 +39,45 @@
   */
  struct omap_opp_def {
char *hwmod_name;
+   char *vdd_name;


vdd should be an attribute of hwmod. For one hwmod in a soc we will 
always have the same vdd.
That will avoid to duplicate information and to have to populate that in 
each OPP entry (cf patch 6).




unsigned long freq;
unsigned long u_volt;

+   int (*set_rate)(struct device *dev, unsigned long rate);
+   unsigned long (*get_rate) (struct device *dev);


We might already discussed that, but why should we store that per OPP?
Cannot we store that per device?

Regards,
Benoit
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC 3/7] OMAP: Introduce voltage domain pointer and device specific set rate and get rate in device opp structures.

2010-07-12 Thread Thomas Petazzoni
Hello Thara,

On Fri,  2 Jul 2010 15:48:25 +0530
Thara Gopinath th...@ti.com wrote:

  #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;
  };

It looks strange to me that per-OPP methods are needed to set/get the
rate. These should only be needed at the device level, no ?

And indeed, in your patch 6/7, for every device, the same get/set rate
methods are used for all OPPs of a given device.

 +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);
 +};

I know this structure already exists, but do we really need a new
structure for this ? Couldn't these infos (OPP list, set/get rate
methods) be stored in an existing device-specific structure (omap_hwmod
for hardware-related things are omap_device for ~software-related
things) ?

For example, why aren't OPPs attached to the hwmod description of the
particular device ? These OPPs definitions really look like a
characteristic of a particular IP, don't they ?

Whatever choice is made, this structure probably needs a comment on top
of it explaining what it does, since the name isn't very obvious IMO.

Thanks!

Thomas
-- 
Thomas Petazzoni, Free Electrons
Kernel, drivers, real-time and embedded Linux
development, consulting, training and support.
http://free-electrons.com
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


Re: [RFC 3/7] OMAP: Introduce voltage domain pointer and device specific set rate and get rate in device opp structures.

2010-07-12 Thread Paul Walmsley
On Mon, 12 Jul 2010, Thomas Petazzoni wrote:

 I know this structure already exists, but do we really need a new
 structure for this ? Couldn't these infos (OPP list, set/get rate
 methods) be stored in an existing device-specific structure (omap_hwmod
 for hardware-related things are omap_device for ~software-related
 things) ?
 
 For example, why aren't OPPs attached to the hwmod description of the
 particular device ? These OPPs definitions really look like a
 characteristic of a particular IP, don't they ?

hwmod data is intended to be used for RTL-level data, e.g., data that is 
invariant of the underlying process technology.  OPP data can vary by the 
underlying fabrication process or per-die speed validation (e.g., 
speed-binning).  So I don't think it belongs in the hwmod data.


- Paul
--
To unsubscribe from this list: send the line unsubscribe linux-omap in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[RFC 3/7] OMAP: Introduce voltage domain pointer and device specific set rate and get rate in device opp structures.

2010-07-02 Thread Thara Gopinath
This patch extends the device opp structure to contain
info about the voltage domain to which the device belongs to
and to contain pointers to scale the operating rate of the
device. This patch also adds an API in the opp layer that
can be used by the voltage layer to get a list of all the
scalable devices belonging to a particular voltage domain.
This API is to be typically called only once by the voltage
layer per voltage domain instance and the device list should
be stored. This approach makes it easy during dvfs to scale
all the devices associated with a voltage domain and then
scale the voltage domain.

Signed-off-by: Thara Gopinath th...@ti.com
---
 arch/arm/plat-omap/include/plat/opp.h |   37 +-
 arch/arm/plat-omap/opp.c  |   47 +---
 2 files changed, 72 insertions(+), 12 deletions(-)

diff --git a/arch/arm/plat-omap/include/plat/opp.h 
b/arch/arm/plat-omap/include/plat/opp.h
index 893731f..15e1e70 100644
--- a/arch/arm/plat-omap/include/plat/opp.h
+++ b/arch/arm/plat-omap/include/plat/opp.h
@@ -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)
 {
diff --git a/arch/arm/plat-omap/opp.c b/arch/arm/plat-omap/opp.c
index 070ff5b..9bc53e8 100644
--- a/arch/arm/plat-omap/opp.c
+++ b/arch/arm/plat-omap/opp.c
@@ -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 =