public inbox for linux-omap@vger.kernel.org
 help / color / mirror / Atom feed
* [PM-WIP-OPP][PATCH v4] omap: pm: Introducing enum for OPP types
@ 2010-01-28 20:40 Nishanth Menon
  2010-01-28 20:45 ` Nishanth Menon
  2010-02-04 19:36 ` Kevin Hilman
  0 siblings, 2 replies; 3+ messages in thread
From: Nishanth Menon @ 2010-01-28 20:40 UTC (permalink / raw)
  To: linux-omap
  Cc: Romit Dasgupta, Benoit Cousson, Eduardo Valentin, Kevin Hilman,
	Madhusudhan Chikkature Rajashekar, Nishanth Menon, Paul Walmsley,
	Sanjeev Premi, Santosh Shilimkar,
	Sergio Alberto Aguirre Rodriguez, Tero Kristo, Thara Gopinath,
	Vishwanath Sripathy

From: Romit Dasgupta <romit@ti.com>

Using omap_opp * to refer to domain types entails opp implementation
into maintaining pointers outside the opp layer.

Since all we need is an identifier to a specific domain for
query/operational purposes, we introduce enum for identifying OPP
types instead of using opp layer's internal data structure pointer.

Currently, OMAP3 is the only silicon supporting the OPP layer, hence
mpu_opps, l3_opps and dsp_opps are deprecated and replaced with
OPP_MPU, OPP_L3 and OPP_DSP respectively.

Cc: Benoit Cousson <b-cousson@ti.com>
Cc: Eduardo Valentin <eduardo.valentin@nokia.com>
Cc: Kevin Hilman <khilman@deeprootsystems.com>
Cc: Madhusudhan Chikkature Rajashekar <madhu.cr@ti.com>
Cc: Nishanth Menon <nm@ti.com>
Cc: Paul Walmsley <paul@pwsan.com>
Cc: Sanjeev Premi <premi@ti.com>
Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
Cc: Sergio Alberto Aguirre Rodriguez <saaguirre@ti.com>
Cc: Tero Kristo <Tero.Kristo@nokia.com>
Cc: Thara Gopinath <thara@ti.com>
Cc: Vishwanath Sripathy <vishwanath.bs@ti.com>

Signed-off-by: Romit Dasgupta <romit@ti.com>

---
Synopsys of changes:
Rev 1: http://marc.info/?t=126330004800004&r=1&w=2
Rev 2: http://marc.info/?t=126355341800003&r=1&w=2
Rev 3: http://marc.info/?t=126408156100006&r=1&w=2
Rev 4 specific changes Vs Rev 3:
 * Multiple TI copyrights merged to a single one
 * Couple of checkpatch warnings for multiple assignments fixed
 * Cpufreq rates were reversed during initialization - fixed
 * Rebased to pm-wip-opp branch as requested for rev 3.

 arch/arm/mach-omap2/cpufreq34xx.c     |   15 +---
 arch/arm/mach-omap2/resource34xx.c    |   84 +++++++++------------
 arch/arm/mach-omap2/smartreflex.c     |   33 +++------
 arch/arm/plat-omap/common.c           |    6 --
 arch/arm/plat-omap/cpu-omap.c         |   12 ++--
 arch/arm/plat-omap/include/plat/opp.h |   61 ++++++++--------
 arch/arm/plat-omap/omap-pm-noop.c     |    4 -
 arch/arm/plat-omap/omap-pm-srf.c      |    4 -
 arch/arm/plat-omap/opp.c              |  129 ++++++++++++++++++++++-----------
 9 files changed, 174 insertions(+), 174 deletions(-)

diff --git a/arch/arm/mach-omap2/cpufreq34xx.c b/arch/arm/mach-omap2/cpufreq34xx.c
index 07873e8..209af2b 100644
--- a/arch/arm/mach-omap2/cpufreq34xx.c
+++ b/arch/arm/mach-omap2/cpufreq34xx.c
@@ -104,7 +104,6 @@ static struct omap_opp_def __initdata omap36xx_dsp_rate_table[] = {
 
 void __init omap3_pm_init_opp_table(void)
 {
-	int i;
 	struct omap_opp_def **omap3_opp_def_list;
 	struct omap_opp_def *omap34xx_opp_def_list[] = {
 		omap34xx_mpu_rate_table,
@@ -116,18 +115,12 @@ void __init omap3_pm_init_opp_table(void)
 		omap36xx_l3_rate_table,
 		omap36xx_dsp_rate_table
 	};
-	struct omap_opp **omap3_rate_tables[] = {
-		&mpu_opps,
-		&l3_opps,
-		&dsp_opps
-	};
 
 	omap3_opp_def_list = cpu_is_omap3630() ? omap36xx_opp_def_list :
 				omap34xx_opp_def_list;
-	for (i = 0; i < ARRAY_SIZE(omap3_rate_tables); i++) {
-		*omap3_rate_tables[i] = opp_init_list(omap3_opp_def_list[i]);
-		/* We dont want half configured system at the moment */
-		BUG_ON(IS_ERR(omap3_rate_tables[i]));
-	}
+
+	BUG_ON(opp_init_list(OPP_MPU, omap3_opp_def_list[0]));
+	BUG_ON(opp_init_list(OPP_L3, omap3_opp_def_list[1]));
+	BUG_ON(opp_init_list(OPP_DSP, omap3_opp_def_list[2]));
 }
 
diff --git a/arch/arm/mach-omap2/resource34xx.c b/arch/arm/mach-omap2/resource34xx.c
index 157b38e..3604a38 100644
--- a/arch/arm/mach-omap2/resource34xx.c
+++ b/arch/arm/mach-omap2/resource34xx.c
@@ -161,7 +161,7 @@ static DEFINE_MUTEX(dvfs_mutex);
 /**
  * opp_to_freq - convert OPPID to frequency (DEPRECATED)
  * @freq: return frequency back to caller
- * @opps: opp list
+ * @opp_type: OPP type where we need to look.
  * @opp_id: OPP ID we are searching for
  *
  * return 0 and freq is populated if we find the opp_id, else,
@@ -169,14 +169,14 @@ static DEFINE_MUTEX(dvfs_mutex);
  *
  * NOTE: this function is a standin for the timebeing as opp_id is deprecated
  */
-static int __deprecated opp_to_freq(unsigned long *freq,
-		const struct omap_opp *opps, u8 opp_id)
+static int __deprecated opp_to_freq(unsigned long *freq, enum opp_t opp_type,
+				 u8 opp_id)
 {
 	struct omap_opp *opp;
 
-	BUG_ON(!freq || !opps);
+	BUG_ON(!freq || opp_type >= OPP_TYPES_MAX);
 
-	opp = opp_find_by_opp_id(opps, opp_id);
+	opp = opp_find_by_opp_id(opp_type, opp_id);
 	if (!opp)
 		return -EINVAL;
 
@@ -188,20 +188,20 @@ static int __deprecated opp_to_freq(unsigned long *freq,
 /**
  * freq_to_opp - convert a frequency back to OPP ID (DEPRECATED)
  * @opp_id: opp ID returned back to caller
- * @opps: opp list
+ * @opp_type: OPP type where we need to look.
  * @freq: frequency we are searching for
  *
  * return 0 and opp_id is populated if we find the freq, else, we return error
  *
  * NOTE: this function is a standin for the timebeing as opp_id is deprecated
  */
-static int __deprecated freq_to_opp(u8 *opp_id, struct omap_opp *opps,
+static int __deprecated freq_to_opp(u8 *opp_id, enum opp_t opp_type,
 		unsigned long freq)
 {
 	struct omap_opp *opp;
 
-	BUG_ON(!opp_id || !opps);
-	opp = opp_find_freq_ceil(opps, &freq);
+	BUG_ON(opp_type >= OPP_TYPES_MAX);
+	opp = opp_find_freq_ceil(opp_type, &freq);
 	if (IS_ERR(opp))
 		return -EINVAL;
 	*opp_id = opp_get_opp_id(opp);
@@ -218,9 +218,6 @@ void init_opp(struct shared_resource *resp)
 	u8 opp_id;
 	resp->no_of_users = 0;
 
-	if (!mpu_opps || !dsp_opps || !l3_opps)
-		return;
-
 	/* Initialize the current level of the OPP resource
 	* to the  opp set by u-boot.
 	*/
@@ -228,14 +225,14 @@ void init_opp(struct shared_resource *resp)
 		vdd1_resp = resp;
 		dpll1_clk = clk_get(NULL, "dpll1_ck");
 		dpll2_clk = clk_get(NULL, "dpll2_ck");
-		ret = freq_to_opp(&opp_id, mpu_opps, dpll1_clk->rate);
+		ret = freq_to_opp(&opp_id, OPP_MPU, dpll1_clk->rate);
 		BUG_ON(ret); /* TBD Cleanup handling */
 		curr_vdd1_opp = opp_id;
 	} else if (strcmp(resp->name, "vdd2_opp") == 0) {
 		vdd2_resp = resp;
 		dpll3_clk = clk_get(NULL, "dpll3_m2_ck");
 		l3_clk = clk_get(NULL, "l3_ick");
-		ret = freq_to_opp(&opp_id, l3_opps, l3_clk->rate);
+		ret = freq_to_opp(&opp_id, OPP_L3, l3_clk->rate);
 		BUG_ON(ret); /* TBD Cleanup handling */
 		curr_vdd2_opp = opp_id;
 	}
@@ -288,13 +285,13 @@ static int program_opp_freq(int res, int target_level, int current_level)
 
 	/* Check if I can actually switch or not */
 	if (res == VDD1_OPP) {
-		ret = opp_to_freq(&mpu_freq, mpu_opps, target_level);
-		ret |= opp_to_freq(&dsp_freq, dsp_opps, target_level);
+		ret = opp_to_freq(&mpu_freq, OPP_MPU, target_level);
+		ret |= opp_to_freq(&dsp_freq, OPP_DSP, target_level);
 #ifndef CONFIG_CPU_FREQ
-		ret |= opp_to_freq(&mpu_cur_freq, mpu_opps, current_level);
+		ret |= opp_to_freq(&mpu_cur_freq, OPP_MPU, current_level);
 #endif
 	} else {
-		ret = opp_to_freq(&l3_freq, l3_opps, target_level);
+		ret = opp_to_freq(&l3_freq, OPP_L3, target_level);
 	}
 	/* we would have caught all bad levels earlier.. */
 	if (unlikely(ret))
@@ -329,7 +326,7 @@ static int program_opp_freq(int res, int target_level, int current_level)
 	return target_level;
 }
 
-static int program_opp(int res, struct omap_opp *opp, int target_level,
+static int program_opp(int res, enum opp_t opp_type, int target_level,
 		int current_level)
 {
 	int i, ret = 0, raise;
@@ -342,7 +339,7 @@ static int program_opp(int res, struct omap_opp *opp, int target_level,
 #endif
 
 	/* See if have a freq associated, if not, invalid opp */
-	ret = opp_to_freq(&freq, opp, target_level);
+	ret = opp_to_freq(&freq, opp_type, target_level);
 	if (unlikely(ret))
 		return ret;
 
@@ -365,13 +362,13 @@ static int program_opp(int res, struct omap_opp *opp, int target_level,
 			 * transitioning from good to good OPP
 			 * none of the following should fail..
 			 */
-			oppx = opp_find_freq_exact(opp, freq, true);
+			oppx = opp_find_freq_exact(opp_type, freq, true);
 			BUG_ON(IS_ERR(oppx));
 			uvdc = opp_get_voltage(oppx);
 			vt = omap_twl_uv_to_vsel(uvdc);
 
-			BUG_ON(opp_to_freq(&freq, opp, current_level));
-			oppx = opp_find_freq_exact(opp, freq, true);
+			BUG_ON(opp_to_freq(&freq, opp_type, current_level));
+			oppx = opp_find_freq_exact(opp_type, freq, true);
 			BUG_ON(IS_ERR(oppx));
 			uvdc = opp_get_voltage(oppx);
 			vc = omap_twl_uv_to_vsel(uvdc);
@@ -404,15 +401,12 @@ int resource_set_opp_level(int res, u32 target_level, int flags)
 	if (resp->curr_level == target_level)
 		return 0;
 
-	if (!mpu_opps || !dsp_opps || !l3_opps)
-		return 0;
-
 	/* Check if I can actually switch or not */
 	if (res == VDD1_OPP) {
-		ret = opp_to_freq(&mpu_freq, mpu_opps, target_level);
-		ret |= opp_to_freq(&mpu_old_freq, mpu_opps, resp->curr_level);
+		ret = opp_to_freq(&mpu_freq, OPP_MPU, target_level);
+		ret |= opp_to_freq(&mpu_old_freq, OPP_MPU, resp->curr_level);
 	} else {
-		ret = opp_to_freq(&l3_freq, l3_opps, target_level);
+		ret = opp_to_freq(&l3_freq, OPP_L3, target_level);
 	}
 	if (ret)
 		return ret;
@@ -431,7 +425,7 @@ int resource_set_opp_level(int res, u32 target_level, int flags)
 		/* Send pre notification to CPUFreq */
 		cpufreq_notify_transition(&freqs_notify, CPUFREQ_PRECHANGE);
 #endif
-		resp->curr_level = program_opp(res, mpu_opps, target_level,
+		resp->curr_level = program_opp(res, OPP_MPU, target_level,
 			resp->curr_level);
 #ifdef CONFIG_CPU_FREQ
 		/* Send a post notification to CPUFreq */
@@ -442,7 +436,7 @@ int resource_set_opp_level(int res, u32 target_level, int flags)
 			mutex_unlock(&dvfs_mutex);
 			return 0;
 		}
-		resp->curr_level = program_opp(res, l3_opps, target_level,
+		resp->curr_level = program_opp(res, OPP_L3, target_level,
 			resp->curr_level);
 	}
 	mutex_unlock(&dvfs_mutex);
@@ -474,17 +468,17 @@ int set_opp(struct shared_resource *resp, u32 target_level)
 		req_l3_freq = (target_level * 1000)/4;
 
 		/* Do I have a best match? */
-		oppx = opp_find_freq_ceil(l3_opps, &req_l3_freq);
+		oppx = opp_find_freq_ceil(OPP_L3, &req_l3_freq);
 		if (IS_ERR(oppx)) {
 			/* Give me the best we got */
 			req_l3_freq = ULONG_MAX;
-			oppx = opp_find_freq_floor(l3_opps, &req_l3_freq);
+			oppx = opp_find_freq_floor(OPP_L3, &req_l3_freq);
 		}
 
 		/* uh uh.. no OPPs?? */
 		BUG_ON(IS_ERR(oppx));
 
-		ret = freq_to_opp((u8 *)&target_level, l3_opps, req_l3_freq);
+		ret = freq_to_opp((u8 *)&target_level, OPP_L3, req_l3_freq);
 		/* we dont expect this to fail */
 		BUG_ON(ret);
 
@@ -503,9 +497,9 @@ int validate_opp(struct shared_resource *resp, u32 target_level)
 {
 	unsigned long x;
 	if (strcmp(resp->name, "mpu_freq") == 0)
-		return opp_to_freq(&x, mpu_opps, target_level);
+		return opp_to_freq(&x, OPP_MPU, target_level);
 	else if (strcmp(resp->name, "dsp_freq") == 0)
-		return opp_to_freq(&x, dsp_opps, target_level);
+		return opp_to_freq(&x, OPP_DSP, target_level);
 	return 0;
 }
 
@@ -519,19 +513,16 @@ void init_freq(struct shared_resource *resp)
 	unsigned long freq;
 	resp->no_of_users = 0;
 
-	if (!mpu_opps || !dsp_opps)
-		return;
-
 	linked_res_name = (char *)resp->resource_data;
 	/* Initialize the current level of the Freq resource
 	* to the frequency set by u-boot.
 	*/
 	if (strcmp(resp->name, "mpu_freq") == 0)
 		/* MPU freq in Mhz */
-		ret = opp_to_freq(&freq, mpu_opps, curr_vdd1_opp);
+		ret = opp_to_freq(&freq, OPP_MPU, curr_vdd1_opp);
 	else if (strcmp(resp->name, "dsp_freq") == 0)
 		/* DSP freq in Mhz */
-		ret = opp_to_freq(&freq, dsp_opps, curr_vdd1_opp);
+		ret = opp_to_freq(&freq, OPP_DSP, curr_vdd1_opp);
 	BUG_ON(ret);
 
 	resp->curr_level = freq;
@@ -543,16 +534,13 @@ int set_freq(struct shared_resource *resp, u32 target_level)
 	u8 vdd1_opp;
 	int ret = -EINVAL;
 
-	if (!mpu_opps || !dsp_opps)
-		return 0;
-
 	if (strcmp(resp->name, "mpu_freq") == 0) {
-		ret = freq_to_opp(&vdd1_opp, mpu_opps, target_level);
+		ret = freq_to_opp(&vdd1_opp, OPP_MPU, target_level);
 		if (!ret)
 			ret = resource_request("vdd1_opp", &dummy_mpu_dev,
 					vdd1_opp);
 	} else if (strcmp(resp->name, "dsp_freq") == 0) {
-		ret = freq_to_opp(&vdd1_opp, dsp_opps, target_level);
+		ret = freq_to_opp(&vdd1_opp, OPP_DSP, target_level);
 		if (!ret)
 			ret = resource_request("vdd1_opp", &dummy_dsp_dev,
 					vdd1_opp);
@@ -566,8 +554,8 @@ int validate_freq(struct shared_resource *resp, u32 target_level)
 {
 	u8 x;
 	if (strcmp(resp->name, "mpu_freq") == 0)
-		return freq_to_opp(&x, mpu_opps, target_level);
+		return freq_to_opp(&x, OPP_MPU, target_level);
 	else if (strcmp(resp->name, "dsp_freq") == 0)
-		return freq_to_opp(&x, dsp_opps, target_level);
+		return freq_to_opp(&x, OPP_DSP, target_level);
 	return 0;
 }
diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
index 3c37837..1c5ec37 100644
--- a/arch/arm/mach-omap2/smartreflex.c
+++ b/arch/arm/mach-omap2/smartreflex.c
@@ -152,12 +152,11 @@ static u8 get_vdd1_opp(void)
 	struct omap_opp *opp;
 	unsigned long freq;
 
-	if (sr1.vdd_opp_clk == NULL || IS_ERR(sr1.vdd_opp_clk) ||
-							mpu_opps == NULL)
+	if (sr1.vdd_opp_clk == NULL || IS_ERR(sr1.vdd_opp_clk))
 		return 0;
 
 	freq = sr1.vdd_opp_clk->rate;
-	opp = opp_find_freq_ceil(mpu_opps, &freq);
+	opp = opp_find_freq_ceil(OPP_MPU, &freq);
 	if (IS_ERR(opp))
 		return 0;
 	/*
@@ -176,12 +175,11 @@ static u8 get_vdd2_opp(void)
 	struct omap_opp *opp;
 	unsigned long freq;
 
-	if (sr2.vdd_opp_clk == NULL || IS_ERR(sr2.vdd_opp_clk) ||
-							l3_opps == NULL)
+	if (sr2.vdd_opp_clk == NULL || IS_ERR(sr2.vdd_opp_clk))
 		return 0;
 
 	freq = sr2.vdd_opp_clk->rate;
-	opp = opp_find_freq_ceil(l3_opps, &freq);
+	opp = opp_find_freq_ceil(OPP_L3, &freq);
 	if (IS_ERR(opp))
 		return 0;
 
@@ -310,7 +308,7 @@ static void sr_configure_vp(int srid)
 		if (!target_opp_no)
 			target_opp_no = VDD1_OPP3;
 
-		opp = opp_find_by_opp_id(mpu_opps, target_opp_no);
+		opp = opp_find_by_opp_id(OPP_MPU, target_opp_no);
 		BUG_ON(!opp); /* XXX ugh */
 
 		uvdc = opp_get_voltage(opp);
@@ -359,7 +357,7 @@ static void sr_configure_vp(int srid)
 		if (!target_opp_no)
 			target_opp_no = VDD2_OPP3;
 
-		opp = opp_find_by_opp_id(l3_opps, target_opp_no);
+		opp = opp_find_by_opp_id(OPP_L3, target_opp_no);
 		BUG_ON(!opp); /* XXX ugh */
 
 		uvdc = opp_get_voltage(opp);
@@ -472,7 +470,7 @@ static int sr_reset_voltage(int srid)
 			return 1;
 		}
 
-		opp = opp_find_by_opp_id(mpu_opps, target_opp_no);
+		opp = opp_find_by_opp_id(OPP_MPU, target_opp_no);
 		if (!opp)
 			return 1;
 
@@ -490,7 +488,7 @@ static int sr_reset_voltage(int srid)
 			return 1;
 		}
 
-		opp = opp_find_by_opp_id(l3_opps, target_opp_no);
+		opp = opp_find_by_opp_id(OPP_L3, target_opp_no);
 		if (!opp)
 			return 1;
 
@@ -546,11 +544,6 @@ static int sr_enable(struct omap_sr *sr, u32 target_opp_no)
 	int uvdc;
 	char vsel;
 
-	if (!(mpu_opps && l3_opps)) {
-		pr_notice("VSEL values not found\n");
-		return false;
-	}
-
 	sr->req_opp_no = target_opp_no;
 
 	if (sr->srid == SR1) {
@@ -575,7 +568,7 @@ static int sr_enable(struct omap_sr *sr, u32 target_opp_no)
 			break;
 		}
 
-		opp = opp_find_by_opp_id(mpu_opps, target_opp_no);
+		opp = opp_find_by_opp_id(OPP_MPU, target_opp_no);
 		if (!opp)
 			return false;
 	} else {
@@ -594,7 +587,7 @@ static int sr_enable(struct omap_sr *sr, u32 target_opp_no)
 			break;
 		}
 
-		opp = opp_find_by_opp_id(l3_opps, target_opp_no);
+		opp = opp_find_by_opp_id(OPP_L3, target_opp_no);
 		if (!opp)
 			return false;
 	}
@@ -1010,12 +1003,6 @@ static int __init omap3_sr_init(void)
 	int ret = 0;
 	u8 RdReg;
 
-	/* Exit if OPP tables are not defined */
-        if (!(mpu_opps && l3_opps)) {
-                pr_err("SR: OPP rate tables not defined for platform, not enabling SmartReflex\n");
-		return -ENODEV;
-        }
-
 	/* Enable SR on T2 */
 	ret = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &RdReg,
 			      R_DCDC_GLOBAL_CFG);
diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
index 6bd62ea..dddc027 100644
--- a/arch/arm/plat-omap/common.c
+++ b/arch/arm/plat-omap/common.c
@@ -52,12 +52,6 @@ int omap_board_config_size;
 /* used by omap-smp.c and board-4430sdp.c */
 void __iomem *gic_cpu_base_addr;
 
-#ifdef CONFIG_OMAP_PM_NONE
-struct omap_opp *mpu_opps;
-struct omap_opp *dsp_opps;
-struct omap_opp *l3_opps;
-#endif
-
 static const void *get_config(u16 tag, size_t len, int skip, size_t *len_out)
 {
 	struct omap_board_config_kernel *kinfo = NULL;
diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
index 109203e..a69b557 100644
--- a/arch/arm/plat-omap/cpu-omap.c
+++ b/arch/arm/plat-omap/cpu-omap.c
@@ -87,6 +87,9 @@ static int omap_target(struct cpufreq_policy *policy,
 #ifdef CONFIG_ARCH_OMAP1
 	struct cpufreq_freqs freqs;
 #endif
+#if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
+	unsigned long freq = target_freq * 1000;
+#endif
 	int ret = 0;
 
 	/* Ensure desired rate is within allowed range.  Some govenors
@@ -111,11 +114,8 @@ static int omap_target(struct cpufreq_policy *policy,
 	ret = clk_set_rate(mpu_clk, freqs.new * 1000);
 	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
 #elif defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
-	if (mpu_opps) {
-		unsigned long freq = target_freq * 1000;
-		if (!IS_ERR(opp_find_freq_ceil(mpu_opps, &freq)))
-			omap_pm_cpu_set_freq(freq);
-	}
+	if (opp_find_freq_ceil(OPP_MPU, &freq))
+		omap_pm_cpu_set_freq(freq);
 #endif
 	return ret;
 }
@@ -136,7 +136,7 @@ static int __init omap_cpu_init(struct cpufreq_policy *policy)
 	if (!cpu_is_omap34xx())
 		clk_init_cpufreq_table(&freq_table);
 	else
-		opp_init_cpufreq_table(mpu_opps, &freq_table);
+		opp_init_cpufreq_table(OPP_MPU, &freq_table);
 
 	if (freq_table) {
 		result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
diff --git a/arch/arm/plat-omap/include/plat/opp.h b/arch/arm/plat-omap/include/plat/opp.h
index d69d61f..33d224c 100644
--- a/arch/arm/plat-omap/include/plat/opp.h
+++ b/arch/arm/plat-omap/include/plat/opp.h
@@ -1,8 +1,9 @@
 /*
  * OMAP OPP Interface
  *
- * Copyright (C) 2009 Texas Instruments Incorporated.
+ * Copyright (C) 2009-2010 Texas Instruments Incorporated.
  *	Nishanth Menon
+ *	Romit Dasgupta <romit@ti.com>
  * Copyright (C) 2009 Deep Root Systems, LLC.
  *	Kevin Hilman
  *
@@ -15,9 +16,16 @@
 
 #include <linux/cpufreq.h>
 
-extern struct omap_opp *mpu_opps;
-extern struct omap_opp *dsp_opps;
-extern struct omap_opp *l3_opps;
+#ifdef CONFIG_ARCH_OMAP3
+enum opp_t {
+	OPP_MPU,
+	OPP_L3,
+	OPP_DSP,
+	OPP_TYPES_MAX
+};
+#else
+#error "You need to populate the OPP types for OMAP chip type."
+#endif
 
 
 /**
@@ -79,16 +87,16 @@ unsigned long opp_get_freq(const struct omap_opp *opp);
 /**
  * opp_get_opp_count() - Get number of opps enabled in the opp list
  * @num:	returns the number of opps
- * @oppl:	opp list
+ * @opp_type:	OPP type we want to count
  *
  * This functions returns the number of opps if there are any OPPs enabled,
  * else returns corresponding error value.
  */
-int opp_get_opp_count(struct omap_opp *oppl);
+int opp_get_opp_count(enum opp_t opp_type);
 
 /**
  * opp_find_freq_exact() - search for an exact frequency
- * @oppl:	OPP list
+ * @opp_type:	OPP type we want to search in.
  * @freq:	frequency to search for
  * @enabled:	enabled/disabled OPP to search for
  *
@@ -100,14 +108,14 @@ int opp_get_opp_count(struct omap_opp *oppl);
  * for exact matching frequency and is enabled. if true, the match is for exact
  * frequency which is disabled.
  */
-struct omap_opp *opp_find_freq_exact(struct omap_opp *oppl,
+struct omap_opp *opp_find_freq_exact(enum opp_t opp_type,
 				     unsigned long freq, bool enabled);
 
 /* XXX This documentation needs fixing */
 
 /**
  * opp_find_freq_floor() - Search for an rounded freq
- * @oppl:	Starting list
+ * @opp_type:	OPP type we want to search in
  * @freq:	Start frequency
  *
  * Search for the lower *enabled* OPP from a starting freq
@@ -136,14 +144,13 @@ struct omap_opp *opp_find_freq_exact(struct omap_opp *oppl,
  * NOTE: if we set freq as ULONG_MAX and search low, we get the
  * highest enabled frequency
  */
-struct omap_opp *opp_find_freq_floor(struct omap_opp *oppl,
-				     unsigned long *freq);
+struct omap_opp *opp_find_freq_floor(enum opp_t opp_type, unsigned long *freq);
 
 /* XXX This documentation needs fixing */
 
 /**
  * opp_find_freq_ceil() - Search for an rounded freq
- * @oppl:	Starting list
+ * @opp_type:	OPP type where we want to search in
  * @freq:	Start frequency
  *
  * Search for the higher *enabled* OPP from a starting freq
@@ -169,40 +176,32 @@ struct omap_opp *opp_find_freq_floor(struct omap_opp *oppl,
  *		freq++; * for next higher match *
  *	}
  */
-struct omap_opp *opp_find_freq_ceil(struct omap_opp *oppl, unsigned long *freq);
+struct omap_opp *opp_find_freq_ceil(enum opp_t opp_type, unsigned long *freq);
 
 
 /**
  * opp_init_list() - Initialize an opp list from the opp definitions
+ * @opp_type:	OPP type to initialize this list for.
  * @opp_defs:	Initial opp definitions to create the list.
  *
- * This function creates a list of opp definitions and returns a handle.
+ * This function creates a list of opp definitions and returns status.
  * This list can be used to further validation/search/modifications. New
  * opp entries can be added to this list by using opp_add().
  *
- * In the case of error, ERR_PTR is returned to the caller and should be
- * appropriately handled with IS_ERR.
+ * In the case of error, suitable error code is returned.
  */
-struct omap_opp __init *opp_init_list(const struct omap_opp_def *opp_defs);
+int  __init opp_init_list(enum opp_t opp_type,
+			 const struct omap_opp_def *opp_defs);
 
 /**
  * opp_add()  - Add an OPP table from a table definitions
- * @oppl:	List to add the OPP to
+ * @opp_type:	OPP type under which we want to add our new OPP.
  * @opp_def:	omap_opp_def to describe the OPP which we want to add to list.
  *
- * This function adds an opp definition to the opp list and returns
- * a handle representing the new OPP list. This handle is then used for further
- * validation, search, modification operations on the OPP list.
- *
- * This function returns the pointer to the allocated list through oppl if
- * success, else corresponding ERR_PTR value. Caller should NOT free the oppl.
- * opps_defs can be freed after use.
+ * This function adds an opp definition to the opp list and returns status.
  *
- * NOTE: caller should assume that on success, oppl is probably populated with
- * a new handle and the new handle should be used for further referencing
  */
-struct omap_opp *opp_add(struct omap_opp *oppl,
-			 const struct omap_opp_def *opp_def);
+int opp_add(enum opp_t opp_type, const struct omap_opp_def *opp_def);
 
 /**
  * opp_enable() - Enable a specific OPP
@@ -228,11 +227,11 @@ int opp_enable(struct omap_opp *opp);
  */
 int opp_disable(struct omap_opp *opp);
 
-struct omap_opp * __deprecated opp_find_by_opp_id(struct omap_opp *opps,
+struct omap_opp * __deprecated opp_find_by_opp_id(enum opp_t opp_type,
 						  u8 opp_id);
 u8 __deprecated opp_get_opp_id(struct omap_opp *opp);
 
-void opp_init_cpufreq_table(struct omap_opp *opps,
+void opp_init_cpufreq_table(enum opp_t opp_type,
 			    struct cpufreq_frequency_table **table);
 #else
 static inline unsigned long opp_get_voltage(const struct omap_opp *opp)
diff --git a/arch/arm/plat-omap/omap-pm-noop.c b/arch/arm/plat-omap/omap-pm-noop.c
index aeb372e..713a59f 100644
--- a/arch/arm/plat-omap/omap-pm-noop.c
+++ b/arch/arm/plat-omap/omap-pm-noop.c
@@ -26,10 +26,6 @@
 
 #include <plat/powerdomain.h>
 
-struct omap_opp *dsp_opps;
-struct omap_opp *mpu_opps;
-struct omap_opp *l3_opps;
-
 /*
  * Device-driver-originated constraints (via board-*.c files)
  */
diff --git a/arch/arm/plat-omap/omap-pm-srf.c b/arch/arm/plat-omap/omap-pm-srf.c
index f7bf353..9b4cf7f 100644
--- a/arch/arm/plat-omap/omap-pm-srf.c
+++ b/arch/arm/plat-omap/omap-pm-srf.c
@@ -25,10 +25,6 @@
 #include <plat/resource.h>
 #include <plat/omap_device.h>
 
-struct omap_opp *dsp_opps;
-struct omap_opp *mpu_opps;
-struct omap_opp *l3_opps;
-
 #define LAT_RES_POSTAMBLE "_latency"
 #define MAX_LATENCY_RES_NAME 30
 
diff --git a/arch/arm/plat-omap/opp.c b/arch/arm/plat-omap/opp.c
index 4fe1933..bb8120e 100644
--- a/arch/arm/plat-omap/opp.c
+++ b/arch/arm/plat-omap/opp.c
@@ -1,8 +1,9 @@
 /*
  * OMAP OPP Interface
  *
- * Copyright (C) 2009 Texas Instruments Incorporated.
+ * Copyright (C) 2009-2010 Texas Instruments Incorporated.
  *	Nishanth Menon
+ *	Romit Dasgupta <romit@ti.com>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 as
@@ -39,6 +40,11 @@ struct omap_opp {
 };
 
 /*
+ * This maintains pointers to the start of each OPP array.
+ */
+
+static struct omap_opp *_opp_list[OPP_TYPES_MAX];
+/*
  * DEPRECATED: Meant to detect end of opp array
  * This is meant to help co-exist with current SRF etc
  * TODO: REMOVE!
@@ -65,18 +71,23 @@ unsigned long opp_get_freq(const struct omap_opp *opp)
 
 /**
  * opp_find_by_opp_id - look up OPP by OPP ID (deprecated)
- * @opps: pointer to an array of struct omap_opp
+ * @opp_type: OPP type where we want the look up to happen.
  *
  * Returns the struct omap_opp pointer corresponding to the given OPP
  * ID @opp_id, or returns NULL on error.
  */
-struct omap_opp * __deprecated opp_find_by_opp_id(struct omap_opp *opps,
+struct omap_opp * __deprecated opp_find_by_opp_id(enum opp_t opp_type,
 						  u8 opp_id)
 {
+	struct omap_opp *opps;
 	int i = 0;
 
-	if (!opps || !opp_id)
-		return NULL;
+	if (unlikely(opp_type >= OPP_TYPES_MAX || !opp_id))
+		return ERR_PTR(-EINVAL);
+	opps = _opp_list[opp_type];
+
+	if (!opps)
+		return ERR_PTR(-ENOENT);
 
 	while (!OPP_TERM(&opps[i])) {
 		if (opps[i].enabled && (opps[i].opp_id == opp_id))
@@ -85,7 +96,7 @@ struct omap_opp * __deprecated opp_find_by_opp_id(struct omap_opp *opps,
 		i++;
 	}
 
-	return NULL;
+	return ERR_PTR(-ENOENT);
 }
 
 u8 __deprecated opp_get_opp_id(struct omap_opp *opp)
@@ -93,14 +104,20 @@ u8 __deprecated opp_get_opp_id(struct omap_opp *opp)
 	return opp->opp_id;
 }
 
-int opp_get_opp_count(struct omap_opp *oppl)
+int opp_get_opp_count(enum opp_t opp_type)
 {
 	u8 n = 0;
+	struct omap_opp *oppl;
 
-	if (unlikely(!oppl || IS_ERR(oppl))) {
+	if (unlikely(opp_type >= OPP_TYPES_MAX)) {
 		pr_err("%s: Invalid parameters being passed\n", __func__);
 		return -EINVAL;
 	}
+
+	oppl = _opp_list[opp_type];
+	if (!oppl)
+		return -ENOENT;
+
 	while (!OPP_TERM(oppl)) {
 		if (oppl->enabled)
 			n++;
@@ -109,14 +126,21 @@ int opp_get_opp_count(struct omap_opp *oppl)
 	return n;
 }
 
-struct omap_opp *opp_find_freq_exact(struct omap_opp *oppl,
+struct omap_opp *opp_find_freq_exact(enum opp_t opp_type,
 				     unsigned long freq, bool enabled)
 {
-	if (unlikely(!oppl || IS_ERR(oppl))) {
+	struct omap_opp *oppl;
+
+	if (unlikely(opp_type >= OPP_TYPES_MAX)) {
 		pr_err("%s: Invalid parameters being passed\n", __func__);
 		return ERR_PTR(-EINVAL);
 	}
 
+	oppl = _opp_list[opp_type];
+
+	if (!oppl)
+		return ERR_PTR(-ENOENT);
+
 	while (!OPP_TERM(oppl)) {
 		if ((oppl->rate == freq) && (oppl->enabled == enabled))
 			break;
@@ -126,17 +150,24 @@ struct omap_opp *opp_find_freq_exact(struct omap_opp *oppl,
 	return OPP_TERM(oppl) ? ERR_PTR(-ENOENT) : oppl;
 }
 
-struct omap_opp *opp_find_freq_ceil(struct omap_opp *oppl, unsigned long *freq)
+struct omap_opp *opp_find_freq_ceil(enum opp_t opp_type, unsigned long *freq)
 {
-	if (unlikely(!oppl || IS_ERR(oppl) || !freq || IS_ERR(freq))) {
+	struct omap_opp *oppl;
+
+	if (unlikely(opp_type >= OPP_TYPES_MAX || !freq ||
+		 IS_ERR(freq))) {
 		pr_err("%s: Invalid parameters being passed\n", __func__);
 		return ERR_PTR(-EINVAL);
 	}
 
+	oppl = _opp_list[opp_type];
+
+	if (!oppl)
+		return ERR_PTR(-ENOENT);
+
 	while (!OPP_TERM(oppl)) {
 		if (oppl->enabled && oppl->rate >= *freq)
 			break;
-
 		oppl++;
 	}
 
@@ -148,23 +179,27 @@ struct omap_opp *opp_find_freq_ceil(struct omap_opp *oppl, unsigned long *freq)
 	return oppl;
 }
 
-struct omap_opp *opp_find_freq_floor(struct omap_opp *oppl, unsigned long *freq)
+struct omap_opp *opp_find_freq_floor(enum opp_t opp_type, unsigned long *freq)
 {
-	struct omap_opp *prev_opp = oppl;
+	struct omap_opp *prev_opp, *oppl;
 
-	if (unlikely(!oppl || IS_ERR(oppl) || !freq || IS_ERR(freq))) {
+	if (unlikely(opp_type >= OPP_TYPES_MAX || !freq ||
+		 IS_ERR(freq))) {
 		pr_err("%s: Invalid parameters being passed\n", __func__);
 		return ERR_PTR(-EINVAL);
 	}
+	oppl = _opp_list[opp_type];
+
+	if (!oppl)
+		return ERR_PTR(-ENOENT);
 
+	prev_opp = oppl;
 	while (!OPP_TERM(oppl)) {
 		if (oppl->enabled) {
 			if (oppl->rate > *freq)
 				break;
-
 			prev_opp = oppl;
 		}
-
 		oppl++;
 	}
 
@@ -185,18 +220,23 @@ static void omap_opp_populate(struct omap_opp *opp,
 	opp->u_volt = opp_def->u_volt;
 }
 
-struct omap_opp *opp_add(struct omap_opp *oppl,
-			 const struct omap_opp_def *opp_def)
+int opp_add(enum opp_t opp_type, const struct omap_opp_def *opp_def)
 {
-	struct omap_opp *opp, *oppt, *oppr;
+	struct omap_opp *opp, *oppt, *oppr, *oppl;
 	u8 n, i, ins;
 
-	if (unlikely(!oppl || IS_ERR(oppl) || !opp_def || IS_ERR(opp_def))) {
+	if (unlikely(opp_type >= OPP_TYPES_MAX || !opp_def ||
+			 IS_ERR(opp_def))) {
 		pr_err("%s: Invalid params being passed\n", __func__);
-		return ERR_PTR(-EINVAL);
+		return -EINVAL;
 	}
 
 	n = 0;
+	oppl = _opp_list[opp_type];
+
+	if (!oppl)
+		return -ENOENT;
+
 	opp = oppl;
 	while (!OPP_TERM(opp)) {
 		n++;
@@ -210,11 +250,11 @@ struct omap_opp *opp_add(struct omap_opp *oppl,
 	oppr = kzalloc(sizeof(struct omap_opp) * (n + 2), GFP_KERNEL);
 	if (!oppr) {
 		pr_err("%s: No memory for new opp array\n", __func__);
-		return ERR_PTR(-ENOMEM);
+		return -ENOMEM;
 	}
 
 	/* Simple insertion sort */
-	opp = oppl;
+	opp = _opp_list[opp_type];
 	oppt = oppr;
 	ins = 0;
 	i = 1;
@@ -238,23 +278,27 @@ struct omap_opp *opp_add(struct omap_opp *oppl,
 		oppt++;
 	}
 
+	_opp_list[opp_type] = oppr;
+
 	/* Terminator implicitly added by kzalloc() */
 
 	/* Free the old list */
 	kfree(oppl);
 
-	return oppr;
+	return 0;
 }
 
-struct omap_opp __init *opp_init_list(const struct omap_opp_def *opp_defs)
+int __init opp_init_list(enum opp_t opp_type,
+				 const struct omap_opp_def *opp_defs)
 {
 	struct omap_opp_def *t = (struct omap_opp_def *)opp_defs;
-	struct omap_opp *opp, *oppl;
+	struct omap_opp *oppl;
 	u8 n = 0, i = 1;
 
-	if (unlikely(!opp_defs || IS_ERR(opp_defs))) {
+	if (unlikely(opp_type >= OPP_TYPES_MAX || !opp_defs ||
+			 IS_ERR(opp_defs))) {
 		pr_err("%s: Invalid params being passed\n", __func__);
-		return ERR_PTR(-EINVAL);
+		return -EINVAL;
 	}
 	/* Grab a count */
 	while (t->enabled || t->freq || t->u_volt) {
@@ -269,22 +313,23 @@ struct omap_opp __init *opp_init_list(const struct omap_opp_def *opp_defs)
 	oppl = kzalloc(sizeof(struct omap_opp) * (n + 1), GFP_KERNEL);
 	if (!oppl) {
 		pr_err("%s: No memory for opp array\n", __func__);
-		return ERR_PTR(-ENOMEM);
+		return -ENOMEM;
 	}
 
-	opp = oppl;
+
+	_opp_list[opp_type] = oppl;
 	while (n) {
-		omap_opp_populate(opp, opp_defs);
-		opp->opp_id = i;
+		omap_opp_populate(oppl, opp_defs);
+		oppl->opp_id = i;
 		n--;
-		opp++;
+		oppl++;
 		opp_defs++;
 		i++;
 	}
 
 	/* Terminator implicitly added by kzalloc() */
 
-	return oppl;
+	return 0;
 }
 
 int opp_enable(struct omap_opp *opp)
@@ -308,20 +353,21 @@ int opp_disable(struct omap_opp *opp)
 }
 
 /* XXX document */
-void opp_init_cpufreq_table(struct omap_opp *opps,
+void opp_init_cpufreq_table(enum opp_t opp_type,
 			    struct cpufreq_frequency_table **table)
 {
 	int i = 0, j;
 	int opp_num;
 	struct cpufreq_frequency_table *freq_table;
+	struct omap_opp *opp;
 
-	if (!opps) {
+	if (opp_type >= OPP_TYPES_MAX) {
 		pr_warning("%s: failed to initialize frequency"
 				"table\n", __func__);
 		return;
 	}
 
-	opp_num = opp_get_opp_count(opps);
+	opp_num = opp_get_opp_count(opp_type);
 	if (opp_num < 0) {
 		pr_err("%s: no opp table?\n", __func__);
 		return;
@@ -335,14 +381,15 @@ void opp_init_cpufreq_table(struct omap_opp *opps,
 		return;
 	}
 
+	opp = _opp_list[opp_type];
+	opp += opp_num;
 	for (j = opp_num; j >= 0; j--) {
-		struct omap_opp *opp = &opps[j];
-
 		if (opp->enabled) {
 			freq_table[i].index = i;
 			freq_table[i].frequency = opp->rate / 1000;
 			i++;
 		}
+		opp--;
 	}
 
 	freq_table[i].index = i;
-- 
1.6.3.3


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PM-WIP-OPP][PATCH v4] omap: pm: Introducing enum for OPP types
  2010-01-28 20:40 [PM-WIP-OPP][PATCH v4] omap: pm: Introducing enum for OPP types Nishanth Menon
@ 2010-01-28 20:45 ` Nishanth Menon
  2010-02-04 19:36 ` Kevin Hilman
  1 sibling, 0 replies; 3+ messages in thread
From: Nishanth Menon @ 2010-01-28 20:45 UTC (permalink / raw)
  To: linux-omap
  Cc: Dasgupta, Romit, Cousson, Benoit, Eduardo Valentin, Kevin Hilman,
	Chikkature Rajashekar, Madhusudhan, Paul Walmsley, Premi, Sanjeev,
	Shilimkar, Santosh, Aguirre, Sergio, Tero Kristo, Gopinath, Thara,
	Sripathy, Vishwanath

Menon, Nishanth had written, on 01/28/2010 02:40 PM, the following:
> From: Romit Dasgupta <romit@ti.com>
> 
> Using omap_opp * to refer to domain types entails opp implementation
> into maintaining pointers outside the opp layer.
> 
> Since all we need is an identifier to a specific domain for
> query/operational purposes, we introduce enum for identifying OPP
> types instead of using opp layer's internal data structure pointer.
> 
> Currently, OMAP3 is the only silicon supporting the OPP layer, hence
> mpu_opps, l3_opps and dsp_opps are deprecated and replaced with
> OPP_MPU, OPP_L3 and OPP_DSP respectively.
> 
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Eduardo Valentin <eduardo.valentin@nokia.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> Cc: Madhusudhan Chikkature Rajashekar <madhu.cr@ti.com>
> Cc: Nishanth Menon <nm@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Sanjeev Premi <premi@ti.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Sergio Alberto Aguirre Rodriguez <saaguirre@ti.com>
> Cc: Tero Kristo <Tero.Kristo@nokia.com>
> Cc: Thara Gopinath <thara@ti.com>
> Cc: Vishwanath Sripathy <vishwanath.bs@ti.com>
> 
> Signed-off-by: Romit Dasgupta <romit@ti.com>
arrgh.. forgot to add, anyways, for patchworks:
Acked-by: Nishanth Menon <nm@ti.com>

Tested also on SDP3430, SDP3630
> 
> ---
> Synopsys of changes:
> Rev 1: http://marc.info/?t=126330004800004&r=1&w=2
> Rev 2: http://marc.info/?t=126355341800003&r=1&w=2
> Rev 3: http://marc.info/?t=126408156100006&r=1&w=2
> Rev 4 specific changes Vs Rev 3:
>  * Multiple TI copyrights merged to a single one
>  * Couple of checkpatch warnings for multiple assignments fixed
>  * Cpufreq rates were reversed during initialization - fixed
>  * Rebased to pm-wip-opp branch as requested for rev 3.
> 
[...]
-- 
Regards,
Nishanth Menon

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PM-WIP-OPP][PATCH v4] omap: pm: Introducing enum for OPP types
  2010-01-28 20:40 [PM-WIP-OPP][PATCH v4] omap: pm: Introducing enum for OPP types Nishanth Menon
  2010-01-28 20:45 ` Nishanth Menon
@ 2010-02-04 19:36 ` Kevin Hilman
  1 sibling, 0 replies; 3+ messages in thread
From: Kevin Hilman @ 2010-02-04 19:36 UTC (permalink / raw)
  To: Nishanth Menon
  Cc: linux-omap, Romit Dasgupta, Benoit Cousson, Eduardo Valentin,
	Madhusudhan Chikkature Rajashekar, Paul Walmsley, Sanjeev Premi,
	Santosh Shilimkar, Sergio Alberto Aguirre Rodriguez, Tero Kristo,
	Thara Gopinath, Vishwanath Sripathy

Nishanth Menon <nm@ti.com> writes:

> From: Romit Dasgupta <romit@ti.com>
>
> Using omap_opp * to refer to domain types entails opp implementation
> into maintaining pointers outside the opp layer.
>
> Since all we need is an identifier to a specific domain for
> query/operational purposes, we introduce enum for identifying OPP
> types instead of using opp layer's internal data structure pointer.
>
> Currently, OMAP3 is the only silicon supporting the OPP layer, hence
> mpu_opps, l3_opps and dsp_opps are deprecated and replaced with
> OPP_MPU, OPP_L3 and OPP_DSP respectively.
>
> Cc: Benoit Cousson <b-cousson@ti.com>
> Cc: Eduardo Valentin <eduardo.valentin@nokia.com>
> Cc: Kevin Hilman <khilman@deeprootsystems.com>
> Cc: Madhusudhan Chikkature Rajashekar <madhu.cr@ti.com>
> Cc: Nishanth Menon <nm@ti.com>
> Cc: Paul Walmsley <paul@pwsan.com>
> Cc: Sanjeev Premi <premi@ti.com>
> Cc: Santosh Shilimkar <santosh.shilimkar@ti.com>
> Cc: Sergio Alberto Aguirre Rodriguez <saaguirre@ti.com>
> Cc: Tero Kristo <Tero.Kristo@nokia.com>
> Cc: Thara Gopinath <thara@ti.com>
> Cc: Vishwanath Sripathy <vishwanath.bs@ti.com>
>
> Signed-off-by: Romit Dasgupta <romit@ti.com>

Thanks, applied to pm-wip-opp.

With this patch, I'm considering the OPP API frozen and this will now
be merged into the PM branch.

Kevin

> ---
> Synopsys of changes:
> Rev 1: http://marc.info/?t=126330004800004&r=1&w=2
> Rev 2: http://marc.info/?t=126355341800003&r=1&w=2
> Rev 3: http://marc.info/?t=126408156100006&r=1&w=2
> Rev 4 specific changes Vs Rev 3:
>  * Multiple TI copyrights merged to a single one
>  * Couple of checkpatch warnings for multiple assignments fixed
>  * Cpufreq rates were reversed during initialization - fixed
>  * Rebased to pm-wip-opp branch as requested for rev 3.
>
>  arch/arm/mach-omap2/cpufreq34xx.c     |   15 +---
>  arch/arm/mach-omap2/resource34xx.c    |   84 +++++++++------------
>  arch/arm/mach-omap2/smartreflex.c     |   33 +++------
>  arch/arm/plat-omap/common.c           |    6 --
>  arch/arm/plat-omap/cpu-omap.c         |   12 ++--
>  arch/arm/plat-omap/include/plat/opp.h |   61 ++++++++--------
>  arch/arm/plat-omap/omap-pm-noop.c     |    4 -
>  arch/arm/plat-omap/omap-pm-srf.c      |    4 -
>  arch/arm/plat-omap/opp.c              |  129 ++++++++++++++++++++++-----------
>  9 files changed, 174 insertions(+), 174 deletions(-)
>
> diff --git a/arch/arm/mach-omap2/cpufreq34xx.c b/arch/arm/mach-omap2/cpufreq34xx.c
> index 07873e8..209af2b 100644
> --- a/arch/arm/mach-omap2/cpufreq34xx.c
> +++ b/arch/arm/mach-omap2/cpufreq34xx.c
> @@ -104,7 +104,6 @@ static struct omap_opp_def __initdata omap36xx_dsp_rate_table[] = {
>  
>  void __init omap3_pm_init_opp_table(void)
>  {
> -	int i;
>  	struct omap_opp_def **omap3_opp_def_list;
>  	struct omap_opp_def *omap34xx_opp_def_list[] = {
>  		omap34xx_mpu_rate_table,
> @@ -116,18 +115,12 @@ void __init omap3_pm_init_opp_table(void)
>  		omap36xx_l3_rate_table,
>  		omap36xx_dsp_rate_table
>  	};
> -	struct omap_opp **omap3_rate_tables[] = {
> -		&mpu_opps,
> -		&l3_opps,
> -		&dsp_opps
> -	};
>  
>  	omap3_opp_def_list = cpu_is_omap3630() ? omap36xx_opp_def_list :
>  				omap34xx_opp_def_list;
> -	for (i = 0; i < ARRAY_SIZE(omap3_rate_tables); i++) {
> -		*omap3_rate_tables[i] = opp_init_list(omap3_opp_def_list[i]);
> -		/* We dont want half configured system at the moment */
> -		BUG_ON(IS_ERR(omap3_rate_tables[i]));
> -	}
> +
> +	BUG_ON(opp_init_list(OPP_MPU, omap3_opp_def_list[0]));
> +	BUG_ON(opp_init_list(OPP_L3, omap3_opp_def_list[1]));
> +	BUG_ON(opp_init_list(OPP_DSP, omap3_opp_def_list[2]));
>  }
>  
> diff --git a/arch/arm/mach-omap2/resource34xx.c b/arch/arm/mach-omap2/resource34xx.c
> index 157b38e..3604a38 100644
> --- a/arch/arm/mach-omap2/resource34xx.c
> +++ b/arch/arm/mach-omap2/resource34xx.c
> @@ -161,7 +161,7 @@ static DEFINE_MUTEX(dvfs_mutex);
>  /**
>   * opp_to_freq - convert OPPID to frequency (DEPRECATED)
>   * @freq: return frequency back to caller
> - * @opps: opp list
> + * @opp_type: OPP type where we need to look.
>   * @opp_id: OPP ID we are searching for
>   *
>   * return 0 and freq is populated if we find the opp_id, else,
> @@ -169,14 +169,14 @@ static DEFINE_MUTEX(dvfs_mutex);
>   *
>   * NOTE: this function is a standin for the timebeing as opp_id is deprecated
>   */
> -static int __deprecated opp_to_freq(unsigned long *freq,
> -		const struct omap_opp *opps, u8 opp_id)
> +static int __deprecated opp_to_freq(unsigned long *freq, enum opp_t opp_type,
> +				 u8 opp_id)
>  {
>  	struct omap_opp *opp;
>  
> -	BUG_ON(!freq || !opps);
> +	BUG_ON(!freq || opp_type >= OPP_TYPES_MAX);
>  
> -	opp = opp_find_by_opp_id(opps, opp_id);
> +	opp = opp_find_by_opp_id(opp_type, opp_id);
>  	if (!opp)
>  		return -EINVAL;
>  
> @@ -188,20 +188,20 @@ static int __deprecated opp_to_freq(unsigned long *freq,
>  /**
>   * freq_to_opp - convert a frequency back to OPP ID (DEPRECATED)
>   * @opp_id: opp ID returned back to caller
> - * @opps: opp list
> + * @opp_type: OPP type where we need to look.
>   * @freq: frequency we are searching for
>   *
>   * return 0 and opp_id is populated if we find the freq, else, we return error
>   *
>   * NOTE: this function is a standin for the timebeing as opp_id is deprecated
>   */
> -static int __deprecated freq_to_opp(u8 *opp_id, struct omap_opp *opps,
> +static int __deprecated freq_to_opp(u8 *opp_id, enum opp_t opp_type,
>  		unsigned long freq)
>  {
>  	struct omap_opp *opp;
>  
> -	BUG_ON(!opp_id || !opps);
> -	opp = opp_find_freq_ceil(opps, &freq);
> +	BUG_ON(opp_type >= OPP_TYPES_MAX);
> +	opp = opp_find_freq_ceil(opp_type, &freq);
>  	if (IS_ERR(opp))
>  		return -EINVAL;
>  	*opp_id = opp_get_opp_id(opp);
> @@ -218,9 +218,6 @@ void init_opp(struct shared_resource *resp)
>  	u8 opp_id;
>  	resp->no_of_users = 0;
>  
> -	if (!mpu_opps || !dsp_opps || !l3_opps)
> -		return;
> -
>  	/* Initialize the current level of the OPP resource
>  	* to the  opp set by u-boot.
>  	*/
> @@ -228,14 +225,14 @@ void init_opp(struct shared_resource *resp)
>  		vdd1_resp = resp;
>  		dpll1_clk = clk_get(NULL, "dpll1_ck");
>  		dpll2_clk = clk_get(NULL, "dpll2_ck");
> -		ret = freq_to_opp(&opp_id, mpu_opps, dpll1_clk->rate);
> +		ret = freq_to_opp(&opp_id, OPP_MPU, dpll1_clk->rate);
>  		BUG_ON(ret); /* TBD Cleanup handling */
>  		curr_vdd1_opp = opp_id;
>  	} else if (strcmp(resp->name, "vdd2_opp") == 0) {
>  		vdd2_resp = resp;
>  		dpll3_clk = clk_get(NULL, "dpll3_m2_ck");
>  		l3_clk = clk_get(NULL, "l3_ick");
> -		ret = freq_to_opp(&opp_id, l3_opps, l3_clk->rate);
> +		ret = freq_to_opp(&opp_id, OPP_L3, l3_clk->rate);
>  		BUG_ON(ret); /* TBD Cleanup handling */
>  		curr_vdd2_opp = opp_id;
>  	}
> @@ -288,13 +285,13 @@ static int program_opp_freq(int res, int target_level, int current_level)
>  
>  	/* Check if I can actually switch or not */
>  	if (res == VDD1_OPP) {
> -		ret = opp_to_freq(&mpu_freq, mpu_opps, target_level);
> -		ret |= opp_to_freq(&dsp_freq, dsp_opps, target_level);
> +		ret = opp_to_freq(&mpu_freq, OPP_MPU, target_level);
> +		ret |= opp_to_freq(&dsp_freq, OPP_DSP, target_level);
>  #ifndef CONFIG_CPU_FREQ
> -		ret |= opp_to_freq(&mpu_cur_freq, mpu_opps, current_level);
> +		ret |= opp_to_freq(&mpu_cur_freq, OPP_MPU, current_level);
>  #endif
>  	} else {
> -		ret = opp_to_freq(&l3_freq, l3_opps, target_level);
> +		ret = opp_to_freq(&l3_freq, OPP_L3, target_level);
>  	}
>  	/* we would have caught all bad levels earlier.. */
>  	if (unlikely(ret))
> @@ -329,7 +326,7 @@ static int program_opp_freq(int res, int target_level, int current_level)
>  	return target_level;
>  }
>  
> -static int program_opp(int res, struct omap_opp *opp, int target_level,
> +static int program_opp(int res, enum opp_t opp_type, int target_level,
>  		int current_level)
>  {
>  	int i, ret = 0, raise;
> @@ -342,7 +339,7 @@ static int program_opp(int res, struct omap_opp *opp, int target_level,
>  #endif
>  
>  	/* See if have a freq associated, if not, invalid opp */
> -	ret = opp_to_freq(&freq, opp, target_level);
> +	ret = opp_to_freq(&freq, opp_type, target_level);
>  	if (unlikely(ret))
>  		return ret;
>  
> @@ -365,13 +362,13 @@ static int program_opp(int res, struct omap_opp *opp, int target_level,
>  			 * transitioning from good to good OPP
>  			 * none of the following should fail..
>  			 */
> -			oppx = opp_find_freq_exact(opp, freq, true);
> +			oppx = opp_find_freq_exact(opp_type, freq, true);
>  			BUG_ON(IS_ERR(oppx));
>  			uvdc = opp_get_voltage(oppx);
>  			vt = omap_twl_uv_to_vsel(uvdc);
>  
> -			BUG_ON(opp_to_freq(&freq, opp, current_level));
> -			oppx = opp_find_freq_exact(opp, freq, true);
> +			BUG_ON(opp_to_freq(&freq, opp_type, current_level));
> +			oppx = opp_find_freq_exact(opp_type, freq, true);
>  			BUG_ON(IS_ERR(oppx));
>  			uvdc = opp_get_voltage(oppx);
>  			vc = omap_twl_uv_to_vsel(uvdc);
> @@ -404,15 +401,12 @@ int resource_set_opp_level(int res, u32 target_level, int flags)
>  	if (resp->curr_level == target_level)
>  		return 0;
>  
> -	if (!mpu_opps || !dsp_opps || !l3_opps)
> -		return 0;
> -
>  	/* Check if I can actually switch or not */
>  	if (res == VDD1_OPP) {
> -		ret = opp_to_freq(&mpu_freq, mpu_opps, target_level);
> -		ret |= opp_to_freq(&mpu_old_freq, mpu_opps, resp->curr_level);
> +		ret = opp_to_freq(&mpu_freq, OPP_MPU, target_level);
> +		ret |= opp_to_freq(&mpu_old_freq, OPP_MPU, resp->curr_level);
>  	} else {
> -		ret = opp_to_freq(&l3_freq, l3_opps, target_level);
> +		ret = opp_to_freq(&l3_freq, OPP_L3, target_level);
>  	}
>  	if (ret)
>  		return ret;
> @@ -431,7 +425,7 @@ int resource_set_opp_level(int res, u32 target_level, int flags)
>  		/* Send pre notification to CPUFreq */
>  		cpufreq_notify_transition(&freqs_notify, CPUFREQ_PRECHANGE);
>  #endif
> -		resp->curr_level = program_opp(res, mpu_opps, target_level,
> +		resp->curr_level = program_opp(res, OPP_MPU, target_level,
>  			resp->curr_level);
>  #ifdef CONFIG_CPU_FREQ
>  		/* Send a post notification to CPUFreq */
> @@ -442,7 +436,7 @@ int resource_set_opp_level(int res, u32 target_level, int flags)
>  			mutex_unlock(&dvfs_mutex);
>  			return 0;
>  		}
> -		resp->curr_level = program_opp(res, l3_opps, target_level,
> +		resp->curr_level = program_opp(res, OPP_L3, target_level,
>  			resp->curr_level);
>  	}
>  	mutex_unlock(&dvfs_mutex);
> @@ -474,17 +468,17 @@ int set_opp(struct shared_resource *resp, u32 target_level)
>  		req_l3_freq = (target_level * 1000)/4;
>  
>  		/* Do I have a best match? */
> -		oppx = opp_find_freq_ceil(l3_opps, &req_l3_freq);
> +		oppx = opp_find_freq_ceil(OPP_L3, &req_l3_freq);
>  		if (IS_ERR(oppx)) {
>  			/* Give me the best we got */
>  			req_l3_freq = ULONG_MAX;
> -			oppx = opp_find_freq_floor(l3_opps, &req_l3_freq);
> +			oppx = opp_find_freq_floor(OPP_L3, &req_l3_freq);
>  		}
>  
>  		/* uh uh.. no OPPs?? */
>  		BUG_ON(IS_ERR(oppx));
>  
> -		ret = freq_to_opp((u8 *)&target_level, l3_opps, req_l3_freq);
> +		ret = freq_to_opp((u8 *)&target_level, OPP_L3, req_l3_freq);
>  		/* we dont expect this to fail */
>  		BUG_ON(ret);
>  
> @@ -503,9 +497,9 @@ int validate_opp(struct shared_resource *resp, u32 target_level)
>  {
>  	unsigned long x;
>  	if (strcmp(resp->name, "mpu_freq") == 0)
> -		return opp_to_freq(&x, mpu_opps, target_level);
> +		return opp_to_freq(&x, OPP_MPU, target_level);
>  	else if (strcmp(resp->name, "dsp_freq") == 0)
> -		return opp_to_freq(&x, dsp_opps, target_level);
> +		return opp_to_freq(&x, OPP_DSP, target_level);
>  	return 0;
>  }
>  
> @@ -519,19 +513,16 @@ void init_freq(struct shared_resource *resp)
>  	unsigned long freq;
>  	resp->no_of_users = 0;
>  
> -	if (!mpu_opps || !dsp_opps)
> -		return;
> -
>  	linked_res_name = (char *)resp->resource_data;
>  	/* Initialize the current level of the Freq resource
>  	* to the frequency set by u-boot.
>  	*/
>  	if (strcmp(resp->name, "mpu_freq") == 0)
>  		/* MPU freq in Mhz */
> -		ret = opp_to_freq(&freq, mpu_opps, curr_vdd1_opp);
> +		ret = opp_to_freq(&freq, OPP_MPU, curr_vdd1_opp);
>  	else if (strcmp(resp->name, "dsp_freq") == 0)
>  		/* DSP freq in Mhz */
> -		ret = opp_to_freq(&freq, dsp_opps, curr_vdd1_opp);
> +		ret = opp_to_freq(&freq, OPP_DSP, curr_vdd1_opp);
>  	BUG_ON(ret);
>  
>  	resp->curr_level = freq;
> @@ -543,16 +534,13 @@ int set_freq(struct shared_resource *resp, u32 target_level)
>  	u8 vdd1_opp;
>  	int ret = -EINVAL;
>  
> -	if (!mpu_opps || !dsp_opps)
> -		return 0;
> -
>  	if (strcmp(resp->name, "mpu_freq") == 0) {
> -		ret = freq_to_opp(&vdd1_opp, mpu_opps, target_level);
> +		ret = freq_to_opp(&vdd1_opp, OPP_MPU, target_level);
>  		if (!ret)
>  			ret = resource_request("vdd1_opp", &dummy_mpu_dev,
>  					vdd1_opp);
>  	} else if (strcmp(resp->name, "dsp_freq") == 0) {
> -		ret = freq_to_opp(&vdd1_opp, dsp_opps, target_level);
> +		ret = freq_to_opp(&vdd1_opp, OPP_DSP, target_level);
>  		if (!ret)
>  			ret = resource_request("vdd1_opp", &dummy_dsp_dev,
>  					vdd1_opp);
> @@ -566,8 +554,8 @@ int validate_freq(struct shared_resource *resp, u32 target_level)
>  {
>  	u8 x;
>  	if (strcmp(resp->name, "mpu_freq") == 0)
> -		return freq_to_opp(&x, mpu_opps, target_level);
> +		return freq_to_opp(&x, OPP_MPU, target_level);
>  	else if (strcmp(resp->name, "dsp_freq") == 0)
> -		return freq_to_opp(&x, dsp_opps, target_level);
> +		return freq_to_opp(&x, OPP_DSP, target_level);
>  	return 0;
>  }
> diff --git a/arch/arm/mach-omap2/smartreflex.c b/arch/arm/mach-omap2/smartreflex.c
> index 3c37837..1c5ec37 100644
> --- a/arch/arm/mach-omap2/smartreflex.c
> +++ b/arch/arm/mach-omap2/smartreflex.c
> @@ -152,12 +152,11 @@ static u8 get_vdd1_opp(void)
>  	struct omap_opp *opp;
>  	unsigned long freq;
>  
> -	if (sr1.vdd_opp_clk == NULL || IS_ERR(sr1.vdd_opp_clk) ||
> -							mpu_opps == NULL)
> +	if (sr1.vdd_opp_clk == NULL || IS_ERR(sr1.vdd_opp_clk))
>  		return 0;
>  
>  	freq = sr1.vdd_opp_clk->rate;
> -	opp = opp_find_freq_ceil(mpu_opps, &freq);
> +	opp = opp_find_freq_ceil(OPP_MPU, &freq);
>  	if (IS_ERR(opp))
>  		return 0;
>  	/*
> @@ -176,12 +175,11 @@ static u8 get_vdd2_opp(void)
>  	struct omap_opp *opp;
>  	unsigned long freq;
>  
> -	if (sr2.vdd_opp_clk == NULL || IS_ERR(sr2.vdd_opp_clk) ||
> -							l3_opps == NULL)
> +	if (sr2.vdd_opp_clk == NULL || IS_ERR(sr2.vdd_opp_clk))
>  		return 0;
>  
>  	freq = sr2.vdd_opp_clk->rate;
> -	opp = opp_find_freq_ceil(l3_opps, &freq);
> +	opp = opp_find_freq_ceil(OPP_L3, &freq);
>  	if (IS_ERR(opp))
>  		return 0;
>  
> @@ -310,7 +308,7 @@ static void sr_configure_vp(int srid)
>  		if (!target_opp_no)
>  			target_opp_no = VDD1_OPP3;
>  
> -		opp = opp_find_by_opp_id(mpu_opps, target_opp_no);
> +		opp = opp_find_by_opp_id(OPP_MPU, target_opp_no);
>  		BUG_ON(!opp); /* XXX ugh */
>  
>  		uvdc = opp_get_voltage(opp);
> @@ -359,7 +357,7 @@ static void sr_configure_vp(int srid)
>  		if (!target_opp_no)
>  			target_opp_no = VDD2_OPP3;
>  
> -		opp = opp_find_by_opp_id(l3_opps, target_opp_no);
> +		opp = opp_find_by_opp_id(OPP_L3, target_opp_no);
>  		BUG_ON(!opp); /* XXX ugh */
>  
>  		uvdc = opp_get_voltage(opp);
> @@ -472,7 +470,7 @@ static int sr_reset_voltage(int srid)
>  			return 1;
>  		}
>  
> -		opp = opp_find_by_opp_id(mpu_opps, target_opp_no);
> +		opp = opp_find_by_opp_id(OPP_MPU, target_opp_no);
>  		if (!opp)
>  			return 1;
>  
> @@ -490,7 +488,7 @@ static int sr_reset_voltage(int srid)
>  			return 1;
>  		}
>  
> -		opp = opp_find_by_opp_id(l3_opps, target_opp_no);
> +		opp = opp_find_by_opp_id(OPP_L3, target_opp_no);
>  		if (!opp)
>  			return 1;
>  
> @@ -546,11 +544,6 @@ static int sr_enable(struct omap_sr *sr, u32 target_opp_no)
>  	int uvdc;
>  	char vsel;
>  
> -	if (!(mpu_opps && l3_opps)) {
> -		pr_notice("VSEL values not found\n");
> -		return false;
> -	}
> -
>  	sr->req_opp_no = target_opp_no;
>  
>  	if (sr->srid == SR1) {
> @@ -575,7 +568,7 @@ static int sr_enable(struct omap_sr *sr, u32 target_opp_no)
>  			break;
>  		}
>  
> -		opp = opp_find_by_opp_id(mpu_opps, target_opp_no);
> +		opp = opp_find_by_opp_id(OPP_MPU, target_opp_no);
>  		if (!opp)
>  			return false;
>  	} else {
> @@ -594,7 +587,7 @@ static int sr_enable(struct omap_sr *sr, u32 target_opp_no)
>  			break;
>  		}
>  
> -		opp = opp_find_by_opp_id(l3_opps, target_opp_no);
> +		opp = opp_find_by_opp_id(OPP_L3, target_opp_no);
>  		if (!opp)
>  			return false;
>  	}
> @@ -1010,12 +1003,6 @@ static int __init omap3_sr_init(void)
>  	int ret = 0;
>  	u8 RdReg;
>  
> -	/* Exit if OPP tables are not defined */
> -        if (!(mpu_opps && l3_opps)) {
> -                pr_err("SR: OPP rate tables not defined for platform, not enabling SmartReflex\n");
> -		return -ENODEV;
> -        }
> -
>  	/* Enable SR on T2 */
>  	ret = twl_i2c_read_u8(TWL4030_MODULE_PM_RECEIVER, &RdReg,
>  			      R_DCDC_GLOBAL_CFG);
> diff --git a/arch/arm/plat-omap/common.c b/arch/arm/plat-omap/common.c
> index 6bd62ea..dddc027 100644
> --- a/arch/arm/plat-omap/common.c
> +++ b/arch/arm/plat-omap/common.c
> @@ -52,12 +52,6 @@ int omap_board_config_size;
>  /* used by omap-smp.c and board-4430sdp.c */
>  void __iomem *gic_cpu_base_addr;
>  
> -#ifdef CONFIG_OMAP_PM_NONE
> -struct omap_opp *mpu_opps;
> -struct omap_opp *dsp_opps;
> -struct omap_opp *l3_opps;
> -#endif
> -
>  static const void *get_config(u16 tag, size_t len, int skip, size_t *len_out)
>  {
>  	struct omap_board_config_kernel *kinfo = NULL;
> diff --git a/arch/arm/plat-omap/cpu-omap.c b/arch/arm/plat-omap/cpu-omap.c
> index 109203e..a69b557 100644
> --- a/arch/arm/plat-omap/cpu-omap.c
> +++ b/arch/arm/plat-omap/cpu-omap.c
> @@ -87,6 +87,9 @@ static int omap_target(struct cpufreq_policy *policy,
>  #ifdef CONFIG_ARCH_OMAP1
>  	struct cpufreq_freqs freqs;
>  #endif
> +#if defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
> +	unsigned long freq = target_freq * 1000;
> +#endif
>  	int ret = 0;
>  
>  	/* Ensure desired rate is within allowed range.  Some govenors
> @@ -111,11 +114,8 @@ static int omap_target(struct cpufreq_policy *policy,
>  	ret = clk_set_rate(mpu_clk, freqs.new * 1000);
>  	cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
>  #elif defined(CONFIG_ARCH_OMAP3) && !defined(CONFIG_OMAP_PM_NONE)
> -	if (mpu_opps) {
> -		unsigned long freq = target_freq * 1000;
> -		if (!IS_ERR(opp_find_freq_ceil(mpu_opps, &freq)))
> -			omap_pm_cpu_set_freq(freq);
> -	}
> +	if (opp_find_freq_ceil(OPP_MPU, &freq))
> +		omap_pm_cpu_set_freq(freq);
>  #endif
>  	return ret;
>  }
> @@ -136,7 +136,7 @@ static int __init omap_cpu_init(struct cpufreq_policy *policy)
>  	if (!cpu_is_omap34xx())
>  		clk_init_cpufreq_table(&freq_table);
>  	else
> -		opp_init_cpufreq_table(mpu_opps, &freq_table);
> +		opp_init_cpufreq_table(OPP_MPU, &freq_table);
>  
>  	if (freq_table) {
>  		result = cpufreq_frequency_table_cpuinfo(policy, freq_table);
> diff --git a/arch/arm/plat-omap/include/plat/opp.h b/arch/arm/plat-omap/include/plat/opp.h
> index d69d61f..33d224c 100644
> --- a/arch/arm/plat-omap/include/plat/opp.h
> +++ b/arch/arm/plat-omap/include/plat/opp.h
> @@ -1,8 +1,9 @@
>  /*
>   * OMAP OPP Interface
>   *
> - * Copyright (C) 2009 Texas Instruments Incorporated.
> + * Copyright (C) 2009-2010 Texas Instruments Incorporated.
>   *	Nishanth Menon
> + *	Romit Dasgupta <romit@ti.com>
>   * Copyright (C) 2009 Deep Root Systems, LLC.
>   *	Kevin Hilman
>   *
> @@ -15,9 +16,16 @@
>  
>  #include <linux/cpufreq.h>
>  
> -extern struct omap_opp *mpu_opps;
> -extern struct omap_opp *dsp_opps;
> -extern struct omap_opp *l3_opps;
> +#ifdef CONFIG_ARCH_OMAP3
> +enum opp_t {
> +	OPP_MPU,
> +	OPP_L3,
> +	OPP_DSP,
> +	OPP_TYPES_MAX
> +};
> +#else
> +#error "You need to populate the OPP types for OMAP chip type."
> +#endif
>  
>  
>  /**
> @@ -79,16 +87,16 @@ unsigned long opp_get_freq(const struct omap_opp *opp);
>  /**
>   * opp_get_opp_count() - Get number of opps enabled in the opp list
>   * @num:	returns the number of opps
> - * @oppl:	opp list
> + * @opp_type:	OPP type we want to count
>   *
>   * This functions returns the number of opps if there are any OPPs enabled,
>   * else returns corresponding error value.
>   */
> -int opp_get_opp_count(struct omap_opp *oppl);
> +int opp_get_opp_count(enum opp_t opp_type);
>  
>  /**
>   * opp_find_freq_exact() - search for an exact frequency
> - * @oppl:	OPP list
> + * @opp_type:	OPP type we want to search in.
>   * @freq:	frequency to search for
>   * @enabled:	enabled/disabled OPP to search for
>   *
> @@ -100,14 +108,14 @@ int opp_get_opp_count(struct omap_opp *oppl);
>   * for exact matching frequency and is enabled. if true, the match is for exact
>   * frequency which is disabled.
>   */
> -struct omap_opp *opp_find_freq_exact(struct omap_opp *oppl,
> +struct omap_opp *opp_find_freq_exact(enum opp_t opp_type,
>  				     unsigned long freq, bool enabled);
>  
>  /* XXX This documentation needs fixing */
>  
>  /**
>   * opp_find_freq_floor() - Search for an rounded freq
> - * @oppl:	Starting list
> + * @opp_type:	OPP type we want to search in
>   * @freq:	Start frequency
>   *
>   * Search for the lower *enabled* OPP from a starting freq
> @@ -136,14 +144,13 @@ struct omap_opp *opp_find_freq_exact(struct omap_opp *oppl,
>   * NOTE: if we set freq as ULONG_MAX and search low, we get the
>   * highest enabled frequency
>   */
> -struct omap_opp *opp_find_freq_floor(struct omap_opp *oppl,
> -				     unsigned long *freq);
> +struct omap_opp *opp_find_freq_floor(enum opp_t opp_type, unsigned long *freq);
>  
>  /* XXX This documentation needs fixing */
>  
>  /**
>   * opp_find_freq_ceil() - Search for an rounded freq
> - * @oppl:	Starting list
> + * @opp_type:	OPP type where we want to search in
>   * @freq:	Start frequency
>   *
>   * Search for the higher *enabled* OPP from a starting freq
> @@ -169,40 +176,32 @@ struct omap_opp *opp_find_freq_floor(struct omap_opp *oppl,
>   *		freq++; * for next higher match *
>   *	}
>   */
> -struct omap_opp *opp_find_freq_ceil(struct omap_opp *oppl, unsigned long *freq);
> +struct omap_opp *opp_find_freq_ceil(enum opp_t opp_type, unsigned long *freq);
>  
>  
>  /**
>   * opp_init_list() - Initialize an opp list from the opp definitions
> + * @opp_type:	OPP type to initialize this list for.
>   * @opp_defs:	Initial opp definitions to create the list.
>   *
> - * This function creates a list of opp definitions and returns a handle.
> + * This function creates a list of opp definitions and returns status.
>   * This list can be used to further validation/search/modifications. New
>   * opp entries can be added to this list by using opp_add().
>   *
> - * In the case of error, ERR_PTR is returned to the caller and should be
> - * appropriately handled with IS_ERR.
> + * In the case of error, suitable error code is returned.
>   */
> -struct omap_opp __init *opp_init_list(const struct omap_opp_def *opp_defs);
> +int  __init opp_init_list(enum opp_t opp_type,
> +			 const struct omap_opp_def *opp_defs);
>  
>  /**
>   * opp_add()  - Add an OPP table from a table definitions
> - * @oppl:	List to add the OPP to
> + * @opp_type:	OPP type under which we want to add our new OPP.
>   * @opp_def:	omap_opp_def to describe the OPP which we want to add to list.
>   *
> - * This function adds an opp definition to the opp list and returns
> - * a handle representing the new OPP list. This handle is then used for further
> - * validation, search, modification operations on the OPP list.
> - *
> - * This function returns the pointer to the allocated list through oppl if
> - * success, else corresponding ERR_PTR value. Caller should NOT free the oppl.
> - * opps_defs can be freed after use.
> + * This function adds an opp definition to the opp list and returns status.
>   *
> - * NOTE: caller should assume that on success, oppl is probably populated with
> - * a new handle and the new handle should be used for further referencing
>   */
> -struct omap_opp *opp_add(struct omap_opp *oppl,
> -			 const struct omap_opp_def *opp_def);
> +int opp_add(enum opp_t opp_type, const struct omap_opp_def *opp_def);
>  
>  /**
>   * opp_enable() - Enable a specific OPP
> @@ -228,11 +227,11 @@ int opp_enable(struct omap_opp *opp);
>   */
>  int opp_disable(struct omap_opp *opp);
>  
> -struct omap_opp * __deprecated opp_find_by_opp_id(struct omap_opp *opps,
> +struct omap_opp * __deprecated opp_find_by_opp_id(enum opp_t opp_type,
>  						  u8 opp_id);
>  u8 __deprecated opp_get_opp_id(struct omap_opp *opp);
>  
> -void opp_init_cpufreq_table(struct omap_opp *opps,
> +void opp_init_cpufreq_table(enum opp_t opp_type,
>  			    struct cpufreq_frequency_table **table);
>  #else
>  static inline unsigned long opp_get_voltage(const struct omap_opp *opp)
> diff --git a/arch/arm/plat-omap/omap-pm-noop.c b/arch/arm/plat-omap/omap-pm-noop.c
> index aeb372e..713a59f 100644
> --- a/arch/arm/plat-omap/omap-pm-noop.c
> +++ b/arch/arm/plat-omap/omap-pm-noop.c
> @@ -26,10 +26,6 @@
>  
>  #include <plat/powerdomain.h>
>  
> -struct omap_opp *dsp_opps;
> -struct omap_opp *mpu_opps;
> -struct omap_opp *l3_opps;
> -
>  /*
>   * Device-driver-originated constraints (via board-*.c files)
>   */
> diff --git a/arch/arm/plat-omap/omap-pm-srf.c b/arch/arm/plat-omap/omap-pm-srf.c
> index f7bf353..9b4cf7f 100644
> --- a/arch/arm/plat-omap/omap-pm-srf.c
> +++ b/arch/arm/plat-omap/omap-pm-srf.c
> @@ -25,10 +25,6 @@
>  #include <plat/resource.h>
>  #include <plat/omap_device.h>
>  
> -struct omap_opp *dsp_opps;
> -struct omap_opp *mpu_opps;
> -struct omap_opp *l3_opps;
> -
>  #define LAT_RES_POSTAMBLE "_latency"
>  #define MAX_LATENCY_RES_NAME 30
>  
> diff --git a/arch/arm/plat-omap/opp.c b/arch/arm/plat-omap/opp.c
> index 4fe1933..bb8120e 100644
> --- a/arch/arm/plat-omap/opp.c
> +++ b/arch/arm/plat-omap/opp.c
> @@ -1,8 +1,9 @@
>  /*
>   * OMAP OPP Interface
>   *
> - * Copyright (C) 2009 Texas Instruments Incorporated.
> + * Copyright (C) 2009-2010 Texas Instruments Incorporated.
>   *	Nishanth Menon
> + *	Romit Dasgupta <romit@ti.com>
>   *
>   * This program is free software; you can redistribute it and/or modify
>   * it under the terms of the GNU General Public License version 2 as
> @@ -39,6 +40,11 @@ struct omap_opp {
>  };
>  
>  /*
> + * This maintains pointers to the start of each OPP array.
> + */
> +
> +static struct omap_opp *_opp_list[OPP_TYPES_MAX];
> +/*
>   * DEPRECATED: Meant to detect end of opp array
>   * This is meant to help co-exist with current SRF etc
>   * TODO: REMOVE!
> @@ -65,18 +71,23 @@ unsigned long opp_get_freq(const struct omap_opp *opp)
>  
>  /**
>   * opp_find_by_opp_id - look up OPP by OPP ID (deprecated)
> - * @opps: pointer to an array of struct omap_opp
> + * @opp_type: OPP type where we want the look up to happen.
>   *
>   * Returns the struct omap_opp pointer corresponding to the given OPP
>   * ID @opp_id, or returns NULL on error.
>   */
> -struct omap_opp * __deprecated opp_find_by_opp_id(struct omap_opp *opps,
> +struct omap_opp * __deprecated opp_find_by_opp_id(enum opp_t opp_type,
>  						  u8 opp_id)
>  {
> +	struct omap_opp *opps;
>  	int i = 0;
>  
> -	if (!opps || !opp_id)
> -		return NULL;
> +	if (unlikely(opp_type >= OPP_TYPES_MAX || !opp_id))
> +		return ERR_PTR(-EINVAL);
> +	opps = _opp_list[opp_type];
> +
> +	if (!opps)
> +		return ERR_PTR(-ENOENT);
>  
>  	while (!OPP_TERM(&opps[i])) {
>  		if (opps[i].enabled && (opps[i].opp_id == opp_id))
> @@ -85,7 +96,7 @@ struct omap_opp * __deprecated opp_find_by_opp_id(struct omap_opp *opps,
>  		i++;
>  	}
>  
> -	return NULL;
> +	return ERR_PTR(-ENOENT);
>  }
>  
>  u8 __deprecated opp_get_opp_id(struct omap_opp *opp)
> @@ -93,14 +104,20 @@ u8 __deprecated opp_get_opp_id(struct omap_opp *opp)
>  	return opp->opp_id;
>  }
>  
> -int opp_get_opp_count(struct omap_opp *oppl)
> +int opp_get_opp_count(enum opp_t opp_type)
>  {
>  	u8 n = 0;
> +	struct omap_opp *oppl;
>  
> -	if (unlikely(!oppl || IS_ERR(oppl))) {
> +	if (unlikely(opp_type >= OPP_TYPES_MAX)) {
>  		pr_err("%s: Invalid parameters being passed\n", __func__);
>  		return -EINVAL;
>  	}
> +
> +	oppl = _opp_list[opp_type];
> +	if (!oppl)
> +		return -ENOENT;
> +
>  	while (!OPP_TERM(oppl)) {
>  		if (oppl->enabled)
>  			n++;
> @@ -109,14 +126,21 @@ int opp_get_opp_count(struct omap_opp *oppl)
>  	return n;
>  }
>  
> -struct omap_opp *opp_find_freq_exact(struct omap_opp *oppl,
> +struct omap_opp *opp_find_freq_exact(enum opp_t opp_type,
>  				     unsigned long freq, bool enabled)
>  {
> -	if (unlikely(!oppl || IS_ERR(oppl))) {
> +	struct omap_opp *oppl;
> +
> +	if (unlikely(opp_type >= OPP_TYPES_MAX)) {
>  		pr_err("%s: Invalid parameters being passed\n", __func__);
>  		return ERR_PTR(-EINVAL);
>  	}
>  
> +	oppl = _opp_list[opp_type];
> +
> +	if (!oppl)
> +		return ERR_PTR(-ENOENT);
> +
>  	while (!OPP_TERM(oppl)) {
>  		if ((oppl->rate == freq) && (oppl->enabled == enabled))
>  			break;
> @@ -126,17 +150,24 @@ struct omap_opp *opp_find_freq_exact(struct omap_opp *oppl,
>  	return OPP_TERM(oppl) ? ERR_PTR(-ENOENT) : oppl;
>  }
>  
> -struct omap_opp *opp_find_freq_ceil(struct omap_opp *oppl, unsigned long *freq)
> +struct omap_opp *opp_find_freq_ceil(enum opp_t opp_type, unsigned long *freq)
>  {
> -	if (unlikely(!oppl || IS_ERR(oppl) || !freq || IS_ERR(freq))) {
> +	struct omap_opp *oppl;
> +
> +	if (unlikely(opp_type >= OPP_TYPES_MAX || !freq ||
> +		 IS_ERR(freq))) {
>  		pr_err("%s: Invalid parameters being passed\n", __func__);
>  		return ERR_PTR(-EINVAL);
>  	}
>  
> +	oppl = _opp_list[opp_type];
> +
> +	if (!oppl)
> +		return ERR_PTR(-ENOENT);
> +
>  	while (!OPP_TERM(oppl)) {
>  		if (oppl->enabled && oppl->rate >= *freq)
>  			break;
> -
>  		oppl++;
>  	}
>  
> @@ -148,23 +179,27 @@ struct omap_opp *opp_find_freq_ceil(struct omap_opp *oppl, unsigned long *freq)
>  	return oppl;
>  }
>  
> -struct omap_opp *opp_find_freq_floor(struct omap_opp *oppl, unsigned long *freq)
> +struct omap_opp *opp_find_freq_floor(enum opp_t opp_type, unsigned long *freq)
>  {
> -	struct omap_opp *prev_opp = oppl;
> +	struct omap_opp *prev_opp, *oppl;
>  
> -	if (unlikely(!oppl || IS_ERR(oppl) || !freq || IS_ERR(freq))) {
> +	if (unlikely(opp_type >= OPP_TYPES_MAX || !freq ||
> +		 IS_ERR(freq))) {
>  		pr_err("%s: Invalid parameters being passed\n", __func__);
>  		return ERR_PTR(-EINVAL);
>  	}
> +	oppl = _opp_list[opp_type];
> +
> +	if (!oppl)
> +		return ERR_PTR(-ENOENT);
>  
> +	prev_opp = oppl;
>  	while (!OPP_TERM(oppl)) {
>  		if (oppl->enabled) {
>  			if (oppl->rate > *freq)
>  				break;
> -
>  			prev_opp = oppl;
>  		}
> -
>  		oppl++;
>  	}
>  
> @@ -185,18 +220,23 @@ static void omap_opp_populate(struct omap_opp *opp,
>  	opp->u_volt = opp_def->u_volt;
>  }
>  
> -struct omap_opp *opp_add(struct omap_opp *oppl,
> -			 const struct omap_opp_def *opp_def)
> +int opp_add(enum opp_t opp_type, const struct omap_opp_def *opp_def)
>  {
> -	struct omap_opp *opp, *oppt, *oppr;
> +	struct omap_opp *opp, *oppt, *oppr, *oppl;
>  	u8 n, i, ins;
>  
> -	if (unlikely(!oppl || IS_ERR(oppl) || !opp_def || IS_ERR(opp_def))) {
> +	if (unlikely(opp_type >= OPP_TYPES_MAX || !opp_def ||
> +			 IS_ERR(opp_def))) {
>  		pr_err("%s: Invalid params being passed\n", __func__);
> -		return ERR_PTR(-EINVAL);
> +		return -EINVAL;
>  	}
>  
>  	n = 0;
> +	oppl = _opp_list[opp_type];
> +
> +	if (!oppl)
> +		return -ENOENT;
> +
>  	opp = oppl;
>  	while (!OPP_TERM(opp)) {
>  		n++;
> @@ -210,11 +250,11 @@ struct omap_opp *opp_add(struct omap_opp *oppl,
>  	oppr = kzalloc(sizeof(struct omap_opp) * (n + 2), GFP_KERNEL);
>  	if (!oppr) {
>  		pr_err("%s: No memory for new opp array\n", __func__);
> -		return ERR_PTR(-ENOMEM);
> +		return -ENOMEM;
>  	}
>  
>  	/* Simple insertion sort */
> -	opp = oppl;
> +	opp = _opp_list[opp_type];
>  	oppt = oppr;
>  	ins = 0;
>  	i = 1;
> @@ -238,23 +278,27 @@ struct omap_opp *opp_add(struct omap_opp *oppl,
>  		oppt++;
>  	}
>  
> +	_opp_list[opp_type] = oppr;
> +
>  	/* Terminator implicitly added by kzalloc() */
>  
>  	/* Free the old list */
>  	kfree(oppl);
>  
> -	return oppr;
> +	return 0;
>  }
>  
> -struct omap_opp __init *opp_init_list(const struct omap_opp_def *opp_defs)
> +int __init opp_init_list(enum opp_t opp_type,
> +				 const struct omap_opp_def *opp_defs)
>  {
>  	struct omap_opp_def *t = (struct omap_opp_def *)opp_defs;
> -	struct omap_opp *opp, *oppl;
> +	struct omap_opp *oppl;
>  	u8 n = 0, i = 1;
>  
> -	if (unlikely(!opp_defs || IS_ERR(opp_defs))) {
> +	if (unlikely(opp_type >= OPP_TYPES_MAX || !opp_defs ||
> +			 IS_ERR(opp_defs))) {
>  		pr_err("%s: Invalid params being passed\n", __func__);
> -		return ERR_PTR(-EINVAL);
> +		return -EINVAL;
>  	}
>  	/* Grab a count */
>  	while (t->enabled || t->freq || t->u_volt) {
> @@ -269,22 +313,23 @@ struct omap_opp __init *opp_init_list(const struct omap_opp_def *opp_defs)
>  	oppl = kzalloc(sizeof(struct omap_opp) * (n + 1), GFP_KERNEL);
>  	if (!oppl) {
>  		pr_err("%s: No memory for opp array\n", __func__);
> -		return ERR_PTR(-ENOMEM);
> +		return -ENOMEM;
>  	}
>  
> -	opp = oppl;
> +
> +	_opp_list[opp_type] = oppl;
>  	while (n) {
> -		omap_opp_populate(opp, opp_defs);
> -		opp->opp_id = i;
> +		omap_opp_populate(oppl, opp_defs);
> +		oppl->opp_id = i;
>  		n--;
> -		opp++;
> +		oppl++;
>  		opp_defs++;
>  		i++;
>  	}
>  
>  	/* Terminator implicitly added by kzalloc() */
>  
> -	return oppl;
> +	return 0;
>  }
>  
>  int opp_enable(struct omap_opp *opp)
> @@ -308,20 +353,21 @@ int opp_disable(struct omap_opp *opp)
>  }
>  
>  /* XXX document */
> -void opp_init_cpufreq_table(struct omap_opp *opps,
> +void opp_init_cpufreq_table(enum opp_t opp_type,
>  			    struct cpufreq_frequency_table **table)
>  {
>  	int i = 0, j;
>  	int opp_num;
>  	struct cpufreq_frequency_table *freq_table;
> +	struct omap_opp *opp;
>  
> -	if (!opps) {
> +	if (opp_type >= OPP_TYPES_MAX) {
>  		pr_warning("%s: failed to initialize frequency"
>  				"table\n", __func__);
>  		return;
>  	}
>  
> -	opp_num = opp_get_opp_count(opps);
> +	opp_num = opp_get_opp_count(opp_type);
>  	if (opp_num < 0) {
>  		pr_err("%s: no opp table?\n", __func__);
>  		return;
> @@ -335,14 +381,15 @@ void opp_init_cpufreq_table(struct omap_opp *opps,
>  		return;
>  	}
>  
> +	opp = _opp_list[opp_type];
> +	opp += opp_num;
>  	for (j = opp_num; j >= 0; j--) {
> -		struct omap_opp *opp = &opps[j];
> -
>  		if (opp->enabled) {
>  			freq_table[i].index = i;
>  			freq_table[i].frequency = opp->rate / 1000;
>  			i++;
>  		}
> +		opp--;
>  	}
>  
>  	freq_table[i].index = i;
> -- 
> 1.6.3.3

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2010-02-04 19:36 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-01-28 20:40 [PM-WIP-OPP][PATCH v4] omap: pm: Introducing enum for OPP types Nishanth Menon
2010-01-28 20:45 ` Nishanth Menon
2010-02-04 19:36 ` Kevin Hilman

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox