From patchwork Thu Jun 24 23:18:39 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rafael Wysocki X-Patchwork-Id: 107947 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.4/8.14.3) with ESMTP id o5ONQ8Bs029190 for ; Thu, 24 Jun 2010 23:26:11 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754156Ab0FXX0J (ORCPT ); Thu, 24 Jun 2010 19:26:09 -0400 Received: from ogre.sisk.pl ([217.79.144.158]:47185 "EHLO ogre.sisk.pl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753268Ab0FXX0I (ORCPT ); Thu, 24 Jun 2010 19:26:08 -0400 Received: from localhost (localhost.localdomain [127.0.0.1]) by ogre.sisk.pl (Postfix) with ESMTP id 47431189631; Fri, 25 Jun 2010 01:14:41 +0200 (CEST) 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 32281-08; Fri, 25 Jun 2010 01:14:22 +0200 (CEST) Received: from ferrari.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 7DE90189615; Fri, 25 Jun 2010 01:14:22 +0200 (CEST) From: "Rafael J. Wysocki" To: Len Brown Subject: [PATCH 1/6] ACPI: Introduce acpi_gpe_wakeup() Date: Fri, 25 Jun 2010 01:18:39 +0200 User-Agent: KMail/1.13.3 (Linux/2.6.35-rc3-rjw+; KDE/4.4.3; x86_64; ; ) Cc: ACPI Devel Maling List , "Lin, Ming M" , Matthew Garrett , "Moore, Robert" , "Linux-pm mailing list" , len.brown@intel.com, Alexey Starikovskiy References: <201006250117.45148.rjw@sisk.pl> In-Reply-To: <201006250117.45148.rjw@sisk.pl> MIME-Version: 1.0 Message-Id: <201006250118.39553.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]); Thu, 24 Jun 2010 23:26:11 +0000 (UTC) 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 @@ -208,6 +208,67 @@ acpi_status acpi_enable_event(u32 event, ACPI_EXPORT_SYMBOL(acpi_enable_event) +/****************************************************************************** + * + * FUNCTION: acpi_gpe_wakeup + * + * PARAMETERS: gpe_device - Parent GPE Device. NULL for GPE0/GPE1 + * gpe_number - GPE level within the GPE block + * action - Disable or enable + * + * RETURN: Status + * + * DESCRIPTION: Set or clear the GPE's wakeup enable mask bit. + * + ******************************************************************************/ +acpi_status acpi_gpe_wakeup(acpi_handle gpe_device, u32 gpe_number, u8 action) +{ + acpi_status status = AE_OK; + struct acpi_gpe_event_info *gpe_event_info; + struct acpi_gpe_register_info *gpe_register_info; + u32 register_bit; + acpi_cpu_flags flags; + + ACPI_FUNCTION_TRACE(acpi_gpe_wakeup); + + 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; + } + + gpe_register_info = gpe_event_info->register_info; + if (!gpe_register_info) { + status = AE_NOT_EXIST; + goto unlock_and_exit; + } + + register_bit = acpi_hw_gpe_register_bit(gpe_event_info, + gpe_register_info); + switch (action) { + case ACPI_GPE_ENABLE: + ACPI_SET_BIT(gpe_register_info->enable_for_wake, register_bit); + break; + + case ACPI_GPE_DISABLE: + ACPI_CLEAR_BIT(gpe_register_info->enable_for_wake, register_bit); + break; + + default: + ACPI_ERROR((AE_INFO, "Invalid action\n")); + status = AE_BAD_PARAMETER; + } + +unlock_and_exit: + acpi_os_release_lock(acpi_gbl_gpe_lock, flags); + return_ACPI_STATUS(status); +} +ACPI_EXPORT_SYMBOL(acpi_gpe_wakeup) + /******************************************************************************* * * FUNCTION: acpi_clear_and_enable_gpe Index: linux-2.6/include/acpi/acpixf.h =================================================================== --- linux-2.6.orig/include/acpi/acpixf.h +++ linux-2.6/include/acpi/acpixf.h @@ -281,6 +281,8 @@ acpi_status acpi_get_event_status(u32 ev /* * GPE Interfaces */ +acpi_status acpi_gpe_wakeup(acpi_handle gpe_device, u32 gpe_number, u8 action); + acpi_status acpi_set_gpe(acpi_handle gpe_device, u32 gpe_number, u8 action); acpi_status Index: linux-2.6/drivers/acpi/sleep.c =================================================================== --- linux-2.6.orig/drivers/acpi/sleep.c +++ linux-2.6/drivers/acpi/sleep.c @@ -664,18 +664,9 @@ int acpi_pm_device_sleep_wake(struct dev return -ENODEV; } - if (enable) { - error = acpi_enable_wakeup_device_power(adev, - acpi_target_sleep_state); - if (!error) - acpi_enable_gpe(adev->wakeup.gpe_device, - adev->wakeup.gpe_number, - ACPI_GPE_TYPE_WAKE); - } else { - acpi_disable_gpe(adev->wakeup.gpe_device, adev->wakeup.gpe_number, - ACPI_GPE_TYPE_WAKE); - error = acpi_disable_wakeup_device_power(adev); - } + error = enable ? + acpi_enable_wakeup_device_power(adev, acpi_target_sleep_state) : + acpi_disable_wakeup_device_power(adev); if (!error) dev_info(dev, "wake-up capability %s by ACPI\n", enable ? "enabled" : "disabled"); Index: linux-2.6/drivers/acpi/wakeup.c =================================================================== --- linux-2.6.orig/drivers/acpi/wakeup.c +++ linux-2.6/drivers/acpi/wakeup.c @@ -64,13 +64,14 @@ void acpi_enable_wakeup_device(u8 sleep_ struct acpi_device *dev = container_of(node, struct acpi_device, wakeup_list); - if (!dev->wakeup.flags.valid || !dev->wakeup.state.enabled + if (!dev->wakeup.flags.valid + || !(dev->wakeup.state.enabled || dev->wakeup.prepare_count) || sleep_state > (u32) dev->wakeup.sleep_state) continue; /* The wake-up power should have been enabled already. */ - acpi_enable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number, - ACPI_GPE_TYPE_WAKE); + acpi_gpe_wakeup(dev->wakeup.gpe_device, dev->wakeup.gpe_number, + ACPI_GPE_ENABLE); } } @@ -89,13 +90,16 @@ void acpi_disable_wakeup_device(u8 sleep struct acpi_device *dev = container_of(node, struct acpi_device, wakeup_list); - if (!dev->wakeup.flags.valid || !dev->wakeup.state.enabled + if (!dev->wakeup.flags.valid + || !(dev->wakeup.state.enabled || dev->wakeup.prepare_count) || (sleep_state > (u32) dev->wakeup.sleep_state)) continue; - acpi_disable_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number, - ACPI_GPE_TYPE_WAKE); - acpi_disable_wakeup_device_power(dev); + acpi_gpe_wakeup(dev->wakeup.gpe_device, dev->wakeup.gpe_number, + ACPI_GPE_DISABLE); + + if (dev->wakeup.state.enabled) + acpi_disable_wakeup_device_power(dev); } } Index: linux-2.6/include/acpi/actypes.h =================================================================== --- linux-2.6.orig/include/acpi/actypes.h +++ linux-2.6/include/acpi/actypes.h @@ -663,7 +663,7 @@ typedef u32 acpi_event_status; #define ACPI_GPE_MAX 0xFF #define ACPI_NUM_GPE 256 -/* Actions for acpi_set_gpe and acpi_hw_low_set_gpe */ +/* Actions for acpi_set_gpe, acpi_hw_low_set_gpe and acpi_gpe_wakeup */ #define ACPI_GPE_ENABLE 0 #define ACPI_GPE_DISABLE 1