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                   |    8 +--
 arch/arm/mach-omap2/pm.h                   |    1 +
 arch/arm/mach-omap2/resource34xx.c         |   70 +++++++++++++++++----------
 arch/arm/plat-omap/include/mach/omap34xx.h |    4 ++
 4 files changed, 51 insertions(+), 32 deletions(-)

diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 3429531..d33eba8 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -62,7 +62,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);
@@ -137,7 +136,6 @@ static ssize_t vdd_opp_store(struct kobject *kobj, struct 
kobj_attribute *attr,
                          const char *buf, size_t n)
 {
        unsigned short value;
-       unsigned long bus_tput;
 
        if (sscanf(buf, "%hu", &value) != 1)
                return -EINVAL;
@@ -147,15 +145,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;
                }
-               /* Convert OPP's requested to appr. bus throughtput in KiB/s */
-               bus_tput = ((l3_opps + value)->rate/1000) * 4;
-               resource_request("vdd2_opp", &dummy_sysfs_dev, bus_tput);
+               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 cb9bff0..15e6d89 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,20 +156,29 @@ 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;
 }
 
 static struct device vdd2_dev;
 
-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, req_l3_freq, tput, t_opp;
-       int ind;
+       unsigned long mpu_freq, mpu_old_freq, l3_freq, req_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;
@@ -175,7 +186,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,
@@ -222,28 +233,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 = target_level;
-
-               /* Convert the tput in KiB/s to Bus frequency in Mhz*/
-               req_l3_freq = (tput * 1000)/4;
-
-               for (ind = 2; ind <= MAX_VDD2_OPP; ind++) {
-                       if ((l3_opps + ind)->rate >= req_l3_freq) {
-                               target_level = ind;
-                               break;
-                       }
-               }
-
-               /* Set the highest OPP possible */
-               if (ind > MAX_VDD2_OPP)
-                       target_level = MAX_VDD2_OPP;
-
-               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) |
@@ -268,6 +258,34 @@ 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;
+       unsigned long req_l3_freq;
+       int ind;
+
+       if (resp == vdd1_resp) {
+               set_opp_level(VDD1_OPP, target_level);
+       } else if (resp == vdd2_resp) {
+               tput = target_level;
+
+               /* Convert the tput in KiB/s to Bus frequency in MHz */
+               req_l3_freq = (tput * 1000)/4;
+
+               for (ind = 2; ind <= MAX_VDD2_OPP; ind++)
+                       if ((l3_opps + ind)->rate >= req_l3_freq) {
+                               target_level = ind;
+                               break;
+                       }
+
+               /* 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 2e4e4ed..382e741 100644
--- a/arch/arm/plat-omap/include/mach/omap34xx.h
+++ b/arch/arm/plat-omap/include/mach/omap34xx.h
@@ -74,6 +74,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

Reply via email to