From: Edward Blair <edward.blair@gmail.com>
To: linux-i2c@vger.kernel.org, linux-usb@vger.kernel.org
Cc: heikki.krogerus@linux.intel.com, gregkh@linuxfoundation.org,
wsa+renesas@sang-engineering.com, westeri@kernel.org,
linux-acpi@vger.kernel.org, linux-kernel@vger.kernel.org,
Edward Blair <edward.blair@gmail.com>
Subject: [PATCH 1/2] i2c: acpi: skip generic I2C device when vendor-specific sibling exists
Date: Sat, 14 Mar 2026 01:31:55 +0000 [thread overview]
Message-ID: <20260314013157.7181-2-edward.blair@gmail.com> (raw)
In-Reply-To: <20260314013157.7181-1-edward.blair@gmail.com>
Some BIOS implementations (notably ASUS Z690/Z790/X670E motherboards)
declare both a generic UCSI device (MSFT8000) and a vendor-specific
device (e.g., ITE8853) as ACPI children of the same I2C controller,
both referencing the same I2C slave address.
During ACPI I2C enumeration, whichever device is walked first claims
the address, causing the second to fail with -EBUSY. When the generic
MSFT8000 device registers first, the vendor-specific driver cannot
bind, losing access to device-specific features like GPIO interrupt
resources that are only declared on the vendor-specific ACPI device.
Fix this by checking, before registering a known generic I2C device,
whether a sibling ACPI device exists at the same address on the same
adapter. If so, skip the generic device to let the vendor-specific
one register instead.
Signed-off-by: Edward Blair <edward.blair@gmail.com>
---
drivers/i2c/i2c-core-acpi.c | 88 +++++++++++++++++++++++++++++++++++++
1 file changed, 88 insertions(+)
diff --git a/drivers/i2c/i2c-core-acpi.c b/drivers/i2c/i2c-core-acpi.c
index 2cbd31f77..87582eac7 100644
--- a/drivers/i2c/i2c-core-acpi.c
+++ b/drivers/i2c/i2c-core-acpi.c
@@ -137,6 +137,17 @@ static const struct acpi_device_id i2c_acpi_ignored_device_ids[] = {
{}
};
+/*
+ * Generic I2C device IDs that may be duplicated by vendor-specific devices.
+ * When a vendor-specific sibling exists at the same address, the generic
+ * device is skipped to avoid -EBUSY address conflicts.
+ */
+static const struct acpi_device_id i2c_acpi_generic_device_ids[] = {
+ /* Microsoft UCSI - often paired with vendor-specific UCSI device */
+ { "MSFT8000" },
+ {}
+};
+
struct i2c_acpi_irq_context {
int irq;
bool wake_capable;
@@ -274,6 +285,76 @@ static int i2c_acpi_get_info(struct acpi_device *adev,
return 0;
}
+struct i2c_acpi_sibling_check {
+ struct acpi_device *self;
+ struct i2c_adapter *adapter;
+ unsigned short addr;
+ bool found;
+};
+
+static int i2c_acpi_check_sibling_addr(struct acpi_device *adev, void *data)
+{
+ struct i2c_acpi_sibling_check *check = data;
+ struct i2c_acpi_lookup lookup;
+ struct i2c_board_info info;
+
+ if (adev == check->self)
+ return 0;
+
+ /* Only yield to vendor-specific devices, not other generic ones */
+ if (!acpi_match_device_ids(adev, i2c_acpi_generic_device_ids))
+ return 0;
+
+ memset(&lookup, 0, sizeof(lookup));
+ lookup.info = &info;
+ lookup.index = -1;
+
+ if (i2c_acpi_do_lookup(adev, &lookup))
+ return 0;
+
+ if (!device_match_acpi_handle(&check->adapter->dev,
+ lookup.adapter_handle))
+ return 0;
+
+ if (info.addr == check->addr) {
+ check->found = true;
+ return 1;
+ }
+
+ return 0;
+}
+
+/*
+ * Check whether this generic ACPI device has a vendor-specific sibling at the
+ * same I2C address. Some BIOS implementations (e.g., ASUS Z690/Z790/X670E)
+ * declare both a generic UCSI device (MSFT8000) and a vendor-specific device
+ * (e.g., ITE8853) at the same address. Skip the generic one so the vendor
+ * driver can bind with proper interrupt and device-specific resources.
+ */
+static bool i2c_acpi_has_vendor_sibling(struct acpi_device *adev,
+ struct i2c_adapter *adapter,
+ struct i2c_board_info *info)
+{
+ struct acpi_device *parent;
+ struct i2c_acpi_sibling_check check;
+
+ if (acpi_match_device_ids(adev, i2c_acpi_generic_device_ids))
+ return false;
+
+ parent = acpi_dev_parent(adev);
+ if (!parent)
+ return false;
+
+ check.self = adev;
+ check.adapter = adapter;
+ check.addr = info->addr;
+ check.found = false;
+
+ acpi_dev_for_each_child(parent, i2c_acpi_check_sibling_addr, &check);
+
+ return check.found;
+}
+
static void i2c_acpi_register_device(struct i2c_adapter *adapter,
struct acpi_device *adev,
struct i2c_board_info *info)
@@ -302,6 +383,13 @@ static acpi_status i2c_acpi_add_device(acpi_handle handle, u32 level,
if (!adev || i2c_acpi_get_info(adev, &info, adapter, NULL))
return AE_OK;
+ if (i2c_acpi_has_vendor_sibling(adev, adapter, &info)) {
+ dev_info(&adapter->dev,
+ "skipping %s in favor of vendor-specific device at 0x%02x\n",
+ dev_name(&adev->dev), info.addr);
+ return AE_OK;
+ }
+
i2c_acpi_register_device(adapter, adev, &info);
return AE_OK;
--
2.53.0
next prev parent reply other threads:[~2026-03-14 1:32 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-14 1:31 [PATCH 0/2] Add UCSI I2C transport driver for ITE885x USB-C controllers Edward Blair
2026-03-14 1:31 ` Edward Blair [this message]
2026-03-16 13:12 ` [PATCH 1/2] i2c: acpi: skip generic I2C device when vendor-specific sibling exists Mika Westerberg
2026-03-16 14:32 ` Edward Blair
2026-03-16 14:45 ` Mika Westerberg
2026-03-16 15:04 ` Edward Blair
2026-03-16 14:07 ` Heikki Krogerus
2026-03-14 1:31 ` [PATCH 2/2] usb: typec: ucsi: add ITE885x I2C transport driver Edward Blair
2026-03-16 14:57 ` Heikki Krogerus
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260314013157.7181-2-edward.blair@gmail.com \
--to=edward.blair@gmail.com \
--cc=gregkh@linuxfoundation.org \
--cc=heikki.krogerus@linux.intel.com \
--cc=linux-acpi@vger.kernel.org \
--cc=linux-i2c@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=westeri@kernel.org \
--cc=wsa+renesas@sang-engineering.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox