From patchwork Sun Oct 7 07:27:15 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jean-Christophe PLAGNIOL-VILLARD X-Patchwork-Id: 1560681 Return-Path: X-Original-To: patchwork-linux-arm@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork1.kernel.org Received: from merlin.infradead.org (merlin.infradead.org [205.233.59.134]) by patchwork1.kernel.org (Postfix) with ESMTP id 67CCD3FC1A for ; Sun, 7 Oct 2012 07:40:28 +0000 (UTC) Received: from localhost ([::1] helo=merlin.infradead.org) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TKlRn-0006si-IA; Sun, 07 Oct 2012 07:38:47 +0000 Received: from 14.mo1.mail-out.ovh.net ([178.32.97.215] helo=mo1.mail-out.ovh.net) by merlin.infradead.org with esmtp (Exim 4.76 #1 (Red Hat Linux)) id 1TKlRK-0006on-Of for linux-arm-kernel@lists.infradead.org; Sun, 07 Oct 2012 07:38:20 +0000 Received: from mail625.ha.ovh.net (b7.ovh.net [213.186.33.57]) by mo1.mail-out.ovh.net (Postfix) with SMTP id 107F5FFB060 for ; Sun, 7 Oct 2012 09:39:10 +0200 (CEST) Received: from b0.ovh.net (HELO queueout) (213.186.33.50) by b0.ovh.net with SMTP; 7 Oct 2012 09:29:54 +0200 Received: from ns32433.ovh.net (HELO localhost) (plagnioj%jcrosoft.com@213.251.161.87) by ns0.ovh.net with SMTP; 7 Oct 2012 09:29:52 +0200 From: Jean-Christophe PLAGNIOL-VILLARD To: linux-arm-kernel@lists.infradead.org X-Ovh-Mailout: 178.32.228.1 (mo1.mail-out.ovh.net) Subject: [PATCH 1/6] pm: add suspend_mem and suspend_standby support Date: Sun, 7 Oct 2012 09:27:15 +0200 Message-Id: <1349594840-11374-1-git-send-email-plagnioj@jcrosoft.com> X-Mailer: git-send-email 1.7.10 In-Reply-To: <20121006161429.GD12462@game.jcrosoft.org> References: <20121006161429.GD12462@game.jcrosoft.org> X-Ovh-Tracer-Id: 3418232118544870397 X-Ovh-Remote: 213.251.161.87 (ns32433.ovh.net) X-Ovh-Local: 213.186.33.20 (ns0.ovh.net) X-OVH-SPAMSTATE: OK X-OVH-SPAMSCORE: -100 X-OVH-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeehuddrudduucetufdoteggodetrfcurfhrohhfihhlvgemucfqggfjnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfhrhhomheplfgvrghnqdevhhhrihhsthhophhhvgcurffntefipffkqffnqdggkffnnfettfffuceophhlrghgnhhiohhjsehjtghrohhsohhfthdrtghomheqnecujfgurhephffvufffkffojghfsedttdertdertddt X-Spam-Check: DONE|U 0.5/N X-VR-SPAMSTATE: OK X-VR-SPAMSCORE: -100 X-VR-SPAMCAUSE: gggruggvucftvghtrhhoucdtuddrfeehuddrudduucetufdoteggodetrfcurfhrohhfihhlvgemucfqggfjnecuuegrihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfhrhhomheplfgvrghnqdevhhhrihhsthhophhhvgcurffntefipffkqffnqdggkffnnfettfffuceophhlrghgnhhiohhjsehjtghrohhsohhfthdrtghomheqnecujfgurhephffvufffkffojghfsedttdertdertddt X-Spam-Note: CRM114 invocation failed X-Spam-Score: -1.9 (-) X-Spam-Report: SpamAssassin version 3.3.2 on merlin.infradead.org summary: Content analysis details: (-1.9 points) pts rule name description ---- ---------------------- -------------------------------------------------- -0.0 RCVD_IN_DNSWL_NONE RBL: Sender listed at http://www.dnswl.org/, no trust [178.32.97.215 listed in list.dnswl.org] -0.0 SPF_PASS SPF: sender matches SPF record -1.9 BAYES_00 BODY: Bayes spam probability is 0 to 1% [score: 0.0000] Cc: Nicolas Ferre , linux-pm@vger.kernel.org, Jean-Christophe PLAGNIOL-VILLARD , Greg Kroah-Hartman X-BeenThere: linux-arm-kernel@lists.infradead.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Sender: linux-arm-kernel-bounces@lists.infradead.org Errors-To: linux-arm-kernel-bounces+patchwork-linux-arm=patchwork.kernel.org@lists.infradead.org Today when we go to suspend we can not knwon at drivers level if we go in STANDBY or MEM. Fix this by introducing two new callback suspend_mem and suspend_standby. If a bus does not need to care about this distinction we fallback to suspend. This will allow to do not update the current bus or drivers. This is needed as example by at91 OHCI and atmel serial Cc: Nicolas Ferre Cc: Greg Kroah-Hartman Signed-off-by: Jean-Christophe PLAGNIOL-VILLARD Cc: linux-pm@vger.kernel.org --- drivers/base/power/main.c | 12 ++++++++++++ include/linux/pm.h | 9 +++++++++ kernel/power/suspend.c | 16 ++++++++++++++-- 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/drivers/base/power/main.c b/drivers/base/power/main.c index a3c1404..581e135 100644 --- a/drivers/base/power/main.c +++ b/drivers/base/power/main.c @@ -218,9 +218,21 @@ static void dpm_wait_for_children(struct device *dev, bool async) */ static pm_callback_t pm_op(const struct dev_pm_ops *ops, pm_message_t state) { + pm_callback_t callback = NULL; + switch (state.event) { #ifdef CONFIG_SUSPEND case PM_EVENT_SUSPEND: + switch (state.param) { + case PM_SUSPEND_MEM: + callback = ops->suspend_mem; + break; + case PM_SUSPEND_STANDBY: + callback = ops->suspend_standby; + break; + } + if (callback) + return callback; return ops->suspend; case PM_EVENT_RESUME: return ops->resume; diff --git a/include/linux/pm.h b/include/linux/pm.h index 007e687..aff344b 100644 --- a/include/linux/pm.h +++ b/include/linux/pm.h @@ -49,6 +49,7 @@ extern const char power_group_name[]; /* = "power" */ typedef struct pm_message { int event; + int param; } pm_message_t; /** @@ -265,6 +266,8 @@ struct dev_pm_ops { int (*prepare)(struct device *dev); void (*complete)(struct device *dev); int (*suspend)(struct device *dev); + int (*suspend_mem)(struct device *dev); + int (*suspend_standby)(struct device *dev); int (*resume)(struct device *dev); int (*freeze)(struct device *dev); int (*thaw)(struct device *dev); @@ -295,8 +298,12 @@ struct dev_pm_ops { .thaw = resume_fn, \ .poweroff = suspend_fn, \ .restore = resume_fn, +#define SET_SYSTEM_SLEEP_STANDBY_MEM_PM_OPS(suspend_standby_fn, suspend_mem_fn) \ + .suspend_standby = suspend_standby_fn, \ + .suspend_mem = suspend_mem_fn, #else #define SET_SYSTEM_SLEEP_PM_OPS(suspend_fn, resume_fn) +#define SET_SYSTEM_SLEEP_STANDBY_MEM_PM_OPS(suspend_standby_fn, suspend_mem_fn) #endif #ifdef CONFIG_PM_RUNTIME @@ -414,6 +421,8 @@ const struct dev_pm_ops name = { \ #define PMSG_FREEZE ((struct pm_message){ .event = PM_EVENT_FREEZE, }) #define PMSG_QUIESCE ((struct pm_message){ .event = PM_EVENT_QUIESCE, }) #define PMSG_SUSPEND ((struct pm_message){ .event = PM_EVENT_SUSPEND, }) +#define PMSG_SUSPEND_MEM ((struct pm_message){ .event = PM_EVENT_SUSPEND, .param = PM_SUSPEND_MEM, }) +#define PMSG_SUSPEND_STANDBY ((struct pm_message){ .event = PM_EVENT_SUSPEND, .param = PM_SUSPEND_STANDBY, }) #define PMSG_HIBERNATE ((struct pm_message){ .event = PM_EVENT_HIBERNATE, }) #define PMSG_RESUME ((struct pm_message){ .event = PM_EVENT_RESUME, }) #define PMSG_THAW ((struct pm_message){ .event = PM_EVENT_THAW, }) diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index c8b7446..9505b55 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c @@ -126,6 +126,18 @@ void __attribute__ ((weak)) arch_suspend_enable_irqs(void) local_irq_enable(); } +static pm_message_t suspend_state_to_pm_state(suspend_state_t state) +{ + switch (state) { + case PM_SUSPEND_STANDBY: + return PMSG_SUSPEND_STANDBY; + case PM_SUSPEND_MEM: + return PMSG_SUSPEND_MEM; + default: + return PMSG_SUSPEND; + } +} + /** * suspend_enter - Make the system enter the given sleep state. * @state: System sleep state to enter. @@ -143,7 +155,7 @@ static int suspend_enter(suspend_state_t state, bool *wakeup) goto Platform_finish; } - error = dpm_suspend_end(PMSG_SUSPEND); + error = dpm_suspend_end(suspend_state_to_pm_state(state)); if (error) { printk(KERN_ERR "PM: Some devices failed to power down\n"); goto Platform_finish; @@ -215,7 +227,7 @@ int suspend_devices_and_enter(suspend_state_t state) suspend_console(); ftrace_stop(); suspend_test_start(); - error = dpm_suspend_start(PMSG_SUSPEND); + error = dpm_suspend_start(suspend_state_to_pm_state(state)); if (error) { printk(KERN_ERR "PM: Some devices failed to suspend\n"); goto Recover_platform;