Received: by 2002:a05:7412:d008:b0:f9:6acb:47ec with SMTP id bd8csp305517rdb; Tue, 19 Dec 2023 18:29:54 -0800 (PST) X-Google-Smtp-Source: AGHT+IHMwah3K68tOXj1ZLnJWa1gnbJZBWopEMrYgBXpuySeTKnpqEiIQodaaTyaZO5rDpdZeA+7 X-Received: by 2002:a05:6808:2e99:b0:3ba:4a:a8c7 with SMTP id gt25-20020a0568082e9900b003ba004aa8c7mr24195447oib.118.1703039394278; Tue, 19 Dec 2023 18:29:54 -0800 (PST) ARC-Seal: i=1; a=rsa-sha256; t=1703039394; cv=none; d=google.com; s=arc-20160816; b=YkuHQwz5U0v2ORVNYFRFAvg/gAfkoSnhdAAMrH74vmVDVPqCVEg9t2VdsycRbLLT4e Jr8Mj+SxnZgiOBYmf3VdwWMfLxa3AvSH+qozj+OxjYQW6JFUcupdL3Ynw1Qiebq9o0sB F6YWFp0+45B0QlT8X+FjhYJCxggFr8mE8relPMzFzmd9UAk8YmKGItGIS9tC8E50mtJ8 Ou/P6JsAyzIYK0mUTKram/UD25KArBrE7hZNon97XdMmAbSkJxzdFsguUkyn5YdUY+vC xycDT5pF+aipQDu6ZoiWMKFlxbLSu86OoeXe+T4bJu70hwmNmyXSm1//zht+M+s2Ksen S1yw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=content-transfer-encoding:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:in-reply-to:message-id :date:subject:cc:to:from; bh=/s6nh+OnT95rk67Vq0CX7/pjmy4zN7W5jm/vs3FA464=; fh=rDQ+Brvi8X8MBGQj98Swf6ntKE0/lLPfVCCWuSkkQw8=; b=zPakeF3nev5piIKowJ03F2AAQdE1wt1aO5NisaoRg32F9CvXnQf8CEP9tg97UtVJmP v02Kuvnt8wolgikkjGRNMB0uib3TpK7t3IZS1EfaXp4aiiMxu1WYU52bIrsMGHk7DmAS Oa3pFw2StFBdPGlzWGx/xVWANvbEHxZJj7Szdhh/eSSo3iSBfKPhiYujE1zNTZ//z341 J7lOjsS5hqEPwNQ32jtdm+0d8ODvwS5XBasVqlA7RlcmAQWOBUVRlLjElgBDYgSRjZzN Gra5s2ULF8+gnvGi7JLAQsPPYf2pjRFIYQP9I80ecJa8mIrVyBtkLdNur2AamAi3z2gG GOYQ== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: domain of linux-kernel+bounces-6289-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-6289-linux.lists.archive=gmail.com@vger.kernel.org" Return-Path: Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [2604:1380:40f1:3f00::1]) by mx.google.com with ESMTPS id y128-20020a62ce86000000b006d9396d730esi1704450pfg.331.2023.12.19.18.29.53 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 19 Dec 2023 18:29:54 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-6289-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) client-ip=2604:1380:40f1:3f00::1; Authentication-Results: mx.google.com; spf=pass (google.com: domain of linux-kernel+bounces-6289-linux.lists.archive=gmail.com@vger.kernel.org designates 2604:1380:40f1:3f00::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-6289-linux.lists.archive=gmail.com@vger.kernel.org" Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sy.mirrors.kernel.org (Postfix) with ESMTPS id D5654B21ACD for ; Wed, 20 Dec 2023 02:29:43 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 507D5BE65; Wed, 20 Dec 2023 02:29:20 +0000 (UTC) X-Original-To: linux-kernel@vger.kernel.org Received: from mail-pl1-f176.google.com (mail-pl1-f176.google.com [209.85.214.176]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id B75B68801; Wed, 20 Dec 2023 02:29:17 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kylinos.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Received: by mail-pl1-f176.google.com with SMTP id d9443c01a7336-1d3d3f0afc4so4615925ad.1; Tue, 19 Dec 2023 18:29:17 -0800 (PST) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1703039357; x=1703644157; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=/s6nh+OnT95rk67Vq0CX7/pjmy4zN7W5jm/vs3FA464=; b=Nggtw0vAtj5Kza0eInQ4fb8EU80aOd14DxSKFF/YUXyawDwENqNbDhg0A7DF3QPqS9 38fim5PRoD8KcyHdbOo7zyPxUC9PQBMRE3iVLyNvQUj0SVbPLkdm+04D6+kpORMK7KCk fN2RD195nFmHOeJPTLJ4mxR/1vot7YC6ZIYiRLNiFsZcLcnIUOUidVkbECywmTugb1N8 Vx0LtWIslhF2Ad/Je2rzdeWKyXBsezNzEAnwiG3y55yzqXZFHSA+gTXl77VdzYdELN56 mbLjO7UVkXbRNb7UnIAKLpnYWdNSNvtJfyAg6NHAUfUHnC4moB9vmnQAJSqS64NPqcMC ZBcg== X-Gm-Message-State: AOJu0YxqepK2bFBXiF+xy5S8aTkqKp9X4+yYZiiQsUTJl6x8CIHugufa +HszXOc1SFeLn5sc+xp3bgc= X-Received: by 2002:a17:902:d2ca:b0:1d0:61a0:9844 with SMTP id n10-20020a170902d2ca00b001d061a09844mr38471639plc.4.1703039356931; Tue, 19 Dec 2023 18:29:16 -0800 (PST) Received: from tgsp-ThinkPad-X280.. ([223.148.26.128]) by smtp.gmail.com with ESMTPSA id l3-20020a170903244300b001d3d81c795bsm2112654pls.271.2023.12.19.18.29.11 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 19 Dec 2023 18:29:16 -0800 (PST) From: xiongxin To: fancer.lancer@gmail.com, hoan@os.amperecomputing.com, linus.walleij@linaro.org, brgl@bgdev.pl, andy@kernel.org Cc: linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org, xiongxin , stable@kernel.org, Riwen Lu Subject: [PATCH v5] gpio: dwapb: mask/unmask IRQ when disable/enale it Date: Wed, 20 Dec 2023 10:29:01 +0800 Message-Id: <20231220022901.29158-1-xiongxin@kylinos.cn> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231219101620.4617-1-xiongxin@kylinos.cn> References: <20231219101620.4617-1-xiongxin@kylinos.cn> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit In the hardware implementation of the I2C HID driver based on DesignWare GPIO IRQ chip, when the user continues to use the I2C HID device in the suspend process, the I2C HID interrupt will be masked after the resume process is finished. This is because the disable_irq()/enable_irq() of the DesignWare GPIO driver does not synchronize the IRQ mask register state. In normal use of the I2C HID procedure, the GPIO IRQ irq_mask()/irq_unmask() functions are called in pairs. In case of an exception, i2c_hid_core_suspend() calls disable_irq() to disable the GPIO IRQ. With low probability, this causes irq_unmask() to not be called, which causes the GPIO IRQ to be masked and not unmasked in enable_irq(), raising an exception. Add synchronization to the masked register state in the dwapb_irq_enable()/dwapb_irq_disable() function. mask the GPIO IRQ before disabling it. After enabling the GPIO IRQ, unmask the IRQ. Fixes: 7779b3455697 ("gpio: add a driver for the Synopsys DesignWare APB GPIO block") Cc: stable@kernel.org Co-developed-by: Riwen Lu Signed-off-by: Riwen Lu Signed-off-by: xiongxin Acked-by: Serge Semin Reviewed-by: Andy Shevchenko --- v5: * fix typo in patch description v4: * Add patch tag information v3: * Modify the submitter's information v2: * Resubmit the patch to fix this exception from the DesignWare GPIO driver side v1: * Resolve the exception from the IRQ core layer. (key point not found correctly) --- drivers/gpio/gpio-dwapb.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/drivers/gpio/gpio-dwapb.c b/drivers/gpio/gpio-dwapb.c index 4a4f61bf6c58..8c59332429c2 100644 --- a/drivers/gpio/gpio-dwapb.c +++ b/drivers/gpio/gpio-dwapb.c @@ -282,13 +282,15 @@ static void dwapb_irq_enable(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct dwapb_gpio *gpio = to_dwapb_gpio(gc); + irq_hw_number_t hwirq = irqd_to_hwirq(d); unsigned long flags; u32 val; raw_spin_lock_irqsave(&gc->bgpio_lock, flags); - val = dwapb_read(gpio, GPIO_INTEN); - val |= BIT(irqd_to_hwirq(d)); + val = dwapb_read(gpio, GPIO_INTEN) | BIT(hwirq); dwapb_write(gpio, GPIO_INTEN, val); + val = dwapb_read(gpio, GPIO_INTMASK) & ~BIT(hwirq); + dwapb_write(gpio, GPIO_INTMASK, val); raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags); } @@ -296,12 +298,14 @@ static void dwapb_irq_disable(struct irq_data *d) { struct gpio_chip *gc = irq_data_get_irq_chip_data(d); struct dwapb_gpio *gpio = to_dwapb_gpio(gc); + irq_hw_number_t hwirq = irqd_to_hwirq(d); unsigned long flags; u32 val; raw_spin_lock_irqsave(&gc->bgpio_lock, flags); - val = dwapb_read(gpio, GPIO_INTEN); - val &= ~BIT(irqd_to_hwirq(d)); + val = dwapb_read(gpio, GPIO_INTMASK) | BIT(hwirq); + dwapb_write(gpio, GPIO_INTMASK, val); + val = dwapb_read(gpio, GPIO_INTEN) & ~BIT(hwirq); dwapb_write(gpio, GPIO_INTEN, val); raw_spin_unlock_irqrestore(&gc->bgpio_lock, flags); } -- 2.34.1