From patchwork Thu Aug 10 01:48:58 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lv Zheng X-Patchwork-Id: 800062 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=linux-pci-owner@vger.kernel.org; receiver=) Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3xSWJt3GjJz9t1t for ; Thu, 10 Aug 2017 11:49:18 +1000 (AEST) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752135AbdHJBtC convert rfc822-to-8bit (ORCPT ); Wed, 9 Aug 2017 21:49:02 -0400 Received: from mga09.intel.com ([134.134.136.24]:42245 "EHLO mga09.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751890AbdHJBtB (ORCPT ); Wed, 9 Aug 2017 21:49:01 -0400 Received: from orsmga002.jf.intel.com ([10.7.209.21]) by orsmga102.jf.intel.com with ESMTP/TLS/DHE-RSA-AES256-GCM-SHA384; 09 Aug 2017 18:49:01 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.41,349,1498546800"; d="scan'208";a="121888545" Received: from fmsmsx108.amr.corp.intel.com ([10.18.124.206]) by orsmga002.jf.intel.com with ESMTP; 09 Aug 2017 18:49:00 -0700 Received: from fmsmsx113.amr.corp.intel.com (10.18.116.7) by FMSMSX108.amr.corp.intel.com (10.18.124.206) with Microsoft SMTP Server (TLS) id 14.3.319.2; Wed, 9 Aug 2017 18:49:00 -0700 Received: from shsmsx104.ccr.corp.intel.com (10.239.4.70) by FMSMSX113.amr.corp.intel.com (10.18.116.7) with Microsoft SMTP Server (TLS) id 14.3.319.2; Wed, 9 Aug 2017 18:49:00 -0700 Received: from shsmsx101.ccr.corp.intel.com ([169.254.1.128]) by SHSMSX104.ccr.corp.intel.com ([169.254.5.114]) with mapi id 14.03.0319.002; Thu, 10 Aug 2017 09:48:58 +0800 From: "Zheng, Lv" To: "Rafael J. Wysocki" , Linux ACPI CC: Mika Westerberg , Srinivas Pandruvada , Linux PCI , LKML , "Moore, Robert" Subject: RE: [PATCH 1/3] ACPICA: Dispatch active GPEs at init time Thread-Topic: [PATCH 1/3] ACPICA: Dispatch active GPEs at init time Thread-Index: AQHTEWDck09JCTGfBE2UIpBZxOhPhaJ80aXw Date: Thu, 10 Aug 2017 01:48:58 +0000 Message-ID: <1AE640813FDE7649BE1B193DEA596E886CF066E6@SHSMSX101.ccr.corp.intel.com> References: <12346760.yAFCnkEgf6@aspire.rjw.lan> <46980112.WLPtxWZQ3y@aspire.rjw.lan> In-Reply-To: <46980112.WLPtxWZQ3y@aspire.rjw.lan> Accept-Language: zh-CN, en-US Content-Language: en-US X-MS-Has-Attach: X-MS-TNEF-Correlator: x-titus-metadata-40: eyJDYXRlZ29yeUxhYmVscyI6IiIsIk1ldGFkYXRhIjp7Im5zIjoiaHR0cDpcL1wvd3d3LnRpdHVzLmNvbVwvbnNcL0ludGVsMyIsImlkIjoiMDBiMjc3NDYtZGYzMS00NDY0LTg5ZTItYjhiMTk5YWFhMTA5IiwicHJvcHMiOlt7Im4iOiJDVFBDbGFzc2lmaWNhdGlvbiIsInZhbHMiOlt7InZhbHVlIjoiQ1RQX0lDIn1dfV19LCJTdWJqZWN0TGFiZWxzIjpbXSwiVE1DVmVyc2lvbiI6IjE2LjUuOS4zIiwiVHJ1c3RlZExhYmVsSGFzaCI6ImVZdnUwVERwbjlYSU43OVdlaUhDcVlEb3NXVUtaUFlIc3h2clZ2b01PdXM9In0= x-ctpclassification: CTP_IC dlp-product: dlpe-windows dlp-version: 10.0.102.7 dlp-reaction: no-action x-originating-ip: [10.239.127.40] MIME-Version: 1.0 Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org Hi, Rafael > From: Rafael J. Wysocki [mailto:rjw@rjwysocki.net] > Subject: [PATCH 1/3] ACPICA: Dispatch active GPEs at init time > > From: Rafael J. Wysocki > > In some cases GPEs are already active when they are enabled by > acpi_ev_initialize_gpe_block() and whatever happens next may depend > on the result of handling the events signaled by them, so the > events should not be discarded (which is what happens currently) and > they should be handled as soon as reasonably possible. > > For this reason, modify acpi_ev_initialize_gpe_block() to > dispatch GPEs with the status flag set in-band right after > enabling them. In fact, what we need seems to be invoking acpi_ev_gpe_dispatch() right after enabling an GPE. So there are 2 conditions related: 1. GPE is enabled for the first time. 2. GPE is initialized. And we need to make sure that before acpi_update_all_gpes() is invoked, all GPE EN bits are actually disabled. What if we do this in this way: Thanks and best regards Lv > > Signed-off-by: Rafael J. Wysocki > --- > drivers/acpi/acpica/evgpeblk.c | 28 +++++++++++++++++++--------- > 1 file changed, 19 insertions(+), 9 deletions(-) > > Index: linux-pm/drivers/acpi/acpica/evgpeblk.c > =================================================================== > --- linux-pm.orig/drivers/acpi/acpica/evgpeblk.c > +++ linux-pm/drivers/acpi/acpica/evgpeblk.c > @@ -440,9 +440,11 @@ acpi_ev_initialize_gpe_block(struct acpi > void *ignored) > { > acpi_status status; > + acpi_event_status event_status; > struct acpi_gpe_event_info *gpe_event_info; > u32 gpe_enabled_count; > u32 gpe_index; > + u32 gpe_number; > u32 i; > u32 j; > > @@ -470,30 +472,38 @@ acpi_ev_initialize_gpe_block(struct acpi > > gpe_index = (i * ACPI_GPE_REGISTER_WIDTH) + j; > gpe_event_info = &gpe_block->event_info[gpe_index]; > + gpe_number = gpe_block->block_base_number + gpe_index; > > /* > * Ignore GPEs that have no corresponding _Lxx/_Exx method > - * and GPEs that are used to wake the system > + * and GPEs that are used for wakeup > */ > - if ((ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) == > - ACPI_GPE_DISPATCH_NONE) > - || (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) == > - ACPI_GPE_DISPATCH_HANDLER) > - || (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) == > - ACPI_GPE_DISPATCH_RAW_HANDLER) > + if ((ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) != > + ACPI_GPE_DISPATCH_METHOD) > || (gpe_event_info->flags & ACPI_GPE_CAN_WAKE)) { > continue; > } > > + event_status = 0; > + (void)acpi_hw_get_gpe_status(gpe_event_info, > + &event_status); > + > status = acpi_ev_add_gpe_reference(gpe_event_info); > if (ACPI_FAILURE(status)) { > ACPI_EXCEPTION((AE_INFO, status, > "Could not enable GPE 0x%02X", > - gpe_index + > - gpe_block->block_base_number)); > + gpe_number)); > continue; > } > > + if (event_status & ACPI_EVENT_FLAG_STATUS_SET) { > + ACPI_INFO(("GPE 0x%02X active on init", > + gpe_number)); > + (void)acpi_ev_gpe_dispatch(gpe_block->node, > + gpe_event_info, > + gpe_number); > + } > + > gpe_enabled_count++; > } > } Index: linux-acpica/drivers/acpi/acpica/evxfgpe.c =================================================================== --- linux-acpica.orig/drivers/acpi/acpica/evxfgpe.c +++ linux-acpica/drivers/acpi/acpica/evxfgpe.c @@ -97,6 +97,14 @@ acpi_status acpi_update_all_gpes(void) unlock_and_exit: (void)acpi_ut_release_mutex(ACPI_MTX_EVENTS); + /* + * Poll GPEs to handle already triggered events. + * It is not sufficient to trigger edge-triggered GPE with specific + * GPE chips, software need to poll once after enabling. + */ + if (acpi_gbl_all_gpes_initialized) { + acpi_ev_gpe_detect(acpi_gbl_gpe_xrupt_list_head); + } return_ACPI_STATUS(status); } @@ -120,6 +128,7 @@ acpi_status acpi_enable_gpe(acpi_handle acpi_status status = AE_BAD_PARAMETER; struct acpi_gpe_event_info *gpe_event_info; acpi_cpu_flags flags; + u8 poll_gpes = FALSE; ACPI_FUNCTION_TRACE(acpi_enable_gpe); @@ -135,12 +144,25 @@ acpi_status acpi_enable_gpe(acpi_handle if (ACPI_GPE_DISPATCH_TYPE(gpe_event_info->flags) != ACPI_GPE_DISPATCH_NONE) { status = acpi_ev_add_gpe_reference(gpe_event_info); + if (ACPI_SUCCESS(status) && + gpe_event_info->runtime_count == 1) { + poll_gpes = TRUE; + } } else { status = AE_NO_HANDLER; } } acpi_os_release_lock(acpi_gbl_gpe_lock, flags); + + /* + * Poll GPEs to handle already triggered events. + * It is not sufficient to trigger edge-triggered GPE with specific + * GPE chips, software need to poll once after enabling. + */ + if (poll_gpes && acpi_gbl_all_gpes_initialized) { + acpi_ev_gpe_detect(acpi_gbl_gpe_xrupt_list_head); + } return_ACPI_STATUS(status); } ACPI_EXPORT_SYMBOL(acpi_enable_gpe) Index: linux-acpica/drivers/acpi/acpica/utxfinit.c =================================================================== --- linux-acpica.orig/drivers/acpi/acpica/utxfinit.c +++ linux-acpica/drivers/acpi/acpica/utxfinit.c @@ -284,6 +284,13 @@ acpi_status ACPI_INIT_FUNCTION acpi_init } /* + * Cleanup GPE enabling status to make sure that the GPE settings are + * as what the OSPMs expect. This should be done before enumerating + * ACPI devices and operation region drivers. + */ + (void)acpi_hw_disable_all_gpes(); + + /* * Initialize all device/region objects in the namespace. This runs * the device _STA and _INI methods and region _REG methods. */