All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Arve Hjønnevåg" <arve@android.com>
To: "Rafael J. Wysocki" <rjw@sisk.pl>
Cc: ncunningham@crca.org.au, u.luckas@road.de, swetland@google.com,
	linux-pm@lists.linux-foundation.org
Subject: Re: [PATCH 1/8] PM: Add suspend block api.
Date: Wed, 29 Apr 2009 17:49:10 -0700	[thread overview]
Message-ID: <d6200be20904291749v55f5e425jcbb570c09a3901d1@mail.gmail.com> (raw)
In-Reply-To: <200904300034.09837.rjw@sisk.pl>

2009/4/29 Rafael J. Wysocki <rjw@sisk.pl>:
> On Wednesday 15 April 2009, Arve Hjønnevåg wrote:
>> diff --git a/include/linux/suspend_block.h b/include/linux/suspend_block.h
>> new file mode 100755
>> index 0000000..7820c60
>> --- /dev/null
>> +++ b/include/linux/suspend_block.h
>
> suspend_blockers.h perhaps?

suspend_blocker.h?

>
>> @@ -0,0 +1,61 @@
>> +/* include/linux/suspend_block.h
>> + *
>> + * Copyright (C) 2007-2009 Google, Inc.
>> + *
>> + * 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_SUSPEND_BLOCK_H
>> +#define _LINUX_SUSPEND_BLOCK_H
>
> SUSPEND_BLOCKERS_H ?
>
>> +
>> +/* A suspend_blocker prevents the system from entering suspend when active.
>> + */
>> +
>> +struct suspend_blocker {
>> +#ifdef CONFIG_SUSPEND_BLOCK
>
> CONFIG_SUSPEND_BLOCKERS ?

OK.

>
>> +     atomic_t            flags;
>> +     const char         *name;
>> +#endif
>> +};
>> +
>> +#ifdef CONFIG_SUSPEND_BLOCK
>> +
>> +void suspend_blocker_init(struct suspend_blocker *blocker, const char *name);
>> +void suspend_blocker_destroy(struct suspend_blocker *blocker);
>> +void suspend_block(struct suspend_blocker *blocker);
>> +void suspend_unblock(struct suspend_blocker *blocker);
>> +
>> +/* is_blocking_suspend returns true if the suspend_blocker is currently active.
>> + */
>> +bool is_blocking_suspend(struct suspend_blocker *blocker);
>
> suspend_blocker_is_active() ?
OK.
> suspend_blocker_enabled() ?
>
>> +
>> +/* suspend_is_blocked can be used by generic power management code to abort
>> + * suspend.
>> + *
>> + * To preserve backward compatibility suspend_is_blocked returns 0 unless it
>> + * is called during suspend initiated from the suspend_block code.
>> + */
>> +bool suspend_is_blocked(void);
>> +
>> +#else
>> +
>> +static inline void suspend_blocker_init(struct suspend_blocker *blocker,
>> +                                     const char *name) {}
>> +static inline void suspend_blocker_destroy(struct suspend_blocker *blocker) {}
>> +static inline void suspend_block(struct suspend_blocker *blocker) {}
>> +static inline void suspend_unblock(struct suspend_blocker *blocker) {}
>> +static inline bool is_blocking_suspend(struct suspend_blocker *bl) { return 0; }
>> +static inline bool suspend_is_blocked(void) { return 0; }
>> +
>> +#endif
>> +
>> +#endif
>> +
>> diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig
>> index 23bd4da..9d1df13 100644
>> --- a/kernel/power/Kconfig
>> +++ b/kernel/power/Kconfig
>> @@ -116,6 +116,16 @@ config SUSPEND_FREEZER
>>
>>         Turning OFF this setting is NOT recommended! If in doubt, say Y.
>>
>> +config SUSPEND_BLOCK
>> +     bool "Suspend block"
>> +     depends on PM
>> +     select RTC_LIB
>
> depends on RTC_LIB
>
> select doesn't really work and I don't think it ever will.

Nothing depends on RTC_LIB, it is only selected.

>
>> +     default n
>> +     ---help---
>> +       Enable suspend_block.
>
> Enable suspend blockers.

OK.

>
>> When user space requests a sleep state through
>> +       /sys/power/request_state, the requested sleep state will be entered
>> +       when no suspend_blockers are active.
>
> Well, if you don't want suspend blockers to block suspend started via
> /sys/power/state, it's worth making it crystal clear in the documentation too.

I added this to the intro.

>
>> +
>>  config HIBERNATION
>>       bool "Hibernation (aka 'suspend to disk')"
>>       depends on PM && SWAP && ARCH_HIBERNATION_POSSIBLE
>> diff --git a/kernel/power/Makefile b/kernel/power/Makefile
>> index 720ea4f..29cdc9e 100644
>> --- a/kernel/power/Makefile
>> +++ b/kernel/power/Makefile
>> @@ -6,6 +6,7 @@ endif
>>  obj-$(CONFIG_PM)             += main.o
>>  obj-$(CONFIG_PM_SLEEP)               += console.o
>>  obj-$(CONFIG_FREEZER)                += process.o
>> +obj-$(CONFIG_SUSPEND_BLOCK)  += suspend_block.o
>>  obj-$(CONFIG_HIBERNATION)    += swsusp.o disk.o snapshot.o swap.o user.o
>>
>>  obj-$(CONFIG_MAGIC_SYSRQ)    += poweroff.o
>> diff --git a/kernel/power/main.c b/kernel/power/main.c
>> index c9632f8..e4c6b20 100644
>> --- a/kernel/power/main.c
>> +++ b/kernel/power/main.c
>> @@ -22,6 +22,7 @@
>>  #include <linux/freezer.h>
>>  #include <linux/vmstat.h>
>>  #include <linux/syscalls.h>
>> +#include <linux/suspend_block.h>
>>
>>  #include "power.h"
>>
>> @@ -392,6 +393,9 @@ static void suspend_finish(void)
>>
>>
>>  static const char * const pm_states[PM_SUSPEND_MAX] = {
>> +#ifdef CONFIG_SUSPEND_BLOCK
>> +     [PM_SUSPEND_ON]         = "on",
>> +#endif
>
> Why #ifdef?

Removed.

>
>>       [PM_SUSPEND_STANDBY]    = "standby",
>>       [PM_SUSPEND_MEM]        = "mem",
>>  };
>> @@ -540,6 +544,61 @@ static ssize_t state_store(struct kobject *kobj, struct kobj_attribute *attr,
>>
>>  power_attr(state);
>>
>> +/**
>> + *   request_state - control system power state.
>> + *
>> + *   This is similar to state, but it does not block until the system
>> + *   resumes, and it will try to re-enter the state until another state is
>> + *   requested. Suspend blockers are respected and the requested state will
>> + *   only be entered when no suspend blockers are active.
>> + *   Write "on" to cancel.
>> + */
>> +
>> +#ifdef CONFIG_SUSPEND_BLOCK
>> +static ssize_t request_state_show(struct kobject *kobj,
>> +                               struct kobj_attribute *attr, char *buf)
>> +{
>> +     char *s = buf;
>> +     int i;
>> +
>> +     for (i = 0; i < PM_SUSPEND_MAX; i++) {
>> +             if (pm_states[i] && (i == PM_SUSPEND_ON || valid_state(i)))
>> +                     s += sprintf(s, "%s ", pm_states[i]);
>> +     }
>> +     if (s != buf)
>> +             /* convert the last space to a newline */
>> +             *(s-1) = '\n';
>> +     return (s - buf);
>> +}
>> +
>> +static ssize_t request_state_store(struct kobject *kobj,
>> +                                struct kobj_attribute *attr,
>> +                                const char *buf, size_t n)
>> +{
>> +     suspend_state_t state = PM_SUSPEND_ON;
>> +     const char * const *s;
>> +     char *p;
>> +     int len;
>> +     int error = -EINVAL;
>> +
>> +     p = memchr(buf, '\n', n);
>> +     len = p ? p - buf : n;
>> +
>> +     for (s = &pm_states[state]; state < PM_SUSPEND_MAX; s++, state++) {
>> +             if (*s && len == strlen(*s) && !strncmp(buf, *s, len))
>> +                     break;
>> +     }
>> +     if (state < PM_SUSPEND_MAX && *s)
>> +             if (state == PM_SUSPEND_ON || valid_state(state)) {
>> +                     error = 0;
>> +                     request_suspend_state(state);
>> +             }
>> +     return error ? error : n;
>> +}
>> +
>> +power_attr(request_state);
>> +#endif /* CONFIG_SUSPEND_BLOCK */
>> +
>>  #ifdef CONFIG_PM_TRACE
>>  int pm_trace_enabled;
>>
>> @@ -567,6 +626,9 @@ power_attr(pm_trace);
>>
>>  static struct attribute * g[] = {
>>       &state_attr.attr,
>> +#ifdef CONFIG_SUSPEND_BLOCK
>> +     &request_state_attr.attr,
>> +#endif
>>  #ifdef CONFIG_PM_TRACE
>>       &pm_trace_attr.attr,
>>  #endif
>> diff --git a/kernel/power/power.h b/kernel/power/power.h
>> index 46b5ec7..2414a74 100644
>> --- a/kernel/power/power.h
>> +++ b/kernel/power/power.h
>> @@ -223,3 +223,9 @@ static inline void suspend_thaw_processes(void)
>>  {
>>  }
>>  #endif
>> +
>> +#ifdef CONFIG_SUSPEND_BLOCK
>> +/* kernel/power/suspend_block.c */
>> +void request_suspend_state(suspend_state_t state);
>> +#endif
>
> Is the #ifdef really necessary?
>

No, but it gives a compile error instead of a link error if you call
request_suspend_state when it is not available so it is useful.

>> +
>> diff --git a/kernel/power/suspend_block.c b/kernel/power/suspend_block.c
>> new file mode 100644
>> index 0000000..b4f2191
>> --- /dev/null
>> +++ b/kernel/power/suspend_block.c
>> @@ -0,0 +1,257 @@
>> +/* kernel/power/suspend_block.c
>> + *
>> + * Copyright (C) 2005-2008 Google, Inc.
>> + *
>> + * 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/module.h>
>> +#include <linux/rtc.h>
>> +#include <linux/suspend.h>
>> +#include <linux/suspend_block.h>
>> +#include <linux/sysdev.h>
>> +#include "power.h"
>> +
>> +enum {
>> +     DEBUG_EXIT_SUSPEND = 1U << 0,
>> +     DEBUG_WAKEUP = 1U << 1,
>> +     DEBUG_USER_STATE = 1U << 2,
>> +     DEBUG_SUSPEND = 1U << 3,
>> +     DEBUG_SUSPEND_BLOCKER = 1U << 4,
>> +};
>> +static int debug_mask = DEBUG_EXIT_SUSPEND | DEBUG_WAKEUP | DEBUG_USER_STATE;
>> +module_param_named(debug_mask, debug_mask, int, S_IRUGO | S_IWUSR | S_IWGRP);
>> +
>> +#define SB_INITIALIZED            (1U << 8)
>> +#define SB_ACTIVE                 (1U << 9)
>> +
>> +static DEFINE_SPINLOCK(state_lock);
>> +static atomic_t suspend_block_count;
>> +static atomic_t current_event_num;
>> +struct workqueue_struct *suspend_work_queue;
>> +struct suspend_blocker main_suspend_blocker;
>> +static suspend_state_t requested_suspend_state = PM_SUSPEND_MEM;
>> +static bool enable_suspend_blockers;
>> +
>> +bool suspend_is_blocked(void)
>> +{
>> +     if (WARN_ONCE(!enable_suspend_blockers, "ignoring suspend blockers\n"))
>> +             return 0;
>> +     return !!atomic_read(&suspend_block_count);
>> +}
>> +
>> +static void suspend_worker(struct work_struct *work)
>> +{
>> +     int ret;
>> +     int entry_event_num;
>> +
>> +     enable_suspend_blockers = 1;
>
> 'true' instead of '1', please.

OK.

>
>> +
>> +retry:
>> +     if (suspend_is_blocked()) {
>> +             if (debug_mask & DEBUG_SUSPEND)
>> +                     pr_info("suspend: abort suspend\n");
>> +             goto abort;
>
> If that were in a loop you could just use 'break' here.

do you think this is better:
while(1) {
        if (exception1) {
                ...
                break;
        }
        ...
        if (exception2) {
                ...
                continue;
        }
        break;
}
>
>> +     }
>> +
>> +     entry_event_num = atomic_read(&current_event_num);
>> +     if (debug_mask & DEBUG_SUSPEND)
>> +             pr_info("suspend: enter suspend\n");
>> +     ret = pm_suspend(requested_suspend_state);
>> +     if (debug_mask & DEBUG_EXIT_SUSPEND) {
>> +             struct timespec ts;
>> +             struct rtc_time tm;
>> +             getnstimeofday(&ts);
>> +             rtc_time_to_tm(ts.tv_sec, &tm);
>> +             pr_info("suspend: exit suspend, ret = %d "
>> +                     "(%d-%02d-%02d %02d:%02d:%02d.%09lu UTC)\n", ret,
>> +                     tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
>> +                     tm.tm_hour, tm.tm_min, tm.tm_sec, ts.tv_nsec);
>> +     }
>> +     if (atomic_read(&current_event_num) == entry_event_num) {
>> +             if (debug_mask & DEBUG_SUSPEND)
>> +                     pr_info("suspend: pm_suspend returned with no event\n");
>> +             goto retry;
>
> Put that into a loop and use 'continue' here?  Or use 'break' to go out of
> the loop?

The retry is a workaround for the lack of suspend_block_timeout.

>
>> +     }
>> +abort:
>> +     enable_suspend_blockers = 0;
>
> 'false' instead of '0', please.

OK.

>
>> +}
>> +static DECLARE_WORK(suspend_work, suspend_worker);
>> +
>> +static int suspend_block_suspend(struct sys_device *dev, pm_message_t state)
>> +{
>> +     int ret = suspend_is_blocked() ? -EAGAIN : 0;
>> +     if (debug_mask & DEBUG_SUSPEND)
>> +             pr_info("suspend_block_suspend return %d\n", ret);
>> +     return ret;
>> +}
>> +
>> +static struct sysdev_class suspend_block_sysclass = {
>> +     .name = "suspend_block",
>> +     .suspend = suspend_block_suspend,
>> +};
>> +static struct sys_device suspend_block_sysdev = {
>> +     .cls = &suspend_block_sysclass,
>> +};
>> +
>
> Hmm.  Perhaps add the suspend_is_blocked() check at the beginning of
> sysdev_suspend() instead of this?  Surely you don't want to suspend
> any sysdevs with any suspend blockers active, right?

You could make the same argument for any device. Using a sysdev makes
the patch easier to apply.

>
>> +/**
>> + * suspend_blocker_init() - Initialize a suspend blocker
>> + * @blocker: The suspend blocker to initialize.
>> + * @name:    The name of the suspend blocker to show in
>> + *           /proc/suspend_blockers
>> + */
>> +void suspend_blocker_init(struct suspend_blocker *blocker, const char *name)
>> +{
>> +     if (name)
>> +             blocker->name = name;
>> +     BUG_ON(!blocker->name);
>
> Do you really want to crash the kernel in this case?  WARN_ON() might be better IMO.

OK.

>
> Also, this assumes that the caller won't release the memory used to store the
> 'name' string.  it might be a good idea to point that out in the kerneldoc
> comment.
>
>> +
>> +     if (debug_mask & DEBUG_SUSPEND_BLOCKER)
>> +             pr_info("suspend_blocker_init name=%s\n", blocker->name);
>> +
>> +     atomic_set(&blocker->flags, SB_INITIALIZED);
>> +}
>> +EXPORT_SYMBOL(suspend_blocker_init);
>> +
>> +/**
>> + * suspend_blocker_destroy() - Destroy a suspend blocker
>> + * @blocker: The suspend blocker to destroy.
>> + */
>> +void suspend_blocker_destroy(struct suspend_blocker *blocker)
>> +{
>> +     int flags;
>> +     if (debug_mask & DEBUG_SUSPEND_BLOCKER)
>> +             pr_info("suspend_blocker_destroy name=%s\n", blocker->name);
>> +     flags = atomic_xchg(&blocker->flags, 0);
>> +     WARN(!(flags & SB_INITIALIZED), "suspend_blocker_destroy called on "
>> +                                     "uninitialized suspend_blocker\n");
>> +     if (flags == (SB_INITIALIZED | SB_ACTIVE))
>> +             if (atomic_dec_and_test(&suspend_block_count))
>> +                     queue_work(suspend_work_queue, &suspend_work);
>> +}
>> +EXPORT_SYMBOL(suspend_blocker_destroy);
>> +
>> +/**
>> + * suspend_block() - Block suspend
>> + * @blocker: The suspend blocker to use
>> + */
>> +void suspend_block(struct suspend_blocker *blocker)
>> +{
>> +     BUG_ON(!(atomic_read(&blocker->flags) & SB_INITIALIZED));
>
> WARN_ON() and exit instead?  BUG_ON() is a bit drastic IMHO.
>
>> +
>> +     if (debug_mask & DEBUG_SUSPEND_BLOCKER)
>> +             pr_info("suspend_block: %s\n", blocker->name);
>> +     if (atomic_cmpxchg(&blocker->flags, SB_INITIALIZED,
>> +         SB_INITIALIZED | SB_ACTIVE) == SB_INITIALIZED)
>> +             atomic_inc(&suspend_block_count);
>> +
>> +     atomic_inc(&current_event_num);
>> +}
>> +EXPORT_SYMBOL(suspend_block);
>> +
>> +/**
>> + * suspend_unblock() - Unblock suspend
>> + * @blocker: The suspend blocker to unblock.
>> + *
>> + * If no other suspend blockers block suspend, the system will suspend.
>> + */
>> +void suspend_unblock(struct suspend_blocker *blocker)
>> +{
>> +     if (debug_mask & DEBUG_SUSPEND_BLOCKER)
>> +             pr_info("suspend_unblock: %s\n", blocker->name);
>> +
>> +     if (atomic_cmpxchg(&blocker->flags, SB_INITIALIZED | SB_ACTIVE,
>> +         SB_INITIALIZED) == (SB_INITIALIZED | SB_ACTIVE))
>> +             if (atomic_dec_and_test(&suspend_block_count))
>> +                     queue_work(suspend_work_queue, &suspend_work);
>> +}
>> +EXPORT_SYMBOL(suspend_unblock);
>> +
>> +/**
>> + * is_blocking_suspend() - Test if a suspend blocker is blocking suspend
>> + * @blocker: The suspend blocker to check.
>> + */
>> +bool is_blocking_suspend(struct suspend_blocker *blocker)
>> +{
>> +     return !!(atomic_read(&blocker->flags) & SB_ACTIVE);
>
> Check SB_INITIALIZED too, perhaps?  WARN_ON(!SB_INITIALIZED)?

Added WARN_ON.

>
>> +}
>> +EXPORT_SYMBOL(is_blocking_suspend);
>> +
>> +void request_suspend_state(suspend_state_t state)
>> +{
>> +     unsigned long irqflags;
>> +     spin_lock_irqsave(&state_lock, irqflags);
>> +     if (debug_mask & DEBUG_USER_STATE) {
>> +             struct timespec ts;
>> +             struct rtc_time tm;
>> +             getnstimeofday(&ts);
>> +             rtc_time_to_tm(ts.tv_sec, &tm);
>> +             pr_info("request_suspend_state: %s (%d->%d) at %lld "
>> +                     "(%d-%02d-%02d %02d:%02d:%02d.%09lu UTC)\n",
>> +                     state != PM_SUSPEND_ON ? "sleep" : "wakeup",
>> +                     requested_suspend_state, state,
>> +                     ktime_to_ns(ktime_get()),
>> +                     tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
>> +                     tm.tm_hour, tm.tm_min, tm.tm_sec, ts.tv_nsec);
>> +     }
>> +     requested_suspend_state = state;
>> +     if (state == PM_SUSPEND_ON)
>> +             suspend_block(&main_suspend_blocker);
>> +     else
>> +             suspend_unblock(&main_suspend_blocker);
>> +     spin_unlock_irqrestore(&state_lock, irqflags);
>> +}
>> +
>> +static int __init suspend_block_init(void)
>> +{
>> +     int ret;
>> +
>> +     suspend_blocker_init(&main_suspend_blocker, "main");
>> +     suspend_block(&main_suspend_blocker);
>> +
>> +     ret = sysdev_class_register(&suspend_block_sysclass);
>> +     if (ret) {
>> +             pr_err("suspend_block_init: sysdev_class_register failed\n");
>> +             goto err_sysdev_class_register;
>> +     }
>> +     ret = sysdev_register(&suspend_block_sysdev);
>> +     if (ret) {
>> +             pr_err("suspend_block_init: suspend_block_sysdev failed\n");
>> +             goto err_sysdev_register;
>> +     }
>> +
>> +     suspend_work_queue = create_singlethread_workqueue("suspend");
>
> Do we need a separate workqueue for this purpose?
>

Yes. Some drivers wait on work that runs on the main workqueue in
their suspend handler.

>> +     if (suspend_work_queue == NULL) {
>> +             ret = -ENOMEM;
>> +             goto err_suspend_work_queue;
>> +     }
>> +
>> +     return 0;
>> +
>> +err_suspend_work_queue:
>> +     sysdev_unregister(&suspend_block_sysdev);
>> +err_sysdev_register:
>> +     sysdev_class_unregister(&suspend_block_sysclass);
>> +err_sysdev_class_register:
>> +     suspend_blocker_destroy(&main_suspend_blocker);
>> +     return ret;
>> +}
>> +
>> +static void  __exit suspend_block_exit(void)
>> +{
>> +     destroy_workqueue(suspend_work_queue);
>> +     sysdev_unregister(&suspend_block_sysdev);
>> +     sysdev_class_unregister(&suspend_block_sysclass);
>> +     suspend_blocker_destroy(&main_suspend_blocker);
>> +}
>> +
>> +core_initcall(suspend_block_init);
>> +module_exit(suspend_block_exit);
>
> Thanks,
> Rafael
>



-- 
Arve Hjønnevåg

  parent reply	other threads:[~2009-04-30  0:49 UTC|newest]

Thread overview: 195+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-04-15  1:41 [RFC][PATCH 0/8] Suspend block api Arve Hjønnevåg
2009-04-15  1:41 ` [PATCH 1/8] PM: Add suspend " Arve Hjønnevåg
2009-04-15  1:41   ` [PATCH 2/8] PM: suspend_block: Add driver to access suspend blockers from user-space Arve Hjønnevåg
2009-04-15  1:41     ` [PATCH 3/8] PM: suspend_block: Abort task freezing if a suspend_blocker is active Arve Hjønnevåg
2009-04-15  1:41       ` [PATCH 4/8] Input: Block suspend while event queue is not empty Arve Hjønnevåg
2009-04-15  1:41         ` [PATCH 5/8] PM: suspend_block: Switch to list of active and inactive suspend blockers Arve Hjønnevåg
2009-04-15  1:41           ` [PATCH 6/8] PM: suspend_block: Add suspend_blocker stats Arve Hjønnevåg
2009-04-15  1:41             ` [PATCH 7/8] PM: suspend_block: Add timeout support Arve Hjønnevåg
2009-04-15  1:41               ` [PATCH 8/8] PM: suspend_block: Add timeout support to user-space suspend_blockers Arve Hjønnevåg
2009-04-29 22:56       ` [PATCH 3/8] PM: suspend_block: Abort task freezing if a suspend_blocker is active Rafael J. Wysocki
2009-04-29 22:52     ` [PATCH 2/8] PM: suspend_block: Add driver to access suspend blockers from user-space Rafael J. Wysocki
2009-04-15 15:29   ` [PATCH 1/8] PM: Add suspend block api Alan Stern
2009-04-15 19:08     ` mark gross
2009-04-16  0:40       ` Arve Hjønnevåg
2009-04-16  0:34     ` Arve Hjønnevåg
2009-04-15 22:31   ` mark gross
2009-04-16  1:45     ` Arve Hjønnevåg
2009-04-16 17:49       ` mark gross
2009-04-20  9:29   ` Pavel Machek
2009-04-21  4:44     ` Arve Hjønnevåg
2009-04-24 20:59       ` Pavel Machek
2009-04-29 21:24         ` Rafael J. Wysocki
2009-04-29 22:52           ` Arve Hjønnevåg
2009-04-29 22:34   ` Rafael J. Wysocki
2009-04-29 23:45     ` Arve Hjønnevåg
2009-04-30  0:49     ` Arve Hjønnevåg [this message]
2009-04-26  9:42       ` Pavel Machek
2009-05-02 12:17         ` Rafael J. Wysocki
2009-05-02 12:14       ` Rafael J. Wysocki
2009-05-02 20:51         ` Pavel Machek
2009-05-05  3:48         ` Arve Hjønnevåg
2009-04-15 23:04 ` [RFC][PATCH 0/8] Suspend " Rafael J. Wysocki
2009-04-16  6:00 [PATCH 1/8] PM: Add suspend " Sam Shang
2010-04-28  4:31 [PATCH 0/9] Suspend block api (version 5) Arve Hjønnevåg
2010-04-28  4:31 ` [PATCH 1/8] PM: Add suspend block api Arve Hjønnevåg
2010-04-28  4:31 ` Arve Hjønnevåg
2010-04-28  6:07   ` Pavel Machek
2010-04-28  6:07     ` Pavel Machek
2010-04-28 19:13   ` Alan Stern
2010-04-28 21:13     ` Rafael J. Wysocki
2010-04-28 21:13     ` Rafael J. Wysocki
2010-04-28 23:35       ` Arve Hjønnevåg
2010-04-28 23:35       ` Arve Hjønnevåg
2010-04-29 15:41         ` Alan Stern
2010-04-29 15:41           ` Alan Stern
2010-04-29 23:39           ` Arve Hjønnevåg
2010-04-29 23:39             ` Arve Hjønnevåg
2010-04-30 14:41             ` Alan Stern
2010-04-30 14:41               ` Alan Stern
2010-04-28 19:13   ` Alan Stern
2010-04-28 20:50   ` Rafael J. Wysocki
2010-04-28 20:50   ` Rafael J. Wysocki
2010-04-29  3:37     ` Arve Hjønnevåg
2010-04-29 21:16       ` Rafael J. Wysocki
2010-04-29 21:16         ` Rafael J. Wysocki
2010-04-30  4:24         ` Tejun Heo
2010-04-30  4:24           ` Tejun Heo
2010-04-30 17:26           ` Oleg Nesterov
2010-04-30 17:26           ` Oleg Nesterov
2010-05-20  8:30             ` Tejun Heo
2010-05-20 22:27               ` Rafael J. Wysocki
2010-05-21  6:35                 ` Tejun Heo
2010-05-21  6:35                   ` Tejun Heo
2010-05-20 22:27               ` Rafael J. Wysocki
2010-05-20  8:30             ` Tejun Heo
2010-04-29  3:37     ` Arve Hjønnevåg
2010-05-06 15:18   ` Alan Stern
2010-05-06 15:18   ` Alan Stern
2010-05-06 19:28     ` Rafael J. Wysocki
2010-05-06 19:28     ` Rafael J. Wysocki
2010-05-06 19:40       ` Alan Stern
2010-05-06 19:40       ` Alan Stern
2010-05-06 23:48         ` Arve Hjønnevåg
2010-05-06 23:48         ` Arve Hjønnevåg
2010-05-07 14:22           ` Alan Stern
2010-05-07 14:22           ` Alan Stern
2010-04-30 22:36 [PATCH 0/8] Suspend block api (version 6) Arve Hjønnevåg
2010-04-30 22:36 ` [PATCH 1/8] PM: Add suspend block api Arve Hjønnevåg
2010-04-30 22:36 ` Arve Hjønnevåg
2010-05-02  6:56   ` Pavel Machek
2010-05-02  6:56   ` Pavel Machek
2010-05-02 20:10     ` Rafael J. Wysocki
2010-05-02 20:52       ` Pavel Machek
2010-05-02 21:29         ` Rafael J. Wysocki
2010-05-02 21:29         ` Rafael J. Wysocki
2010-05-03 19:01           ` Pavel Machek
2010-05-03 21:38             ` Rafael J. Wysocki
2010-05-03 21:38             ` Rafael J. Wysocki
2010-05-03 22:11               ` Alan Stern
2010-05-03 22:11               ` Alan Stern
2010-05-03 22:24                 ` Arve Hjønnevåg
2010-05-03 22:24                 ` Arve Hjønnevåg
2010-05-03 19:01           ` Pavel Machek
2010-05-02 20:52       ` Pavel Machek
2010-05-02 20:10     ` Rafael J. Wysocki
2010-05-02  7:01   ` Pavel Machek
2010-05-02  7:01   ` Pavel Machek
2010-05-04  5:12   ` [linux-pm] " mark gross
2010-05-04 13:59     ` Alan Stern
2010-05-04 13:59     ` [linux-pm] " Alan Stern
2010-05-04 16:03       ` mark gross
2010-05-04 20:40     ` Arve Hjønnevåg
2010-05-04  5:12   ` mark gross
2010-05-13 19:01   ` Paul Walmsley
2010-05-14 20:05     ` Paul Walmsley
2010-05-04 16:03 [linux-pm] " mark gross
2010-05-04 17:16 ` Alan Stern
2010-05-05  1:50   ` mark gross
2010-05-05 13:31     ` Matthew Garrett
2010-05-05 20:09       ` mark gross
2010-05-05 20:21         ` Matthew Garrett
2010-05-05 20:09       ` mark gross
2010-05-05 13:31     ` Matthew Garrett
2010-05-05 15:44     ` Alan Stern
2010-05-05 15:44     ` [linux-pm] " Alan Stern
2010-05-05 20:28       ` mark gross
2010-05-05  1:50   ` mark gross
2010-05-04 17:16 ` Alan Stern
2010-05-05 20:28 [linux-pm] " mark gross
2010-05-05 21:12 ` Alan Stern
2010-05-05 21:37   ` Brian Swetland
2010-05-05 23:47     ` Tony Lindgren
2010-05-05 23:47     ` [linux-pm] " Tony Lindgren
2010-05-05 23:56       ` Brian Swetland
2010-05-06  0:05         ` Tony Lindgren
2010-05-06  4:16           ` Arve Hjønnevåg
2010-05-06 17:04             ` Tony Lindgren
2010-05-07  0:10               ` Arve Hjønnevåg
2010-05-07 15:54                 ` Tony Lindgren
2010-05-28  6:43                 ` Pavel Machek
2010-05-28  6:43                 ` [linux-pm] " Pavel Machek
2010-05-28  7:01                   ` Arve Hjønnevåg
2010-05-07  0:10               ` Arve Hjønnevåg
2010-05-06 17:04             ` Tony Lindgren
2010-05-06  4:16           ` Arve Hjønnevåg
2010-05-06  0:05         ` Tony Lindgren
2010-05-05 23:56       ` Brian Swetland
2010-05-06 13:40       ` Matthew Garrett
2010-05-06 13:40       ` [linux-pm] " Matthew Garrett
2010-05-06 17:01         ` Tony Lindgren
2010-05-06 17:01         ` [linux-pm] " Tony Lindgren
2010-05-06 17:09           ` Matthew Garrett
2010-05-06 17:09           ` [linux-pm] " Matthew Garrett
2010-05-06 17:14             ` Tony Lindgren
2010-05-06 17:22               ` Matthew Garrett
2010-05-06 17:38                 ` Tony Lindgren
2010-05-06 17:38                 ` [linux-pm] " Tony Lindgren
2010-05-06 17:43                   ` Matthew Garrett
2010-05-06 18:33                     ` Tony Lindgren
2010-05-06 18:33                     ` [linux-pm] " Tony Lindgren
2010-05-06 18:44                       ` Matthew Garrett
2010-05-07  2:05                         ` Tony Lindgren
2010-05-07  2:05                         ` [linux-pm] " Tony Lindgren
2010-05-07 17:12                           ` Matthew Garrett
2010-05-07 17:35                             ` Tony Lindgren
2010-05-07 17:35                             ` [linux-pm] " Tony Lindgren
2010-05-07 17:50                               ` Matthew Garrett
2010-05-07 18:01                                 ` Tony Lindgren
2010-05-07 18:01                                 ` [linux-pm] " Tony Lindgren
2010-05-07 18:28                                   ` Matthew Garrett
2010-05-07 18:43                                     ` Tony Lindgren
2010-05-07 18:46                                       ` Matthew Garrett
2010-05-07 18:46                                       ` [linux-pm] " Matthew Garrett
2010-05-07 19:06                                         ` Daniel Walker
2010-05-07 19:06                                         ` [linux-pm] " Daniel Walker
2010-05-07 19:28                                           ` Tony Lindgren
2010-05-07 19:33                                             ` Matthew Garrett
2010-05-07 19:33                                             ` [linux-pm] " Matthew Garrett
2010-05-07 19:55                                               ` Tony Lindgren
2010-05-07 20:28                                                 ` Matthew Garrett
2010-05-07 20:28                                                 ` [linux-pm] " Matthew Garrett
2010-05-07 20:53                                                   ` Tony Lindgren
2010-05-07 20:53                                                   ` [linux-pm] " Tony Lindgren
2010-05-07 21:03                                                     ` Matthew Garrett
2010-05-07 21:25                                                       ` Tony Lindgren
2010-05-07 21:25                                                       ` [linux-pm] " Tony Lindgren
2010-05-07 21:32                                                         ` Arve Hjønnevåg
2010-05-07 21:39                                                         ` Matthew Garrett
2010-05-07 21:39                                                         ` [linux-pm] " Matthew Garrett
2010-05-07 21:42                                                           ` Tony Lindgren
2010-05-07 21:42                                                           ` [linux-pm] " Tony Lindgren
2010-05-07 21:48                                                             ` Matthew Garrett
2010-05-07 22:00                                                               ` Tony Lindgren
2010-05-07 22:00                                                               ` [linux-pm] " Tony Lindgren
2010-05-07 22:28                                                                 ` Matthew Garrett
2010-05-07 21:48                                                             ` Matthew Garrett
2010-05-07 21:30                                                       ` Daniel Walker
2010-05-07 21:30                                                       ` [linux-pm] " Daniel Walker
2010-05-07 21:35                                                         ` Arve Hjønnevåg
2010-05-07 21:43                                                           ` Daniel Walker
2010-05-07 21:35                                                         ` Arve Hjønnevåg
2010-05-07 21:38                                                         ` Matthew Garrett
2010-05-07 21:03                                                     ` Matthew Garrett
2010-05-07 19:55                                               ` Tony Lindgren
2010-05-07 19:28                                           ` Tony Lindgren
2010-05-07 18:28                                   ` Matthew Garrett
2010-05-07 17:50                               ` Matthew Garrett
2010-05-07 17:12                           ` Matthew Garrett
2010-05-06 18:44                       ` Matthew Garrett
2010-05-06 18:47                       ` Alan Stern
2010-05-06 18:47                       ` [linux-pm] " Alan Stern
2010-05-07  2:20                         ` Tony Lindgren
2010-05-06 17:43                   ` Matthew Garrett
2010-05-28 13:29                   ` [linux-pm] " Pavel Machek
2010-05-28 13:42                     ` Brian Swetland
2010-05-28 13:29                   ` Pavel Machek
2010-05-06 17:22               ` Matthew Garrett
2010-05-06 17:35               ` [linux-pm] " Daniel Walker
2010-05-06 18:36                 ` Tony Lindgren
2010-05-06 19:11                   ` Daniel Walker
2010-05-07  2:00                     ` Tony Lindgren
2010-05-07  2:00                     ` [linux-pm] " Tony Lindgren
2010-05-07 17:20                       ` Daniel Walker
2010-05-07 17:36                         ` Matthew Garrett
2010-05-07 17:36                         ` [linux-pm] " Matthew Garrett
2010-05-07 17:40                           ` Daniel Walker
2010-05-07 17:51                             ` Matthew Garrett
2010-05-07 17:51                             ` [linux-pm] " Matthew Garrett
2010-05-07 18:00                               ` Daniel Walker
2010-05-07 18:17                                 ` Tony Lindgren
2010-05-07 18:00                               ` Daniel Walker
2010-05-07 17:40                           ` Daniel Walker
2010-05-07 17:50                         ` Tony Lindgren
2010-05-07 17:20                       ` Daniel Walker
2010-05-06 19:11                   ` Daniel Walker
2010-05-06 18:36                 ` Tony Lindgren
2010-05-06 17:35               ` Daniel Walker
2010-05-07  3:45               ` mgross
2010-05-06 17:14             ` Tony Lindgren
2010-05-07  3:45             ` [linux-pm] " mgross
2010-05-07  4:10               ` Arve Hjønnevåg
2010-05-07  3:45             ` mgross
2010-05-05 21:37   ` Brian Swetland
2010-05-05 21:12 ` Alan Stern
2010-05-14  4:11 [PATCH 0/8] Suspend block api (version 7) Arve Hjønnevåg
2010-05-14  4:11 ` [PATCH 1/8] PM: Add suspend block api Arve Hjønnevåg
2010-05-14  4:11   ` Arve Hjønnevåg
2010-05-14  6:13   ` Paul Walmsley
2010-05-14  6:27   ` Paul Walmsley
2010-05-14  7:14     ` Arve Hjønnevåg
2010-05-18  2:17       ` Paul Walmsley
2010-05-18  3:06         ` Arve Hjønnevåg
2010-05-18  3:34           ` Paul Walmsley
2010-05-18  3:51             ` Arve Hjønnevåg
2010-05-19 15:55               ` Paul Walmsley
2010-05-20  0:35                 ` Arve Hjønnevåg
2010-05-18 13:11   ` Pavel Machek
2010-05-18 13:11   ` Pavel Machek
2010-05-20  9:11     ` Florian Mickler
2010-05-20  9:26       ` Florian Mickler
2010-05-20  9:26       ` Florian Mickler
2010-05-20 22:18         ` Rafael J. Wysocki
2010-05-20 22:18         ` Rafael J. Wysocki
2010-05-21  6:04           ` Florian Mickler
2010-05-21  6:04           ` Florian Mickler
2010-05-27 15:41           ` Pavel Machek
2010-05-27 15:41           ` Pavel Machek
2010-05-20  9:11     ` Florian Mickler

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=d6200be20904291749v55f5e425jcbb570c09a3901d1@mail.gmail.com \
    --to=arve@android.com \
    --cc=linux-pm@lists.linux-foundation.org \
    --cc=ncunningham@crca.org.au \
    --cc=rjw@sisk.pl \
    --cc=swetland@google.com \
    --cc=u.luckas@road.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.