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 | 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 majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html