OMAP3 SRF: Fix crash on non-3430SDP platforms with DVFS/CPUFreq
[linux-ginger.git] / arch / arm / mach-omap2 / pm.c
blobc530dd767f44dbfda213be2f8bbe68963762dd79
1 /*
2 * linux/arch/arm/mach-omap2/pm.c
4 * OMAP Power Management Common Routines
6 * Copyright (C) 2005 Texas Instruments, Inc.
7 * Copyright (C) 2006-2008 Nokia Corporation
9 * Written by:
10 * Richard Woodruff <r-woodruff2@ti.com>
11 * Tony Lindgren
12 * Juha Yrjola
13 * Amit Kucheria <amit.kucheria@nokia.com>
14 * Igor Stoppa <igor.stoppa@nokia.com>
15 * Jouni Hogander
17 * Based on pm.c for omap1
19 * This program is free software; you can redistribute it and/or modify
20 * it under the terms of the GNU General Public License version 2 as
21 * published by the Free Software Foundation.
24 #include <linux/suspend.h>
25 #include <linux/time.h>
26 #include <linux/platform_device.h>
27 #include <linux/device.h>
29 #include <plat/cpu.h>
30 #include <asm/mach/time.h>
31 #include <asm/atomic.h>
33 #include <plat/powerdomain.h>
34 #include <plat/omapdev.h>
35 #include <plat/resource.h>
37 #include "prm-regbits-34xx.h"
38 #include "pm.h"
40 atomic_t sleep_block = ATOMIC_INIT(0);
42 static ssize_t idle_show(struct kobject *, struct kobj_attribute *, char *);
43 static ssize_t idle_store(struct kobject *k, struct kobj_attribute *,
44 const char *buf, size_t n);
46 #ifdef CONFIG_OMAP_PM_SRF
47 static struct device dummy_sysfs_dev;
48 static ssize_t vdd_opp_show(struct kobject *, struct kobj_attribute *, char *);
49 static ssize_t vdd_opp_store(struct kobject *k, struct kobj_attribute *,
50 const char *buf, size_t n);
51 static struct kobj_attribute vdd1_opp_attr =
52 __ATTR(vdd1_opp, 0644, vdd_opp_show, vdd_opp_store);
54 static struct kobj_attribute vdd2_opp_attr =
55 __ATTR(vdd2_opp, 0644, vdd_opp_show, vdd_opp_store);
56 #endif
58 static ssize_t idle_show(struct kobject *kobj, struct kobj_attribute *attr,
59 char *buf)
61 return -EINVAL;
64 static ssize_t idle_store(struct kobject *kobj, struct kobj_attribute *attr,
65 const char *buf, size_t n)
67 unsigned short value;
69 if (sscanf(buf, "%hu", &value) != 1 ||
70 (value != 0 && value != 1)) {
71 printk(KERN_ERR "idle_store: Invalid value\n");
72 return -EINVAL;
75 return n;
78 #ifdef CONFIG_OMAP_PM_SRF
79 static ssize_t vdd_opp_show(struct kobject *kobj, struct kobj_attribute *attr,
80 char *buf)
82 if (attr == &vdd1_opp_attr)
83 return sprintf(buf, "%hu\n", resource_get_level("vdd1_opp"));
84 else if (attr == &vdd2_opp_attr)
85 return sprintf(buf, "%hu\n", resource_get_level("vdd2_opp"));
86 else
87 return -EINVAL;
90 static ssize_t vdd_opp_store(struct kobject *kobj, struct kobj_attribute *attr,
91 const char *buf, size_t n)
93 unsigned short value;
95 if (sscanf(buf, "%hu", &value) != 1)
96 return -EINVAL;
98 if (attr == &vdd1_opp_attr) {
99 if (value < 1 || value > 5) {
100 printk(KERN_ERR "vdd_opp_store: Invalid value\n");
101 return -EINVAL;
103 resource_request("vdd1_opp", &dummy_sysfs_dev, value);
104 } else if (attr == &vdd2_opp_attr) {
105 if (value < 2 || value > 3) {
106 printk(KERN_ERR "vdd_opp_store: Invalid value\n");
107 return -EINVAL;
109 resource_request("vdd2_opp", &dummy_sysfs_dev, value);
110 } else {
111 return -EINVAL;
113 return n;
115 #endif
117 void omap2_block_sleep(void)
119 atomic_inc(&sleep_block);
122 void omap2_allow_sleep(void)
124 int i;
126 i = atomic_dec_return(&sleep_block);
127 BUG_ON(i < 0);
130 unsigned get_last_off_on_transaction_id(struct device *dev)
132 struct platform_device *pdev = to_platform_device(dev);
133 struct omapdev *odev = omapdev_find_pdev(pdev);
134 struct powerdomain *pwrdm;
136 if (odev) {
137 pwrdm = omapdev_get_pwrdm(odev);
138 if (pwrdm)
139 return pwrdm->state_counter[0];
142 return 0;
145 static int __init omap_pm_init(void)
147 int error = -1;
149 #ifdef CONFIG_OMAP_PM_SRF
150 error = sysfs_create_file(power_kobj,
151 &vdd1_opp_attr.attr);
152 if (error) {
153 printk(KERN_ERR "sysfs_create_file failed: %d\n", error);
154 return error;
156 error = sysfs_create_file(power_kobj,
157 &vdd2_opp_attr.attr);
158 if (error) {
159 printk(KERN_ERR "sysfs_create_file failed: %d\n", error);
160 return error;
162 #endif
164 return error;
166 late_initcall(omap_pm_init);