From patchwork Wed Nov 24 23:06:09 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Rafael Wysocki X-Patchwork-Id: 354662 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter1.kernel.org (8.14.4/8.14.3) with ESMTP id oAONHHVn022277 for ; Wed, 24 Nov 2010 23:17:17 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1756535Ab0KXXQj (ORCPT ); Wed, 24 Nov 2010 18:16:39 -0500 Received: from ogre.sisk.pl ([217.79.144.158]:52714 "EHLO ogre.sisk.pl" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1756470Ab0KXXQi (ORCPT ); Wed, 24 Nov 2010 18:16:38 -0500 Received: from localhost (localhost.localdomain [127.0.0.1]) by ogre.sisk.pl (Postfix) with ESMTP id B71C119E061; Thu, 25 Nov 2010 00:00:43 +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 08821-03; Thu, 25 Nov 2010 00:00:11 +0100 (CET) Received: from ferrari.rjw.lan (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 44F9A19E0A3; Thu, 25 Nov 2010 00:00:11 +0100 (CET) From: "Rafael J. Wysocki" To: Len Brown Subject: [PATCH 4/13] ACPI / PM: Add functions for manipulating lists of power resources Date: Thu, 25 Nov 2010 00:06:09 +0100 User-Agent: KMail/1.13.5 (Linux/2.6.37-rc3+; KDE/4.4.4; x86_64; ; ) Cc: ACPI Devel Maling List , LKML , "Linux-pm mailing list" , Matthew Garrett , Maciej Rutecki References: <201011250001.11297.rjw@sisk.pl> In-Reply-To: <201011250001.11297.rjw@sisk.pl> MIME-Version: 1.0 Message-Id: <201011250006.09337.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 (demeter1.kernel.org [140.211.167.41]); Wed, 24 Nov 2010 23:17:17 +0000 (UTC) Index: linux-2.6/drivers/acpi/power.c =================================================================== --- linux-2.6.orig/drivers/acpi/power.c +++ linux-2.6/drivers/acpi/power.c @@ -266,6 +266,35 @@ static int acpi_power_off_device(acpi_ha return result; } +static void __acpi_power_off_list(struct acpi_handle_list *list, int num_res) +{ + int i; + + for (i = num_res - 1; i >= 0 ; i--) + acpi_power_off_device(list->handles[i]); +} + +static void acpi_power_off_list(struct acpi_handle_list *list) +{ + __acpi_power_off_list(list, list->count); +} + +static int acpi_power_on_list(struct acpi_handle_list *list) +{ + int result = 0; + int i; + + for (i = 0; i < list->count; i++) { + result = acpi_power_on(list->handles[i]); + if (result) { + __acpi_power_off_list(list, i); + break; + } + } + + return result; +} + /** * acpi_device_sleep_wake - execute _DSW (Device Sleep Wake) or (deprecated in * ACPI 3.0) _PSW (Power State Wake) @@ -458,10 +487,7 @@ int acpi_power_get_inferred_state(struct int acpi_power_transition(struct acpi_device *device, int state) { - int result = 0; - struct acpi_handle_list *cl = NULL; /* Current Resources */ - struct acpi_handle_list *tl = NULL; /* Target Resources */ - int i = 0; + int result; if (!device || (state < ACPI_STATE_D0) || (state > ACPI_STATE_D3)) return -EINVAL; @@ -473,37 +499,20 @@ int acpi_power_transition(struct acpi_de || (device->power.state > ACPI_STATE_D3)) return -ENODEV; - cl = &device->power.states[device->power.state].resources; - tl = &device->power.states[state].resources; - /* TBD: Resources must be ordered. */ /* * First we reference all power resources required in the target list - * (e.g. so the device doesn't lose power while transitioning). - */ - for (i = 0; i < tl->count; i++) { - result = acpi_power_on(tl->handles[i]); - if (result) - goto end; - } - - /* - * Then we dereference all power resources used in the current list. + * (e.g. so the device doesn't lose power while transitioning). Then, + * we dereference all power resources used in the current list. */ - for (i = 0; i < cl->count; i++) { - result = acpi_power_off_device(cl->handles[i]); - if (result) - goto end; - } + result = acpi_power_on_list(&device->power.states[state].resources); + if (!result) + acpi_power_off_list( + &device->power.states[device->power.state].resources); - end: - if (result) - device->power.state = ACPI_STATE_UNKNOWN; - else { - /* We shouldn't change the state till all above operations succeed */ - device->power.state = state; - } + /* We shouldn't change the state unless the above operations succeed. */ + device->power.state = result ? ACPI_STATE_UNKNOWN : state; return result; }