blob: 6588c22b8a64116dd11004001e2682aa14fe423e [file] [log] [blame]
Kevin Hilmane933ec72010-06-17 15:48:43 -07001/*
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
25static 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
49static int omap1_pm_runtime_resume(struct device *dev)
50{
Kevin Hilmane933ec72010-06-17 15:48:43 -070051 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
70static int __init omap1_pm_runtime_init(void)
71{
72 const struct dev_pm_ops *pm;
73 struct dev_pm_ops *omap_pm;
74
Tony Lindgren7f9187c2010-12-10 09:46:24 -080075 if (!cpu_class_is_omap1())
76 return -ENODEV;
77
Kevin Hilmane933ec72010-06-17 15:48:43 -070078 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}
99core_initcall(omap1_pm_runtime_init);
100#endif /* CONFIG_PM_RUNTIME */