From patchwork Fri Nov 6 16:00:41 2009 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Falempe Jocelyn X-Patchwork-Id: 58064 X-Patchwork-Delegate: khilman@deeprootsystems.com Received: from vger.kernel.org (vger.kernel.org [209.132.176.167]) by demeter.kernel.org (8.14.2/8.14.2) with ESMTP id nA6G1HkC010846 for ; Fri, 6 Nov 2009 16:01:18 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1759377AbZKFQBL (ORCPT ); Fri, 6 Nov 2009 11:01:11 -0500 Received: (majordomo@vger.kernel.org) by vger.kernel.org id S1759379AbZKFQBL (ORCPT ); Fri, 6 Nov 2009 11:01:11 -0500 Received: from mail153.messagelabs.com ([216.82.253.51]:59639 "EHLO mail153.messagelabs.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1759377AbZKFQBJ convert rfc822-to-8bit (ORCPT ); Fri, 6 Nov 2009 11:01:09 -0500 X-VirusChecked: Checked X-Env-Sender: jocelyn.falempe@motorola.com X-Msg-Ref: server-14.tower-153.messagelabs.com!1257523273!43199946!1 X-StarScan-Version: 6.1.3; banners=-,-,- X-Originating-IP: [136.182.1.14] Received: (qmail 24009 invoked from network); 6 Nov 2009 16:01:14 -0000 Received: from motgate4.mot.com (HELO motgate4.mot.com) (136.182.1.14) by server-14.tower-153.messagelabs.com with DHE-RSA-AES256-SHA encrypted SMTP; 6 Nov 2009 16:01:14 -0000 Received: from il27exr04.cig.mot.com (il27exr04.mot.com [10.17.196.73]) by motgate4.mot.com (8.14.3/8.14.3) with ESMTP id nA6G1Dhb002417; Fri, 6 Nov 2009 09:01:13 -0700 (MST) Received: from il27vts03 (il27vts03.cig.mot.com [10.17.196.87]) by il27exr04.cig.mot.com (8.13.1/Vontu) with SMTP id nA6G1Cuq015723; Fri, 6 Nov 2009 10:01:12 -0600 (CST) Received: from zuk35exm61.ds.mot.com (zuk35exm61.ea.mot.com [10.178.4.19]) by il27exr04.cig.mot.com (8.13.1/8.13.0) with ESMTP id nA6G1Bd0015696; Fri, 6 Nov 2009 10:01:12 -0600 (CST) Received: from 10.160.49.235 ([10.160.49.235]) by zuk35exm61.ds.mot.com ([10.178.4.19]) via Exchange Front-End Server zuk35exf61.ds.mot.com ([10.178.4.18]) with Microsoft Exchange Server HTTP-DAV ; Fri, 6 Nov 2009 16:00:49 +0000 Received: from xhp836-11 by zuk35exf61.ds.mot.com; 06 Nov 2009 17:00:41 +0100 Subject: New feature proposal "quickwakeup" From: Falempe Jocelyn To: linux-acpi@vger.kernel.org, linux-omap@vger.kernel.org Organization: Motorola Date: Fri, 06 Nov 2009 17:00:41 +0100 Message-ID: <1257523241.1318.367.camel@xhp836-11> Mime-Version: 1.0 X-Mailer: Evolution 2.28.1 X-CFilter-Loop: Reflected Sender: linux-omap-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-omap@vger.kernel.org diff --git a/include/linux/quickwakeup.h b/include/linux/quickwakeup.h new file mode 100755 index 0000000..60df3b8 --- /dev/null +++ b/include/linux/quickwakeup.h @@ -0,0 +1,33 @@ +/* include/linux/quickwakeup.h + * + * Copyright (C) 2009 Motorola. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +struct quickwakeup_ops { + struct list_head list; + int (*qw_callback) (void); + int (*qw_check)(void); + int checked; +}; + +#ifdef CONFIG_QUICK_WAKEUP + +int quickwakeup_register(struct quickwakeup_ops *ops); +int quickwakeup_check(void); +int quickwakeup_execute(void); +void quickwakeup_unregister(struct quickwakeup_ops *ops); + +#else +static int quickwakeup_register(struct quickwakeup_ops *ops) { return 0; }; +void quickwakeup_unregister(struct quickwakeup_ops *ops) {}; +#endif diff --git a/kernel/power/Kconfig b/kernel/power/Kconfig index 39263f4..5671f98 100644 --- a/kernel/power/Kconfig +++ b/kernel/power/Kconfig @@ -236,3 +236,11 @@ config PM_RUNTIME and the bus type drivers of the buses the devices are on are responsible for the actual handling of the autosuspend requests and wake-up events. + +config QUICK_WAKEUP + bool "Quick wakeup" + depends on SUSPEND + default n + ---help--- + Allow kernel driver to do periodic jobs without resuming the full system + This option can increase battery life on android powered smartphone. diff --git a/kernel/power/Makefile b/kernel/power/Makefile index 4319181..18b55e5 100644 --- a/kernel/power/Makefile +++ b/kernel/power/Makefile @@ -10,5 +10,5 @@ obj-$(CONFIG_SUSPEND) += suspend.o obj-$(CONFIG_PM_TEST_SUSPEND) += suspend_test.o obj-$(CONFIG_HIBERNATION) += hibernate.o snapshot.o swap.o user.o obj-$(CONFIG_HIBERNATION_NVS) += hibernate_nvs.o - +obj-$(CONFIG_QUICK_WAKEUP) += quickwakeup.o obj-$(CONFIG_MAGIC_SYSRQ) += poweroff.o diff --git a/kernel/power/quickwakeup.c b/kernel/power/quickwakeup.c new file mode 100644 index 0000000..3ad7392 --- /dev/null +++ b/kernel/power/quickwakeup.c @@ -0,0 +1,60 @@ +/* kernel/power/quickwakeup.c + * + * Copyright (C) 2009 Motorola. + * + * This software is licensed under the terms of the GNU General Public + * License version 2, as published by the Free Software Foundation, and + * may be copied, distributed, and modified under those terms. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include + +static LIST_HEAD(qw_head); + +int quickwakeup_register(struct quickwakeup_ops *ops) +{ + list_add(&ops->list, &qw_head); + return 0; +} + +void quickwakeup_unregister(struct quickwakeup_ops *ops) +{ + list_del(&ops->list); +} + +int quickwakeup_check(void) +{ + int ret = 0; + struct quickwakeup_ops *index; + + list_for_each_entry(index, &qw_head, list) { + index->checked = index->qw_check(); + ret |= index->checked; + } + return ret; +} + +int quickwakeup_execute(void) +{ + int ret; + int count = 0; + struct quickwakeup_ops *index; + + list_for_each_entry(index, &qw_head, list) { + if (index->checked) + ret = index->qw_callback(); + if (ret != 0) + return ret; + count++; + } + if (!count) + return -1; + return 0; +} diff --git a/kernel/power/suspend.c b/kernel/power/suspend.c index 6f10dfc..3fe1ec0 100644 --- a/kernel/power/suspend.c +++ b/kernel/power/suspend.c @@ -116,6 +116,28 @@ void __attribute__ ((weak)) arch_suspend_enable_irqs(void) local_irq_enable(); } +static int _suspend_enter(suspend_state_t state) +{ + int error; + arch_suspend_disable_irqs(); + BUG_ON(!irqs_disabled()); + + error = sysdev_suspend(PMSG_SUSPEND); + if (!error) { + if (!suspend_test(TEST_CORE)) + error = suspend_ops->enter(state); + sysdev_resume(); + } + if (!error) { +#ifdef CONFIG_QUICK_WAKEUP + quickwakeup_check(); +#endif + } + arch_suspend_enable_irqs(); + BUG_ON(irqs_disabled()); + return error; +} + /** * suspend_enter - enter the desired system sleep state. * @state: state to enter @@ -151,18 +173,14 @@ static int suspend_enter(suspend_state_t state) if (error || suspend_test(TEST_CPUS)) goto Enable_cpus; - arch_suspend_disable_irqs(); - BUG_ON(!irqs_disabled()); - - error = sysdev_suspend(PMSG_SUSPEND); - if (!error) { - if (!suspend_test(TEST_CORE)) - error = suspend_ops->enter(state); - sysdev_resume(); - } - - arch_suspend_enable_irqs(); - BUG_ON(irqs_disabled()); + error = _suspend_enter(state); +#ifdef CONFIG_QUICK_WAKEUP + while (!error && !quickwakeup_execute()) { + if (has_wake_lock(WAKE_LOCK_SUSPEND)) + break; + error = _suspend_enter(state); + } +#endif Enable_cpus: enable_nonboot_cpus();