From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 664D03168EE; Fri, 8 May 2026 09:03:32 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778231012; cv=none; b=CxCl18B3Kv3dR9XV3dwULOPpnq2BILAMx9NqPNC91uaBpoNQtdqvVypqtM96ze4JzGV9/U3ZFv0mDgft9G3BI4DbM0auSBI3rnC2fXpqty35+kEyYfVGh+bxEUvKlnEAiyHVlqI4ImgFrnBYP1bj18bv7s9RFtfMgkj3Qh8OWWw= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778231012; c=relaxed/simple; bh=iWOJMFzk81mc01UCHmR2eS+IPYYYlYe4517FrK8gdpc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=CpQY+4DsjiZCzy3wo4qckkXRQmMYf4qlP/706W8FFep4I/6xVdshujGa5FySMfbI+aM/qn3g1hkQbirDTYZMG7Hmc7EkjAvqghOeOTcTmc5S+iT4YWrJQmgtDAR3CPcuesUcsNxdjo9vgmVi7o9eRvPoSYCSizl6523y60I2XwE= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=PbCEH/SV; arc=none smtp.client-ip=10.30.226.201 Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="PbCEH/SV" Received: by smtp.kernel.org (Postfix) with ESMTPSA id 21C2DC2BCC7; Fri, 8 May 2026 09:03:32 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1778231012; bh=iWOJMFzk81mc01UCHmR2eS+IPYYYlYe4517FrK8gdpc=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=PbCEH/SVJOl3yT2Vmiek8Wf8cjsfZ/SgELzFV5uBjRDyNcLTPMocA95c7C4rwEHRl l9rftj8wG2jtU2/U0XhtRqZMDb99TCZEhQdLHe8OxHp/S6fSzroJ0uOLQRFjqjpZAx 3cFbCgP6H2PKeVYo1qf8thtrjI44+j9tSC75sQ3gvJ+2dpSQb+/hhqwGWUWRc9Ovrz fj32iFRpXZPdERdMladQdxyxFsk2P6JAOewZ5PbK8g6CaiPf78HHcQCr7RjTNl8gyM Av+zfPILSH1otArlRk+woU58QIHe7dm/9rh1ts2eMFuGAvy3dKnijowlF6SdOJIUzu WGk6DHPCKTG8w== Received: from johan by xi.lan with local (Exim 4.98.2) (envelope-from ) id 1wLH7J-00000001ah2-45ME; Fri, 08 May 2026 11:03:29 +0200 From: Johan Hovold To: Wolfram Sang Cc: Andi Shyti , linux-i2c@vger.kernel.org, linux-kernel@vger.kernel.org, Johan Hovold , stable@vger.kernel.org, Phil Reid Subject: [PATCH v2 2/9] i2c: core: fix hang on adapter registration failure Date: Fri, 8 May 2026 11:03:04 +0200 Message-ID: <20260508090311.379333-3-johan@kernel.org> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260508090311.379333-1-johan@kernel.org> References: <20260508090311.379333-1-johan@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Clients may be registered from bus notifier callbacks when the adapter is registered. On a subsequent error during registration, the adapter references taken by such clients prevent the wait for the references to be released from ever completing. Fix this by refactoring client deregistration and deregistering also on late adapter registration failures. Fixes: f8756c67b3de ("i2c: core: call of_i2c_setup_smbus_alert in i2c_register_adapter") Cc: stable@vger.kernel.org # 4.15 Cc: Phil Reid Signed-off-by: Johan Hovold --- drivers/i2c/i2c-core-base.c | 49 ++++++++++++++++++++++--------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/drivers/i2c/i2c-core-base.c b/drivers/i2c/i2c-core-base.c index abe8341c1d6e..e42851a10098 100644 --- a/drivers/i2c/i2c-core-base.c +++ b/drivers/i2c/i2c-core-base.c @@ -63,6 +63,7 @@ static DEFINE_MUTEX(core_lock); static DEFINE_IDR(i2c_adapter_idr); +static void i2c_deregister_clients(struct i2c_adapter *adap); static int i2c_detect(struct i2c_adapter *adapter, struct i2c_driver *driver); static DEFINE_STATIC_KEY_FALSE(i2c_trace_msg_key); @@ -1605,6 +1606,7 @@ static int i2c_register_adapter(struct i2c_adapter *adap) return 0; out_reg: + i2c_deregister_clients(adap); debugfs_remove_recursive(adap->debugfs); init_completion(&adap->dev_released); device_unregister(&adap->dev); @@ -1746,29 +1748,10 @@ static int __process_removed_adapter(struct device_driver *d, void *data) return 0; } -/** - * i2c_del_adapter - unregister I2C adapter - * @adap: the adapter being unregistered - * Context: can sleep - * - * This unregisters an I2C adapter which was previously registered - * by @i2c_add_adapter or @i2c_add_numbered_adapter. - */ -void i2c_del_adapter(struct i2c_adapter *adap) +static void i2c_deregister_clients(struct i2c_adapter *adap) { - struct i2c_adapter *found; struct i2c_client *client, *next; - /* First make sure that this adapter was ever added */ - mutex_lock(&core_lock); - found = idr_find(&i2c_adapter_idr, adap->nr); - mutex_unlock(&core_lock); - if (found != adap) { - pr_debug("attempting to delete unregistered adapter [%s]\n", adap->name); - return; - } - - i2c_acpi_remove_space_handler(adap); /* Tell drivers about this removal */ mutex_lock(&core_lock); bus_for_each_drv(&i2c_bus_type, NULL, adap, @@ -1794,6 +1777,32 @@ void i2c_del_adapter(struct i2c_adapter *adap) * them up properly, so we give them a chance to do that first. */ device_for_each_child(&adap->dev, NULL, __unregister_client); device_for_each_child(&adap->dev, NULL, __unregister_dummy); +} + +/** + * i2c_del_adapter - unregister I2C adapter + * @adap: the adapter being unregistered + * Context: can sleep + * + * This unregisters an I2C adapter which was previously registered + * by @i2c_add_adapter or @i2c_add_numbered_adapter. + */ +void i2c_del_adapter(struct i2c_adapter *adap) +{ + struct i2c_adapter *found; + + /* First make sure that this adapter was ever added */ + mutex_lock(&core_lock); + found = idr_find(&i2c_adapter_idr, adap->nr); + mutex_unlock(&core_lock); + if (found != adap) { + pr_debug("attempting to delete unregistered adapter [%s]\n", adap->name); + return; + } + + i2c_acpi_remove_space_handler(adap); + + i2c_deregister_clients(adap); /* device name is gone after device_unregister */ dev_dbg(&adap->dev, "adapter [%s] unregistered\n", adap->name); -- 2.53.0