Merge branch 'tip/perf/jump-label-2' of git://git.kernel.org/pub/scm/linux/kernel...
[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         int ret = 0;
52         struct clk *iclk, *fclk;
53
54         dev_dbg(dev, "%s\n", __func__);
55
56         iclk = clk_get(dev, "ick");
57         if (!IS_ERR(iclk)) {
58                 clk_enable(iclk);
59                 clk_put(iclk);
60         }
61
62         fclk = clk_get(dev, "fck");
63         if (!IS_ERR(fclk)) {
64                 clk_enable(fclk);
65                 clk_put(fclk);
66         }
67
68         return pm_generic_runtime_resume(dev);
69 };
70
71 static int __init omap1_pm_runtime_init(void)
72 {
73         const struct dev_pm_ops *pm;
74         struct dev_pm_ops *omap_pm;
75
76         pm = platform_bus_get_pm_ops();
77         if (!pm) {
78                 pr_err("%s: unable to get dev_pm_ops from platform_bus\n",
79                         __func__);
80                 return -ENODEV;
81         }
82
83         omap_pm = kmemdup(pm, sizeof(struct dev_pm_ops), GFP_KERNEL);
84         if (!omap_pm) {
85                 pr_err("%s: unable to alloc memory for new dev_pm_ops\n",
86                         __func__);
87                 return -ENOMEM;
88         }
89
90         omap_pm->runtime_suspend = omap1_pm_runtime_suspend;
91         omap_pm->runtime_resume = omap1_pm_runtime_resume;
92
93         platform_bus_set_pm_ops(omap_pm);
94
95         return 0;
96 }
97 core_initcall(omap1_pm_runtime_init);
98 #endif /* CONFIG_PM_RUNTIME */