Merge git://git.kernel.org/pub/scm/linux/kernel/git/mason/btrfs-unstable
[pandora-kernel.git] / arch / arm / mach-omap1 / pm_bus.c
1 /*
2  * Runtime PM support code for OMAP1
3  *
4  * Author: Kevin Hilman, Deep Root Systems, LLC
5  *
6  * Copyright (C) 2010 Texas Instruments, Inc.
7  *
8  * This file is licensed under the terms of the GNU General Public
9  * License version 2. This program is licensed "as is" without any
10  * warranty of any kind, whether express or implied.
11  */
12 #include <linux/init.h>
13 #include <linux/kernel.h>
14 #include <linux/io.h>
15 #include <linux/pm_runtime.h>
16 #include <linux/platform_device.h>
17 #include <linux/mutex.h>
18 #include <linux/clk.h>
19 #include <linux/err.h>
20
21 #include <plat/omap_device.h>
22 #include <plat/omap-pm.h>
23
24 #ifdef CONFIG_PM_RUNTIME
25 static int omap1_pm_runtime_suspend(struct device *dev)
26 {
27         struct clk *iclk, *fclk;
28         int ret = 0;
29
30         dev_dbg(dev, "%s\n", __func__);
31
32         ret = pm_generic_runtime_suspend(dev);
33
34         fclk = clk_get(dev, "fck");
35         if (!IS_ERR(fclk)) {
36                 clk_disable(fclk);
37                 clk_put(fclk);
38         }
39
40         iclk = clk_get(dev, "ick");
41         if (!IS_ERR(iclk)) {
42                 clk_disable(iclk);
43                 clk_put(iclk);
44         }
45
46         return 0;
47 };
48
49 static int omap1_pm_runtime_resume(struct device *dev)
50 {
51         struct clk *iclk, *fclk;
52
53         dev_dbg(dev, "%s\n", __func__);
54
55         iclk = clk_get(dev, "ick");
56         if (!IS_ERR(iclk)) {
57                 clk_enable(iclk);
58                 clk_put(iclk);
59         }
60
61         fclk = clk_get(dev, "fck");
62         if (!IS_ERR(fclk)) {
63                 clk_enable(fclk);
64                 clk_put(fclk);
65         }
66
67         return pm_generic_runtime_resume(dev);
68 };
69
70 static int __init omap1_pm_runtime_init(void)
71 {
72         const struct dev_pm_ops *pm;
73         struct dev_pm_ops *omap_pm;
74
75         if (!cpu_class_is_omap1())
76                 return -ENODEV;
77
78         pm = platform_bus_get_pm_ops();
79         if (!pm) {
80                 pr_err("%s: unable to get dev_pm_ops from platform_bus\n",
81                         __func__);
82                 return -ENODEV;
83         }
84
85         omap_pm = kmemdup(pm, sizeof(struct dev_pm_ops), GFP_KERNEL);
86         if (!omap_pm) {
87                 pr_err("%s: unable to alloc memory for new dev_pm_ops\n",
88                         __func__);
89                 return -ENOMEM;
90         }
91
92         omap_pm->runtime_suspend = omap1_pm_runtime_suspend;
93         omap_pm->runtime_resume = omap1_pm_runtime_resume;
94
95         platform_bus_set_pm_ops(omap_pm);
96
97         return 0;
98 }
99 core_initcall(omap1_pm_runtime_init);
100 #endif /* CONFIG_PM_RUNTIME */