From patchwork Sun Feb 4 00:19:22 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhang Bo X-Patchwork-Id: 10199201 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 AC16C60247 for ; Sun, 4 Feb 2018 00:20:25 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 849C728F76 for ; Sun, 4 Feb 2018 00:20:25 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 7572028FD9; Sun, 4 Feb 2018 00:20:25 +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, FREEMAIL_FROM, RCVD_IN_DNSWL_HI, T_DKIM_INVALID 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 B140628F9B for ; Sun, 4 Feb 2018 00:20:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752214AbeBDAUF (ORCPT ); Sat, 3 Feb 2018 19:20:05 -0500 Received: from m50-110.126.com ([123.125.50.110]:42085 "EHLO m50-110.126.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752210AbeBDAUF (ORCPT ); Sat, 3 Feb 2018 19:20:05 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=126.com; s=s110527; h=From:Subject:Date:Message-Id; bh=L9daB6Dd/+VMSiJ/dI lD8Q6/Klb13IJK8PgK6V3qe8c=; b=PXJ5fIkhzKHEBt6g4+YNkLRjsY32/smSot JVdzYHyYGpPMDhxoIaLv93musNG60oLOhtOyY+cH9YvRteM/ccTZSfg/qw6z2cHf 65x5VNsOIoVbjeOyfoH4oz/0hug8ZJP6unlpWPvxn+/yGRsCSyMENpV8dAOSVWsU FaeRJqC6Y= Received: from bogon.DHCP (unknown [123.139.75.126]) by smtp4 (Coremail) with SMTP id jdKowAB3EOyQUXZagIQwAA--.2S4; Sun, 04 Feb 2018 08:19:54 +0800 (CST) From: Zhang Bo To: dmitry.torokhov@gmail.com Cc: zbsdta@126.com, DRivshin@allworx.com, robh@kernel.org, linux-input@vger.kernel.org, linux-kernel@vger.kernel.org, zhang.bo19@zte.com.cn Subject: [PATCH v3] Input: matrix_keypad - fix keypad does not response Date: Sun, 4 Feb 2018 08:19:22 +0800 Message-Id: <20180204001922.32084-1-zbsdta@126.com> X-Mailer: git-send-email 2.14.3 X-CM-TRANSID: jdKowAB3EOyQUXZagIQwAA--.2S4 X-Coremail-Antispam: 1Uf129KBjvJXoW7Aw1rXF4UGFWfAw1fZw1fZwb_yoW8Xry3pr W3Gw1vkr48J3Wj93yqq34v9a4DCw4kZrWagrn5W3s5X3s0qr15Krsak3yaga4UArW8t3ZF vr4DZr15JF1qyr7anT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07UdrcfUUUUU= X-Originating-IP: [123.139.75.126] X-CM-SenderInfo: h2evv3bd6rjloofrz/1tbijgriSVpD3+lL1AAAsf 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 If matrix_keypad_stop() is calling and the keypad interrupt is triggered, disable_row_irqs() is called by both matrix_keypad_interrupt() and matrix_keypad_stop() at the same time. then disable_row_irqs() is called twice, and the device enter suspend state before keypad->work is executed. At this condition the device will start keypad and enable irq once after resume. and then irqs are disabled yet because irqs are disabled twice and only enable once. Take lock around keypad->stopped to ensure irqs operation is in atomic operation. Signed-off-by: Zhang Bo --- Changes in v3: - delete no needed lock protection, only add lock in matrix_keypad_stop(). Changes in v2: - Change commit message and full name in the signed-off-by tag. drivers/input/keyboard/matrix_keypad.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c index 1f316d66e6f7..41614c185918 100644 --- a/drivers/input/keyboard/matrix_keypad.c +++ b/drivers/input/keyboard/matrix_keypad.c @@ -218,8 +218,10 @@ static void matrix_keypad_stop(struct input_dev *dev) { struct matrix_keypad *keypad = input_get_drvdata(dev); + spin_lock_irq(&keypad->lock); keypad->stopped = true; - mb(); + spin_unlock_irq(&keypad->lock); + flush_work(&keypad->work.work); /* * matrix_keypad_scan() will leave IRQs enabled;