From patchwork Thu Mar 3 05:10:17 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Chen Yu X-Patchwork-Id: 8487861 Return-Path: X-Original-To: patchwork-linux-acpi@patchwork.kernel.org Delivered-To: patchwork-parsemail@patchwork2.web.kernel.org Received: from mail.kernel.org (mail.kernel.org [198.145.29.136]) by patchwork2.web.kernel.org (Postfix) with ESMTP id B2F1AC0553 for ; Thu, 3 Mar 2016 05:04:55 +0000 (UTC) Received: from mail.kernel.org (localhost [127.0.0.1]) by mail.kernel.org (Postfix) with ESMTP id C6C3A202E5 for ; Thu, 3 Mar 2016 05:04:54 +0000 (UTC) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.kernel.org (Postfix) with ESMTP id B59A6202AE for ; Thu, 3 Mar 2016 05:04:53 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751175AbcCCFEw (ORCPT ); Thu, 3 Mar 2016 00:04:52 -0500 Received: from mga01.intel.com ([192.55.52.88]:17509 "EHLO mga01.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751082AbcCCFEw (ORCPT ); Thu, 3 Mar 2016 00:04:52 -0500 Received: from orsmga002.jf.intel.com ([10.7.209.21]) by fmsmga101.fm.intel.com with ESMTP; 02 Mar 2016 21:04:30 -0800 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.22,531,1449561600"; d="scan'208";a="925707007" Received: from unknown (HELO localhost.localdomain.sh.intel.com) ([10.239.160.87]) by orsmga002.jf.intel.com with ESMTP; 02 Mar 2016 21:04:30 -0800 From: Chen Yu To: linux-acpi@vger.kernel.org Cc: x86@kernel.org, linux-kernel@vger.kernel.org, linux-efi@vger.kernel.org, "Rafael J. Wysocki" , Len Brown , Zhang Rui , Chen Yu Subject: [PATCH][v2] ACPI / PM: Fix poweroff issue on HW-full platforms without _S5 Date: Thu, 3 Mar 2016 13:10:17 +0800 Message-Id: <1456981817-26248-1-git-send-email-yu.c.chen@intel.com> X-Mailer: git-send-email 1.8.4.2 Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Spam-Status: No, score=-6.9 required=5.0 tests=BAYES_00, RCVD_IN_DNSWL_HI, RP_MATCHES_RCVD, UNPARSEABLE_RELAY autolearn=unavailable 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 The problem is Linux registers pm_power_off = efi_power_off only if we are in hardware reduced mode. Actually, what we also want is to do this when ACPI S5 is simply not supported. That should handle both the HW reduced mode, and the HW-full mode where the DSDT fails to supply an _S5 object. This patch fixes this issue by introducing a new flag acpi_no_s5 which indicates the non-existence of _S5. The initial state of acpi_no_s5 is false and probed in acpi_sleep_init, then we'll later see the updated value in efi_poweroff_required, according to which we can set pm_power_off to efi_power_off in efi_shutdown_init. Suggested-by: Len Brown Signed-off-by: Chen Yu --- v2: - Convert the acpi_no_s5 to a global bool variable in sleep.c and add a declaration to include/linux/acpi.h. --- arch/x86/platform/efi/quirks.c | 2 +- drivers/acpi/sleep.c | 7 +++++++ include/linux/acpi.h | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/arch/x86/platform/efi/quirks.c b/arch/x86/platform/efi/quirks.c index 2d66db8..04fa63b 100644 --- a/arch/x86/platform/efi/quirks.c +++ b/arch/x86/platform/efi/quirks.c @@ -295,5 +295,5 @@ bool efi_reboot_required(void) bool efi_poweroff_required(void) { - return !!acpi_gbl_reduced_hardware; + return acpi_gbl_reduced_hardware || acpi_no_s5; } diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 9cb9752..a33859c 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -25,6 +25,11 @@ #include "internal.h" #include "sleep.h" +/* + * Some HW-full platforms do not have _S5, so they may need + * to leverage efi power off for a shutdown. + */ +bool acpi_no_s5; static u8 sleep_states[ACPI_S_STATE_COUNT]; static void acpi_sleep_tts_switch(u32 acpi_state) @@ -846,6 +851,8 @@ int __init acpi_sleep_init(void) sleep_states[ACPI_STATE_S5] = 1; pm_power_off_prepare = acpi_power_off_prepare; pm_power_off = acpi_power_off; + } else { + acpi_no_s5 = true; } supported[0] = 0; diff --git a/include/linux/acpi.h b/include/linux/acpi.h index 06ed7e5..4d2e67f 100644 --- a/include/linux/acpi.h +++ b/include/linux/acpi.h @@ -278,6 +278,7 @@ void acpi_irq_stats_init(void); extern u32 acpi_irq_handled; extern u32 acpi_irq_not_handled; extern unsigned int acpi_sci_irq; +extern bool acpi_no_s5; #define INVALID_ACPI_IRQ ((unsigned)-1) static inline bool acpi_sci_irq_valid(void) {