public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Ross Zwisler <zwisler@google.com>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Furquan Shaikh <furquan@chromium.org>,
	Duncan Laurie <dlaurie@chromium.org>,
	Guenter Roeck <groeck@google.com>,
	linux-kernel@vger.kernel.org, Furquan Shaikh <furquan@google.com>,
	Ross Zwisler <zwisler@google.com>
Subject: [PATCH 4/4] gsmi: Add GSMI commands to log S0ix info
Date: Fri, 12 Oct 2018 10:04:48 -0600	[thread overview]
Message-ID: <20181012160448.79018-5-zwisler@google.com> (raw)
In-Reply-To: <20181012160448.79018-1-zwisler@google.com>

From: Furquan Shaikh <furquan@chromium.org>

Add new GSMI commands (GSMI_CMD_LOG_S0IX_SUSPEND = 0xa,
GSMI_CMD_LOG_S0IX_RESUME = 0xb) that allow firmware to log any
information during S0ix suspend/resume paths.

Traditional ACPI suspend S3 involves BIOS both during the suspend and
the resume paths. However, modern suspend type like S0ix does not
involve firmware on either of the paths. This command gives the
firmware an opportunity to log any required information about the
suspend and resume operations e.g. wake sources.

Additionally, this change adds a module parameter to allow platforms
to specifically enable S0ix logging if required. This prevents any
other platforms from unnecessarily making a GSMI call which could have
any side-effects.

Tested by verifying that wake sources are correctly logged in eventlog.

Signed-off-by: Furquan Shaikh <furquan@chromium.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-by: Rajat Jain <rajatja@chromium.org>
Signed-off-by: Furquan Shaikh <furquan@google.com>
Tested-by: Furquan Shaikh <furquan@chromium.org>
Reviewed-by: Aaron Durbin <adurbin@chromium.org>
[zwisler: update changelog for upstream]
Signed-off-by: Ross Zwisler <zwisler@google.com>
---
 drivers/firmware/google/gsmi.c | 93 +++++++++++++++++++++++++++++++++-
 1 file changed, 92 insertions(+), 1 deletion(-)

diff --git a/drivers/firmware/google/gsmi.c b/drivers/firmware/google/gsmi.c
index edab00cc6bba..7ee25ce0e318 100644
--- a/drivers/firmware/google/gsmi.c
+++ b/drivers/firmware/google/gsmi.c
@@ -29,6 +29,7 @@
 #include <linux/efi.h>
 #include <linux/module.h>
 #include <linux/ucs2_string.h>
+#include <linux/suspend.h>
 
 #define GSMI_SHUTDOWN_CLEAN	0	/* Clean Shutdown */
 /* TODO(mikew@google.com): Tie in HARDLOCKUP_DETECTOR with NMIWDT */
@@ -70,6 +71,8 @@
 #define GSMI_CMD_SET_NVRAM_VAR		0x03
 #define GSMI_CMD_SET_EVENT_LOG		0x08
 #define GSMI_CMD_CLEAR_EVENT_LOG	0x09
+#define GSMI_CMD_LOG_S0IX_SUSPEND	0x0a
+#define GSMI_CMD_LOG_S0IX_RESUME	0x0b
 #define GSMI_CMD_CLEAR_CONFIG		0x20
 #define GSMI_CMD_HANDSHAKE_TYPE		0xC1
 
@@ -122,7 +125,6 @@ struct gsmi_log_entry_type_1 {
 	u32	instance;
 } __packed;
 
-
 /*
  * Some platforms don't have explicit SMI handshake
  * and need to wait for SMI to complete.
@@ -133,6 +135,15 @@ module_param(spincount, uint, 0600);
 MODULE_PARM_DESC(spincount,
 	"The number of loop iterations to use when using the spin handshake.");
 
+/*
+ * Platforms might not support S0ix logging in their GSMI handlers. In order to
+ * avoid any side-effects of generating an SMI for S0ix logging, use the S0ix
+ * related GSMI commands only for those platforms that explicitly enable this
+ * option.
+ */
+static bool s0ix_logging_enable;
+module_param(s0ix_logging_enable, bool, 0600);
+
 static struct gsmi_buf *gsmi_buf_alloc(void)
 {
 	struct gsmi_buf *smibuf;
@@ -781,6 +792,78 @@ static const struct platform_device_info gsmi_dev_info = {
 	.dma_mask	= DMA_BIT_MASK(32),
 };
 
+#ifdef CONFIG_PM
+static void gsmi_log_s0ix_info(u8 cmd)
+{
+	unsigned long flags;
+
+	/*
+	 * If platform has not enabled S0ix logging, then no action is
+	 * necessary.
+	 */
+	if (!s0ix_logging_enable)
+		return;
+
+	spin_lock_irqsave(&gsmi_dev.lock, flags);
+
+	memset(gsmi_dev.param_buf->start, 0, gsmi_dev.param_buf->length);
+
+	gsmi_exec(GSMI_CALLBACK, cmd);
+
+	spin_unlock_irqrestore(&gsmi_dev.lock, flags);
+}
+
+static int gsmi_log_s0ix_suspend(struct device *dev)
+{
+	/*
+	 * If system is not suspending via firmware using the standard ACPI Sx
+	 * types, then make a GSMI call to log the suspend info.
+	 */
+	if (!pm_suspend_via_firmware())
+		gsmi_log_s0ix_info(GSMI_CMD_LOG_S0IX_SUSPEND);
+
+	/*
+	 * Always return success, since we do not want suspend
+	 * to fail just because of logging failure.
+	 */
+	return 0;
+}
+
+static int gsmi_log_s0ix_resume(struct device *dev)
+{
+	/*
+	 * If system did not resume via firmware, then make a GSMI call to log
+	 * the resume info and wake source.
+	 */
+	if (!pm_resume_via_firmware())
+		gsmi_log_s0ix_info(GSMI_CMD_LOG_S0IX_RESUME);
+
+	/*
+	 * Always return success, since we do not want resume
+	 * to fail just because of logging failure.
+	 */
+	return 0;
+}
+
+static const struct dev_pm_ops gsmi_pm_ops = {
+	.suspend_noirq = gsmi_log_s0ix_suspend,
+	.resume_noirq = gsmi_log_s0ix_resume,
+};
+
+static int gsmi_platform_driver_probe(struct platform_device *dev)
+{
+	return 0;
+}
+
+static struct platform_driver gsmi_driver_info = {
+	.driver = {
+		.name = "gsmi",
+		.pm = &gsmi_pm_ops,
+	},
+	.probe = gsmi_platform_driver_probe,
+};
+#endif
+
 static __init int gsmi_init(void)
 {
 	unsigned long flags;
@@ -792,6 +875,14 @@ static __init int gsmi_init(void)
 
 	gsmi_dev.smi_cmd = acpi_gbl_FADT.smi_command;
 
+#ifdef CONFIG_PM
+	ret = platform_driver_register(&gsmi_driver_info);
+	if (unlikely(ret)) {
+		printk(KERN_ERR "gsmi: unable to register platform driver\n");
+		return ret;
+	}
+#endif
+
 	/* register device */
 	gsmi_dev.pdev = platform_device_register_full(&gsmi_dev_info);
 	if (IS_ERR(gsmi_dev.pdev)) {
-- 
2.19.0.605.g01d371f741-goog


  parent reply	other threads:[~2018-10-12 16:05 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-10-12 16:04 [PATCH 0/4] gsmi: Google specific firmware patches Ross Zwisler
2018-10-12 16:04 ` [PATCH 1/4] gsmi: Fix bug in append_to_eventlog sysfs handler Ross Zwisler
2018-10-12 16:04 ` [PATCH 2/4] gsmi: Add coreboot to list of matching BIOS vendors Ross Zwisler
2018-10-12 16:04 ` [PATCH 3/4] gsmi: Remove autoselected dependency on EFI and EFI_VARS Ross Zwisler
2018-10-12 16:04 ` Ross Zwisler [this message]
     [not found] ` <CABXOdTfUKWejqTxvtcH_O6SKaWDRGcu5qCVafTstm-r8y7ke1Q@mail.gmail.com>
2018-10-15 18:30   ` [PATCH 0/4] gsmi: Google specific firmware patches Greg Kroah-Hartman

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=20181012160448.79018-5-zwisler@google.com \
    --to=zwisler@google.com \
    --cc=dlaurie@chromium.org \
    --cc=furquan@chromium.org \
    --cc=furquan@google.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=groeck@google.com \
    --cc=linux-kernel@vger.kernel.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox