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 <[EMAIL PROTECTED]>
---
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 [EMAIL PROTECTED]
More majordomo info at http://vger.kernel.org/majordomo-info.html