Skip to content

Commit

Permalink
Merge branch 'pm-assorted'
Browse files Browse the repository at this point in the history
* pm-assorted:
  suspend: enable freeze timeout configuration through sys
  ACPI: enable ACPI SCI during suspend
  PM: Introduce suspend state PM_SUSPEND_FREEZE
  PM / Runtime: Add new helper function: pm_runtime_active()
  PM / tracing: remove deprecated power trace API
  PM: don't use [delayed_]work_pending()
  PM / Domains: don't use [delayed_]work_pending()
  • Loading branch information
Rafael J. Wysocki committed Feb 15, 2013
2 parents a68d353 + 957d128 commit 7113fe7
Show file tree
Hide file tree
Showing 21 changed files with 125 additions and 174 deletions.
5 changes: 5 additions & 0 deletions Documentation/power/freezing-of-tasks.txt
Original file line number Diff line number Diff line change
Expand Up @@ -223,3 +223,8 @@ since they ask the freezer to skip freezing this task, since it is anyway
only after the entire suspend/hibernation sequence is complete.
So, to summarize, use [un]lock_system_sleep() instead of directly using
mutex_[un]lock(&pm_mutex). That would prevent freezing failures.

V. Miscellaneous
/sys/power/pm_freeze_timeout controls how long it will cost at most to freeze
all user space processes or all freezable kernel threads, in unit of millisecond.
The default value is 20000, with range of unsigned integer.
4 changes: 4 additions & 0 deletions Documentation/power/runtime_pm.txt
Original file line number Diff line number Diff line change
Expand Up @@ -426,6 +426,10 @@ drivers/base/power/runtime.c and include/linux/pm_runtime.h:
'power.runtime_error' is set or 'power.disable_depth' is greater than
zero)

bool pm_runtime_active(struct device *dev);
- return true if the device's runtime PM status is 'active' or its
'power.disable_depth' field is not equal to zero, or false otherwise

bool pm_runtime_suspended(struct device *dev);
- return true if the device's runtime PM status is 'suspended' and its
'power.disable_depth' field is equal to zero, or false otherwise
Expand Down
27 changes: 1 addition & 26 deletions Documentation/trace/events-power.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Cf. include/trace/events/power.h for the events definitions.
1. Power state switch events
============================

1.1 New trace API
1.1 Trace API
-----------------

A 'cpu' event class gathers the CPU-related events: cpuidle and
Expand All @@ -41,31 +41,6 @@ The event which has 'state=4294967295' in the trace is very important to the use
space tools which are using it to detect the end of the current state, and so to
correctly draw the states diagrams and to calculate accurate statistics etc.

1.2 DEPRECATED trace API
------------------------

A new Kconfig option CONFIG_EVENT_POWER_TRACING_DEPRECATED with the default value of
'y' has been created. This allows the legacy trace power API to be used conjointly
with the new trace API.
The Kconfig option, the old trace API (in include/trace/events/power.h) and the
old trace points will disappear in a future release (namely 2.6.41).

power_start "type=%lu state=%lu cpu_id=%lu"
power_frequency "type=%lu state=%lu cpu_id=%lu"
power_end "cpu_id=%lu"

The 'type' parameter takes one of those macros:
. POWER_NONE = 0,
. POWER_CSTATE = 1, /* C-State */
. POWER_PSTATE = 2, /* Frequency change or DVFS */

The 'state' parameter is set depending on the type:
. Target C-state for type=POWER_CSTATE,
. Target frequency for type=POWER_PSTATE,

power_end is used to indicate the exit of a state, corresponding to the latest
power_start event.

2. Clocks events
================
The clock events are used for clock enable/disable and for
Expand Down
2 changes: 0 additions & 2 deletions arch/arm/mach-omap2/pm34xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -351,12 +351,10 @@ static void omap3_pm_idle(void)
if (omap_irq_pending())
goto out;

trace_power_start(POWER_CSTATE, 1, smp_processor_id());
trace_cpu_idle(1, smp_processor_id());

omap_sram_idle();

trace_power_end(smp_processor_id());
trace_cpu_idle(PWR_EVENT_EXIT, smp_processor_id());

out:
Expand Down
6 changes: 0 additions & 6 deletions arch/x86/kernel/process.c
Original file line number Diff line number Diff line change
Expand Up @@ -375,7 +375,6 @@ void cpu_idle(void)
*/
void default_idle(void)
{
trace_power_start_rcuidle(POWER_CSTATE, 1, smp_processor_id());
trace_cpu_idle_rcuidle(1, smp_processor_id());
current_thread_info()->status &= ~TS_POLLING;
/*
Expand All @@ -389,7 +388,6 @@ void default_idle(void)
else
local_irq_enable();
current_thread_info()->status |= TS_POLLING;
trace_power_end_rcuidle(smp_processor_id());
trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id());
}
#ifdef CONFIG_APM_MODULE
Expand Down Expand Up @@ -423,7 +421,6 @@ void stop_this_cpu(void *dummy)
static void mwait_idle(void)
{
if (!need_resched()) {
trace_power_start_rcuidle(POWER_CSTATE, 1, smp_processor_id());
trace_cpu_idle_rcuidle(1, smp_processor_id());
if (this_cpu_has(X86_FEATURE_CLFLUSH_MONITOR))
clflush((void *)&current_thread_info()->flags);
Expand All @@ -434,7 +431,6 @@ static void mwait_idle(void)
__sti_mwait(0, 0);
else
local_irq_enable();
trace_power_end_rcuidle(smp_processor_id());
trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id());
} else
local_irq_enable();
Expand All @@ -447,12 +443,10 @@ static void mwait_idle(void)
*/
static void poll_idle(void)
{
trace_power_start_rcuidle(POWER_CSTATE, 0, smp_processor_id());
trace_cpu_idle_rcuidle(0, smp_processor_id());
local_irq_enable();
while (!need_resched())
cpu_relax();
trace_power_end_rcuidle(smp_processor_id());
trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, smp_processor_id());
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/acpi/osl.c
Original file line number Diff line number Diff line change
Expand Up @@ -787,7 +787,7 @@ acpi_os_install_interrupt_handler(u32 gsi, acpi_osd_handler handler,

acpi_irq_handler = handler;
acpi_irq_context = context;
if (request_irq(irq, acpi_irq, IRQF_SHARED, "acpi", acpi_irq)) {
if (request_irq(irq, acpi_irq, IRQF_SHARED | IRQF_NO_SUSPEND, "acpi", acpi_irq)) {
printk(KERN_ERR PREFIX "SCI (IRQ%d) allocation failed\n", irq);
acpi_irq_handler = NULL;
return AE_NOT_ACQUIRED;
Expand Down
3 changes: 1 addition & 2 deletions drivers/base/power/domain.c
Original file line number Diff line number Diff line change
Expand Up @@ -433,8 +433,7 @@ static bool genpd_abort_poweroff(struct generic_pm_domain *genpd)
*/
void genpd_queue_power_off_work(struct generic_pm_domain *genpd)
{
if (!work_pending(&genpd->power_off_work))
queue_work(pm_wq, &genpd->power_off_work);
queue_work(pm_wq, &genpd->power_off_work);
}

/**
Expand Down
6 changes: 6 additions & 0 deletions drivers/base/power/wakeup.c
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,12 @@ static void wakeup_source_activate(struct wakeup_source *ws)
{
unsigned int cec;

/*
* active wakeup source should bring the system
* out of PM_SUSPEND_FREEZE state
*/
freeze_wake();

ws->active = true;
ws->active_count++;
ws->last_time = ktime_get();
Expand Down
1 change: 0 additions & 1 deletion drivers/cpufreq/cpufreq.c
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,6 @@ void cpufreq_notify_transition(struct cpufreq_freqs *freqs, unsigned int state)
adjust_jiffies(CPUFREQ_POSTCHANGE, freqs);
pr_debug("FREQ: %lu - CPU: %lu", (unsigned long)freqs->new,
(unsigned long)freqs->cpu);
trace_power_frequency(POWER_PSTATE, freqs->new, freqs->cpu);
trace_cpu_frequency(freqs->new, freqs->cpu);
srcu_notifier_call_chain(&cpufreq_transition_notifier_list,
CPUFREQ_POSTCHANGE, freqs);
Expand Down
2 changes: 0 additions & 2 deletions drivers/cpuidle/cpuidle.c
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,6 @@ int cpuidle_idle_call(void)
return 0;
}

trace_power_start_rcuidle(POWER_CSTATE, next_state, dev->cpu);
trace_cpu_idle_rcuidle(next_state, dev->cpu);

if (cpuidle_state_is_coupled(dev, drv, next_state))
Expand All @@ -153,7 +152,6 @@ int cpuidle_idle_call(void)
else
entered_state = cpuidle_enter_state(dev, drv, next_state);

trace_power_end_rcuidle(dev->cpu);
trace_cpu_idle_rcuidle(PWR_EVENT_EXIT, dev->cpu);

/* give the governor an opportunity to reflect on the outcome */
Expand Down
5 changes: 5 additions & 0 deletions include/linux/freezer.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ extern atomic_t system_freezing_cnt; /* nr of freezing conds in effect */
extern bool pm_freezing; /* PM freezing in effect */
extern bool pm_nosig_freezing; /* PM nosig freezing in effect */

/*
* Timeout for stopping processes
*/
extern unsigned int freeze_timeout_msecs;

/*
* Check if a process has been frozen
*/
Expand Down
7 changes: 7 additions & 0 deletions include/linux/pm_runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,12 @@ static inline bool pm_runtime_suspended(struct device *dev)
&& !dev->power.disable_depth;
}

static inline bool pm_runtime_active(struct device *dev)
{
return dev->power.runtime_status == RPM_ACTIVE
|| dev->power.disable_depth;
}

static inline bool pm_runtime_status_suspended(struct device *dev)
{
return dev->power.runtime_status == RPM_SUSPENDED;
Expand Down Expand Up @@ -132,6 +138,7 @@ static inline void pm_runtime_put_noidle(struct device *dev) {}
static inline bool device_run_wake(struct device *dev) { return false; }
static inline void device_set_run_wake(struct device *dev, bool enable) {}
static inline bool pm_runtime_suspended(struct device *dev) { return false; }
static inline bool pm_runtime_active(struct device *dev) { return true; }
static inline bool pm_runtime_status_suspended(struct device *dev) { return false; }
static inline bool pm_runtime_enabled(struct device *dev) { return false; }

Expand Down
6 changes: 5 additions & 1 deletion include/linux/suspend.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,10 @@ static inline void pm_restore_console(void)
typedef int __bitwise suspend_state_t;

#define PM_SUSPEND_ON ((__force suspend_state_t) 0)
#define PM_SUSPEND_STANDBY ((__force suspend_state_t) 1)
#define PM_SUSPEND_FREEZE ((__force suspend_state_t) 1)
#define PM_SUSPEND_STANDBY ((__force suspend_state_t) 2)
#define PM_SUSPEND_MEM ((__force suspend_state_t) 3)
#define PM_SUSPEND_MIN PM_SUSPEND_FREEZE
#define PM_SUSPEND_MAX ((__force suspend_state_t) 4)

enum suspend_stat_step {
Expand Down Expand Up @@ -192,6 +194,7 @@ struct platform_suspend_ops {
*/
extern void suspend_set_ops(const struct platform_suspend_ops *ops);
extern int suspend_valid_only_mem(suspend_state_t state);
extern void freeze_wake(void);

/**
* arch_suspend_disable_irqs - disable IRQs for suspend
Expand All @@ -217,6 +220,7 @@ extern int pm_suspend(suspend_state_t state);

static inline void suspend_set_ops(const struct platform_suspend_ops *ops) {}
static inline int pm_suspend(suspend_state_t state) { return -ENOSYS; }
static inline void freeze_wake(void) {}
#endif /* !CONFIG_SUSPEND */

/* struct pbe is used for creating lists of pages that should be restored
Expand Down
92 changes: 0 additions & 92 deletions include/trace/events/power.h
Original file line number Diff line number Diff line change
Expand Up @@ -99,98 +99,6 @@ DEFINE_EVENT(wakeup_source, wakeup_source_deactivate,
TP_ARGS(name, state)
);

#ifdef CONFIG_EVENT_POWER_TRACING_DEPRECATED

/*
* The power events are used for cpuidle & suspend (power_start, power_end)
* and for cpufreq (power_frequency)
*/
DECLARE_EVENT_CLASS(power,

TP_PROTO(unsigned int type, unsigned int state, unsigned int cpu_id),

TP_ARGS(type, state, cpu_id),

TP_STRUCT__entry(
__field( u64, type )
__field( u64, state )
__field( u64, cpu_id )
),

TP_fast_assign(
__entry->type = type;
__entry->state = state;
__entry->cpu_id = cpu_id;
),

TP_printk("type=%lu state=%lu cpu_id=%lu", (unsigned long)__entry->type,
(unsigned long)__entry->state, (unsigned long)__entry->cpu_id)
);

DEFINE_EVENT(power, power_start,

TP_PROTO(unsigned int type, unsigned int state, unsigned int cpu_id),

TP_ARGS(type, state, cpu_id)
);

DEFINE_EVENT(power, power_frequency,

TP_PROTO(unsigned int type, unsigned int state, unsigned int cpu_id),

TP_ARGS(type, state, cpu_id)
);

TRACE_EVENT(power_end,

TP_PROTO(unsigned int cpu_id),

TP_ARGS(cpu_id),

TP_STRUCT__entry(
__field( u64, cpu_id )
),

TP_fast_assign(
__entry->cpu_id = cpu_id;
),

TP_printk("cpu_id=%lu", (unsigned long)__entry->cpu_id)

);

/* Deprecated dummy functions must be protected against multi-declartion */
#ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED
#define _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED

enum {
POWER_NONE = 0,
POWER_CSTATE = 1,
POWER_PSTATE = 2,
};
#endif /* _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED */

#else /* CONFIG_EVENT_POWER_TRACING_DEPRECATED */

#ifndef _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED
#define _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED
enum {
POWER_NONE = 0,
POWER_CSTATE = 1,
POWER_PSTATE = 2,
};

/* These dummy declaration have to be ripped out when the deprecated
events get removed */
static inline void trace_power_start(u64 type, u64 state, u64 cpuid) {};
static inline void trace_power_end(u64 cpuid) {};
static inline void trace_power_start_rcuidle(u64 type, u64 state, u64 cpuid) {};
static inline void trace_power_end_rcuidle(u64 cpuid) {};
static inline void trace_power_frequency(u64 type, u64 state, u64 cpuid) {};
#endif /* _PWR_EVENT_AVOID_DOUBLE_DEFINING_DEPRECATED */

#endif /* CONFIG_EVENT_POWER_TRACING_DEPRECATED */

/*
* The clock events are used for clock enable/disable and for
* clock rate change
Expand Down
2 changes: 1 addition & 1 deletion kernel/power/autosleep.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ static DECLARE_WORK(suspend_work, try_to_suspend);

void queue_up_suspend_work(void)
{
if (!work_pending(&suspend_work) && autosleep_state > PM_SUSPEND_ON)
if (autosleep_state > PM_SUSPEND_ON)
queue_work(autosleep_wq, &suspend_work);
}

Expand Down
29 changes: 28 additions & 1 deletion kernel/power/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -313,7 +313,7 @@ static ssize_t state_show(struct kobject *kobj, struct kobj_attribute *attr,
static suspend_state_t decode_state(const char *buf, size_t n)
{
#ifdef CONFIG_SUSPEND
suspend_state_t state = PM_SUSPEND_STANDBY;
suspend_state_t state = PM_SUSPEND_MIN;
const char * const *s;
#endif
char *p;
Expand Down Expand Up @@ -553,6 +553,30 @@ power_attr(pm_trace_dev_match);

#endif /* CONFIG_PM_TRACE */

#ifdef CONFIG_FREEZER
static ssize_t pm_freeze_timeout_show(struct kobject *kobj,
struct kobj_attribute *attr, char *buf)
{
return sprintf(buf, "%u\n", freeze_timeout_msecs);
}

static ssize_t pm_freeze_timeout_store(struct kobject *kobj,
struct kobj_attribute *attr,
const char *buf, size_t n)
{
unsigned long val;

if (kstrtoul(buf, 10, &val))
return -EINVAL;

freeze_timeout_msecs = val;
return n;
}

power_attr(pm_freeze_timeout);

#endif /* CONFIG_FREEZER*/

static struct attribute * g[] = {
&state_attr.attr,
#ifdef CONFIG_PM_TRACE
Expand All @@ -575,6 +599,9 @@ static struct attribute * g[] = {
#ifdef CONFIG_PM_SLEEP_DEBUG
&pm_print_times_attr.attr,
#endif
#endif
#ifdef CONFIG_FREEZER
&pm_freeze_timeout_attr.attr,
#endif
NULL,
};
Expand Down
Loading

0 comments on commit 7113fe7

Please sign in to comment.