From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pj1-f46.google.com (mail-pj1-f46.google.com [209.85.216.46]) (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 C2A5730F934 for ; Mon, 4 May 2026 20:15:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.46 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777925709; cv=none; b=i2SjEVLBULiJAJfk1hcgnZQSp+rdHC6yoqbYVqisxXvvbYNLaTGrg8sX+TzeolbWfw1ll+YrgbEPz9k7IGAwyYQ3FDNLIkeXQn+PwD9xZuNeBvWnnAjGg6LW3BIsBg8cc4FTRt4k8E83yTFh33SEIxO+UlB6aLmfffvu8YRy1vA= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1777925709; c=relaxed/simple; bh=T0R/JRPSIi4l6iZ8HhDvk/mxhiX1g/sSVAs1BzrrMLM=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=C/UbzMyFnTuN64aEXNewjdJI5A7e9R1uxfOD3mGzwHimpFlNWCi55fQPSRm2FSIJquJNpMGHnoJfYmFxuGFTtyw7zrzsDC/wQAPFaQdAiyAdCZfWW+aI7bitIalHZ8pnK5QV/Yv2OMJCklLayQ+RRpEZOAJp4qsL6Um2Jm1fTYM= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=wkennington.com; spf=none smtp.mailfrom=wkennington.com; dkim=pass (2048-bit key) header.d=wkennington-com.20251104.gappssmtp.com header.i=@wkennington-com.20251104.gappssmtp.com header.b=CLITdPNy; arc=none smtp.client-ip=209.85.216.46 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=wkennington.com Authentication-Results: smtp.subspace.kernel.org; spf=none smtp.mailfrom=wkennington.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=wkennington-com.20251104.gappssmtp.com header.i=@wkennington-com.20251104.gappssmtp.com header.b="CLITdPNy" Received: by mail-pj1-f46.google.com with SMTP id 98e67ed59e1d1-356337f058aso2869421a91.2 for ; Mon, 04 May 2026 13:15:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=wkennington-com.20251104.gappssmtp.com; s=20251104; t=1777925707; x=1778530507; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=qgxSZwGgCRa1NejRL1TMSL6Pe1HA8DjUPmozziT+PDM=; b=CLITdPNyDt/qDbNsAGSd55st+7asWryawkz3HawcWyyC3Wuyg3jEqGwTIGfkqvsQz+ poaYwxwMqlQt0t2yA1X1VzrmXwkuwWc4ZxyuOOtbuYJjrHVDCMmkD5TFI+G5SUUW8eEO EwqIW4r0BxLph19cPHAfTStW9gaeQKp1wlyYg8wpBdTbIE0uQ85a6hnBlz8ZP8vrP5IA SuMBxqm9VuGDV3lkJzaW7fhOfMUoUyngTWdNkTrKEv24uQ6k1kGvuZvPv+paPD7zYCPv zyKkDLGK0AgyBztTpaUaVVetvB/lsqxVjE1tE3hDdJPqhkl+2lTV4LMrzcxAnI0Q7yMD 8+NA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1777925707; x=1778530507; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to; bh=qgxSZwGgCRa1NejRL1TMSL6Pe1HA8DjUPmozziT+PDM=; b=RrF+fX+tGxSyT3L+6APkn5Sd410A+9fVKt/Gj++nhQ5XBaE1k6BfTqjoToTVe1Fh7s xx3g68mrEm7ljd9v9U4Ol0wxH+wl8pVXrCr3d5tIcPK7CCqF3GNVjXCz7LXZ5Z7oLz0m ZIzerUEknkEwdkR99PNXpi+CMyWImv49fIXHEU95pn5LSkkaOYPAAFu6iE/A5cuwK+RN 2BgErgXYdGnTYsZ/+89ZiHFwRIJ3wuB809Zubsrc+N84++9oB7FgE1JRjzloFraF/AhS iTxOFbxeBFCTpjnp0kMBAd/rKZQX49zKRkWTVJfZPBxn5OAVXnFVzu8aZ3+rUUicYrKi D4gw== X-Forwarded-Encrypted: i=1; AFNElJ/q2aM5DMQZCcKMJQl1A40oBk/CO/pWUpAdTbgYaPBBAEl6mulyYeJZUq4ves45S2+gdKeh7F38AnPKR+E=@vger.kernel.org X-Gm-Message-State: AOJu0YykbzLHf6IiGJRBJWa30eZxpZqZjqPq3EGbON7DXDY3fjvB2Fy3 JEV9x7iZOonU5cSerrbKtEd5OZf1b1mBTUJttfZw7jaAvENUCj+W/DwpYuabrQol+4E= X-Gm-Gg: AeBDietw8CuUVGs+soUdjZ1aW/yFOWN/Q03BI5hLWAVomSG2gKuFpTSag6DuQZvORei hFpRLQ4XFlnUrr6y8ZzFkSKTeLuwfm9UrfEMyn6DJYyVWCQTYlhwzivlGK0RKLCGQR9sUVuFbM5 h3v3V3zGXHQE5nwQf56G9lW9G0V83YEXl0+oBBXY7spzeIivX+QYL4uyM58GLv3UzpsTGKuQvTu Z74i7pWqK+GRDvCptFXi27icEh7zYag9cVUCaJjZIzoQgBoHXF3Nq+tACFaIyTm4tTTPDII4y8o aQEv5If8c9gRET17L95qm9jkwL1d3MbclF3R4qB86Kw3fNgZ2ysll0hTUBoafbrn3JiyQRrxH8r Y4IBHYCtFHsqUPT773oWRgezATmsR2tE1vf54VEAmbbYrvvhTOWRJCJh5mKy5ODKAkuUSKddc7G b352whccfkN+xV6qG1e+GWgEnD/lqbXq/tVRAqNQW+LP0E//eouC4dbm7as6o/2JDaqF3O1Y7nf ieTnEXUMnTTCg96M7+cJQuMuA== X-Received: by 2002:a17:90a:e7cd:b0:359:fdc0:4621 with SMTP id 98e67ed59e1d1-3650cdb883dmr10970435a91.11.1777925707166; Mon, 04 May 2026 13:15:07 -0700 (PDT) Received: from wakbuild.c.googlers.com (123.143.125.34.bc.googleusercontent.com. [34.125.143.123]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-364bdf2aa41sm20568593a91.4.2026.05.04.13.15.06 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 04 May 2026 13:15:06 -0700 (PDT) From: "William A. Kennington III" Date: Mon, 04 May 2026 20:15:05 +0000 Subject: [PATCH v3 4/4] i2c: designware: Handle active slave cleanly Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: 7bit Message-Id: <20260504-dw-i2c-v3-4-57e56135d602@wkennington.com> References: <20260504-dw-i2c-v3-0-57e56135d602@wkennington.com> In-Reply-To: <20260504-dw-i2c-v3-0-57e56135d602@wkennington.com> To: Mika Westerberg , Andy Shevchenko , Jan Dabros , Andi Shyti Cc: linux-i2c@vger.kernel.org, linux-kernel@vger.kernel.org, "William A. Kennington III" X-Mailer: b4 0.14.3 When the I2C master attempts a new transaction while the slave controller is shutting down or restarting, it can lead to bus lockups and system bootloops if the hardware enters an inconsistent state. Address this by ensuring that the internal state machines are properly cleared when disabling the controller if slave activity is detected. If the controller remains active after disabling, perform a bus recovery to reset it to a known good state. Signed-off-by: William A. Kennington III --- drivers/i2c/busses/i2c-designware-common.c | 8 ++++++++ drivers/i2c/busses/i2c-designware-core.h | 4 ++-- drivers/i2c/busses/i2c-designware-master.c | 31 ++++++++++++++++++------------ 3 files changed, 29 insertions(+), 14 deletions(-) diff --git a/drivers/i2c/busses/i2c-designware-common.c b/drivers/i2c/busses/i2c-designware-common.c index 0703fb29038c..31394d8fe612 100644 --- a/drivers/i2c/busses/i2c-designware-common.c +++ b/drivers/i2c/busses/i2c-designware-common.c @@ -633,6 +633,14 @@ void __i2c_dw_disable(struct dw_i2c_dev *dev) abort_needed = (raw_intr_stats & DW_IC_INTR_MST_ON_HOLD) || (ic_stats & DW_IC_STATUS_MASTER_HOLD_TX_FIFO_EMPTY); + + /* + * If we are in slave mode and there is activity, we should also + * trigger an abort to clear the internal state machines. + */ + if (dev->mode == DW_IC_SLAVE && (ic_stats & DW_IC_STATUS_SLAVE_ACTIVITY)) + abort_needed = true; + if (abort_needed) { if (!(enable & DW_IC_ENABLE_ENABLE)) { regmap_write(dev->map, DW_IC_ENABLE, DW_IC_ENABLE_ENABLE); diff --git a/drivers/i2c/busses/i2c-designware-core.h b/drivers/i2c/busses/i2c-designware-core.h index 8b422249acbd..259b7ce16d0c 100644 --- a/drivers/i2c/busses/i2c-designware-core.h +++ b/drivers/i2c/busses/i2c-designware-core.h @@ -129,8 +129,8 @@ #define DW_IC_STATUS_ACTIVITY BIT(0) #define DW_IC_STATUS_TFE BIT(2) #define DW_IC_STATUS_RFNE BIT(3) -#define DW_IC_STATUS_MASTER_ACTIVITY BIT(5) -#define DW_IC_STATUS_SLAVE_ACTIVITY BIT(6) +#define DW_IC_STATUS_MASTER_ACTIVITY BIT(5) +#define DW_IC_STATUS_SLAVE_ACTIVITY BIT(6) #define DW_IC_STATUS_MASTER_HOLD_TX_FIFO_EMPTY BIT(7) #define DW_IC_SDA_HOLD_RX_SHIFT 16 diff --git a/drivers/i2c/busses/i2c-designware-master.c b/drivers/i2c/busses/i2c-designware-master.c index de929b91d5ea..7a301c8b604e 100644 --- a/drivers/i2c/busses/i2c-designware-master.c +++ b/drivers/i2c/busses/i2c-designware-master.c @@ -785,18 +785,25 @@ __i2c_dw_xfer_one_part(struct dw_i2c_dev *dev, struct i2c_msg *msgs, size_t num) * IC_RAW_INTR_STAT.MASTER_ON_HOLD holding SCL low. Check if * controller is still ACTIVE before disabling I2C. */ - if (i2c_dw_is_controller_active(dev)) - dev_err(dev->dev, "controller active\n"); - - /* - * We must disable the adapter before returning and signaling the end - * of the current transfer. Otherwise the hardware might continue - * generating interrupts which in turn causes a race condition with - * the following transfer. Needs some more investigation if the - * additional interrupts are a hardware bug or this driver doesn't - * handle them correctly yet. - */ - __i2c_dw_disable_nowait(dev); + if (i2c_dw_is_controller_active(dev)) { + /* + * If the controller is still active after the timeout, attempt a + * bus recovery to clear any potentially locked state. + */ + dev_err(dev->dev, "controller active after xfer, recovering\n"); + i2c_recover_bus(&dev->adapter); + i2c_dw_init(dev); + } else { + /* + * We must disable the adapter before returning and signaling the end + * of the current transfer. Otherwise the hardware might continue + * generating interrupts which in turn causes a race condition with + * the following transfer. Needs some more investigation if the + * additional interrupts are a hardware bug or this driver doesn't + * handle them correctly yet. + */ + __i2c_dw_disable_nowait(dev); + } if (dev->msg_err) return dev->msg_err; -- 2.54.0.545.g6539524ca2-goog