* [PATCH v3 0/2] i2c: cadence: Add support for Axiado AX3000
@ 2026-07-01 4:48 Swark Yang
2026-07-01 4:48 ` [PATCH v3 1/2] dt-bindings: i2c: cadence: Add " Swark Yang
2026-07-01 4:48 ` [PATCH v3 2/2] i2c: cadence: Add support for " Swark Yang
0 siblings, 2 replies; 5+ messages in thread
From: Swark Yang @ 2026-07-01 4:48 UTC (permalink / raw)
To: Michal Simek, Andi Shyti, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: linux-arm-kernel, linux-i2c, devicetree, linux-kernel, openbmc,
Swark Yang, Conor Dooley
This patch series adds support for the Cadence I2C controller
integrated into the Axiado AX3000 SoC and enables SMBus Quick
command functionality.
The Axiado AX3000 utilizes the Cadence I2C IP core (version r1p14).
While it is largely compatible with the existing i2c-cadence
driver logic, the AX3000 hardware specifically supports SMBus Quick
commands. This feature is currently disabled by default in the
i2c-cadence driver (masked out from I2C_FUNC_SMBUS_EMUL).
To enable this functionality, this series introduces a new
platform-specific quirk (CDNS_I2C_ENABLE_SMBUS_QUICK) and
uses driver match data for the "axiado,ax3000-i2c" compatible string.
This allows tools like 'i2cdetect' to properly scan the bus using
quick write commands.
The DT binding update follows the recommended fallback structure,
referencing the 'cdns,i2c-r1p14' fallback to ensure compatibility with
older kernels while allowing the new quirk to be enabled on AX3000.
Patch breakdown:
Patch 1: dt-bindings: i2c: cadence: Add Axiado AX3000
Patch 2: i2c: cadence: Add support for Axiado AX3000
These patches are expected to go via the I2C subsystem tree.
Feedback is welcome.
Signed-off-by: Swark Yang <syang@axiado.com>
---
Changes in v3:
- Addressed Sashiko AI bot report: Populated adapter quirks with I2C_AQ_NO_ZERO_LEN_READ to safely reject 0-length reads and prevent potential bus hangs.
- Note on AI review: The bot also reported a pre-existing UAF vulnerability triggered by 0-length reads. Since this v3 patch prevents the core from passing 0-length reads to the driver, this specific trigger path is mitigated for AX3000. Atomic transfer issues are left out of scope for this hardware enablement series.
- Renamed the quirk macro to CDNS_I2C_ENABLE_SMBUS_QUICK for consistency.
- Link to v2: https://lore.kernel.org/r/20260611-axiado-ax3000-cadence-i2c-support-v2-0-cfdad0534afa@axiado.com
Changes in v2:
- Collected Conor Dooley's Acked-by for Patch 1.
- No functional code changes (sent primarily as a RESEND to update status).
- Link to v1: https://lore.kernel.org/r/20260504-axiado-ax3000-cadence-i2c-support-v1-0-97ed2fdc0b7b@axiado.com
---
Swark Yang (2):
dt-bindings: i2c: cadence: Add Axiado AX3000
i2c: cadence: Add support for Axiado AX3000
.../devicetree/bindings/i2c/cdns,i2c-r1p10.yaml | 10 +++++++---
drivers/i2c/busses/i2c-cadence.c | 23 ++++++++++++++++++++++
2 files changed, 30 insertions(+), 3 deletions(-)
---
base-commit: 63804fed149a6750ffd28610c5c1c98cce6bd377
change-id: 20260111-axiado-ax3000-cadence-i2c-support-53ec117bb074
Best regards,
--
Swark Yang <syang@axiado.com>
^ permalink raw reply [flat|nested] 5+ messages in thread
* [PATCH v3 1/2] dt-bindings: i2c: cadence: Add Axiado AX3000
2026-07-01 4:48 [PATCH v3 0/2] i2c: cadence: Add support for Axiado AX3000 Swark Yang
@ 2026-07-01 4:48 ` Swark Yang
2026-07-01 4:48 ` [PATCH v3 2/2] i2c: cadence: Add support for " Swark Yang
1 sibling, 0 replies; 5+ messages in thread
From: Swark Yang @ 2026-07-01 4:48 UTC (permalink / raw)
To: Michal Simek, Andi Shyti, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: linux-arm-kernel, linux-i2c, devicetree, linux-kernel, openbmc,
Swark Yang, Conor Dooley
The Axiado AX3000 SoC integrates the Cadence I2C controller.
Add a specific compatible string "axiado,ax3000-i2c" to support
its hardware features, including SMBus Quick command capability.
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Swark Yang <syang@axiado.com>
---
Documentation/devicetree/bindings/i2c/cdns,i2c-r1p10.yaml | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/i2c/cdns,i2c-r1p10.yaml b/Documentation/devicetree/bindings/i2c/cdns,i2c-r1p10.yaml
index 9f1d35ce1fe8..de2110376a3f 100644
--- a/Documentation/devicetree/bindings/i2c/cdns,i2c-r1p10.yaml
+++ b/Documentation/devicetree/bindings/i2c/cdns,i2c-r1p10.yaml
@@ -14,9 +14,13 @@ allOf:
properties:
compatible:
- enum:
- - cdns,i2c-r1p10 # cadence i2c controller version 1.0
- - cdns,i2c-r1p14 # cadence i2c controller version 1.4
+ oneOf:
+ - items:
+ - const: axiado,ax3000-i2c
+ - const: cdns,i2c-r1p14
+ - enum:
+ - cdns,i2c-r1p10 # cadence i2c controller version 1.0
+ - cdns,i2c-r1p14 # cadence i2c controller version 1.4
reg:
maxItems: 1
--
2.34.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* [PATCH v3 2/2] i2c: cadence: Add support for Axiado AX3000
2026-07-01 4:48 [PATCH v3 0/2] i2c: cadence: Add support for Axiado AX3000 Swark Yang
2026-07-01 4:48 ` [PATCH v3 1/2] dt-bindings: i2c: cadence: Add " Swark Yang
@ 2026-07-01 4:48 ` Swark Yang
2026-07-01 4:58 ` sashiko-bot
2026-07-02 6:35 ` Michal Simek
1 sibling, 2 replies; 5+ messages in thread
From: Swark Yang @ 2026-07-01 4:48 UTC (permalink / raw)
To: Michal Simek, Andi Shyti, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: linux-arm-kernel, linux-i2c, devicetree, linux-kernel, openbmc,
Swark Yang
The Axiado AX3000 SoC integrates a Cadence I2C controller
that supports SMBus Quick commands.
Introduce the "axiado,ax3000-i2c" compatible string and
add a new quirk CDNS_I2C_ENABLE_SMBUS_QUICK to enable
this functionality. This allows the controller to support
I2C_FUNC_SMBUS_QUICK, enabling features such as bus scanning
via quick write commands.
Additionally, enabling SMBus Quick emulation in the I2C core exposes
the controller to potential 0-length reads. Because the Cadence IP
does not natively support 0-length reads (writing 0 to the transfer
size register leaves the hardware in an unsupported state), this patch
also populates the adapter quirks with I2C_AQ_NO_ZERO_LEN_READ.
This ensures 0-length reads are safely rejected by the core, preventing
potential bus hangs.
Signed-off-by: Swark Yang <syang@axiado.com>
---
drivers/i2c/busses/i2c-cadence.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c
index 0fb728ade92e..1964ea1650c5 100644
--- a/drivers/i2c/busses/i2c-cadence.c
+++ b/drivers/i2c/busses/i2c-cadence.c
@@ -128,6 +128,7 @@
#define CDNS_I2C_TIMEOUT_MAX 0xFF
#define CDNS_I2C_BROKEN_HOLD_BIT BIT(0)
+#define CDNS_I2C_ENABLE_SMBUS_QUICK BIT(1)
#define CDNS_I2C_POLL_US 100000
#define CDNS_I2C_POLL_US_ATOMIC 10
#define CDNS_I2C_TIMEOUT_US 500000
@@ -1175,10 +1176,14 @@ static int cdns_i2c_master_xfer_atomic(struct i2c_adapter *adap, struct i2c_msg
*/
static u32 cdns_i2c_func(struct i2c_adapter *adap)
{
+ struct cdns_i2c *id = adap->algo_data;
u32 func = I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR |
(I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK) |
I2C_FUNC_SMBUS_BLOCK_DATA;
+ if (id->quirks & CDNS_I2C_ENABLE_SMBUS_QUICK)
+ func |= I2C_FUNC_SMBUS_QUICK;
+
#if IS_ENABLED(CONFIG_I2C_SLAVE)
func |= I2C_FUNC_SLAVE;
#endif
@@ -1442,9 +1447,24 @@ static const struct cdns_platform_data r1p10_i2c_def = {
.quirks = CDNS_I2C_BROKEN_HOLD_BIT,
};
+static const struct cdns_platform_data ax3000_i2c_def = {
+ .quirks = CDNS_I2C_ENABLE_SMBUS_QUICK,
+};
+
+/*
+ * The controller does not support zero-length reads. Enabling SMBus Quick
+ * commands would otherwise let the core emulate a Quick read as a zero-length
+ * read message, which writes 0 to the transfer size register and leaves the
+ * hardware in an unsupported state. Reject such transfers in the core.
+ */
+static const struct i2c_adapter_quirks cdns_i2c_quirks = {
+ .flags = I2C_AQ_NO_ZERO_LEN_READ,
+};
+
static const struct of_device_id cdns_i2c_of_match[] = {
{ .compatible = "cdns,i2c-r1p10", .data = &r1p10_i2c_def },
{ .compatible = "cdns,i2c-r1p14",},
+ { .compatible = "axiado,ax3000-i2c", .data = &ax3000_i2c_def },
{ /* end of table */ }
};
MODULE_DEVICE_TABLE(of, cdns_i2c_of_match);
@@ -1510,6 +1530,9 @@ static int cdns_i2c_probe(struct platform_device *pdev)
id->quirks = data->quirks;
}
+ if (id->quirks & CDNS_I2C_ENABLE_SMBUS_QUICK)
+ id->adap.quirks = &cdns_i2c_quirks;
+
id->rinfo.pinctrl = devm_pinctrl_get(&pdev->dev);
if (IS_ERR(id->rinfo.pinctrl)) {
int err = PTR_ERR(id->rinfo.pinctrl);
--
2.34.1
^ permalink raw reply related [flat|nested] 5+ messages in thread
* Re: [PATCH v3 2/2] i2c: cadence: Add support for Axiado AX3000
2026-07-01 4:48 ` [PATCH v3 2/2] i2c: cadence: Add support for " Swark Yang
@ 2026-07-01 4:58 ` sashiko-bot
2026-07-02 6:35 ` Michal Simek
1 sibling, 0 replies; 5+ messages in thread
From: sashiko-bot @ 2026-07-01 4:58 UTC (permalink / raw)
To: Swark Yang; +Cc: conor+dt, robh, devicetree
Thank you for your contribution! Sashiko AI review found 3 potential issue(s) to consider:
Pre-existing issues:
- [High] The I2C_AQ_NO_ZERO_LEN_READ adapter quirk is conditionally applied only when CDNS_I2C_ENABLE_SMBUS_QUICK is set, leaving all other Cadence I2C controllers vulnerable to unprivileged hardware hangs triggered by 0-length reads.
- [High] Atomic mode transfers completely bypass error checking for short messages, silently ignoring NACKs and incorrectly reporting success.
- [High] Incorrect teardown order in `cdns_i2c_remove` disables runtime PM before unregistering the I2C adapter, preventing client devices from communicating during removal.
--
commit 64d28f7fd176831d6ec144e8d435ebe00982b497
Author: Swark Yang <syang@axiado.com>
i2c: cadence: Add support for Axiado AX3000
The Axiado AX3000 SoC integrates a Cadence I2C controller that supports
SMBus Quick commands. This introduces the compatible string and a quirk
to enable this functionality. It also adds I2C_AQ_NO_ZERO_LEN_READ to
prevent hardware hangs from 0-length reads.
> diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c
> index 0fb728ade92e4..1964ea1650c59 100644
> --- a/drivers/i2c/busses/i2c-cadence.c
> +++ b/drivers/i2c/busses/i2c-cadence.c
[ ... ]
> @@ -1175,10 +1176,14 @@ static int cdns_i2c_master_xfer_atomic(struct i2c_adapter *adap, struct i2c_msg
> */
> static u32 cdns_i2c_func(struct i2c_adapter *adap)
> {
> + struct cdns_i2c *id = adap->algo_data;
> u32 func = I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR |
> (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK) |
> I2C_FUNC_SMBUS_BLOCK_DATA;
>
> + if (id->quirks & CDNS_I2C_ENABLE_SMBUS_QUICK)
> + func |= I2C_FUNC_SMBUS_QUICK;
> +
[Severity: High]
This is a pre-existing issue, but enabling SMBus Quick exposes a bug in
atomic transfers where short messages bypass error checking.
When performing a short write in atomic mode (like an SMBus Quick write
for bus scanning), cdns_i2c_msend() writes data to the FIFO and decrements
id->send_count to 0. This bypasses cdns_i2c_msend_rem_atomic(), which means
cdns_i2c_error_check() is never invoked.
cdns_i2c_process_msg() then polls for the completion bit but fails to
verify the NACK error bits because id->err_status was not updated.
Does this completely break atomic bus scanning, since all polled addresses
will falsely appear to exist and ACK? Furthermore, if the hardware does not
set the completion bit on a NACK, could the polling loop hit its maximum
timeout in atomic context for every NACKed address, leading to stalls?
> #if IS_ENABLED(CONFIG_I2C_SLAVE)
> func |= I2C_FUNC_SLAVE;
> #endif
[ ... ]
> @@ -1510,6 +1530,9 @@ static int cdns_i2c_probe(struct platform_device *pdev)
> id->quirks = data->quirks;
> }
>
> + if (id->quirks & CDNS_I2C_ENABLE_SMBUS_QUICK)
> + id->adap.quirks = &cdns_i2c_quirks;
> +
[Severity: High]
This isn't a bug introduced by this patch, but should the 0-length read
quirk be applied unconditionally to all Cadence controllers?
The commit message notes that writing 0 to the transfer size register leaves
the hardware in an unsupported state. As written, the quirk is conditionally
applied only when CDNS_I2C_ENABLE_SMBUS_QUICK is set.
Does this leave other Cadence I2C controllers (like legacy Zynq platforms)
vulnerable to unprivileged hardware hangs triggered by 0-length reads via
the I2C_RDWR ioctl?
[Severity: High]
This is another pre-existing issue, but there appears to be an incorrect
teardown order in cdns_i2c_remove() that prevents client devices from
communicating during removal:
drivers/i2c/busses/i2c-cadence.c:cdns_i2c_remove() {
...
pm_runtime_disable(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
pm_runtime_dont_use_autosuspend(&pdev->dev);
i2c_del_adapter(&id->adap);
...
}
Because runtime PM is disabled before unregistering the adapter and its
child devices, any child driver's remove callback that performs I2C
transfers to quiesce the hardware will fail. The transfer invokes
cdns_i2c_master_xfer(), which calls pm_runtime_resume_and_get(). Since
runtime PM is already disabled, this returns -EACCES.
Could this prevent clean module unloads or suspend by leaving hardware in a
bad state?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260630-axiado-ax3000-cadence-i2c-support-v3-0-4e217cfe5904@axiado.com?part=2
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [PATCH v3 2/2] i2c: cadence: Add support for Axiado AX3000
2026-07-01 4:48 ` [PATCH v3 2/2] i2c: cadence: Add support for " Swark Yang
2026-07-01 4:58 ` sashiko-bot
@ 2026-07-02 6:35 ` Michal Simek
1 sibling, 0 replies; 5+ messages in thread
From: Michal Simek @ 2026-07-02 6:35 UTC (permalink / raw)
To: Swark Yang, Andi Shyti, Rob Herring, Krzysztof Kozlowski,
Conor Dooley
Cc: linux-arm-kernel, linux-i2c, devicetree, linux-kernel, openbmc
On 7/1/26 06:48, Swark Yang wrote:
> The Axiado AX3000 SoC integrates a Cadence I2C controller
> that supports SMBus Quick commands.
>
> Introduce the "axiado,ax3000-i2c" compatible string and
> add a new quirk CDNS_I2C_ENABLE_SMBUS_QUICK to enable
> this functionality. This allows the controller to support
> I2C_FUNC_SMBUS_QUICK, enabling features such as bus scanning
> via quick write commands.
>
> Additionally, enabling SMBus Quick emulation in the I2C core exposes
> the controller to potential 0-length reads. Because the Cadence IP
> does not natively support 0-length reads (writing 0 to the transfer
> size register leaves the hardware in an unsupported state), this patch
> also populates the adapter quirks with I2C_AQ_NO_ZERO_LEN_READ.
nit: Avoid "this patch". Just use ", populate ..."
> This ensures 0-length reads are safely rejected by the core, preventing
> potential bus hangs.
>
> Signed-off-by: Swark Yang <syang@axiado.com>
> ---
> drivers/i2c/busses/i2c-cadence.c | 23 +++++++++++++++++++++++
> 1 file changed, 23 insertions(+)
>
> diff --git a/drivers/i2c/busses/i2c-cadence.c b/drivers/i2c/busses/i2c-cadence.c
> index 0fb728ade92e..1964ea1650c5 100644
> --- a/drivers/i2c/busses/i2c-cadence.c
> +++ b/drivers/i2c/busses/i2c-cadence.c
> @@ -128,6 +128,7 @@
> #define CDNS_I2C_TIMEOUT_MAX 0xFF
>
> #define CDNS_I2C_BROKEN_HOLD_BIT BIT(0)
> +#define CDNS_I2C_ENABLE_SMBUS_QUICK BIT(1)
> #define CDNS_I2C_POLL_US 100000
> #define CDNS_I2C_POLL_US_ATOMIC 10
> #define CDNS_I2C_TIMEOUT_US 500000
> @@ -1175,10 +1176,14 @@ static int cdns_i2c_master_xfer_atomic(struct i2c_adapter *adap, struct i2c_msg
> */
> static u32 cdns_i2c_func(struct i2c_adapter *adap)
> {
> + struct cdns_i2c *id = adap->algo_data;
> u32 func = I2C_FUNC_I2C | I2C_FUNC_10BIT_ADDR |
> (I2C_FUNC_SMBUS_EMUL & ~I2C_FUNC_SMBUS_QUICK) |
> I2C_FUNC_SMBUS_BLOCK_DATA;
>
> + if (id->quirks & CDNS_I2C_ENABLE_SMBUS_QUICK)
> + func |= I2C_FUNC_SMBUS_QUICK;
> +
> #if IS_ENABLED(CONFIG_I2C_SLAVE)
> func |= I2C_FUNC_SLAVE;
> #endif
> @@ -1442,9 +1447,24 @@ static const struct cdns_platform_data r1p10_i2c_def = {
> .quirks = CDNS_I2C_BROKEN_HOLD_BIT,
> };
>
> +static const struct cdns_platform_data ax3000_i2c_def = {
> + .quirks = CDNS_I2C_ENABLE_SMBUS_QUICK,
> +};
> +
> +/*
> + * The controller does not support zero-length reads. Enabling SMBus Quick
> + * commands would otherwise let the core emulate a Quick read as a zero-length
> + * read message, which writes 0 to the transfer size register and leaves the
> + * hardware in an unsupported state. Reject such transfers in the core.
> + */
> +static const struct i2c_adapter_quirks cdns_i2c_quirks = {
> + .flags = I2C_AQ_NO_ZERO_LEN_READ,
> +};
> +
> static const struct of_device_id cdns_i2c_of_match[] = {
> { .compatible = "cdns,i2c-r1p10", .data = &r1p10_i2c_def },
> { .compatible = "cdns,i2c-r1p14",},
> + { .compatible = "axiado,ax3000-i2c", .data = &ax3000_i2c_def },
> { /* end of table */ }
> };
> MODULE_DEVICE_TABLE(of, cdns_i2c_of_match);
> @@ -1510,6 +1530,9 @@ static int cdns_i2c_probe(struct platform_device *pdev)
> id->quirks = data->quirks;
> }
>
> + if (id->quirks & CDNS_I2C_ENABLE_SMBUS_QUICK)
> + id->adap.quirks = &cdns_i2c_quirks;
> +
> id->rinfo.pinctrl = devm_pinctrl_get(&pdev->dev);
> if (IS_ERR(id->rinfo.pinctrl)) {
> int err = PTR_ERR(id->rinfo.pinctrl);
>
Wiring looks good to me.
Acked-by: Michal Simek <michal.simek@amd.com>
Thanks,
Michal
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2026-07-02 6:35 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-01 4:48 [PATCH v3 0/2] i2c: cadence: Add support for Axiado AX3000 Swark Yang
2026-07-01 4:48 ` [PATCH v3 1/2] dt-bindings: i2c: cadence: Add " Swark Yang
2026-07-01 4:48 ` [PATCH v3 2/2] i2c: cadence: Add support for " Swark Yang
2026-07-01 4:58 ` sashiko-bot
2026-07-02 6:35 ` Michal Simek
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox