From patchwork Fri Jul 22 06:24:42 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Lv Zheng X-Patchwork-Id: 9243019 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork.web.codeaurora.org (Postfix) with ESMTP id 193B460757 for ; Fri, 22 Jul 2016 06:25:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id EE33A27D76 for ; Fri, 22 Jul 2016 06:25:15 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id DFE6627F9C; Fri, 22 Jul 2016 06:25:15 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-6.9 required=2.0 tests=BAYES_00,RCVD_IN_DNSWL_HI autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 344A527D76 for ; Fri, 22 Jul 2016 06:25:14 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1751726AbcGVGYv (ORCPT ); Fri, 22 Jul 2016 02:24:51 -0400 Received: from mga02.intel.com ([134.134.136.20]:42603 "EHLO mga02.intel.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751020AbcGVGYu (ORCPT ); Fri, 22 Jul 2016 02:24:50 -0400 Received: from fmsmga001.fm.intel.com ([10.253.24.23]) by orsmga101.jf.intel.com with ESMTP; 21 Jul 2016 23:24:49 -0700 X-ExtLoop1: 1 X-IronPort-AV: E=Sophos;i="5.28,403,1464678000"; d="scan'208";a="1011755340" Received: from lvzheng-z530.sh.intel.com ([10.239.159.47]) by fmsmga001.fm.intel.com with ESMTP; 21 Jul 2016 23:24:47 -0700 From: Lv Zheng To: "Rafael J. Wysocki" , "Rafael J. Wysocki" , Len Brown Cc: Lv Zheng , Lv Zheng , , linux-acpi@vger.kernel.org, Dmitry Torokhov , Benjamin Tissoires , "Bastien Nocera:" , linux-input@vger.kernel.org Subject: [PATCH v5 1/3] ACPI / button: Add missing event to keep SW_LID running without additional event loss Date: Fri, 22 Jul 2016 14:24:42 +0800 Message-Id: <0d28076e25047db356eeedbb2d8ae204f0ec893d.1469168549.git.lv.zheng@intel.com> X-Mailer: git-send-email 1.7.10 In-Reply-To: References: Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP There are several possibilities that a lid event can be lost. For example, EC event queue full, or the resume order of the underlying drivers. When the event loss happens, new event may also be lost due to the type of the SW_LID (switch event). The 2nd loss is what we want to avoid. This patch adds a mechanism to insert lid events as a compensation for the switch event nature of the lid events in order to avoid the 2nd loss. Signed-off-by: Lv Zheng Cc: Dmitry Torokhov Cc: Benjamin Tissoires Cc: Bastien Nocera: Cc: linux-input@vger.kernel.org --- drivers/acpi/button.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c index 148f4e5..41fd21d 100644 --- a/drivers/acpi/button.c +++ b/drivers/acpi/button.c @@ -104,6 +104,8 @@ struct acpi_button { struct input_dev *input; char phys[32]; /* for input device */ unsigned long pushed; + int sw_last_state; + unsigned long sw_last_time; bool suspended; }; @@ -111,6 +113,10 @@ static BLOCKING_NOTIFIER_HEAD(acpi_lid_notifier); static struct acpi_device *lid_device; static u8 lid_init_state = ACPI_BUTTON_LID_INIT_METHOD; +static unsigned long lid_report_interval __read_mostly = 500; +module_param(lid_report_interval, ulong, 0644); +MODULE_PARM_DESC(lid_report_interval, "Interval (ms) between lid key events"); + /* -------------------------------------------------------------------------- FS Interface (/proc) -------------------------------------------------------------------------- */ @@ -133,11 +139,22 @@ static int acpi_lid_evaluate_state(struct acpi_device *device) static int acpi_lid_notify_state(struct acpi_device *device, int state) { struct acpi_button *button = acpi_driver_data(device); + unsigned long sw_tout; int ret; - /* input layer checks if event is redundant */ + /* Send the switch event */ + sw_tout = button->sw_last_time + + msecs_to_jiffies(lid_report_interval); + if (time_after(jiffies, sw_tout) && + (button->sw_last_state == !!state)) { + /* Send the complement switch event */ + input_report_switch(button->input, SW_LID, state); + input_sync(button->input); + } input_report_switch(button->input, SW_LID, !state); input_sync(button->input); + button->sw_last_state = !!state; + button->sw_last_time = jiffies; if (state) pm_wakeup_event(&device->dev, 0); @@ -407,6 +424,8 @@ static int acpi_button_add(struct acpi_device *device) strcpy(name, ACPI_BUTTON_DEVICE_NAME_LID); sprintf(class, "%s/%s", ACPI_BUTTON_CLASS, ACPI_BUTTON_SUBCLASS_LID); + button->sw_last_state = !!acpi_lid_evaluate_state(device); + button->sw_last_time = jiffies; } else { printk(KERN_ERR PREFIX "Unsupported hid [%s]\n", hid); error = -ENODEV;