From patchwork Sat Feb 3 12:00:46 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Zhang Bo X-Patchwork-Id: 10198495 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 4376C60247 for ; Sat, 3 Feb 2018 12:02:09 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 33B3A27E5A for ; Sat, 3 Feb 2018 12:02:09 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 284FB28FCD; Sat, 3 Feb 2018 12:02:09 +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 AEE1F285A0 for ; Sat, 3 Feb 2018 12:02:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752188AbeBCMCC (ORCPT ); Sat, 3 Feb 2018 07:02:02 -0500 Received: from m50-111.126.com ([123.125.50.111]:39342 "EHLO m50-111.126.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751789AbeBCMCB (ORCPT ); Sat, 3 Feb 2018 07:02:01 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=126.com; s=s110527; h=From:Subject:Date:Message-Id; bh=8EoDSWhXlyMO/u52NE wUo9G02qCw9Sjm41Af4cAJKcQ=; b=nxRMQ3pb47xYQpTFzF95qwOa7ZA0c0omLU FqBudrYBtx+Z+5lp9MNdEbcrldjQNMTHJnbmyMKEj9KXLgPENxGF+PWRGB8Rg/wn 27CzvzLVAtycXXwK66WZcCg6a991rD10ZrNZJ7z+nbu/ErEq2tUPsyzPV+jErdz8 P8tvPDUD8= Received: from bogon.DHCP (unknown [123.139.75.126]) by smtp5 (Coremail) with SMTP id jtKowABH+L6RpHVa8KdTAA--.192S4; Sat, 03 Feb 2018 20:01:49 +0800 (CST) From: Zhang Bo To: dmitry.torokhov@gmail.com Cc: DRivshin@allworx.com, robh@kernel.org, linux-input@vger.kernel.org, linux-kernel@vger.kernel.org, zbsdta@126.com, zhang.bo19@zte.com.cn Subject: [PATCH] Input: matrix_keypad - fix keypad does not response Date: Sat, 3 Feb 2018 20:00:46 +0800 Message-Id: <20180203120046.10988-1-zbsdta@126.com> X-Mailer: git-send-email 2.14.3 X-CM-TRANSID: jtKowABH+L6RpHVa8KdTAA--.192S4 X-Coremail-Antispam: 1Uf129KBjvJXoW7Aw1rXF4UGFWfAw1fZw1fZwb_yoW8Kr4xpr WfG34qyr4UJ3Wj93yvqr4093Z8Gw4kZry2grn5W34kJrn0vr17Grn3K3ySga4UZrW0yanx ZF4kZw15G3WqyF7anT9S1TB71UUUUUUqnTZGkaVYY2UrUUUUjbIjqfuFe4nvWSU5nxnvy2 9KBjDUYxBIdaVFxhVjvjDU0xZFpf9x07UfxhLUUUUU= X-Originating-IP: [123.139.75.126] X-CM-SenderInfo: h2evv3bd6rjloofrz/1tbiOxbhSVpD4XaxggAAs4 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 From: zhangbo 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. Signed-off-by: zhangbo --- drivers/input/keyboard/matrix_keypad.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/drivers/input/keyboard/matrix_keypad.c b/drivers/input/keyboard/matrix_keypad.c index 1f316d66e6f7..13fe51824637 100644 --- a/drivers/input/keyboard/matrix_keypad.c +++ b/drivers/input/keyboard/matrix_keypad.c @@ -169,7 +169,8 @@ static void matrix_keypad_scan(struct work_struct *work) /* Enable IRQs again */ spin_lock_irq(&keypad->lock); keypad->scan_pending = false; - enable_row_irqs(keypad); + if (keypad->stopped == false) + enable_row_irqs(keypad); spin_unlock_irq(&keypad->lock); } @@ -202,14 +203,16 @@ static int matrix_keypad_start(struct input_dev *dev) { struct matrix_keypad *keypad = input_get_drvdata(dev); + spin_lock_irq(&keypad->lock); keypad->stopped = false; - mb(); /* * Schedule an immediate key scan to capture current key state; * columns will be activated and IRQs be enabled after the scan. */ - schedule_delayed_work(&keypad->work, 0); + if (keypad->scan_pending == false) + schedule_delayed_work(&keypad->work, 0); + spin_unlock_irq(&keypad->lock); return 0; } @@ -218,14 +221,17 @@ 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(); - flush_work(&keypad->work.work); /* * matrix_keypad_scan() will leave IRQs enabled; * we should disable them now. */ - disable_row_irqs(keypad); + if (keypad->scan_pending == false) + disable_row_irqs(keypad); + spin_unlock_irq(&keypad->lock); + + flush_work(&keypad->work.work); } #ifdef CONFIG_PM_SLEEP