mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-10 04:48:04 +09:00
Merge branch 'develop-3.0-rk30' of ssh://10.10.10.29/rk/kernel into develop-3.0-rk30
This commit is contained in:
@@ -29,6 +29,7 @@ config ARM
|
||||
select HAVE_GENERIC_HARDIRQS
|
||||
select HAVE_SPARSE_IRQ
|
||||
select GENERIC_IRQ_SHOW
|
||||
select CPU_PM if (SUSPEND || CPU_IDLE)
|
||||
help
|
||||
The ARM series is a line of low-power-consumption RISC chip designs
|
||||
licensed by ARM Ltd and targeted at embedded applications and
|
||||
|
||||
@@ -97,8 +97,22 @@ extern void cpu_resume(void);
|
||||
|
||||
#ifdef CONFIG_MMU
|
||||
|
||||
#ifdef CONFIG_SMP
|
||||
|
||||
#define cpu_switch_mm(pgd, mm) \
|
||||
({ \
|
||||
unsigned long flags; \
|
||||
local_irq_save(flags); \
|
||||
cpu_do_switch_mm(virt_to_phys(pgd), mm); \
|
||||
local_irq_restore(flags); \
|
||||
})
|
||||
|
||||
#else /* SMP */
|
||||
|
||||
#define cpu_switch_mm(pgd,mm) cpu_do_switch_mm(virt_to_phys(pgd),mm)
|
||||
|
||||
#endif
|
||||
|
||||
#define cpu_get_pgd() \
|
||||
({ \
|
||||
unsigned long pg; \
|
||||
|
||||
@@ -10,13 +10,17 @@
|
||||
*/
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/clk.h>
|
||||
#include <linux/cpufreq.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/device.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/smp.h>
|
||||
#include <linux/jiffies.h>
|
||||
#include <linux/clockchips.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/io.h>
|
||||
#include <linux/percpu.h>
|
||||
|
||||
#include <asm/smp_twd.h>
|
||||
#include <asm/hardware/gic.h>
|
||||
@@ -24,7 +28,9 @@
|
||||
/* set up by the platform code */
|
||||
void __iomem *twd_base;
|
||||
|
||||
static struct clk *twd_clk;
|
||||
static unsigned long twd_timer_rate;
|
||||
static DEFINE_PER_CPU(struct clock_event_device *, twd_ce);
|
||||
|
||||
static void twd_set_mode(enum clock_event_mode mode,
|
||||
struct clock_event_device *clk)
|
||||
@@ -80,6 +86,48 @@ int twd_timer_ack(void)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Updates clockevent frequency when the cpu frequency changes.
|
||||
* Called on the cpu that is changing frequency with interrupts disabled.
|
||||
*/
|
||||
static void twd_update_frequency(void *data)
|
||||
{
|
||||
twd_timer_rate = clk_get_rate(twd_clk);
|
||||
|
||||
clockevents_update_freq(__get_cpu_var(twd_ce), twd_timer_rate);
|
||||
}
|
||||
|
||||
static int twd_cpufreq_transition(struct notifier_block *nb,
|
||||
unsigned long state, void *data)
|
||||
{
|
||||
struct cpufreq_freqs *freqs = data;
|
||||
|
||||
/*
|
||||
* The twd clock events must be reprogrammed to account for the new
|
||||
* frequency. The timer is local to a cpu, so cross-call to the
|
||||
* changing cpu.
|
||||
*/
|
||||
if (state == CPUFREQ_POSTCHANGE || state == CPUFREQ_RESUMECHANGE)
|
||||
smp_call_function_single(freqs->cpu, twd_update_frequency,
|
||||
NULL, 1);
|
||||
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static struct notifier_block twd_cpufreq_nb = {
|
||||
.notifier_call = twd_cpufreq_transition,
|
||||
};
|
||||
|
||||
static int twd_cpufreq_init(void)
|
||||
{
|
||||
if (!IS_ERR_OR_NULL(twd_clk))
|
||||
return cpufreq_register_notifier(&twd_cpufreq_nb,
|
||||
CPUFREQ_TRANSITION_NOTIFIER);
|
||||
|
||||
return 0;
|
||||
}
|
||||
core_initcall(twd_cpufreq_init);
|
||||
|
||||
static void __cpuinit twd_calibrate_rate(void)
|
||||
{
|
||||
unsigned long count;
|
||||
@@ -124,7 +172,18 @@ static void __cpuinit twd_calibrate_rate(void)
|
||||
*/
|
||||
void __cpuinit twd_timer_setup(struct clock_event_device *clk)
|
||||
{
|
||||
twd_calibrate_rate();
|
||||
if (twd_clk == NULL) {
|
||||
twd_clk = clk_get_sys("smp_twd", NULL);
|
||||
if (IS_ERR_OR_NULL(twd_clk))
|
||||
pr_warn("%s: no clock found\n", __func__);
|
||||
}
|
||||
|
||||
if (!IS_ERR_OR_NULL(twd_clk))
|
||||
twd_timer_rate = clk_get_rate(twd_clk);
|
||||
else
|
||||
twd_calibrate_rate();
|
||||
|
||||
__raw_writel(0, twd_base + TWD_TIMER_CONTROL);
|
||||
|
||||
clk->name = "local_timer";
|
||||
clk->features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT |
|
||||
@@ -132,13 +191,11 @@ void __cpuinit twd_timer_setup(struct clock_event_device *clk)
|
||||
clk->rating = 350;
|
||||
clk->set_mode = twd_set_mode;
|
||||
clk->set_next_event = twd_set_next_event;
|
||||
clk->shift = 20;
|
||||
clk->mult = div_sc(twd_timer_rate, NSEC_PER_SEC, clk->shift);
|
||||
clk->max_delta_ns = clockevent_delta2ns(0xffffffff, clk);
|
||||
clk->min_delta_ns = clockevent_delta2ns(0xf, clk);
|
||||
|
||||
__get_cpu_var(twd_ce) = clk;
|
||||
|
||||
clockevents_config_and_register(clk, twd_timer_rate, 0xf, 0xffffffff);
|
||||
|
||||
/* Make sure our local interrupt controller has this enabled */
|
||||
gic_enable_ppi(clk->irq);
|
||||
|
||||
clockevents_register_device(clk);
|
||||
}
|
||||
|
||||
@@ -99,8 +99,7 @@ static void reset_context(void *info)
|
||||
set_mm_context(mm, asid);
|
||||
|
||||
/* set the new ASID */
|
||||
asm("mcr p15, 0, %0, c13, c0, 1\n" : : "r" (mm->context.id));
|
||||
isb();
|
||||
cpu_switch_mm(mm->pgd, mm);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/cpu.h>
|
||||
#include <linux/cpu_pm.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/signal.h>
|
||||
@@ -403,9 +404,7 @@ static void vfp_enable(void *unused)
|
||||
set_copro_access(access | CPACC_FULL(10) | CPACC_FULL(11));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
#include <linux/syscore_ops.h>
|
||||
|
||||
#ifdef CONFIG_CPU_PM
|
||||
static int vfp_pm_suspend(void)
|
||||
{
|
||||
struct thread_info *ti = current_thread_info();
|
||||
@@ -439,19 +438,33 @@ static void vfp_pm_resume(void)
|
||||
fmxr(FPEXC, fmrx(FPEXC) & ~FPEXC_EN);
|
||||
}
|
||||
|
||||
static struct syscore_ops vfp_pm_syscore_ops = {
|
||||
.suspend = vfp_pm_suspend,
|
||||
.resume = vfp_pm_resume,
|
||||
static int vfp_cpu_pm_notifier(struct notifier_block *self, unsigned long cmd,
|
||||
void *v)
|
||||
{
|
||||
switch (cmd) {
|
||||
case CPU_PM_ENTER:
|
||||
vfp_pm_suspend();
|
||||
break;
|
||||
case CPU_PM_ENTER_FAILED:
|
||||
case CPU_PM_EXIT:
|
||||
vfp_pm_resume();
|
||||
break;
|
||||
}
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
|
||||
static struct notifier_block vfp_cpu_pm_notifier_block = {
|
||||
.notifier_call = vfp_cpu_pm_notifier,
|
||||
};
|
||||
|
||||
static void vfp_pm_init(void)
|
||||
{
|
||||
register_syscore_ops(&vfp_pm_syscore_ops);
|
||||
cpu_pm_register_notifier(&vfp_cpu_pm_notifier_block);
|
||||
}
|
||||
|
||||
#else
|
||||
static inline void vfp_pm_init(void) { }
|
||||
#endif /* CONFIG_PM */
|
||||
#endif /* CONFIG_CPU_PM */
|
||||
|
||||
void vfp_sync_hwstate(struct thread_info *thread)
|
||||
{
|
||||
|
||||
109
include/linux/cpu_pm.h
Normal file
109
include/linux/cpu_pm.h
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Google, Inc.
|
||||
*
|
||||
* Author:
|
||||
* Colin Cross <ccross@android.com>
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_CPU_PM_H
|
||||
#define _LINUX_CPU_PM_H
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/notifier.h>
|
||||
|
||||
/*
|
||||
* When a CPU goes to a low power state that turns off power to the CPU's
|
||||
* power domain, the contents of some blocks (floating point coprocessors,
|
||||
* interrupt controllers, caches, timers) in the same power domain can
|
||||
* be lost. The cpm_pm notifiers provide a method for platform idle, suspend,
|
||||
* and hotplug implementations to notify the drivers for these blocks that
|
||||
* they may be reset.
|
||||
*
|
||||
* All cpu_pm notifications must be called with interrupts disabled.
|
||||
*
|
||||
* The notifications are split into two classes: CPU notifications and CPU
|
||||
* cluster notifications.
|
||||
*
|
||||
* CPU notifications apply to a single CPU and must be called on the affected
|
||||
* CPU. They are used to save per-cpu context for affected blocks.
|
||||
*
|
||||
* CPU cluster notifications apply to all CPUs in a single power domain. They
|
||||
* are used to save any global context for affected blocks, and must be called
|
||||
* after all the CPUs in the power domain have been notified of the low power
|
||||
* state.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Event codes passed as unsigned long val to notifier calls
|
||||
*/
|
||||
enum cpu_pm_event {
|
||||
/* A single cpu is entering a low power state */
|
||||
CPU_PM_ENTER,
|
||||
|
||||
/* A single cpu failed to enter a low power state */
|
||||
CPU_PM_ENTER_FAILED,
|
||||
|
||||
/* A single cpu is exiting a low power state */
|
||||
CPU_PM_EXIT,
|
||||
|
||||
/* A cpu power domain is entering a low power state */
|
||||
CPU_CLUSTER_PM_ENTER,
|
||||
|
||||
/* A cpu power domain failed to enter a low power state */
|
||||
CPU_CLUSTER_PM_ENTER_FAILED,
|
||||
|
||||
/* A cpu power domain is exiting a low power state */
|
||||
CPU_CLUSTER_PM_EXIT,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_CPU_PM
|
||||
int cpu_pm_register_notifier(struct notifier_block *nb);
|
||||
int cpu_pm_unregister_notifier(struct notifier_block *nb);
|
||||
int cpu_pm_enter(void);
|
||||
int cpu_pm_exit(void);
|
||||
int cpu_cluster_pm_enter(void);
|
||||
int cpu_cluster_pm_exit(void);
|
||||
|
||||
#else
|
||||
|
||||
static inline int cpu_pm_register_notifier(struct notifier_block *nb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int cpu_pm_unregister_notifier(struct notifier_block *nb)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int cpu_pm_enter(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int cpu_pm_exit(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int cpu_cluster_pm_enter(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int cpu_cluster_pm_exit(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
@@ -101,6 +101,7 @@ obj-$(CONFIG_RING_BUFFER) += trace/
|
||||
obj-$(CONFIG_TRACEPOINTS) += trace/
|
||||
obj-$(CONFIG_SMP) += sched_cpupri.o
|
||||
obj-$(CONFIG_IRQ_WORK) += irq_work.o
|
||||
obj-$(CONFIG_CPU_PM) += cpu_pm.o
|
||||
|
||||
obj-$(CONFIG_PERF_EVENTS) += events/
|
||||
|
||||
|
||||
233
kernel/cpu_pm.c
Normal file
233
kernel/cpu_pm.c
Normal file
@@ -0,0 +1,233 @@
|
||||
/*
|
||||
* Copyright (C) 2011 Google, Inc.
|
||||
*
|
||||
* Author:
|
||||
* Colin Cross <ccross@android.com>
|
||||
*
|
||||
* This software is licensed under the terms of the GNU General Public
|
||||
* License version 2, as published by the Free Software Foundation, and
|
||||
* may be copied, distributed, and modified under those terms.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/cpu_pm.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/notifier.h>
|
||||
#include <linux/spinlock.h>
|
||||
#include <linux/syscore_ops.h>
|
||||
|
||||
static DEFINE_RWLOCK(cpu_pm_notifier_lock);
|
||||
static RAW_NOTIFIER_HEAD(cpu_pm_notifier_chain);
|
||||
|
||||
static int cpu_pm_notify(enum cpu_pm_event event, int nr_to_call, int *nr_calls)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = __raw_notifier_call_chain(&cpu_pm_notifier_chain, event, NULL,
|
||||
nr_to_call, nr_calls);
|
||||
|
||||
return notifier_to_errno(ret);
|
||||
}
|
||||
|
||||
/**
|
||||
* cpu_pm_register_notifier - register a driver with cpu_pm
|
||||
* @nb: notifier block to register
|
||||
*
|
||||
* Add a driver to a list of drivers that are notified about
|
||||
* CPU and CPU cluster low power entry and exit.
|
||||
*
|
||||
* This function may sleep, and has the same return conditions as
|
||||
* raw_notifier_chain_register.
|
||||
*/
|
||||
int cpu_pm_register_notifier(struct notifier_block *nb)
|
||||
{
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
write_lock_irqsave(&cpu_pm_notifier_lock, flags);
|
||||
ret = raw_notifier_chain_register(&cpu_pm_notifier_chain, nb);
|
||||
write_unlock_irqrestore(&cpu_pm_notifier_lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cpu_pm_register_notifier);
|
||||
|
||||
/**
|
||||
* cpu_pm_unregister_notifier - unregister a driver with cpu_pm
|
||||
* @nb: notifier block to be unregistered
|
||||
*
|
||||
* Remove a driver from the CPU PM notifier list.
|
||||
*
|
||||
* This function may sleep, and has the same return conditions as
|
||||
* raw_notifier_chain_unregister.
|
||||
*/
|
||||
int cpu_pm_unregister_notifier(struct notifier_block *nb)
|
||||
{
|
||||
unsigned long flags;
|
||||
int ret;
|
||||
|
||||
write_lock_irqsave(&cpu_pm_notifier_lock, flags);
|
||||
ret = raw_notifier_chain_unregister(&cpu_pm_notifier_chain, nb);
|
||||
write_unlock_irqrestore(&cpu_pm_notifier_lock, flags);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cpu_pm_unregister_notifier);
|
||||
|
||||
/**
|
||||
* cpm_pm_enter - CPU low power entry notifier
|
||||
*
|
||||
* Notifies listeners that a single CPU is entering a low power state that may
|
||||
* cause some blocks in the same power domain as the cpu to reset.
|
||||
*
|
||||
* Must be called on the affected CPU with interrupts disabled. Platform is
|
||||
* responsible for ensuring that cpu_pm_enter is not called twice on the same
|
||||
* CPU before cpu_pm_exit is called. Notified drivers can include VFP
|
||||
* co-processor, interrupt controller and it's PM extensions, local CPU
|
||||
* timers context save/restore which shouldn't be interrupted. Hence it
|
||||
* must be called with interrupts disabled.
|
||||
*
|
||||
* Return conditions are same as __raw_notifier_call_chain.
|
||||
*/
|
||||
int cpu_pm_enter(void)
|
||||
{
|
||||
int nr_calls;
|
||||
int ret = 0;
|
||||
|
||||
read_lock(&cpu_pm_notifier_lock);
|
||||
ret = cpu_pm_notify(CPU_PM_ENTER, -1, &nr_calls);
|
||||
if (ret)
|
||||
/*
|
||||
* Inform listeners (nr_calls - 1) about failure of CPU PM
|
||||
* PM entry who are notified earlier to prepare for it.
|
||||
*/
|
||||
cpu_pm_notify(CPU_PM_ENTER_FAILED, nr_calls - 1, NULL);
|
||||
read_unlock(&cpu_pm_notifier_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cpu_pm_enter);
|
||||
|
||||
/**
|
||||
* cpm_pm_exit - CPU low power exit notifier
|
||||
*
|
||||
* Notifies listeners that a single CPU is exiting a low power state that may
|
||||
* have caused some blocks in the same power domain as the cpu to reset.
|
||||
*
|
||||
* Notified drivers can include VFP co-processor, interrupt controller
|
||||
* and it's PM extensions, local CPU timers context save/restore which
|
||||
* shouldn't be interrupted. Hence it must be called with interrupts disabled.
|
||||
*
|
||||
* Return conditions are same as __raw_notifier_call_chain.
|
||||
*/
|
||||
int cpu_pm_exit(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
read_lock(&cpu_pm_notifier_lock);
|
||||
ret = cpu_pm_notify(CPU_PM_EXIT, -1, NULL);
|
||||
read_unlock(&cpu_pm_notifier_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cpu_pm_exit);
|
||||
|
||||
/**
|
||||
* cpm_cluster_pm_enter - CPU cluster low power entry notifier
|
||||
*
|
||||
* Notifies listeners that all cpus in a power domain are entering a low power
|
||||
* state that may cause some blocks in the same power domain to reset.
|
||||
*
|
||||
* Must be called after cpu_pm_enter has been called on all cpus in the power
|
||||
* domain, and before cpu_pm_exit has been called on any cpu in the power
|
||||
* domain. Notified drivers can include VFP co-processor, interrupt controller
|
||||
* and it's PM extensions, local CPU timers context save/restore which
|
||||
* shouldn't be interrupted. Hence it must be called with interrupts disabled.
|
||||
*
|
||||
* Must be called with interrupts disabled.
|
||||
*
|
||||
* Return conditions are same as __raw_notifier_call_chain.
|
||||
*/
|
||||
int cpu_cluster_pm_enter(void)
|
||||
{
|
||||
int nr_calls;
|
||||
int ret = 0;
|
||||
|
||||
read_lock(&cpu_pm_notifier_lock);
|
||||
ret = cpu_pm_notify(CPU_CLUSTER_PM_ENTER, -1, &nr_calls);
|
||||
if (ret)
|
||||
/*
|
||||
* Inform listeners (nr_calls - 1) about failure of CPU cluster
|
||||
* PM entry who are notified earlier to prepare for it.
|
||||
*/
|
||||
cpu_pm_notify(CPU_CLUSTER_PM_ENTER_FAILED, nr_calls - 1, NULL);
|
||||
read_unlock(&cpu_pm_notifier_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cpu_cluster_pm_enter);
|
||||
|
||||
/**
|
||||
* cpm_cluster_pm_exit - CPU cluster low power exit notifier
|
||||
*
|
||||
* Notifies listeners that all cpus in a power domain are exiting form a
|
||||
* low power state that may have caused some blocks in the same power domain
|
||||
* to reset.
|
||||
*
|
||||
* Must be called after cpu_pm_exit has been called on all cpus in the power
|
||||
* domain, and before cpu_pm_exit has been called on any cpu in the power
|
||||
* domain. Notified drivers can include VFP co-processor, interrupt controller
|
||||
* and it's PM extensions, local CPU timers context save/restore which
|
||||
* shouldn't be interrupted. Hence it must be called with interrupts disabled.
|
||||
*
|
||||
* Return conditions are same as __raw_notifier_call_chain.
|
||||
*/
|
||||
int cpu_cluster_pm_exit(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
read_lock(&cpu_pm_notifier_lock);
|
||||
ret = cpu_pm_notify(CPU_CLUSTER_PM_EXIT, -1, NULL);
|
||||
read_unlock(&cpu_pm_notifier_lock);
|
||||
|
||||
return ret;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(cpu_cluster_pm_exit);
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
static int cpu_pm_suspend(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = cpu_pm_enter();
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = cpu_cluster_pm_enter();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void cpu_pm_resume(void)
|
||||
{
|
||||
cpu_cluster_pm_exit();
|
||||
cpu_pm_exit();
|
||||
}
|
||||
|
||||
static struct syscore_ops cpu_pm_syscore_ops = {
|
||||
.suspend = cpu_pm_suspend,
|
||||
.resume = cpu_pm_resume,
|
||||
};
|
||||
|
||||
static int cpu_pm_init(void)
|
||||
{
|
||||
register_syscore_ops(&cpu_pm_syscore_ops);
|
||||
return 0;
|
||||
}
|
||||
core_initcall(cpu_pm_init);
|
||||
#endif
|
||||
@@ -295,6 +295,10 @@ config PM_RUNTIME_CLK
|
||||
def_bool y
|
||||
depends on PM_RUNTIME && HAVE_CLK
|
||||
|
||||
config CPU_PM
|
||||
bool
|
||||
depends on SUSPEND || CPU_IDLE
|
||||
|
||||
config SUSPEND_TIME
|
||||
bool "Log time spent in suspend"
|
||||
---help---
|
||||
|
||||
Reference in New Issue
Block a user