]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
i2c: spacemit: request IRQ after controller initialization
authorLinmao Li <lilinmao@kylinos.cn>
Thu, 23 Jul 2026 02:11:40 +0000 (10:11 +0800)
committerAndi Shyti <andi.shyti@kernel.org>
Mon, 27 Jul 2026 20:52:34 +0000 (22:52 +0200)
spacemit_i2c_probe() requests the IRQ before it enables the clocks, resets
the controller and runs init_completion(). If an interrupt is already
pending, the handler runs too early: it reads registers while the clocks
are still off and calls complete() on an uninitialized completion. Request
the IRQ after the controller and completion are initialized, but still
before the adapter is registered.

Fixes: 5ea558473fa3 ("i2c: spacemit: add support for SpacemiT K1 SoC")
Signed-off-by: Linmao Li <lilinmao@kylinos.cn>
Cc: <stable@vger.kernel.org> # v6.15+
Reviewed-by: Troy Mitchell <troy.mitchell@linux.spacemit.com>
Reviewed-by: Alex Elder <elder@riscstar.com>
Signed-off-by: Andi Shyti <andi.shyti@kernel.org>
Link: https://lore.kernel.org/r/20260723021140.2293844-1-lilinmao@kylinos.cn
drivers/i2c/busses/i2c-k1.c

index 51a0c3d80fc92fa673af4820c9149a566770dbf2..3fe716cc153db6203c92e21d4a6de3860325a1f2 100644 (file)
@@ -723,11 +723,6 @@ static int spacemit_i2c_probe(struct platform_device *pdev)
        if (i2c->irq < 0)
                return dev_err_probe(dev, i2c->irq, "failed to get irq resource");
 
-       ret = devm_request_irq(i2c->dev, i2c->irq, spacemit_i2c_irq_handler,
-                              IRQF_NO_SUSPEND, dev_name(i2c->dev), i2c);
-       if (ret)
-               return dev_err_probe(dev, ret, "failed to request irq");
-
        clk = devm_clk_get_enabled(dev, "func");
        if (IS_ERR(clk))
                return dev_err_probe(dev, PTR_ERR(clk), "failed to enable func clock");
@@ -755,6 +750,11 @@ static int spacemit_i2c_probe(struct platform_device *pdev)
 
        init_completion(&i2c->complete);
 
+       ret = devm_request_irq(i2c->dev, i2c->irq, spacemit_i2c_irq_handler,
+                              IRQF_NO_SUSPEND, dev_name(i2c->dev), i2c);
+       if (ret)
+               return dev_err_probe(dev, ret, "failed to request irq");
+
        platform_set_drvdata(pdev, i2c);
 
        ret = i2c_add_numbered_adapter(&i2c->adapt);