From patchwork Fri Jun 16 04:40:52 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?b?TWljaGHFgiBLxJlwaWXFhA==?= X-Patchwork-Id: 9790527 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 5B01860326 for ; Fri, 16 Jun 2017 04:42:56 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 58652285FE for ; Fri, 16 Jun 2017 04:42:56 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 47CAB2855C; Fri, 16 Jun 2017 04:42:56 +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.8 required=2.0 tests=BAYES_00,DKIM_SIGNED, RCVD_IN_DNSWL_HI,T_DKIM_INVALID autolearn=unavailable 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 A89C92855C for ; Fri, 16 Jun 2017 04:42:55 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752406AbdFPEmm (ORCPT ); Fri, 16 Jun 2017 00:42:42 -0400 Received: from mail-wm0-f65.google.com ([74.125.82.65]:33863 "EHLO mail-wm0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1750872AbdFPElM (ORCPT ); Fri, 16 Jun 2017 00:41:12 -0400 Received: by mail-wm0-f65.google.com with SMTP id 70so2751589wme.1 for ; Thu, 15 Jun 2017 21:41:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=kempniu.pl; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=xICRVCMXNi6M2LRzyt478cIrlw/8JrBRxR5psSyosx4=; b=T3BAJKwDFjeOQLa/5v3EY0psi6lZy7mWdwam/UOp/NlHnlYnYzAuKUZRbI5pyIm+zu xrgEsMFdfZqgEw/rQ2pFa7qnLjWV+Z1fRnPeyoRHExmW7d+BSXMcHl0hraTibKWpQUgd 9dh5U8E4+JS93JehJuVIx5T3A2vOSu2jknUrA= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=xICRVCMXNi6M2LRzyt478cIrlw/8JrBRxR5psSyosx4=; b=Ei8l4wPvSLPgwSCWHaw64pwcmxxmA+aGhK+DQH2apI0cixfjDhqkWcZv3VXAg7mFRC 0u4zTcSK3Z9RBfDhtPlN650ms20xf63d7AWiByp58LvOMyT/tiacHNwJkMmVVr/Lz7TP C5SI4EuAk1VzzY0iH3cbO/gDGbSdqunNIycjfCaNKgtAjFcwVZ5jMcWGEWLaIlW+QG01 oqnmd5lhlzG/nmWZZPHHPgysO8LXzKOlDcckneLi2Ae0dwdn7h1G4NvZXOLd0u6PxxWw tQ9jSKgAOsLlGEsQXdpA8l9cv65E6CvyfTnHDbEUUclu2VcLhOIZPGHh98OKZ4CAHTSu jv4Q== X-Gm-Message-State: AKS2vOzWzSkNG/tJcFOViEu+Jx+eCdQFwWbzzU097+8eNKbq/f4Uf7o4 uDHMWdQzTWZ720cDUNA= X-Received: by 10.28.52.195 with SMTP id b186mr5843400wma.122.1497588070860; Thu, 15 Jun 2017 21:41:10 -0700 (PDT) Received: from kmp-mobile.hq.kempniu.pl (kmp-mobile.hq.kempniu.pl. [2001:470:64df:111::2d90]) by smtp.googlemail.com with ESMTPSA id g3sm2026681wrd.11.2017.06.15.21.41.09 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 15 Jun 2017 21:41:10 -0700 (PDT) From: =?UTF-8?q?Micha=C5=82=20K=C4=99pie=C5=84?= To: Jonathan Woithe , Darren Hart , Andy Shevchenko Cc: platform-driver-x86@vger.kernel.org, linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org Subject: [PATCH 1/7] platform/x86: fujitsu-laptop: do not use kfifo for storing hotkey scancodes Date: Fri, 16 Jun 2017 06:40:52 +0200 Message-Id: <20170616044058.30443-2-kernel@kempniu.pl> X-Mailer: git-send-email 2.13.1 In-Reply-To: <20170616044058.30443-1-kernel@kempniu.pl> References: <20170616044058.30443-1-kernel@kempniu.pl> MIME-Version: 1.0 Sender: linux-acpi-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-acpi@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP All ACPI device notify callbacks are invoked using acpi_os_execute(), which causes the supplied callback to be queued to a static workqueue which always executes on CPU 0. This means that there is no possibility for any ACPI device notify callback to be concurrently executed on multiple CPUs, which in the case of fujitsu-laptop means that using a locked kfifo for handling hotkeys is redundant: as hotkey scancodes are only pushed and popped from within acpi_fujitsu_laptop_notify(), no risk of concurrent pushing and popping exists. Instead of a kfifo, use a fixed-size integer table for storing pushed scancodes and an associated variable holding the number of scancodes currently stored in that table. Change debug messages so that they no longer contain the term "ringbuffer". In order to simplify implementation, hotkey input device behavior is slightly changed (from FIFO to LIFO). The order of release events generated by the input device should not matter from end user perspective as upon releasing any hotkey the firmware only produces a single event which means "all hotkeys were released". Signed-off-by: Michał Kępień --- drivers/platform/x86/fujitsu-laptop.c | 54 +++++++++-------------------------- 1 file changed, 14 insertions(+), 40 deletions(-) diff --git a/drivers/platform/x86/fujitsu-laptop.c b/drivers/platform/x86/fujitsu-laptop.c index 1c6fdd952c75..54cb7ae541d4 100644 --- a/drivers/platform/x86/fujitsu-laptop.c +++ b/drivers/platform/x86/fujitsu-laptop.c @@ -58,7 +58,6 @@ #include #include #include -#include #include #include #include @@ -110,7 +109,6 @@ #define KEY5_CODE 0x420 #define MAX_HOTKEY_RINGBUFFER_SIZE 100 -#define RINGBUFFERSIZE 40 /* Debugging */ #define FUJLAPTOP_DBG_ERROR 0x0001 @@ -146,8 +144,8 @@ struct fujitsu_laptop { struct input_dev *input; char phys[32]; struct platform_device *pf_device; - struct kfifo fifo; - spinlock_t fifo_lock; + int scancode_buf[40]; + int scancode_count; int flags_supported; int flags_state; }; @@ -813,23 +811,14 @@ static int acpi_fujitsu_laptop_add(struct acpi_device *device) sprintf(acpi_device_class(device), "%s", ACPI_FUJITSU_CLASS); device->driver_data = priv; - /* kfifo */ - spin_lock_init(&priv->fifo_lock); - error = kfifo_alloc(&priv->fifo, RINGBUFFERSIZE * sizeof(int), - GFP_KERNEL); - if (error) { - pr_err("kfifo_alloc failed\n"); - goto err_stop; - } - error = acpi_fujitsu_laptop_input_setup(device); if (error) - goto err_free_fifo; + return error; error = acpi_bus_update_power(device->handle, &state); if (error) { pr_err("Error reading power state\n"); - goto err_free_fifo; + return error; } pr_info("ACPI: %s [%s] (%s)\n", @@ -877,62 +866,47 @@ static int acpi_fujitsu_laptop_add(struct acpi_device *device) error = acpi_fujitsu_laptop_leds_register(device); if (error) - goto err_free_fifo; + return error; error = fujitsu_laptop_platform_add(device); if (error) - goto err_free_fifo; + return error; return 0; - -err_free_fifo: - kfifo_free(&priv->fifo); -err_stop: - return error; } static int acpi_fujitsu_laptop_remove(struct acpi_device *device) { - struct fujitsu_laptop *priv = acpi_driver_data(device); - fujitsu_laptop_platform_remove(device); - kfifo_free(&priv->fifo); - return 0; } static void acpi_fujitsu_laptop_press(struct acpi_device *device, int scancode) { struct fujitsu_laptop *priv = acpi_driver_data(device); - int status; - status = kfifo_in_locked(&priv->fifo, (unsigned char *)&scancode, - sizeof(scancode), &priv->fifo_lock); - if (status != sizeof(scancode)) { + if (priv->scancode_count == ARRAY_SIZE(priv->scancode_buf)) { vdbg_printk(FUJLAPTOP_DBG_WARN, "Could not push scancode [0x%x]\n", scancode); return; } + priv->scancode_buf[priv->scancode_count++] = scancode; sparse_keymap_report_event(priv->input, scancode, 1, false); vdbg_printk(FUJLAPTOP_DBG_TRACE, - "Push scancode into ringbuffer [0x%x]\n", scancode); + "Push scancode into buffer [0x%x]\n", scancode); } static void acpi_fujitsu_laptop_release(struct acpi_device *device) { struct fujitsu_laptop *priv = acpi_driver_data(device); - int scancode, status; - - while (true) { - status = kfifo_out_locked(&priv->fifo, - (unsigned char *)&scancode, - sizeof(scancode), &priv->fifo_lock); - if (status != sizeof(scancode)) - return; + int scancode; + + while (priv->scancode_count > 0) { + scancode = priv->scancode_buf[--priv->scancode_count]; sparse_keymap_report_event(priv->input, scancode, 0, false); vdbg_printk(FUJLAPTOP_DBG_TRACE, - "Pop scancode from ringbuffer [0x%x]\n", scancode); + "Pop scancode from buffer [0x%x]\n", scancode); } }