aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRafael J. Wysocki <rjw@sisk.pl>2011-04-29 18:25:44 -0400
committerRafael J. Wysocki <rjw@sisk.pl>2011-04-29 18:25:44 -0400
commit85eb8c8d0b0900c073b0e6f89979ac9c439ade1a (patch)
treeff3486424b60bb8de28ef76655d65cd0c1180449
parent1d2b71f61b6a10216274e27b717becf9ae101fc7 (diff)
PM / Runtime: Generic clock manipulation rountines for runtime PM (v6)
Many different platforms and subsystems may want to disable device clocks during suspend and enable them during resume which is going to be done in a very similar way in all those cases. For this reason, provide generic routines for the manipulation of device clocks during suspend and resume. Convert the ARM shmobile platform to using the new routines. Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
-rw-r--r--arch/arm/mach-shmobile/pm_runtime.c140
-rw-r--r--drivers/base/power/Makefile1
-rw-r--r--drivers/base/power/clock_ops.c430
-rw-r--r--include/linux/pm_runtime.h42
-rw-r--r--kernel/power/Kconfig4
5 files changed, 486 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);
diff --git a/drivers/base/power/Makefile b/drivers/base/power/Makefile
index 118c1b92a511..06a7073f9027 100644
--- a/drivers/base/power/Makefile
+++ b/drivers/base/power/Makefile
@@ -3,6 +3,7 @@ obj-$(CONFIG_PM_SLEEP) += main.o wakeup.o
3obj-$(CONFIG_PM_RUNTIME) += runtime.o 3obj-$(CONFIG_PM_RUNTIME) += runtime.o
4obj-$(CONFIG_PM_TRACE_RTC) += trace.o 4obj-$(CONFIG_PM_TRACE_RTC) += trace.o
5obj-$(CONFIG_PM_OPP) += opp.o 5obj-$(CONFIG_PM_OPP) += opp.o
6obj-$(CONFIG_HAVE_CLK) += clock_ops.o
6 7
7ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG 8ccflags-$(CONFIG_DEBUG_DRIVER) := -DDEBUG
8ccflags-$(CONFIG_PM_VERBOSE) += -DDEBUG 9ccflags-$(CONFIG_PM_VERBOSE) += -DDEBUG
diff --git a/drivers/base/power/clock_ops.c b/drivers/base/power/clock_ops.c
new file mode 100644
index 000000000000..d74abf334391
--- /dev/null
+++ b/drivers/base/power/clock_ops.c
@@ -0,0 +1,430 @@
1/*
2 * drivers/base/power/clock_ops.c - Generic clock manipulation PM callbacks
3 *
4 * Copyright (c) 2011 Rafael J. Wysocki <rjw@sisk.pl>, Renesas Electronics Corp.
5 *
6 * This file is released under the GPLv2.
7 */
8
9#include <linux/init.h>
10#include <linux/kernel.h>
11#include <linux/io.h>
12#include <linux/pm.h>
13#include <linux/pm_runtime.h>
14#include <linux/clk.h>
15#include <linux/slab.h>
16#include <linux/err.h>
17
18#ifdef CONFIG_PM_RUNTIME
19
20struct pm_runtime_clk_data {
21 struct list_head clock_list;
22 struct mutex lock;
23};
24
25enum pce_status {
26 PCE_STATUS_NONE = 0,
27 PCE_STATUS_ACQUIRED,
28 PCE_STATUS_ENABLED,
29 PCE_STATUS_ERROR,
30};
31
32struct pm_clock_entry {
33 struct list_head node;
34 char *con_id;
35 struct clk *clk;
36 enum pce_status status;
37};
38
39static struct pm_runtime_clk_data *__to_prd(struct device *dev)
40{
41 return dev ? dev->power.subsys_data : NULL;
42}
43
44/**
45 * pm_runtime_clk_add - Start using a device clock for runtime PM.
46 * @dev: Device whose clock is going to be used for runtime PM.
47 * @con_id: Connection ID of the clock.
48 *
49 * Add the clock represented by @con_id to the list of clocks used for
50 * the runtime PM of @dev.
51 */
52int pm_runtime_clk_add(struct device *dev, const char *con_id)
53{
54 struct pm_runtime_clk_data *prd = __to_prd(dev);
55 struct pm_clock_entry *ce;
56
57 if (!prd)
58 return -EINVAL;
59
60 ce = kzalloc(sizeof(*ce), GFP_KERNEL);
61 if (!ce) {
62 dev_err(dev, "Not enough memory for clock entry.\n");
63 return -ENOMEM;
64 }
65
66 if (con_id) {
67 ce->con_id = kstrdup(con_id, GFP_KERNEL);
68 if (!ce->con_id) {
69 dev_err(dev,
70 "Not enough memory for clock connection ID.\n");
71 kfree(ce);
72 return -ENOMEM;
73 }
74 }
75
76 mutex_lock(&prd->lock);
77 list_add_tail(&ce->node, &prd->clock_list);
78 mutex_unlock(&prd->lock);
79 return 0;
80}
81
82/**
83 * __pm_runtime_clk_remove - Destroy runtime PM clock entry.
84 * @ce: Runtime PM clock entry to destroy.
85 *
86 * This routine must be called under the mutex protecting the runtime PM list
87 * of clocks corresponding the the @ce's device.
88 */
89static void __pm_runtime_clk_remove(struct pm_clock_entry *ce)
90{
91 if (!ce)
92 return;
93
94 list_del(&ce->node);
95
96 if (ce->status < PCE_STATUS_ERROR) {
97 if (ce->status == PCE_STATUS_ENABLED)
98 clk_disable(ce->clk);
99
100 if (ce->status >= PCE_STATUS_ACQUIRED)
101 clk_put(ce->clk);
102 }
103
104 if (ce->con_id)
105 kfree(ce->con_id);
106
107 kfree(ce);
108}
109
110/**
111 * pm_runtime_clk_remove - Stop using a device clock for runtime PM.
112 * @dev: Device whose clock should not be used for runtime PM any more.
113 * @con_id: Connection ID of the clock.
114 *
115 * Remove the clock represented by @con_id from the list of clocks used for
116 * the runtime PM of @dev.
117 */
118void pm_runtime_clk_remove(struct device *dev, const char *con_id)
119{
120 struct pm_runtime_clk_data *prd = __to_prd(dev);
121 struct pm_clock_entry *ce;
122
123 if (!prd)
124 return;
125
126 mutex_lock(&prd->lock);
127
128 list_for_each_entry(ce, &prd->clock_list, node) {
129 if (!con_id && !ce->con_id) {
130 __pm_runtime_clk_remove(ce);
131 break;
132 } else if (!con_id || !ce->con_id) {
133 continue;
134 } else if (!strcmp(con_id, ce->con_id)) {
135 __pm_runtime_clk_remove(ce);
136 break;
137 }
138 }
139
140 mutex_unlock(&prd->lock);
141}
142
143/**
144 * pm_runtime_clk_init - Initialize a device's list of runtime PM clocks.
145 * @dev: Device to initialize the list of runtime PM clocks for.
146 *
147 * Allocate a struct pm_runtime_clk_data object, initialize its lock member and
148 * make the @dev's power.subsys_data field point to it.
149 */
150int pm_runtime_clk_init(struct device *dev)
151{
152 struct pm_runtime_clk_data *prd;
153
154 prd = kzalloc(sizeof(*prd), GFP_KERNEL);
155 if (!prd) {
156 dev_err(dev, "Not enough memory fo runtime PM data.\n");
157 return -ENOMEM;
158 }
159
160 INIT_LIST_HEAD(&prd->clock_list);
161 mutex_init(&prd->lock);
162 dev->power.subsys_data = prd;
163 return 0;
164}
165
166/**
167 * pm_runtime_clk_destroy - Destroy a device's list of runtime PM clocks.
168 * @dev: Device to destroy the list of runtime PM clocks for.
169 *
170 * Clear the @dev's power.subsys_data field, remove the list of clock entries
171 * from the struct pm_runtime_clk_data object pointed to by it before and free
172 * that object.
173 */
174void pm_runtime_clk_destroy(struct device *dev)
175{
176 struct pm_runtime_clk_data *prd = __to_prd(dev);
177 struct pm_clock_entry *ce, *c;
178
179 if (!prd)
180 return;
181
182 dev->power.subsys_data = NULL;
183
184 mutex_lock(&prd->lock);
185
186 list_for_each_entry_safe_reverse(ce, c, &prd->clock_list, node)
187 __pm_runtime_clk_remove(ce);
188
189 mutex_unlock(&prd->lock);
190
191 kfree(prd);
192}
193
194/**
195 * pm_runtime_clk_acquire - Acquire a device clock.
196 * @dev: Device whose clock is to be acquired.
197 * @con_id: Connection ID of the clock.
198 */
199static void pm_runtime_clk_acquire(struct device *dev,
200 struct pm_clock_entry *ce)
201{
202 ce->clk = clk_get(dev, ce->con_id);
203 if (IS_ERR(ce->clk)) {
204 ce->status = PCE_STATUS_ERROR;
205 } else {
206 ce->status = PCE_STATUS_ACQUIRED;
207 dev_dbg(dev, "Clock %s managed by runtime PM.\n", ce->con_id);
208 }
209}
210
211/**
212 * pm_runtime_clk_suspend - Disable clocks in a device's runtime PM clock list.
213 * @dev: Device to disable the clocks for.
214 */
215int pm_runtime_clk_suspend(struct device *dev)
216{
217 struct pm_runtime_clk_data *prd = __to_prd(dev);
218 struct pm_clock_entry *ce;
219
220 dev_dbg(dev, "%s()\n", __func__);
221
222 if (!prd)
223 return 0;
224
225 mutex_lock(&prd->lock);
226
227 list_for_each_entry_reverse(ce, &prd->clock_list, node) {
228 if (ce->status == PCE_STATUS_NONE)
229 pm_runtime_clk_acquire(dev, ce);
230
231 if (ce->status < PCE_STATUS_ERROR) {
232 clk_disable(ce->clk);
233 ce->status = PCE_STATUS_ACQUIRED;
234 }
235 }
236
237 mutex_unlock(&prd->lock);
238
239 return 0;
240}
241
242/**
243 * pm_runtime_clk_resume - Enable clocks in a device's runtime PM clock list.
244 * @dev: Device to enable the clocks for.
245 */
246int pm_runtime_clk_resume(struct device *dev)
247{
248 struct pm_runtime_clk_data *prd = __to_prd(dev);
249 struct pm_clock_entry *ce;
250
251 dev_dbg(dev, "%s()\n", __func__);
252
253 if (!prd)
254 return 0;
255
256 mutex_lock(&prd->lock);
257
258 list_for_each_entry(ce, &prd->clock_list, node) {
259 if (ce->status == PCE_STATUS_NONE)
260 pm_runtime_clk_acquire(dev, ce);
261
262 if (ce->status < PCE_STATUS_ERROR) {
263 clk_enable(ce->clk);
264 ce->status = PCE_STATUS_ENABLED;
265 }
266 }
267
268 mutex_unlock(&prd->lock);
269
270 return 0;
271}
272
273/**
274 * pm_runtime_clk_notify - Notify routine for device addition and removal.
275 * @nb: Notifier block object this function is a member of.
276 * @action: Operation being carried out by the caller.
277 * @data: Device the routine is being run for.
278 *
279 * For this function to work, @nb must be a member of an object of type
280 * struct pm_clk_notifier_block containing all of the requisite data.
281 * Specifically, the pwr_domain member of that object is copied to the device's
282 * pwr_domain field and its con_ids member is used to populate the device's list
283 * of runtime PM clocks, depending on @action.
284 *
285 * If the device's pwr_domain field is already populated with a value different
286 * from the one stored in the struct pm_clk_notifier_block object, the function
287 * does nothing.
288 */
289static int pm_runtime_clk_notify(struct notifier_block *nb,
290 unsigned long action, void *data)
291{
292 struct pm_clk_notifier_block *clknb;
293 struct device *dev = data;
294 char *con_id;
295 int error;
296
297 dev_dbg(dev, "%s() %ld\n", __func__, action);
298
299 clknb = container_of(nb, struct pm_clk_notifier_block, nb);
300
301 switch (action) {
302 case BUS_NOTIFY_ADD_DEVICE:
303 if (dev->pwr_domain)
304 break;
305
306 error = pm_runtime_clk_init(dev);
307 if (error)
308 break;
309
310 dev->pwr_domain = clknb->pwr_domain;
311 if (clknb->con_ids[0]) {
312 for (con_id = clknb->con_ids[0]; *con_id; con_id++)
313 pm_runtime_clk_add(dev, con_id);
314 } else {
315 pm_runtime_clk_add(dev, NULL);
316 }
317
318 break;
319 case BUS_NOTIFY_DEL_DEVICE:
320 if (dev->pwr_domain != clknb->pwr_domain)
321 break;
322
323 dev->pwr_domain = NULL;
324 pm_runtime_clk_destroy(dev);
325 break;
326 }
327
328 return 0;
329}
330
331#else /* !CONFIG_PM_RUNTIME */
332
333/**
334 * enable_clock - Enable a device clock.
335 * @dev: Device whose clock is to be enabled.
336 * @con_id: Connection ID of the clock.
337 */
338static void enable_clock(struct device *dev, const char *con_id)
339{
340 struct clk *clk;
341
342 clk = clk_get(dev, con_id);
343 if (!IS_ERR(clk)) {
344 clk_enable(clk);
345 clk_put(clk);
346 dev_info(dev, "Runtime PM disabled, clock forced on.\n");
347 }
348}
349
350/**
351 * disable_clock - Disable a device clock.
352 * @dev: Device whose clock is to be disabled.
353 * @con_id: Connection ID of the clock.
354 */
355static void disable_clock(struct device *dev, const char *con_id)
356{
357 struct clk *clk;
358
359 clk = clk_get(dev, con_id);
360 if (!IS_ERR(clk)) {
361 clk_disable(clk);
362 clk_put(clk);
363 dev_info(dev, "Runtime PM disabled, clock forced off.\n");
364 }
365}
366
367/**
368 * pm_runtime_clk_notify - Notify routine for device addition and removal.
369 * @nb: Notifier block object this function is a member of.
370 * @action: Operation being carried out by the caller.
371 * @data: Device the routine is being run for.
372 *
373 * For this function to work, @nb must be a member of an object of type
374 * struct pm_clk_notifier_block containing all of the requisite data.
375 * Specifically, the con_ids member of that object is used to enable or disable
376 * the device's clocks, depending on @action.
377 */
378static int pm_runtime_clk_notify(struct notifier_block *nb,
379 unsigned long action, void *data)
380{
381 struct pm_clk_notifier_block *clknb;
382 struct device *dev = data;
383
384 dev_dbg(dev, "%s() %ld\n", __func__, action);
385
386 clknb = container_of(nb, struct pm_clk_notifier_block, nb);
387
388 switch (action) {
389 case BUS_NOTIFY_ADD_DEVICE:
390 if (clknb->con_ids[0]) {
391 for (con_id = clknb->con_ids[0]; *con_id; con_id++)
392 enable_clock(dev, con_id);
393 } else {
394 enable_clock(dev, NULL);
395 }
396 break;
397 case BUS_NOTIFY_DEL_DEVICE:
398 if (clknb->con_ids[0]) {
399 for (con_id = clknb->con_ids[0]; *con_id; con_id++)
400 disable_clock(dev, con_id);
401 } else {
402 disable_clock(dev, NULL);
403 }
404 break;
405 }
406
407 return 0;
408}
409
410#endif /* !CONFIG_PM_RUNTIME */
411
412/**
413 * pm_runtime_clk_add_notifier - Add bus type notifier for runtime PM clocks.
414 * @bus: Bus type to add the notifier to.
415 * @clknb: Notifier to be added to the given bus type.
416 *
417 * The nb member of @clknb is not expected to be initialized and its
418 * notifier_call member will be replaced with pm_runtime_clk_notify(). However,
419 * the remaining members of @clknb should be populated prior to calling this
420 * routine.
421 */
422void pm_runtime_clk_add_notifier(struct bus_type *bus,
423 struct pm_clk_notifier_block *clknb)
424{
425 if (!bus || !clknb)
426 return;
427
428 clknb->nb.notifier_call = pm_runtime_clk_notify;
429 bus_register_notifier(bus, &clknb->nb);
430}
diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h
index 8de9aa6e7def..878cf84baeb1 100644
--- a/include/linux/pm_runtime.h
+++ b/include/linux/pm_runtime.h
@@ -245,4 +245,46 @@ static inline void pm_runtime_dont_use_autosuspend(struct device *dev)
245 __pm_runtime_use_autosuspend(dev, false); 245 __pm_runtime_use_autosuspend(dev, false);
246} 246}
247 247
248struct pm_clk_notifier_block {
249 struct notifier_block nb;
250 struct dev_power_domain *pwr_domain;
251 char *con_ids[];
252};
253
254#ifdef CONFIG_PM_RUNTIME_CLK
255extern int pm_runtime_clk_init(struct device *dev);
256extern void pm_runtime_clk_destroy(struct device *dev);
257extern int pm_runtime_clk_add(struct device *dev, const char *con_id);
258extern void pm_runtime_clk_remove(struct device *dev, const char *con_id);
259extern int pm_runtime_clk_suspend(struct device *dev);
260extern int pm_runtime_clk_resume(struct device *dev);
261#else
262static inline int pm_runtime_clk_init(struct device *dev)
263{
264 return -EINVAL;
265}
266static inline void pm_runtime_clk_destroy(struct device *dev)
267{
268}
269static inline int pm_runtime_clk_add(struct device *dev, const char *con_id)
270{
271 return -EINVAL;
272}
273static inline void pm_runtime_clk_remove(struct device *dev, const char *con_id)
274{
275}
276#define pm_runtime_clock_suspend NULL
277#define pm_runtime_clock_resume NULL
278#endif
279
280#ifdef CONFIG_HAVE_CLK
281extern void pm_runtime_clk_add_notifier(struct bus_type *bus,
282 struct pm_clk_notifier_block *clknb);
283#else
284static inline void pm_runtime_clk_add_notifier(struct bus_type *bus,
285 struct pm_clk_notifier_block *clknb)
286{
287}
288#endif
289
248#endif 290#endif
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
index 6de9a8fc3417..d74ad4a90695 100644
--- a/kernel/power/Kconfig
+++ b/kernel/power/Kconfig
@@ -229,3 +229,7 @@ config PM_OPP
229 representing individual voltage domains and provides SOC 229 representing individual voltage domains and provides SOC
230 implementations a ready to use framework to manage OPPs. 230 implementations a ready to use framework to manage OPPs.
231 For more information, read <file:Documentation/power/opp.txt> 231 For more information, read <file:Documentation/power/opp.txt>
232
233config PM_RUNTIME_CLK
234 def_bool y
235 depends on PM_RUNTIME && HAVE_CLK