* [PATCH v7 0/2] i2c: ls2x: Add clock- related properties and parsing
@ 2026-07-07 3:51 Hongliang Wang
2026-07-07 3:51 ` [PATCH v7 1/2] dt-bindings: i2c: ls2x-i2c: Add clocks and clock-frequency properties Hongliang Wang
2026-07-07 3:51 ` [PATCH v7 2/2] i2c: ls2x: Add clocks property parsing and adjust bus speed Hongliang Wang
0 siblings, 2 replies; 4+ messages in thread
From: Hongliang Wang @ 2026-07-07 3:51 UTC (permalink / raw)
To: Hongliang Wang, Binbin Zhou, Andi Shyti, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Wolfram Sang
Cc: linux-i2c, devicetree, loongarch
Hi all:
This patch set adds clock related properties and parsing in dts and acpi.
======
V7:
Patch (2/2):
Fix the potential issues from Sashiko AI review:
- Move the clock property parsing process to probe function to solve the issue
of calling `devm_clk_get_optional_enabled()` dynamically causes unbounded memory
leaks and unbalanced clock enable counts.
- Add non-zero checking to priv->div.
Link to V6:
https://lore.kernel.org/all/20260608024533.32419-1-wanghongliang@loongson.cn/
V6:
- Add Reviewed-by tag from Huacai, thanks.
Patch (1/2):
- Remove CC stable.
Link to V5:
https://lore.kernel.org/all/20260604015848.18643-1-wanghongliang@loongson.cn/
V5:
Patch (1/2):
- Adjust the position of #include <dt-bindings/clock/loongson,ls2k-clk.h>;
- Add CC stable;
- Fix Signed-off-by.
Patch (2/2):
- Replace 2K0500/2K1000/2K2000 with LS2K0500/2K1000/2K2000;
- Replace 7A1000/7A2000 with LS7A1000/7A2000;
- Replace if (clk && !IS_ERR(clk)) with if(!IS_ERR_OR_NULL(clk));
- Add document that clocks and clock-div are only ACPI properties in ACPI;
- Remove unsigned int cast in code (unsigned long)device_get_match_data(dev);
- Add CC stable;
- Fix Signed-off-by.
Link to V4:
https://lore.kernel.org/all/20260526031021.32662-1-wanghongliang@loongson.cn/
V4:
- Add Acked-by tag from Conor Dooley, thanks.
Patch (2/2):
- Adjust the position of #include <linux/clk.h>;
- Remove struct ls2x_i2c_chip_data and use macro to describe div;
- Use div instead of factor in ls2x_i2c_adjust_bus_speed;
- Reverse the "if & else" code logic in ls2x_i2c_adjust_bus_speed;
Link to V2:
The PATCH v3 is incomplete, v4 is the replacement of v3, so the previous patch link is v2.
[PATCH v2] dt-bindings: i2c: ls2x-i2c: Add clocks and clock-frequency properties
https://lore.kernel.org/all/20260507081010.12810-1-wanghongliang@loongson.cn/
[PATCH v2] i2c: ls2x: Add clocks property parsing and adjust bus speed
https://lore.kernel.org/all/20260507081010.12810-2-wanghongliang@loongson.cn/
V2:
[PATCH v2] dt-bindings: i2c: ls2x-i2c: Add clocks and clock-frequency properties
- Remove the custom properties clock-input and clock-div, use clock framework;
[PATCH v2] i2c: ls2x: Add clocks property parsing and adjust bus speed
- Use clock framework to obtain the i2c reference clock in dts.
Link to V1:
https://lore.kernel.org/all/20260325011852.19079-1-wanghongliang@loongson.cn/
Hongliang Wang (2):
dt-bindings: i2c: ls2x-i2c: Add clocks and clock-frequency properties
i2c: ls2x: Add clocks property parsing and adjust bus speed
.../bindings/i2c/loongson,ls2x-i2c.yaml | 3 ++
drivers/i2c/busses/i2c-ls2x.c | 36 +++++++++++++++++--
2 files changed, 36 insertions(+), 3 deletions(-)
--
2.47.2
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH v7 1/2] dt-bindings: i2c: ls2x-i2c: Add clocks and clock-frequency properties
2026-07-07 3:51 [PATCH v7 0/2] i2c: ls2x: Add clock- related properties and parsing Hongliang Wang
@ 2026-07-07 3:51 ` Hongliang Wang
2026-07-07 3:51 ` [PATCH v7 2/2] i2c: ls2x: Add clocks property parsing and adjust bus speed Hongliang Wang
1 sibling, 0 replies; 4+ messages in thread
From: Hongliang Wang @ 2026-07-07 3:51 UTC (permalink / raw)
To: Hongliang Wang, Binbin Zhou, Andi Shyti, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Wolfram Sang
Cc: linux-i2c, devicetree, loongarch, Huacai Chen, Conor Dooley
Add clocks and clock-frequency properties to examples.
Reviewed-by: Huacai Chen <chenhuacai@loongson.cn>
Acked-by: Conor Dooley <conor.dooley@microchip.com>
Signed-off-by: Hongliang Wang <wanghongliang@loongson.cn>
---
Documentation/devicetree/bindings/i2c/loongson,ls2x-i2c.yaml | 3 +++
1 file changed, 3 insertions(+)
diff --git a/Documentation/devicetree/bindings/i2c/loongson,ls2x-i2c.yaml b/Documentation/devicetree/bindings/i2c/loongson,ls2x-i2c.yaml
index ee09c6d9c5f0..0beb7f2515c8 100644
--- a/Documentation/devicetree/bindings/i2c/loongson,ls2x-i2c.yaml
+++ b/Documentation/devicetree/bindings/i2c/loongson,ls2x-i2c.yaml
@@ -37,11 +37,14 @@ unevaluatedProperties: false
examples:
- |
+ #include <dt-bindings/clock/loongson,ls2k-clk.h>
#include <dt-bindings/interrupt-controller/irq.h>
i2c0: i2c@1fe21000 {
compatible = "loongson,ls2k-i2c";
reg = <0x1fe21000 0x8>;
+ clock-frequency = <100000>;
+ clocks = <&clk LOONGSON2_APB_CLK>;
interrupt-parent = <&extioiic>;
interrupts = <22 IRQ_TYPE_LEVEL_LOW>;
#address-cells = <1>;
--
2.47.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH v7 2/2] i2c: ls2x: Add clocks property parsing and adjust bus speed
2026-07-07 3:51 [PATCH v7 0/2] i2c: ls2x: Add clock- related properties and parsing Hongliang Wang
2026-07-07 3:51 ` [PATCH v7 1/2] dt-bindings: i2c: ls2x-i2c: Add clocks and clock-frequency properties Hongliang Wang
@ 2026-07-07 3:51 ` Hongliang Wang
2026-07-07 4:00 ` sashiko-bot
1 sibling, 1 reply; 4+ messages in thread
From: Hongliang Wang @ 2026-07-07 3:51 UTC (permalink / raw)
To: Hongliang Wang, Binbin Zhou, Andi Shyti, Rob Herring,
Krzysztof Kozlowski, Conor Dooley, Wolfram Sang
Cc: linux-i2c, devicetree, loongarch, Huacai Chen, stable
The i2c-ls2x driver supports dts and acpi parameter passing.
In dts, uses clock framework, by parsing clocks property to
get i2c bus reference clock, and define the div of reference
clock by device data.
In acpi, by passing clocks property to describe i2c bus reference
clock and clock-div property to describe the div of reference clock.
Based on i2c bus reference clock(clock_a), i2c bus speed(clock_s)
and div, calculate the prcescale of i2c divider register. The
calculation formula is
prcescale = (clock_a*10)/(div*clock_s)-1
Reviewed-by: Huacai Chen <chenhuacai@loongson.cn>
Cc: stable@vger.kernel.org
Signed-off-by: Hongliang Wang <wanghongliang@loongson.cn>
---
drivers/i2c/busses/i2c-ls2x.c | 36 ++++++++++++++++++++++++++++++++---
1 file changed, 33 insertions(+), 3 deletions(-)
diff --git a/drivers/i2c/busses/i2c-ls2x.c b/drivers/i2c/busses/i2c-ls2x.c
index b475dd27b7af..18b79dc759bf 100644
--- a/drivers/i2c/busses/i2c-ls2x.c
+++ b/drivers/i2c/busses/i2c-ls2x.c
@@ -12,6 +12,7 @@
#include <linux/bitfield.h>
#include <linux/bits.h>
+#include <linux/clk.h>
#include <linux/completion.h>
#include <linux/device.h>
#include <linux/iopoll.h>
@@ -63,11 +64,19 @@
/* The default bus frequency, which is an empirical value */
#define LS2X_I2C_FREQ_STD (33 * HZ_PER_KHZ)
+/* The div of i2c reference clock on LS2K0500/2K1000/2K2000 */
+#define LS2X_I2C_2K_CLOCK_DIV 40
+
+/* The div of i2c reference clock on LS7A1000/7A2000 */
+#define LS2X_I2C_7A_CLOCK_DIV 50
+
struct ls2x_i2c_priv {
struct i2c_adapter adapter;
void __iomem *base;
struct i2c_timings i2c_t;
struct completion cmd_complete;
+ unsigned int div;
+ unsigned int pclk;
};
/*
@@ -107,12 +116,13 @@ static void ls2x_i2c_adjust_bus_speed(struct ls2x_i2c_priv *priv)
else
t->bus_freq_hz = LS2X_I2C_FREQ_STD;
+ val = (priv->pclk * 10) / (priv->div * t->bus_freq_hz) - 1;
+
/*
* According to the chip manual, we can only access the registers as bytes,
* otherwise the high bits will be truncated.
* So set the I2C frequency with a sequential writeb() instead of writew().
*/
- val = LS2X_I2C_PCLK_FREQ / (5 * t->bus_freq_hz) - 1;
writeb(FIELD_GET(GENMASK(7, 0), val), priv->base + I2C_LS2X_PRER_LO);
writeb(FIELD_GET(GENMASK(15, 8), val), priv->base + I2C_LS2X_PRER_HI);
}
@@ -287,6 +297,7 @@ static const struct i2c_algorithm ls2x_i2c_algo = {
static int ls2x_i2c_probe(struct platform_device *pdev)
{
int ret, irq;
+ struct clk *clk;
struct i2c_adapter *adap;
struct ls2x_i2c_priv *priv;
struct device *dev = &pdev->dev;
@@ -304,6 +315,25 @@ static int ls2x_i2c_probe(struct platform_device *pdev)
if (irq < 0)
return irq;
+ if (dev_of_node(dev)) {
+ clk = devm_clk_get_optional_enabled(dev, NULL);
+ if (!IS_ERR_OR_NULL(clk))
+ priv->pclk = clk_get_rate(clk);
+ else
+ priv->pclk = LS2X_I2C_PCLK_FREQ;
+
+ priv->div = (unsigned long)device_get_match_data(dev);
+ } else {
+ /* clocks and clock-div are only ACPI properties. */
+ ret = device_property_read_u32(dev, "clocks", &priv->pclk);
+ if (ret)
+ priv->pclk = LS2X_I2C_PCLK_FREQ;
+
+ ret = device_property_read_u32(dev, "clock-div", &priv->div);
+ if (ret || !priv->div)
+ priv->div = LS2X_I2C_7A_CLOCK_DIV;
+ }
+
/* Add the i2c adapter */
adap = &priv->adapter;
adap->retries = 5;
@@ -349,8 +379,8 @@ static DEFINE_RUNTIME_DEV_PM_OPS(ls2x_i2c_pm_ops,
ls2x_i2c_suspend, ls2x_i2c_resume, NULL);
static const struct of_device_id ls2x_i2c_id_table[] = {
- { .compatible = "loongson,ls2k-i2c" },
- { .compatible = "loongson,ls7a-i2c" },
+ { .compatible = "loongson,ls2k-i2c", .data = (void *)LS2X_I2C_2K_CLOCK_DIV, },
+ { .compatible = "loongson,ls7a-i2c", .data = (void *)LS2X_I2C_7A_CLOCK_DIV, },
{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, ls2x_i2c_id_table);
--
2.47.2
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH v7 2/2] i2c: ls2x: Add clocks property parsing and adjust bus speed
2026-07-07 3:51 ` [PATCH v7 2/2] i2c: ls2x: Add clocks property parsing and adjust bus speed Hongliang Wang
@ 2026-07-07 4:00 ` sashiko-bot
0 siblings, 0 replies; 4+ messages in thread
From: sashiko-bot @ 2026-07-07 4:00 UTC (permalink / raw)
To: Hongliang Wang; +Cc: conor+dt, robh, devicetree
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
New issues:
- [High] The driver ignores error pointers returned by `devm_clk_get_optional_enabled()`, failing to defer the probe when the clock is not yet available.
- [High] Missing validation for `device_get_match_data()` in the Device Tree path causes a fatal kernel panic due to division by zero.
- [Medium] Misuse of the standardized "clocks" property to store a raw integer frequency.
Pre-existing issues:
- [High] The driver uses `DEFINE_RUNTIME_DEV_PM_OPS` without enabling runtime PM, causing system suspend/resume callbacks to be ignored.
--
--- Patch [2]: [PATCH v7 2/2] i2c: ls2x: Add clocks property parsing and adjust bus speed ---
commit ef2ab423afedc619ef9de8c57be0ad9e47092b2f
Author: Hongliang Wang <wanghongliang@loongson.cn>
i2c: ls2x: Add clocks property parsing and adjust bus speed
The i2c-ls2x driver supports dts and acpi parameter passing. In dts,
it uses the clock framework to get the i2c bus reference clock and
define the divider by device data. In acpi, it passes properties to
describe the bus reference clock and calculate the prescale value.
> --- a/drivers/i2c/busses/i2c-ls2x.c
> +++ b/drivers/i2c/busses/i2c-ls2x.c
[ ... ]
> @@ -304,6 +315,25 @@ static int ls2x_i2c_probe(struct platform_device *pdev)
> if (irq < 0)
> return irq;
>
> + if (dev_of_node(dev)) {
> + clk = devm_clk_get_optional_enabled(dev, NULL);
> + if (!IS_ERR_OR_NULL(clk))
[Severity: High]
If the clock provider is not yet ready, devm_clk_get_optional_enabled()
returns -EPROBE_DEFER. Because !IS_ERR_OR_NULL(clk) evaluates to false for
error pointers, does this skip returning the error and instead apply the
fallback frequency, preventing the probe from correctly deferring?
> + priv->pclk = clk_get_rate(clk);
> + else
> + priv->pclk = LS2X_I2C_PCLK_FREQ;
> +
> + priv->div = (unsigned long)device_get_match_data(dev);
[Severity: High]
If the driver is bound via sysfs to a platform device with an of_node but
an unmatched compatible string, device_get_match_data() will return NULL.
Does assigning this directly to priv->div without a fallback cause a
division by zero later in ls2x_i2c_adjust_bus_speed() when calculating the
prescale value?
ls2x_i2c_adjust_bus_speed()
val = (priv->pclk * 10) / (priv->div * t->bus_freq_hz) - 1;
> + } else {
> + /* clocks and clock-div are only ACPI properties. */
> + ret = device_property_read_u32(dev, "clocks", &priv->pclk);
[Severity: Medium]
Across standard device bindings, the "clocks" property is strictly defined
as an array of phandles or references. Could reading it as a raw 32-bit
integer frequency cause naming conflicts or failures in generic firmware
parsing tools? Should "clock-frequency" be used instead?
> + if (ret)
> + priv->pclk = LS2X_I2C_PCLK_FREQ;
[ ... ]
> @@ -349,8 +379,8 @@ static DEFINE_RUNTIME_DEV_PM_OPS(ls2x_i2c_pm_ops,
> ls2x_i2c_suspend, ls2x_i2c_resume, NULL);
>
[Severity: High]
This is a pre-existing issue, but the driver uses DEFINE_RUNTIME_DEV_PM_OPS
without enabling runtime pm via pm_runtime_enable().
Because the device pm state defaults to RPM_SUSPENDED, do system suspend
and resume operations using pm_runtime_force_suspend() see the device as
already suspended and skip calling ls2x_i2c_suspend() and ls2x_i2c_resume()?
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260707035104.3092-1-wanghongliang@loongson.cn?part=2
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-07-07 4:00 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-07 3:51 [PATCH v7 0/2] i2c: ls2x: Add clock- related properties and parsing Hongliang Wang
2026-07-07 3:51 ` [PATCH v7 1/2] dt-bindings: i2c: ls2x-i2c: Add clocks and clock-frequency properties Hongliang Wang
2026-07-07 3:51 ` [PATCH v7 2/2] i2c: ls2x: Add clocks property parsing and adjust bus speed Hongliang Wang
2026-07-07 4:00 ` sashiko-bot
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox