[PATCH 17/23] OMAP3: PM: Fixed VDD2 control to work from both sysfs and SRF API

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



SRF API for setting throughput requirement attempted to use throughput values
as parameter to set_opp() and sysfs was attempting to use OPP levels (1..3.)

Signed-off-by: Tero Kristo <tero.kristo@xxxxxxxxx>
---
 arch/arm/mach-omap2/pm.c                   |    5 +-
 arch/arm/mach-omap2/pm.h                   |    1 +
 arch/arm/mach-omap2/resource34xx.c         |   62 ++++++++++++++++++----------
 arch/arm/plat-omap/include/mach/omap34xx.h |    4 ++
 4 files changed, 47 insertions(+), 25 deletions(-)

diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 285f596..2dd1341 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -61,7 +61,6 @@ static struct kobj_attribute voltage_off_while_idle_attr =
 	__ATTR(voltage_off_while_idle, 0644, idle_show, idle_store);
 
 #ifdef CONFIG_OMAP_PM_SRF
-static struct device dummy_sysfs_dev;
 static ssize_t vdd_opp_show(struct kobject *, struct kobj_attribute *, char *);
 static ssize_t vdd_opp_store(struct kobject *k, struct kobj_attribute *,
 			  const char *buf, size_t n);
@@ -145,13 +144,13 @@ static ssize_t vdd_opp_store(struct kobject *kobj, struct kobj_attribute *attr,
 			printk(KERN_ERR "vdd_opp_store: Invalid value\n");
 			return -EINVAL;
 		}
-		resource_request("vdd1_opp", &dummy_sysfs_dev, value);
+		set_opp_level(VDD1_OPP, value);
 	} else if (attr == &vdd2_opp_attr) {
 		if (value < 2 || value > 3) {
 			printk(KERN_ERR "vdd_opp_store: Invalid value\n");
 			return -EINVAL;
 		}
-		resource_request("vdd2_opp", &dummy_sysfs_dev, value);
+		set_opp_level(VDD2_OPP, value);
 	} else {
 		return -EINVAL;
 	}
diff --git a/arch/arm/mach-omap2/pm.h b/arch/arm/mach-omap2/pm.h
index a209819..4c0052f 100644
--- a/arch/arm/mach-omap2/pm.h
+++ b/arch/arm/mach-omap2/pm.h
@@ -42,6 +42,7 @@ extern int omap3_pm_set_suspend_state(struct powerdomain *pwrdm, int state);
 #define omap3_pm_set_suspend_state(pwrdm,state) do {} while (0);
 #endif
 extern int set_pwrdm_state(struct powerdomain *pwrdm, u32 state);
+extern int set_opp_level(int res, u32 target_level);
 
 #ifdef CONFIG_PM_DEBUG
 extern void omap2_pm_dump(int mode, int resume, unsigned int us);
diff --git a/arch/arm/mach-omap2/resource34xx.c b/arch/arm/mach-omap2/resource34xx.c
index 034318b..d2c4e1f 100644
--- a/arch/arm/mach-omap2/resource34xx.c
+++ b/arch/arm/mach-omap2/resource34xx.c
@@ -135,6 +135,8 @@ int set_pd_latency(struct shared_resource *resp, u32 latency)
 
 static struct clk *vdd1_clk;
 static struct clk *vdd2_clk;
+static struct shared_resource *vdd1_resp;
+static struct shared_resource *vdd2_resp;
 static struct device dummy_mpu_dev;
 static struct device dummy_dsp_dev;
 
@@ -154,19 +156,27 @@ void init_opp(struct shared_resource *resp)
 	if (strcmp(resp->name, "vdd1_opp") == 0) {
 		resp->curr_level = curr_vdd1_prcm_set->opp_id;
 		vdd1_clk = clk_get(NULL, "virt_vdd1_prcm_set");
+		vdd1_resp = resp;
 	} else if (strcmp(resp->name, "vdd2_opp") == 0) {
 		resp->curr_level = curr_vdd2_prcm_set->opp_id;
 		vdd2_clk = clk_get(NULL, "virt_vdd2_prcm_set");
+		vdd2_resp = resp;
 	}
 	return;
 }
 
-int set_opp(struct shared_resource *resp, u32 target_level)
+int set_opp_level(int res, u32 target_level)
 {
-	unsigned long mpu_freq, mpu_old_freq, l3_freq, tput, t_opp;
-	int ind;
-	struct bus_throughput_db *tput_db;
+	unsigned long mpu_freq, mpu_old_freq, l3_freq, t_opp;
 	struct cpufreq_freqs freqs_notify;
+	struct shared_resource *resp;
+
+	if (res == VDD1_OPP)
+		resp = vdd1_resp;
+	else if (res == VDD2_OPP)
+		resp = vdd2_resp;
+	else
+		return 0;
 
 	if (resp->curr_level == target_level)
 		return 0;
@@ -174,7 +184,7 @@ int set_opp(struct shared_resource *resp, u32 target_level)
 	if (!mpu_opps || !dsp_opps || !l3_opps)
 		return 0;
 
-	if (strcmp(resp->name, "vdd1_opp") == 0) {
+	if (res == VDD1_OPP) {
 		mpu_old_freq = get_freq(mpu_opps + MAX_VDD1_OPP,
 					curr_vdd1_prcm_set->opp_id);
 		mpu_freq = get_freq(mpu_opps + MAX_VDD1_OPP,
@@ -208,23 +218,7 @@ int set_opp(struct shared_resource *resp, u32 target_level)
 		/* Send a post notification to CPUFreq */
 		cpufreq_notify_transition(&freqs_notify, CPUFREQ_POSTCHANGE);
 #endif
-	} else if (strcmp(resp->name, "vdd2_opp") == 0) {
-		tput_db = resp->resource_data;
-		tput = target_level;
-		/* using the throughput db map to the appropriate L3 Freq */
-		for (ind = 1; ind < MAX_VDD2_OPP; ind++)
-			if (tput_db->throughput[ind] > tput)
-				target_level = ind;
-
-		/* Set the highest OPP possible */
-		if (ind == MAX_VDD2_OPP)
-			target_level = ind-1;
-
-		if (resp->curr_level == target_level)
-			return 0;
-
-		resp->curr_level = target_level;
-
+	} else {
 		l3_freq = get_freq(l3_opps + MAX_VDD2_OPP,
 					target_level);
 		t_opp = ID_VDD(PRCM_VDD2) |
@@ -249,6 +243,30 @@ int set_opp(struct shared_resource *resp, u32 target_level)
 	return 0;
 }
 
+int set_opp(struct shared_resource *resp, u32 target_level)
+{
+	unsigned long tput;
+	int ind;
+	struct bus_throughput_db *tput_db;
+
+	if (resp == vdd1_resp) {
+		set_opp_level(VDD1_OPP, target_level);
+	} else if (resp == vdd2_resp) {
+		tput_db = resp->resource_data;
+		tput = target_level;
+		/* using the throughput db map to the appropriate L3 Freq */
+		for (ind = 1; ind < MAX_VDD2_OPP; ind++)
+			if (tput_db->throughput[ind] > tput)
+				target_level = ind;
+
+		/* Set the highest OPP possible */
+		if (ind == MAX_VDD2_OPP)
+			target_level = ind-1;
+		set_opp_level(VDD2_OPP, target_level);
+	}
+	return 0;
+}
+
 /**
  * validate_opp - Validates if valid VDD1 OPP's are passed as the
  * target_level.
diff --git a/arch/arm/plat-omap/include/mach/omap34xx.h b/arch/arm/plat-omap/include/mach/omap34xx.h
index b64375e..6db9a6c 100644
--- a/arch/arm/plat-omap/include/mach/omap34xx.h
+++ b/arch/arm/plat-omap/include/mach/omap34xx.h
@@ -72,6 +72,10 @@
 #define OMAP34XX_DSP_IPI_BASE	(OMAP34XX_DSP_BASE + 0x1000000)
 #define OMAP34XX_DSP_MMU_BASE	(OMAP34XX_DSP_BASE + 0x2000000)
 
+/* VDD OPP identifiers */
+#define VDD1_OPP	0x1
+#define VDD2_OPP	0x2
+
 /* VDD1 OPPS */
 #define VDD1_OPP1	0x1
 #define VDD1_OPP2	0x2
-- 
1.5.4.3

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

[Index of Archives]     [Linux Arm (vger)]     [ARM Kernel]     [ARM MSM]     [Linux Tegra]     [Linux WPAN Networking]     [Linux Wireless Networking]     [Maemo Users]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite Trails]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux