From patchwork Sun Feb 7 02:22:52 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rafael Wysocki X-Patchwork-Id: 77570 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 o172Ou26004064 for ; Sun, 7 Feb 2010 02:24:57 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752946Ab0BGCY4 (ORCPT ); Sat, 6 Feb 2010 21:24:56 -0500 Received: from ogre.sisk.pl ([217.79.144.158]:53141 "EHLO ogre.sisk.pl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752602Ab0BGCYy (ORCPT ); Sat, 6 Feb 2010 21:24:54 -0500 Received: from localhost (localhost.localdomain [127.0.0.1]) by ogre.sisk.pl (Postfix) with ESMTP id 631911751DB; Sun, 7 Feb 2010 03:08:50 +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 13338-03; Sun, 7 Feb 2010 03:08:35 +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 64DE717595E; Sun, 7 Feb 2010 03:08:35 +0100 (CET) From: "Rafael J. Wysocki" To: "Moore, Robert" Subject: [RFC][PATCH 1/3] ACPI: Add infrastructure for refcounting GPE consumers Date: Sun, 7 Feb 2010 03:22:52 +0100 User-Agent: KMail/1.12.4 (Linux/2.6.33-rc6-rjw; KDE/4.3.5; x86_64; ; ) Cc: Matthew Garrett , "linux-acpi@vger.kernel.org" , Len Brown , Jesse Barnes References: <4911F71203A09E4D9981D27F9D83085855AF782E@orsmsx503.amr.corp.intel.com> <201002070031.54680.rjw@sisk.pl> <201002070317.47029.rjw@sisk.pl> In-Reply-To: <201002070317.47029.rjw@sisk.pl> MIME-Version: 1.0 Message-Id: <201002070322.53017.rjw@sisk.pl> X-Virus-Scanned: amavisd-new at ogre.sisk.pl using MkS_Vir for Linux 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.3 (demeter.kernel.org [140.211.167.41]); Sun, 07 Feb 2010 02:24:57 +0000 (UTC) Index: linux-2.6/drivers/acpi/acpica/aclocal.h =================================================================== --- linux-2.6.orig/drivers/acpi/acpica/aclocal.h +++ linux-2.6/drivers/acpi/acpica/aclocal.h @@ -426,6 +426,8 @@ struct acpi_gpe_event_info { struct acpi_gpe_register_info *register_info; /* Backpointer to register info */ u8 flags; /* Misc info about this GPE */ u8 gpe_number; /* This GPE */ + u8 runtime_count; + u8 wakeup_count; }; /* Information about a GPE register pair, one per each status/enable pair in an array */ 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 @@ -201,6 +201,103 @@ ACPI_EXPORT_SYMBOL(acpi_enable_event) /******************************************************************************* * + * FUNCTION: acpi_get_gpe + * + * PARAMETERS: gpe_device - Parent GPE Device + * gpe_number - GPE level within the GPE block + * type - Purpose the GPE will be used for + * + * RETURN: Status + * + * DESCRIPTION: Take a reference to a GPE and enable it if necessary + * + ******************************************************************************/ +acpi_status acpi_get_gpe(acpi_handle gpe_device, u32 gpe_number, u8 type) +{ + acpi_status status = AE_OK; + acpi_cpu_flags flags; + struct acpi_gpe_event_info *gpe_event_info; + + ACPI_FUNCTION_TRACE(acpi_ref_runtime_gpe); + + flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); + + /* Ensure that we have a valid GPE number */ + gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); + if (!gpe_event_info) { + status = AE_BAD_PARAMETER; + goto unlock_and_exit; + } + + 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 (type & ACPI_GPE_TYPE_WAKE) { + if (++gpe_event_info->wakeup_count == 1) + acpi_ev_update_gpe_enable_masks(gpe_event_info, + ACPI_GPE_ENABLE); + } + +unlock_and_exit: + acpi_os_release_lock(acpi_gbl_gpe_lock, flags); + return_ACPI_STATUS(status); +} +ACPI_EXPORT_SYMBOL(acpi_get_gpe) + +/******************************************************************************* + * + * FUNCTION: acpi_put_gpe + * + * PARAMETERS: gpe_device - Parent GPE Device + * gpe_number - GPE level within the GPE block + * type - Purpose the GPE won't be used for any more + * + * RETURN: Status + * + * DESCRIPTION: Release a reference to a GPE and disable it if necessary + * + ******************************************************************************/ +acpi_status acpi_put_gpe(acpi_handle gpe_device, u32 gpe_number, u8 type) +{ + acpi_status status = AE_OK; + acpi_cpu_flags flags; + struct acpi_gpe_event_info *gpe_event_info; + + ACPI_FUNCTION_TRACE(acpi_unref_runtime_gpe); + + flags = acpi_os_acquire_lock(acpi_gbl_gpe_lock); + + /* Ensure that we have a valid GPE number */ + gpe_event_info = acpi_ev_get_gpe_event_info(gpe_device, gpe_number); + if (!gpe_event_info) { + status = AE_BAD_PARAMETER; + goto unlock_and_exit; + } + + if ((type & ACPI_GPE_TYPE_WAKE) && gpe_event_info->runtime_count) { + if (--gpe_event_info->runtime_count == 0) + acpi_ev_disable_gpe(gpe_event_info); + } + + if ((type & ACPI_GPE_TYPE_RUNTIME) && gpe_event_info->wakeup_count) { + if (--gpe_event_info->wakeup_count == 0) + acpi_ev_update_gpe_enable_masks(gpe_event_info, + ACPI_GPE_DISABLE); + } + +unlock_and_exit: + acpi_os_release_lock(acpi_gbl_gpe_lock, flags); + return_ACPI_STATUS(status); +} +ACPI_EXPORT_SYMBOL(acpi_put_gpe) + +/******************************************************************************* + * * FUNCTION: acpi_set_gpe_type * * PARAMETERS: gpe_device - Parent GPE Device Index: linux-2.6/include/acpi/acpixf.h =================================================================== --- linux-2.6.orig/include/acpi/acpixf.h +++ linux-2.6/include/acpi/acpixf.h @@ -283,6 +283,10 @@ acpi_status acpi_get_event_status(u32 ev */ acpi_status acpi_set_gpe_type(acpi_handle gpe_device, u32 gpe_number, u8 type); +acpi_status acpi_get_gpe(acpi_handle gpe_device, u32 gpe_number, u8 type); + +acpi_status acpi_put_gpe(acpi_handle gpe_device, u32 gpe_number, u8 type); + acpi_status acpi_enable_gpe(acpi_handle gpe_device, u32 gpe_number); acpi_status acpi_disable_gpe(acpi_handle gpe_device, u32 gpe_number);