From patchwork Tue Feb 23 23:52:08 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rafael Wysocki X-Patchwork-Id: 81556 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o1NNpb18004170 for ; Tue, 23 Feb 2010 23:51:37 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754780Ab0BWXvg (ORCPT ); Tue, 23 Feb 2010 18:51:36 -0500 Received: from ogre.sisk.pl ([217.79.144.158]:40667 "EHLO ogre.sisk.pl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1754358Ab0BWXvg (ORCPT ); Tue, 23 Feb 2010 18:51:36 -0500 Received: from localhost (localhost.localdomain [127.0.0.1]) by ogre.sisk.pl (Postfix) with ESMTP id 0AA95179264; Wed, 24 Feb 2010 00:30:02 +0100 (CET) Received: from ogre.sisk.pl ([127.0.0.1]) by localhost (ogre.sisk.pl [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 16993-07; Wed, 24 Feb 2010 00:29:54 +0100 (CET) Received: from tosh.localnet (220-bem-13.acn.waw.pl [82.210.184.220]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by ogre.sisk.pl (Postfix) with ESMTP id B316B179255; Wed, 24 Feb 2010 00:29:54 +0100 (CET) From: "Rafael J. Wysocki" To: Jesse Barnes Subject: Re: [PATCH 4/8] ACPI: Use GPE reference counting to support shared GPEs Date: Wed, 24 Feb 2010 00:52:08 +0100 User-Agent: KMail/1.12.4 (Linux/2.6.33-rc8-rjw; KDE/4.3.5; x86_64; ; ) Cc: "Moore, Robert" , "Lin, Ming M" , Matthew Garrett , "Brown, Len" , ACPI Devel Maling List , pm list , Linux PCI References: <4911F71203A09E4D9981D27F9D83085859958760@orsmsx503.amr.corp.intel.com> <201002200018.02700.rjw@sisk.pl> <20100222162622.3d9c684a@jbarnes-piketon> In-Reply-To: <20100222162622.3d9c684a@jbarnes-piketon> MIME-Version: 1.0 Message-Id: <201002240052.08098.rjw@sisk.pl> X-Virus-Scanned: amavisd-new at ogre.sisk.pl using MkS_Vir for Linux Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Tue, 23 Feb 2010 23:51:37 +0000 (UTC) Index: linux-2.6/drivers/acpi/acpica/acevents.h =================================================================== --- linux-2.6.orig/drivers/acpi/acpica/acevents.h +++ linux-2.6/drivers/acpi/acpica/acevents.h @@ -78,9 +78,7 @@ acpi_ev_queue_notify_request(struct acpi acpi_status acpi_ev_update_gpe_enable_masks(struct acpi_gpe_event_info *gpe_event_info); -acpi_status -acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info, - u8 write_to_hardware); +acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info); acpi_status acpi_ev_disable_gpe(struct acpi_gpe_event_info *gpe_event_info); Index: linux-2.6/drivers/acpi/acpica/evgpe.c =================================================================== --- linux-2.6.orig/drivers/acpi/acpica/evgpe.c +++ linux-2.6/drivers/acpi/acpica/evgpe.c @@ -98,8 +98,6 @@ acpi_ev_update_gpe_enable_masks(struct a * FUNCTION: acpi_ev_enable_gpe * * PARAMETERS: gpe_event_info - GPE to enable - * write_to_hardware - Enable now, or just mark data structs - * (WAKE GPEs should be deferred) * * RETURN: Status * @@ -107,9 +105,7 @@ acpi_ev_update_gpe_enable_masks(struct a * ******************************************************************************/ -acpi_status -acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info, - u8 write_to_hardware) +acpi_status acpi_ev_enable_gpe(struct acpi_gpe_event_info *gpe_event_info) { acpi_status status; @@ -123,7 +119,7 @@ acpi_ev_enable_gpe(struct acpi_gpe_event /* Mark wake-enabled or HW enable, or both */ - if (gpe_event_info->runtime_count && write_to_hardware) { + if (gpe_event_info->runtime_count) { /* Clear the GPE (of stale events), then enable it */ status = acpi_hw_clear_gpe(gpe_event_info); if (ACPI_FAILURE(status)) @@ -400,7 +396,7 @@ static void ACPI_SYSTEM_XFACE acpi_ev_as /* Set the GPE flags for return to enabled state */ - (void)acpi_ev_enable_gpe(gpe_event_info, FALSE); + (void)acpi_ev_update_gpe_enable_masks(gpe_event_info); /* * Take a snapshot of the GPE info for this level - we copy the info to Index: linux-2.6/drivers/acpi/acpica/evxfevnt.c =================================================================== --- linux-2.6.orig/drivers/acpi/acpica/evxfevnt.c +++ linux-2.6/drivers/acpi/acpica/evxfevnt.c @@ -235,7 +235,7 @@ acpi_status acpi_set_gpe(acpi_handle gpe switch (action) { case ACPI_GPE_ENABLE: - status = acpi_ev_enable_gpe(gpe_event_info, TRUE); + status = acpi_ev_enable_gpe(gpe_event_info); break; case ACPI_GPE_DISABLE: @@ -276,6 +276,9 @@ acpi_status acpi_enable_gpe(acpi_handle ACPI_FUNCTION_TRACE(acpi_enable_gpe); + if (type & ~ACPI_GPE_TYPE_WAKE_RUN) + return_ACPI_STATUS(AE_BAD_PARAMETER); + flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); /* Ensure that we have a valid GPE number */ @@ -287,11 +290,11 @@ acpi_status acpi_enable_gpe(acpi_handle } if (type & ACPI_GPE_TYPE_RUNTIME) { - if (++gpe_event_info->runtime_count == 1) - status = acpi_ev_enable_gpe(gpe_event_info, TRUE); - - if (ACPI_FAILURE(status)) - gpe_event_info->runtime_count--; + if (++gpe_event_info->runtime_count == 1) { + status = acpi_ev_enable_gpe(gpe_event_info); + if (ACPI_FAILURE(status)) + gpe_event_info->runtime_count--; + } } if (type & ACPI_GPE_TYPE_WAKE) { @@ -335,6 +338,9 @@ acpi_status acpi_disable_gpe(acpi_handle ACPI_FUNCTION_TRACE(acpi_disable_gpe); + if (type & ~ACPI_GPE_TYPE_WAKE_RUN) + return_ACPI_STATUS(AE_BAD_PARAMETER); + flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); /* Ensure that we have a valid GPE number */ @@ -344,12 +350,12 @@ acpi_status acpi_disable_gpe(acpi_handle goto unlock_and_exit; } - if ((type & ACPI_GPE_TYPE_WAKE) && gpe_event_info->runtime_count) { + if ((type & ACPI_GPE_TYPE_RUNTIME) && gpe_event_info->runtime_count) { if (--gpe_event_info->runtime_count == 0) - acpi_ev_disable_gpe(gpe_event_info); + status = acpi_ev_disable_gpe(gpe_event_info); } - if ((type & ACPI_GPE_TYPE_RUNTIME) && gpe_event_info->wakeup_count) { + if ((type & ACPI_GPE_TYPE_WAKE) && gpe_event_info->wakeup_count) { /* * Wake-up GPEs are not enabled after leaving system sleep * states, so we don't need to disable them here. Index: linux-2.6/drivers/acpi/ec.c =================================================================== --- linux-2.6.orig/drivers/acpi/ec.c +++ linux-2.6/drivers/acpi/ec.c @@ -307,6 +307,10 @@ static int acpi_ec_transaction(struct ac pr_debug(PREFIX "transaction start\n"); /* disable GPE during transaction if storm is detected */ if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { + /* + * It has to be disabled at the hardware level regardless of the + * GPE reference counting, so that it doesn't trigger. + */ acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_DISABLE); } @@ -316,7 +320,11 @@ static int acpi_ec_transaction(struct ac ec_check_sci_sync(ec, acpi_ec_read_status(ec)); if (test_bit(EC_FLAGS_GPE_STORM, &ec->flags)) { msleep(1); - /* it is safe to enable GPE outside of transaction */ + /* + * It is safe to enable the GPE outside of the transaction. Use + * acpi_set_gpe() for that, since we used it to disable the GPE + * above. + */ acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_ENABLE); } else if (t->irq_count > ACPI_EC_STORM_THRESHOLD) { pr_info(PREFIX "GPE storm detected, " @@ -1059,7 +1067,7 @@ error: static int acpi_ec_suspend(struct acpi_device *device, pm_message_t state) { struct acpi_ec *ec = acpi_driver_data(device); - /* Stop using GPE */ + /* Stop using the GPE, but keep it reference counted. */ acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_DISABLE); return 0; } @@ -1067,7 +1075,7 @@ static int acpi_ec_suspend(struct acpi_d static int acpi_ec_resume(struct acpi_device *device) { struct acpi_ec *ec = acpi_driver_data(device); - /* Enable use of GPE back */ + /* Enable the GPE again, but don't reference count it once more. */ acpi_set_gpe(NULL, ec->gpe, ACPI_GPE_ENABLE); return 0; }