diff options
author | Rafael J. Wysocki <rjw@sisk.pl> | 2011-07-01 16:13:37 -0400 |
---|---|---|
committer | Rafael J. Wysocki <rjw@sisk.pl> | 2011-07-02 08:29:56 -0400 |
commit | b7b95920aa2e89e655afe9913ee0e55855ceda90 (patch) | |
tree | 6f7f30252e2b4b518d76906706a745107288a701 | |
parent | d4f2d87a8b46c14c4307c690c92bd08229f66ecf (diff) |
PM: Allow the clocks management code to be used during system suspend
The common clocks management code in drivers/base/power/clock_ops.c
is going to be used during system-wide power transitions as well as
for runtime PM, so it shouldn't depend on CONFIG_PM_RUNTIME.
However, the suspend/resume functions provided by it for
CONFIG_PM_RUNTIME unset, to be used during system-wide power
transitions, should not behave in the same way as their counterparts
defined for CONFIG_PM_RUNTIME set, because in that case the clocks
are managed differently at run time.
The names of the functions still contain the word "runtime" after
this change, but that is going to be modified by a separate patch
later.
Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Reviewed-by: Kevin Hilman <khilman@ti.com>
-rw-r--r-- | drivers/base/power/clock_ops.c | 60 | ||||
-rw-r--r-- | include/linux/pm_runtime.h | 2 | ||||
-rw-r--r-- | kernel/power/Kconfig | 4 |
3 files changed, 62 insertions, 4 deletions
diff --git a/drivers/base/power/clock_ops.c b/drivers/base/power/clock_ops.c index c5624818259e..2fb9c121c64b 100644 --- a/drivers/base/power/clock_ops.c +++ b/drivers/base/power/clock_ops.c | |||
@@ -15,7 +15,7 @@ | |||
15 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
16 | #include <linux/err.h> | 16 | #include <linux/err.h> |
17 | 17 | ||
18 | #ifdef CONFIG_PM_RUNTIME | 18 | #ifdef CONFIG_PM |
19 | 19 | ||
20 | struct pm_runtime_clk_data { | 20 | struct pm_runtime_clk_data { |
21 | struct list_head clock_list; | 21 | struct list_head clock_list; |
@@ -191,6 +191,10 @@ void pm_runtime_clk_destroy(struct device *dev) | |||
191 | kfree(prd); | 191 | kfree(prd); |
192 | } | 192 | } |
193 | 193 | ||
194 | #endif /* CONFIG_PM */ | ||
195 | |||
196 | #ifdef CONFIG_PM_RUNTIME | ||
197 | |||
194 | /** | 198 | /** |
195 | * pm_runtime_clk_acquire - Acquire a device clock. | 199 | * pm_runtime_clk_acquire - Acquire a device clock. |
196 | * @dev: Device whose clock is to be acquired. | 200 | * @dev: Device whose clock is to be acquired. |
@@ -330,6 +334,60 @@ static int pm_runtime_clk_notify(struct notifier_block *nb, | |||
330 | 334 | ||
331 | #else /* !CONFIG_PM_RUNTIME */ | 335 | #else /* !CONFIG_PM_RUNTIME */ |
332 | 336 | ||
337 | #ifdef CONFIG_PM | ||
338 | |||
339 | /** | ||
340 | * pm_runtime_clk_suspend - Disable clocks in a device's PM clock list. | ||
341 | * @dev: Device to disable the clocks for. | ||
342 | */ | ||
343 | int pm_runtime_clk_suspend(struct device *dev) | ||
344 | { | ||
345 | struct pm_runtime_clk_data *prd = __to_prd(dev); | ||
346 | struct pm_clock_entry *ce; | ||
347 | |||
348 | dev_dbg(dev, "%s()\n", __func__); | ||
349 | |||
350 | /* If there is no driver, the clocks are already disabled. */ | ||
351 | if (!prd || !dev->driver) | ||
352 | return 0; | ||
353 | |||
354 | mutex_lock(&prd->lock); | ||
355 | |||
356 | list_for_each_entry_reverse(ce, &prd->clock_list, node) | ||
357 | clk_disable(ce->clk); | ||
358 | |||
359 | mutex_unlock(&prd->lock); | ||
360 | |||
361 | return 0; | ||
362 | } | ||
363 | |||
364 | /** | ||
365 | * pm_runtime_clk_resume - Enable clocks in a device's PM clock list. | ||
366 | * @dev: Device to enable the clocks for. | ||
367 | */ | ||
368 | int pm_runtime_clk_resume(struct device *dev) | ||
369 | { | ||
370 | struct pm_runtime_clk_data *prd = __to_prd(dev); | ||
371 | struct pm_clock_entry *ce; | ||
372 | |||
373 | dev_dbg(dev, "%s()\n", __func__); | ||
374 | |||
375 | /* If there is no driver, the clocks should remain disabled. */ | ||
376 | if (!prd || !dev->driver) | ||
377 | return 0; | ||
378 | |||
379 | mutex_lock(&prd->lock); | ||
380 | |||
381 | list_for_each_entry(ce, &prd->clock_list, node) | ||
382 | clk_enable(ce->clk); | ||
383 | |||
384 | mutex_unlock(&prd->lock); | ||
385 | |||
386 | return 0; | ||
387 | } | ||
388 | |||
389 | #endif /* CONFIG_PM */ | ||
390 | |||
333 | /** | 391 | /** |
334 | * enable_clock - Enable a device clock. | 392 | * enable_clock - Enable a device clock. |
335 | * @dev: Device whose clock is to be enabled. | 393 | * @dev: Device whose clock is to be enabled. |
diff --git a/include/linux/pm_runtime.h b/include/linux/pm_runtime.h index ef91904c7110..1bd5063a2cc8 100644 --- a/include/linux/pm_runtime.h +++ b/include/linux/pm_runtime.h | |||
@@ -251,7 +251,7 @@ struct pm_clk_notifier_block { | |||
251 | char *con_ids[]; | 251 | char *con_ids[]; |
252 | }; | 252 | }; |
253 | 253 | ||
254 | #ifdef CONFIG_PM_RUNTIME_CLK | 254 | #ifdef CONFIG_PM_CLK |
255 | extern int pm_runtime_clk_init(struct device *dev); | 255 | extern int pm_runtime_clk_init(struct device *dev); |
256 | extern void pm_runtime_clk_destroy(struct device *dev); | 256 | extern void pm_runtime_clk_destroy(struct device *dev); |
257 | extern int pm_runtime_clk_add(struct device *dev, const char *con_id); | 257 | extern int pm_runtime_clk_add(struct device *dev, const char *con_id); |
diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index e83ac2556c86..7b856b3458d2 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig | |||
@@ -224,9 +224,9 @@ config PM_OPP | |||
224 | implementations a ready to use framework to manage OPPs. | 224 | implementations a ready to use framework to manage OPPs. |
225 | For more information, read <file:Documentation/power/opp.txt> | 225 | For more information, read <file:Documentation/power/opp.txt> |
226 | 226 | ||
227 | config PM_RUNTIME_CLK | 227 | config PM_CLK |
228 | def_bool y | 228 | def_bool y |
229 | depends on PM_RUNTIME && HAVE_CLK | 229 | depends on PM && HAVE_CLK |
230 | 230 | ||
231 | config PM_GENERIC_DOMAINS | 231 | config PM_GENERIC_DOMAINS |
232 | bool | 232 | bool |