Adds sysfs hooks to control VDD1 and VDD2 OPP's in the absense of a CPUFreq driver/governor Signed-off-by: Rajendra Nayak <rnayak@xxxxxx> --- arch/arm/mach-omap2/pm.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 67 insertions(+), 1 deletion(-) Index: linux-omap-2.6/arch/arm/mach-omap2/pm.c =================================================================== --- linux-omap-2.6.orig/arch/arm/mach-omap2/pm.c 2008-11-10 15:24:50.000000000 +0530 +++ linux-omap-2.6/arch/arm/mach-omap2/pm.c 2008-11-10 15:44:19.000000000 +0530 @@ -24,6 +24,7 @@ #include <linux/suspend.h> #include <linux/time.h> #include <linux/platform_device.h> +#include <linux/device.h> #include <mach/cpu.h> #include <asm/mach/time.h> @@ -32,6 +33,7 @@ #include <mach/pm.h> #include <mach/powerdomain.h> #include <mach/omapdev.h> +#include <mach/resource.h> #include "prm-regbits-34xx.h" #include "pm.h" @@ -58,6 +60,18 @@ static struct kobj_attribute enable_off_ 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); +static struct kobj_attribute vdd1_opp_attr = + __ATTR(vdd1_opp, 0644, vdd_opp_show, vdd_opp_store); + +static struct kobj_attribute vdd2_opp_attr = + __ATTR(vdd2_opp, 0644, vdd_opp_show, vdd_opp_store); +#endif + static ssize_t idle_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { @@ -106,6 +120,45 @@ static ssize_t idle_store(struct kobject return n; } +#ifdef CONFIG_OMAP_PM_SRF +static ssize_t vdd_opp_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +{ + if (attr == &vdd1_opp_attr) + return sprintf(buf, "%hu\n", resource_get_level("vdd1_opp")); + else if (attr == &vdd2_opp_attr) + return sprintf(buf, "%hu\n", resource_get_level("vdd2_opp")); + else + return -EINVAL; +} + +static ssize_t vdd_opp_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t n) +{ + unsigned short value; + + if (sscanf(buf, "%hu", &value) != 1) + return -EINVAL; + + if (attr == &vdd1_opp_attr) { + if (value < 1 || value > 5) { + printk(KERN_ERR "vdd_opp_store: Invalid value\n"); + return -EINVAL; + } + resource_request("vdd1_opp", &dummy_sysfs_dev, 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); + } else { + return -EINVAL; + } + return n; +} +#endif + void omap2_block_sleep(void) { atomic_inc(&sleep_block); @@ -162,7 +215,20 @@ static int __init omap_pm_init(void) printk(KERN_ERR "sysfs_create_file failed: %d\n", error); return error; } - +#ifdef CONFIG_OMAP_PM_SRF + error = sysfs_create_file(power_kobj, + &vdd1_opp_attr.attr); + if (error) { + printk(KERN_ERR "sysfs_create_file failed: %d\n", error); + return error; + } + error = sysfs_create_file(power_kobj, + &vdd2_opp_attr.attr); + if (error) { + printk(KERN_ERR "sysfs_create_file failed: %d\n", error); + return error; + } +#endif voltage_off_while_idle = 0; /* Going to 0V on anything under ES2.1 will eventually cause a crash */ if (system_rev > OMAP3430_REV_ES2_0) { -- 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