diff mbox

[RFC] OMAP3 PM: sysfs vdd_opp change to use Constraint Framework

Message ID FCCFB4CDC6E5564B9182F639FC35608702FA174C99@dbde02.ent.ti.com (mailing list archive)
State Not Applicable
Delegated to: Kevin Hilman
Headers show

Commit Message

Sripathy, Vishwanath Oct. 16, 2009, 7:27 p.m. UTC
None
diff mbox

Patch

diff --git a/arch/arm/mach-omap2/pm.c b/arch/arm/mach-omap2/pm.c
index 13783f3..bcdc00d 100644
--- a/arch/arm/mach-omap2/pm.c
+++ b/arch/arm/mach-omap2/pm.c
@@ -47,6 +47,8 @@  static ssize_t idle_store(struct kobject *k, struct kobj_attribute *,
 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);
+static ssize_t vdd_opp_lock_store(struct kobject *k, struct kobj_attribute *,
+			  const char *buf, size_t n);
 static struct kobj_attribute vdd1_opp_attr =
 	__ATTR(vdd1_opp, 0644, vdd_opp_show, vdd_opp_store);
 
@@ -103,6 +105,41 @@  static ssize_t vdd_opp_store(struct kobject *kobj, struct kobj_attribute *attr,
 			  const char *buf, size_t n)
 {
 	unsigned short value;
+	struct omap_opp *opp_table;
+
+	if (sscanf(buf, "%hu", &value) != 1)
+		return -EINVAL;
+
+	if (attr == &vdd1_opp_attr) {
+		if (value < MIN_VDD1_OPP || value > MAX_VDD1_OPP) {
+			printk(KERN_ERR "vdd_opp_store: Invalid value\n");
+			return -EINVAL;
+		}
+		opp_table = omap_get_mpu_rate_table();
+		omap_pm_cpu_set_freq(&sysfs_cpufreq_dev,
+					opp_table[value].rate);
+	} else if (attr == &vdd2_opp_attr) {
+		if (value < MIN_VDD2_OPP || (value > MAX_VDD2_OPP)) {
+			printk(KERN_ERR "vdd_opp_store: Invalid value\n");
+			return -EINVAL;
+		}
+		if (value == VDD2_OPP2)
+			omap_pm_set_min_bus_tput(&sysfs_cpufreq_dev,
+					OCP_INITIATOR_AGENT, 83*1000*4);
+		else if (value == VDD2_OPP3)
+			omap_pm_set_min_bus_tput(&sysfs_cpufreq_dev,
+					OCP_INITIATOR_AGENT, 166*1000*4);
+
+	} else {
+		return -EINVAL;
+	}
+	return n;
+}
+
+static ssize_t vdd_opp_lock_store(struct kobject *kobj,
+	struct kobj_attribute *attr, const char *buf, size_t n)
+{
+	unsigned short value;
 	int flags = 0;
 
 	if (sscanf(buf, "%hu", &value) != 1)
@@ -121,6 +158,11 @@  static ssize_t vdd_opp_store(struct kobject *kobj, struct kobj_attribute *attr,
 		if (vdd1_locked == 0 && value != 0) {
 			resource_lock_opp(VDD1_OPP);
 			vdd1_locked = 1;
+			if (value < MIN_VDD1_OPP || value > MAX_VDD1_OPP) {
+				printk(KERN_ERR "vdd_opp_store: Invalid value\n");
+				return -EINVAL;
+				}
+		resource_set_opp_level(VDD1_OPP, value, flags);
 		}
 	} else if (attr == &vdd2_lock_attr) {
 		flags = OPP_IGNORE_LOCK;
@@ -134,21 +176,12 @@  static ssize_t vdd_opp_store(struct kobject *kobj, struct kobj_attribute *attr,
 		if (vdd2_locked == 0 && value != 0) {
 			resource_lock_opp(VDD2_OPP);
 			vdd2_locked = 1;
+			if (value < MIN_VDD2_OPP || value > MAX_VDD2_OPP) {
+				printk(KERN_ERR "vdd_opp_store: Invalid value\n");
+				return -EINVAL;
+			}
+			resource_set_opp_level(VDD2_OPP, value, flags);
 		}
-	}
-
-	if (attr == &vdd1_opp_attr) {
-		if (value < 1 || value > 5) {
-			printk(KERN_ERR "vdd_opp_store: Invalid value\n");
-			return -EINVAL;
-		}
-		resource_set_opp_level(VDD1_OPP, value, flags);
-	} else if (attr == &vdd2_opp_attr) {
-		if (value < 2 || value > 3) {
-			printk(KERN_ERR "vdd_opp_store: Invalid value\n");
-			return -EINVAL;
-		}
-		resource_set_opp_level(VDD2_OPP, value, flags);
 	} else {
 		return -EINVAL;
 	}