Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id D4E95C433EF for ; Tue, 30 Nov 2021 14:53:30 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237796AbhK3O4p (ORCPT ); Tue, 30 Nov 2021 09:56:45 -0500 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:60424 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S242515AbhK3Ox1 (ORCPT ); Tue, 30 Nov 2021 09:53:27 -0500 Received: from sin.source.kernel.org (sin.source.kernel.org [IPv6:2604:1380:40e1:4800::1]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 1371EC0617A2; Tue, 30 Nov 2021 06:48:49 -0800 (PST) Received: from smtp.kernel.org (relay.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sin.source.kernel.org (Postfix) with ESMTPS id 56EAACE1A53; Tue, 30 Nov 2021 14:48:47 +0000 (UTC) Received: by smtp.kernel.org (Postfix) with ESMTPSA id 7E9FDC53FD0; Tue, 30 Nov 2021 14:48:44 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1638283725; bh=wSy4ngHqonLlpwH4MCkuw7K7ZRA4PhoObos2hxXHl1I=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=fdgdhaawgE1EaawLep+Rlh9iTl1YiAIZdPNGXuoJXsuen1rkgVpXRZ5a9VP+UfhVD GBz2vGFCr9cyVXz41W9SkL0VUbh+8l4SsGQizxE01z4RzG4KW9x/CAKj7aT/j25w20 EAK5UhO8Gs42HN0QlPL0b3FD5Y1RrlnkKx6t3EiwTGMxLsjEQvVR8xk5m/AA5VRfKN JdPZR4KOkhgAwZaQAyZyBAaF4Zfty2Ss//r3aBwnEzcpOPKorfLUNfPWvxPh67wSwX fVg2htfklucF7fJKfcpvbyqcp7wLDb79fMPFOWaZcQAATE/Wy1FgZVKZEMgeFCM3DO 5RBRZek9QWkxA== From: Sasha Levin To: linux-kernel@vger.kernel.org, stable@vger.kernel.org Cc: Jarkko Nikula , ck+kernelbugzilla@bl4ckb0x.de, stephane.poignant@protonmail.com, Jean Delvare , Wolfram Sang , Sasha Levin , jdelvare@suse.com, linux-i2c@vger.kernel.org Subject: [PATCH AUTOSEL 5.15 35/68] i2c: i801: Fix interrupt storm from SMB_ALERT signal Date: Tue, 30 Nov 2021 09:46:31 -0500 Message-Id: <20211130144707.944580-35-sashal@kernel.org> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20211130144707.944580-1-sashal@kernel.org> References: <20211130144707.944580-1-sashal@kernel.org> MIME-Version: 1.0 X-stable: review X-Patchwork-Hint: Ignore Content-Transfer-Encoding: 8bit Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org From: Jarkko Nikula [ Upstream commit 03a976c9afb5e3c4f8260c6c08a27d723b279c92 ] Currently interrupt storm will occur from i2c-i801 after first transaction if SMB_ALERT signal is enabled and ever asserted. It is enough if the signal is asserted once even before the driver is loaded and does not recover because that interrupt is not acknowledged. This fix aims to fix it by two ways: - Add acknowledging for the SMB_ALERT interrupt status - Disable the SMB_ALERT interrupt on platforms where possible since the driver currently does not make use for it Acknowledging resets the SMB_ALERT interrupt status on all platforms and also should help to avoid interrupt storm on older platforms where the SMB_ALERT interrupt disabling is not available. For simplicity this fix reuses the host notify feature for disabling and restoring original register value. Link: https://bugzilla.kernel.org/show_bug.cgi?id=177311 Reported-by: ck+kernelbugzilla@bl4ckb0x.de Reported-by: stephane.poignant@protonmail.com Signed-off-by: Jarkko Nikula Reviewed-by: Jean Delvare Tested-by: Jean Delvare Signed-off-by: Wolfram Sang Signed-off-by: Sasha Levin --- drivers/i2c/busses/i2c-i801.c | 25 +++++++++++++++++++------ 1 file changed, 19 insertions(+), 6 deletions(-) diff --git a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c index 1f929e6c30bea..9be0b8f3e4a54 100644 --- a/drivers/i2c/busses/i2c-i801.c +++ b/drivers/i2c/busses/i2c-i801.c @@ -190,6 +190,7 @@ #define SMBSLVSTS_HST_NTFY_STS BIT(0) /* Host Notify Command register bits */ +#define SMBSLVCMD_SMBALERT_DISABLE BIT(2) #define SMBSLVCMD_HST_NTFY_INTREN BIT(0) #define STATUS_ERROR_FLAGS (SMBHSTSTS_FAILED | SMBHSTSTS_BUS_ERR | \ @@ -639,12 +640,20 @@ static irqreturn_t i801_isr(int irq, void *dev_id) i801_isr_byte_done(priv); /* - * Clear irq sources and report transaction result. + * Clear remaining IRQ sources: Completion of last command, errors + * and the SMB_ALERT signal. SMB_ALERT status is set after signal + * assertion independently of the interrupt generation being blocked + * or not so clear it always when the status is set. + */ + status &= SMBHSTSTS_INTR | STATUS_ERROR_FLAGS | SMBHSTSTS_SMBALERT_STS; + if (status) + outb_p(status, SMBHSTSTS(priv)); + status &= ~SMBHSTSTS_SMBALERT_STS; /* SMB_ALERT not reported */ + /* + * Report transaction result. * ->status must be cleared before the next transaction is started. */ - status &= SMBHSTSTS_INTR | STATUS_ERROR_FLAGS; if (status) { - outb_p(status, SMBHSTSTS(priv)); priv->status = status; complete(&priv->done); } @@ -972,9 +981,13 @@ static void i801_enable_host_notify(struct i2c_adapter *adapter) if (!(priv->features & FEATURE_HOST_NOTIFY)) return; - if (!(SMBSLVCMD_HST_NTFY_INTREN & priv->original_slvcmd)) - outb_p(SMBSLVCMD_HST_NTFY_INTREN | priv->original_slvcmd, - SMBSLVCMD(priv)); + /* + * Enable host notify interrupt and block the generation of interrupt + * from the SMB_ALERT signal because the driver does not support + * SMBus Alert. + */ + outb_p(SMBSLVCMD_HST_NTFY_INTREN | SMBSLVCMD_SMBALERT_DISABLE | + priv->original_slvcmd, SMBSLVCMD(priv)); /* clear Host Notify bit to allow a new notification */ outb_p(SMBSLVSTS_HST_NTFY_STS, SMBSLVSTS(priv)); -- 2.33.0