From patchwork Wed Sep 3 23:55:35 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brian Norris X-Patchwork-Id: 4841331 Return-Path: X-Original-To: patchwork-linux-pm@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork1.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.19.201]) by patchwork1.web.kernel.org (Postfix) with ESMTP id C1C7B9F314 for ; Thu, 4 Sep 2014 00:06:34 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id BBFEA2020E for ; Thu, 4 Sep 2014 00:06:33 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id 9D62120148 for ; Thu, 4 Sep 2014 00:06:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1753749AbaIDAGb (ORCPT ); Wed, 3 Sep 2014 20:06:31 -0400 Received: from mail-pa0-f42.google.com ([209.85.220.42]:39694 "EHLO mail-pa0-f42.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750788AbaIDAGa (ORCPT ); Wed, 3 Sep 2014 20:06:30 -0400 Received: by mail-pa0-f42.google.com with SMTP id lf10so18696419pab.1 for ; Wed, 03 Sep 2014 17:06:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:to:cc:subject:date:message-id; bh=eI74xFqlkOzlScthDbTSpMYVW11NokB4fLP8btyeSjk=; b=AJl31bRfQ+BTzLJWCO2FlJ5Pp9cDKhab/+jinxvcMVqiXOMIydgyWrGpvFFbg0nKw7 HTmsQk1SlbLQErvKYi2YxWpi9KiddOaBTrxWKmF/xVXQPGkdZtJkqfPAp3n6BM3hbOst VAhfGL4f5ZD2FnNsjeLBg7Lc3+AObay0IJ8Ta0rZOQSHmIBDeJUEP60tUD4FW4EBOMC8 jDf8nsFwhz4yZjYwiyGSel5dvtDq2CVBshw8zF0NZg7501vrmGL4p18XDr+tLdSpgn32 mVA8OAHpoSjnegEz7p9Qkt3Ou0Y1D85iS6UUFsGUdNmgycoUVKaf18T6gyguVoMZ80Hg 1+eA== X-Received: by 10.66.251.132 with SMTP id zk4mr1456856pac.47.1409789190147; Wed, 03 Sep 2014 17:06:30 -0700 (PDT) Received: from ld-irv-0074.broadcom.com (5520-maca-inet1-outside.broadcom.com. [216.31.211.11]) by mx.google.com with ESMTPSA id j1sm37580pdf.72.2014.09.03.17.06.28 for (version=TLSv1.2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 03 Sep 2014 17:06:29 -0700 (PDT) From: Brian Norris To: "Rafael J. Wysocki\"" Cc: Brian Norris , Linux Kernel , , Len Brown , Pavel Machek Subject: [PATCH] PM / sleep: add configurable delay for pm_test Date: Wed, 3 Sep 2014 16:55:35 -0700 Message-Id: <1409788535-28264-1-git-send-email-computersforpeace@gmail.com> X-Mailer: git-send-email 1.9.1 Sender: linux-pm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pm@vger.kernel.org X-Spam-Status: No, score=-8.5 required=5.0 tests=BAYES_00, DKIM_ADSP_CUSTOM_MED, DKIM_SIGNED, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, T_DKIM_INVALID, UNPARSEABLE_RELAY autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on mail.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP When CONFIG_PM_DEBUG=y, we provide a sysfs file (/sys/power/pm_test) for selecting one of a few suspend test modes, where rather than entering a full suspend state, the kernel will perform some subset of suspend steps, wait 5 seconds, and then resume back to normal operation. This mode is useful for (among other things) observing the state of the system just before entering a sleep mode, for debugging or analysis purposes. However, a constant 5 second wait is not sufficient for some sorts of analysis; for example, on an SoC, one might want to use external tools to probe the power states of various on-chip controllers or clocks. This patch adds a companion sysfs file (/sys/power/pm_test_delay) that allows user-space to configure how long the system waits in this test state before resuming. It also updates the PM debugging documentation to mention the new file. Signed-off-by: Brian Norris --- Documentation/power/basic-pm-debugging.txt | 14 ++++++++------ kernel/power/main.c | 27 +++++++++++++++++++++++++++ kernel/power/power.h | 5 +++++ kernel/power/suspend.c | 8 ++++++-- 4 files changed, 46 insertions(+), 8 deletions(-) diff --git a/Documentation/power/basic-pm-debugging.txt b/Documentation/power/basic-pm-debugging.txt index edeecd447d23..bd9f27ae99fe 100644 --- a/Documentation/power/basic-pm-debugging.txt +++ b/Documentation/power/basic-pm-debugging.txt @@ -75,12 +75,14 @@ you should do the following: # echo platform > /sys/power/disk # echo disk > /sys/power/state -Then, the kernel will try to freeze processes, suspend devices, wait 5 seconds, -resume devices and thaw processes. If "platform" is written to -/sys/power/pm_test , then after suspending devices the kernel will additionally -invoke the global control methods (eg. ACPI global control methods) used to -prepare the platform firmware for hibernation. Next, it will wait 5 seconds and -invoke the platform (eg. ACPI) global methods used to cancel hibernation etc. +Then, the kernel will try to freeze processes, suspend devices, wait a few +seconds (5 by default, but configurable via /sys/power/pm_test_delay), resume +devices and thaw processes. If "platform" is written to /sys/power/pm_test, +then after suspending devices the kernel will additionally invoke the global +control methods (eg. ACPI global control methods) used to prepare the platform +firmware for hibernation. Next, it will wait a configurable number of seconds +and invoke the platform (eg. ACPI) global methods used to cancel hibernation +etc. Writing "none" to /sys/power/pm_test causes the kernel to switch to the normal hibernation/suspend operations. Also, when open for reading, /sys/power/pm_test diff --git a/kernel/power/main.c b/kernel/power/main.c index 9a59d042ea84..4d242c8b43a0 100644 --- a/kernel/power/main.c +++ b/kernel/power/main.c @@ -73,6 +73,7 @@ power_attr(pm_async); #ifdef CONFIG_PM_DEBUG int pm_test_level = TEST_NONE; +int pm_test_seconds = PM_TEST_DELAY_DEFAULT; static const char * const pm_tests[__TEST_AFTER_LAST] = { [TEST_NONE] = "none", @@ -132,6 +133,31 @@ static ssize_t pm_test_store(struct kobject *kobj, struct kobj_attribute *attr, } power_attr(pm_test); + +static ssize_t pm_test_delay_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + return sprintf(buf, "%d\n", pm_test_seconds); +} + +static ssize_t pm_test_delay_store(struct kobject *kobj, + struct kobj_attribute *attr, + const char *buf, size_t n) +{ + int val; + + if (kstrtoint(buf, 10, &val)) + return -EINVAL; + + if (val < 0) + return -EINVAL; + + pm_test_seconds = val; + + return n; +} + +power_attr(pm_test_delay); #endif /* CONFIG_PM_DEBUG */ #ifdef CONFIG_DEBUG_FS @@ -601,6 +627,7 @@ static struct attribute * g[] = { #endif #ifdef CONFIG_PM_DEBUG &pm_test_attr.attr, + &pm_test_delay_attr.attr, #endif #ifdef CONFIG_PM_SLEEP_DEBUG &pm_print_times_attr.attr, diff --git a/kernel/power/power.h b/kernel/power/power.h index 5d49dcac2537..28111795da71 100644 --- a/kernel/power/power.h +++ b/kernel/power/power.h @@ -230,6 +230,11 @@ enum { extern int pm_test_level; +/* Default to 5 second delay */ +#define PM_TEST_DELAY_DEFAULT 5 + +extern int pm_test_seconds; + #ifdef CONFIG_SUSPEND_FREEZER static inline int suspend_freeze_processes(void) { diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index 6dadb25cb0d8..2372a99d4356 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c @@ -196,8 +196,12 @@ static int suspend_test(int level) { #ifdef CONFIG_PM_DEBUG if (pm_test_level == level) { - printk(KERN_INFO "suspend debug: Waiting for 5 seconds.\n"); - mdelay(5000); + int i; + + pr_info("suspend debug: waiting for %d second(s)\n", + pm_test_seconds); + for (i = 0; i < pm_test_seconds; i++) + mdelay(1000); return 1; } #endif /* !CONFIG_PM_DEBUG */