Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752766AbZKOX7C (ORCPT ); Sun, 15 Nov 2009 18:59:02 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1751585AbZKOX7A (ORCPT ); Sun, 15 Nov 2009 18:59:00 -0500 Received: from ogre.sisk.pl ([217.79.144.158]:54463 "EHLO ogre.sisk.pl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752344AbZKOX6l (ORCPT ); Sun, 15 Nov 2009 18:58:41 -0500 From: "Rafael J. Wysocki" To: pm list Subject: [RFC][PATCH 8/10] ACPI / PM: Add more run-time wake-up fields Date: Mon, 16 Nov 2009 00:55:56 +0100 User-Agent: KMail/1.12.3 (Linux/2.6.32-rc7-rjw; KDE/4.3.3; x86_64; ; ) Cc: LKML , Linux PCI , ACPI Devel Maling List , Alan Stern , Jesse Barnes , Matthew Garrett , Oliver Neukum , Shaohua Li , Bjorn Helgaas References: <200911160047.46299.rjw@sisk.pl> In-Reply-To: <200911160047.46299.rjw@sisk.pl> MIME-Version: 1.0 Message-Id: <200911160055.56451.rjw@sisk.pl> Content-Type: Text/Plain; charset="iso-8859-1" Content-Transfer-Encoding: 7bit Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Length: 5135 Lines: 145 From: Rafael J. Wysocki Use the run_wake flag to mark all devices for which run-time wake-up events may be generated by the platform. Introduce a new wake-up flag, special, for marking devices that should be permanently enabled to generate run-time events. Also, introduce a reference counter for run-wake devices and a function that will initialize all of the run-time wake-up fields for given device. Signed-off-by: Rafael J. Wysocki --- drivers/acpi/button.c | 2 ++ drivers/acpi/scan.c | 37 +++++++++++++++++++++++++++---------- drivers/acpi/wakeup.c | 2 +- include/acpi/acpi_bus.h | 2 ++ 4 files changed, 32 insertions(+), 11 deletions(-) Index: linux-2.6/drivers/acpi/wakeup.c =================================================================== --- linux-2.6.orig/drivers/acpi/wakeup.c +++ linux-2.6/drivers/acpi/wakeup.c @@ -106,7 +106,7 @@ int __init acpi_wakeup_device_init(void) struct acpi_device, wakeup_list); /* In case user doesn't load button driver */ - if (!dev->wakeup.flags.run_wake || dev->wakeup.state.enabled) + if (!dev->wakeup.flags.special || dev->wakeup.state.enabled) continue; acpi_ref_wakeup_gpe(dev->wakeup.gpe_device, dev->wakeup.gpe_number); Index: linux-2.6/include/acpi/acpi_bus.h =================================================================== --- linux-2.6.orig/include/acpi/acpi_bus.h +++ linux-2.6/include/acpi/acpi_bus.h @@ -242,6 +242,7 @@ struct acpi_device_perf { struct acpi_device_wakeup_flags { u8 valid:1; /* Can successfully enable wakeup? */ u8 run_wake:1; /* Run-Wake GPE devices */ + u8 special:1; /* Run-wake devices that are always enabled */ }; struct acpi_device_wakeup_state { @@ -256,6 +257,7 @@ struct acpi_device_wakeup { struct acpi_device_wakeup_state state; struct acpi_device_wakeup_flags flags; int prepare_count; + int run_wake_count; }; /* Device */ Index: linux-2.6/drivers/acpi/button.c =================================================================== --- linux-2.6.orig/drivers/acpi/button.c +++ linux-2.6/drivers/acpi/button.c @@ -419,6 +419,7 @@ static int acpi_button_add(struct acpi_d device->wakeup.gpe_number); acpi_ref_wakeup_gpe(device->wakeup.gpe_device, device->wakeup.gpe_number); + device->wakeup.run_wake_count++; device->wakeup.state.enabled = 1; } @@ -443,6 +444,7 @@ static int acpi_button_remove(struct acp device->wakeup.gpe_number); acpi_unref_wakeup_gpe(device->wakeup.gpe_device, device->wakeup.gpe_number); + device->wakeup.run_wake_count--; device->wakeup.state.enabled = 0; } Index: linux-2.6/drivers/acpi/scan.c =================================================================== --- linux-2.6.orig/drivers/acpi/scan.c +++ linux-2.6/drivers/acpi/scan.c @@ -742,19 +742,39 @@ acpi_bus_extract_wakeup_device_power_pac return AE_OK; } -static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) +static void acpi_bus_set_run_wake_flags(struct acpi_device *device) { - acpi_status status = 0; - struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; - union acpi_object *package = NULL; - int psw_error; - struct acpi_device_id button_device_ids[] = { {"PNP0C0D", 0}, {"PNP0C0C", 0}, {"PNP0C0E", 0}, {"", 0}, }; + acpi_status status; + acpi_event_status event_status; + + device->wakeup.run_wake_count = 0; + + /* Power button, Lid switch always enable wakeup */ + if (!acpi_match_device_ids(device, button_device_ids)) { + device->wakeup.flags.run_wake = 1; + device->wakeup.flags.special = 1; + return; + } + + status = acpi_get_gpe_status(NULL, device->wakeup.gpe_number, + ACPI_NOT_ISR, &event_status); + if (status == AE_OK) + device->wakeup.flags.run_wake = + !!(event_status & ACPI_EVENT_FLAG_HANDLE); +} + +static int acpi_bus_get_wakeup_device_flags(struct acpi_device *device) +{ + acpi_status status = 0; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + union acpi_object *package = NULL; + int psw_error; /* _PRW */ status = acpi_evaluate_object(device->handle, "_PRW", NULL, &buffer); @@ -774,6 +794,7 @@ static int acpi_bus_get_wakeup_device_fl device->wakeup.flags.valid = 1; device->wakeup.prepare_count = 0; + acpi_bus_set_run_wake_flags(device); /* Call _PSW/_DSW object to disable its ability to wake the sleeping * system for the ACPI device with the _PRW object. * The _PSW object is depreciated in ACPI 3.0 and is replaced by _DSW. @@ -785,10 +806,6 @@ static int acpi_bus_get_wakeup_device_fl ACPI_DEBUG_PRINT((ACPI_DB_INFO, "error in _DSW or _PSW evaluation\n")); - /* Power button, Lid switch always enable wakeup */ - if (!acpi_match_device_ids(device, button_device_ids)) - device->wakeup.flags.run_wake = 1; - end: if (ACPI_FAILURE(status)) device->flags.wake_capable = 0; -- To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/