aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm')
-rw-r--r--arch/arm/mach-shmobile/pm_runtime.c140
1 files changed, 9 insertions, 131 deletions
diff --git a/arch/arm/mach-shmobile/pm_runtime.c b/arch/arm/mach-shmobile/pm_runtime.c
index 30bbe9a99ae1..2d1b67a59e4a 100644
--- a/arch/arm/mach-shmobile/pm_runtime.c
+++ b/arch/arm/mach-shmobile/pm_runtime.c
@@ -21,70 +21,6 @@
21#include <linux/slab.h> 21#include <linux/slab.h>
22 22
23#ifdef CONFIG_PM_RUNTIME 23#ifdef CONFIG_PM_RUNTIME
24#define BIT_ONCE 0
25#define BIT_ACTIVE 1
26#define BIT_CLK_ENABLED 2
27
28struct pm_runtime_data {
29 unsigned long flags;
30 struct clk *clk;
31};
32
33static struct pm_runtime_data *__to_prd(struct device *dev)
34{
35 return dev ? dev->power.subsys_data : NULL;
36}
37
38static void platform_pm_runtime_init(struct device *dev,
39 struct pm_runtime_data *prd)
40{
41 if (prd && !test_and_set_bit(BIT_ONCE, &prd->flags)) {
42 prd->clk = clk_get(dev, NULL);
43 if (!IS_ERR(prd->clk)) {
44 set_bit(BIT_ACTIVE, &prd->flags);
45 dev_info(dev, "clocks managed by runtime pm\n");
46 }
47 }
48}
49
50static void platform_pm_runtime_bug(struct device *dev,
51 struct pm_runtime_data *prd)
52{
53 if (prd && !test_and_set_bit(BIT_ONCE, &prd->flags))
54 dev_err(dev, "runtime pm suspend before resume\n");
55}
56
57static int default_platform_runtime_suspend(struct device *dev)
58{
59 struct pm_runtime_data *prd = __to_prd(dev);
60
61 dev_dbg(dev, "%s()\n", __func__);
62
63 platform_pm_runtime_bug(dev, prd);
64
65 if (prd && test_bit(BIT_ACTIVE, &prd->flags)) {
66 clk_disable(prd->clk);
67 clear_bit(BIT_CLK_ENABLED, &prd->flags);
68 }
69
70 return 0;
71}
72
73static int default_platform_runtime_resume(struct device *dev)
74{
75 struct pm_runtime_data *prd = __to_prd(dev);
76
77 dev_dbg(dev, "%s()\n", __func__);
78
79 platform_pm_runtime_init(dev, prd);
80
81 if (prd && test_bit(BIT_ACTIVE, &prd->flags)) {
82 clk_enable(prd->clk);
83 set_bit(BIT_CLK_ENABLED, &prd->flags);
84 }
85
86 return 0;
87}
88 24
89static int default_platform_runtime_idle(struct device *dev) 25static int default_platform_runtime_idle(struct device *dev)
90{ 26{
@@ -94,87 +30,29 @@ static int default_platform_runtime_idle(struct device *dev)
94 30
95static struct dev_power_domain default_power_domain = { 31static struct dev_power_domain default_power_domain = {
96 .ops = { 32 .ops = {
97 .runtime_suspend = default_platform_runtime_suspend, 33 .runtime_suspend = pm_runtime_clk_suspend,
98 .runtime_resume = default_platform_runtime_resume, 34 .runtime_resume = pm_runtime_clk_resume,
99 .runtime_idle = default_platform_runtime_idle, 35 .runtime_idle = default_platform_runtime_idle,
100 USE_PLATFORM_PM_SLEEP_OPS 36 USE_PLATFORM_PM_SLEEP_OPS
101 }, 37 },
102}; 38};
103 39
104static int platform_bus_notify(struct notifier_block *nb, 40#define DEFAULT_PWR_DOMAIN_PTR (&default_power_domain)
105 unsigned long action, void *data)
106{
107 struct device *dev = data;
108 struct pm_runtime_data *prd;
109
110 dev_dbg(dev, "platform_bus_notify() %ld !\n", action);
111
112 switch (action) {
113 case BUS_NOTIFY_BIND_DRIVER:
114 prd = kzalloc(sizeof(*prd), GFP_KERNEL);
115 if (prd) {
116 dev->power.subsys_data = prd;
117 dev->pwr_domain = &default_power_domain;
118 } else {
119 dev_err(dev, "unable to alloc memory for runtime pm\n");
120 }
121 break;
122 case BUS_NOTIFY_UNBOUND_DRIVER:
123 prd = __to_prd(dev);
124 if (prd) {
125 if (test_bit(BIT_CLK_ENABLED, &prd->flags))
126 clk_disable(prd->clk);
127 41
128 if (test_bit(BIT_ACTIVE, &prd->flags)) 42#else
129 clk_put(prd->clk);
130 }
131 break;
132 }
133 43
134 return 0; 44#define DEFAULT_PWR_DOMAIN_PTR NULL
135}
136
137#else /* CONFIG_PM_RUNTIME */
138
139static int platform_bus_notify(struct notifier_block *nb,
140 unsigned long action, void *data)
141{
142 struct device *dev = data;
143 struct clk *clk;
144
145 dev_dbg(dev, "platform_bus_notify() %ld !\n", action);
146
147 switch (action) {
148 case BUS_NOTIFY_BIND_DRIVER:
149 clk = clk_get(dev, NULL);
150 if (!IS_ERR(clk)) {
151 clk_enable(clk);
152 clk_put(clk);
153 dev_info(dev, "runtime pm disabled, clock forced on\n");
154 }
155 break;
156 case BUS_NOTIFY_UNBOUND_DRIVER:
157 clk = clk_get(dev, NULL);
158 if (!IS_ERR(clk)) {
159 clk_disable(clk);
160 clk_put(clk);
161 dev_info(dev, "runtime pm disabled, clock forced off\n");
162 }
163 break;
164 }
165
166 return 0;
167}
168 45
169#endif /* CONFIG_PM_RUNTIME */ 46#endif /* CONFIG_PM_RUNTIME */
170 47
171static struct notifier_block platform_bus_notifier = { 48static struct pm_clk_notifier_block platform_bus_notifier = {
172 .notifier_call = platform_bus_notify 49 .pwr_domain = DEFAULT_PWR_DOMAIN_PTR,
50 .con_ids = { NULL, },
173}; 51};
174 52
175static int __init sh_pm_runtime_init(void) 53static int __init sh_pm_runtime_init(void)
176{ 54{
177 bus_register_notifier(&platform_bus_type, &platform_bus_notifier); 55 pm_runtime_clk_add_notifier(&platform_bus_type, &platform_bus_notifier);
178 return 0; 56 return 0;
179} 57}
180core_initcall(sh_pm_runtime_init); 58core_initcall(sh_pm_runtime_init);