From nobody Fri Jun 12 15:51:47 2026 Received: from mail-dy1-f170.google.com (mail-dy1-f170.google.com [74.125.82.170]) (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 C2F85285068 for ; Thu, 14 May 2026 00:54:30 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.82.170 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778720072; cv=none; b=RzjLLcA6WGfsqdf+sUjb5dcHEEd1SZQfr8SgsAc0tb7ofirGZN2K53LfAF1C1iHTpxQXwzKJXR17h0PcesWZqmjDS5pFmf9SraIilPDX3K+t6FG7G9908zNBlgCeD4gUf7+JoWO5OpkJDsvSkw0Yre40BCzxpCIs2a3BRqzy1F4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1778720072; c=relaxed/simple; bh=MzGODVa4DeGQU5C+cZnr92IEwH4cg6ZVCQfAWMsP+Ow=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:To:Cc; b=uiq9LRpxjG89Yryjmpns/og9SOSgdZDALJhUZPPb7XAy1GApD20dZUy8fpsOeDw7zu8QFhQjx+X+h4hLRJlNOXxxC+LbKyz7tJbezXspgxUdwPotPRTNtsh4SHFFYl9pblsUPO/eI27OtR0pk//wTqhKLJ/x7/puuVyO1HZGwCo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nexthop.ai; spf=pass smtp.mailfrom=nexthop.ai; dkim=pass (2048-bit key) header.d=nexthop.ai header.i=@nexthop.ai header.b=GC8pRs0g; arc=none smtp.client-ip=74.125.82.170 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=nexthop.ai Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=nexthop.ai Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=nexthop.ai header.i=@nexthop.ai header.b="GC8pRs0g" Received: by mail-dy1-f170.google.com with SMTP id 5a478bee46e88-2ef2a1cc06dso1254253eec.0 for ; Wed, 13 May 2026 17:54:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=nexthop.ai; s=google; t=1778720070; x=1779324870; darn=vger.kernel.org; h=cc:to:message-id:content-transfer-encoding:mime-version:subject :date:from:from:to:cc:subject:date:message-id:reply-to; bh=BELW03wfNz2uc0F8K5d4Plbu0HoPLaDaE6GI8cbjIGU=; b=GC8pRs0gvYnBoau+iTo9L1PdMlhDcdPldCBtXuv7KwOtPfO30QGYXljCnVi9o7MCdV SQjJgJjdKE6XW3M/t/+GcOBmsyZnhwT+gjIFUf5Ex6wDpJNb/49SH1HT3YirT7V//dGS omIWm4XcXZDa9OyQmhAY1USUp92Ppc5UcCRu3j48spPoNpooJxp30Gdt0UJcSjvGm2nQ +Xf7aHiHMz5usfoQfhf7Zp0ayaYoy8eoHvkA9+YY6N2HCJBdKEVJgce4WH3PZyM08zaE HkkYBgvoFSEJb/yklPoEQDXTrTPUlef98B472z9gY4j6lOWNisVw7UJuAHqlA6oiF2BD J9fQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1778720070; x=1779324870; h=cc:to: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=BELW03wfNz2uc0F8K5d4Plbu0HoPLaDaE6GI8cbjIGU=; b=J9QY4ES5QkFWxdXE7GR8DSlvelhX8TUPliMi183HOEkfsdu+yLo6WmGyixVmdfXRZE NovX7nSOURIcvXau5cg9hVdUEExDLf+VEA2ESkkzqxQHEOpXN0+0a4llPps5g4yHtocy z05m7Ajbo1n4ocR0XO4t5usm3NXPNdXp/X9rC8SqnMN2QmB905m4OghLuIEznWhqW8av 6Jnuo9ebwP3wQp/V4qxT0xt66R6TfL/GabRv8nVL94JdmfhYge+43Dwi/TI852sxbaix 9LRKS9Htm4sb+BlcPKLQv/W6ztEw2Ge+TvEgBo9PmPYPnrFcusuyoMgjGfIW6V3wg9/a 1WYw== X-Forwarded-Encrypted: i=1; AFNElJ85X64lPVKCNfozBvNbgcUxZa0Mh98pHkGubrrH3wPNGahitUGY4Sy2mvXMgHpXIbFjisTdet/AblNXZMA=@vger.kernel.org X-Gm-Message-State: AOJu0YxZoSQOodtDdmHw6lCTHzOA1gBjyq32r5sWWdlGPW7LYXT18fw4 Y78mjiRwKMHIg+6tit/13IMLiWKKyikX0ecFC5GQ8hlbQBbeyiM4vl+n3/SIR4vGWSAQqfRykPR UPolvJfI= X-Gm-Gg: Acq92OGAEhTCdtdBQYJgCmaqPLFa5+gus0oNVSrvwZ30VS6H8Y+p+lkQwpORcUbxENG iLlsQ2CXj2K0TgkVObT5LsFED5Zotmqmr0sNC17ctw1gMAqeSjJcsXfQMlC8nmZvYmRZQfBi1Mt Q7uPRPUExPUr6r6WK09GXAlcZxUn0tIXyacKnLK59i4fTpDb54jsogJPt4Oi5ZoT+UeDjCvcP91 vEZMPIrlE5Bhaq6cjN/diic9bpQwqprzrw3MIDpBqwtTSo7LRSF2eXyYWuxaTfCOyvN8yX/QDpt EbTNfO713UogWdh+wAT5ZsJmUseLPo5LIyW7o0sijWIQCIvYIJ/a0SdkesuKDoIYMMMuJyNXlhS okVmgJlFCCO8gp0xbR2gh6Lo9s30CC/5r5xKaWcHdulhL6nw/V0Qx5x0T0C7X+oabv223fHH/bW pGyYB1/20v2ESdVqtpreJedr4yPw== X-Received: by 2002:a05:7301:2290:b0:2f5:5dd3:1fcf with SMTP id 5a478bee46e88-301185a953emr3607968eec.10.1778720069630; Wed, 13 May 2026 17:54:29 -0700 (PDT) Received: from [127.0.0.2] ([50.145.100.174]) by smtp.gmail.com with ESMTPSA id 5a478bee46e88-30296dcb6adsm1288218eec.15.2026.05.13.17.54.29 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 13 May 2026 17:54:29 -0700 (PDT) From: Abdurrahman Hussain Date: Wed, 13 May 2026 17:54:27 -0700 Subject: [PATCH v3] i2c: mux: reg: use device property accessors 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: quoted-printable Message-Id: <20260513-i2c-mux-reg-v3-1-0fa7242605bc@nexthop.ai> X-B4-Tracking: v=1; b=H4sIAEIdBWoC/1XOOw7CMBBF0a1ErjEaj2MLUbEPlGKIB+wiH00+C oqydxwogPIW7+itamBJPKhzsSrhOQ2pa3PYQ6HqSO2DdQq5FQJ6sOB0wlo306KFH9o5RLCBTs6 XKi964Xta3tq1yn2XrtFjFKavYYwDsA7tEb33oI2mW5hEKDbUXlpextj1R0q7F9MwdvJ8n5txV z+GM/j3Y8bMnIDJBCrrAPTrVNu2vQCpRjVe5wAAAA== X-Change-ID: 20260305-i2c-mux-reg-552203da8564 To: Peter Rosin Cc: linux-i2c@vger.kernel.org, linux-kernel@vger.kernel.org, Abdurrahman Hussain X-Mailer: b4 0.15.2 X-Developer-Signature: v=1; a=ed25519-sha256; t=1778720069; l=9590; i=abdurrahman@nexthop.ai; s=20260510; h=from:subject:message-id; bh=MzGODVa4DeGQU5C+cZnr92IEwH4cg6ZVCQfAWMsP+Ow=; b=iObh15q+RVHet8dZIpR2c0r2DJjpoQGMNIrbDZzTIF0bsG4uCwAQ1WO7rKOvYquyRm4yJmyie iwgHH2VGI5ICetTU/ckTUbhV7aoRLkYW45/EMs1TAkdnmhdgb2fmKej X-Developer-Key: i=abdurrahman@nexthop.ai; a=ed25519; pk=omTm9cCAbO0ZhS32aKfJDKue0W3sQGpG9ub5eYHif8I= Convert the device-tree parsing path to the generic fwnode/device property accessors so the driver can be probed on ACPI and swnode platforms as well as OF. The helper is renamed from i2c_mux_reg_probe_dt() to i2c_mux_reg_probe_fw() to reflect that. Accessor translation: of_parse_phandle("i2c-parent") + of_find_i2c_adapter_by_node() -> fwnode_find_reference() + i2c_get_adapter_by_fwnode() of_get_child_count() -> device_get_child_node_count() of_property_read_bool() -> device_property_read_bool() for_each_child_of_node() -> device_for_each_child_node() of_property_read_u32("reg") on OF: fwnode_property_read_u32() on ACPI: acpi_get_local_address() of_property_read_u32("idle-state") -> device_property_read_u32() Behavioural preservations (deliberate, to avoid regressing existing users): - The three-way endian fallback is kept verbatim: an explicit "little-endian" property wins, then "big-endian", and otherwise the host's compile-time byte order. device_is_big_endian() is not used here because it ignores "little-endian" and introduces "native-endian" semantics, which would diverge from the binding. - The platform-resource fallback for an un-mapped reg keeps its "if (!mux->data.reg)" guard so a platdata user that supplies a pre-ioremapped reg through struct i2c_mux_reg_platform_data is not clobbered. The OF-only of_address_to_resource() translation in the old probe_dt() is dropped because the same address is available from the platform_device resource table on both OF and ACPI, and the existing fallback in probe() ioremaps it. Signed-off-by: Abdurrahman Hussain --- - Restore the original __BYTE_ORDER preprocessor check for the endian-property fallback. v2 replaced it with IS_ENABLED(CONFIG_CPU_LITTLE_ENDIAN), but that Kconfig symbol is only defined on architectures with configurable endianness (arm, arm64, mips, ppc, sh, xtensa, microblaze). On architectures where endianness is fixed (x86, RISC-V, ...), the symbol is undefined, IS_ENABLED() silently evaluates to false, and the mux defaults to big-endian register writes. On a little-endian host that turns any non-zero channel selection into garbage and quietly breaks every slave behind the mux. - Replace put_device(&adapter->dev) with i2c_put_adapter(adapter). v1 switched from of_find_i2c_adapter_by_node() to i2c_get_adapter_by_fwnode(); the new helper additionally takes a try_module_get() on the adapter owner that put_device() alone does not release. This leaked a module reference on every successful probe. - Read swnode child "reg" properties via fwnode_property_read_u32(). The previous loop branched on is_of_node()/is_acpi_node() only; software nodes hit neither arm and silently left values[i] =3D 0, giving every swnode channel index 0 and breaking channel mapping on swnode platforms -- exactly the case the cover claims to add support for. i2c: mux: reg: use device property accessors Convert the device-tree parsing path in i2c-mux-reg to the generic fwnode/device property accessors so the driver can be probed on ACPI and swnode platforms in addition to OF. Changes in v2 (per Peter's review of v1 [1]): - Restore the three-way endian-property fallback verbatim. v1 used device_is_big_endian(), which ignores "little-endian" and adds "native-endian" semantics -- a binding-visible behaviour change on big-endian hosts that did not specify the property. v2 keeps the original logic ("little-endian" wins, then "big-endian", else the host's compile-time byte order), expressed via device_property_read_bool() instead of of_property_read_bool(). - Restore the "if (!mux->data.reg)" guard around devm_platform_get_and_ioremap_resource() in probe(). v1 dropped it and would have clobbered the pre-ioremapped reg supplied by a platdata user through struct i2c_mux_reg_platform_data. - Restore the dev_err_probe() wrapper at the probe_fw() call site so the silent error paths in the helper still produce a dmesg line on failure. - Rewrite the changelog to enumerate the accessor translations, the new ACPI child-node handling via acpi_get_local_address(), and the behavioural preservations above. [1] https://lore.kernel.org/r/20260115003523.26660-1-abdurrahman@nexthop.ai Link to v2: https://patch.msgid.link/20260512-i2c-mux-reg-v2-1-80ea1da4cd0a= @nexthop.ai --- drivers/i2c/muxes/i2c-mux-reg.c | 75 ++++++++++++++++++-------------------= ---- 1 file changed, 32 insertions(+), 43 deletions(-) diff --git a/drivers/i2c/muxes/i2c-mux-reg.c b/drivers/i2c/muxes/i2c-mux-re= g.c index 1e566ea92bc9..8b35a50e2841 100644 --- a/drivers/i2c/muxes/i2c-mux-reg.c +++ b/drivers/i2c/muxes/i2c-mux-reg.c @@ -11,7 +11,6 @@ #include #include #include -#include #include #include #include @@ -75,37 +74,34 @@ static int i2c_mux_reg_deselect(struct i2c_mux_core *mu= xc, u32 chan) return 0; } =20 -#ifdef CONFIG_OF -static int i2c_mux_reg_probe_dt(struct regmux *mux, - struct platform_device *pdev) +static int i2c_mux_reg_probe_fw(struct regmux *mux, struct device *dev) { - struct device_node *np =3D pdev->dev.of_node; - struct device_node *adapter_np, *child; + struct fwnode_handle *fwnode, *child; struct i2c_adapter *adapter; - struct resource res; unsigned *values; - int i =3D 0; + int ret, i =3D 0; =20 - if (!np) + if (!dev_fwnode(dev)) return -ENODEV; =20 - adapter_np =3D of_parse_phandle(np, "i2c-parent", 0); - if (!adapter_np) { - dev_err(&pdev->dev, "Cannot parse i2c-parent\n"); + fwnode =3D fwnode_find_reference(dev_fwnode(dev), "i2c-parent", 0); + if (IS_ERR(fwnode)) { + dev_err(dev, "missing 'i2c-parent' property\n"); return -ENODEV; } - adapter =3D of_find_i2c_adapter_by_node(adapter_np); - of_node_put(adapter_np); + + adapter =3D i2c_get_adapter_by_fwnode(fwnode); + fwnode_handle_put(fwnode); if (!adapter) return -EPROBE_DEFER; =20 mux->data.parent =3D i2c_adapter_id(adapter); - put_device(&adapter->dev); + i2c_put_adapter(adapter); =20 - mux->data.n_values =3D of_get_child_count(np); - if (of_property_read_bool(np, "little-endian")) { + mux->data.n_values =3D device_get_child_node_count(dev); + if (device_property_read_bool(dev, "little-endian")) { mux->data.little_endian =3D true; - } else if (of_property_read_bool(np, "big-endian")) { + } else if (device_property_read_bool(dev, "big-endian")) { mux->data.little_endian =3D false; } else { #if defined(__BYTE_ORDER) ? __BYTE_ORDER =3D=3D __LITTLE_ENDIAN : \ @@ -118,40 +114,35 @@ static int i2c_mux_reg_probe_dt(struct regmux *mux, #error Endianness not defined? #endif } - mux->data.write_only =3D of_property_read_bool(np, "write-only"); + mux->data.write_only =3D device_property_read_bool(dev, "write-only"); =20 - values =3D devm_kcalloc(&pdev->dev, - mux->data.n_values, sizeof(*mux->data.values), + values =3D devm_kcalloc(dev, mux->data.n_values, sizeof(*mux->data.values= ), GFP_KERNEL); if (!values) return -ENOMEM; =20 - for_each_child_of_node(np, child) { - of_property_read_u32(child, "reg", values + i); + device_for_each_child_node(dev, child) { + if (is_acpi_node(child)) { + ret =3D acpi_get_local_address(ACPI_HANDLE_FWNODE(child), + &values[i]); + if (ret) { + fwnode_handle_put(child); + return dev_err_probe(dev, ret, + "Cannot get address\n"); + } + } else { + fwnode_property_read_u32(child, "reg", &values[i]); + } + i++; } mux->data.values =3D values; =20 - if (!of_property_read_u32(np, "idle-state", &mux->data.idle)) + if (!device_property_read_u32(dev, "idle-state", &mux->data.idle)) mux->data.idle_in_use =3D true; =20 - /* map address from "reg" if exists */ - if (of_address_to_resource(np, 0, &res) =3D=3D 0) { - mux->data.reg_size =3D resource_size(&res); - mux->data.reg =3D devm_ioremap_resource(&pdev->dev, &res); - if (IS_ERR(mux->data.reg)) - return PTR_ERR(mux->data.reg); - } - return 0; } -#else -static int i2c_mux_reg_probe_dt(struct regmux *mux, - struct platform_device *pdev) -{ - return 0; -} -#endif =20 static int i2c_mux_reg_probe(struct platform_device *pdev) { @@ -169,10 +160,10 @@ static int i2c_mux_reg_probe(struct platform_device *= pdev) memcpy(&mux->data, dev_get_platdata(&pdev->dev), sizeof(mux->data)); } else { - ret =3D i2c_mux_reg_probe_dt(mux, pdev); + ret =3D i2c_mux_reg_probe_fw(mux, &pdev->dev); if (ret < 0) return dev_err_probe(&pdev->dev, ret, - "Error parsing device tree"); + "Error parsing firmware description\n"); } =20 parent =3D i2c_get_adapter(mux->data.parent); @@ -180,8 +171,6 @@ static int i2c_mux_reg_probe(struct platform_device *pd= ev) return -EPROBE_DEFER; =20 if (!mux->data.reg) { - dev_info(&pdev->dev, - "Register not set, using platform resource\n"); mux->data.reg =3D devm_platform_get_and_ioremap_resource(pdev, 0, &res); if (IS_ERR(mux->data.reg)) { ret =3D PTR_ERR(mux->data.reg); --- base-commit: 254f49634ee16a731174d2ae34bc50bd5f45e731 change-id: 20260305-i2c-mux-reg-552203da8564 Best regards, -- =20 Abdurrahman Hussain