From patchwork Wed Aug 31 18:31:19 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Konrad Rzeszutek Wilk X-Patchwork-Id: 1117562 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.4) with ESMTP id p7VIXU6J000602 for ; Wed, 31 Aug 2011 18:33:37 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751882Ab1HaSdf (ORCPT ); Wed, 31 Aug 2011 14:33:35 -0400 Received: from acsinet15.oracle.com ([141.146.126.227]:43066 "EHLO acsinet15.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751702Ab1HaSdd (ORCPT ); Wed, 31 Aug 2011 14:33:33 -0400 Received: from rtcsinet21.oracle.com (rtcsinet21.oracle.com [66.248.204.29]) by acsinet15.oracle.com (Switch-3.4.4/Switch-3.4.4) with ESMTP id p7VIVfs3023467 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=OK); Wed, 31 Aug 2011 18:31:43 GMT Received: from acsmt356.oracle.com (acsmt356.oracle.com [141.146.40.156]) by rtcsinet21.oracle.com (8.14.4+Sun/8.14.4) with ESMTP id p7VIVcSi007986 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 31 Aug 2011 18:31:38 GMT Received: from abhmt103.oracle.com (abhmt103.oracle.com [141.146.116.55]) by acsmt356.oracle.com (8.12.11.20060308/8.12.11) with ESMTP id p7VIVVG7005222; Wed, 31 Aug 2011 13:31:31 -0500 Received: from phenom (/209.6.55.207) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 31 Aug 2011 11:31:31 -0700 Received: by phenom (Postfix, from userid 1000) id 74BE3E45; Wed, 31 Aug 2011 14:31:29 -0400 (EDT) From: Konrad Rzeszutek Wilk To: x86@kernel.org, tglx@linutronix.de, tboot-devel@lists.sourceforge.net, shane.wang@intel.com, linux-pm@lists.linux-foundation.org, linux-acpi@vger.kernel.org, len.brown@intel.com, joseph.cihula@intel.com, hpa@zytor.com, ke.yu@intel.com, liang.tang@oracle.com, kevin.tian@intel.com, keir@xen.org Cc: xen-devel@lists.xensource.com, Konrad Rzeszutek Wilk Subject: [PATCH 2/7] x86, acpi, tboot: Have a ACPI sleep override instead of calling tboot_sleep. Date: Wed, 31 Aug 2011 14:31:19 -0400 Message-Id: <1314815484-4668-3-git-send-email-konrad.wilk@oracle.com> X-Mailer: git-send-email 1.7.4.1 In-Reply-To: <1314815484-4668-1-git-send-email-konrad.wilk@oracle.com> References: <1314815484-4668-1-git-send-email-konrad.wilk@oracle.com> X-Source-IP: rtcsinet21.oracle.com [66.248.204.29] X-CT-RefId: str=0001.0A090205.4E5E7E13.016D,ss=1,re=0.000,fgs=0 Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.6 (demeter1.kernel.org [140.211.167.41]); Wed, 31 Aug 2011 18:33:37 +0000 (UTC) The ACPI suspend path makes a call to tboot_sleep right before it writes the PM1A, PM1B values. We replace the direct call to tboot via an registration callback similar to __acpi_register_gsi. CC: Thomas Gleixner CC: "H. Peter Anvin" CC: x86@kernel.org CC: Len Brown CC: Joseph Cihula CC: Shane Wang CC: xen-devel@lists.xensource.com CC: linux-pm@lists.linux-foundation.org CC: tboot-devel@lists.sourceforge.net CC: linux-acpi@vger.kernel.org Signed-off-by: Konrad Rzeszutek Wilk --- arch/x86/include/asm/acpi.h | 3 +++ arch/x86/kernel/acpi/boot.c | 3 +++ arch/x86/kernel/tboot.c | 13 +++++++++---- drivers/acpi/acpica/hwsleep.c | 12 ++++++++++-- include/linux/tboot.h | 3 ++- 5 files changed, 27 insertions(+), 7 deletions(-) diff --git a/arch/x86/include/asm/acpi.h b/arch/x86/include/asm/acpi.h index 610001d..49864a1 100644 --- a/arch/x86/include/asm/acpi.h +++ b/arch/x86/include/asm/acpi.h @@ -98,6 +98,9 @@ void acpi_pic_sci_set_trigger(unsigned int, u16); extern int (*__acpi_register_gsi)(struct device *dev, u32 gsi, int trigger, int polarity); +extern int (*__acpi_override_sleep)(u8 sleep_state, u32 pm1a_ctrl, + u32 pm1b_ctrl, bool *skip_rest); + static inline void disable_acpi(void) { acpi_disabled = 1; diff --git a/arch/x86/kernel/acpi/boot.c b/arch/x86/kernel/acpi/boot.c index 4558f0d..d191b4c 100644 --- a/arch/x86/kernel/acpi/boot.c +++ b/arch/x86/kernel/acpi/boot.c @@ -552,6 +552,9 @@ static int acpi_register_gsi_ioapic(struct device *dev, u32 gsi, int (*__acpi_register_gsi)(struct device *dev, u32 gsi, int trigger, int polarity) = acpi_register_gsi_pic; +int (*__acpi_override_sleep)(u8 sleep_state, u32 pm1a_ctrl, + u32 pm1b_ctrl, bool *skip_rest) = NULL; + /* * success: return IRQ number (>=0) * failure: return < 0 diff --git a/arch/x86/kernel/tboot.c b/arch/x86/kernel/tboot.c index 30ac65d..a18070c 100644 --- a/arch/x86/kernel/tboot.c +++ b/arch/x86/kernel/tboot.c @@ -41,7 +41,7 @@ #include #include #include - +#include #include "acpi/realmode/wakeup.h" /* Global pointer to shared data; NULL means no measured launch. */ @@ -270,7 +270,8 @@ static void tboot_copy_fadt(const struct acpi_table_fadt *fadt) offsetof(struct acpi_table_facs, firmware_waking_vector); } -void tboot_sleep(u8 sleep_state, u32 pm1a_control, u32 pm1b_control) +int tboot_sleep(u8 sleep_state, u32 pm1a_control, u32 pm1b_control, + bool *skip_rest) { static u32 acpi_shutdown_map[ACPI_S_STATE_COUNT] = { /* S0,1,2: */ -1, -1, -1, @@ -279,7 +280,7 @@ void tboot_sleep(u8 sleep_state, u32 pm1a_control, u32 pm1b_control) /* S5: */ TB_SHUTDOWN_S5 }; if (!tboot_enabled()) - return; + return AE_OK; tboot_copy_fadt(&acpi_gbl_FADT); tboot->acpi_sinfo.pm1a_cnt_val = pm1a_control; @@ -290,10 +291,12 @@ void tboot_sleep(u8 sleep_state, u32 pm1a_control, u32 pm1b_control) if (sleep_state >= ACPI_S_STATE_COUNT || acpi_shutdown_map[sleep_state] == -1) { pr_warning("unsupported sleep state 0x%x\n", sleep_state); - return; + return AE_ERROR; } tboot_shutdown(acpi_shutdown_map[sleep_state]); + + return AE_OK; } static atomic_t ap_wfs_count; @@ -343,6 +346,8 @@ static __init int tboot_late_init(void) atomic_set(&ap_wfs_count, 0); register_hotcpu_notifier(&tboot_cpu_notifier); + + __acpi_override_sleep = tboot_sleep; return 0; } diff --git a/drivers/acpi/acpica/hwsleep.c b/drivers/acpi/acpica/hwsleep.c index 2ac28bb..31d1198 100644 --- a/drivers/acpi/acpica/hwsleep.c +++ b/drivers/acpi/acpica/hwsleep.c @@ -45,7 +45,6 @@ #include #include "accommon.h" #include "actables.h" -#include #define _COMPONENT ACPI_HARDWARE ACPI_MODULE_NAME("hwsleep") @@ -343,8 +342,17 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state) ACPI_FLUSH_CPU_CACHE(); - tboot_sleep(sleep_state, pm1a_control, pm1b_control); + if (__acpi_override_sleep) { + bool skip_rest = false; + status = __acpi_override_sleep(sleep_state, pm1a_control, + pm1b_control, &skip_rest); + + if (ACPI_FAILURE(status)) + return_ACPI_STATUS(status); + if (skip_rest) + return_ACPI_STATUS(AE_OK); + } /* Write #2: Write both SLP_TYP + SLP_EN */ status = acpi_hw_write_pm1_control(pm1a_control, pm1b_control); diff --git a/include/linux/tboot.h b/include/linux/tboot.h index 1dba6ee..19badbd 100644 --- a/include/linux/tboot.h +++ b/include/linux/tboot.h @@ -143,7 +143,8 @@ static inline int tboot_enabled(void) extern void tboot_probe(void); extern void tboot_shutdown(u32 shutdown_type); -extern void tboot_sleep(u8 sleep_state, u32 pm1a_control, u32 pm1b_control); +extern int tboot_sleep(u8 sleep_state, u32 pm1a_control, u32 pm1b_control, + bool *skip); extern struct acpi_table_header *tboot_get_dmar_table( struct acpi_table_header *dmar_tbl); extern int tboot_force_iommu(void);